diff --git a/builtin/providers/consul/data_source_consul_catalog_nodes.go b/builtin/providers/consul/data_source_consul_catalog_nodes.go index 21783d7cc8..666d716539 100644 --- a/builtin/providers/consul/data_source_consul_catalog_nodes.go +++ b/builtin/providers/consul/data_source_consul_catalog_nodes.go @@ -9,60 +9,80 @@ import ( ) const ( - queryOptNodesAttr = "nodes" + catalogNodesElem = "nodes" + catalogNodesDatacenter = "datacenter" + catalogNodesQueryOpts = "query_options" - nodeID = "id" - nodeAddress = "address" - nodeMetaAttr = "meta" - nodeName = "name" - nodeTaggedAddresses = "tagged_addresses" + catalogNodesNodeID = "id" + catalogNodesNodeAddress = "address" + catalogNodesNodeMeta = "meta" + catalogNodesNodeName = "name" + catalogNodesNodeTaggedAddresses = "tagged_addresses" - queryOpts = "query_options" + catalogNodesNodeIDs = "node_ids" + catalogNodesNodeNames = "node_names" - apiTaggedLAN = "lan" - apiTaggedWAN = "wan" - schemaTaggedLAN = "lan" - schemaTaggedWAN = "wan" + catalogNodesAPITaggedLAN = "lan" + catalogNodesAPITaggedWAN = "wan" + catalogNodesSchemaTaggedLAN = "lan" + catalogNodesSchemaTaggedWAN = "wan" ) func dataSourceConsulCatalogNodes() *schema.Resource { return &schema.Resource{ Read: dataSourceConsulCatalogNodesRead, Schema: map[string]*schema.Schema{ - queryOpts: schemaQueryOpts, - queryOptNodesAttr: &schema.Schema{ + // Filters + catalogNodesQueryOpts: schemaQueryOpts, + + // Out parameters + catalogNodesDatacenter: &schema.Schema{ + Computed: true, + Type: schema.TypeString, + }, + catalogNodesNodeIDs: &schema.Schema{ + Computed: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + catalogNodesNodeNames: &schema.Schema{ + Computed: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + catalogNodesElem: &schema.Schema{ Computed: true, Type: schema.TypeList, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - nodeID: &schema.Schema{ + catalogNodesNodeID: &schema.Schema{ Type: schema.TypeString, Computed: true, - ValidateFunc: makeValidationFunc(nodeID, []interface{}{validateRegexp(`^[\S]+$`)}), + ValidateFunc: makeValidationFunc(catalogNodesNodeID, []interface{}{validateRegexp(`^[\S]+$`)}), }, - nodeName: &schema.Schema{ + catalogNodesNodeName: &schema.Schema{ Type: schema.TypeString, Computed: true, - ValidateFunc: makeValidationFunc(nodeName, []interface{}{validateRegexp(`^[\S]+$`)}), + ValidateFunc: makeValidationFunc(catalogNodesNodeName, []interface{}{validateRegexp(`^[\S]+$`)}), }, - nodeAddress: &schema.Schema{ + catalogNodesNodeAddress: &schema.Schema{ Type: schema.TypeString, Computed: true, }, - nodeMetaAttr: &schema.Schema{ + catalogNodesNodeMeta: &schema.Schema{ Type: schema.TypeMap, Computed: true, }, - nodeTaggedAddresses: &schema.Schema{ + catalogNodesNodeTaggedAddresses: &schema.Schema{ Type: schema.TypeMap, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - schemaTaggedLAN: &schema.Schema{ + catalogNodesSchemaTaggedLAN: &schema.Schema{ Type: schema.TypeString, Computed: true, }, - schemaTaggedWAN: &schema.Schema{ + catalogNodesSchemaTaggedWAN: &schema.Schema{ Type: schema.TypeString, Computed: true, }, @@ -92,6 +112,9 @@ func dataSourceConsulCatalogNodesRead(d *schema.ResourceData, meta interface{}) l := make([]interface{}, 0, len(nodes)) + nodeNames := make([]interface{}, 0, len(nodes)) + nodeIDs := make([]interface{}, 0, len(nodes)) + for _, node := range nodes { const defaultNodeAttrs = 4 m := make(map[string]interface{}, defaultNodeAttrs) @@ -100,30 +123,14 @@ func dataSourceConsulCatalogNodesRead(d *schema.ResourceData, meta interface{}) id = node.Node } - m[nodeID] = id - m[nodeName] = node.Node - m[nodeAddress] = node.Address + nodeIDs = append(nodeIDs, id) + nodeNames = append(nodeNames, node.Node) - { - const initNumTaggedAddrs = 2 - taggedAddrs := make(map[string]interface{}, initNumTaggedAddrs) - if addr, found := node.TaggedAddresses[apiTaggedLAN]; found { - taggedAddrs[schemaTaggedLAN] = addr - } - if addr, found := node.TaggedAddresses[apiTaggedWAN]; found { - taggedAddrs[schemaTaggedWAN] = addr - } - m[nodeTaggedAddresses] = taggedAddrs - } - - { - const initNumMetaAddrs = 4 - metaVals := make(map[string]interface{}, initNumMetaAddrs) - for s, t := range node.Meta { - metaVals[s] = t - } - m[nodeMetaAttr] = metaVals - } + m[catalogNodesNodeAddress] = node.Address + m[catalogNodesNodeID] = id + m[catalogNodesNodeName] = node.Node + m[catalogNodesNodeMeta] = node.Meta + m[catalogNodesNodeTaggedAddresses] = node.TaggedAddresses l = append(l, m) } @@ -131,8 +138,16 @@ func dataSourceConsulCatalogNodesRead(d *schema.ResourceData, meta interface{}) const idKeyFmt = "catalog-nodes-%s" d.SetId(fmt.Sprintf(idKeyFmt, queryOpts.Datacenter)) - d.Set("datacenter", queryOpts.Datacenter) - if err := d.Set(queryOptNodesAttr, l); err != nil { + d.Set(catalogNodesDatacenter, queryOpts.Datacenter) + if err := d.Set(catalogNodesNodeIDs, nodeIDs); err != nil { + return errwrap.Wrapf("Unable to store node IDs: {{err}}", err) + } + + if err := d.Set(catalogNodesNodeNames, nodeNames); err != nil { + return errwrap.Wrapf("Unable to store node names: {{err}}", err) + } + + if err := d.Set(catalogNodesElem, l); err != nil { return errwrap.Wrapf("Unable to store nodes: {{err}}", err) } diff --git a/builtin/providers/consul/data_source_consul_catalog_service.go b/builtin/providers/consul/data_source_consul_catalog_service.go index 71dc00780b..1affc781ef 100644 --- a/builtin/providers/consul/data_source_consul_catalog_service.go +++ b/builtin/providers/consul/data_source_consul_catalog_service.go @@ -55,7 +55,7 @@ func dataSourceConsulCatalogService() *schema.Resource { Required: true, Type: schema.TypeString, }, - queryOpts: schemaQueryOpts, + catalogNodesQueryOpts: schemaQueryOpts, // Out parameters catalogServiceElem: &schema.Schema{ @@ -117,11 +117,11 @@ func dataSourceConsulCatalogService() *schema.Resource { Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - schemaTaggedLAN: &schema.Schema{ + catalogNodesSchemaTaggedLAN: &schema.Schema{ Type: schema.TypeString, Computed: true, }, - schemaTaggedWAN: &schema.Schema{ + catalogNodesSchemaTaggedWAN: &schema.Schema{ Type: schema.TypeString, Computed: true, }, diff --git a/builtin/providers/consul/data_source_consul_catalog_services.go b/builtin/providers/consul/data_source_consul_catalog_services.go index ad7535a09a..85770d6113 100644 --- a/builtin/providers/consul/data_source_consul_catalog_services.go +++ b/builtin/providers/consul/data_source_consul_catalog_services.go @@ -33,7 +33,7 @@ func dataSourceConsulCatalogServices() *schema.Resource { Type: schema.TypeString, ForceNew: true, }, - queryOpts: schemaQueryOpts, + catalogNodesQueryOpts: schemaQueryOpts, // Out parameters catalogServicesNames: &schema.Schema{ diff --git a/website/source/docs/providers/consul/d/nodes.html.markdown b/website/source/docs/providers/consul/d/nodes.html.markdown new file mode 100644 index 0000000000..8c1c240057 --- /dev/null +++ b/website/source/docs/providers/consul/d/nodes.html.markdown @@ -0,0 +1,83 @@ +--- +layout: "consul" +page_title: "Consul: consul_catalog_nodes" +sidebar_current: "docs-consul-data-source-catalog-nodes" +description: |- + Provides a list of nodes in a given Consul datacenter. +--- + +# consul\_catalog\_nodes + +The `consul_catalog_nodes` data source returns a list of Consul nodes that have +been registered with the Consul cluster in a given datacenter. By specifying a +different datacenter in the `query_options` it is possible to retrieve a list of +nodes from a different WAN-attached Consul datacenter. + +## Example Usage + +``` +data "consul_catalog_nodes" "read-dc1-nodes" { + # query_options { + # # Optional parameter: implicitly uses the current datacenter of the agent + # datacenter = "dc1" + # } +} + +# Set the description to a whitespace delimited list of the node names +resource "example_resource" "app" { + description = "${join(" ", formatlist("%s", data.consul_catalog_nodes.node_names))}" + ... +} +``` + +## Argument Reference + +The following arguments are supported: + +* `datacenter` - (Optional) The Consul datacenter to query. Defaults to the + same value found in `query_options` parameter specified below, or if that is + empty, the `datacenter` value found in the Consul agent that this provider is + configured to talk to. + +* `query_options` - (Optional) See below. + +The `query_options` block supports the following: + +* `allow_stale` - (Optional) When `true`, the default, allow responses from + Consul servers that are followers. + +* `require_consistent` - (Optional) When `true` force the client to perform a + read on at least quorum servers and verify the result is the same. Defaults + to `false`. + +* `token` - (Optional) Specify the Consul ACL token to use when performing the + request. This defaults to the same API token configured by the `consul` + provider but may be overriden if necessary. + +* `wait_index` - (Optional) Index number used to enable blocking quereis. + +* `wait_time` - (Optional) Max time the client should wait for a blocking query + to return. + +## Attributes Reference + +The following attributes are exported: + +* `datacenter` - The datacenter the keys are being read from to. +* `node_ids` - A list of the Consul node IDs. +* `node_names` - A list of the Consul node names. +* `nodes` - A list of nodes and details about each Consul agent. The list of + per-node attributes is detailed below. + +The following is a list of the per-node attributes contained within the `nodes` +map: + +* `id` - The Node ID of the Consul agent. +* [`meta`](https://www.consul.io/docs/agent/http/catalog.html#Meta) - Node meta + data tag information, if any. +* [`name`](https://www.consul.io/docs/agent/http/catalog.html#Node) - The name + of the Consul node. +* [`address`](https://www.consul.io/docs/agent/http/catalog.html#Address) - The + IP address the node is advertising to the Consul cluster. +* [`tagged_addresses`](https://www.consul.io/docs/agent/http/catalog.html#TaggedAddresses) - + List of explicit LAN and WAN IP addresses for the agent. diff --git a/website/source/docs/providers/consul/d/services.html.markdown b/website/source/docs/providers/consul/d/services.html.markdown index f8fe6ee474..4bda1d3190 100644 --- a/website/source/docs/providers/consul/d/services.html.markdown +++ b/website/source/docs/providers/consul/d/services.html.markdown @@ -20,10 +20,10 @@ source, which provides a detailed response about a specific Consul service. ``` data "consul_catalog_services" "read-dc1" { - query_options { - # Optional parameter - datacenter = "dc1" - } + # query_options { + # # Optional parameter: implicitly uses the current datacenter of the agent + # datacenter = "dc1" + # } } # Set the description to a whitespace delimited list of the services @@ -71,9 +71,7 @@ The following attributes are exported: list of services found. * `services.` - For each name given, the corresponding attribute is a Terraform map of services and their tags. The value is an alphanumerically - sorted, whitespace delimited set of tags associated with the service. As - shown in the example above, to create a list of the available servies, wrap - the `names` attribute in a call to `keys()`. + sorted, whitespace delimited set of tags associated with the service. * `tags` - A map of the tags found for each service. If more than one service shares the same tag, unique service names will be joined by whitespace (this is the inverse of `services` and can be used to lookup the services that match