diff --git a/dag/extdeps/bmc/openbmc_fan_control.dag b/dag/extdeps/bmc/openbmc_fan_control.dag index efbd1f5cb92..72835924b96 100644 --- a/dag/extdeps/bmc/openbmc_fan_control.dag +++ b/dag/extdeps/bmc/openbmc_fan_control.dag @@ -180,12 +180,14 @@ type OpenBmcCollection fn openbmc_collection_from_values( values: List, ) -> OpenBmcCollection { - if values.length() == 0 { - OpenBmcCollectionZero - } else if values.length() == 1 { - OpenBmcCollectionOne { value: values.first() } - } else { - OpenBmcCollectionMany { values: values } + match values.first() { + Absent => OpenBmcCollectionZero + Present { value: head } => + if values.length() == 1 { + OpenBmcCollectionOne { value: head } + } else { + OpenBmcCollectionMany { values: values } + } } } @@ -299,19 +301,31 @@ fn openbmc_zone_failsafe_result( } else { let tokens = split(s: trim(remote.stdout), delimiter: " ") |> filter(token => trim(token) != "") - if tokens.length() != 2 || trim(tokens.first()) != "b" { - OpenBmcBoolRefused { + match tokens.first() { + Absent => OpenBmcBoolRefused { reason: "zone failsafe response does not have one typed boolean payload", } - } else { - let payload = trim(tokens.skip(n: 1).first()) - if payload == "true" { - OpenBmcBoolObserved { value: true } - } else if payload == "false" { - OpenBmcBoolObserved { value: false } - } else { - OpenBmcBoolRefused { reason: "zone failsafe payload is not boolean" } - } + Present { value: tag } => + match tokens.skip(n: 1).first() { + Absent => OpenBmcBoolRefused { + reason: "zone failsafe response does not have one typed boolean payload", + } + Present { value: raw_payload } => + if tokens.length() != 2 || trim(tag) != "b" { + OpenBmcBoolRefused { + reason: "zone failsafe response does not have one typed boolean payload", + } + } else { + let payload = trim(raw_payload) + if payload == "true" { + OpenBmcBoolObserved { value: true } + } else if payload == "false" { + OpenBmcBoolObserved { value: false } + } else { + OpenBmcBoolRefused { reason: "zone failsafe payload is not boolean" } + } + } + } } } } @@ -377,19 +391,19 @@ fn openbmc_disk_usage_result( OpenBmcByteSizeRefused { reason: reason } } else { let lines = split(s: trim(remote.stdout), delimiter: "\n") - if lines.length() < 2 { - OpenBmcByteSizeRefused { reason: "disk usage response has no data row" } - } else { + match lines.skip(n: 1).first() { + Absent => OpenBmcByteSizeRefused { reason: "disk usage response has no data row" } + Present { value: data_row } => { let fields = split( - s: trim(lines.skip(n: 1).first()), + s: trim(data_row), delimiter: " ", ) |> filter(field => trim(field) != "") - if fields.length() < 4 { - OpenBmcByteSizeRefused { + match fields.skip(n: 3).first() { + Absent => OpenBmcByteSizeRefused { reason: "disk usage data row has no available-kibibyte field", } - } else { - match parse_int(s: trim(fields.skip(n: 3).first())) { + Present { value: kib_field } => + match parse_int(s: trim(kib_field)) { Absent => OpenBmcByteSizeRefused { reason: "available-kibibyte field is not an integer", @@ -404,6 +418,7 @@ fn openbmc_disk_usage_result( } } } + } } } } @@ -1801,15 +1816,47 @@ fn openbmc_fan_controllers( } } -fn openbmc_fan_controller_collection( - values: List, -) -> OpenBmcCollection { - if values.length() == 0 { - OpenBmcCollectionZero - } else if values.length() == 1 { - OpenBmcCollectionOne { value: values.first() } +type OpenBmcStepwiseScalars { + minimum_duty: Percent + zone_failsafe_duty: Percent + sensor_failsafe_duty: Percent + positive_hysteresis: CelsiusDelta + negative_hysteresis: CelsiusDelta +} + +fn openbmc_stepwise_scalars(scalars: List) -> OpenBmcStepwiseScalars? { + if scalars.length() != 5 { + Absent } else { - OpenBmcCollectionMany { values: values } + match scalars.first() { + Absent => Absent + Present { value: a } => + match scalars.skip(n: 1).first() { + Absent => Absent + Present { value: b } => + match scalars.skip(n: 2).first() { + Absent => Absent + Present { value: c } => + match scalars.skip(n: 3).first() { + Absent => Absent + Present { value: d } => + match scalars.skip(n: 4).first() { + Absent => Absent + Present { value: e } => + Present { + value: OpenBmcStepwiseScalars { + minimum_duty: percent(a), + zone_failsafe_duty: percent(b), + sensor_failsafe_duty: percent(c), + positive_hysteresis: celsius_delta(d), + negative_hysteresis: celsius_delta(e), + }, + } + } + } + } + } + } } } @@ -1819,23 +1866,23 @@ fn openbmc_fan_config_queries_rec( queries: List, built: List, ) -> OpenBmcIntegerListResult { - if queries.length() == 0 { - OpenBmcIntegerListObserved { values: built } - } else { - match openbmc_fan_config_integer( - session: session, - config_path: config_path, - query: queries.first(), - ) { - OpenBmcIntegerRefused { reason } => OpenBmcIntegerListRefused { reason: reason } - OpenBmcIntegerObserved { value } => - openbmc_fan_config_queries_rec( - session: session, - config_path: config_path, - queries: queries.skip(n: 1), - built: append(built, items: [value]), - ) - } + match queries.first() { + Absent => OpenBmcIntegerListObserved { values: built } + Present { value: query } => + match openbmc_fan_config_integer( + session: session, + config_path: config_path, + query: query, + ) { + OpenBmcIntegerRefused { reason } => OpenBmcIntegerListRefused { reason: reason } + OpenBmcIntegerObserved { value } => + openbmc_fan_config_queries_rec( + session: session, + config_path: config_path, + queries: queries.skip(n: 1), + built: append(built, items: [value]), + ) + } } } @@ -1851,7 +1898,7 @@ fn openbmc_fan_config_finish_observation( OpenBmcFanConfigObserved { observation: OpenBmcFanConfigObservation { stepwise: stepwise, - fan_controllers: openbmc_fan_controller_collection(values: values), + fan_controllers: openbmc_collection_from_values(values: values), }, } } @@ -1893,28 +1940,35 @@ fn openbmc_fan_config_observe_one( OpenBmcIntegerListRefused { reason } => OpenBmcFanConfigObservationRefused { reason: reason } OpenBmcIntegerListObserved { values: outputs } => - if scalars.length() != 5 || readings.length() != outputs.length() - || scalars |> any(value => value < 0) - || outputs |> any(value => value < 0) { - OpenBmcFanConfigObservationRefused { - reason: "OpenBMC fan config response has invalid structured cardinality or negative duty", - } - } else { - openbmc_fan_config_finish_observation( - session: session, - config_path: config_path, - stepwise: OpenBmcSelectionOne { - value: OpenBmcStepwiseController { - minimum_duty: percent(scalars.first()), - zone_failsafe_duty: percent(scalars.skip(n: 1).first()), - sensor_failsafe_duty: percent(scalars.skip(n: 2).first()), - positive_hysteresis: celsius_delta(scalars.skip(n: 3).first()), - negative_hysteresis: celsius_delta(scalars.skip(n: 4).first()), - readings: readings |> map(value => celsius(value)), - outputs: outputs |> map(value => percent(value)), - }, - }, - ) + match openbmc_stepwise_scalars(scalars: scalars) { + Absent => + OpenBmcFanConfigObservationRefused { + reason: "OpenBMC fan config response has invalid structured cardinality or negative duty", + } + Present { value: five } => + if readings.length() != outputs.length() + || scalars |> any(value => value < 0) + || outputs |> any(value => value < 0) { + OpenBmcFanConfigObservationRefused { + reason: "OpenBMC fan config response has invalid structured cardinality or negative duty", + } + } else { + openbmc_fan_config_finish_observation( + session: session, + config_path: config_path, + stepwise: OpenBmcSelectionOne { + value: OpenBmcStepwiseController { + minimum_duty: five.minimum_duty, + zone_failsafe_duty: five.zone_failsafe_duty, + sensor_failsafe_duty: five.sensor_failsafe_duty, + positive_hysteresis: five.positive_hysteresis, + negative_hysteresis: five.negative_hysteresis, + readings: readings |> map(value => celsius(value)), + outputs: outputs |> map(value => percent(value)), + }, + }, + ) + } } } }