use serde_repr::{Deserialize_repr, Serialize_repr};
use std::{
cmp::{Ord, Ordering},
collections::{BTreeMap, BTreeSet, HashMap},
convert::TryFrom,
fmt,
ops::Deref,
sync::Arc,
};
#[derive(Eq, PartialEq, Hash, Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct PluginName(pub String);
impl From<PluginName> for String {
fn from(PluginName(s): PluginName) -> Self {
s
}
}
impl From<&str> for PluginName {
fn from(name: &str) -> Self {
Self(name.into())
}
}
impl fmt::Display for PluginName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(
Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, serde::Serialize, serde::Deserialize,
)]
#[serde(transparent)]
pub struct Fqdn(pub String);
impl From<Fqdn> for String {
fn from(Fqdn(s): Fqdn) -> Self {
s
}
}
impl fmt::Display for Fqdn {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct Id(pub String);
impl From<&str> for Id {
fn from(name: &str) -> Self {
Self(name.into())
}
}
impl fmt::Display for Id {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct Seq(pub u64);
impl From<u64> for Seq {
fn from(name: u64) -> Self {
Self(name)
}
}
impl Default for Seq {
fn default() -> Self {
Self(0)
}
}
impl Seq {
pub fn increment(&mut self) {
self.0 += 1;
}
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(tag = "type")]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Message {
Data {
fqdn: Fqdn,
plugin: PluginName,
session_id: Id,
session_seq: Seq,
body: serde_json::Value,
},
SessionCreateRequest {
fqdn: Fqdn,
plugin: PluginName,
},
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct Envelope {
pub messages: Vec<Message>,
pub server_boot_time: String,
pub client_start_time: String,
}
impl Envelope {
pub fn new(
messages: Vec<Message>,
client_start_time: impl Into<String>,
server_boot_time: impl Into<String>,
) -> Self {
Self {
messages,
server_boot_time: server_boot_time.into(),
client_start_time: client_start_time.into(),
}
}
}
#[derive(serde::Deserialize, serde::Serialize, Debug)]
#[serde(tag = "type")]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ManagerMessage {
SessionCreateResponse {
fqdn: Fqdn,
plugin: PluginName,
session_id: Id,
},
Data {
fqdn: Fqdn,
plugin: PluginName,
session_id: Id,
body: serde_json::Value,
},
SessionTerminate {
fqdn: Fqdn,
plugin: PluginName,
session_id: Id,
},
SessionTerminateAll {
fqdn: Fqdn,
},
}
#[derive(serde::Deserialize, serde::Serialize, Debug)]
pub struct ManagerMessages {
pub messages: Vec<ManagerMessage>,
}
#[derive(serde::Deserialize, serde::Serialize, Debug)]
#[serde(tag = "type")]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PluginMessage {
SessionTerminate {
fqdn: Fqdn,
plugin: PluginName,
session_id: Id,
},
SessionCreate {
fqdn: Fqdn,
plugin: PluginName,
session_id: Id,
},
Data {
fqdn: Fqdn,
plugin: PluginName,
session_id: Id,
session_seq: Seq,
body: serde_json::Value,
},
}
pub trait FlatQuery {
fn query() -> Vec<(&'static str, &'static str)> {
vec![("limit", "0")]
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Deserialize, serde::Serialize)]
pub struct ActionName(pub String);
impl From<&str> for ActionName {
fn from(name: &str) -> Self {
Self(name.into())
}
}
impl fmt::Display for ActionName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct ActionId(pub String);
impl fmt::Display for ActionId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Action {
ActionStart {
action: ActionName,
args: serde_json::value::Value,
id: ActionId,
},
ActionCancel {
id: ActionId,
},
}
impl Action {
pub fn get_id(&self) -> &ActionId {
match self {
Self::ActionStart { id, .. } | Self::ActionCancel { id, .. } => id,
}
}
}
impl TryFrom<Action> for serde_json::Value {
type Error = serde_json::Error;
fn try_from(action: Action) -> Result<Self, Self::Error> {
serde_json::to_value(action)
}
}
#[derive(serde::Deserialize, serde::Serialize, Debug)]
pub struct ActionResult {
pub id: ActionId,
pub result: Result<serde_json::value::Value, String>,
}
pub type AgentResult = std::result::Result<serde_json::Value, String>;
pub trait ToJsonValue {
fn to_json_value(&self) -> Result<serde_json::Value, String>;
}
impl<T: serde::Serialize> ToJsonValue for T {
fn to_json_value(&self) -> Result<serde_json::Value, String> {
serde_json::to_value(self).map_err(|e| format!("{:?}", e))
}
}
pub trait ToBytes {
fn to_bytes(&self) -> Result<Vec<u8>, serde_json::error::Error>;
}
impl<T: serde::Serialize> ToBytes for T {
fn to_bytes(&self) -> Result<Vec<u8>, serde_json::error::Error> {
serde_json::to_vec(&self)
}
}
#[derive(
serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash,
)]
#[serde(try_from = "String")]
#[serde(into = "String")]
pub struct CompositeId(pub u32, pub u32);
impl fmt::Display for CompositeId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}:{}", self.0, self.1)
}
}
impl From<CompositeId> for String {
fn from(x: CompositeId) -> Self {
format!("{}", x)
}
}
impl TryFrom<String> for CompositeId {
type Error = Box<dyn std::error::Error>;
fn try_from(s: String) -> Result<Self, Self::Error> {
let xs: Vec<_> = s.split(':').collect();
if xs.len() != 2 {
return Err("Could not convert to CompositeId, String did not contain 2 parts.".into());
}
let x = xs[0].parse::<u32>()?;
let y = xs[1].parse::<u32>()?;
Ok(Self(x, y))
}
}
pub trait ToCompositeId {
fn composite_id(&self) -> CompositeId;
}
impl<T: ToCompositeId> ToCompositeId for &Arc<T> {
fn composite_id(&self) -> CompositeId {
let t: &T = self.deref();
t.composite_id()
}
}
impl<T: ToCompositeId> ToCompositeId for Arc<T> {
fn composite_id(&self) -> CompositeId {
let t: &T = self.deref();
t.composite_id()
}
}
pub trait Label {
fn label(&self) -> &str;
}
pub trait EndpointName {
fn endpoint_name() -> &'static str;
}
pub trait EndpointNameSelf {
fn endpoint_name(&self) -> &'static str;
}
impl<T: EndpointName> EndpointNameSelf for T {
fn endpoint_name(&self) -> &'static str {
Self::endpoint_name()
}
}
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, Eq, PartialEq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum LockType {
Read,
Write,
}
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, Eq, PartialEq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum LockAction {
Add,
Remove,
}
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, Eq, PartialEq, Hash)]
pub struct LockChange {
pub uuid: String,
pub job_id: u64,
pub content_type_id: u32,
pub item_id: u32,
pub description: String,
pub lock_type: LockType,
pub action: LockAction,
}
impl ToCompositeId for LockChange {
fn composite_id(&self) -> CompositeId {
CompositeId(self.content_type_id, self.item_id)
}
}
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
pub struct Meta {
pub limit: u32,
pub next: Option<String>,
pub offset: u32,
pub previous: Option<String>,
pub total_count: u32,
}
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
pub struct ApiList<T> {
pub meta: Meta,
pub objects: Vec<T>,
}
impl<T> ApiList<T> {
pub fn new(objects: Vec<T>) -> Self {
Self {
meta: Meta {
limit: 0,
next: None,
offset: 0,
previous: None,
total_count: objects.len() as u32,
},
objects,
}
}
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct Conf {
pub allow_anonymous_read: bool,
pub build: String,
pub version: String,
pub is_release: bool,
pub branding: Branding,
pub use_stratagem: bool,
}
impl Default for Conf {
fn default() -> Self {
Self {
allow_anonymous_read: true,
build: "Not Loaded".into(),
version: "0".into(),
is_release: false,
branding: Branding::default(),
use_stratagem: false,
}
}
}
impl EndpointName for Conf {
fn endpoint_name() -> &'static str {
"conf"
}
}
#[derive(serde::Deserialize, serde::Serialize, PartialEq, Clone, Debug)]
pub struct AvailableAction {
pub args: Option<HashMap<String, Option<u64>>>,
pub composite_id: CompositeId,
pub class_name: Option<String>,
pub confirmation: Option<String>,
pub display_group: u64,
pub display_order: u64,
pub long_description: String,
pub state: Option<String>,
pub verb: String,
}
impl EndpointName for AvailableAction {
fn endpoint_name() -> &'static str {
"action"
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct NtpConfiguration {
pub content_type_id: u32,
pub id: u32,
pub immutable_state: bool,
pub label: String,
pub not_deleted: Option<bool>,
pub resource_uri: String,
pub state: String,
pub state_modified_at: String,
}
impl EndpointName for NtpConfiguration {
fn endpoint_name() -> &'static str {
"ntp_configuration"
}
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct ClientMount {
pub filesystem_name: String,
pub mountpoint: Option<String>,
pub state: String,
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct Host {
pub address: String,
pub boot_time: Option<String>,
pub client_mounts: Option<Vec<ClientMount>>,
pub content_type_id: u32,
pub corosync_configuration: Option<String>,
pub corosync_ring0: String,
pub fqdn: String,
pub id: u32,
pub immutable_state: bool,
pub install_method: String,
pub label: String,
pub lnet_configuration: String,
pub member_of_active_filesystem: bool,
pub needs_update: bool,
pub nids: Option<Vec<String>>,
pub nodename: String,
pub pacemaker_configuration: Option<String>,
pub private_key: Option<String>,
pub private_key_passphrase: Option<String>,
pub properties: String,
pub resource_uri: String,
pub root_pw: Option<String>,
pub server_profile: ServerProfile,
pub state: String,
pub state_modified_at: String,
}
impl Host {
pub fn lnet_id(&self) -> Option<u32> {
let id = iml_api_utils::extract_id(&self.lnet_configuration)?;
id.parse::<u32>().ok()
}
pub fn corosync_id(&self) -> Option<u32> {
let id = iml_api_utils::extract_id(self.corosync_configuration.as_ref()?)?;
id.parse::<u32>().ok()
}
pub fn pacemaker_id(&self) -> Option<u32> {
let id = iml_api_utils::extract_id(self.pacemaker_configuration.as_ref()?)?;
id.parse::<u32>().ok()
}
}
impl FlatQuery for Host {}
impl ToCompositeId for Host {
fn composite_id(&self) -> CompositeId {
CompositeId(self.content_type_id, self.id)
}
}
impl ToCompositeId for &Host {
fn composite_id(&self) -> CompositeId {
CompositeId(self.content_type_id, self.id)
}
}
impl Label for Host {
fn label(&self) -> &str {
&self.label
}
}
impl Label for &Host {
fn label(&self) -> &str {
&self.label
}
}
impl db::Id for Host {
fn id(&self) -> u32 {
self.id
}
}
impl db::Id for &Host {
fn id(&self) -> u32 {
self.id
}
}
impl EndpointName for Host {
fn endpoint_name() -> &'static str {
"host"
}
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct ServerProfile {
pub corosync: bool,
pub corosync2: bool,
pub default: bool,
pub initial_state: String,
pub managed: bool,
pub name: String,
pub ntp: bool,
pub pacemaker: bool,
pub repolist: Vec<String>,
pub resource_uri: String,
pub ui_description: String,
pub ui_name: String,
pub user_selectable: bool,
pub worker: bool,
}
impl FlatQuery for ServerProfile {}
impl EndpointName for ServerProfile {
fn endpoint_name() -> &'static str {
"server_profile"
}
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct HostProfileWrapper {
pub host_profiles: Option<HostProfile>,
pub error: Option<String>,
pub traceback: Option<String>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct HostProfile {
pub address: String,
pub host: u32,
pub profiles: HashMap<String, Vec<ProfileTest>>,
pub profiles_valid: bool,
pub resource_uri: String,
}
impl EndpointName for HostProfile {
fn endpoint_name() -> &'static str {
"host_profile"
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ProfileTest {
pub description: String,
pub error: String,
pub pass: bool,
pub test: String,
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct CmdWrapper {
pub command: Command,
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct Command {
pub cancelled: bool,
pub complete: bool,
pub created_at: String,
pub errored: bool,
pub id: u32,
pub jobs: Vec<String>,
pub logs: String,
pub message: String,
pub resource_uri: String,
}
impl EndpointName for Command {
fn endpoint_name() -> &'static str {
"command"
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct JobLock {
pub locked_item_content_type_id: u32,
pub locked_item_id: u32,
pub locked_item_uri: String,
pub resource_uri: String,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct AvailableTransition {
pub label: String,
pub state: String,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Job<T> {
pub available_transitions: Vec<AvailableTransition>,
pub cancelled: bool,
pub class_name: String,
pub commands: Vec<String>,
pub created_at: String,
pub description: String,
pub errored: bool,
pub id: u32,
pub modified_at: String,
pub read_locks: Vec<JobLock>,
pub resource_uri: String,
pub state: String,
pub step_results: HashMap<String, T>,
pub steps: Vec<String>,
pub wait_for: Vec<String>,
pub write_locks: Vec<JobLock>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Check {
pub name: String,
pub value: bool,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct HostValididity {
pub address: String,
pub status: Vec<Check>,
pub valid: bool,
}
pub type TestHostJob = Job<HostValididity>;
impl<T> EndpointName for Job<T> {
fn endpoint_name() -> &'static str {
"job"
}
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct FilesystemConfParams {
#[serde(rename = "llite.max_cached_mb")]
pub llite_max_cached_mb: Option<String>,
#[serde(rename = "llite.max_read_ahead_mb")]
pub llite_max_read_ahead_mb: Option<String>,
#[serde(rename = "llite.max_read_ahead_whole_mb")]
pub llite_max_read_ahead_whole_mb: Option<String>,
#[serde(rename = "llite.statahead_max")]
pub llite_statahead_max: Option<String>,
#[serde(rename = "sys.at_early_margin")]
pub sys_at_early_margin: Option<String>,
#[serde(rename = "sys.at_extra")]
pub sys_at_extra: Option<String>,
#[serde(rename = "sys.at_history")]
pub sys_at_history: Option<String>,
#[serde(rename = "sys.at_max")]
pub sys_at_max: Option<String>,
#[serde(rename = "sys.at_min")]
pub sys_at_min: Option<String>,
#[serde(rename = "sys.ldlm_timeout")]
pub sys_ldlm_timeout: Option<String>,
#[serde(rename = "sys.timeout")]
pub sys_timeout: Option<String>,
}
#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Clone)]
pub struct MdtConfParams {
#[serde(rename = "lov.qos_prio_free")]
lov_qos_prio_free: Option<String>,
#[serde(rename = "lov.qos_threshold_rr")]
lov_qos_threshold_rr: Option<String>,
#[serde(rename = "lov.stripecount")]
lov_stripecount: Option<String>,
#[serde(rename = "lov.stripesize")]
lov_stripesize: Option<String>,
#[serde(rename = "mdt.MDS.mds.threads_max")]
mdt_mds_mds_threads_max: Option<String>,
#[serde(rename = "mdt.MDS.mds.threads_min")]
mdt_mds_mds_threads_min: Option<String>,
#[serde(rename = "mdt.MDS.mds_readpage.threads_max")]
mdt_mds_mds_readpage_threads_max: Option<String>,
#[serde(rename = "mdt.MDS.mds_readpage.threads_min")]
mdt_mds_mds_readpage_threads_min: Option<String>,
#[serde(rename = "mdt.MDS.mds_setattr.threads_max")]
mdt_mds_mds_setattr_threads_max: Option<String>,
#[serde(rename = "mdt.MDS.mds_setattr.threads_min")]
mdt_mds_mds_setattr_threads_min: Option<String>,
#[serde(rename = "mdt.hsm_control")]
mdt_hsm_control: Option<String>,
}
#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Clone)]
pub struct OstConfParams {
#[serde(rename = "osc.active")]
osc_active: Option<String>,
#[serde(rename = "osc.max_dirty_mb")]
osc_max_dirty_mb: Option<String>,
#[serde(rename = "osc.max_pages_per_rpc")]
osc_max_pages_per_rpc: Option<String>,
#[serde(rename = "osc.max_rpcs_in_flight")]
osc_max_rpcs_in_flight: Option<String>,
#[serde(rename = "ost.OSS.ost.threads_max")]
ost_oss_ost_threads_max: Option<String>,
#[serde(rename = "ost.OSS.ost.threads_min")]
ost_oss_ost_threads_min: Option<String>,
#[serde(rename = "ost.OSS.ost_create.threads_max")]
ost_oss_ost_create_threads_max: Option<String>,
#[serde(rename = "ost.OSS.ost_create.threads_min")]
ost_oss_ost_create_threads_min: Option<String>,
#[serde(rename = "ost.OSS.ost_io.threads_max")]
ost_oss_ost_io_threads_max: Option<String>,
#[serde(rename = "ost.OSS.ost_io.threads_min")]
ost_oss_ost_io_threads_min: Option<String>,
#[serde(rename = "ost.read_cache_enable")]
ost_read_cache_enable: Option<String>,
#[serde(rename = "ost.readcache_max_filesize")]
ost_readcache_max_filesize: Option<String>,
#[serde(rename = "ost.sync_journal")]
ost_sync_journal: Option<String>,
#[serde(rename = "ost.sync_on_lock_cancel")]
ost_sync_on_lock_cancel: Option<String>,
#[serde(rename = "ost.writethrough_cache_enable")]
ost_writethrough_cache_enable: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct Volume {
pub filesystem_type: Option<String>,
pub id: u32,
pub kind: String,
pub label: String,
pub resource_uri: String,
pub size: Option<i64>,
pub status: Option<String>,
pub storage_resource: Option<String>,
pub usable_for_lustre: bool,
pub volume_nodes: Vec<VolumeNode>,
}
impl FlatQuery for Volume {}
impl Label for Volume {
fn label(&self) -> &str {
&self.label
}
}
impl Label for &Volume {
fn label(&self) -> &str {
&self.label
}
}
impl db::Id for Volume {
fn id(&self) -> u32 {
self.id
}
}
impl db::Id for &Volume {
fn id(&self) -> u32 {
self.id
}
}
impl EndpointName for Volume {
fn endpoint_name() -> &'static str {
"volume"
}
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct VolumeNode {
pub host: String,
pub host_id: u32,
pub host_label: String,
pub id: u32,
pub path: String,
pub primary: bool,
pub resource_uri: String,
#[serde(rename = "use")]
pub _use: bool,
pub volume_id: u32,
}
impl FlatQuery for VolumeNode {}
impl EndpointName for VolumeNode {
fn endpoint_name() -> &'static str {
"volume_node"
}
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
#[serde(untagged)]
pub enum TargetConfParam {
MdtConfParam(MdtConfParams),
OstConfParam(OstConfParams),
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
#[serde(untagged)]
pub enum VolumeOrResourceUri {
ResourceUri(String),
Volume(Volume),
}
#[derive(serde::Deserialize, serde::Serialize, Clone, Copy, Debug, Eq, PartialEq)]
#[serde(rename_all = "UPPERCASE")]
pub enum TargetKind {
Mgt,
Mdt,
Ost,
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct Target<T> {
pub active_host: Option<String>,
pub active_host_name: String,
pub conf_params: Option<T>,
pub content_type_id: u32,
pub failover_server_name: String,
pub failover_servers: Vec<String>,
pub filesystem: Option<String>,
pub filesystem_id: Option<u32>,
pub filesystem_name: Option<String>,
pub filesystems: Option<Vec<FilesystemShort>>,
pub ha_label: Option<String>,
pub id: u32,
pub immutable_state: bool,
pub index: Option<u32>,
pub inode_count: Option<u64>,
pub inode_size: Option<u32>,
pub kind: TargetKind,
pub label: String,
pub name: String,
pub primary_server: String,
pub primary_server_name: String,
pub resource_uri: String,
pub state: String,
pub state_modified_at: String,
pub uuid: Option<String>,
pub volume: VolumeOrResourceUri,
pub volume_name: String,
}
impl<T> FlatQuery for Target<T> {
fn query() -> Vec<(&'static str, &'static str)> {
vec![("limit", "0"), ("dehydrate__volume", "false")]
}
}
impl<T> ToCompositeId for Target<T> {
fn composite_id(&self) -> CompositeId {
CompositeId(self.content_type_id, self.id)
}
}
impl<T> ToCompositeId for &Target<T> {
fn composite_id(&self) -> CompositeId {
CompositeId(self.content_type_id, self.id)
}
}
impl<T> Label for Target<T> {
fn label(&self) -> &str {
&self.label
}
}
impl<T> Label for &Target<T> {
fn label(&self) -> &str {
&self.label
}
}
impl<T> EndpointName for Target<T> {
fn endpoint_name() -> &'static str {
"target"
}
}
impl<T> db::Id for Target<T> {
fn id(&self) -> u32 {
self.id
}
}
pub type Mdt = Target<MdtConfParams>;
pub type Mgt = Target<Option<TargetConfParam>>;
pub type Ost = Target<OstConfParams>;
#[derive(serde::Deserialize, serde::Serialize, PartialEq, Clone, Debug)]
pub struct HsmControlParamMdt {
pub id: String,
pub kind: String,
pub resource: String,
pub conf_params: MdtConfParams,
}
#[derive(serde::Deserialize, serde::Serialize, PartialEq, Clone, Debug)]
pub struct HsmControlParam {
pub long_description: String,
pub param_key: String,
pub param_value: String,
pub verb: String,
pub mdt: HsmControlParamMdt,
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct Filesystem {
pub bytes_free: Option<f64>,
pub bytes_total: Option<f64>,
pub cdt_mdt: Option<String>,
pub cdt_status: Option<String>,
pub client_count: Option<u64>,
pub conf_params: FilesystemConfParams,
pub content_type_id: u32,
pub files_free: Option<u64>,
pub files_total: Option<u64>,
pub hsm_control_params: Option<Vec<HsmControlParam>>,
pub id: u32,
pub immutable_state: bool,
pub label: String,
pub mdts: Vec<Mdt>,
pub mgt: String,
pub mount_command: String,
pub mount_path: String,
pub name: String,
pub osts: Vec<String>,
pub resource_uri: String,
pub state: String,
pub state_modified_at: String,
}
impl FlatQuery for Filesystem {
fn query() -> Vec<(&'static str, &'static str)> {
vec![("limit", "0"), ("dehydrate__mgt", "false")]
}
}
impl ToCompositeId for Filesystem {
fn composite_id(&self) -> CompositeId {
CompositeId(self.content_type_id, self.id)
}
}
impl ToCompositeId for &Filesystem {
fn composite_id(&self) -> CompositeId {
CompositeId(self.content_type_id, self.id)
}
}
impl Label for Filesystem {
fn label(&self) -> &str {
&self.label
}
}
impl Label for &Filesystem {
fn label(&self) -> &str {
&self.label
}
}
impl db::Id for Filesystem {
fn id(&self) -> u32 {
self.id
}
}
impl db::Id for &Filesystem {
fn id(&self) -> u32 {
self.id
}
}
impl EndpointName for Filesystem {
fn endpoint_name() -> &'static str {
"filesystem"
}
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct FilesystemShort {
pub id: u32,
pub name: String,
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Copy, Debug)]
pub enum AlertRecordType {
AlertState,
LearnEvent,
AlertEvent,
SyslogEvent,
ClientConnectEvent,
CommandRunningAlert,
CommandSuccessfulAlert,
CommandCancelledAlert,
CommandErroredAlert,
CorosyncUnknownPeersAlert,
CorosyncToManyPeersAlert,
CorosyncNoPeersAlert,
CorosyncStoppedAlert,
StonithNotEnabledAlert,
PacemakerStoppedAlert,
HostContactAlert,
HostOfflineAlert,
HostRebootEvent,
UpdatesAvailableAlert,
TargetOfflineAlert,
TargetFailoverAlert,
TargetRecoveryAlert,
StorageResourceOffline,
StorageResourceAlert,
StorageResourceLearnEvent,
PowerControlDeviceUnavailableAlert,
IpmiBmcUnavailableAlert,
LNetOfflineAlert,
LNetNidsChangedAlert,
StratagemUnconfiguredAlert,
TimeOutOfSyncAlert,
NoTimeSyncAlert,
MultipleTimeSyncAlert,
UnknownTimeSyncAlert,
}
impl ToString for AlertRecordType {
fn to_string(&self) -> String {
serde_json::to_string(self).unwrap().replace("\"", "")
}
}
#[derive(
serde::Serialize, serde::Deserialize, Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq,
)]
pub enum AlertSeverity {
DEBUG,
INFO,
WARNING,
ERROR,
CRITICAL,
}
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct Alert {
pub _message: Option<String>,
pub active: Option<bool>,
pub affected: Option<Vec<String>>,
pub affected_composite_ids: Option<Vec<CompositeId>>,
pub alert_item: String,
pub alert_item_id: Option<i32>,
pub alert_item_str: String,
pub alert_type: String,
pub begin: String,
pub dismissed: bool,
pub end: Option<String>,
pub id: u32,
pub lustre_pid: Option<i32>,
pub message: String,
pub record_type: AlertRecordType,
pub resource_uri: String,
pub severity: AlertSeverity,
pub variant: String,
}
impl FlatQuery for Alert {
fn query() -> Vec<(&'static str, &'static str)> {
vec![("limit", "0"), ("active", "true")]
}
}
impl EndpointName for Alert {
fn endpoint_name() -> &'static str {
"alert"
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct Substitution {
pub start: String,
pub end: String,
pub label: String,
pub resource_uri: String,
}
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum MessageClass {
Normal,
Lustre,
LustreError,
Copytool,
CopytoolError,
}
#[derive(Serialize_repr, Deserialize_repr, PartialEq, Eq, Ord, PartialOrd, Clone, Copy, Debug)]
#[repr(u8)]
pub enum LogSeverity {
Emergency = 0,
Alert = 1,
Critical = 2,
Error = 3,
Warning = 4,
Notice = 5,
Informational = 6,
Debug = 7,
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct Log {
pub datetime: String,
pub facility: u32,
pub fqdn: String,
pub id: u32,
pub message: String,
pub message_class: MessageClass,
pub resource_uri: String,
pub severity: LogSeverity,
pub substitutions: Vec<Substitution>,
pub tag: String,
}
impl EndpointName for Log {
fn endpoint_name() -> &'static str {
"log"
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct StratagemConfiguration {
pub content_type_id: u32,
pub filesystem: String,
pub id: u32,
pub immutable_state: bool,
pub interval: u64,
pub label: String,
pub not_deleted: Option<bool>,
pub purge_duration: Option<u64>,
pub report_duration: Option<u64>,
pub resource_uri: String,
pub state: String,
pub state_modified_at: String,
}
impl EndpointName for StratagemConfiguration {
fn endpoint_name() -> &'static str {
"stratagem_configuration"
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct AlertType {
pub description: String,
pub id: String,
pub resource_uri: String,
}
impl EndpointName for AlertType {
fn endpoint_name() -> &'static str {
"alert_type"
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct AlertSubscription {
pub alert_type: AlertType,
pub id: u32,
pub resource_uri: String,
pub user: String,
}
impl EndpointName for AlertSubscription {
fn endpoint_name() -> &'static str {
"alert_subscription"
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum GroupType {
Superusers,
FilesystemAdministrators,
FilesystemUsers,
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct Group {
pub id: u32,
pub name: GroupType,
pub resource_uri: String,
}
impl EndpointName for Group {
fn endpoint_name() -> &'static str {
"group"
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct User {
pub alert_subscriptions: Option<Vec<AlertSubscription>>,
pub email: String,
pub first_name: String,
pub full_name: String,
pub groups: Option<Vec<Group>>,
pub id: u32,
pub is_superuser: bool,
pub last_name: String,
pub new_password1: Option<String>,
pub new_password2: Option<String>,
pub password1: Option<String>,
pub password2: Option<String>,
pub resource_uri: String,
pub username: String,
}
impl EndpointName for User {
fn endpoint_name() -> &'static str {
"user"
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct Session {
pub read_enabled: bool,
pub resource_uri: String,
pub user: Option<User>,
}
impl EndpointName for Session {
fn endpoint_name() -> &'static str {
"session"
}
}
pub mod time {
#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum Synced {
Synced,
Unsynced,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub enum State {
None,
Multiple,
Synced,
Unsynced(Option<Offset>),
Unknown,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, PartialEq)]
pub struct Offset(String);
impl<T: ToString> From<T> for Offset {
fn from(s: T) -> Self {
Self(s.to_string())
}
}
}
#[derive(Debug, Default, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct ElementState {
pub name: String,
pub configurable: bool,
}
#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum UnitFileState {
Disabled,
Enabled,
}
#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum ActiveState {
Inactive,
Active,
Activating,
Failed,
}
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
pub enum RunState {
Stopped,
Enabled,
Activating,
Failed,
Started,
Setup,
}
impl Default for RunState {
fn default() -> Self {
Self::Stopped
}
}
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum ServiceState {
Unconfigured,
Configured(RunState),
}
impl Default for ServiceState {
fn default() -> Self {
Self::Unconfigured
}
}
impl fmt::Display for ServiceState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Unconfigured => f.pad(&format!("{:?}", self)),
Self::Configured(r) => f.pad(&format!("{:?}", r)),
}
}
}
#[derive(serde::Deserialize, serde::Serialize, PartialEq, Clone, Debug)]
pub struct ResourceAgentType {
pub standard: String,
pub provider: Option<String>,
pub ocftype: String,
}
impl ResourceAgentType {
pub fn new<'a>(
standard: impl Into<Option<&'a str>>,
provider: impl Into<Option<&'a str>>,
ocftype: impl Into<Option<&'a str>>,
) -> Self {
Self {
standard: standard.into().map(str::to_string).unwrap_or_default(),
provider: provider.into().map(str::to_string),
ocftype: ocftype.into().map(str::to_string).unwrap_or_default(),
}
}
}
impl fmt::Display for ResourceAgentType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.provider {
Some(provider) => write!(f, "{}:{}:{}", self.standard, provider, self.ocftype),
None => write!(f, "{}:{}", self.standard, self.ocftype),
}
}
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct ResourceAgentInfo {
pub agent: ResourceAgentType,
pub id: String,
pub args: HashMap<String, String>,
}
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum ConfigState {
Unknown,
Default,
IML,
Other,
}
impl Default for ConfigState {
fn default() -> Self {
Self::Unknown
}
}
impl fmt::Display for ConfigState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad(&format!("{:?}", self))
}
}
#[derive(Debug, Default, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
pub struct ComponentState<T: Default> {
pub service: ServiceState,
pub config: ConfigState,
pub elements: Vec<ElementState>,
pub info: String,
pub state: T,
}
#[derive(Debug, Default, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct OstPoolApi {
pub id: u32,
pub resource_uri: String,
#[serde(flatten)]
pub ost: OstPool,
}
impl EndpointName for OstPoolApi {
fn endpoint_name() -> &'static str {
"ostpool"
}
}
impl FlatQuery for OstPoolApi {}
impl std::fmt::Display for OstPoolApi {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[#{}] {}", self.id, self.ost)
}
}
pub type FsPoolMap = BTreeMap<String, BTreeSet<OstPool>>;
#[derive(Debug, Default, Clone, Eq, serde::Serialize, serde::Deserialize)]
pub struct OstPool {
pub name: String,
pub filesystem: String,
pub osts: Vec<String>,
}
impl std::fmt::Display for OstPool {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}.{} [{}]",
self.filesystem,
self.name,
self.osts.join(", ")
)
}
}
impl Ord for OstPool {
fn cmp(&self, other: &Self) -> Ordering {
let x = self.filesystem.cmp(&other.filesystem);
if x != Ordering::Equal {
return x;
}
self.name.cmp(&other.name)
}
}
impl PartialOrd for OstPool {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for OstPool {
fn eq(&self, other: &Self) -> bool {
self.filesystem == other.filesystem && self.name == other.name
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
pub enum Branding {
Whamcloud,
Ddn,
DdnAi400,
}
impl Default for Branding {
fn default() -> Self {
Self::Whamcloud
}
}
impl From<String> for Branding {
fn from(x: String) -> Self {
match x.to_lowercase().as_str() {
"whamcloud" => Self::Whamcloud,
"ddn" => Self::Ddn,
"ddnai400" => Self::DdnAi400,
_ => Self::Whamcloud,
}
}
}
impl fmt::Display for Branding {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Ddn => write!(f, "ddn"),
Self::Whamcloud => write!(f, "whamcloud"),
Self::DdnAi400 => write!(f, "ddnai400"),
}
}
}
pub mod db;
pub mod warp_drive;