diff --git a/plugins/inputs/redfish/README.md b/plugins/inputs/redfish/README.md index 87f3443a5..0f3120435 100644 --- a/plugins/inputs/redfish/README.md +++ b/plugins/inputs/redfish/README.md @@ -31,6 +31,13 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. ## System Id to collect data for in Redfish APIs. computer_system_id="System.Embedded.1" + ## Tag sets allow you to include redfish OData link parent data + ## For Example. + ## Thermal data is an OData link with parent Chassis which has a link of Location. + ## For more info see the Redfish Resource and Schema Guide at DMTFs website. + ## Available sets are: "chassis.location" and "chassis" + # include_tag_sets = ["chassis.location"] + ## Amount of time allowed to complete the HTTP request # timeout = "5s" @@ -50,10 +57,6 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - member_id - address - name - - datacenter (available only if location data is found) - - rack (available only if location data is found) - - room (available only if location data is found) - - row (available only if location data is found) - state - health - fields: @@ -69,10 +72,6 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - member_id - address - name - - datacenter (available only if location data is found) - - rack (available only if location data is found) - - room (available only if location data is found) - - row (available only if location data is found) - state - health - fields: @@ -85,13 +84,9 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - redfish_power_powersupplies - tags: - source - - address - member_id + - address - name - - datacenter (available only if location data is found) - - rack (available only if location data is found) - - room (available only if location data is found) - - row (available only if location data is found) - state - health - fields: @@ -104,13 +99,9 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - redfish_power_voltages (available only if voltage data is found) - tags: - source - - address - member_id + - address - name - - datacenter (available only if location data is found) - - rack (available only if location data is found) - - room (available only if location data is found) - - row (available only if location data is found) - state - health - fields: @@ -120,20 +111,39 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - lower_threshold_critical - lower_threshold_fatal +## Tag Sets + +- chassis.location + - tags: + - datacenter (available only if location data is found) + - rack (available only if location data is found) + - room (available only if location data is found) + - row (available only if location data is found) + +- chassis + - tags: + - chassis_chassistype + - chassis_manufacturer + - chassis_model + - chassis_partnumber + - chassis_powerstate + - chassis_sku + - chassis_serialnumber + - chassis_state + - chassis_health + ## Example Output ```text -redfish_thermal_temperatures,source=test-hostname,name=CPU1,address=http://190.0.0.1,member_id="0"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_celsius=41,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_thermal_temperatures,source=test-hostname,name=CPU2,address=http://190.0.0.1,member_id="1"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_celsius=51,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_thermal_temperatures,source=test-hostname,name=SystemBoardInlet,address=http://190.0.0.1,member_id="2"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_celsius=23,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_thermal_temperatures,source=test-hostname,name=SystemBoardExhaust,address=http://190.0.0.1,member_id="3"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_celsius=33,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_thermal_fans,source=test-hostname,name=SystemBoardFan1A,address=http://190.0.0.1,member_id="0"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_rpm=17720,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_thermal_fans,source=test-hostname,name=SystemBoardFan1B,address=http://190.0.0.1,member_id="1"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_rpm=17760,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_thermal_fans,source=test-hostname,name=SystemBoardFan2A,address=http://190.0.0.1,member_id="2"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_rpm=17880,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_power_powersupplies,source=test-hostname,name=PS1Status,address=http://190.0.0.1,member_id="0"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" power_capacity_watts=750,power_input_watts=900,power_output_watts=208,last_power_output_watts=98,line_input_reading_volts=204 1582114112000000000 -redfish_power_powersupplies,source=test-hostname,name=PS2Status,address=http://190.0.0.1,member_id="1",datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" power_capacity_watts=750,power_input_watts=900,power_output_watts=194,last_power_output_watts=98,line_input_reading_volts=204 1582114112000000000 -redfish_power_voltages,source=test-hostname,name=CPU1MEM345,address=http://190.0.0.1,member_id="0"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_volts=1,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_power_voltages,source=test-hostname,name=CPU1MEM345,address=http://190.0.0.1,member_id="1"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_volts=1,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_power_voltages,source=test-hostname,name=CPU1MEM347,address=http://190.0.0.1,member_id="2"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_volts=1,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 -redfish_power_voltages,source=test-hostname,name=PS1voltage1,address=http://190.0.0.1,member_id="12"datacenter="Tampa",health="OK",rack="12",room="tbc",row="3",state="Enabled" reading_volts=208,upper_threshold_critical=59,upper_threshold_fatal=64 1582114112000000000 +redfish_thermal_temperatures,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=OK,member_id=0,name=CPU1\ Temp,rack=WEB43,row=North,source=web483,state=Enabled reading_celsius=41,upper_threshold_critical=45,upper_threshold_fatal=48 1691270160000000000 +redfish_thermal_temperatures,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,member_id=1,name=CPU2\ Temp,rack=WEB43,row=North,source=web483,state=Disabled upper_threshold_critical=45,upper_threshold_fatal=48 1691270160000000000 +redfish_thermal_temperatures,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=OK,member_id=2,name=Chassis\ Intake\ Temp,rack=WEB43,row=North,source=web483,state=Enabled upper_threshold_critical=40,upper_threshold_fatal=50,lower_threshold_critical=5,lower_threshold_fatal=0,reading_celsius=25 1691270160000000000 +redfish_thermal_fans,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=OK,member_id=0,name=BaseBoard\ System\ Fan,rack=WEB43,row=North,source=web483,state=Enabled lower_threshold_fatal=0i,reading_rpm=2100i 1691270160000000000 +redfish_thermal_fans,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=OK,member_id=1,name=BaseBoard\ System\ Fan\ Backup,rack=WEB43,row=North,source=web483,state=Enabled lower_threshold_fatal=0i,reading_rpm=2050i 1691270160000000000 +redfish_power_powersupplies,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=Warning,member_id=0,name=Power\ Supply\ Bay,rack=WEB43,row=North,source=web483,state=Enabled line_input_voltage=120,last_power_output_watts=325,power_capacity_watts=800 1691270160000000000 +redfish_power_voltages,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=OK,member_id=0,name=VRM1\ Voltage,rack=WEB43,row=North,source=web483,state=Enabled upper_threshold_fatal=15,lower_threshold_critical=11,lower_threshold_fatal=10,reading_volts=12,upper_threshold_critical=13 1691270160000000000 +redfish_power_voltages,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=OK,member_id=1,name=VRM2\ Voltage,rack=WEB43,row=North,source=web483,state=Enabled reading_volts=5,upper_threshold_critical=7,lower_threshold_critical=4.5 1691270160000000000 +redfish_thermal_temperatures,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=OK,member_id=0,name=CPU1\ Temp,rack=WEB43,row=North,source=web483,state=Enabled upper_threshold_critical=45,upper_threshold_fatal=48,reading_celsius=41 1691270170000000000 +redfish_thermal_temperatures,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,member_id=1,name=CPU2\ Temp,rack=WEB43,row=North,source=web483,state=Disabled upper_threshold_critical=45,upper_threshold_fatal=48 1691270170000000000 +redfish_thermal_temperatures,address=127.0.0.1,chassis_chassistype=RackMount,chassis_health=OK,chassis_manufacturer=Contoso,chassis_model=3500RX,chassis_partnumber=224071-J23,chassis_powerstate=On,chassis_serialnumber=437XR1138R2,chassis_sku=8675309,chassis_state=Enabled,health=OK,member_id=2,name=Chassis\ Intake\ Temp,rack=WEB43,row=North,source=web483,state=Enabled lower_threshold_critical=5,lower_threshold_fatal=0,reading_celsius=25,upper_threshold_critical=40,upper_threshold_fatal=50 1691270170000000000 ``` diff --git a/plugins/inputs/redfish/redfish.go b/plugins/inputs/redfish/redfish.go index 826732200..b2af61f13 100644 --- a/plugins/inputs/redfish/redfish.go +++ b/plugins/inputs/redfish/redfish.go @@ -26,13 +26,21 @@ type Redfish struct { Username string `toml:"username"` Password string `toml:"password"` ComputerSystemID string `toml:"computer_system_id"` + IncludeTagSets []string `toml:"include_tag_sets"` Timeout config.Duration `toml:"timeout"` + tagSet map[string]bool client http.Client tls.ClientConfig baseURL *url.URL } +const ( + // tag sets used for including redfish OData link parent data + tagSetChassisLocation = "chassis.location" + tagSetChassis = "chassis" +) + type System struct { Hostname string `json:"hostname"` Links struct { @@ -43,11 +51,19 @@ type System struct { } type Chassis struct { - Location *Location - Power struct { + ChassisType string + Location *Location + Manufacturer string + Model string + PartNumber string + Power struct { Ref string `json:"@odata.id"` } - Thermal struct { + PowerState string + SKU string + SerialNumber string + Status Status + Thermal struct { Ref string `json:"@odata.id"` } } @@ -147,6 +163,11 @@ func (r *Redfish) Init() error { return fmt.Errorf("did not provide the computer system ID of the resource") } + r.tagSet = make(map[string]bool, len(r.IncludeTagSets)) + for _, setLabel := range r.IncludeTagSets { + r.tagSet[setLabel] = true + } + var err error r.baseURL, err = url.Parse(r.Address) if err != nil { @@ -245,6 +266,18 @@ func (r *Redfish) getThermal(ref string) (*Thermal, error) { return thermal, nil } +func setChassisTags(chassis *Chassis, tags map[string]string) { + tags["chassis_chassistype"] = chassis.ChassisType + tags["chassis_manufacturer"] = chassis.Manufacturer + tags["chassis_model"] = chassis.Model + tags["chassis_partnumber"] = chassis.PartNumber + tags["chassis_powerstate"] = chassis.PowerState + tags["chassis_sku"] = chassis.SKU + tags["chassis_serialnumber"] = chassis.SerialNumber + tags["chassis_state"] = chassis.Status.State + tags["chassis_health"] = chassis.Status.Health +} + func (r *Redfish) Gather(acc telegraf.Accumulator) error { address, _, err := net.SplitHostPort(r.baseURL.Host) if err != nil { @@ -275,12 +308,15 @@ func (r *Redfish) Gather(acc telegraf.Accumulator) error { tags["source"] = system.Hostname tags["state"] = j.Status.State tags["health"] = j.Status.Health - if chassis.Location != nil { + if _, ok := r.tagSet[tagSetChassisLocation]; ok && chassis.Location != nil { tags["datacenter"] = chassis.Location.PostalAddress.DataCenter tags["room"] = chassis.Location.PostalAddress.Room tags["rack"] = chassis.Location.Placement.Rack tags["row"] = chassis.Location.Placement.Row } + if _, ok := r.tagSet[tagSetChassis]; ok { + setChassisTags(chassis, tags) + } fields := make(map[string]interface{}) fields["reading_celsius"] = j.ReadingCelsius @@ -300,12 +336,15 @@ func (r *Redfish) Gather(acc telegraf.Accumulator) error { tags["source"] = system.Hostname tags["state"] = j.Status.State tags["health"] = j.Status.Health - if chassis.Location != nil { + if _, ok := r.tagSet[tagSetChassisLocation]; ok && chassis.Location != nil { tags["datacenter"] = chassis.Location.PostalAddress.DataCenter tags["room"] = chassis.Location.PostalAddress.Room tags["rack"] = chassis.Location.Placement.Rack tags["row"] = chassis.Location.Placement.Row } + if _, ok := r.tagSet[tagSetChassis]; ok { + setChassisTags(chassis, tags) + } if j.ReadingUnits != nil && *j.ReadingUnits == "RPM" { fields["upper_threshold_critical"] = j.UpperThresholdCritical @@ -331,12 +370,15 @@ func (r *Redfish) Gather(acc telegraf.Accumulator) error { "name": j.Name, "source": system.Hostname, } - if chassis.Location != nil { + if _, ok := r.tagSet[tagSetChassisLocation]; ok && chassis.Location != nil { tags["datacenter"] = chassis.Location.PostalAddress.DataCenter tags["room"] = chassis.Location.PostalAddress.Room tags["rack"] = chassis.Location.Placement.Rack tags["row"] = chassis.Location.Placement.Row } + if _, ok := r.tagSet[tagSetChassis]; ok { + setChassisTags(chassis, tags) + } fields := map[string]interface{}{ "power_allocated_watts": j.PowerAllocatedWatts, @@ -361,12 +403,15 @@ func (r *Redfish) Gather(acc telegraf.Accumulator) error { tags["source"] = system.Hostname tags["state"] = j.Status.State tags["health"] = j.Status.Health - if chassis.Location != nil { + if _, ok := r.tagSet[tagSetChassisLocation]; ok && chassis.Location != nil { tags["datacenter"] = chassis.Location.PostalAddress.DataCenter tags["room"] = chassis.Location.PostalAddress.Room tags["rack"] = chassis.Location.Placement.Rack tags["row"] = chassis.Location.Placement.Row } + if _, ok := r.tagSet[tagSetChassis]; ok { + setChassisTags(chassis, tags) + } fields := make(map[string]interface{}) fields["power_input_watts"] = j.PowerInputWatts @@ -385,12 +430,15 @@ func (r *Redfish) Gather(acc telegraf.Accumulator) error { tags["source"] = system.Hostname tags["state"] = j.Status.State tags["health"] = j.Status.Health - if chassis.Location != nil { + if _, ok := r.tagSet[tagSetChassisLocation]; ok && chassis.Location != nil { tags["datacenter"] = chassis.Location.PostalAddress.DataCenter tags["room"] = chassis.Location.PostalAddress.Room tags["rack"] = chassis.Location.Placement.Rack tags["row"] = chassis.Location.Placement.Row } + if _, ok := r.tagSet[tagSetChassis]; ok { + setChassisTags(chassis, tags) + } fields := make(map[string]interface{}) fields["reading_volts"] = j.ReadingVolts @@ -407,6 +455,9 @@ func (r *Redfish) Gather(acc telegraf.Accumulator) error { func init() { inputs.Add("redfish", func() telegraf.Input { - return &Redfish{} + return &Redfish{ + // default tag set of chassis.location required for backwards compatibility + IncludeTagSets: []string{tagSetChassisLocation}, + } }) } diff --git a/plugins/inputs/redfish/redfish_test.go b/plugins/inputs/redfish/redfish_test.go index ebf3b24b2..099cd720f 100644 --- a/plugins/inputs/redfish/redfish_test.go +++ b/plugins/inputs/redfish/redfish_test.go @@ -46,16 +46,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_temperatures", map[string]string{ - "name": "CPU1 Temp", - "member_id": "iDRAC.Embedded.1#CPU1Temp", - "source": "tpa-hostname", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "name": "CPU1 Temp", + "member_id": "iDRAC.Embedded.1#CPU1Temp", + "source": "tpa-hostname", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 3.0, @@ -69,16 +65,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan1A", - "member_id": "0x17||Fan.Embedded.1A", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan1A", + "member_id": "0x17||Fan.Embedded.1A", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "reading_rpm": 17760, @@ -90,16 +82,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan1B", - "member_id": "0x17||Fan.Embedded.1B", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan1B", + "member_id": "0x17||Fan.Embedded.1B", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -111,16 +99,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan2A", - "member_id": "0x17||Fan.Embedded.2A", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan2A", + "member_id": "0x17||Fan.Embedded.2A", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -132,16 +116,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan2B", - "member_id": "0x17||Fan.Embedded.2B", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan2B", + "member_id": "0x17||Fan.Embedded.2B", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -153,16 +133,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan3A", - "member_id": "0x17||Fan.Embedded.3A", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan3A", + "member_id": "0x17||Fan.Embedded.3A", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -174,16 +150,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan3B", - "member_id": "0x17||Fan.Embedded.3B", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan3B", + "member_id": "0x17||Fan.Embedded.3B", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -195,16 +167,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan4A", - "member_id": "0x17||Fan.Embedded.4A", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan4A", + "member_id": "0x17||Fan.Embedded.4A", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -216,16 +184,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan4B", - "member_id": "0x17||Fan.Embedded.4B", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan4B", + "member_id": "0x17||Fan.Embedded.4B", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -237,16 +201,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan5A", - "member_id": "0x17||Fan.Embedded.5A", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan5A", + "member_id": "0x17||Fan.Embedded.5A", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -258,16 +218,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan5B", - "member_id": "0x17||Fan.Embedded.5B", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan5B", + "member_id": "0x17||Fan.Embedded.5B", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -279,16 +235,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan6A", - "member_id": "0x17||Fan.Embedded.6A", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan6A", + "member_id": "0x17||Fan.Embedded.6A", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -300,16 +252,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan6B", - "member_id": "0x17||Fan.Embedded.6B", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan6B", + "member_id": "0x17||Fan.Embedded.6B", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -321,16 +269,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan7A", - "member_id": "0x17||Fan.Embedded.7A", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan7A", + "member_id": "0x17||Fan.Embedded.7A", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -342,16 +286,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan7B", - "member_id": "0x17||Fan.Embedded.7B", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan7B", + "member_id": "0x17||Fan.Embedded.7B", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -363,16 +303,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan8A", - "member_id": "0x17||Fan.Embedded.8A", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan8A", + "member_id": "0x17||Fan.Embedded.8A", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -384,16 +320,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_thermal_fans", map[string]string{ - "source": "tpa-hostname", - "name": "System Board Fan8B", - "member_id": "0x17||Fan.Embedded.8B", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board Fan8B", + "member_id": "0x17||Fan.Embedded.8B", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "lower_threshold_critical": 600, @@ -405,14 +337,10 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_power_powercontrol", map[string]string{ - "source": "tpa-hostname", - "name": "System Power Control", - "member_id": "PowerControl", - "address": address, - "datacenter": "", - "rack": "", - "room": "", - "row": "", + "source": "tpa-hostname", + "name": "System Power Control", + "member_id": "PowerControl", + "address": address, }, map[string]interface{}{ "average_consumed_watts": 426.0, @@ -430,16 +358,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_power_powersupplies", map[string]string{ - "source": "tpa-hostname", - "name": "PS1 Status", - "member_id": "PSU.Slot.1", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "PS1 Status", + "member_id": "PSU.Slot.1", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "power_capacity_watts": 750.00, @@ -452,16 +376,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_power_voltages", map[string]string{ - "source": "tpa-hostname", - "name": "System Board DIMM PG", - "member_id": "iDRAC.Embedded.1#SystemBoardDIMMPG", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board DIMM PG", + "member_id": "iDRAC.Embedded.1#SystemBoardDIMMPG", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "reading_volts": 1.0, @@ -471,16 +391,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_power_voltages", map[string]string{ - "source": "tpa-hostname", - "name": "System Board NDC PG", - "member_id": "iDRAC.Embedded.1#SystemBoardNDCPG", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board NDC PG", + "member_id": "iDRAC.Embedded.1#SystemBoardNDCPG", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "reading_volts": 1.0, @@ -491,16 +407,12 @@ func TestDellApis(t *testing.T) { testutil.MustMetric( "redfish_power_voltages", map[string]string{ - "source": "tpa-hostname", - "name": "System Board PS1 PG FAIL", - "member_id": "iDRAC.Embedded.1#SystemBoardPS1PGFAIL", - "address": address, - "datacenter": "", - "health": "OK", - "rack": "", - "room": "", - "row": "", - "state": "Enabled", + "source": "tpa-hostname", + "name": "System Board PS1 PG FAIL", + "member_id": "iDRAC.Embedded.1#SystemBoardPS1PGFAIL", + "address": address, + "health": "OK", + "state": "Enabled", }, map[string]interface{}{ "reading_volts": 1.0, @@ -912,3 +824,286 @@ func TestInvalidHPJSON(t *testing.T) { }) } } + +func TestIncludeTagSetsConfiguration(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !checkAuth(r, "test", "test") { + http.Error(w, "Unauthorized.", 401) + return + } + + switch r.URL.Path { + case "/redfish/v1/Chassis/1/Thermal": + http.ServeFile(w, r, "testdata/hp_thermal.json") + case "/redfish/v1/Chassis/1/Power": + http.ServeFile(w, r, "testdata/hp_power.json") + case "/redfish/v1/Systems/1": + http.ServeFile(w, r, "testdata/hp_systems.json") + case "/redfish/v1/Chassis/1/": + http.ServeFile(w, r, "testdata/hp_chassis.json") + default: + w.WriteHeader(http.StatusNotFound) + } + })) + + defer ts.Close() + + u, err := url.Parse(ts.URL) + require.NoError(t, err) + address, _, err := net.SplitHostPort(u.Host) + require.NoError(t, err) + + expectedMetricsHp := []telegraf.Metric{ + testutil.MustMetric( + "redfish_thermal_temperatures", + map[string]string{ + "name": "01-Inlet Ambient", + "member_id": "0", + "source": "tpa-hostname", + "address": address, + "health": "OK", + "state": "Enabled", + "rack": "", + "room": "", + "row": "", + "datacenter": "", + "chassis_chassistype": "RackMount", + "chassis_manufacturer": "HP", + "chassis_model": "Proliant Gen10", + "chassis_partnumber": "CT6NWPYZ", + "chassis_powerstate": "On", + "chassis_sku": "CLFYTTWP", + "chassis_serialnumber": "QWEVC007C99803", + "chassis_state": "Enabled", + "chassis_health": "OK", + }, + map[string]interface{}{ + "reading_celsius": 19.0, + "upper_threshold_critical": 42.0, + "upper_threshold_fatal": 47.0, + }, + time.Unix(0, 0), + ), + testutil.MustMetric( + "redfish_thermal_temperatures", + map[string]string{ + "name": "44-P/S 2 Zone", + "source": "tpa-hostname", + "member_id": "42", + "address": address, + "health": "OK", + "state": "Enabled", + "rack": "", + "room": "", + "row": "", + "datacenter": "", + "chassis_chassistype": "RackMount", + "chassis_manufacturer": "HP", + "chassis_model": "Proliant Gen10", + "chassis_partnumber": "CT6NWPYZ", + "chassis_powerstate": "On", + "chassis_sku": "CLFYTTWP", + "chassis_serialnumber": "QWEVC007C99803", + "chassis_state": "Enabled", + "chassis_health": "OK", + }, + map[string]interface{}{ + "reading_celsius": 34.0, + "upper_threshold_critical": 75.0, + "upper_threshold_fatal": 80.0, + }, + time.Unix(0, 0), + ), + testutil.MustMetric( + "redfish_thermal_fans", + map[string]string{ + "source": "tpa-hostname", + "name": "Fan 1", + "member_id": "0", + "address": address, + "health": "OK", + "state": "Enabled", + "rack": "", + "room": "", + "row": "", + "datacenter": "", + "chassis_chassistype": "RackMount", + "chassis_manufacturer": "HP", + "chassis_model": "Proliant Gen10", + "chassis_partnumber": "CT6NWPYZ", + "chassis_powerstate": "On", + "chassis_sku": "CLFYTTWP", + "chassis_serialnumber": "QWEVC007C99803", + "chassis_state": "Enabled", + "chassis_health": "OK", + }, + map[string]interface{}{ + "reading_percent": 23, + }, + time.Unix(0, 0), + ), + testutil.MustMetric( + "redfish_thermal_fans", + map[string]string{ + "source": "tpa-hostname", + "name": "Fan 2", + "member_id": "1", + "address": address, + "health": "OK", + "state": "Enabled", + "rack": "", + "room": "", + "row": "", + "datacenter": "", + "chassis_chassistype": "RackMount", + "chassis_manufacturer": "HP", + "chassis_model": "Proliant Gen10", + "chassis_partnumber": "CT6NWPYZ", + "chassis_powerstate": "On", + "chassis_sku": "CLFYTTWP", + "chassis_serialnumber": "QWEVC007C99803", + "chassis_state": "Enabled", + "chassis_health": "OK", + }, + map[string]interface{}{ + "reading_percent": 23, + }, + time.Unix(0, 0), + ), + testutil.MustMetric( + "redfish_thermal_fans", + map[string]string{ + "source": "tpa-hostname", + "name": "Fan 3", + "member_id": "2", + "address": address, + "health": "OK", + "state": "Enabled", + "rack": "", + "room": "", + "row": "", + "datacenter": "", + "chassis_chassistype": "RackMount", + "chassis_manufacturer": "HP", + "chassis_model": "Proliant Gen10", + "chassis_partnumber": "CT6NWPYZ", + "chassis_powerstate": "On", + "chassis_sku": "CLFYTTWP", + "chassis_serialnumber": "QWEVC007C99803", + "chassis_state": "Enabled", + "chassis_health": "OK", + }, + map[string]interface{}{ + "reading_percent": 23, + }, + time.Unix(0, 0), + ), + testutil.MustMetric( + "redfish_power_powercontrol", + map[string]string{ + "source": "tpa-hostname", + "name": "", + "member_id": "0", + "address": address, + "rack": "", + "room": "", + "row": "", + "datacenter": "", + "chassis_chassistype": "RackMount", + "chassis_manufacturer": "HP", + "chassis_model": "Proliant Gen10", + "chassis_partnumber": "CT6NWPYZ", + "chassis_powerstate": "On", + "chassis_sku": "CLFYTTWP", + "chassis_serialnumber": "QWEVC007C99803", + "chassis_state": "Enabled", + "chassis_health": "OK", + }, + map[string]interface{}{ + "average_consumed_watts": 221.0, + "interval_in_min": int64(20), + "max_consumed_watts": 252.0, + "min_consumed_watts": 220.0, + "power_capacity_watts": 1600.0, + "power_consumed_watts": 221.0, + }, + time.Unix(0, 0), + ), + testutil.MustMetric( + "redfish_power_powersupplies", + map[string]string{ + "source": "tpa-hostname", + "name": "HpeServerPowerSupply", + "member_id": "0", + "address": address, + "health": "OK", + "state": "Enabled", + "rack": "", + "room": "", + "row": "", + "datacenter": "", + "chassis_chassistype": "RackMount", + "chassis_manufacturer": "HP", + "chassis_model": "Proliant Gen10", + "chassis_partnumber": "CT6NWPYZ", + "chassis_powerstate": "On", + "chassis_sku": "CLFYTTWP", + "chassis_serialnumber": "QWEVC007C99803", + "chassis_state": "Enabled", + "chassis_health": "OK", + }, + map[string]interface{}{ + "power_capacity_watts": 800.0, + "line_input_voltage": 205.0, + "last_power_output_watts": 0.0, + }, + time.Unix(0, 0), + ), + testutil.MustMetric( + "redfish_power_powersupplies", + map[string]string{ + "source": "tpa-hostname", + "name": "HpeServerPowerSupply", + "member_id": "1", + "address": address, + "health": "OK", + "state": "Enabled", + "rack": "", + "room": "", + "row": "", + "datacenter": "", + "chassis_chassistype": "RackMount", + "chassis_manufacturer": "HP", + "chassis_model": "Proliant Gen10", + "chassis_partnumber": "CT6NWPYZ", + "chassis_powerstate": "On", + "chassis_sku": "CLFYTTWP", + "chassis_serialnumber": "QWEVC007C99803", + "chassis_state": "Enabled", + "chassis_health": "OK", + }, + map[string]interface{}{ + "power_capacity_watts": 800.0, + "line_input_voltage": 205.0, + "last_power_output_watts": 90.0, + }, + time.Unix(0, 0), + ), + } + + hpPlugin := &Redfish{ + Address: ts.URL, + Username: "test", + Password: "test", + ComputerSystemID: "1", + IncludeTagSets: []string{"chassis", "chassis.location"}, + } + require.NoError(t, hpPlugin.Init()) + var hpAcc testutil.Accumulator + + err = hpPlugin.Gather(&hpAcc) + require.NoError(t, err) + require.True(t, hpAcc.HasMeasurement("redfish_thermal_temperatures")) + testutil.RequireMetricsEqual(t, expectedMetricsHp, hpAcc.GetTelegrafMetrics(), + testutil.IgnoreTime()) +} diff --git a/plugins/inputs/redfish/sample.conf b/plugins/inputs/redfish/sample.conf index 1cced5c08..d8610f741 100644 --- a/plugins/inputs/redfish/sample.conf +++ b/plugins/inputs/redfish/sample.conf @@ -10,6 +10,13 @@ ## System Id to collect data for in Redfish APIs. computer_system_id="System.Embedded.1" + ## Tag sets allow you to include redfish OData link parent data + ## For Example. + ## Thermal data is an OData link with parent Chassis which has a link of Location. + ## For more info see the Redfish Resource and Schema Guide at DMTFs website. + ## Available sets are: "chassis.location" and "chassis" + # include_tag_sets = ["chassis.location"] + ## Amount of time allowed to complete the HTTP request # timeout = "5s" diff --git a/plugins/inputs/redfish/testdata/hp_chassis.json b/plugins/inputs/redfish/testdata/hp_chassis.json index a7da7face..2dee6a6a3 100644 --- a/plugins/inputs/redfish/testdata/hp_chassis.json +++ b/plugins/inputs/redfish/testdata/hp_chassis.json @@ -1,7 +1,30 @@ { + "ChassisType": "RackMount", + "Location": { + "Info": ";;;;1", + "InfoFormat": "DataCenter;RoomName;Aisle;RackName;RackSlot", + "Placement": { + "Rack": "", + "Row": "" + }, + "PostalAddress": { + "Building": "", + "Room": "" + } + }, + "Manufacturer": "HP", + "Model": "Proliant Gen10", + "PartNumber": "CT6NWPYZ", "Power": { "@odata.id": "/redfish/v1/Chassis/1/Power" }, + "PowerState": "On", + "SKU": "CLFYTTWP", + "SerialNumber": "QWEVC007C99803", + "Status": { + "Health": "OK", + "State": "Enabled" + }, "Thermal": { "@odata.id": "/redfish/v1/Chassis/1/Thermal" }