diff --git a/cli.go b/cli.go index c212193..b4c3061 100644 --- a/cli.go +++ b/cli.go @@ -53,6 +53,7 @@ func gatherResources(s *state) map[string]interface{} { unsortedOrdered := make(map[string][]*Resource) + resourceIDNames := s.mapResourceIDNames() for _, res := range s.resources() { // place in list of all resources all.Hosts = appendUniq(all.Hosts, res.Hostname()) @@ -77,6 +78,10 @@ func gatherResources(s *state) map[string]interface{} { if v != "" { tag = fmt.Sprintf("%s_%s", k, v) } + // if v is a resource ID, then tag should be resource name + if _, exists := resourceIDNames[v]; exists { + tag = resourceIDNames[v] + } tags[tag] = appendUniq(tags[tag], res.Hostname()) } } diff --git a/parser.go b/parser.go index 6dc27e0..7f0f5e8 100644 --- a/parser.go +++ b/parser.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "sort" + "strings" ) type state struct { @@ -52,13 +53,27 @@ func (s *state) outputs() []*Output { return inst } +// map of resource ID -> resource Name +func (s *state) mapResourceIDNames() map[string]string { + t := map[string]string{} + + for _, m := range s.Modules { + for _, k := range m.resourceKeys() { + if m.ResourceStates[k].Primary.ID != "" && m.ResourceStates[k].Primary.Attributes["name"] != "" { + kk := strings.ToLower(m.ResourceStates[k].Primary.ID) + t[kk] = m.ResourceStates[k].Primary.Attributes["name"] + } + } + } + return t +} + // resources returns a slice of the Resources found in the statefile. func (s *state) resources() []*Resource { inst := make([]*Resource, 0) for _, m := range s.Modules { for _, k := range m.resourceKeys() { - // Terraform stores resources in a name->map map, but we need the name to // decide which groups to include the resource in. So wrap it in a higher- // level object with both properties. diff --git a/parser_test.go b/parser_test.go index 7977f83..e8b7ef3 100644 --- a/parser_test.go +++ b/parser_test.go @@ -329,7 +329,18 @@ const exampleStateFile = ` "primary": { "id": "422cfa4a-c6bb-3405-0335-2d9b2034405f", "attributes": { - "default_ip_address": "10.20.30.50" + "default_ip_address": "10.20.30.50", + "tags.#": "1", + "tags.1357913579": "urn:vmomi:InventoryServiceTag:00000000-0001-4957-81fa-1234567890ab:GLOBAL" + } + } + }, + "data.vsphere_tag.testTag1": { + "type": "vsphere_tag", + "primary": { + "id": "urn:vmomi:InventoryServiceTag:00000000-0001-4957-81fa-1234567890ab:GLOBAL", + "attributes": { + "name": "testTag1" } } }, @@ -432,6 +443,7 @@ const expectedListOutput = ` "ten": ["10.0.0.10"], "eleven": ["10.0.0.11"], "twelve": ["10.20.30.50"], + "testTag1": ["10.20.30.50"], "thirteen": ["10.0.0.13"], "fourteen": ["192.168.102.14"], "sixteen": ["10.0.0.16"], @@ -600,6 +612,9 @@ olddatacenter="\u003c0.7_format" [ten.0] 10.0.0.10 +[testTag1] +10.20.30.50 + [thirteen] 10.0.0.13 diff --git a/resource.go b/resource.go index eca628f..2921e8c 100644 --- a/resource.go +++ b/resource.go @@ -126,11 +126,17 @@ func (r Resource) Tags() map[string]string { case "vsphere_virtual_machine": for k, v := range r.Attributes() { parts := strings.SplitN(k, ".", 2) + if len(parts) == 2 && parts[0] == "custom_configuration_parameters" && parts[1] != "#" && parts[1] != "%" { kk := strings.ToLower(parts[1]) vv := strings.ToLower(v) t[kk] = vv } + if len(parts) == 2 && parts[0] == "tags" && parts[1] != "#" && parts[1] != "%" { + kk := strings.ToLower(parts[1]) + vv := strings.ToLower(v) + t[kk] = vv + } } case "digitalocean_droplet", "google_compute_instance", "scaleway_server": for k, v := range r.Attributes() {