1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
//! Data types used when interacting with the control interface of a wasmCloud lattice
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::ComponentId;
/// A control interface response that wraps a response payload, a success flag, and a message
/// with additional context if necessary.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CtlResponse<T> {
/// Whether the request succeeded
pub success: bool,
/// A message with additional context about the response
pub message: String,
/// The response data, if any
#[serde(skip_serializing_if = "Option::is_none")]
pub response: Option<T>,
}
impl<T> CtlResponse<T> {
pub fn ok(response: T) -> Self {
CtlResponse {
success: true,
message: "".to_string(),
response: Some(response),
}
}
}
impl CtlResponse<()> {
/// Helper function to return a successful response without
/// a message or a payload.
pub fn success() -> Self {
CtlResponse {
success: true,
message: "".to_string(),
response: None,
}
}
/// Helper function to return an unsuccessful response with
/// a message but no payload. Note that this implicitly is
/// typing the inner payload as `()` for efficiency.
pub fn error(message: &str) -> Self {
CtlResponse {
success: false,
message: message.to_string(),
response: None,
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct ScaleComponentCommand {
/// Image reference for the component.
#[serde(default)]
pub component_ref: String,
/// Unique identifier of the component to scale.
pub component_id: ComponentId,
/// Optional set of annotations used to describe the nature of this component scale command. For
/// example, autonomous agents may wish to "tag" scale requests as part of a given deployment
#[serde(default, skip_serializing_if = "Option::is_none")]
pub annotations: Option<HashMap<String, String>>,
/// The maximum number of concurrent executing instances of this component. Setting this to `0` will
/// stop the component.
// NOTE: renaming to `count` lets us remain backwards compatible for a few minor versions
#[serde(default, alias = "count", rename = "count")]
pub max_instances: u32,
/// Host ID on which to scale this component
#[serde(default)]
pub host_id: String,
/// A list of named configs to use for this component. It is not required to specify a config.
/// Configs are merged together before being given to the component, with values from the right-most
/// config in the list taking precedence. For example, given ordered configs foo {a: 1, b: 2},
/// bar {b: 3, c: 4}, and baz {c: 5, d: 6}, the resulting config will be: {a: 1, b: 3, c: 5, d:
/// 6}
#[serde(default)]
pub config: Vec<String>,
}
/// A command sent to a host requesting a capability provider be started with the
/// given link name and optional configuration.
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct StartProviderCommand {
/// Optional set of annotations used to describe the nature of this provider start command. For
/// example, autonomous agents may wish to "tag" start requests as part of a given deployment
#[serde(default, skip_serializing_if = "Option::is_none")]
pub annotations: Option<HashMap<String, String>>,
/// Unique identifier of the provider to start.
pub provider_id: ComponentId,
/// A list of named configs to use for this provider. It is not required to specify a config.
/// Configs are merged together before being given to the provider, with values from the right-most
/// config in the list taking precedence. For example, given ordered configs foo {a: 1, b: 2},
/// bar {b: 3, c: 4}, and baz {c: 5, d: 6}, the resulting config will be: {a: 1, b: 3, c: 5, d:
/// 6}
#[serde(default)]
pub config: Vec<String>,
/// The host ID on which to start the provider
#[serde(default)]
pub host_id: String,
/// The image reference of the provider to be started
#[serde(default)]
pub provider_ref: String,
}
/// A command sent to request that the given host purge and stop
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct StopHostCommand {
/// The ID of the target host
#[serde(default)]
pub host_id: String,
/// An optional timeout, in seconds
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timeout: Option<u64>,
}
/// A request to stop the given provider on the indicated host
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct StopProviderCommand {
/// Host ID on which to stop the provider
#[serde(default)]
pub host_id: String,
/// Unique identifier for the provider to stop.
#[serde(default, alias = "provider_ref")]
pub provider_id: ComponentId,
}
/// A command instructing a specific host to perform a live update
/// on the indicated component by supplying a new image reference. Note that
/// live updates are only possible through image references
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct UpdateComponentCommand {
/// The component's 56-character unique ID
#[serde(default)]
pub component_id: ComponentId,
/// Optional set of annotations used to describe the nature of this
/// update request. Only component instances that have matching annotations
/// will be upgraded, allowing for instance isolation by
#[serde(default, skip_serializing_if = "Option::is_none")]
pub annotations: Option<HashMap<String, String>>,
/// The host ID of the host to perform the live update
#[serde(default)]
pub host_id: String,
/// The new image reference of the upgraded version of this component
#[serde(default)]
pub new_component_ref: String,
}