Skip to content

Commit 2365c9b

Browse files
cgroschuppadammck
authored andcommitted
Add TF_HOSTNAME_KEY_NAME to specify which hostname to return (#94)
Overwrite with the environment variable TF_HOSTNAME_KEY_NAME which attribute is to be used for the ansible inventory name. By default, the IP address is used. The Ansible variable "ansible_host" is used to connect to the host.
1 parent 842b8f7 commit 2365c9b

File tree

4 files changed

+94
-8
lines changed

4 files changed

+94
-8
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ to `private_ip` before running the playbook, like:
147147

148148
TF_KEY_NAME=private_ip ansible-playbook --inventory-file=/path/to/terraform-inventory deploy/playbook.yml
149149

150+
By default, the ip address is the ansible inventory name. The `TF_HOSTNAME_KEY_NAME` environment variable allows
151+
you to overwrite the source of the ansible inventory name.
152+
153+
TF_HOSTNAME_KEY_NAME=name ansible-playbook --inventory-file=/path/to/terraform-inventory deploy/playbook.yml
154+
150155
## Development
151156

152157
It's just a Go app, so the usual:

cli.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,20 @@ func gatherResources(s *state) map[string]interface{} {
5555

5656
for _, res := range s.resources() {
5757
// place in list of all resources
58-
all.Hosts = appendUniq(all.Hosts, res.Address())
58+
all.Hosts = appendUniq(all.Hosts, res.Hostname())
5959

6060
// place in list of resource types
6161
tp := fmt.Sprintf("type_%s", res.resourceType)
62-
types[tp] = appendUniq(types[tp], res.Address())
62+
types[tp] = appendUniq(types[tp], res.Hostname())
6363

6464
unsortedOrdered[res.baseName] = append(unsortedOrdered[res.baseName], res)
6565

6666
// store as invdividual host (eg. <name>.<count>)
6767
invdName := fmt.Sprintf("%s.%d", res.baseName, res.counter)
6868
if old, exists := individual[invdName]; exists {
69-
fmt.Fprintf(os.Stderr, "overwriting already existing individual key %s, old: %v, new: %v", invdName, old, res.Address())
69+
fmt.Fprintf(os.Stderr, "overwriting already existing individual key %s, old: %v, new: %v", invdName, old, res.Hostname())
7070
}
71-
individual[invdName] = []string{res.Address()}
71+
individual[invdName] = []string{res.Hostname()}
7272

7373
// inventorize tags
7474
for k, v := range res.Tags() {
@@ -77,7 +77,7 @@ func gatherResources(s *state) map[string]interface{} {
7777
if v != "" {
7878
tag = fmt.Sprintf("%s_%s", k, v)
7979
}
80-
tags[tag] = appendUniq(tags[tag], res.Address())
80+
tags[tag] = appendUniq(tags[tag], res.Hostname())
8181
}
8282
}
8383

@@ -94,7 +94,7 @@ func gatherResources(s *state) map[string]interface{} {
9494
sort.Sort(cs)
9595

9696
for i := range resources {
97-
ordered[basename] = append(ordered[basename], resources[i].Address())
97+
ordered[basename] = append(ordered[basename], resources[i].Hostname())
9898
}
9999
}
100100

@@ -187,8 +187,10 @@ func checkErr(err error, stderr io.Writer) int {
187187

188188
func cmdHost(stdout io.Writer, stderr io.Writer, s *state, hostname string) int {
189189
for _, res := range s.resources() {
190-
if hostname == res.Address() {
191-
return output(stdout, stderr, res.Attributes())
190+
if hostname == res.Hostname() {
191+
attributes := res.Attributes()
192+
attributes["ansible_host"] = res.Address()
193+
return output(stdout, stderr, attributes)
192194
}
193195
}
194196

parser_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,52 @@ package main
33
import (
44
"bytes"
55
"encoding/json"
6+
"os"
67
"strings"
78
"testing"
89

910
"github.com/stretchr/testify/assert"
1011
)
1112

13+
const exampleStateFileEnvHostname = `
14+
{
15+
"version": 1,
16+
"serial": 1,
17+
"modules": [
18+
{
19+
"resources": {
20+
"libvirt_domain.fourteen": {
21+
"type": "libvirt_domain",
22+
"primary": {
23+
"id": "824c29be-2164-44c8-83e0-787705571d95",
24+
"attributes": {
25+
"name": "fourteen",
26+
"network_interface.#": "1",
27+
"network_interface.0.addresses.#": "1",
28+
"network_interface.0.addresses.0": "192.168.102.14",
29+
"network_interface.0.mac": "96:EE:4D:BD:B2:45"
30+
}
31+
}
32+
}
33+
}
34+
}
35+
]
36+
}`
37+
38+
const expectedListOutputEnvHostname = `
39+
{
40+
"all": {
41+
"hosts": [
42+
"fourteen"
43+
],
44+
"vars": {
45+
}
46+
},
47+
"fourteen": ["fourteen"],
48+
"fourteen.0": ["fourteen"],
49+
"type_libvirt_domain": ["fourteen"]
50+
}`
51+
1252
const exampleStateFile = `
1353
{
1454
"version": 1,
@@ -633,6 +673,7 @@ olddatacenter="\u003c0.7_format"
633673

634674
const expectedHostOneOutput = `
635675
{
676+
"ansible_host": "10.0.0.1",
636677
"id":"i-aaaaaaaa",
637678
"private_ip":"10.0.0.1",
638679
"tags.#": "1",
@@ -665,6 +706,33 @@ func TestListCommand(t *testing.T) {
665706
assert.Equal(t, exp, act)
666707
}
667708

709+
func TestListCommandEnvHostname(t *testing.T) {
710+
var s state
711+
r := strings.NewReader(exampleStateFileEnvHostname)
712+
err := s.read(r)
713+
assert.NoError(t, err)
714+
715+
// Decode expectation as JSON
716+
var exp interface{}
717+
err = json.Unmarshal([]byte(expectedListOutputEnvHostname), &exp)
718+
assert.NoError(t, err)
719+
720+
// Run the command, capture the output
721+
var stdout, stderr bytes.Buffer
722+
os.Setenv("TF_HOSTNAME_KEY_NAME", "name")
723+
exitCode := cmdList(&stdout, &stderr, &s)
724+
os.Unsetenv("TF_HOSTNAME_KEY_NAME")
725+
assert.Equal(t, 0, exitCode)
726+
assert.Equal(t, "", stderr.String())
727+
728+
// Decode the output to compare
729+
var act interface{}
730+
err = json.Unmarshal([]byte(stdout.String()), &act)
731+
assert.NoError(t, err)
732+
733+
assert.Equal(t, exp, act)
734+
}
735+
668736
func TestHostCommand(t *testing.T) {
669737
var s state
670738
r := strings.NewReader(exampleStateFile)

resource.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,17 @@ func (r Resource) NameWithCounter() string {
164164
return fmt.Sprintf("%s.%d", r.baseName, r.counter)
165165
}
166166

167+
// Hostname returns the hostname of this resource.
168+
func (r Resource) Hostname() string {
169+
if keyName := os.Getenv("TF_HOSTNAME_KEY_NAME"); keyName != "" {
170+
if ip := r.State.Primary.Attributes[keyName]; ip != "" {
171+
return ip
172+
}
173+
}
174+
175+
return r.Address()
176+
}
177+
167178
// Address returns the IP address of this resource.
168179
func (r Resource) Address() string {
169180
if keyName := os.Getenv("TF_KEY_NAME"); keyName != "" {

0 commit comments

Comments
 (0)