This commit is contained in:
9
.drone.sh
Normal file
9
.drone.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export now=$(TZ=Australia/Sydney date '+%Y%m%d-%H%M%S')
|
||||||
|
echo $now
|
||||||
|
echo "build commences"
|
||||||
|
go build -ldflags "-X main.sha1ver=`git rev-parse HEAD` -X main.buildTime=$now" -o ucs-exporter
|
||||||
|
echo "build complete"
|
||||||
|
sha256sum ucs-exporter > smt_checksum.txt
|
||||||
|
ls -lah
|
28
.drone.yml
Normal file
28
.drone.yml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: default
|
||||||
|
|
||||||
|
# Docs at https://docs.drone.io/pipeline/exec/overview/
|
||||||
|
# Also see https://github.com/harness/drone-cli/blob/master/.drone.yml
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: golang
|
||||||
|
commands:
|
||||||
|
- sh ./.drone.sh
|
||||||
|
|
||||||
|
- name: dell-deploy
|
||||||
|
# # https://github.com/cschlosser/drone-ftps/blob/master/README.md
|
||||||
|
image: cschlosser/drone-ftps
|
||||||
|
environment:
|
||||||
|
FTP_USERNAME:
|
||||||
|
from_secret: FTP_USERNAME
|
||||||
|
FTP_PASSWORD:
|
||||||
|
from_secret: FTP_PASSWORD
|
||||||
|
PLUGIN_HOSTNAME: ftp.emc.com:21
|
||||||
|
PLUGIN_SECURE: false
|
||||||
|
PLUGIN_VERIFY: false
|
||||||
|
PLUGIN_CHMOD: false
|
||||||
|
#PLUGIN_DEBUG: false
|
||||||
|
PLUGIN_INCLUDE: ^ucs-exporter$,^ucs-exporter_checksum.txt$
|
||||||
|
PLUGIN_EXCLUDE: ^\.git/$,^\cmd/$,^\internal/$
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
ucs-exporter
|
||||||
|
ucs-exporter.*
|
||||||
|
.env
|
||||||
|
*.pem
|
||||||
|
.DS_Store
|
@@ -3,13 +3,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/xml"
|
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"ucs-exporter/internal/exporters"
|
||||||
|
|
||||||
"github.com/dnaeon/go-ucs/api"
|
"github.com/dnaeon/go-ucs/api"
|
||||||
"github.com/dnaeon/go-ucs/mo"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@ func main() {
|
|||||||
vURL := flag.String("url", "", "The URL of a UCS Manager, eg https://server.domain.example/nuova")
|
vURL := flag.String("url", "", "The URL of a UCS Manager, eg https://server.domain.example/nuova")
|
||||||
vUser := flag.String("user", "ucspe", "The username to use when connecting to UCS Manager")
|
vUser := flag.String("user", "ucspe", "The username to use when connecting to UCS Manager")
|
||||||
vPass := flag.String("password", "ucspe", "The password to use when connecting to UCS Manager")
|
vPass := flag.String("password", "ucspe", "The password to use when connecting to UCS Manager")
|
||||||
|
listenPort := flag.String("listen-port", "9101", "The port to listen on for telemetry")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// The following example shows how to retrieve all compute blades.
|
// The following example shows how to retrieve all compute blades.
|
||||||
@@ -38,7 +39,7 @@ func main() {
|
|||||||
HttpClient: httpClient,
|
HttpClient: httpClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := api.NewClient(config)
|
ucsClient, err := api.NewClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to create API client: %s", err)
|
log.Fatalf("Unable to create API client: %s", err)
|
||||||
}
|
}
|
||||||
@@ -46,44 +47,20 @@ func main() {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
log.Printf("Logging in to %s\n", config.Endpoint)
|
log.Printf("Logging in to %s\n", config.Endpoint)
|
||||||
if _, err := client.AaaLogin(ctx); err != nil {
|
if _, err := ucsClient.AaaLogin(ctx); err != nil {
|
||||||
log.Fatalf("Unable to login: %s\n", err)
|
log.Fatalf("Unable to login: %s\n", err)
|
||||||
}
|
}
|
||||||
defer client.AaaLogout(ctx)
|
defer ucsClient.AaaLogout(ctx)
|
||||||
|
|
||||||
log.Printf("Got authentication cookie: %s\n", client.Cookie)
|
log.Printf("Got authentication cookie: %s\n", ucsClient.Cookie)
|
||||||
|
|
||||||
// The type into which we unmarshal the result data
|
// Register prometheus exporters
|
||||||
type blades struct {
|
exporter := exporters.NewUcsmTemperatureCollector(ucsClient, ctx)
|
||||||
XMLName xml.Name
|
prometheus.MustRegister(exporter)
|
||||||
Blades []mo.ComputeBlade `xml:"computeBlade"`
|
|
||||||
}
|
|
||||||
|
|
||||||
req := api.ConfigResolveClassRequest{
|
|
||||||
Cookie: client.Cookie,
|
|
||||||
ClassId: "computeBlade",
|
|
||||||
InHierarchical: "false",
|
|
||||||
}
|
|
||||||
|
|
||||||
var out blades
|
|
||||||
|
|
||||||
log.Println("Retrieving managed objects with class `computeBlade`")
|
|
||||||
if err := client.ConfigResolveClass(ctx, req, &out); err != nil {
|
|
||||||
log.Fatalf("Unable to retrieve `computeBlade` managed object: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("Retrieved %d compute blades\n", len(out.Blades))
|
|
||||||
for _, blade := range out.Blades {
|
|
||||||
log.Printf("%s:\n", blade.Dn)
|
|
||||||
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
|
||||||
log.Printf("\tTotal Memory: %d\n", blade.TotalMemory)
|
|
||||||
log.Printf("\tModel: %s\n", blade.Model)
|
|
||||||
log.Printf("\tVendor: %s\n", blade.Vendor)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start prometheus exporter
|
// Start prometheus exporter
|
||||||
http.Handle("/metrics", promhttp.Handler())
|
http.Handle("/metrics", promhttp.Handler())
|
||||||
|
|
||||||
// TODO - run this in a go routine to avoid blocking, as per cbs code
|
// TODO - run this in a go routine to avoid blocking, as per cbs code
|
||||||
log.Fatal(http.ListenAndServe(":9101", nil))
|
log.Fatal(http.ListenAndServe(*listenPort, nil))
|
||||||
}
|
}
|
106
internal/exporters/UcsmTemperatures.go
Normal file
106
internal/exporters/UcsmTemperatures.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package exporters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/xml"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/dnaeon/go-ucs/api"
|
||||||
|
"github.com/dnaeon/go-ucs/mo"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UcsmTemperaturesCollector struct {
|
||||||
|
ucsClient *api.Client
|
||||||
|
ctx context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUcsmTemperatureCollector(client *api.Client, ctx context.Context) *UcsmTemperaturesCollector {
|
||||||
|
return &UcsmTemperaturesCollector{
|
||||||
|
ucsClient: client,
|
||||||
|
ctx: ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describe prometheus describe
|
||||||
|
func (u *UcsmTemperaturesCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||||
|
log.Printf("Running Describe for UcsmTemperaturesCollector\n")
|
||||||
|
ch <- prometheus.NewDesc("ucsm_temperature_sensor",
|
||||||
|
"UCSM temperature sensor for motherboard/cpu/psu",
|
||||||
|
[]string{"server", "component", "description"}, nil,
|
||||||
|
)
|
||||||
|
ch <- prometheus.NewDesc("ucsm_temperature_sensor",
|
||||||
|
"UCSM temperature sensor for motherboard/cpu/psu",
|
||||||
|
[]string{"server", "component", "description"}, nil,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect prometheus collect
|
||||||
|
func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
|
||||||
|
// The type into which we unmarshal the result data
|
||||||
|
type blades struct {
|
||||||
|
XMLName xml.Name
|
||||||
|
Blades []mo.ComputeBlade `xml:"computeBlade"`
|
||||||
|
}
|
||||||
|
|
||||||
|
req := api.ConfigResolveClassRequest{
|
||||||
|
Cookie: u.ucsClient.Cookie,
|
||||||
|
ClassId: "computeBlade",
|
||||||
|
InHierarchical: "false",
|
||||||
|
}
|
||||||
|
|
||||||
|
var out blades
|
||||||
|
|
||||||
|
log.Println("Retrieving managed objects with class `computeBlade`")
|
||||||
|
if err := u.ucsClient.ConfigResolveClass(u.ctx, req, &out); err != nil {
|
||||||
|
log.Fatalf("Unable to retrieve `computeBlade` managed object: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Retrieved %d compute blades\n", len(out.Blades))
|
||||||
|
for _, blade := range out.Blades {
|
||||||
|
log.Printf("%s:\n", blade.Dn)
|
||||||
|
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
||||||
|
log.Printf("\tTotal Memory: %d\n", blade.TotalMemory)
|
||||||
|
log.Printf("\tModel: %s\n", blade.Model)
|
||||||
|
log.Printf("\tVendor: %s\n", blade.Vendor)
|
||||||
|
log.Printf("\tThermal: %s\n", blade.ComputeBoard.Thermal)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
logger = logging.getLogger("UcsmTemperatureSensorCollector")
|
||||||
|
|
||||||
|
class UcsmTemperatureSensorCollector(BaseCollector):
|
||||||
|
def get_metrics(self):
|
||||||
|
return {
|
||||||
|
"sensor": GaugeMetricFamily("ucsm_temperature_sensor",
|
||||||
|
"UCSM temperature sensor for motherboard/cpu/psu",
|
||||||
|
labels=['server', 'component',
|
||||||
|
'description'])
|
||||||
|
}
|
||||||
|
|
||||||
|
def collect_metrics(self, server, handle):
|
||||||
|
logger.debug("Collecting Metrics ")
|
||||||
|
g = self.get_metrics()['sensor']
|
||||||
|
|
||||||
|
mb_temp = handle.query_classid(NamingId.COMPUTE_MB_TEMP_STATS)
|
||||||
|
for temp in mb_temp:
|
||||||
|
value_rear = math.nan if temp.fm_temp_sen_rear == 'not-applicable' else temp.fm_temp_sen_rear
|
||||||
|
g.add_metric(labels=[server, temp.dn, "motherboard_rear_temperature"],
|
||||||
|
value=value_rear)
|
||||||
|
value_io = math.nan if temp.fm_temp_sen_io == 'not-applicable' else temp.fm_temp_sen_io
|
||||||
|
g.add_metric(labels=[server, temp.dn, "motherboard_front_temperature"],
|
||||||
|
value=value_io)
|
||||||
|
|
||||||
|
cpu_temp = handle.query_classid(NamingId.PROCESSOR_ENV_STATS)
|
||||||
|
for temp in cpu_temp:
|
||||||
|
g.add_metric(labels=[server, temp.dn, "cpu_temperature"],
|
||||||
|
value=temp.temperature)
|
||||||
|
|
||||||
|
psu_temp = handle.query_classid(NamingId.EQUIPMENT_PSU_STATS)
|
||||||
|
for temp in psu_temp:
|
||||||
|
g.add_metric(labels=[server, temp.dn, "psu_temperature"],
|
||||||
|
value=temp.ambient_temp)
|
||||||
|
yield g
|
||||||
|
*/
|
Reference in New Issue
Block a user