1package command
2
3import (
4	"fmt"
5	"sort"
6
7	"github.com/hashicorp/nomad/api"
8	"github.com/mitchellh/cli"
9)
10
11func deviceQualifiedID(vendor, typ, name, id string) string {
12	p := vendor
13	if typ != "" {
14		p += "/" + typ
15	}
16	if name != "" {
17		p += "/" + name
18	}
19
20	return p + "[" + id + "]"
21}
22
23func buildDeviceStatsSummaryMap(deviceGroupStats []*api.DeviceGroupStats) map[string]*api.StatValue {
24	r := map[string]*api.StatValue{}
25
26	for _, dg := range deviceGroupStats {
27		for id, stats := range dg.InstanceStats {
28			k := deviceQualifiedID(dg.Vendor, dg.Type, dg.Name, id)
29			r[k] = stats.Summary
30		}
31	}
32
33	return r
34}
35
36func formatDeviceStats(qid string, stat *api.StatObject) []string {
37	attrs := []string{fmt.Sprintf("Device|%s", qid)}
38	formatDeviceStatsImpl(stat, "", &attrs)
39
40	sort.Strings(attrs[1:])
41
42	return attrs
43}
44
45func formatDeviceStatsImpl(stat *api.StatObject, keyPrefix string, result *[]string) {
46	if keyPrefix != "" {
47		keyPrefix = keyPrefix + "."
48	}
49
50	for n, stat := range stat.Attributes {
51		*result = append(*result, fmt.Sprintf("%s%s|%s", keyPrefix, n, stat))
52	}
53
54	for k, o := range stat.Nested {
55		formatDeviceStatsImpl(o, keyPrefix+k, result)
56	}
57}
58
59// getDeviceResourcesForNode returns a list of devices and their statistics summary
60// and tracks devices without statistics
61func getDeviceResourcesForNode(deviceGroupStats []*api.DeviceGroupStats, node *api.Node) []string {
62	statsSummaryMap := buildDeviceStatsSummaryMap(deviceGroupStats)
63
64	devices := []string{}
65	for _, dg := range node.NodeResources.Devices {
66		for _, inst := range dg.Instances {
67			id := deviceQualifiedID(dg.Vendor, dg.Type, dg.Name, inst.ID)
68			statStr := ""
69			if stats, ok := statsSummaryMap[id]; ok && stats != nil {
70				statStr = stats.String()
71			}
72
73			devices = append(devices, fmt.Sprintf("%v|%v", id, statStr))
74		}
75	}
76
77	sort.Strings(devices)
78
79	return devices
80}
81
82// getDeviceResources returns alist of devices and their statistics summary
83func getDeviceResources(deviceGroupStats []*api.DeviceGroupStats) []string {
84	statsSummaryMap := buildDeviceStatsSummaryMap(deviceGroupStats)
85
86	result := make([]string, 0, len(statsSummaryMap))
87	for id, stats := range statsSummaryMap {
88		result = append(result, id+"|"+stats.String())
89	}
90
91	sort.Strings(result)
92
93	return result
94}
95
96func printDeviceStats(ui cli.Ui, deviceGroupStats []*api.DeviceGroupStats) {
97	isFirst := true
98	for _, dg := range deviceGroupStats {
99		for id, dinst := range dg.InstanceStats {
100			if !isFirst {
101				ui.Output("")
102			}
103			isFirst = false
104
105			qid := deviceQualifiedID(dg.Vendor, dg.Type, dg.Name, id)
106			attrs := formatDeviceStats(qid, dinst.Stats)
107
108			ui.Output(formatKV(attrs))
109		}
110	}
111}
112
113func getDeviceAttributes(d *api.NodeDeviceResource) []string {
114	attrs := []string{fmt.Sprintf("Device Group|%s", d.ID())}
115
116	for k, v := range d.Attributes {
117		attrs = append(attrs, k+"|"+v.String())
118	}
119
120	sort.Strings(attrs[1:])
121
122	return attrs
123}
124