forked from cloudradar-monitoring/cagent
/
system_profiler.go
160 lines (136 loc) · 4.36 KB
/
system_profiler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Package for parsing the XML output of system_profiler command output (available on OS X)
package hwinfo
import (
"fmt"
"io"
"strings"
"github.com/pkg/errors"
"howett.net/plist"
)
type spPCIDataTypeEntry struct {
Name string `plist:"_name"`
DeviceType string `plist:"sppci_device_type"`
SlotName string `plist:"sppci_slot_name"`
VendorID string `plist:"sppci_vendor-id"`
NameExtra string `plist:"sppci_name"`
}
const spPCIPrefix = "sppci_"
type spPCIDataType struct {
Items []spPCIDataTypeEntry `plist:"_items"`
}
type spUSBDataTypeEntry struct {
Items []spUSBDataTypeEntry `plist:"_items"`
Name string `plist:"_name"`
HostController string `plist:"host_controller"`
PCIDevice string `plist:"pci_device"`
LocationID string `plist:"location_id"`
ProductID string `plist:"product_id"`
VendorID string `plist:"vendor_id"`
Manufacturer string `plist:"manufacturer"`
}
type spUSBDataType struct {
Items []spUSBDataTypeEntry `plist:"_items"`
}
type spDisplayDataTypeEntry struct {
Name string `plist:"_name"`
ResolutionExtra string `plist:"_spdisplays_resolution"`
Resolution string `plist:"spdisplays_resolution"`
ConnectionType string `plist:"spdisplays_connection_type"`
DisplayType string `plist:"spdisplays_display_type"`
VendorID string `plist:"_spdisplays_display-vendor-id"`
}
const spDisplaysPrefix = "spdisplays_"
type spGraphicsCardDataTypeEntry struct {
Displays []spDisplayDataTypeEntry `plist:"spdisplays_ndrvs"`
}
type spDisplaysDataType struct {
GraphicCards []spGraphicsCardDataTypeEntry `plist:"_items"`
}
func parseOutputToListOfPCIDevices(r io.ReadSeeker) ([]*pciDeviceInfo, error) {
decoder := plist.NewDecoder(r)
var data []spPCIDataType
err := decoder.Decode(&data)
if err != nil {
return nil, err
}
if len(data) == 0 {
return nil, errors.New("unexpected XML input: no entries in plist of PCI devices")
}
result := make([]*pciDeviceInfo, 0)
for _, device := range data[0].Items {
pciInfo := &pciDeviceInfo{
Address: device.SlotName,
DeviceType: strings.TrimPrefix(device.DeviceType, spPCIPrefix),
VendorName: device.VendorID,
ProductName: device.Name,
Description: device.NameExtra,
}
result = append(result, pciInfo)
}
return result, nil
}
func parseOutputToListOfUSBDevices(r io.ReadSeeker) ([]*usbDeviceInfo, error) {
decoder := plist.NewDecoder(r)
var data []spUSBDataType
err := decoder.Decode(&data)
if err != nil {
return nil, err
}
if len(data) == 0 {
return nil, errors.New("unexpected XML input: no entries in plist of USB devices")
}
return getUSBInfoFromHierarchy(data[0].Items), nil
}
func getUSBInfoFromHierarchy(items []spUSBDataTypeEntry) []*usbDeviceInfo {
list := make([]*usbDeviceInfo, 0)
for _, item := range items {
vendorID := item.VendorID
if vendorID == "apple_vendor_id" {
vendorID = ""
}
vendorName := item.Manufacturer + " " + vendorID
address := item.LocationID + " " + item.PCIDevice
description := item.Name + " " + item.HostController
usbInfo := &usbDeviceInfo{
VendorName: strings.TrimSpace(vendorName),
Address: strings.TrimSpace(address),
Description: strings.TrimSpace(description),
DeviceID: item.ProductID,
}
list = append(list, usbInfo)
list = append(list, getUSBInfoFromHierarchy(item.Items)...)
}
return list
}
func parseOutputToListOfDisplays(r io.ReadSeeker) ([]*monitorInfo, error) {
decoder := plist.NewDecoder(r)
var data []spDisplaysDataType
err := decoder.Decode(&data)
if err != nil {
return nil, err
}
if len(data) == 0 {
return nil, errors.New("unexpected XML input: no entries in plist of monitors")
}
result := make([]*monitorInfo, 0)
for _, graphicsCard := range data[0].GraphicCards {
for _, display := range graphicsCard.Displays {
resolution := display.Resolution
if resolution == "" {
resolution = display.ResolutionExtra
}
displayType := strings.TrimPrefix(display.DisplayType, spDisplaysPrefix)
connectionType := strings.TrimPrefix(display.ConnectionType, spDisplaysPrefix)
description := fmt.Sprintf("Display Type: %s, Connection Type: %s", displayType, connectionType)
monitorInfo := &monitorInfo{
ID: display.Name,
Description: description,
VendorName: display.VendorID,
Size: "",
Resolution: resolution,
}
result = append(result, monitorInfo)
}
}
return result, nil
}