func Get() (Docker, error) { d := Docker{} if err := parse.Exists("docker"); err == nil { d.Installed = true } else { d.Installed = false d.Running = false return d, nil } o, err := parse.Exec("docker", []string{"--version"}) if err != nil { return Docker{}, err } v := strings.Fields(o) d.Version = strings.TrimRight(v[2], ",") d.Build = v[4] _, err2 := parse.Exec("docker", []string{"ps"}) if err2 != nil { d.Running = false } else { d.Running = true } return d, nil }
func Get() (Sensors, error) { // Create sdr dump, too speed up consequtive queries sdr := "/tmp/peekaboo.sdr" if _, err := os.Stat(sdr); os.IsNotExist(err) { _, err := parse.Exec("ipmitool", []string{"sdr", "dump", sdr}) if err != nil { return Sensors{}, err } } // Query for sdr (sensor data records) o, err := parse.Exec("ipmitool", []string{"sdr", "-S", sdr, "elist", "all"}) if err != nil { return Sensors{}, err } s := Sensors{} for _, line := range strings.Split(o, "\n") { a := strings.Split(line, "|") if len(a) < 5 { continue } s = append(s, Sensor{ Name: strings.TrimSpace(a[0]), ID: strings.TrimSpace(a[1]), Status: strings.TrimSpace(a[2]), Entity: strings.TrimSpace(a[3]), Value: strings.TrimSpace(a[4]), }) } return s, nil }
func Get() (IPMI, error) { i := IPMI{} // ipmitool if err := parse.Exists("ipmitool"); err == nil { i.IpmitoolInstalled = true o, err := parse.Exec("ipmitool", []string{"-V"}) if err != nil { return IPMI{}, err } arr := strings.Split(o, " ") i.IpmitoolVersion = arr[2] } else { i.IpmitoolInstalled = false return i, nil } o, err := parse.Exec("ipmitool", []string{"lan", "print", "1"}) if err == nil { for _, line := range strings.Split(o, "\n") { a := strings.SplitN(line, ":", 2) if len(a) < 2 { continue } k := strings.TrimSpace(a[0]) v := strings.TrimSpace(a[1]) switch k { case "IP Address Source": i.IPSource = &v case "IP Address": i.IPAddr = &v case "Subnet Mask": i.Netmask = &v case "MAC Address": i.HWAddr = &v case "Default Gateway IP": i.Gateway = &v } } } if i.IPAddr != nil { names, err := net.LookupAddr(*i.IPAddr) if err == nil { for i, v := range names { names[i] = strings.TrimRight(v, ".") } i.DNSNames = &names } } return i, nil }
func Get() (KernelCfgs, error) { kernel, err := parse.Exec("uname", []string{"-r"}) if err != nil { return KernelCfgs{}, err } fn := "/boot/config-" + kernel if _, err := os.Stat(fn); os.IsNotExist(err) { return KernelCfgs{}, fmt.Errorf("file doesn't exist: %s", fn) } o, err := ioutil.ReadFile(fn) if err != nil { return KernelCfgs{}, err } k := KernelCfgs{} for _, line := range strings.Split(string(o), "\n") { v := strings.Split(line, "=") if len(v) < 2 { continue } k = append(k, KernelCfg{ Key: v[0], Value: strings.Trim(v[1], "\""), }) } return k, nil }
func Get() (Containers, error) { cnts := Containers{} o, err := parse.Exec("docker", []string{"ps", "-a", "--no-trunc=true", "--format={{.ID}}!{{.Image}}!{{.Command}}!{{.CreatedAt}}!{{.RunningFor}}!{{.Ports}}!{{.Status}}!{{.Size}}!{{.Names}}!{{.Labels}}"}) if err != nil { return Containers{}, err } for _, line := range strings.Split(o, "\n") { v := strings.Split(line, "!") if len(v) < 10 { continue } c := Container{} c.ID = v[0] c.Image = v[1] c.Command = v[2] c.CreatedAt = v[3] c.RunningFor = v[4] c.Ports = v[5] c.Status = v[6] c.Size = v[7] c.Names = v[8] c.Labels = v[9] cnts = append(cnts, c) } return cnts, nil }
func Get() (Modules, error) { o, err := parse.Exec("lsmod", []string{}) if err != nil { return Modules{}, err } m := Modules{} first := true for _, line := range strings.Split(string(o), "\n") { a := strings.Fields(line) if len(a) < 3 || first == true { first = false continue } size, err := strconv.Atoi(strings.TrimSpace(a[1])) if err != nil { return Modules{}, err } usedBy := []string{} if len(a) > 3 { usedBy = strings.Split(strings.TrimSpace(a[3]), ",") } m = append(m, Module{ Module: strings.TrimSpace(a[0]), Size: size, UsedBy: usedBy, }) } return m, nil }
func Get() (RPMs, error) { o, err := parse.Exec("rpm", []string{"-qa", "--queryformat", "%{NAME}|%{VERSION}|%{RELEASE}|%{ARCH}|%{INSTALLTIME}\n"}) if err != nil { return RPMs{}, err } r := RPMs{} for _, line := range strings.Split(string(o), "\n") { v := strings.Split(line, "|") if len(v) < 5 { continue } sec, err := strconv.ParseInt(v[4], 10, 64) if err != nil { return RPMs{}, err } tm := time.Unix(int64(sec), 0) r = append(r, RPM{ Name: v[0], Version: v[1], Release: v[2], Arch: v[3], Installed: tm.Format("2006-01-02T15:04:05Z"), }) } return r, nil }
func Get() (OpSys, error) { o := OpSys{} m, err := parse.ExecRegexpMap("/usr/bin/sw_vers", []string{}, ":", "\\S+:\\s\\S+") if err != nil { return OpSys{}, err } o.Kernel = runtime.GOOS o.Product = m["ProductName"] o.ProductVersion = m["ProductVersion"] o.KernelVersion, err = parse.Exec("uname", []string{"-r"}) if err != nil { return OpSys{}, err } return o, nil }
func Get() (OpSys, error) { op := OpSys{} o, err := parse.ExecRegexpMap("lsb_release", []string{"-a"}, ":", "\\S+:\\s\\S+") if err != nil { return OpSys{}, err } op.Kernel = runtime.GOOS op.Product = o["Distributor ID"] op.ProductVersion = o["Release"] op.KernelVersion, err = parse.Exec("uname", []string{"-r"}) if err != nil { return OpSys{}, err } return op, nil }
func Get() (Images, error) { images := Images{} o, err := parse.Exec("docker", []string{"images", "--no-trunc=true"}) if err != nil { return nil, err } for c, line := range strings.Split(string(o), "\n") { re := regexp.MustCompile(`\s{2,}`) v := re.Split(line, -1) if c < 1 || len(v) < 5 { continue } i := Image{} if v[0] == "<none>" { i.Repo = "" } else { i.Repo = v[0] } if v[1] == "<none>" { i.Tag = "" } else { i.Tag = v[1] } i.ID = strings.TrimLeft(v[2], "sha256:") i.Created = v[3] i.VirtSize = v[4] images = append(images, i) } return images, nil }
func Get() (Sysctls, error) { sysctls := Sysctls{} o, err := parse.Exec("sysctl", []string{"-a"}) if err != nil { return Sysctls{}, err } for _, line := range strings.Split(o, "\n") { vals := strings.Fields(line) if len(vals) < 3 { continue } s := Sysctl{} s.Key = vals[0] s.Value = vals[2] sysctls = append(sysctls, s) } return sysctls, nil }
func Get() (Network, error) { n := Network{} // ethtool n.EthtoolInstalled = false if err := parse.Exists("ethtool"); err == nil { n.EthtoolInstalled = true o, err := parse.Exec("ethtool", []string{"--version"}) if err != nil { return Network{}, err } arr := strings.Split(o, " ") n.EthtoolVersion = arr[2] } // lldpctl n.LldpctlInstalled = false if err := parse.Exists("lldpctl"); err == nil { n.LldpctlInstalled = true o, err := parse.Exec("lldpctl", []string{"-v"}) if err != nil { return Network{}, err } n.LldpctlVersion = o } // onload n.OnloadInstalled = false if err := parse.Exists("onload"); err == nil { n.OnloadInstalled = true o, err := parse.Exec("onload", []string{"--version"}) if err != nil { return Network{}, err } for _, line := range strings.Split(o, "\n") { arr := strings.SplitN(line, " ", 2) if len(arr) < 2 { continue } key := strings.TrimSpace(arr[0]) val := strings.TrimSpace(arr[1]) switch key { case "OpenOnload": n.OnloadVersion = val } } } // sfctool n.SfctoolInstalled = false if err := parse.Exists("sfctool"); err == nil { n.SfctoolInstalled = true o, err := parse.Exec("sfctool", []string{"--version"}) if err != nil { return Network{}, err } arr := strings.Split(o, " ") n.SfctoolVersion = arr[2] } // sfckey n.SfkeyInstalled = false if err := parse.Exists("sfkey"); err == nil { n.SfkeyInstalled = true o, err := parse.Exec("sfkey", []string{"--version"}) if err != nil { return Network{}, err } for _, line := range strings.Split(o, "\n") { arr := strings.Split(line, ":") if len(arr) < 2 { continue } key := strings.TrimSpace(arr[0]) val := strings.TrimSpace(arr[1]) switch key { case "sfkey firmware update utility": n.SfkeyVersion = strings.TrimLeft(val, "v") } } } return n, nil }
// Get network interfaces. func Get() (Interfaces, error) { hasEthtool := false if err := parse.Exists("ethtool"); err == nil { hasEthtool = true } hasLldpctl := false if err := parse.Exists("lldpctl"); err == nil { hasLldpctl = true } hasSfctool := false if err := parse.Exists("sfctool"); err == nil { hasSfctool = true } rIntfs, err := net.Interfaces() if err != nil { return Interfaces{}, err } i := Interfaces{} for _, rIntf := range rIntfs { // Skip loopback interfaces if rIntf.Flags&net.FlagLoopback != 0 { continue } addrs, err := rIntf.Addrs() if err != nil { return Interfaces{}, err } wIntf := Interface{ Name: rIntf.Name, HWAddr: rIntf.HardwareAddr.String(), MTU: rIntf.MTU, } for _, addr := range addrs { wIntf.IPAddr = append(wIntf.IPAddr, addr.String()) } if rIntf.Flags&net.FlagUp != 0 { wIntf.Flags = append(wIntf.Flags, "UP") } if rIntf.Flags&net.FlagBroadcast != 0 { wIntf.Flags = append(wIntf.Flags, "BROADCAST") } if rIntf.Flags&net.FlagPointToPoint != 0 { wIntf.Flags = append(wIntf.Flags, "POINTTOPOINT") } if rIntf.Flags&net.FlagMulticast != 0 { wIntf.Flags = append(wIntf.Flags, "MULTICAST") } if runtime.GOOS == "linux" && hasEthtool == true { m, err := parse.ExecRegexpMap("ethtool", []string{"-i", rIntf.Name}, ":", "\\S+:\\s\\S+") // Do nothing on error if err == nil { s1 := m["driver"] wIntf.Driver = &s1 s2 := m["version"] wIntf.DriverVersion = &s2 s3 := m["firmware-version"] wIntf.FirmwareVersion = &s3 if strings.HasPrefix(m["bus-info"], "0000:") { s4 := m["bus-info"] wIntf.PCIBus = &s4 s5 := fmt.Sprintf("/pci/%v", m["bus-info"]) wIntf.PCIBusURL = &s5 } } } if runtime.GOOS == "linux" && hasEthtool == true { m, err := parse.ExecRegexpMap("ethtool", []string{rIntf.Name}, ":", "\\S+:\\s\\S+") // Do nothing on error if err == nil { i, err := strconv.Atoi(strings.TrimRight(m["Speed"], "Mb/s")) if err == nil { wIntf.SpeedMbs = &i } if wIntf.SpeedMbs != nil { s := m["Duplex"] wIntf.Duplex = &s } switch m["Link detected"] { case "yes": b := true wIntf.LinkDetected = &b case "no": b := false wIntf.LinkDetected = &b } } } if runtime.GOOS == "linux" && hasEthtool == true { m, err := parse.ExecRegexpMap("ethtool", []string{"-P", rIntf.Name}, ":[ ]", "\\S+:\\s([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})") // Do nothing on error if err == nil { bia := m["Permanent address"] wIntf.PermanentHWAddr = &bia } } if runtime.GOOS == "linux" && hasEthtool && wIntf.Driver != nil && *wIntf.Driver != "sfc" { o, err := parse.Exec("ethtool", []string{"-m", rIntf.Name, "raw", "on"}) // Do nothing on error, doesn't support getting Eeprom info if err == nil { s := hex.EncodeToString([]byte(o)) var b []byte var eeprom string = "" switch s[:2] { case "03": // SFP+ eeprom = s[0:] case "0d": // QSFP+ eeprom = s[256:768] } length := len(eeprom) if length >= 512 { ep := eeprom wIntf.TransceiverEeprom = &ep // Serial Number b, err = hex.DecodeString(eeprom[136:168]) if err == nil { sn := strings.Trim(string(b), " ") wIntf.TransceiverSN = &sn } // Vendor Name b, err = hex.DecodeString(eeprom[40:72]) if err == nil { vn := strings.Trim(string(b), " ") wIntf.TransceiverVN = &vn } // Product Name b, err = hex.DecodeString(eeprom[80:112]) if err == nil { pn := strings.Trim(string(b), " ") wIntf.TransceiverPN = &pn } // Arista specific QSFP-4xSFP sub-assembly if *wIntf.TransceiverVN == "Arista Networks" && strings.HasPrefix(*wIntf.TransceiverPN, "CAB-Q-S-") { b, err = hex.DecodeString(eeprom[240:242]) if err == nil { sa := int(b[0]) wIntf.TransceiverSA = &sa } } } } } if runtime.GOOS == "linux" && hasSfctool && wIntf.Driver != nil && *wIntf.Driver == "sfc" { o, err := parse.Exec("sfctool", []string{"-m", rIntf.Name, "raw", "on"}) // Do nothing on error, doesn't support getting Eeprom info if err == nil { s := hex.EncodeToString([]byte(o)) var b []byte var eeprom string = "" switch s[:2] { case "03": // SFP+ eeprom = s[0:512] case "0d": // QSFP+ eeprom = s[256:768] } length := len(eeprom) if length == 512 { ep := eeprom wIntf.TransceiverEeprom = &ep // Serial Number b, err = hex.DecodeString(eeprom[136:168]) if err == nil { sn := strings.Trim(string(b), " ") wIntf.TransceiverSN = &sn } // Vendor Name b, err = hex.DecodeString(eeprom[40:72]) if err == nil { vn := strings.Trim(string(b), " ") wIntf.TransceiverVN = &vn } // Product Name b, err = hex.DecodeString(eeprom[80:112]) if err == nil { pn := strings.Trim(string(b), " ") wIntf.TransceiverPN = &pn } // Arista specific QSFP-4xSFP sub-assembly if *wIntf.TransceiverVN == "Arista Networks" && strings.HasPrefix(*wIntf.TransceiverPN, "CAB-Q-S-") { b, err = hex.DecodeString(eeprom[240:242]) if err == nil { sa := int(b[0]) wIntf.TransceiverSA = &sa } } } } } if runtime.GOOS == "linux" && hasLldpctl == true { o, err := parse.Exec("lldpctl", []string{rIntf.Name}) // Do nothing on error if err == nil { for _, line := range strings.Split(o, "\n") { arr := strings.SplitN(line, ":", 2) if len(arr) < 2 { continue } key := strings.TrimSpace(arr[0]) val := strings.TrimSpace(arr[1]) switch key { case "ChassisID": wIntf.SwChassisID = &val case "SysName": wIntf.SwName = &val case "SysDescr": wIntf.SwDescr = &val case "PortID": wIntf.SwPortID = &val case "PortDescr": wIntf.SwPortDescr = &val case "VLAN": wIntf.SwVLAN = &val } } } } i = append(i, wIntf) } return i, nil }
func Get() (PCICards, error) { o, err := parse.Exec("lspci", []string{"-vmm", "-nn"}) if err != nil { return PCICards{}, err } p := PCICard{} list := PCICards{} first := true for _, line := range strings.Split(o, "\n") { if !first && line == "" { list = append(list, p) p = PCICard{} } arr := strings.SplitN(line, ":", 2) if len(arr) < 2 { continue } key := strings.TrimSpace(arr[0]) arr2 := strings.SplitN(arr[1], "[", 2) val := strings.TrimSpace(arr2[0]) id := "" if len(arr2) > 1 { id = strings.TrimRight(arr2[1], "]") } switch key { case "Slot": p.Slot = val first = false case "Class": p.Class = val p.ClassId = id case "Vendor": p.Vendor = val p.VendorId = id case "Device": p.Device = val p.DeviceId = id case "SVendor": if val != "" { p.SubVendor = &val p.SubVendorId = &id } case "SDevice": if val != "" { p.SubDevice = &val p.SubDeviceId = &id } case "Rev": if val != "" { p.Revision = &val } case "ProgIf": if val != "" { p.ProgIntf = &val } } } return list, nil }