blob: fb4a05b6fa7dc67875a16739cbba2d56f99d559d [file] [log] [blame]
edition = "2023";
package safepower_agent_proto;
import "google/protobuf/timestamp.proto";
option features.field_presence = IMPLICIT;
service SafepowerLocalAgent {
// Get a list of all supported actions
rpc GetSupportedActions(GetSupportedActionsRequest)
returns (GetSupportedActionsResponse) {}
// Execute an action when a condition is met
rpc StartAction(StartActionRequest) returns (StartActionResponse) {}
// Monitor reaction
rpc MonitorAction(MonitorActionRequest) returns (stream ActionStateLog) {}
// Monitor state.
rpc MonitorState(MonitorStateRequest) returns (stream SystemState) {}
}
message GetSupportedActionsRequest {}
message GetSupportedActionsResponse {
// This lists all supported actions.
repeated Action actions = 1; // may be empty
}
// Identifies a component of the system whose state is monitored or acted upon.
message SystemComponent {
string node_entity_tag = 1 [features.field_presence = EXPLICIT];
string name = 2 [features.field_presence = EXPLICIT];
}
enum ActionType {
ACTION_TYPE_UNSPECIFIED = 0;
ACTION_TYPE_CYCLE = 1;
ACTION_TYPE_REBOOT = 2;
ACTION_TYPE_OFF = 3;
ACTION_TYPE_ON = 4;
}
enum ActionSeverity {
ACTION_SEVERITY_UNSPECIFIED = 0;
ACTION_SEVERITY_FORCE = 1;
ACTION_SEVERITY_GRACEFUL = 2;
}
// LINT.IfChange(ActionFields)
message Action {
ActionType action_type = 1 [features.field_presence = EXPLICIT]; // Required
ActionSeverity action_severity = 2 [features.field_presence = EXPLICIT];
// This may or may not correspond to an entry in SystemStatus reported by
// this node. For example, it is possible that the actuating node is not the
// same as the one that can get this status reliably.
SystemComponent target_component = 3; // Required
}
// LINT.ThenChange(//depot/action_hash.h:ActionFields)
message StartActionRequest {
// This is an informational string that can be used to identidfy the caller
string caller_cookie = 1 [features.field_presence = EXPLICIT]; // required
// Wait for this condition before running the action. If the matching
// condition(s) specify that they should abort, the action will not be run. If
// unspecified, runs the action immediately.
Condition precondition = 2;
Action action = 3; // required
// Wait until this condition is met. If matching conditions(s) specify that
// they should abort, the result will be an error.
Condition validation = 4;
}
message StartActionResponse {
string response_id = 1 [features.field_presence = EXPLICIT];
}
message Condition {
oneof condition_type {
AnyOfCondition any_of = 1;
AllOfCondition all_of = 2;
StateMatchedCondition state_condition = 3;
TimeoutCondition timeout = 4;
}
}
// Condition that matches when any of nested conditions match
message AnyOfCondition {
repeated Condition conditions = 1;
}
// Condition that matches when all of nested conditions match
message AllOfCondition {
repeated Condition conditions = 1;
}
// Condition that matches when the system state changes to match some expected
// state(s)
message StateMatchedCondition {
// This matches the keys in SystemState.node_state then
// NodeState.component_state
SystemComponent system_component = 1;
// Determine how to compare ComponentStates. Not all types may be applicable
// to all ComponentState.state types.
ComparisonType comparison_type = 2 [features.field_presence = EXPLICIT];
// Ignored if matcher is COMPARISON_TYPE_CHANGED. Otherwise, the current state
// is compared to this state.
ComponentState component_state = 3;
// If true, the action will be aborted on match.
bool abort = 4 [features.field_presence = EXPLICIT];
}
enum ComparisonType {
COMPARISON_TYPE_UNSPECIFIED = 0;
COMPARISON_TYPE_EQ = 1;
COMPARISON_TYPE_NE = 2;
COMPARISON_TYPE_GT = 3;
COMPARISON_TYPE_GE = 4;
COMPARISON_TYPE_LT = 5;
COMPARISON_TYPE_LE = 6;
}
// Condition that matches at/after some time
message TimeoutCondition {
oneof time {
uint64 timeout_ms = 1;
google.protobuf.Timestamp deadline = 2;
}
// If true, the action will be aborted on match.
bool abort = 3 [features.field_presence = EXPLICIT];
}
message MonitorActionRequest {
// This should be an ID returned in StartActionResponse
string response_id = 1 [features.field_presence = EXPLICIT];
}
message ActionStateLog {
// Included in all updates. This is a timestamp that is set at service start.
// This is mostly useful to detect service restarts.
uint64 epoch_ms = 1 [features.field_presence = EXPLICIT]; // required
repeated ActionStateChange history = 2;
ActionState current_state = 3
[features.field_presence = EXPLICIT]; // required
}
enum ActionState {
ACTION_STATE_UNDEFINED = 0;
ACTION_STATE_INIT = 1;
ACTION_STATE_CHECKING_PRECONDITION = 2;
ACTION_STATE_RUNNING_ACTION = 3;
ACTION_STATE_VALIDATING_FINAL_STATE = 4;
ACTION_STATE_ERROR = 5;
ACTION_STATE_SUCCESS = 6;
}
message ActionStateChange {
ActionState previous_state = 1
[features.field_presence =
EXPLICIT]; // Required except for transition to Init
// Time when the state changed to the next state
google.protobuf.Timestamp changed_at = 2;
// Status of the operation that caused the state change
Status status = 3;
// Optional conditions that matched resulting in the state change. This is
// only present if the state change was because of a condition match.
repeated Condition matching_conditions = 4;
}
message Status {
int64 code = 1 [features.field_presence = EXPLICIT];
string message = 2 [features.field_presence = EXPLICIT];
}
message MonitorStateRequest {}
message SystemState {
// Included in all updates. This is a timestamp that is set at service start.
// This is mostly useful to detect service restarts.
uint64 epoch_ms = 1 [features.field_presence = EXPLICIT]; // required
// The contents are platform and node specific. Keys are node entity tags and
// values are state information for the corresponding node. This includes all
// nodes for which this node can obtain status. For example, an arena
// controller may have power state information for other nodes in the arena.
map<string, NodeState> node_state = 2;
}
message NodeState {
// The contents are platform and node specific. Keys are component names
// (service, subsystem, or other property like power state), values are the
// state of the component.
map<string, ComponentState> component_state = 1;
}
// State of a specific "component" where a component may be a service or some
// other part of the system such as power or network connectivity.
// LINT.IfChange(ComponentState)
message ComponentState {
oneof state {
DaemonState daemon_state = 64;
BootState boot_state = 65;
ConnectionState connection_state = 66;
PowerState power_state = 67;
// add specific types for component types here
}
}
message DaemonState {
uint32 restart_counter = 1 [features.field_presence = EXPLICIT];
bool healthy = 2 [features.field_presence = EXPLICIT];
}
enum BootStateSpecifier {
BOOT_STATE_UNSPECIFIED = 0;
BOOT_STATE_NOT_BOOTED = 1;
BOOT_STATE_BOOTING = 2;
BOOT_STATE_BOOTED = 3;
}
message BootState {
uint32 boot_counter = 1 [features.field_presence = EXPLICIT];
uint64 uptime_ms = 2 [features.field_presence = EXPLICIT];
BootStateSpecifier state = 3 [features.field_presence = EXPLICIT];
}
message ConnectionState {
uint32 reconnect_counter = 1 [features.field_presence = EXPLICIT];
}
// Based on Redfish PowerState
enum PowerStateSpecifier {
POWER_STATE_UNSPECIFIED = 0;
POWER_STATE_OFF = 1;
POWER_STATE_ON = 2;
POWER_STATE_PAUSED = 3;
POWER_STATE_POWERING_ON = 4;
POWER_STATE_POWERING_OFF = 5;
}
message PowerState {
PowerStateSpecifier state = 1 [features.field_presence = EXPLICIT];
uint32 power_cycle_counter = 2 [features.field_presence = EXPLICIT];
}
// LINT.ThenChange(//depot/state_fields.h:ComponentStateFields)