From efb76b33747ba84800cf3e2ed686c9cc015f9f2b Mon Sep 17 00:00:00 2001 From: Sean Chittenden Date: Mon, 13 Feb 2017 12:09:29 -0800 Subject: [PATCH] Update the style of the `consul_catalog_nodes` data source. --- .../consul/data_source_consul_agent_self.go | 2199 +++++++++++------ .../data_source_consul_agent_self_test.go | 60 +- .../data_source_consul_catalog_nodes.go | 44 +- builtin/providers/consul/utils.go | 557 +---- builtin/providers/consul/validators.go | 50 +- 5 files changed, 1524 insertions(+), 1386 deletions(-) diff --git a/builtin/providers/consul/data_source_consul_agent_self.go b/builtin/providers/consul/data_source_consul_agent_self.go index 98489267f..715013cfb 100644 --- a/builtin/providers/consul/data_source_consul_agent_self.go +++ b/builtin/providers/consul/data_source_consul_agent_self.go @@ -2,6 +2,8 @@ package consul import ( "fmt" + "strconv" + "time" consulapi "github.com/hashicorp/consul/api" "github.com/hashicorp/errwrap" @@ -9,819 +11,811 @@ import ( ) const ( - agentSelfACLDatacenter typeKey = iota - agentSelfACLDefaultPolicy - agentSelfACLDisableTTL - agentSelfACLDownPolicy - agentSelfACLEnforceVersion8 - agentSelfACLTTL - agentSelfAddresses - agentSelfAdvertiseAddr - agentSelfAdvertiseAddrWAN - agentSelfAdvertiseAddrs - agentSelfAtlasJoin - agentSelfBindAddr - agentSelfBootstrap - agentSelfBootstrapExpect - agentSelfCAFile - agentSelfCertFile - agentSelfCheckDeregisterIntervalMin - agentSelfCheckDisableAnonymousSignature - agentSelfCheckDisableRemoteExec - agentSelfCheckReapInterval - agentSelfCheckUpdateInterval - agentSelfClientAddr - agentSelfDNSConfig - agentSelfDNSRecursors - agentSelfDataDir - agentSelfDatacenter - agentSelfDevMode - agentSelfDisableCoordinates - agentSelfDisableUpdateCheck - agentSelfDomain - agentSelfEnableDebug - agentSelfEnableSyslog - agentSelfEnableUI - agentSelfID - agentSelfKeyFile - agentSelfLeaveOnInt - agentSelfLeaveOnTerm - agentSelfLogLevel - agentSelfName - agentSelfPerformance - agentSelfPidFile - agentSelfPorts - agentSelfProtocol - agentSelfReconnectTimeoutLAN - agentSelfReconnectTimeoutWAN - agentSelfRejoinAfterLeave - agentSelfRetryJoin - agentSelfRetryJoinEC2 - agentSelfRetryJoinGCE - agentSelfRetryJoinWAN - agentSelfRetryMaxAttempts - agentSelfRetryMaxAttemptsWAN - agentSelfRevision - agentSelfSerfLANBindAddr - agentSelfSerfWANBindAddr - agentSelfServer - agentSelfServerName - agentSelfSessionTTLMin - agentSelfStartJoin - agentSelfStartJoinWAN - agentSelfSyslogFacility - agentSelfTLSMinVersion - agentSelfTaggedAddresses - agentSelfTelemetry - agentSelfTranslateWANAddrs - agentSelfUIDir - agentSelfUnixSockets - agentSelfVerifyIncoming - agentSelfVerifyOutgoing - agentSelfVerifyServerHostname - agentSelfVersion - agentSelfVersionPrerelease + agentSelfACLDatacenter = "acl_datacenter" + agentSelfACLDefaultPolicy = "acl_default_policy" + agentSelfACLDisabledTTL = "acl_disabled_ttl" + agentSelfACLDownPolicy = "acl_down_policy" + agentSelfACLEnforceVersion8 = "acl_enforce_0_8_semantics" + agentSelfACLTTL = "acl_ttl" + agentSelfAddresses = "addresses" + agentSelfAdvertiseAddr = "advertise_addr" + agentSelfAdvertiseAddrWAN = "wan" + agentSelfAdvertiseAddrs = "advertise_addrs" + agentSelfAtlasJoin = "atlas_join" + agentSelfBindAddr = "bind_addr" + agentSelfBootstrapExpect = "bootstrap_expect" + agentSelfBootstrapMode = "bootstrap_mode" + agentSelfCheckDeregisterIntervalMin = "check_deregister_interval_min" + agentSelfCheckReapInterval = "check_reap_interval" + agentSelfCheckUpdateInterval = "check_update_interval" + agentSelfClientAddr = "client_addr" + agentSelfDNSConfig = "dns" + agentSelfDNSRecursors = "dns_recursors" + agentSelfDataDir = "data_dir" + agentSelfDatacenter = "datacenter" + agentSelfDevMode = "dev_mode" + agentSelfDomain = "domain" + agentSelfEnableAnonymousSignature = "enable_anonymous_signature" + agentSelfEnableCoordinates = "enable_coordinates" + agentSelfEnableDebug = "enable_debug" + agentSelfEnableRemoteExec = "enable_remote_exec" + agentSelfEnableSyslog = "enable_syslog" + agentSelfEnableUI = "enable_ui" + agentSelfEnableUpdateCheck = "enable_update_check" + agentSelfID = "id" + agentSelfLeaveOnInt = "leave_on_int" + agentSelfLeaveOnTerm = "leave_on_term" + agentSelfLogLevel = "log_level" + agentSelfName = "name" + agentSelfPerformance = "performance" + agentSelfPidFile = "pid_file" + agentSelfPorts = "ports" + agentSelfProtocol = "protocol_version" + agentSelfReconnectTimeoutLAN = "reconnect_timeout_lan" + agentSelfReconnectTimeoutWAN = "reconnect_timeout_wan" + agentSelfRejoinAfterLeave = "rejoin_after_leave" + agentSelfRetryJoin = "retry_join" + agentSelfRetryJoinEC2 = "retry_join_ec2" + agentSelfRetryJoinWAN = "retry_join_wan" + agentSelfRetryMaxAttempts = "retry_max_attempts" + agentSelfRetryMaxAttemptsWAN = "retry_max_attempts_wan" + agentSelfSerfLANBindAddr = "serf_lan_bind_addr" + agentSelfSerfWANBindAddr = "serf_wan_bind_addr" + agentSelfServerMode = "server_mode" + agentSelfServerName = "server_name" + agentSelfSessionTTLMin = "session_ttl_min" + agentSelfStartJoin = "start_join" + agentSelfStartJoinWAN = "start_join_wan" + agentSelfSyslogFacility = "syslog_facility" + agentSelfTLSCAFile = "tls_ca_file" + agentSelfTLSCertFile = "tls_cert_file" + agentSelfTLSKeyFile = "tls_key_file" + agentSelfTLSMinVersion = "tls_min_version" + agentSelfTLSVerifyIncoming = "tls_verify_incoming" + agentSelfTLSVerifyOutgoing = "tls_verify_outgoing" + agentSelfTLSVerifyServerHostname = "tls_verify_server_hostname" + agentSelfTaggedAddresses = "tagged_addresses" + agentSelfTelemetry = "telemetry" + agentSelfTranslateWANAddrs = "translate_wan_addrs" + agentSelfUIDir = "ui_dir" + agentSelfUnixSockets = "unix_sockets" + agentSelfVersion = "version" + agentSelfVersionPrerelease = "version_prerelease" + agentSelfVersionRevision = "version_revision" ) const ( - agentSelfDNSAllowStale typeKey = iota - agentSelfDNSMaxStale - agentSelfRecursorTimeout - agentSelfDNSDisableCompression - agentSelfDNSEnableTruncate - agentSelfDNSNodeTTL - agentSelfDNSOnlyPassing - agentSelfDNSUDPAnswerLimit - agentSelfServiceTTL + agentSelfRetryJoinAWSAccessKeyID = "access_key_id" + agentSelfRetryJoinAWSRegion = "region" + agentSelfRetryJoinAWSSecretAccessKey = "secret_access_key" + agentSelfRetryJoinAWSTagKey = "tag_key" + agentSelfRetryJoinAWSTagValue = "tag_value" ) const ( - agentSelfPerformanceRaftMultiplier typeKey = iota + agentSelfRetryJoinGCE = "retry_join_gce" + agentSelfRetryJoinGCECredentialsFile = "credentials_file" + agentSelfRetryJoinGCEProjectName = "project_name" + agentSelfRetryJoinGCETagValue = "tag_value" + agentSelfRetryJoinGCEZonePattern = "zone_pattern" ) const ( - agentSelfPortsDNS typeKey = iota - agentSelfPortsHTTP - agentSelfPortsHTTPS - agentSelfPortsRPC - agentSelfPortsSerfLAN - agentSelfPortsSerfWAN - agentSelfPortsServer + agentSelfDNSAllowStale = "allow_stale" + agentSelfDNSEnableCompression = "enable_compression" + agentSelfDNSEnableTruncate = "enable_truncate" + agentSelfDNSMaxStale = "max_stale" + agentSelfDNSNodeTTL = "node_ttl" + agentSelfDNSOnlyPassing = "only_passing" + agentSelfDNSRecursorTimeout = "recursor_timeout" + agentSelfDNSServiceTTL = "service_ttl" + agentSelfDNSUDPAnswerLimit = "udp_answer_limit" ) const ( - agentSelfTaggedAddressesLAN typeKey = iota - agentSelfTaggedAddressesWAN + agentSelfPerformanceRaftMultiplier = "raft_multiplier" ) const ( - agentSelfTelemetryCirconusAPIApp typeKey = iota - agentSelfTelemetryCirconusAPIURL - agentSelfTelemetryCirconusBrokerID - agentSelfTelemetryCirconusBrokerSelectTag - agentSelfTelemetryCirconusCheckDisplayName - agentSelfTelemetryCirconusCheckForceMetricActiation - agentSelfTelemetryCirconusCheckID - agentSelfTelemetryCirconusCheckInstanceID - agentSelfTelemetryCirconusCheckSearchTag - agentSelfTelemetryCirconusCheckSubmissionURL - agentSelfTelemetryCirconusCheckTags - agentSelfTelemetryCirconusSubmissionInterval - agentSelfTelemetryDisableHostname - agentSelfTelemetryDogStatsdAddr - agentSelfTelemetryDogStatsdTags - agentSelfTelemetryStatsdAddr - agentSelfTelemetryStatsiteAddr - agentSelfTelemetryStatsitePrefix + agentSelfAPIPortsDNS = "dns" + agentSelfAPIPortsHTTP = "http" + agentSelfAPIPortsHTTPS = "https" + agentSelfAPIPortsRPC = "rpc" + agentSelfAPIPortsSerfLAN = "serf_lan" + agentSelfAPIPortsSerfWAN = "serf_wan" + agentSelfAPIPortsServer = "server" + + agentSelfSchemaPortsDNS = "dns" + agentSelfSchemaPortsHTTP = "http" + agentSelfSchemaPortsHTTPS = "https" + agentSelfSchemaPortsRPC = "rpc" + agentSelfSchemaPortsSerfLAN = "serf_lan" + agentSelfSchemaPortsSerfWAN = "serf_wan" + agentSelfSchemaPortsServer = "server" ) -// Schema for consul's /v1/agent/self endpoint -var agentSelfMap = map[typeKey]*typeEntry{ - agentSelfACLDatacenter: { - APIName: "ACLDatacenter", - SchemaName: "acl_datacenter", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfACLDefaultPolicy: { - APIName: "ACLDefaultPolicy", - SchemaName: "acl_default_policy", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfACLDisableTTL: { - APIName: "ACLDisabledTTL", - SchemaName: "acl_disable_ttl", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfACLDownPolicy: { - APIName: "ACLDownPolicy", - SchemaName: "acl_down_policy", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfACLEnforceVersion8: { - APIName: "ACLEnforceVersion8", - SchemaName: "acl_enforce_version_8", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfACLTTL: { - APIName: "ACLTTL", - SchemaName: "acl_ttl", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfAddresses: { - APIName: "Addresses", - SchemaName: "addresses", - Source: sourceAPIResult, - Type: schema.TypeMap, - }, - agentSelfAdvertiseAddr: { - APIName: "AdvertiseAddr", - SchemaName: "advertise_addr", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfAdvertiseAddrs: { - APIName: "AdvertiseAddrs", - SchemaName: "advertise_addrs", - Source: sourceAPIResult, - Type: schema.TypeMap, - }, - agentSelfAdvertiseAddrWAN: { - APIName: "AdvertiseAddrWan", - SchemaName: "advertise_addr_wan", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - // Omitting the following since they've been depreciated: - // - // "AtlasInfrastructure": "", - // "AtlasEndpoint": "", - agentSelfAtlasJoin: { - APIName: "AtlasJoin", - SchemaName: "atlas_join", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfBindAddr: { - APIName: "BindAddr", - SchemaName: "bind_addr", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfBootstrap: { - APIName: "Bootstrap", - SchemaName: "bootstrap", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfBootstrapExpect: { - APIName: "BootstrapExpect", - SchemaName: "bootstrap_expect", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfCAFile: { - APIName: "CAFile", - SchemaName: "ca_file", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfCertFile: { - APIName: "CertFile", - SchemaName: "cert_file", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfCheckDeregisterIntervalMin: { - APIName: "CheckDeregisterIntervalMin", - SchemaName: "check_deregister_interval_min", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfCheckDisableAnonymousSignature: { - APIName: "DisableAnonymousSignature", - SchemaName: "disable_anonymous_signature", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfCheckDisableRemoteExec: { - APIName: "DisableRemoteExec", - SchemaName: "disable_remote_exec", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfCheckReapInterval: { - APIName: "CheckReapInterval", - SchemaName: "check_reap_interval", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfCheckUpdateInterval: { - APIName: "CheckUpdateInterval", - SchemaName: "check_update_interval", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfClientAddr: { - APIName: "ClientAddr", - SchemaName: "client_addr", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfDNSConfig: { - APIName: "DNSConfig", - SchemaName: "dns_config", - Source: sourceAPIResult, - Type: schema.TypeMap, - SetMembers: map[typeKey]*typeEntry{ - agentSelfDNSAllowStale: { - APIName: "AllowStale", - SchemaName: "allow_stale", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfDNSDisableCompression: { - APIName: "DisableCompression", - SchemaName: "disable_compression", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfDNSEnableTruncate: { - APIName: "EnableTruncate", - SchemaName: "enable_truncate", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfDNSMaxStale: { - APIName: "MaxStale", - SchemaName: "max_stale", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfDNSNodeTTL: { - APIName: "NodeTTL", - SchemaName: "node_ttl", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfDNSOnlyPassing: { - APIName: "OnlyPassing", - SchemaName: "only_passing", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfRecursorTimeout: { - APIName: "RecursorTimeout", - SchemaName: "recursor_timeout", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfServiceTTL: { - APIName: "ServiceTTL", - SchemaName: "service_ttl", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfDNSUDPAnswerLimit: { - APIName: "UDPAnswerLimit", - SchemaName: "udp_answer_limit", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - }, - }, - agentSelfDataDir: { - APIName: "DataDir", - SchemaName: "data_dir", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfDatacenter: { - APIName: "Datacenter", - SchemaName: "datacenter", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfDevMode: { - APIName: "DevMode", - SchemaName: "dev_mode", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfDisableCoordinates: { - APIName: "DisableCoordinates", - SchemaName: "coordinates", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfDisableUpdateCheck: { - APIName: "DisableUpdateCheck", - SchemaName: "update_check", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfDNSRecursors: { - APIName: "DNSRecursors", - APIAliases: []apiAttr{"DNSRecursor"}, - SchemaName: "dns_recursors", - Source: sourceAPIResult, - Type: schema.TypeList, - }, - agentSelfDomain: { - APIName: "Domain", - SchemaName: "domain", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfEnableDebug: { - APIName: "EnableDebug", - SchemaName: "debug", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfEnableSyslog: { - APIName: "EnableSyslog", - SchemaName: "syslog", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfEnableUI: { - APIName: "EnableUi", - SchemaName: "ui", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - // "HTTPAPIResponseHeaders": nil, - agentSelfID: { - APIName: "NodeID", - SchemaName: "id", - Source: sourceAPIResult, - Type: schema.TypeString, - ValidateFuncs: []interface{}{ - validateRegexp(`(?i)^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$`), - }, - APITest: apiTestID, - APIToState: apiToStateID, - }, - agentSelfKeyFile: { - APIName: "KeyFile", - SchemaName: "key_file", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfLeaveOnInt: { - APIName: "SkipLeaveOnInt", - SchemaName: "leave_on_int", - Source: sourceAPIResult, - Type: schema.TypeBool, - APITest: apiTestBool, - APIToState: negateBoolToState(apiToStateBool), - }, - agentSelfLeaveOnTerm: { - APIName: "LeaveOnTerm", - SchemaName: "leave_on_term", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfLogLevel: { - APIName: "LogLevel", - SchemaName: "log_level", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfName: { - APIName: "NodeName", - SchemaName: "name", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfPerformance: { - APIName: "Performance", - SchemaName: "performance", - Source: sourceAPIResult, - Type: schema.TypeMap, - SetMembers: map[typeKey]*typeEntry{ - agentSelfPerformanceRaftMultiplier: { - APIName: "RaftMultiplier", - SchemaName: "raft_multiplier", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - }, - }, - agentSelfPidFile: { - APIName: "PidFile", - SchemaName: "pid_file", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfPorts: { - APIName: "Ports", - SchemaName: "ports", - Source: sourceAPIResult, - Type: schema.TypeMap, - SetMembers: map[typeKey]*typeEntry{ - agentSelfPortsDNS: { - APIName: "DNS", - SchemaName: "dns", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfPortsHTTP: { - APIName: "HTTP", - SchemaName: "http", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfPortsHTTPS: { - APIName: "HTTPS", - SchemaName: "https", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfPortsRPC: { - APIName: "RPC", - SchemaName: "rpc", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfPortsSerfLAN: { - APIName: "SerfLan", - SchemaName: "serf_lan", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfPortsSerfWAN: { - APIName: "SerfWan", - SchemaName: "serf_wan", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfPortsServer: { - APIName: "Server", - SchemaName: "server", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - }, - }, - agentSelfProtocol: { - APIName: "Protocol", - SchemaName: "protocol", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfReconnectTimeoutLAN: { - APIName: "ReconnectTimeoutLan", - SchemaName: "reconnect_timeout_lan", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfReconnectTimeoutWAN: { - APIName: "ReconnectTimeoutWan", - SchemaName: "reconnect_timeout_wan", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfRejoinAfterLeave: { - APIName: "RejoinAfterLeave", - SchemaName: "rejoin_after_leave", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - // "RetryIntervalWanRaw": "", - agentSelfRetryJoin: { - APIName: "RetryJoin", - SchemaName: "retry_join", - Source: sourceAPIResult, - Type: schema.TypeList, - }, - agentSelfRetryJoinWAN: { - APIName: "RetryJoinWan", - SchemaName: "retry_join_wan", - Source: sourceAPIResult, - Type: schema.TypeList, - }, - agentSelfRetryMaxAttempts: { - APIName: "RetryMaxAttempts", - SchemaName: "retry_max_attempts", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfRetryMaxAttemptsWAN: { - APIName: "RetryMaxAttemptsWan", - SchemaName: "retry_max_attempts_wan", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfRetryJoinEC2: { - APIName: "RetryJoinEC2", - SchemaName: "retry_join_ec2", - Source: sourceAPIResult, - Type: schema.TypeMap, - }, - agentSelfRetryJoinGCE: { - APIName: "RetryJoinGCE", - SchemaName: "retry_join_GCE", - Source: sourceAPIResult, - Type: schema.TypeMap, - }, - agentSelfRevision: { - APIName: "Revision", - SchemaName: "revision", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfSerfLANBindAddr: { - APIName: "SerfLanBindAddr", - SchemaName: "serf_lan_bind_addr", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfSerfWANBindAddr: { - APIName: "SerfWanBindAddr", - SchemaName: "serf_wan_bind_addr", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfServer: { - APIName: "Server", - SchemaName: "server", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfServerName: { - APIName: "ServerName", - SchemaName: "server_name", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfSessionTTLMin: { - APIName: "SessionTTLMin", - SchemaName: "session_ttl_min", - Source: sourceAPIResult, - Type: schema.TypeFloat, - }, - agentSelfStartJoin: { - APIName: "StartJoin", - SchemaName: "start_join", - Source: sourceAPIResult, - Type: schema.TypeList, - }, - agentSelfStartJoinWAN: { - APIName: "StartJoinWan", - SchemaName: "start_join_wan", - Source: sourceAPIResult, - Type: schema.TypeList, - }, - agentSelfSyslogFacility: { - APIName: "SyslogFacility", - SchemaName: "syslog_facility", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTaggedAddresses: { - APIName: "TaggedAddresses", - SchemaName: "tagged_addresses", - Source: sourceAPIResult, - Type: schema.TypeMap, - SetMembers: map[typeKey]*typeEntry{ - agentSelfTaggedAddressesLAN: { - APIName: "LAN", - SchemaName: "lan", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTaggedAddressesWAN: { - APIName: "WAN", - SchemaName: "wan", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - }, - }, - agentSelfTelemetry: { - APIName: "Telemetry", - SchemaName: "telemetry", - Source: sourceAPIResult, - Type: schema.TypeMap, - SetMembers: map[typeKey]*typeEntry{ - agentSelfTelemetryCirconusAPIApp: { - APIName: "CirconusAPIApp", - SchemaName: "circonus_api_app", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusAPIURL: { - APIName: "CirconusAPIURL", - SchemaName: "circonus_api_url", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusBrokerID: { - APIName: "CirconusBrokerID", - SchemaName: "circonus_broker_id", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusBrokerSelectTag: { - APIName: "CirconusBrokerSelectTag", - SchemaName: "circonus_broker_select_tag", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusCheckDisplayName: { - APIName: "CirconusCheckDisplayName", - SchemaName: "circonus_check_display_name", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusCheckForceMetricActiation: { - APIName: "CirconusCheckForceMetricActivation", - SchemaName: "circonus_check_force_metric_activation", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusCheckID: { - APIName: "CirconusCheckID", - SchemaName: "circonus_check_id", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusCheckInstanceID: { - APIName: "CirconusCheckInstanceID", - SchemaName: "circonus_check_instance_id", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusCheckSearchTag: { - APIName: "CirconusCheckSearchTag", - SchemaName: "circonus_check_search_tag", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusCheckSubmissionURL: { - APIName: "CirconusCheckSubmissionURL", - SchemaName: "circonus_check_submission_url", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusCheckTags: { - APIName: "CirconusCheckTags", - SchemaName: "circonus_check_tags", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryCirconusSubmissionInterval: { - APIName: "CirconusSubmissionInterval", - SchemaName: "circonus_submission_interval", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryDisableHostname: { - APIName: "DisableHostname", - SchemaName: "disable_hostname", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfTelemetryDogStatsdAddr: { - APIName: "DogStatsdAddr", - SchemaName: "dog_statsd_addr", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryDogStatsdTags: { - APIName: "DogStatsdTags", - SchemaName: "dog_statsd_tags", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryStatsdAddr: { - APIName: "StatsdTags", - SchemaName: "statsd_tags", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryStatsiteAddr: { - APIName: "StatsiteAddr", - SchemaName: "statsite_addr", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTelemetryStatsitePrefix: { - APIName: "StatsitePrefix", - SchemaName: "statsite_prefix", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - }, - }, - agentSelfTLSMinVersion: { - APIName: "TLSMinVersion", - SchemaName: "tls_min_version", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfTranslateWANAddrs: { - APIName: "TranslateWanAddrs", - SchemaName: "translate_wan_addrs", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfUIDir: { - APIName: "UiDir", - SchemaName: "ui_dir", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfUnixSockets: { - APIName: "UnixSockets", - SchemaName: "unix_sockets", - Source: sourceAPIResult, - Type: schema.TypeMap, - }, - agentSelfVerifyIncoming: { - APIName: "VerifyIncoming", - SchemaName: "verify_incoming", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfVerifyServerHostname: { - APIName: "VerifyServerHostname", - SchemaName: "verify_server_hostname", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfVerifyOutgoing: { - APIName: "VerifyOutgoing", - SchemaName: "verify_outgoing", - Source: sourceAPIResult, - Type: schema.TypeBool, - }, - agentSelfVersion: { - APIName: "Version", - SchemaName: "version", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - agentSelfVersionPrerelease: { - APIName: "VersionPrerelease", - SchemaName: "version_prerelease", - Source: sourceAPIResult, - Type: schema.TypeString, - }, - // "Watches": nil, -} +const ( + agentSelfTaggedAddressesLAN = "lan" + agentSelfTaggedAddressesWAN = "wan" +) + +const ( + agentSelfTelemetryCirconusAPIApp = "circonus_api_app" + agentSelfTelemetryCirconusAPIToken = "circonus_api_token" + agentSelfTelemetryCirconusAPIURL = "circonus_api_url" + agentSelfTelemetryCirconusBrokerID = "circonus_broker_id" + agentSelfTelemetryCirconusBrokerSelectTag = "circonus_select_tag" + agentSelfTelemetryCirconusCheckDisplayName = "circonus_display_name" + agentSelfTelemetryCirconusCheckForceMetricActiation = "circonus_force_metric_activation" + agentSelfTelemetryCirconusCheckID = "circonus_check_id" + agentSelfTelemetryCirconusCheckInstanceID = "circonus_instance_id" + agentSelfTelemetryCirconusCheckSearchTag = "circonus_search_tag" + agentSelfTelemetryCirconusCheckSubmissionURL = "circonus_submission_url" + agentSelfTelemetryCirconusCheckTags = "circonus_tags" + agentSelfTelemetryCirconusSubmissionInterval = "circonus_submission_interval" + + agentSelfTelemetryDogStatsdAddr = "dogstatsd_addr" + agentSelfTelemetryDogStatsdTags = "dogstatsd_tags" + agentSelfTelemetryEnableHostname = "enable_hostname" + agentSelfTelemetryStatsdAddr = "statsd_addr" + agentSelfTelemetryStatsiteAddr = "statsite_addr" + agentSelfTelemetryStatsitePrefix = "statsite_prefix" +) + +const ( + agentSelfUnixSocketGroup = "group" + agentSelfUnixSocketMode = "mode" + agentSelfUnixSocketUser = "user" +) func dataSourceConsulAgentSelf() *schema.Resource { return &schema.Resource{ - Read: dataSourceConsulAgentSelfRead, - Schema: typeEntryMapToSchema(agentSelfMap), + Read: dataSourceConsulAgentSelfRead, + Schema: map[string]*schema.Schema{ + agentSelfACLDatacenter: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfACLDefaultPolicy: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfACLDisabledTTL: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfACLDisabledTTL, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfACLDownPolicy: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfACLEnforceVersion8: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfACLTTL: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfACLTTL, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfAddresses: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfSchemaPortsDNS: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfSchemaPortsHTTP: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfSchemaPortsHTTPS: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfSchemaPortsRPC: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + agentSelfAdvertiseAddr: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfAdvertiseAddrs: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfSchemaPortsSerfLAN: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfSchemaPortsSerfWAN: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfSchemaPortsRPC: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + agentSelfAdvertiseAddrWAN: { + Computed: true, + Type: schema.TypeString, + }, + // Omitting the following since they've been depreciated: + // + // "AtlasInfrastructure": "", + // "AtlasEndpoint": "", + agentSelfAtlasJoin: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfBindAddr: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfBootstrapMode: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfBootstrapExpect: { + Computed: true, + Type: schema.TypeInt, + }, + agentSelfCheckDeregisterIntervalMin: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfCheckDeregisterIntervalMin, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfCheckReapInterval: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfCheckReapInterval, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfCheckUpdateInterval: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfCheckUpdateInterval, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfClientAddr: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfDNSConfig: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfDNSAllowStale: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfDNSEnableCompression: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfDNSEnableTruncate: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfDNSMaxStale: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfDNSMaxStale, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfDNSNodeTTL: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfDNSNodeTTL, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfDNSOnlyPassing: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfDNSRecursorTimeout: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfDNSRecursorTimeout, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfDNSServiceTTL: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfDNSServiceTTL, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfDNSUDPAnswerLimit: { + Computed: true, + Type: schema.TypeInt, + }, + }, + }, + }, + agentSelfDataDir: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfDatacenter: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfDevMode: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfEnableAnonymousSignature: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfEnableCoordinates: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfEnableRemoteExec: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfEnableUpdateCheck: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfDNSRecursors: { + Computed: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + agentSelfDomain: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfEnableDebug: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfEnableSyslog: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfEnableUI: { + Computed: true, + Type: schema.TypeBool, + }, + // "HTTPAPIResponseHeaders": nil, // TODO(sean@) + agentSelfID: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfID, validatorInputs{ + validateRegexp(`(?i)^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$`), + }), + }, + agentSelfLeaveOnInt: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfLeaveOnTerm: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfLogLevel: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfName: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfPerformance: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfPerformanceRaftMultiplier: { + Computed: true, + Type: schema.TypeString, // FIXME(sean@): should be schema.TypeInt + ValidateFunc: makeValidationFunc(agentSelfPerformanceRaftMultiplier, validatorInputs{ + validateIntMin(0), + }), + }, + }, + }, + }, + agentSelfPidFile: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfPorts: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfSchemaPortsDNS: { + Computed: true, + Type: schema.TypeInt, + ValidateFunc: makeValidationFunc(agentSelfSchemaPortsDNS, validatorInputs{ + validateIntMin(1), + validateIntMax(65535), + }), + }, + agentSelfSchemaPortsHTTP: { + Computed: true, + Type: schema.TypeInt, + ValidateFunc: makeValidationFunc(agentSelfSchemaPortsHTTP, validatorInputs{ + validateIntMin(1), + validateIntMax(65535), + }), + }, + agentSelfSchemaPortsHTTPS: { + Computed: true, + Type: schema.TypeInt, + ValidateFunc: makeValidationFunc(agentSelfSchemaPortsHTTPS, validatorInputs{ + validateIntMin(1), + validateIntMax(65535), + }), + }, + agentSelfSchemaPortsRPC: { + Computed: true, + Type: schema.TypeInt, + ValidateFunc: makeValidationFunc(agentSelfSchemaPortsRPC, validatorInputs{ + validateIntMin(1), + validateIntMax(65535), + }), + }, + agentSelfSchemaPortsSerfLAN: { + Computed: true, + Type: schema.TypeInt, + ValidateFunc: makeValidationFunc(agentSelfSchemaPortsSerfLAN, validatorInputs{ + validateIntMin(1), + validateIntMax(65535), + }), + }, + agentSelfSchemaPortsSerfWAN: { + Computed: true, + Type: schema.TypeInt, + ValidateFunc: makeValidationFunc(agentSelfSchemaPortsSerfWAN, validatorInputs{ + validateIntMin(1), + validateIntMax(65535), + }), + }, + agentSelfSchemaPortsServer: { + Computed: true, + Type: schema.TypeInt, + ValidateFunc: makeValidationFunc(agentSelfSchemaPortsServer, validatorInputs{ + validateIntMin(1), + validateIntMax(65535), + }), + }, + }, + }, + }, + agentSelfProtocol: { + Computed: true, + Type: schema.TypeInt, + }, + agentSelfReconnectTimeoutLAN: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfReconnectTimeoutLAN, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfReconnectTimeoutWAN: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfReconnectTimeoutWAN, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfRejoinAfterLeave: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfRetryJoin: { + Computed: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + agentSelfRetryJoinWAN: { + Computed: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + agentSelfRetryMaxAttempts: { + Computed: true, + Type: schema.TypeInt, + }, + agentSelfRetryMaxAttemptsWAN: { + Computed: true, + Type: schema.TypeInt, + }, + agentSelfRetryJoinEC2: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfRetryJoinAWSRegion: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfRetryJoinAWSTagKey: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfRetryJoinAWSTagValue: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfRetryJoinAWSAccessKeyID: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + agentSelfRetryJoinAWSSecretAccessKey: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, + }, + }, + agentSelfRetryJoinGCE: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfRetryJoinGCEProjectName: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfRetryJoinGCEZonePattern: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfRetryJoinGCETagValue: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfRetryJoinGCECredentialsFile: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + agentSelfSerfLANBindAddr: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfSerfWANBindAddr: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfServerMode: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfServerName: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfSessionTTLMin: { + Computed: true, + Type: schema.TypeString, + ValidateFunc: makeValidationFunc(agentSelfSessionTTLMin, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfStartJoin: { + Computed: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + agentSelfStartJoinWAN: { + Computed: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + agentSelfSyslogFacility: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfTaggedAddresses: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfTaggedAddressesLAN: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTaggedAddressesWAN: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + agentSelfTelemetry: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfTelemetryCirconusAPIApp: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusAPIToken: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusAPIURL: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusBrokerID: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusBrokerSelectTag: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusCheckDisplayName: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusCheckID: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusCheckInstanceID: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusCheckSearchTag: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusCheckSubmissionURL: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusCheckTags: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryCirconusCheckForceMetricActiation: &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + }, + agentSelfTelemetryCirconusSubmissionInterval: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + ValidateFunc: makeValidationFunc(agentSelfTelemetryCirconusSubmissionInterval, validatorInputs{ + validateDurationMin("0ns"), + }), + }, + agentSelfTelemetryEnableHostname: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryDogStatsdAddr: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryDogStatsdTags: &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + agentSelfTelemetryStatsdAddr: { + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryStatsiteAddr: { + Type: schema.TypeString, + Computed: true, + }, + agentSelfTelemetryStatsitePrefix: { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + agentSelfTLSCAFile: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfTLSCertFile: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfTLSKeyFile: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfTLSMinVersion: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfTLSVerifyIncoming: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfTLSVerifyServerHostname: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfTLSVerifyOutgoing: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfTranslateWANAddrs: { + Computed: true, + Type: schema.TypeBool, + }, + agentSelfUIDir: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfUnixSockets: { + Computed: true, + Type: schema.TypeMap, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + agentSelfUnixSocketUser: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfUnixSocketGroup: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + agentSelfUnixSocketMode: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + agentSelfVersion: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfVersionPrerelease: { + Computed: true, + Type: schema.TypeString, + }, + agentSelfVersionRevision: { + Computed: true, + Type: schema.TypeString, + }, + // "Watches": nil, + }, } } @@ -838,35 +832,612 @@ func dataSourceConsulAgentSelfRead(d *schema.ResourceData, meta interface{}) err return fmt.Errorf("No %s info available within provider's agent/self endpoint", apiAgentConfig) } - // TODO(sean@): It'd be nice if this data source had a way of filtering out - // irrelevant data so only the important bits are persisted in the state file. - // Something like an attribute mask or even a regexp of matching schema names - // would be sufficient in the most basic case. Food for thought. - dataSourceWriter := newStateWriter(d) + // Pull the datacenter first because we use it when setting the ID + var dc string + if v, found := cfg["Datacenter"]; found { + dc = v.(string) + } - for k, e := range agentSelfMap { - apiTest := e.APITest - if apiTest == nil { - apiTest = e.LookupDefaultTypeHandler().APITest - } - if apiTest == nil { - panic(fmt.Sprintf("PROVIDER BUG: %v missing APITest method", k)) + const idKeyFmt = "agent-self-%s" + d.SetId(fmt.Sprintf(idKeyFmt, dc)) + + if v, found := cfg["ACLDatacenter"]; found { + d.Set(agentSelfACLDatacenter, v.(string)) + } + + if v, found := cfg["ACLDefaultPolicy"]; found { + d.Set(agentSelfACLDefaultPolicy, v.(string)) + } + + if v, found := cfg["ACLDisabledTTL"]; found { + dur := time.Duration(int64(v.(float64))) + d.Set(agentSelfACLDisabledTTL, dur.String()) + } + + if v, found := cfg["ACLDownPolicy"]; found { + d.Set(agentSelfACLDownPolicy, v.(string)) + } + + if v, found := cfg["ACLEnforceVersion8"]; found { + d.Set(agentSelfACLEnforceVersion8, v.(bool)) + } + + if v, found := cfg["ACLTTL"]; found { + dur := time.Duration(int64(v.(float64))) + d.Set(agentSelfACLTTL, dur.String()) + } + + if v, found := cfg["Addresses"]; found { + addrs := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(addrs)) + + if v, found := addrs["DNS"]; found { + m[agentSelfSchemaPortsDNS] = v.(string) } - apiToState := e.APIToState - if apiToState == nil { - apiToState = e.LookupDefaultTypeHandler().APIToState - } - if apiToState == nil { - panic(fmt.Sprintf("PROVIDER BUG: %v missing APIToState method", k)) + if v, found := addrs["HTTP"]; found { + m[agentSelfSchemaPortsHTTP] = v.(string) } - if v, ok := apiTest(e, cfg); ok { - if err := apiToState(e, v, dataSourceWriter); err != nil { - return errwrap.Wrapf(fmt.Sprintf("error writing %q's data to state: {{err}}", e.SchemaName), err) + if v, found := addrs["HTTPS"]; found { + m[agentSelfSchemaPortsHTTPS] = v.(string) + } + + if v, found := addrs["RPC"]; found { + m[agentSelfSchemaPortsRPC] = v.(string) + } + + if err := d.Set(agentSelfAddresses, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfAddresses), err) + } + } + + if v, found := cfg["AdvertiseAddr"]; found { + d.Set(agentSelfAdvertiseAddr, v.(string)) + } + + if v, found := cfg["AdvertiseAddrs"]; found { + addrs := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(addrs)) + + if v, found := addrs["SerfLan"]; found && v != nil { + m[agentSelfSchemaPortsSerfLAN] = v.(string) + } + + if v, found := addrs["SerfWan"]; found && v != nil { + m[agentSelfSchemaPortsSerfWAN] = v.(string) + } + + if v, found := addrs["RPC"]; found && v != nil { + m[agentSelfSchemaPortsRPC] = v.(string) + } + + if err := d.Set(agentSelfAdvertiseAddrs, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfAdvertiseAddrs), err) + } + } + + if v, found := cfg["AtlasJoin"]; found { + d.Set(agentSelfAtlasJoin, v.(bool)) + } + + if v, found := cfg["BindAddr"]; found { + d.Set(agentSelfBindAddr, v.(string)) + } + + if v, found := cfg["Bootstrap"]; found { + d.Set(agentSelfBootstrapMode, v.(bool)) + } + + if v, found := cfg["BootstrapExpect"]; found { + d.Set(agentSelfBootstrapExpect, int(v.(float64))) + } + + if v, found := cfg["CheckDeregisterIntervalMin"]; found { + dur := time.Duration(int64(v.(float64))) + d.Set(agentSelfCheckDeregisterIntervalMin, dur.String()) + } + + if v, found := cfg["CheckReapInterval"]; found { + dur := time.Duration(int64(v.(float64))) + d.Set(agentSelfCheckReapInterval, dur.String()) + } + + if v, found := cfg["CheckUpdateInterval"]; found { + dur := time.Duration(int64(v.(float64))) + d.Set(agentSelfCheckUpdateInterval, dur.String()) + } + + if v, found := cfg["ClientAddr"]; found { + d.Set(agentSelfClientAddr, v.(string)) + } + + if v, found := cfg["DNS"]; found { + dnsOpts := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(dnsOpts)) + + if v, found := dnsOpts["AllowStale"]; found { + m[agentSelfDNSAllowStale] = v.(bool) + } + + if v, found := dnsOpts["DisableCompression"]; found { + m[agentSelfDNSEnableCompression] = !v.(bool) + } + + if v, found := dnsOpts["EnableTruncate"]; found { + m[agentSelfDNSEnableTruncate] = v.(bool) + } + + if v, found := dnsOpts["MaxStale"]; found { + dur := time.Duration(int64(v.(float64))) + m[agentSelfDNSMaxStale] = dur.String() + } + + if v, found := dnsOpts["NodeTTL"]; found { + dur := time.Duration(int64(v.(float64))) + m[agentSelfDNSNodeTTL] = dur.String() + } + + if v, found := dnsOpts["OnlyPassing"]; found { + m[agentSelfDNSOnlyPassing] = v.(bool) + } + + if v, found := dnsOpts["RecursorTimeout"]; found { + dur := time.Duration(int64(v.(float64))) + m[agentSelfDNSRecursorTimeout] = dur.String() + } + + if v, found := dnsOpts["ServiceTTL"]; found { + dur := time.Duration(int64(v.(float64))) + m[agentSelfDNSServiceTTL] = dur.String() + } + + if v, found := dnsOpts["UDPAnswerLimit"]; found { + m[agentSelfDNSServiceTTL] = v.(int) + } + + if err := d.Set(agentSelfDNSConfig, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfDNSConfig), err) + } + } + + { + var l []interface{} + + if v, found := cfg["DNSRecursors"]; found { + l = make([]interface{}, 0, len(v.([]interface{}))+1) + l = append(l, v.([]interface{})...) + } + + if v, found := cfg["DNSRecursor"]; found { + l = append([]interface{}{v.(string)}, l...) + } + + if len(l) > 0 { + if err := d.Set(agentSelfDNSRecursors, l); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfDNSRecursors), err) } } } + if v, found := cfg["DataDir"]; found { + d.Set(agentSelfDataDir, v.(string)) + } + + if len(dc) > 0 { + d.Set(agentSelfDatacenter, dc) + } + + if v, found := cfg["DevMode"]; found { + d.Set(agentSelfDevMode, v.(bool)) + } + + if v, found := cfg["DisableAnonymousSignature"]; found { + d.Set(agentSelfEnableAnonymousSignature, !v.(bool)) + } + + if v, found := cfg["DisableCoordinates"]; found { + d.Set(agentSelfEnableCoordinates, !v.(bool)) + } + + if v, found := cfg["DisableRemoteExec"]; found { + d.Set(agentSelfEnableRemoteExec, !v.(bool)) + } + + if v, found := cfg["DisableUpdateCheck"]; found { + d.Set(agentSelfEnableUpdateCheck, !v.(bool)) + } + + if v, found := cfg["Domain"]; found { + d.Set(agentSelfDomain, v.(string)) + } + + if v, found := cfg["EnableDebug"]; found { + d.Set(agentSelfEnableDebug, v.(bool)) + } + + if v, found := cfg["EnableSyslog"]; found { + d.Set(agentSelfEnableSyslog, v.(bool)) + } + + if v, found := cfg["EnableUi"]; found { + d.Set(agentSelfEnableUI, v.(bool)) + } + + if v, found := cfg["id"]; found { + d.Set(agentSelfID, v.(string)) + } + + if v, found := cfg["SkipLeaveOnInt"]; found { + d.Set(agentSelfLeaveOnInt, !v.(bool)) + } + + if v, found := cfg["LeaveOnTerm"]; found { + d.Set(agentSelfLeaveOnTerm, v.(bool)) + } + + if v, found := cfg["LogLevel"]; found { + d.Set(agentSelfLogLevel, v.(string)) + } + + if v, found := cfg["NodeName"]; found { + d.Set(agentSelfName, v.(string)) + } + + if v, found := cfg["Performance"]; found { + cfgs := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(cfgs)) + + if v, found := cfgs["RaftMultiplier"]; found { + m[agentSelfPerformanceRaftMultiplier] = strconv.FormatFloat(v.(float64), 'g', -1, 64) + } + + if err := d.Set(agentSelfPerformance, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfPerformance), err) + } + } + + if v, found := cfg["PidFile"]; found { + d.Set(agentSelfPidFile, v.(string)) + } + + if v, found := cfg["Ports"]; found { + cfgs := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(cfgs)) + + if v, found := cfgs[agentSelfAPIPortsDNS]; found { + m[agentSelfSchemaPortsDNS] = int(v.(float64)) + } + + if v, found := cfgs[agentSelfAPIPortsHTTP]; found { + m[agentSelfSchemaPortsHTTP] = int(v.(float64)) + } + + if v, found := cfgs[agentSelfAPIPortsHTTPS]; found { + m[agentSelfSchemaPortsHTTPS] = int(v.(float64)) + } + + if v, found := cfgs[agentSelfAPIPortsRPC]; found { + m[agentSelfSchemaPortsRPC] = int(v.(float64)) + } + + if v, found := cfgs[agentSelfAPIPortsSerfLAN]; found { + m[agentSelfSchemaPortsSerfLAN] = int(v.(float64)) + } + + if v, found := cfgs[agentSelfAPIPortsSerfWAN]; found { + m[agentSelfSchemaPortsSerfWAN] = int(v.(float64)) + } + + if v, found := cfgs[agentSelfAPIPortsServer]; found { + m[agentSelfSchemaPortsServer] = int(v.(float64)) + } + + if err := d.Set(agentSelfPorts, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfPorts), err) + } + } + + if v, found := cfg["Protocol"]; found { + d.Set(agentSelfProtocol, int(v.(float64))) + } + + if v, found := cfg["ReconnectTimeoutLan"]; found { + dur := time.Duration(int64(v.(float64))) + d.Set(agentSelfReconnectTimeoutLAN, dur.String()) + } + + if v, found := cfg["ReconnectTimeoutWan"]; found { + dur := time.Duration(int64(v.(float64))) + d.Set(agentSelfReconnectTimeoutWAN, dur.String()) + } + + if v, found := cfg["RejoinAfterLeave"]; found { + d.Set(agentSelfRejoinAfterLeave, v.(bool)) + } + + if v, found := cfg["RetryJoin"]; found { + l := make([]string, 0, len(v.([]interface{}))) + for _, e := range v.([]interface{}) { + l = append(l, e.(string)) + } + + if err := d.Set(agentSelfRetryJoin, l); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfRetryJoin), err) + } + } + + if v, found := cfg["RetryJoinEC2"]; found { + ec2Config := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(ec2Config)) + + if v, found := ec2Config["Region"]; found { + m[agentSelfRetryJoinAWSRegion] = v.(string) + } + + if v, found := ec2Config["TagKey"]; found { + m[agentSelfRetryJoinAWSTagKey] = v.(string) + } + + if v, found := ec2Config["TagValue"]; found { + m[agentSelfRetryJoinAWSTagValue] = v.(string) + } + + if v, found := ec2Config["AccessKeyID"]; found { + m[agentSelfRetryJoinAWSAccessKeyID] = v.(string) + } + + if v, found := ec2Config["SecretAccessKey"]; found { + m[agentSelfRetryJoinAWSSecretAccessKey] = v.(string) + } + + if err := d.Set(agentSelfRetryJoinEC2, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfRetryJoinEC2), err) + } + } + + if v, found := cfg["RetryJoinWan"]; found { + l := make([]string, 0, len(v.([]interface{}))) + for _, e := range v.([]interface{}) { + l = append(l, e.(string)) + } + + if err := d.Set(agentSelfRetryJoinWAN, l); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfRetryJoinWAN), err) + } + } + + if v, found := cfg["RetryMaxAttempts"]; found { + d.Set(agentSelfRetryMaxAttempts, int(v.(float64))) + } + + if v, found := cfg["RetryMaxAttemptsWan"]; found { + d.Set(agentSelfRetryMaxAttemptsWAN, int(v.(float64))) + } + + if v, found := cfg["SerfLanBindAddr"]; found { + d.Set(agentSelfSerfLANBindAddr, v.(string)) + } + + if v, found := cfg["SerfWanBindAddr"]; found { + d.Set(agentSelfSerfWANBindAddr, v.(string)) + } + + if v, found := cfg["Server"]; found { + d.Set(agentSelfServerMode, v.(bool)) + } + + if v, found := cfg["ServerName"]; found { + d.Set(agentSelfServerName, v.(string)) + } + + if v, found := cfg["SessionTTLMin"]; found { + dur := time.Duration(int64(v.(float64))) + d.Set(agentSelfSessionTTLMin, dur.String()) + } + + if v, found := cfg["StartJoin"]; found { + serverList := v.([]interface{}) + l := make([]interface{}, 0, len(serverList)) + l = append(l, serverList...) + if err := d.Set(agentSelfStartJoin, l); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfStartJoin), err) + } + } + + if v, found := cfg["StartJoinWan"]; found { + serverList := v.([]interface{}) + l := make([]interface{}, 0, len(serverList)) + l = append(l, serverList...) + if err := d.Set(agentSelfStartJoinWAN, l); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfStartJoinWAN), err) + } + } + + if v, found := cfg["SyslogFacility"]; found { + d.Set(agentSelfSyslogFacility, v.(string)) + } + + if v, found := cfg["CAFile"]; found { + d.Set(agentSelfTLSCAFile, v.(string)) + } + + if v, found := cfg["CertFile"]; found { + d.Set(agentSelfTLSCertFile, v.(string)) + } + + if v, found := cfg["KeyFile"]; found { + d.Set(agentSelfTLSKeyFile, v.(string)) + } + + if v, found := cfg["TLSMinVersion"]; found { + d.Set(agentSelfTLSMinVersion, v.(string)) + } + + if v, found := cfg["VerifyIncoming"]; found { + d.Set(agentSelfTLSVerifyIncoming, v.(bool)) + } + + if v, found := cfg["VerifyOutgoing"]; found { + d.Set(agentSelfTLSVerifyOutgoing, v.(bool)) + } + + if v, found := cfg["VerifyServerHostname"]; found { + d.Set(agentSelfTLSVerifyServerHostname, v.(bool)) + } + + if v, found := cfg["TaggedAddresses"]; found { + addrs := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(addrs)) + + // NOTE(sean@): agentSelfTaggedAddressesLAN and agentSelfTaggedAddressesWAN + // are the only two known values that should be in this map at present, but + // in the future this value could/will expand and the schema should be + // releaxed to include both the known *{L,W}AN values as well as whatever + // else the user specifies. + for s, t := range addrs { + m[s] = t + } + + if err := d.Set(agentSelfTaggedAddresses, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfTaggedAddresses), err) + } + } + + if v, found := cfg["Telemetry"]; found { + telemetryCfg := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(telemetryCfg)) + + if v, found := telemetryCfg["CirconusAPIApp"]; found { + m[agentSelfTelemetryCirconusAPIApp] = v.(string) + } + + if v, found := telemetryCfg["CirconusAPIURL"]; found { + m[agentSelfTelemetryCirconusAPIURL] = v.(string) + } + + if v, found := telemetryCfg["CirconusBrokerID"]; found { + m[agentSelfTelemetryCirconusBrokerID] = v.(string) + } + + if v, found := telemetryCfg["CirconusBrokerSelectTag"]; found { + m[agentSelfTelemetryCirconusBrokerSelectTag] = v.(string) + } + + if v, found := telemetryCfg["CirconusCheckDisplayName"]; found { + m[agentSelfTelemetryCirconusCheckDisplayName] = v.(string) + } + + if v, found := telemetryCfg["CirconusCheckID"]; found { + m[agentSelfTelemetryCirconusCheckID] = v.(string) + } + + if v, found := telemetryCfg["CirconusCheckInstanceID"]; found { + m[agentSelfTelemetryCirconusCheckInstanceID] = v.(string) + } + + if v, found := telemetryCfg["CirconusCheckSearchTag"]; found { + m[agentSelfTelemetryCirconusCheckSearchTag] = v.(string) + } + + if v, found := telemetryCfg["CirconusCheckSubmissionURL"]; found { + m[agentSelfTelemetryCirconusCheckSubmissionURL] = v.(string) + } + + if v, found := telemetryCfg["CirconusCheckTags"]; found { + m[agentSelfTelemetryCirconusCheckTags] = v.(string) + } + + if v, found := telemetryCfg["CirconusCheckForceMetricActivation"]; found { + m[agentSelfTelemetryCirconusCheckForceMetricActiation] = v.(string) + } + + if v, found := telemetryCfg["CirconusSubmissionInterval"]; found { + m[agentSelfTelemetryCirconusSubmissionInterval] = v.(string) + } + + if v, found := telemetryCfg["DisableHostname"]; found { + m[agentSelfTelemetryEnableHostname] = fmt.Sprintf("%t", !v.(bool)) + } + + if v, found := telemetryCfg["DogStatsdAddr"]; found { + m[agentSelfTelemetryDogStatsdAddr] = v.(string) + } + + if v, found := telemetryCfg["DogStatsdTags"]; found && v != nil { + m[agentSelfTelemetryDogStatsdTags] = append([]interface{}(nil), v.([]interface{})...) + } + + if v, found := telemetryCfg["StatsdAddr"]; found { + m[agentSelfTelemetryStatsdAddr] = v.(string) + } + + if v, found := telemetryCfg["StatsiteAddr"]; found { + m[agentSelfTelemetryStatsiteAddr] = v.(string) + } + + if v, found := telemetryCfg["StatsitePrefix"]; found { + m[agentSelfTelemetryStatsitePrefix] = v.(string) + } + + if err := d.Set(agentSelfTelemetry, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfTelemetry), err) + } + } + + if v, found := cfg["TranslateWanTelemetryCfg"]; found { + d.Set(agentSelfTranslateWANAddrs, v.(bool)) + } + + if v, found := cfg["UiDir"]; found { + d.Set(agentSelfUIDir, v.(string)) + } + + if v, found := cfg["UnixSockets"]; found { + socketConfig := v.(map[string]interface{}) + + m := make(map[string]interface{}, len(socketConfig)) + + if v, found := socketConfig["Grp"]; found { + m[agentSelfUnixSocketGroup] = v.(string) + } + + if v, found := socketConfig["Mode"]; found { + m[agentSelfUnixSocketMode] = v.(string) + } + + if v, found := socketConfig["Usr"]; found { + m[agentSelfUnixSocketUser] = v.(string) + } + + if err := d.Set(agentSelfUnixSockets, m); err != nil { + return errwrap.Wrapf(fmt.Sprintf("Unable to set %s: {{err}}", agentSelfUnixSockets), err) + } + } + + if v, found := cfg["Version"]; found { + d.Set(agentSelfVersion, v.(string)) + } + + if v, found := cfg["VersionPrerelease"]; found { + d.Set(agentSelfVersionPrerelease, v.(string)) + } + + if v, found := cfg["VersionPrerelease"]; found { + d.Set(agentSelfVersionPrerelease, v.(string)) + } + + if v, found := cfg["Revision"]; found { + d.Set(agentSelfVersionRevision, v.(string)) + } + return nil } diff --git a/builtin/providers/consul/data_source_consul_agent_self_test.go b/builtin/providers/consul/data_source_consul_agent_self_test.go index b52b3f870..341a89c9c 100644 --- a/builtin/providers/consul/data_source_consul_agent_self_test.go +++ b/builtin/providers/consul/data_source_consul_agent_self_test.go @@ -16,11 +16,52 @@ func TestAccDataConsulAgentSelf_basic(t *testing.T) { resource.TestStep{ Config: testAccDataConsulAgentSelfConfig, Check: resource.ComposeTestCheckFunc( - testAccCheckDataSourceValue("data.consul_agent_self.read", "bootstrap", "false"), - testAccCheckDataSourceValue("data.consul_agent_self.read", "datacenter", "dc1"), + testAccCheckDataSourceValue("data.consul_agent_self.read", "acl_datacenter", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "acl_default_policy", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "acl_disabled_ttl", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "acl_down_policy", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "acl_enforce_0_8_semantics", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "acl_ttl", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "advertise_addr", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "bind_addr", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "bootstrap_expect", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "bootstrap_mode", "false"), + testAccCheckDataSourceValue("data.consul_agent_self.read", "client_addr", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "datacenter", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "dev_mode", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "domain", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "enable_anonymous_signature", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "enable_coordinates", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "enable_debug", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "enable_remote_exec", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "enable_syslog", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "enable_ui", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "enable_update_check", ""), testAccCheckDataSourceValue("data.consul_agent_self.read", "id", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "leave_on_int", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "leave_on_term", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "log_level", ""), testAccCheckDataSourceValue("data.consul_agent_self.read", "name", ""), - testAccCheckDataSourceValue("data.consul_agent_self.read", "server", "true"), + testAccCheckDataSourceValue("data.consul_agent_self.read", "pid_file", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "rejoin_after_leave", ""), + // testAccCheckDataSourceValue("data.consul_agent_self.read", "retry_join", ""), + // testAccCheckDataSourceValue("data.consul_agent_self.read", "retry_join_wan", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "retry_max_attempts", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "retry_max_attempts_wan", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "serf_lan_bind_addr", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "serf_wan_bind_addr", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "server_mode", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "server_name", ""), + // testAccCheckDataSourceValue("data.consul_agent_self.read", "start_join", ""), + // testAccCheckDataSourceValue("data.consul_agent_self.read", "start_join_wan", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "syslog_facility", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "telemetry.enable_hostname", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "tls_ca_file", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "tls_cert_file", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "tls_key_file", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "tls_verify_incoming", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "tls_verify_outgoing", ""), + testAccCheckDataSourceValue("data.consul_agent_self.read", "tls_verify_server_hostname", ""), ), }, }, @@ -33,14 +74,15 @@ func testAccCheckDataSourceValue(n, attr, val string) resource.TestCheckFunc { if !ok { return fmt.Errorf("Resource not found") } - out, ok := rn.Primary.Attributes[attr] - if !ok { + out, found := rn.Primary.Attributes[attr] + switch { + case !found: return fmt.Errorf("Attribute '%s' not found: %#v", attr, rn.Primary.Attributes) - } - if val != "" && out != val { + case val == "": + // Value found, don't care what the payload is (including the zero value) + case val != "" && out != val: return fmt.Errorf("Attribute '%s' value '%s' != '%s'", attr, out, val) - } - if val == "" && out == "" { + case val == "" && out == "": return fmt.Errorf("Attribute '%s' value '%s'", attr, out) } return nil diff --git a/builtin/providers/consul/data_source_consul_catalog_nodes.go b/builtin/providers/consul/data_source_consul_catalog_nodes.go index 0565d21b1..2cf440a80 100644 --- a/builtin/providers/consul/data_source_consul_catalog_nodes.go +++ b/builtin/providers/consul/data_source_consul_catalog_nodes.go @@ -2,7 +2,6 @@ package consul import ( "fmt" - "time" consulapi "github.com/hashicorp/consul/api" "github.com/hashicorp/errwrap" @@ -115,44 +114,9 @@ func dataSourceConsulCatalogNodesRead(d *schema.ResourceData, meta interface{}) client := meta.(*consulapi.Client) // Parse out data source filters to populate Consul's query options - - dc, err := getDC(d, client) + queryOpts, err := getQueryOpts(d, client) if err != nil { - return err - } - - queryOpts := &consulapi.QueryOptions{ - Datacenter: dc, - } - - if v, ok := d.GetOk(allowStale); ok { - queryOpts.AllowStale = v.(bool) - } - - if v, ok := d.GetOk(requireConsistent); ok { - queryOpts.RequireConsistent = v.(bool) - } - - if v, ok := d.GetOk(nodeMeta); ok { - m := v.(map[string]interface{}) - nodeMetaMap := make(map[string]string, len(nodeMeta)) - for s, t := range m { - nodeMetaMap[s] = t.(string) - } - queryOpts.NodeMeta = nodeMetaMap - } - - if v, ok := d.GetOk(token); ok { - queryOpts.Token = v.(string) - } - - if v, ok := d.GetOk(waitIndex); ok { - queryOpts.WaitIndex = uint64(v.(int)) - } - - if v, ok := d.GetOk(waitTime); ok { - d, _ := time.ParseDuration(v.(string)) - queryOpts.WaitTime = d + return errwrap.Wrapf("unable to get query options for fetching catalog nodes: {{err}}", err) } nodes, meta, err := client.Catalog().Nodes(queryOpts) @@ -199,9 +163,9 @@ func dataSourceConsulCatalogNodesRead(d *schema.ResourceData, meta interface{}) } const idKeyFmt = "catalog-nodes-%s" - d.SetId(fmt.Sprintf(idKeyFmt, dc)) + d.SetId(fmt.Sprintf(idKeyFmt, queryOpts.Datacenter)) - d.Set("datacenter", dc) + d.Set("datacenter", queryOpts.Datacenter) if err := d.Set(nodesAttr, l); err != nil { return errwrap.Wrapf("Unable to store nodes: {{err}}", err) } diff --git a/builtin/providers/consul/utils.go b/builtin/providers/consul/utils.go index ce7c764c0..442057562 100644 --- a/builtin/providers/consul/utils.go +++ b/builtin/providers/consul/utils.go @@ -1,536 +1,51 @@ package consul import ( - "bytes" - "fmt" - "sort" - "strconv" + "time" - "github.com/hashicorp/errwrap" - "github.com/hashicorp/terraform/helper/hashcode" + consulapi "github.com/hashicorp/consul/api" "github.com/hashicorp/terraform/helper/schema" ) -// apiAttr is the type used for constants representing well known keys within -// the API that are transmitted back to a resource over an API. -type apiAttr string +func getQueryOpts(d *schema.ResourceData, client *consulapi.Client) (*consulapi.QueryOptions, error) { + dc, err := getDC(d, client) + if err != nil { + return nil, err + } -// schemaAttr is the type used for constants representing well known keys -// within the schema for a resource. -type schemaAttr string + queryOpts := &consulapi.QueryOptions{ + Datacenter: dc, + } -// sourceFlags represent the ways in which an attribute can be written. Some -// sources are mutually exclusive, yet other flag combinations are composable. -type sourceFlags int + if v, ok := d.GetOk(allowStale); ok { + queryOpts.AllowStale = v.(bool) + } -// typeKey is the lookup mechanism for the generated schema. -type typeKey int + if v, ok := d.GetOk(requireConsistent); ok { + queryOpts.RequireConsistent = v.(bool) + } -const ( - // sourceUserRequired indicates the parameter must be provided by the user in - // their configuration. - sourceUserRequired sourceFlags = 1 << iota - - // sourceUserOptional indicates the parameter may optionally be specified by - // the user in their configuration. - sourceUserOptional - - // sourceAPIResult indicates the parameter may only be set by the return of - // an API call. - sourceAPIResult - - // sourceLocalFilter indicates the parameter is only used as input to the - // resource or data source and not to be entered into the state file. - sourceLocalFilter -) - -const ( - // modifyState is a mask that selects all attribute sources that can modify - // the state (i.e. everything but filters used in data sources). - modifyState = sourceUserRequired | sourceUserOptional | sourceAPIResult - - // computedAttrMask is a mask that selects source*'s that are Computed in the - // schema. - computedAttrMask = sourceAPIResult - - // optionalAttrMask is a mask that selects source*'s that are Optional in the - // schema. - optionalAttrMask = sourceAPIResult | sourceLocalFilter - - // requiredAttrMask is a mask that selects source*'s that are Required in the - // schema. - requiredAttrMask = sourceUserRequired -) - -type typeEntry struct { - APIName apiAttr - APIAliases []apiAttr - Source sourceFlags - Default interface{} - Description string - SchemaName schemaAttr - Type schema.ValueType - ValidateFuncs []interface{} - SetMembers map[typeKey]*typeEntry - ListSchema map[typeKey]*typeEntry - - // APITest, if returns true, will call APIToState. The if the value was - // found, the second return parameter will include the value that should be - // set in the state store. - APITest func(*typeEntry, interface{}) (interface{}, bool) - - // APIToState takes the value from APITest and writes it to the attrWriter - APIToState func(*typeEntry, interface{}, attrWriter) error - - // ConfigRead, if it returns true, returned a value that will be passed to its - // ConfigUse handler. - ConfigRead func(*typeEntry, attrReader) (interface{}, bool) - - // ConfigUse takes the value returned from ConfigRead as the second argument - // and a 3rd optional opaque context argument. - ConfigUse func(e *typeEntry, v interface{}, target interface{}) error -} - -type typeHandlers struct { - APITest func(*typeEntry, interface{}) (interface{}, bool) - APIToState func(*typeEntry, interface{}, attrWriter) error -} - -var typeHandlerLookupMap = map[schema.ValueType]*typeHandlers{ - schema.TypeBool: &typeHandlers{ - APITest: apiTestBool, - APIToState: apiToStateBool, - }, - schema.TypeFloat: &typeHandlers{ - APITest: apiTestFloat64, - APIToState: apiToStateFloat64, - }, - schema.TypeList: &typeHandlers{ - APITest: apiTestList, - APIToState: apiToStateList, - }, - schema.TypeMap: &typeHandlers{ - APITest: apiTestMap, - APIToState: apiToStateMap, - }, - schema.TypeSet: &typeHandlers{ - APITest: apiTestSet, - APIToState: apiToStateSet, - }, - schema.TypeString: &typeHandlers{ - APITest: apiTestString, - APIToState: apiToStateString, - }, -} - -func apiTestBool(e *typeEntry, self interface{}) (interface{}, bool) { - m := self.(map[string]interface{}) - - v, found := m[string(e.APIName)] - if found { - if b, ok := v.(bool); ok { - return b, true - } else { - panic(fmt.Sprintf("PROVIDER BUG: %q fails bool type assertion", e.SchemaName)) + if v, ok := d.GetOk(nodeMeta); ok { + m := v.(map[string]interface{}) + nodeMetaMap := make(map[string]string, len(nodeMeta)) + for s, t := range m { + nodeMetaMap[s] = t.(string) } + queryOpts.NodeMeta = nodeMetaMap } - return false, false -} - -func apiTestFloat64(e *typeEntry, self interface{}) (interface{}, bool) { - m := self.(map[string]interface{}) - - v, found := m[string(e.APIName)] - if found { - if f, ok := v.(float64); ok { - return f, true - } else { - panic(fmt.Sprintf("PROVIDER BUG: %q fails float64 type assertion", e.SchemaName)) - } - } - return 0.0, false -} - -func apiTestID(e *typeEntry, self interface{}) (interface{}, bool) { - m := self.(map[string]interface{}) - - v, _ := apiTestString(e, m) - - // Unconditionally return true so that the call to the APIToState handler can - // return an error. - return v, true -} - -func apiTestList(e *typeEntry, self interface{}) (interface{}, bool) { - m := self.(map[string]interface{}) - - names := append([]apiAttr{e.APIName}, e.APIAliases...) - const defaultListLen = 8 - l := make([]interface{}, 0, defaultListLen) - - var foundName bool - for _, name := range names { - v, found := m[string(name)] - if found { - foundName = true - // TODO(sean@): should make a list writer that normalizes v.(type) to a - // string. For now we only accept strings and lists. - switch u := v.(type) { - case []interface{}: - l = append(l, u...) - case string: - l = append(l, u) - default: - panic(fmt.Sprintf("PROVIDER BUG: %q fails list type assertion", e.SchemaName)) - } - } - } - - if foundName { - return l, true - } - - return []interface{}{}, false -} - -func apiTestMap(e *typeEntry, selfRaw interface{}) (interface{}, bool) { - self := selfRaw.(map[string]interface{}) - - v, found := self[string(e.APIName)] - if found { - if m, ok := v.(map[string]interface{}); ok { - return m, true - } else { - panic(fmt.Sprintf("PROVIDER BUG: %q fails map type assertion", e.SchemaName)) - } - } - return "", false -} - -func apiTestSet(e *typeEntry, selfRaw interface{}) (interface{}, bool) { - self := selfRaw.(map[string]interface{}) - - v, found := self[string(e.APIName)] - if found { - if m, ok := v.(map[string]interface{}); ok { - return m, true - } else { - panic(fmt.Sprintf("PROVIDER BUG: %q fails map type assertion", e.SchemaName)) - } - } - return "", false -} - -func apiTestString(e *typeEntry, selfRaw interface{}) (interface{}, bool) { - self := selfRaw.(map[string]interface{}) - - v, found := self[string(e.APIName)] - if found { - if s, ok := v.(string); ok { - return s, true - } else { - panic(fmt.Sprintf("PROVIDER BUG: %q fails string type assertion", e.SchemaName)) - } - } - return "", false -} - -func apiToStateBool(e *typeEntry, v interface{}, w attrWriter) error { - return w.SetBool(e.SchemaName, v.(bool)) -} - -func apiToStateID(e *typeEntry, v interface{}, w attrWriter) error { - s, ok := v.(string) - if !ok || len(s) == 0 { - return fmt.Errorf("Unable to set %q's ID to an empty or non-string value: %#v", e.SchemaName, v) - } - - stateWriter, ok := w.(*attrWriterState) - if !ok { - return fmt.Errorf("PROVIDER BUG: unable to SetID with a non-attrWriterState") - } - - stateWriter.SetID(s) - - return nil -} - -func apiToStateFloat64(e *typeEntry, v interface{}, w attrWriter) error { - f, ok := v.(float64) - if !ok { - return fmt.Errorf("PROVIDER BUG: unable to cast %s to a float64", e.SchemaName) - } - - return w.SetFloat64(e.SchemaName, f) -} - -func apiToStateList(e *typeEntry, v interface{}, w attrWriter) error { - l, ok := v.([]interface{}) - if !ok { - return fmt.Errorf("PROVIDER BUG: unable to cast %s to a list", e.SchemaName) - } - - return w.SetList(e.SchemaName, l) -} - -func apiToStateMap(e *typeEntry, v interface{}, w attrWriter) error { - rawMap, ok := v.(map[string]interface{}) - if !ok { - return fmt.Errorf("PROVIDER BUG: unable to cast %s to a map", e.SchemaName) - } - - mWriter := newMapWriter(make(map[string]interface{}, len(rawMap))) - - // Make a lookup map by API Schema Name - var setMembersLen int - if e.SetMembers != nil { - setMembersLen = len(e.SetMembers) - } - apiLookup := make(map[string]*typeEntry, setMembersLen) - for _, typeEntry := range e.SetMembers { - apiLookup[string(e.SchemaName)] = typeEntry - } - - for k, v := range rawMap { - var usedSchemaHandler bool - if attrEntry, found := apiLookup[k]; found { - usedSchemaHandler = true - if err := attrEntry.APIToState(e, v, mWriter); err != nil { - return errwrap.Wrapf(fmt.Sprintf("Error calling API to state handler on %s: {{err}}", k), err) - } - } - - if !usedSchemaHandler { - if err := mWriter.Set(schemaAttr(k), v); err != nil { - return errwrap.Wrapf("Unable to store map in state: {{err}}", err) - } - } - } - - return w.SetMap(e.SchemaName, mWriter.ToMap()) -} - -func apiToStateSet(e *typeEntry, v interface{}, w attrWriter) error { - s, ok := v.([]map[string]interface{}) - if !ok { - return fmt.Errorf("PROVIDER BUG: unable to cast %s to a set", e.SchemaName) - } - - set := schema.NewSet(schema.HashResource(nil), nil) - set.Add(s) - - return w.SetSet(e.SchemaName, set) -} - -func apiToStateString(e *typeEntry, v interface{}, w attrWriter) error { - s, ok := v.(string) - if !ok { - return fmt.Errorf("PROVIDER BUG: unable to cast %s to a float64", e.SchemaName) - } - - return w.SetString(e.SchemaName, s) -} - -func hashMap(in interface{}) int { - return 0 - m, ok := in.(map[string]interface{}) - if !ok { - panic(fmt.Sprintf("PROVIDER BUG: Unable to cast %#v to a map", in)) - } - - keys := make([]string, 0, len(m)) - for k, _ := range m { - keys = append(keys, k) - } - - sort.Strings(keys) - - b := &bytes.Buffer{} - const defaultHashBufSize = 4096 - b.Grow(defaultHashBufSize) - - for _, k := range keys { - v, found := m[k] - if !found { - panic("PROVIDER BUG: race condition: key should not be missing") - } - - fmt.Fprintf(b, k) - switch u := v.(type) { - case string: - fmt.Fprint(b, u) - case bool: - fmt.Fprintf(b, "%t", u) - case float64: - fmt.Fprint(b, strconv.FormatFloat(u, 'g', -1, 64)) - case int, uint: - fmt.Fprintf(b, "%d", u) - case nil: - default: - panic(fmt.Sprintf("Unsupported type %T in map hasher", v)) - } - } - - return hashcode.String(b.String()) -} - -func indirect(v interface{}) interface{} { - switch v.(type) { - case string: - return v - case *string: - p := v.(*string) - if p == nil { - return nil - } - return *p - default: - return v - } -} - -func (e *typeEntry) LookupDefaultTypeHandler() *typeHandlers { - h, found := typeHandlerLookupMap[e.Type] - if !found { - panic(fmt.Sprintf("PROVIDER BUG: unable to lookup %q's type (%#v)", e.SchemaName, e.Type)) - } - - return h -} - -func (e *typeEntry) MustLookupTypeHandler() *typeHandlers { - h := &typeHandlers{ - APITest: e.APITest, - APIToState: e.APIToState, - } - - defaultHandler := e.LookupDefaultTypeHandler() - - if h.APITest == nil { - h.APITest = defaultHandler.APITest - - if h.APITest == nil { - panic(fmt.Sprint("PROVIDER BUG: %v missing APITest method", e.SchemaName)) - } - } - - if h.APIToState == nil { - h.APIToState = defaultHandler.APIToState - - if h.APIToState == nil { - panic(fmt.Sprint("PROVIDER BUG: %v missing APIToState method", e.SchemaName)) - } - } - - return h -} - -// negateBoolToState is a factory function that creates a new function that -// negates whatever the bool is that's passed in as an argument. -func negateBoolToState(fn func(*typeEntry, interface{}, attrWriter) error) func(*typeEntry, interface{}, attrWriter) error { - return func(e *typeEntry, v interface{}, w attrWriter) error { - b, ok := v.(bool) - if !ok { - return fmt.Errorf("Unable to type assert non-bool value: %#v", v) - } - - return fn(e, !b, w) - } -} - -// stateSet sets an attribute based on an attrName. Return an error if the -// Set() to schema.ResourceData fails. -func stateSet(d *schema.ResourceData, attrName schemaAttr, v interface{}) error { - if err := d.Set(string(attrName), indirect(v)); err != nil { - return fmt.Errorf("PROVIDER BUG: failed set schema attribute %s to value %#v: %v", attrName, v, err) - } - - return nil -} - -func typeEntryListToSchema(e *typeEntry) map[string]*schema.Schema { - return map[string]*schema.Schema{ - string(e.SchemaName): e.ToSchema(), - } -} - -func typeEntryMapToResource(in map[typeKey]*typeEntry) *schema.Resource { - return &schema.Resource{ - Schema: typeEntryMapToSchema(in), - } -} - -func typeEntryMapToSchema(in map[typeKey]*typeEntry) map[string]*schema.Schema { - out := make(map[string]*schema.Schema, len(in)) - for _, e := range in { - out[string(e.SchemaName)] = e.ToSchema() - } - - return out -} - -func (e *typeEntry) Validate() { - if e.Source&sourceAPIResult != 0 && e.Type == schema.TypeSet { - panic(fmt.Sprintf("PROVIDER BUG: %s can not be computed and of type Set", e.SchemaName)) - } - - if e.Source&sourceLocalFilter != 0 { - if e.ConfigRead == nil { - panic(fmt.Sprintf("PROVIDER BUG: %s can not be configured as a local filter and be missing a config read handler", e.SchemaName)) - } - - if e.ConfigUse == nil { - panic(fmt.Sprintf("PROVIDER BUG: %s can not be configured as a local filter and be missing a config use handler", e.SchemaName)) - } - } - - if len(e.SetMembers) != 0 && !(e.Type == schema.TypeSet || e.Type == schema.TypeMap) { - panic(fmt.Sprintf("PROVIDER BUG: %s is not of type Set but has SetMembers set", e.SchemaName)) - } - - if e.Source&(sourceUserRequired|sourceAPIResult) == (sourceUserRequired | sourceAPIResult) { - panic(fmt.Sprintf("PROVIDER BUG: %#v and %#v are mutually exclusive Source flags", sourceUserRequired, sourceAPIResult)) - } -} - -func (e *typeEntry) ToSchema() *schema.Schema { - e.Validate() - - attr := &schema.Schema{ - Computed: e.Source&computedAttrMask != 0, - Default: e.Default, - Description: e.Description, - Optional: e.Source&optionalAttrMask != 0, - Required: e.Source&requiredAttrMask != 0, - Type: e.Type, - // ValidateFunc: e.MakeValidationFunc(), - } - - // Fixup the type: use the real type vs a surrogate type - switch e.Type { - case schema.TypeList: - if e.ListSchema == nil { - attr.Elem = &schema.Schema{ - Type: schema.TypeString, - } - } else { - attr.Elem = typeEntryMapToResource(e.ListSchema) - } - - case schema.TypeSet: - attr.Elem = &schema.Resource{ - Schema: typeEntryMapToSchema(e.SetMembers), - } - } - - return attr -} - -func mapStringToMapInterface(in map[string]string) map[string]interface{} { - out := make(map[string]interface{}, len(in)) - for k, v := range in { - out[k] = v - } - return out + if v, ok := d.GetOk(token); ok { + queryOpts.Token = v.(string) + } + + if v, ok := d.GetOk(waitIndex); ok { + queryOpts.WaitIndex = uint64(v.(int)) + } + + if v, ok := d.GetOk(waitTime); ok { + d, _ := time.ParseDuration(v.(string)) + queryOpts.WaitTime = d + } + + return queryOpts, nil } diff --git a/builtin/providers/consul/validators.go b/builtin/providers/consul/validators.go index 55591cbaf..8e74223f1 100644 --- a/builtin/providers/consul/validators.go +++ b/builtin/providers/consul/validators.go @@ -3,6 +3,7 @@ package consul import ( "fmt" "regexp" + "strconv" "time" "github.com/hashicorp/errwrap" @@ -15,6 +16,9 @@ type validatorInputs []interface{} // validateDurationMin is the minimum duration to accept as input type validateDurationMin string +// validateIntMax is the maximum integer value to accept as input +type validateIntMax int + // validateIntMin is the minimum integer value to accept as input type validateIntMin int @@ -35,6 +39,8 @@ func makeValidationFunc(name string, validators []interface{}) func(v interface{ switch u := v.(type) { case validateDurationMin: fns = append(fns, validateDurationMinFactory(name, string(u))) + case validateIntMax: + fns = append(fns, validateIntMaxFactory(name, int(u))) case validateIntMin: fns = append(fns, validateIntMinFactory(name, int(u))) case validateRegexp: @@ -77,10 +83,50 @@ func validateDurationMinFactory(name, minDuration string) func(v interface{}, ke } } +func validateIntMaxFactory(name string, max int) func(v interface{}, key string) (warnings []string, errors []error) { + return func(v interface{}, key string) (warnings []string, errors []error) { + switch u := v.(type) { + case string: + i, err := strconv.ParseInt(u, 10, 64) + if err != nil { + errors = append(errors, errwrap.Wrapf(fmt.Sprintf("unable to convert %q to an integer: {{err}}", u), err)) + break + } + + if i > int64(max) { + errors = append(errors, fmt.Errorf("Invalid %s specified: %d more than the required maximum %d", name, v.(int), max)) + } + case int: + if u > max { + errors = append(errors, fmt.Errorf("Invalid %s specified: %d more than the required maximum %d", name, v.(int), max)) + } + default: + errors = append(errors, fmt.Errorf("Unsupported type in int max validation: %T", v)) + } + + return warnings, errors + } +} + func validateIntMinFactory(name string, min int) func(v interface{}, key string) (warnings []string, errors []error) { return func(v interface{}, key string) (warnings []string, errors []error) { - if v.(int) < min { - errors = append(errors, fmt.Errorf("Invalid %s specified: %d less than the required minimum %d", name, v.(int), min)) + switch u := v.(type) { + case string: + i, err := strconv.ParseInt(u, 10, 64) + if err != nil { + errors = append(errors, errwrap.Wrapf(fmt.Sprintf("unable to convert %q to an integer: {{err}}", u), err)) + break + } + + if i < int64(min) { + errors = append(errors, fmt.Errorf("Invalid %s specified: %d less than the required minimum %d", name, v.(int), min)) + } + case int: + if u < min { + errors = append(errors, fmt.Errorf("Invalid %s specified: %d less than the required minimum %d", name, v.(int), min)) + } + default: + errors = append(errors, fmt.Errorf("Unsupported type in int min validation: %T", v)) } return warnings, errors