1
1
mirror of https://github.com/adammck/terraform-inventory synced 2024-11-26 07:43:46 +01:00

Order output for resources with count (#77)

This commit is contained in:
Sami Hiltunen 2017-10-20 17:32:34 +02:00 committed by Adam Mckaig
parent 636eac273c
commit 2222e6477f
4 changed files with 95 additions and 42 deletions

100
cli.go

@ -4,9 +4,26 @@ import (
"encoding/json"
"fmt"
"io"
"os"
"sort"
)
type counterSorter struct {
resources []*Resource
}
func (cs counterSorter) Len() int {
return len(cs.resources)
}
func (cs counterSorter) Swap(i, j int) {
cs.resources[i], cs.resources[j] = cs.resources[j], cs.resources[i]
}
func (cs counterSorter) Less(i, j int) bool {
return cs.resources[i].counter < cs.resources[j].counter
}
type allGroup struct {
Hosts []string `json:"hosts"`
Vars map[string]interface{} `json:"vars"`
@ -26,29 +43,88 @@ func appendUniq(strs []string, item string) []string {
}
func gatherResources(s *state) map[string]interface{} {
groups := make(map[string]interface{}, 0)
all_group := allGroup{Vars: make(map[string]interface{}), Hosts: make([]string, 0)}
groups["all"] = &all_group
outputGroups := make(map[string]interface{})
all := &allGroup{Hosts: make([]string, 0), Vars: make(map[string]interface{})}
types := make(map[string][]string)
individual := make(map[string][]string)
ordered := make(map[string][]string)
tags := make(map[string][]string)
unsortedOrdered := make(map[string][]*Resource)
for _, res := range s.resources() {
for _, grp := range res.Groups() {
// place in list of all resources
all.Hosts = appendUniq(all.Hosts, res.Address())
_, ok := groups[grp]
if !ok {
groups[grp] = []string{}
// place in list of resource types
tp := fmt.Sprintf("type_%s", res.resourceType)
types[tp] = appendUniq(types[tp], res.Address())
unsortedOrdered[res.baseName] = append(unsortedOrdered[res.baseName], res)
// store as invdividual host (eg. <name>.<count>)
invdName := fmt.Sprintf("%s.%d", res.baseName, res.counter)
if old, exists := individual[invdName]; exists {
fmt.Fprintf(os.Stderr, "overwriting already existing individual key %s, old: %v, new: %v", invdName, old, res.Address())
}
individual[invdName] = []string{res.Address()}
// inventorize tags
for k, v := range res.Tags() {
// Valueless
tag := k
if v != "" {
tag = fmt.Sprintf("%s_%s", k, v)
}
groups[grp] = appendUniq(groups[grp].([]string), res.Address())
all_group.Hosts = appendUniq(all_group.Hosts, res.Address())
tags[tag] = appendUniq(tags[tag], res.Address())
}
}
// inventorize outputs as variables
if len(s.outputs()) > 0 {
for _, out := range s.outputs() {
all_group.Vars[out.keyName] = out.value
all.Vars[out.keyName] = out.value
}
}
return groups
// sort the ordered groups
for basename, resources := range unsortedOrdered {
cs := counterSorter{resources}
sort.Sort(cs)
for i := range resources {
ordered[basename] = append(ordered[basename], resources[i].Address())
}
}
outputGroups["all"] = all
for k, v := range individual {
if old, exists := outputGroups[k]; exists {
fmt.Fprintf(os.Stderr, "individual overwriting already existing output with key %s, old: %v, new: %v", k, old, v)
}
outputGroups[k] = v
}
for k, v := range ordered {
if old, exists := outputGroups[k]; exists {
fmt.Fprintf(os.Stderr, "ordered overwriting already existing output with key %s, old: %v, new: %v", k, old, v)
}
outputGroups[k] = v
}
for k, v := range types {
if old, exists := outputGroups[k]; exists {
fmt.Fprintf(os.Stderr, "types overwriting already existing output key %s, old: %v, new: %v", k, old, v)
}
outputGroups[k] = v
}
for k, v := range tags {
if old, exists := outputGroups[k]; exists {
fmt.Fprintf(os.Stderr, "tags overwriting already existing output key %s, old: %v, new: %v", k, old, v)
}
outputGroups[k] = v
}
return outputGroups
}
func cmdList(stdout io.Writer, stderr io.Writer, s *state) int {

@ -4,11 +4,12 @@ import (
"bytes"
"flag"
"fmt"
"github.com/adammck/venv"
"github.com/blang/vfs"
"os"
"os/exec"
"path/filepath"
"github.com/adammck/venv"
"github.com/blang/vfs"
)
var version = flag.Bool("version", false, "print version information and exit")

@ -276,9 +276,9 @@ const expectedListOutput = `
"10.0.1.1",
"10.120.0.226",
"10.2.1.5",
"10.20.30.40",
"192.168.0.3",
"50.0.0.1"
"50.0.0.1",
"10.20.30.40"
],
"vars": {
"datacenter": "mydc",
@ -341,9 +341,9 @@ const expectedInventoryOutput = `[all]
10.0.1.1
10.120.0.226
10.2.1.5
10.20.30.40
192.168.0.3
50.0.0.1
10.20.30.40
[all:vars]
datacenter="mydc"

@ -87,30 +87,6 @@ func (r Resource) IsSupported() bool {
return r.Address() != ""
}
// Groups returns the list of Ansible groups which this resource should be
// included in.
func (r Resource) Groups() []string {
groups := []string{
r.baseName,
r.NameWithCounter(),
fmt.Sprintf("type_%s", r.resourceType),
}
for k, v := range r.Tags() {
// Valueless
if v == "" {
g := k
groups = append(groups, g)
// Key-value
} else {
g := fmt.Sprintf("%s_%s", k, v)
groups = append(groups, g)
}
}
return groups
}
// Tags returns a map of arbitrary key/value pairs explicitly associated with
// the resource. Different providers have different mechanisms for attaching
// these.
@ -159,7 +135,7 @@ func (r Resource) Tags() map[string]string {
t[vv] = ""
}
}
case "triton_machine":
case "triton_machine":
for k, v := range r.Attributes() {
parts := strings.SplitN(k, ".", 2)
if len(parts) == 2 && parts[0] == "tags" && parts[1] != "%" {