2015-02-06 22:31:59 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2016-09-22 06:13:26 +02:00
|
|
|
"sort"
|
2015-02-06 22:31:59 +01:00
|
|
|
)
|
|
|
|
|
2016-09-22 06:13:26 +02:00
|
|
|
type allGroup struct {
|
|
|
|
Hosts []string `json:"hosts"`
|
|
|
|
Vars map[string]interface{} `json:"vars"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func appendUniq(strs []string, item string) []string {
|
|
|
|
if len(strs) == 0 {
|
|
|
|
strs = append(strs, item)
|
|
|
|
return strs
|
|
|
|
}
|
|
|
|
sort.Strings(strs)
|
|
|
|
i := sort.SearchStrings(strs, item)
|
|
|
|
if i == len(strs) || (i < len(strs) && strs[i] != item) {
|
|
|
|
strs = append(strs, item)
|
|
|
|
}
|
|
|
|
return strs
|
|
|
|
}
|
|
|
|
|
2016-04-09 17:22:39 +02:00
|
|
|
func gatherResources(s *state) map[string]interface{} {
|
|
|
|
groups := make(map[string]interface{}, 0)
|
2017-01-19 03:24:46 +01:00
|
|
|
all_group := allGroup{Vars: make(map[string]interface{}), Hosts: make([]string, 0)}
|
2016-09-22 06:13:26 +02:00
|
|
|
groups["all"] = &all_group
|
|
|
|
|
2016-04-09 17:27:00 +02:00
|
|
|
for _, res := range s.resources() {
|
|
|
|
for _, grp := range res.Groups() {
|
2016-04-09 17:22:39 +02:00
|
|
|
|
2016-04-09 17:27:00 +02:00
|
|
|
_, ok := groups[grp]
|
|
|
|
if !ok {
|
|
|
|
groups[grp] = []string{}
|
|
|
|
}
|
2016-04-09 17:22:39 +02:00
|
|
|
|
2016-09-22 06:13:26 +02:00
|
|
|
groups[grp] = appendUniq(groups[grp].([]string), res.Address())
|
|
|
|
all_group.Hosts = appendUniq(all_group.Hosts, res.Address())
|
2016-04-09 17:27:00 +02:00
|
|
|
}
|
2015-02-06 22:31:59 +01:00
|
|
|
}
|
|
|
|
|
2016-04-09 17:27:00 +02:00
|
|
|
if len(s.outputs()) > 0 {
|
2016-02-18 11:46:40 +01:00
|
|
|
for _, out := range s.outputs() {
|
2016-09-22 06:13:26 +02:00
|
|
|
all_group.Vars[out.keyName] = out.value
|
2016-02-18 11:46:40 +01:00
|
|
|
}
|
2016-02-16 12:12:49 +01:00
|
|
|
}
|
2016-04-09 17:27:00 +02:00
|
|
|
return groups
|
2016-02-24 13:03:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func cmdList(stdout io.Writer, stderr io.Writer, s *state) int {
|
|
|
|
return output(stdout, stderr, gatherResources(s))
|
|
|
|
}
|
|
|
|
|
|
|
|
func cmdInventory(stdout io.Writer, stderr io.Writer, s *state) int {
|
2016-04-09 17:27:00 +02:00
|
|
|
groups := gatherResources(s)
|
|
|
|
for group, res := range groups {
|
|
|
|
|
2016-09-22 06:13:26 +02:00
|
|
|
switch grp := res.(type) {
|
|
|
|
case []string:
|
|
|
|
writeLn("["+group+"]", stdout, stderr)
|
|
|
|
for _, item := range grp {
|
|
|
|
writeLn(item, stdout, stderr)
|
|
|
|
}
|
2016-04-09 17:27:00 +02:00
|
|
|
|
2016-09-22 06:13:26 +02:00
|
|
|
case *allGroup:
|
|
|
|
writeLn("["+group+"]", stdout, stderr)
|
|
|
|
for _, item := range grp.Hosts {
|
|
|
|
writeLn(item, stdout, stderr)
|
|
|
|
}
|
|
|
|
writeLn("", stdout, stderr)
|
|
|
|
writeLn("["+group+":vars]", stdout, stderr)
|
|
|
|
for key, item := range grp.Vars {
|
|
|
|
writeLn(key+"="+item.(string), stdout, stderr)
|
2016-04-09 17:27:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-22 06:13:26 +02:00
|
|
|
writeLn("", stdout, stderr)
|
2016-04-09 17:27:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
2015-02-06 22:31:59 +01:00
|
|
|
}
|
|
|
|
|
2016-09-22 06:13:26 +02:00
|
|
|
func writeLn(str string, stdout io.Writer, stderr io.Writer) {
|
|
|
|
_, err := io.WriteString(stdout, str+"\n")
|
|
|
|
checkErr(err, stderr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkErr(err error, stderr io.Writer) int {
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintf(stderr, "Error writing inventory: %s\n", err)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2015-02-06 22:31:59 +01:00
|
|
|
func cmdHost(stdout io.Writer, stderr io.Writer, s *state, hostname string) int {
|
2015-12-10 04:54:19 +01:00
|
|
|
for _, res := range s.resources() {
|
2015-12-10 05:34:25 +01:00
|
|
|
if hostname == res.Address() {
|
2015-06-05 04:43:56 +02:00
|
|
|
return output(stdout, stderr, res.Attributes())
|
2015-02-06 22:31:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-04 17:56:13 +02:00
|
|
|
fmt.Fprintf(stdout, "{}")
|
2015-02-06 22:31:59 +01:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// output marshals an arbitrary JSON object and writes it to stdout, or writes
|
|
|
|
// an error to stderr, then returns the appropriate exit code.
|
|
|
|
func output(stdout io.Writer, stderr io.Writer, whatever interface{}) int {
|
|
|
|
b, err := json.Marshal(whatever)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintf(stderr, "Error encoding JSON: %s\n", err)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = stdout.Write(b)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintf(stderr, "Error writing JSON: %s\n", err)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|