use std::{collections::HashMap, str::FromStr};
use chrono::{DateTime, Duration, Utc};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use utoipa::{IntoParams, ToSchema};
use uuid::Uuid;
use validator::{Validate, ValidationError};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum AuthProvider {
Local,
OAuth { provider: String },
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateUserRequest {
#[validate(length(min = 3, max = 32))]
pub username: String,
#[validate(email)]
pub email: String,
#[validate(length(min = 12, max = 128))]
pub password: String,
#[validate(length(max = 64))]
pub display_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct LoginRequest {
#[validate(length(min = 1, max = 320))]
pub username_or_email: String,
#[validate(length(min = 1, max = 128))]
pub password: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct RefreshTokenRequest {
#[validate(length(min = 32, max = 128))]
pub refresh_token: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct UpdateUserRequest {
#[validate(length(min = 1, max = 64))]
pub display_name: Option<String>,
#[validate(length(min = 1, max = 512))]
pub bio: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct User {
pub id: Uuid,
pub username: String,
pub email: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bio: Option<String>,
#[serde(default, skip_serializing)]
#[schema(ignore)]
pub roles: Vec<String>,
#[serde(default)]
pub groups: Vec<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_login: Option<DateTime<Utc>>,
pub is_active: bool,
pub is_verified: bool,
pub provider: AuthProvider,
}
impl User {
#[must_use]
pub fn effective_roles(&self) -> &[String] {
if self.roles.is_empty() {
&self.groups
} else {
&self.roles
}
}
#[must_use]
pub fn has_role(&self, role: &str) -> bool {
self.effective_roles()
.iter()
.any(|value| value.eq_ignore_ascii_case(role))
}
#[must_use]
pub fn has_any_role(&self, roles: &[&str]) -> bool {
self.effective_roles()
.iter()
.any(|value| roles.iter().any(|role| value.eq_ignore_ascii_case(role)))
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[allow(clippy::struct_excessive_bools)]
pub struct AdminUserSummary {
pub id: Uuid,
pub username: String,
pub email: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bio: Option<String>,
#[serde(default, skip_serializing)]
#[schema(ignore)]
pub roles: Vec<String>,
#[serde(default)]
pub groups: Vec<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_login: Option<DateTime<Utc>>,
pub is_active: bool,
pub is_verified: bool,
pub provider: AuthProvider,
pub is_admin: bool,
pub can_manage_api_keys: bool,
}
impl AdminUserSummary {
#[must_use]
pub fn from_user(user: &User) -> Self {
let is_admin = user.has_role("admin");
let can_manage_api_keys = user.has_role("api_admin");
Self {
id: user.id,
username: user.username.clone(),
email: user.email.clone(),
display_name: user.display_name.clone(),
bio: user.bio.clone(),
roles: user.effective_roles().to_vec(),
groups: user.effective_roles().to_vec(),
created_at: user.created_at,
updated_at: user.updated_at,
last_login: user.last_login,
is_active: user.is_active,
is_verified: user.is_verified,
provider: user.provider.clone(),
is_admin,
can_manage_api_keys,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AdminUserListResponse {
pub users: Vec<AdminUserSummary>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UpdateUserAccessRequest {
pub is_admin: Option<bool>,
pub can_manage_api_keys: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TokenResponse {
pub access_token: String,
pub refresh_token: String,
pub token_type: String,
pub expires_in: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ProviderTokenResponse {
pub access_token: String,
pub token_type: String,
pub expires_in: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scope: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum AgentStatus {
Online,
Offline,
Draining,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AgentInputCapability {
#[serde(default)]
pub keyboard: bool,
#[serde(default)]
pub mouse: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ScreenCaptureCapability {
pub supported: bool,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub formats: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Capabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub os: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tasks: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub input: Option<AgentInputCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub screen_capture: Option<ScreenCaptureCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_concurrency: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CpuInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
pub logical_cores: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub physical_cores: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub usage_percent: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MemoryInfo {
pub total_bytes: u64,
pub available_bytes: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GpuInfo {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub memory_total_bytes: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub memory_used_bytes: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct DiskInfo {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub mount_point: Option<String>,
pub total_bytes: u64,
pub available_bytes: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub filesystem: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AgentSystemInfo {
pub cpu: CpuInfo,
pub memory: MemoryInfo,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub gpus: Vec<GpuInfo>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub disks: Vec<DiskInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AgentSystemSnapshot {
pub captured_at: DateTime<Utc>,
pub system: AgentSystemInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VncTarget {
pub id: String,
pub name: String,
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub notes: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum VncSessionState {
Pending,
Active,
Revoked,
Expired,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VncSession {
pub id: Uuid,
pub target_id: String,
pub state: VncSessionState,
pub created_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub connect_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub password: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_by: Option<Uuid>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateVncSessionRequest {
#[validate(length(min = 1, max = 128))]
pub target_id: String,
#[serde(default)]
pub duration_minutes: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none", default)]
#[validate(length(max = 64))]
pub password: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Agent {
pub id: Uuid,
pub name: String,
pub status: AgentStatus,
pub last_seen: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub load: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub queue_depth: Option<u32>,
pub capabilities: Capabilities,
#[serde(default)]
pub metadata: HashMap<String, Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub system: Option<AgentSystemInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct RegisterAgentRequest {
#[validate(length(min = 1, max = 128))]
pub name: String,
pub capabilities: Capabilities,
#[serde(default)]
pub metadata: HashMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AgentWithToken {
#[serde(flatten)]
pub agent: Agent,
pub token: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct UpdateAgentRequest {
#[validate(length(min = 1, max = 128))]
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<AgentStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Heartbeat {
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<AgentStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub load: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub queue_depth: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub system: Option<AgentSystemInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum AgentInstallChannel {
Ssh,
Wmi,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum DeploymentStatus {
Pending,
Running,
Succeeded,
Failed,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct DeploymentLog {
pub ts: DateTime<Utc>,
pub level: String,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
pub struct DeploymentAgentConfig {
#[validate(length(min = 1, max = 128))]
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub capabilities: Capabilities,
#[serde(default)]
pub metadata: HashMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Default)]
pub struct DeploymentInstallOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub download_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub install_path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bootstrap_script: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct SshDeployment {
#[validate(length(min = 1, max = 255))]
pub host: String,
#[serde(default = "SshDeployment::default_port")]
pub port: u16,
#[validate(length(min = 1, max = 64))]
pub username: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub private_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub password: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub install_path: Option<String>,
}
impl SshDeployment {
#[must_use]
const fn default_port() -> u16 {
22
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct WmiDeployment {
#[validate(length(min = 1, max = 255))]
pub host: String,
#[validate(length(min = 1, max = 128))]
pub username: String,
#[validate(length(min = 1, max = 256))]
pub password: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateAgentDeploymentRequest {
pub channel: AgentInstallChannel,
#[validate(nested)]
#[serde(skip_serializing_if = "Option::is_none")]
pub ssh: Option<SshDeployment>,
#[validate(nested)]
#[serde(skip_serializing_if = "Option::is_none")]
pub wmi: Option<WmiDeployment>,
#[validate(nested)]
pub agent: DeploymentAgentConfig,
#[serde(skip_serializing_if = "Option::is_none")]
pub install: Option<DeploymentInstallOptions>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AgentDeploymentTarget {
pub host: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub port: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub transport: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AgentDeployment {
pub id: Uuid,
pub channel: AgentInstallChannel,
pub target: AgentDeploymentTarget,
pub status: DeploymentStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub status_message: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub install_path: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub logs: Vec<DeploymentLog>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum OAuthGrantType {
AuthorizationCode,
RefreshToken,
ClientCredentials,
}
impl OAuthGrantType {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::AuthorizationCode => "authorization_code",
Self::RefreshToken => "refresh_token",
Self::ClientCredentials => "client_credentials",
}
}
}
impl FromStr for OAuthGrantType {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"authorization_code" | "code" => Ok(Self::AuthorizationCode),
"refresh_token" => Ok(Self::RefreshToken),
"client_credentials" => Ok(Self::ClientCredentials),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum CodeChallengeMethod {
Plain,
S256,
}
impl CodeChallengeMethod {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Plain => "plain",
Self::S256 => "S256",
}
}
}
impl FromStr for CodeChallengeMethod {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"plain" => Ok(Self::Plain),
"S256" | "s256" => Ok(Self::S256),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct OAuthClient {
pub client_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub redirect_uris: Vec<String>,
pub allowed_scopes: Vec<String>,
pub allowed_grant_types: Vec<OAuthGrantType>,
pub is_confidential: bool,
pub is_active: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub secret_preview: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct OAuthClientWithSecret {
pub client: OAuthClient,
#[serde(skip_serializing_if = "Option::is_none")]
pub client_secret: Option<String>,
}
#[derive(Debug, Clone)]
pub struct StoredOAuthClient {
pub client: OAuthClient,
pub secret_hash: Option<String>,
}
#[derive(Debug, Clone)]
pub struct NewOAuthClient {
pub client_id: String,
pub name: Option<String>,
pub secret_hash: Option<String>,
pub secret_preview: Option<String>,
pub redirect_uris: Vec<String>,
pub allowed_scopes: Vec<String>,
pub allowed_grant_types: Vec<OAuthGrantType>,
pub is_confidential: bool,
pub is_active: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
pub struct OAuthClientUpdate {
pub name: Option<String>,
pub redirect_uris: Option<Vec<String>>,
pub allowed_scopes: Option<Vec<String>>,
pub allowed_grant_types: Option<Vec<OAuthGrantType>>,
pub is_confidential: Option<bool>,
pub is_active: Option<bool>,
pub secret_hash: Option<String>,
pub secret_preview: Option<String>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct OAuthClientListResponse {
pub clients: Vec<OAuthClient>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateOAuthClientRequest {
#[validate(length(min = 3, max = 96))]
pub name: Option<String>,
#[validate(length(min = 8, max = 96))]
pub client_id: Option<String>,
#[validate(length(min = 1))]
pub redirect_uris: Vec<String>,
#[validate(length(min = 1))]
pub allowed_scopes: Vec<String>,
#[validate(length(min = 1))]
pub allowed_grant_types: Vec<OAuthGrantType>,
pub is_confidential: Option<bool>,
#[validate(length(min = 16, max = 256))]
pub client_secret: Option<String>,
pub is_active: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct UpdateOAuthClientRequest {
#[validate(length(min = 3, max = 96))]
pub name: Option<String>,
#[validate(length(min = 1))]
pub redirect_uris: Option<Vec<String>>,
#[validate(length(min = 1))]
pub allowed_scopes: Option<Vec<String>>,
#[validate(length(min = 1))]
pub allowed_grant_types: Option<Vec<OAuthGrantType>>,
pub is_confidential: Option<bool>,
pub is_active: Option<bool>,
}
#[derive(Debug, Clone)]
pub struct OAuthAuthorizationCode {
pub code: String,
pub client_id: String,
pub user_id: Uuid,
pub redirect_uri: String,
pub scope: Vec<String>,
pub code_challenge: Option<String>,
pub code_challenge_method: Option<CodeChallengeMethod>,
pub nonce: Option<String>,
pub created_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
pub struct OAuthRefreshTokenData {
pub fingerprint: String,
pub token_hash: String,
pub client_id: String,
pub user_id: Option<Uuid>,
pub scope: Vec<String>,
pub created_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
}
#[derive(Debug, Deserialize, Serialize, IntoParams, ToSchema)]
#[serde(rename_all = "snake_case")]
pub struct AuthorizationRequest {
pub response_type: Option<String>,
pub client_id: String,
pub redirect_uri: Option<String>,
pub scope: Option<String>,
pub state: Option<String>,
pub code_challenge: Option<String>,
pub code_challenge_method: Option<String>,
pub nonce: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub struct TokenRequest {
pub grant_type: String,
pub code: Option<String>,
pub redirect_uri: Option<String>,
pub code_verifier: Option<String>,
pub refresh_token: Option<String>,
pub scope: Option<String>,
pub client_id: Option<String>,
pub client_secret: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum TaskKind {
Command,
Keyboard,
Mouse,
Capture,
SystemInfo,
FilesystemCrawl,
Custom,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum TaskState {
Queued,
Assigned,
Running,
WaitingInput,
Cancelling,
Cancelled,
Succeeded,
Failed,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TaskStatus {
pub state: TaskState,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub progress: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub step: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
impl TaskStatus {
#[must_use]
pub fn queued(now: DateTime<Utc>) -> Self {
Self {
state: TaskState::Queued,
progress: Some(0.0),
step: None,
message: None,
updated_at: Some(now),
error: None,
}
}
#[must_use]
pub fn with_state(mut self, state: TaskState, now: DateTime<Utc>) -> Self {
self.state = state;
self.updated_at = Some(now);
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateTaskRequest {
pub kind: TaskKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub run_id: Option<Uuid>,
#[serde(default)]
pub payload: Value,
#[serde(default)]
pub priority: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub deadline: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AgentTask {
pub id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub run_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_info: Option<AgentSystemInfo>,
pub kind: TaskKind,
pub payload: Value,
pub priority: i32,
pub status: TaskStatus,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deadline: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub result: Option<TaskResult>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub artifacts: Vec<Artifact>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TaskStatusUpdate {
#[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<TaskState>,
#[serde(skip_serializing_if = "Option::is_none")]
pub progress: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub step: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CancelRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PollRequest {
#[serde(default = "PollRequest::default_max_tasks")]
pub max_tasks: u32,
#[serde(default = "PollRequest::default_wait_seconds")]
pub wait_seconds: u64,
}
impl PollRequest {
const fn default_max_tasks() -> u32 {
1
}
const fn default_wait_seconds() -> u64 {
15
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Default)]
pub struct SystemInfoRequest {
#[serde(default)]
pub include_usage: bool,
}
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Default)]
pub struct HashingRequest {
#[serde(default)]
pub md5: bool,
#[serde(default)]
pub sha256: bool,
#[serde(default)]
pub sha512: bool,
#[serde(default)]
pub blake3: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_concurrent: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub buffer_size: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Default)]
pub struct FileHashes {
#[serde(skip_serializing_if = "Option::is_none")]
pub md5: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sha256: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sha512: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub blake3: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema, Default)]
#[serde(rename_all = "snake_case")]
pub enum FileVisibility {
#[default]
Private,
Shared,
Public,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateFileRequest {
#[validate(length(min = 1, max = 255))]
pub name: String,
#[validate(length(max = 1024))]
pub description: Option<String>,
#[validate(length(max = 256))]
pub content_type: Option<String>,
#[serde(default)]
pub visibility: FileVisibility,
#[serde(default)]
pub shared_with: Vec<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data_base64: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hashes: Option<FileHashes>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CaptureFileRequest {
#[validate(length(min = 1, max = 255))]
pub name: String,
#[validate(length(max = 1024))]
pub description: Option<String>,
#[validate(length(max = 256))]
pub content_type: Option<String>,
#[serde(default)]
pub visibility: FileVisibility,
#[serde(default)]
pub shared_with: Vec<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data_base64: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hashes: Option<FileHashes>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema, Default)]
pub struct UpdateFileRequest {
#[serde(skip_serializing_if = "Option::is_none")]
#[validate(length(min = 1, max = 255))]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[validate(length(max = 1024))]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub visibility: Option<FileVisibility>,
#[serde(skip_serializing_if = "Option::is_none")]
pub shared_with: Option<Vec<Uuid>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct FileMetadata {
pub id: Uuid,
pub owner_id: Uuid,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_type: Option<String>,
pub size_bytes: i64,
pub visibility: FileVisibility,
#[serde(skip_serializing_if = "Option::is_none")]
pub hashes: Option<FileHashes>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub shared_with: Vec<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub download_url: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct FileDownloadUrl {
pub url: String,
pub expires_in_seconds: u64,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum FilePermission {
Read,
Write,
Delete,
Admin,
}
impl std::str::FromStr for FilePermission {
type Err = ValidationError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value.to_ascii_lowercase().as_str() {
"read" => Ok(Self::Read),
"write" => Ok(Self::Write),
"delete" => Ok(Self::Delete),
"admin" => Ok(Self::Admin),
_ => Err(ValidationError::new("file_permission")),
}
}
}
impl std::fmt::Display for FilePermission {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let value = match self {
Self::Read => "read",
Self::Write => "write",
Self::Delete => "delete",
Self::Admin => "admin",
};
write!(f, "{value}")
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
#[validate(schema(function = "validate_grant_file_permission"))]
pub struct GrantFilePermissionRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub team_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
#[validate(length(min = 1, max = 128))]
pub role: Option<String>,
pub permission: FilePermission,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct FilePermissionResponse {
pub id: Uuid,
pub file_id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub team_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
pub permission: FilePermission,
pub granted_by: Uuid,
pub granted_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct FileDownloadResponse {
pub downloaded_by: Uuid,
pub downloaded_at: DateTime<Utc>,
pub download_size: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_agent: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct FileStatsResponse {
pub total_downloads: i64,
pub total_download_size: i64,
pub unique_downloaders: i64,
pub recent_downloads: Vec<FileDownloadResponse>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct UploadFileRequest {
#[validate(length(min = 1, max = 255))]
pub filename: String,
#[validate(length(min = 1, max = 256))]
pub content_type: String,
#[validate(range(min = 1))]
pub file_size: i64,
#[serde(skip_serializing_if = "Option::is_none")]
#[validate(length(max = 1024))]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub visibility: Option<FileVisibility>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PresignedUrlResponse {
pub upload_url: String,
pub expires_at: DateTime<Utc>,
pub file_id: Uuid,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct StartMultipartUploadRequest {
#[validate(length(min = 1, max = 255))]
pub filename: String,
#[validate(length(min = 1, max = 256))]
pub content_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub expected_size: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[validate(length(max = 1024))]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub visibility: Option<FileVisibility>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UploadSessionResponse {
pub session_id: Uuid,
pub upload_id: String,
pub upload_url: String,
pub expires_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UploadPartInfo {
pub part_number: i32,
pub etag: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CompleteMultipartUploadRequest {
#[validate(length(min = 1, max = 512))]
pub upload_id: String,
pub parts: Vec<UploadPartInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum FilesystemEntryType {
File,
Directory,
Symlink,
Other,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct FilesystemEntry {
pub path: String,
pub entry_type: FilesystemEntryType,
#[serde(skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub modified: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hashes: Option<FileHashes>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct FilesystemCrawlRequest {
pub root: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_depth: Option<u32>,
#[serde(default)]
pub follow_symlinks: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub hash: Option<HashingRequest>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct FilesystemCrawlResult {
pub root: String,
pub entries: Vec<FilesystemEntry>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TaskResult {
pub status: String,
#[serde(default)]
pub output: Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub artifacts: Vec<Artifact>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TaskLogAppend {
pub stream: Option<String>,
pub lines: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TaskLogEvent {
pub ts: DateTime<Utc>,
pub stream: String,
pub line: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct RunLogEvent {
pub ts: DateTime<Utc>,
pub stream: String,
pub line: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub task_id: Option<Uuid>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CommandRequest {
pub command: String,
#[serde(default)]
pub args: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cwd: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub env: HashMap<String, String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timeout_seconds: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CommandResponse {
pub command_id: Uuid,
pub task_id: Uuid,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CommandOutputEvent {
pub ts: DateTime<Utc>,
pub stream: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exit_code: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct KeyboardInput {
pub text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub delay_ms: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MouseInput {
pub action: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub x: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub y: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub button: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scroll_x: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scroll_y: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ScreenCaptureRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub region: Option<CaptureRegion>,
#[serde(default)]
pub include_cursor: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quality: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub display: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CaptureRegion {
pub x: i32,
pub y: i32,
pub width: i32,
pub height: i32,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ScreenCaptureTicket {
pub capture_id: Uuid,
pub task_id: Uuid,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ScreenCapture {
pub id: Uuid,
pub task_id: Uuid,
pub agent_id: Uuid,
pub status: String,
pub format: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub download_url: Option<String>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Artifact {
pub id: Uuid,
pub task_id: Uuid,
pub name: String,
pub content_type: String,
pub size_bytes: u64,
pub download_url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateArtifactRequest {
pub task_id: Uuid,
#[validate(length(min = 1))]
pub name: String,
#[validate(length(min = 1))]
pub content_type: String,
pub size_bytes: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ArtifactUpload {
pub artifact: Artifact,
pub upload_url: String,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub headers: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct StoredUser {
pub user: User,
pub password_hash: Option<String>,
}
#[derive(Debug, Clone)]
pub struct RefreshTokenData {
pub user_id: Uuid,
pub expires_at: DateTime<Utc>,
pub token_hash: String,
pub fingerprint: String,
}
#[derive(Debug, Clone)]
pub struct OAuthStateRecord {
pub provider: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ErrorResponse {
pub error: String,
pub status: u16,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum ApiKeyRole {
Owner,
Manager,
Contributor,
Viewer,
}
impl ApiKeyRole {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Owner => "owner",
Self::Manager => "manager",
Self::Contributor => "contributor",
Self::Viewer => "viewer",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum ApiKeyStatus {
Active,
Revoked,
Expired,
}
impl ApiKeyStatus {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Active => "active",
Self::Revoked => "revoked",
Self::Expired => "expired",
}
}
}
impl FromStr for ApiKeyRole {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"owner" => Ok(Self::Owner),
"manager" => Ok(Self::Manager),
"contributor" => Ok(Self::Contributor),
"viewer" => Ok(Self::Viewer),
_ => Err(()),
}
}
}
impl FromStr for ApiKeyStatus {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"active" => Ok(Self::Active),
"revoked" => Ok(Self::Revoked),
"expired" => Ok(Self::Expired),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, ToSchema)]
#[serde(transparent)]
pub struct ApiKeyScope(pub String);
impl ApiKeyScope {
#[must_use]
pub fn new(value: impl Into<String>) -> Self {
Self(value.into())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ApiKey {
pub id: Uuid,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub role: ApiKeyRole,
#[serde(skip_serializing_if = "Option::is_none")]
pub scopes: Option<Vec<ApiKeyScope>>,
pub status: ApiKeyStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_used_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub created_by: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub managed_by: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_preview: Option<String>,
}
impl ApiKey {
#[must_use]
pub fn to_summary(&self) -> ApiKeySummary {
ApiKeySummary {
id: self.id,
name: self.name.clone(),
role: self.role.clone(),
status: self.status.clone(),
created_at: self.created_at,
expires_at: self.expires_at,
last_used_at: self.last_used_at,
token_preview: self.token_preview.clone(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ApiKeySummary {
pub id: Uuid,
pub name: String,
pub role: ApiKeyRole,
pub status: ApiKeyStatus,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_used_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_preview: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ApiKeyWithSecret {
#[serde(flatten)]
pub api_key: ApiKey,
pub secret: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CreateApiKeyRequest {
pub name: String,
pub description: Option<String>,
pub role: ApiKeyRole,
pub scopes: Option<Vec<ApiKeyScope>>,
pub expires_at: Option<DateTime<Utc>>,
pub ttl_days: Option<i32>,
pub metadata: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UpdateApiKeyRequest {
pub name: Option<String>,
pub description: Option<Option<String>>,
pub role: Option<ApiKeyRole>,
pub scopes: Option<Option<Vec<ApiKeyScope>>>,
pub status: Option<ApiKeyStatus>,
pub expires_at: Option<Option<DateTime<Utc>>>,
pub ttl_days: Option<i32>,
pub metadata: Option<Option<HashMap<String, String>>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct RotateApiKeyRequest {
pub expires_at: Option<DateTime<Utc>>,
pub ttl_days: Option<i32>,
pub reason: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ApiKeyListResponse {
pub object: String,
pub data: Vec<ApiKeySummary>,
pub has_more: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub first_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_id: Option<Uuid>,
}
#[derive(Debug, Clone)]
pub struct NewApiKey {
pub id: Uuid,
pub name: String,
pub description: Option<String>,
pub role: ApiKeyRole,
pub scopes: Option<Vec<ApiKeyScope>>,
pub status: ApiKeyStatus,
pub secret_hash: String,
pub token_preview: Option<String>,
pub created_by: Uuid,
pub managed_by: Option<Uuid>,
pub metadata: Option<HashMap<String, String>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub expires_at: Option<DateTime<Utc>>,
pub last_used_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
pub struct ApiKeyUpdate {
pub name: Option<String>,
pub description: Option<Option<String>>,
pub role: Option<ApiKeyRole>,
pub scopes: Option<Option<Vec<ApiKeyScope>>>,
pub status: Option<ApiKeyStatus>,
pub token_preview: Option<Option<String>>,
pub secret_hash: Option<String>,
pub expires_at: Option<Option<DateTime<Utc>>>,
pub metadata: Option<Option<HashMap<String, String>>>,
pub managed_by: Option<Uuid>,
pub last_used_at: Option<Option<DateTime<Utc>>>,
pub updated_at: DateTime<Utc>,
}
impl ApiKeyUpdate {
#[must_use]
pub const fn new(updated_at: DateTime<Utc>) -> Self {
Self {
name: None,
description: None,
role: None,
scopes: None,
status: None,
token_preview: None,
secret_hash: None,
expires_at: None,
metadata: None,
managed_by: None,
last_used_at: None,
updated_at,
}
}
}
#[derive(Debug, Clone)]
pub struct StoredApiKey {
pub api_key: ApiKey,
pub secret_hash: String,
}
impl StoredApiKey {
#[must_use]
pub fn into_api_key(self) -> ApiKey {
self.api_key
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum OrganizationRole {
Owner,
Admin,
Member,
Viewer,
}
impl OrganizationRole {
#[must_use]
pub const fn is_admin_like(&self) -> bool {
matches!(self, Self::Owner | Self::Admin)
}
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Owner => "owner",
Self::Admin => "admin",
Self::Member => "member",
Self::Viewer => "viewer",
}
}
}
impl FromStr for OrganizationRole {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"owner" => Ok(Self::Owner),
"admin" => Ok(Self::Admin),
"member" => Ok(Self::Member),
"viewer" => Ok(Self::Viewer),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum OrganizationMemberStatus {
Pending,
Active,
Suspended,
Removed,
}
impl OrganizationMemberStatus {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Pending => "pending",
Self::Active => "active",
Self::Suspended => "suspended",
Self::Removed => "removed",
}
}
}
impl FromStr for OrganizationMemberStatus {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"pending" => Ok(Self::Pending),
"active" => Ok(Self::Active),
"suspended" => Ok(Self::Suspended),
"removed" => Ok(Self::Removed),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Organization {
pub id: Uuid,
pub name: String,
pub slug: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, String>>,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub is_active: bool,
pub member_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateOrganizationRequest {
#[validate(length(min = 3, max = 128))]
pub name: String,
#[validate(length(min = 3, max = 64))]
pub slug: Option<String>,
#[validate(length(max = 1024))]
pub description: Option<String>,
pub metadata: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct UpdateOrganizationRequest {
#[validate(length(min = 3, max = 128))]
pub name: Option<String>,
#[validate(length(min = 3, max = 64))]
pub slug: Option<Option<String>>,
#[validate(length(max = 1024))]
pub description: Option<Option<String>>,
pub metadata: Option<Option<HashMap<String, String>>>,
pub is_active: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct OrganizationSummary {
#[serde(flatten)]
pub organization: Organization,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct OrganizationListResponse {
pub organizations: Vec<OrganizationSummary>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct OrganizationMember {
pub user_id: Uuid,
pub role: OrganizationRole,
pub status: OrganizationMemberStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub invited_by: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub invited_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub joined_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct OrganizationMemberListResponse {
pub members: Vec<OrganizationMember>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct AddOrganizationMemberRequest {
pub user_id: Uuid,
pub role: OrganizationRole,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct UpdateOrganizationMemberRequest {
pub role: Option<OrganizationRole>,
pub status: Option<OrganizationMemberStatus>,
}
#[derive(Debug, Clone)]
pub struct NewOrganization {
pub id: Uuid,
pub name: String,
pub slug: String,
pub description: Option<String>,
pub metadata: Option<HashMap<String, String>>,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub is_active: bool,
}
#[derive(Debug, Clone)]
pub struct OrganizationUpdate {
pub name: Option<String>,
pub slug: Option<Option<String>>,
pub description: Option<Option<String>>,
pub metadata: Option<Option<HashMap<String, String>>>,
pub is_active: Option<bool>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
pub struct NewOrganizationMember {
pub organization_id: Uuid,
pub user_id: Uuid,
pub role: OrganizationRole,
pub status: OrganizationMemberStatus,
pub invited_by: Option<Uuid>,
pub invited_at: Option<DateTime<Utc>>,
pub joined_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
pub struct OrganizationMemberUpdate {
pub role: Option<OrganizationRole>,
pub status: Option<OrganizationMemberStatus>,
pub joined_at: Option<Option<DateTime<Utc>>>,
}
#[derive(Debug, Clone, Default)]
pub struct OrganizationListFilters {
pub limit: Option<usize>,
pub after: Option<Uuid>,
pub search: Option<String>,
pub include_inactive: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema, Default)]
#[serde(rename_all = "snake_case")]
pub enum GroupType {
#[default]
Standard,
Team,
}
impl GroupType {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Standard => "standard",
Self::Team => "team",
}
}
}
impl FromStr for GroupType {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"standard" => Ok(Self::Standard),
"team" => Ok(Self::Team),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GroupRole {
Owner,
Admin,
Member,
Viewer,
}
impl GroupRole {
#[must_use]
pub const fn is_admin_like(&self) -> bool {
matches!(self, Self::Owner | Self::Admin)
}
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Owner => "owner",
Self::Admin => "admin",
Self::Member => "member",
Self::Viewer => "viewer",
}
}
}
impl FromStr for GroupRole {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"owner" => Ok(Self::Owner),
"admin" => Ok(Self::Admin),
"member" => Ok(Self::Member),
"viewer" => Ok(Self::Viewer),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GroupMemberStatus {
Pending,
Active,
Suspended,
Removed,
}
impl GroupMemberStatus {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Pending => "pending",
Self::Active => "active",
Self::Suspended => "suspended",
Self::Removed => "removed",
}
}
}
impl FromStr for GroupMemberStatus {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"pending" => Ok(Self::Pending),
"active" => Ok(Self::Active),
"suspended" => Ok(Self::Suspended),
"removed" => Ok(Self::Removed),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Group {
pub id: Uuid,
pub organization_id: Uuid,
pub name: String,
pub slug: String,
pub group_type: GroupType,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, String>>,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub is_active: bool,
pub member_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct CreateGroupRequest {
#[validate(length(min = 3, max = 128))]
pub name: String,
#[validate(length(min = 3, max = 64))]
pub slug: Option<String>,
#[serde(default)]
pub group_type: GroupType,
#[validate(length(max = 1024))]
pub description: Option<String>,
pub metadata: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct UpdateGroupRequest {
#[validate(length(min = 3, max = 128))]
pub name: Option<String>,
#[validate(length(min = 3, max = 64))]
pub slug: Option<Option<String>>,
pub group_type: Option<GroupType>,
#[validate(length(max = 1024))]
pub description: Option<Option<String>>,
pub metadata: Option<Option<HashMap<String, String>>>,
pub is_active: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GroupSummary {
#[serde(flatten)]
pub group: Group,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GroupListResponse {
pub groups: Vec<GroupSummary>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GroupMember {
pub user_id: Uuid,
pub role: GroupRole,
pub status: GroupMemberStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub invited_by: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub invited_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub joined_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GroupMemberListResponse {
pub members: Vec<GroupMember>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct AddGroupMemberRequest {
pub user_id: Uuid,
pub role: GroupRole,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct UpdateGroupMemberRequest {
pub role: Option<GroupRole>,
pub status: Option<GroupMemberStatus>,
}
#[derive(Debug, Clone)]
pub struct NewGroup {
pub id: Uuid,
pub organization_id: Uuid,
pub name: String,
pub slug: String,
pub group_type: GroupType,
pub description: Option<String>,
pub metadata: Option<HashMap<String, String>>,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub is_active: bool,
}
#[derive(Debug, Clone)]
pub struct GroupUpdate {
pub name: Option<String>,
pub slug: Option<Option<String>>,
pub group_type: Option<GroupType>,
pub description: Option<Option<String>>,
pub metadata: Option<Option<HashMap<String, String>>>,
pub is_active: Option<bool>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
pub struct NewGroupMember {
pub group_id: Uuid,
pub user_id: Uuid,
pub role: GroupRole,
pub status: GroupMemberStatus,
pub invited_by: Option<Uuid>,
pub invited_at: Option<DateTime<Utc>>,
pub joined_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
pub struct GroupMemberUpdate {
pub role: Option<GroupRole>,
pub status: Option<GroupMemberStatus>,
pub joined_at: Option<Option<DateTime<Utc>>>,
}
#[derive(Debug, Clone, Default)]
pub struct GroupListFilters {
pub organization_id: Uuid,
pub group_type: Option<GroupType>,
pub limit: Option<usize>,
pub after: Option<Uuid>,
pub search: Option<String>,
pub include_inactive: bool,
}
#[derive(Debug, Clone, Default)]
pub struct ApiKeyListFilters {
pub role: Option<ApiKeyRole>,
pub status: Option<ApiKeyStatus>,
pub expires_before: Option<DateTime<Utc>>,
pub created_by: Option<Uuid>,
pub search: Option<String>,
pub limit: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct ObjectMeta {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uid: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub creation_timestamp: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub labels: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub annotations: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct ListMeta {
#[serde(skip_serializing_if = "Option::is_none")]
pub resource_version: Option<String>,
#[serde(rename = "continue", skip_serializing_if = "Option::is_none")]
pub continue_token: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct ResourceListOptions {
#[serde(rename = "labelSelector", skip_serializing_if = "Option::is_none")]
pub label_selector: Option<String>,
#[serde(rename = "fieldSelector", skip_serializing_if = "Option::is_none")]
pub field_selector: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<usize>,
#[serde(rename = "continue", skip_serializing_if = "Option::is_none")]
pub continue_token: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct LabelSelector {
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub match_labels: HashMap<String, String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub match_expressions: Vec<LabelSelectorRequirement>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct LabelSelectorRequirement {
pub key: String,
pub operator: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub values: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct ObjectReference {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uid: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NamespaceStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub phase: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Namespace {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<NamespaceStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NamespaceList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Namespace>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Taint {
pub key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub effect: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub time_added: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NodeSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub unschedulable: Option<bool>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub taints: Vec<Taint>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NodeResourceCapacity {
#[serde(skip_serializing_if = "Option::is_none")]
pub pods: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cpu_millis: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub memory_mb: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gpus: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NodeInventory {
#[serde(skip_serializing_if = "Option::is_none")]
pub capacity: Option<NodeResourceCapacity>,
#[serde(skip_serializing_if = "Option::is_none")]
pub allocatable: Option<NodeResourceCapacity>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NodeStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub ready: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inventory: Option<NodeInventory>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Node {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<NodeSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<NodeStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NodeList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Node>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ConfigMap {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub data: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ConfigMapList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<ConfigMap>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Secret {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub secret_type: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub data: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct SecretList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Secret>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ServiceAccount {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub secrets: Vec<ObjectReference>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ServiceAccountList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<ServiceAccount>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ServicePort {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub port: u16,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_port: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub protocol: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ServiceSpec {
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub service_type: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub selector: HashMap<String, String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ports: Vec<ServicePort>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Service {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<ServiceSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ServiceList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Service>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EndpointAddress {
pub ip: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_ref: Option<ObjectReference>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EndpointPort {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub port: u16,
#[serde(skip_serializing_if = "Option::is_none")]
pub protocol: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EndpointSubset {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub addresses: Vec<EndpointAddress>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ports: Vec<EndpointPort>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Endpoints {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub subsets: Vec<EndpointSubset>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EndpointsList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Endpoints>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EndpointSlicePort {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub port: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub protocol: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EndpointSliceEndpoint {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub addresses: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_ref: Option<ObjectReference>,
#[serde(skip_serializing_if = "Option::is_none")]
pub conditions: Option<HashMap<String, bool>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EndpointSlice {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
pub address_type: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub endpoints: Vec<EndpointSliceEndpoint>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ports: Vec<EndpointSlicePort>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EndpointSliceList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<EndpointSlice>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct WebhookServiceReference {
pub name: String,
pub namespace: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct WebhookClientConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service: Option<WebhookServiceReference>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ca_bundle: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct WebhookRule {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub api_groups: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub api_versions: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub resources: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scope: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct WebhookRuleWithOperations {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub operations: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub api_groups: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub api_versions: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub resources: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scope: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Webhook {
pub name: String,
pub client_config: WebhookClientConfig,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rules: Vec<WebhookRuleWithOperations>,
#[serde(skip_serializing_if = "Option::is_none")]
pub failure_policy: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub match_policy: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub namespace_selector: HashMap<String, Value>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub object_selector: HashMap<String, Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub admission_review_versions: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub side_effects: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timeout_seconds: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MutatingWebhookConfiguration {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub webhooks: Vec<Webhook>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MutatingWebhookConfigurationList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<MutatingWebhookConfiguration>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ValidatingWebhookConfiguration {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub webhooks: Vec<Webhook>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ValidatingWebhookConfigurationList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<ValidatingWebhookConfiguration>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CustomResourceDefinition {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<HashMap<String, Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CustomResourceDefinitionList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<CustomResourceDefinition>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ResourceQuotaSpec {
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub hard: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ResourceQuotaStatus {
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub hard: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub used: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ResourceQuota {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<ResourceQuotaSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<ResourceQuotaStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ResourceQuotaList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<ResourceQuota>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct LimitRangeItem {
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub limit_type: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub max: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub min: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub default: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub default_request: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub max_limit_request_ratio: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct LimitRangeSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub limits: Vec<LimitRangeItem>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct LimitRange {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<LimitRangeSpec>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct LimitRangeList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<LimitRange>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodDisruptionBudgetSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub min_available: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_unavailable: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub selector: Option<LabelSelector>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodDisruptionBudgetStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub current_healthy: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub desired_healthy: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disruptions_allowed: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodDisruptionBudget {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<PodDisruptionBudgetSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<PodDisruptionBudgetStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodDisruptionBudgetList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<PodDisruptionBudget>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PriorityClass {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
pub value: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub global_default: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub preemption_policy: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PriorityClassList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<PriorityClass>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkPolicySpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub pod_selector: Option<LabelSelector>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub policy_types: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ingress: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub egress: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkPolicy {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<NetworkPolicySpec>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkPolicyList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<NetworkPolicy>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct IngressSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub ingress_class_name: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rules: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tls: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Ingress {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<IngressSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct IngressList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Ingress>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct IngressClassSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub controller: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub parameters: HashMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct IngressClass {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<IngressClassSpec>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct IngressClassList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<IngressClass>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GatewayClassSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub controller_name: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub parameters_ref: HashMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GatewayClass {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<GatewayClassSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GatewayClassList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<GatewayClass>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GatewaySpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub gateway_class_name: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub listeners: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Gateway {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<GatewaySpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GatewayList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Gateway>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HTTPRouteSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub parent_refs: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub hostnames: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rules: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HTTPRoute {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<HTTPRouteSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HTTPRouteList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<HTTPRoute>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TCPRouteSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub parent_refs: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rules: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TCPRoute {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<TCPRouteSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TCPRouteList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<TCPRoute>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TLSRouteSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub parent_refs: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rules: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TLSRoute {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<TLSRouteSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TLSRouteList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<TLSRoute>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UDPRouteSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub parent_refs: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rules: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UDPRoute {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<UDPRouteSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UDPRouteList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<UDPRoute>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GRPCRouteSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub parent_refs: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rules: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GRPCRoute {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<GRPCRouteSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GRPCRouteList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<GRPCRoute>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ReferenceGrantSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub from: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub to: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ReferenceGrant {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<ReferenceGrantSpec>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ReferenceGrantList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<ReferenceGrant>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageClass {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
pub provisioner: String,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub parameters: HashMap<String, String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub mount_options: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reclaim_policy: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_binding_mode: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub allow_volume_expansion: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageClassList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<StorageClass>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CsiDriverSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub attach_required: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pod_info_on_mount: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub fs_group_policy: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub storage_capacity: Option<bool>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub volume_lifecycle_modes: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CsiDriver {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<CsiDriverSpec>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CsiDriverList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<CsiDriver>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PersistentVolumeSpec {
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub capacity: HashMap<String, String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub access_modes: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub storage_class_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub claim_ref: Option<ObjectReference>,
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_mode: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub persistent_volume_reclaim_policy: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_source: Option<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PersistentVolumeStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub phase: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub capacity: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PersistentVolume {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<PersistentVolumeSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<PersistentVolumeStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PersistentVolumeList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<PersistentVolume>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PersistentVolumeClaimSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub access_modes: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub storage_class_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resources: Option<ResourceRequirements>,
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_mode: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub selector: Option<LabelSelector>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PersistentVolumeClaimStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub phase: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub access_modes: Vec<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub capacity: HashMap<String, String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PersistentVolumeClaim {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<PersistentVolumeClaimSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<PersistentVolumeClaimStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PersistentVolumeClaimList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<PersistentVolumeClaim>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VolumeSnapshotSource {
#[serde(skip_serializing_if = "Option::is_none")]
pub persistent_volume_claim_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_snapshot_content_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VolumeSnapshotSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_snapshot_class_name: Option<String>,
pub source: VolumeSnapshotSource,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VolumeSnapshotStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub ready_to_use: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub creation_time: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub restore_size: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bound_volume_snapshot_content_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VolumeSnapshot {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<VolumeSnapshotSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<VolumeSnapshotStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VolumeSnapshotList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<VolumeSnapshot>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Volume {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub volume_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VirtualMachineDomain {
#[serde(skip_serializing_if = "Option::is_none")]
pub cpu: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub memory: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub devices: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VirtualMachineInstanceSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub domain: Option<VirtualMachineDomain>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub node_selector: HashMap<String, String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub networks: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub volumes: Vec<Volume>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VirtualMachineTemplateSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<ObjectMeta>,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<VirtualMachineInstanceSpec>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VirtualMachineSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub run_strategy: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub template: Option<VirtualMachineTemplateSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cpu: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub memory: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub disks: Vec<Volume>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub networks: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VirtualMachine {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<VirtualMachineSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VirtualMachineList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<VirtualMachine>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VirtualMachineInstance {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<VirtualMachineInstanceSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VirtualMachineInstanceList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<VirtualMachineInstance>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmSnapshotSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub source_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmSnapshot {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<VmSnapshotSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmSnapshotList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<VmSnapshot>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmMemoryDumpSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub source_name: Option<String>,
pub file: CreateFileRequest,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmMemoryDumpStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub ready: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmMemoryDump {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<VmMemoryDumpSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<VmMemoryDumpStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmMemoryDumpList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<VmMemoryDump>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureTarget {
pub kind: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub container_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pod_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub container_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureFilter {
#[serde(skip_serializing_if = "Option::is_none")]
pub bpf: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub protocols: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ports: Vec<u16>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub cidrs: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureRotation {
#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_duration_seconds: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_files: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureCaptureOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub snaplen: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_packets: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rotation: Option<NetworkCaptureRotation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub compression: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureLifecycle {
#[serde(skip_serializing_if = "Option::is_none")]
pub desired_state: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ttl_seconds_after_finished: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureSegment {
#[serde(skip_serializing_if = "Option::is_none")]
pub index: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub started_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub finished_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureSpec {
pub target: NetworkCaptureTarget,
#[serde(skip_serializing_if = "Option::is_none")]
pub direction: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub interfaces: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter: Option<NetworkCaptureFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub capture: Option<NetworkCaptureCaptureOptions>,
pub file: CaptureFileRequest,
#[serde(skip_serializing_if = "Option::is_none")]
pub run_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lifecycle: Option<NetworkCaptureLifecycle>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub phase: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub started_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub finished_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bytes_captured: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub packets_captured: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_type: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub segments: Vec<NetworkCaptureSegment>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCapture {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<NetworkCaptureSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<NetworkCaptureStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkCaptureList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<NetworkCapture>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmMigrationSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub vmi_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_node: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmMigration {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<VmMigrationSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VmMigrationList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<VmMigration>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ConsoleSession {
pub protocol: String,
pub url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ContainerPort {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub container_port: u16,
#[serde(skip_serializing_if = "Option::is_none")]
pub protocol: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EnvVar {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Default)]
pub struct ResourceRequirements {
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub limits: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub requests: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Toleration {
#[serde(skip_serializing_if = "Option::is_none")]
pub key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub operator: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub effect: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub toleration_seconds: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PreferredSchedulingTerm {
pub weight: i32,
pub preference: LabelSelector,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NodeAffinity {
#[serde(skip_serializing_if = "Option::is_none")]
pub required: Option<LabelSelector>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub preferred: Vec<PreferredSchedulingTerm>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodAffinityTerm {
pub label_selector: LabelSelector,
pub topology_key: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct WeightedPodAffinityTerm {
pub weight: i32,
pub pod_affinity_term: PodAffinityTerm,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodAffinity {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub required: Vec<PodAffinityTerm>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub preferred: Vec<WeightedPodAffinityTerm>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Affinity {
#[serde(skip_serializing_if = "Option::is_none")]
pub node_affinity: Option<NodeAffinity>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pod_affinity: Option<PodAffinity>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pod_anti_affinity: Option<PodAffinity>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodContainer {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub image: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub command: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub args: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub env: Vec<EnvVar>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ports: Vec<ContainerPort>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub resources: Option<ResourceRequirements>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub service_account_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub node_name: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub node_selector: HashMap<String, String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority_class_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<i32>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tolerations: Vec<Toleration>,
#[serde(skip_serializing_if = "Option::is_none")]
pub affinity: Option<Affinity>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub containers: Vec<PodContainer>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub volumes: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodContainerStatus {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub container_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ready: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub restart_count: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub phase: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pod_ip: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub host_ip: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub qos_class: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start_time: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub container_statuses: Vec<PodContainerStatus>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub conditions: Vec<PodCondition>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodCondition {
#[serde(rename = "type")]
pub condition_type: String,
pub status: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_probe_time: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_transition_time: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodTemplateSpec {
pub metadata: ObjectMeta,
pub spec: PodSpec,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Pod {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
pub spec: PodSpec,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<PodStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodStatusUpdate {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<PodStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Pod>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct DeploymentSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub replicas: Option<i32>,
pub selector: LabelSelector,
pub template: PodTemplateSpec,
#[serde(skip_serializing_if = "Option::is_none")]
pub strategy: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct WorkloadDeploymentStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub available_replicas: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_replicas: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Deployment {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<DeploymentSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<WorkloadDeploymentStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct DeploymentList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Deployment>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ReplicaSet {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<DeploymentSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ReplicaSetList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<ReplicaSet>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StatefulSetSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub replicas: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service_name: Option<String>,
pub selector: LabelSelector,
pub template: PodTemplateSpec,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub volume_claim_templates: Vec<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StatefulSet {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<StatefulSetSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StatefulSetList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<StatefulSet>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct DaemonSetSpec {
pub selector: LabelSelector,
pub template: PodTemplateSpec,
#[serde(skip_serializing_if = "Option::is_none")]
pub update_strategy: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct DaemonSet {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<DaemonSetSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct DaemonSetList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<DaemonSet>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct JobSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub parallelism: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completions: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub backoff_limit: Option<i32>,
pub template: PodTemplateSpec,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Job {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<JobSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct JobList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Job>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct JobTemplateSpec {
pub spec: JobSpec,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CronJobSpec {
pub schedule: String,
pub job_template: JobTemplateSpec,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CronJob {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<CronJobSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CronJobList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<CronJob>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct ScaleSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub replicas: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct ScaleStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub replicas: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct Scale {
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<ScaleSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<ScaleStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CrossVersionObjectReference {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MetricIdentifier {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub selector: Option<LabelSelector>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MetricTarget {
#[serde(rename = "type")]
pub target_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub average_value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub average_utilization: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MetricValueStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub average_value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub average_utilization: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ResourceMetricSource {
pub name: String,
pub target: MetricTarget,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ResourceMetricStatus {
pub name: String,
pub current: MetricValueStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodsMetricSource {
pub metric: MetricIdentifier,
pub target: MetricTarget,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PodsMetricStatus {
pub metric: MetricIdentifier,
pub current: MetricValueStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ObjectMetricSource {
pub described_object: CrossVersionObjectReference,
pub metric: MetricIdentifier,
pub target: MetricTarget,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ObjectMetricStatus {
pub described_object: CrossVersionObjectReference,
pub metric: MetricIdentifier,
pub current: MetricValueStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ExternalMetricSource {
pub metric: MetricIdentifier,
pub target: MetricTarget,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ExternalMetricStatus {
pub metric: MetricIdentifier,
pub current: MetricValueStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MetricSpec {
#[serde(rename = "type")]
pub metric_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource: Option<ResourceMetricSource>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pods: Option<PodsMetricSource>,
#[serde(skip_serializing_if = "Option::is_none")]
pub object: Option<ObjectMetricSource>,
#[serde(skip_serializing_if = "Option::is_none")]
pub external: Option<ExternalMetricSource>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MetricStatus {
#[serde(rename = "type")]
pub metric_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource: Option<ResourceMetricStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pods: Option<PodsMetricStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub object: Option<ObjectMetricStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub external: Option<ExternalMetricStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AutoscalerCondition {
#[serde(rename = "type")]
pub condition_type: String,
pub status: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_transition_time: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HorizontalPodAutoscalerBehavior {
#[serde(skip_serializing_if = "Option::is_none")]
pub scale_up: Option<HorizontalPodAutoscalerScalingRules>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scale_down: Option<HorizontalPodAutoscalerScalingRules>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HorizontalPodAutoscalerScalingRules {
#[serde(skip_serializing_if = "Option::is_none")]
pub stabilization_window_seconds: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub select_policy: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub policies: Vec<HorizontalPodAutoscalerScalingPolicy>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HorizontalPodAutoscalerScalingPolicy {
#[serde(rename = "type")]
pub policy_type: String,
pub value: i32,
pub period_seconds: i32,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HorizontalPodAutoscalerSpec {
pub scale_target_ref: CrossVersionObjectReference,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_replicas: Option<i32>,
pub max_replicas: i32,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub metrics: Vec<MetricSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub behavior: Option<HorizontalPodAutoscalerBehavior>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HorizontalPodAutoscalerStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub current_replicas: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub desired_replicas: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_scale_time: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub current_metrics: Vec<MetricStatus>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub conditions: Vec<AutoscalerCondition>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HorizontalPodAutoscaler {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<HorizontalPodAutoscalerSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<HorizontalPodAutoscalerStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct HorizontalPodAutoscalerList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<HorizontalPodAutoscaler>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscalerUpdatePolicy {
#[serde(skip_serializing_if = "Option::is_none")]
pub update_mode: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscalerContainerPolicy {
pub container_name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub min_allowed: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub max_allowed: HashMap<String, String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub controlled_resources: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub controlled_values: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscalerResourcePolicy {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub container_policies: Vec<VerticalPodAutoscalerContainerPolicy>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscalerSpec {
pub target_ref: CrossVersionObjectReference,
#[serde(skip_serializing_if = "Option::is_none")]
pub update_policy: Option<VerticalPodAutoscalerUpdatePolicy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource_policy: Option<VerticalPodAutoscalerResourcePolicy>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscalerContainerRecommendation {
pub container_name: String,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub lower_bound: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub target: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub upper_bound: HashMap<String, String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub uncapped_target: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscalerRecommendation {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub container_recommendations: Vec<VerticalPodAutoscalerContainerRecommendation>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscalerStatus {
#[serde(skip_serializing_if = "Option::is_none")]
pub recommendation: Option<VerticalPodAutoscalerRecommendation>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub conditions: Vec<AutoscalerCondition>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscaler {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec: Option<VerticalPodAutoscalerSpec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<VerticalPodAutoscalerStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct VerticalPodAutoscalerList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<VerticalPodAutoscaler>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct RolloutRequest {
pub action: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ToSchema)]
pub struct MetricsSample {
#[serde(flatten)]
pub values: HashMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MetricsSeries {
pub ts: DateTime<Utc>,
pub samples: Vec<MetricsSample>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Event {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
pub metadata: ObjectMeta,
#[serde(skip_serializing_if = "Option::is_none")]
pub involved_object: Option<ObjectReference>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub event_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub first_timestamp: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_timestamp: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct EventList {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default)]
pub metadata: ListMeta,
pub items: Vec<Event>,
}
pub fn compute_expiration(
explicit: Option<DateTime<Utc>>,
ttl_days: Option<i32>,
) -> Result<Option<DateTime<Utc>>, ValidationError> {
if let Some(ttl) = ttl_days {
if ttl <= 0 {
return Err(ValidationError::new("ttl_days"));
}
if explicit.is_some() {
return Err(ValidationError::new("expires_at_conflict"));
}
return Ok(Some(Utc::now() + Duration::days(ttl.into())));
}
Ok(explicit)
}
fn validate_grant_file_permission(
request: &GrantFilePermissionRequest,
) -> Result<(), ValidationError> {
if request.user_id.is_none()
&& request.team_id.is_none()
&& request
.role
.as_ref()
.is_none_or(|value| value.trim().is_empty())
{
return Err(ValidationError::new("missing_grantee"));
}
Ok(())
}
impl AuthProvider {
#[must_use]
pub fn as_storage(&self) -> (String, Option<String>) {
match self {
Self::Local => ("local".to_string(), None),
Self::OAuth { provider } => ("oauth".to_string(), Some(provider.clone())),
}
}
#[must_use]
pub fn from_storage(kind: &str, provider: Option<String>) -> Self {
if kind.eq_ignore_ascii_case("oauth") {
Self::OAuth {
provider: provider.unwrap_or_else(|| "unknown".to_string()),
}
} else {
Self::Local
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum MfaMethod {
Totp,
}
impl std::fmt::Display for MfaMethod {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Totp => write!(f, "totp"),
}
}
}
impl FromStr for MfaMethod {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"totp" => Ok(Self::Totp),
_ => Err(format!("Unknown MFA method: {s}")),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MfaSecret {
pub id: Uuid,
pub user_id: Uuid,
pub secret_encrypted: String,
pub method: MfaMethod,
pub is_enabled: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub verified_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MfaBackupCode {
pub id: Uuid,
pub user_id: Uuid,
pub code_hash: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub used_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum PartialSessionPurpose {
MfaVerify,
MfaSetup,
}
impl std::fmt::Display for PartialSessionPurpose {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MfaVerify => write!(f, "mfa_verify"),
Self::MfaSetup => write!(f, "mfa_setup"),
}
}
}
impl FromStr for PartialSessionPurpose {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"mfa_verify" => Ok(Self::MfaVerify),
"mfa_setup" => Ok(Self::MfaSetup),
_ => Err(format!("Unknown partial session purpose: {s}")),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PartialSession {
pub id: Uuid,
pub user_id: Uuid,
pub token_hash: String,
pub purpose: PartialSessionPurpose,
pub expires_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ip_address: Option<String>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct MfaSetupRequest {
#[validate(length(equal = 6))]
pub code: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MfaSetupResponse {
pub secret: String,
pub qr_code_url: String,
pub provisioning_uri: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct MfaVerifyRequest {
#[validate(length(min = 6, max = 32))]
pub code: String,
#[validate(length(min = 32, max = 64))]
pub partial_token: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MfaStatusResponse {
pub enabled: bool,
pub method: Option<MfaMethod>,
pub backup_codes_remaining: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub verified_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct BackupCodesResponse {
pub codes: Vec<String>,
pub generated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum TokenPurpose {
MagicLink,
PasswordReset,
}
impl std::fmt::Display for TokenPurpose {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MagicLink => write!(f, "magic_link"),
Self::PasswordReset => write!(f, "password_reset"),
}
}
}
impl FromStr for TokenPurpose {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"magic_link" => Ok(Self::MagicLink),
"password_reset" => Ok(Self::PasswordReset),
_ => Err(format!("Unknown token purpose: {s}")),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct MagicLink {
pub id: Uuid,
pub user_id: Uuid,
pub token_hash: String,
pub expires_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub used_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ip_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_agent: Option<String>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PasswordResetToken {
pub id: Uuid,
pub user_id: Uuid,
pub token_hash: String,
pub expires_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub used_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ip_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_agent: Option<String>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct MagicLinkRequest {
#[validate(email)]
pub email: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct PasswordResetRequest {
#[validate(email)]
pub email: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct PasswordResetCompleteRequest {
#[validate(length(min = 32, max = 64))]
pub token: String,
#[validate(length(min = 12, max = 128))]
pub new_password: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct MagicLinkVerifyRequest {
#[validate(length(min = 32, max = 64))]
pub token: String,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum DeviceType {
Desktop,
Mobile,
Tablet,
#[default]
Unknown,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, ToSchema)]
pub struct DeviceInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub browser: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub os: Option<String>,
pub device_type: DeviceType,
#[serde(skip_serializing_if = "Option::is_none")]
pub fingerprint: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UserSession {
pub id: Uuid,
pub user_id: Uuid,
pub session_token_hash: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_token_hash: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub device_fingerprint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub device_info: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub browser: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub os: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ip_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub location_city: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub location_country: Option<String>,
pub is_current: bool,
pub last_active_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub revoked_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct SessionSummary {
pub id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub browser: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub os: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ip_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub location: Option<String>,
pub is_current: bool,
pub last_active_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
}
impl From<UserSession> for SessionSummary {
fn from(session: UserSession) -> Self {
let location = match (&session.location_city, &session.location_country) {
(Some(city), Some(country)) => Some(format!("{city}, {country}")),
(Some(city), None) => Some(city.clone()),
(None, Some(country)) => Some(country.clone()),
_ => None,
};
Self {
id: session.id,
browser: session.browser,
os: session.os,
ip_address: session.ip_address,
location,
is_current: session.is_current,
last_active_at: session.last_active_at,
created_at: session.created_at,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct RevokeSessionRequest {
pub session_id: Uuid,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct WebAuthnCredential {
pub id: Uuid,
pub user_id: Uuid,
#[serde(with = "base64_bytes")]
pub credential_id: Vec<u8>,
pub passkey: String,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub aaguid: Option<Uuid>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub transports: Vec<String>,
pub is_discoverable: bool,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_used_at: Option<DateTime<Utc>>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct WebAuthnChallenge {
pub id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<Uuid>,
pub challenge_hash: String,
pub state_encrypted: String,
pub expires_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PasskeySummary {
pub id: Uuid,
pub name: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub transports: Vec<String>,
pub is_discoverable: bool,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_used_at: Option<DateTime<Utc>>,
}
impl From<WebAuthnCredential> for PasskeySummary {
fn from(cred: WebAuthnCredential) -> Self {
Self {
id: cred.id,
name: cred.name,
transports: cred.transports,
is_discoverable: cred.is_discoverable,
created_at: cred.created_at,
last_used_at: cred.last_used_at,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct RenamePasskeyRequest {
#[validate(length(min = 1, max = 100))]
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Validate, ToSchema)]
pub struct PasskeyRegisterStartRequest {
#[validate(length(min = 1, max = 100))]
pub name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StorageBucketVersioning {
Disabled,
Enabled,
Suspended,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StorageReplicationStrategy {
Mirror,
Erasure,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageObjectLock {
pub enabled: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_retention_days: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageReplicationPolicy {
pub factor: i32,
pub strategy: StorageReplicationStrategy,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub zones: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_success: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageCacheTier {
#[serde(skip_serializing_if = "Option::is_none")]
pub max_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ttl_seconds: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageCachePolicy {
#[serde(skip_serializing_if = "Option::is_none")]
pub memory: Option<StorageCacheTier>,
#[serde(skip_serializing_if = "Option::is_none")]
pub nvme: Option<StorageCacheTier>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageLifecyclePolicy {
#[serde(skip_serializing_if = "Option::is_none")]
pub expire_days: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub transition_days: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub transition_class: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageQuota {
#[serde(skip_serializing_if = "Option::is_none")]
pub max_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_objects: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageBucket {
pub id: Uuid,
pub organization_id: Uuid,
pub name: String,
pub region: String,
pub versioning: StorageBucketVersioning,
#[serde(skip_serializing_if = "Option::is_none")]
pub object_lock: Option<StorageObjectLock>,
#[serde(skip_serializing_if = "Option::is_none")]
pub replication: Option<StorageReplicationPolicy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_policy: Option<StorageCachePolicy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lifecycle: Option<StorageLifecyclePolicy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quota: Option<StorageQuota>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tags: Vec<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageBucketList {
pub items: Vec<StorageBucket>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageObject {
pub bucket_id: Uuid,
pub key: String,
pub size_bytes: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub etag: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version_id: Option<String>,
pub created_at: DateTime<Utc>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub metadata: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageObjectList {
pub items: Vec<StorageObject>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StorageVolumeStatus {
Available,
Bound,
InUse,
Error,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageVolume {
pub id: Uuid,
pub organization_id: Uuid,
pub name: String,
pub size_bytes: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub filesystem: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub replica_count: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub storage_class: Option<String>,
pub status: StorageVolumeStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_policy: Option<StorageCachePolicy>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageVolumeList {
pub items: Vec<StorageVolume>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StorageDriveType {
Personal,
Shared,
Project,
Compute,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageDrive {
pub id: Uuid,
pub organization_id: Uuid,
pub name: String,
pub drive_type: StorageDriveType,
#[serde(skip_serializing_if = "Option::is_none")]
pub root_folder_id: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageDriveList {
pub items: Vec<StorageDrive>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageContentRef {
pub bucket_id: Uuid,
pub key: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageFile {
pub id: Uuid,
pub organization_id: Uuid,
pub drive_id: Uuid,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub mime_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<i64>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub parents: Vec<Uuid>,
pub trashed: bool,
pub version: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_ref: Option<StorageContentRef>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageFileList {
pub items: Vec<StorageFile>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StoragePermissionResourceKind {
Bucket,
Drive,
File,
Volume,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StoragePermissionSubjectType {
User,
Group,
ServiceAccount,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StoragePermissionRole {
Owner,
Admin,
Editor,
Viewer,
Commenter,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StoragePermission {
pub id: Uuid,
pub organization_id: Uuid,
pub resource_kind: StoragePermissionResourceKind,
pub resource_id: Uuid,
pub subject_type: StoragePermissionSubjectType,
pub subject_id: Uuid,
pub role: StoragePermissionRole,
pub allow_file_discovery: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StoragePermissionList {
pub items: Vec<StoragePermission>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StorageServiceAccountStatus {
Active,
Disabled,
}
impl StorageServiceAccountStatus {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Active => "active",
Self::Disabled => "disabled",
}
}
}
impl FromStr for StorageServiceAccountStatus {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"active" => Ok(Self::Active),
"disabled" => Ok(Self::Disabled),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, ToSchema)]
#[serde(transparent)]
pub struct StorageServiceAccountScope(pub String);
impl StorageServiceAccountScope {
#[must_use]
pub fn new(value: impl Into<String>) -> Self {
Self(value.into())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageServiceAccount {
pub id: Uuid,
pub organization_id: Uuid,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scopes: Option<Vec<StorageServiceAccountScope>>,
pub status: StorageServiceAccountStatus,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_used_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageServiceAccountList {
pub items: Vec<StorageServiceAccount>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum StorageAccessKeyStatus {
Active,
Revoked,
Expired,
}
impl StorageAccessKeyStatus {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Active => "active",
Self::Revoked => "revoked",
Self::Expired => "expired",
}
}
}
impl FromStr for StorageAccessKeyStatus {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"active" => Ok(Self::Active),
"revoked" => Ok(Self::Revoked),
"expired" => Ok(Self::Expired),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageAccessKey {
pub id: Uuid,
pub service_account_id: Uuid,
pub access_key: String,
pub status: StorageAccessKeyStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub secret_preview: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_used_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageAccessKeyWithSecret {
#[serde(flatten)]
pub access_key: StorageAccessKey,
pub secret_key: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct StorageAccessKeyList {
pub items: Vec<StorageAccessKey>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CreateStorageServiceAccountRequest {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scopes: Option<Vec<StorageServiceAccountScope>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UpdateStorageServiceAccountRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scopes: Option<Option<Vec<StorageServiceAccountScope>>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<StorageServiceAccountStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CreateStorageAccessKeyRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ttl_days: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct RotateStorageAccessKeyRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ttl_days: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
}
#[derive(Debug, Clone)]
pub struct NewStorageServiceAccount {
pub id: Uuid,
pub organization_id: Uuid,
pub name: String,
pub description: Option<String>,
pub scopes: Option<Vec<StorageServiceAccountScope>>,
pub status: StorageServiceAccountStatus,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub last_used_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
pub struct StorageServiceAccountUpdate {
pub name: Option<String>,
pub description: Option<Option<String>>,
pub scopes: Option<Option<Vec<StorageServiceAccountScope>>>,
pub status: Option<StorageServiceAccountStatus>,
pub updated_at: DateTime<Utc>,
pub last_used_at: Option<Option<DateTime<Utc>>>,
}
impl StorageServiceAccountUpdate {
#[must_use]
pub fn new(updated_at: DateTime<Utc>) -> Self {
Self {
name: None,
description: None,
scopes: None,
status: None,
updated_at,
last_used_at: None,
}
}
}
#[derive(Debug, Clone)]
pub struct NewStorageAccessKey {
pub id: Uuid,
pub service_account_id: Uuid,
pub access_key: String,
pub secret_hash: String,
pub secret_preview: Option<String>,
pub status: StorageAccessKeyStatus,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub expires_at: Option<DateTime<Utc>>,
pub last_used_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
pub struct StorageAccessKeyUpdate {
pub status: Option<StorageAccessKeyStatus>,
pub secret_hash: Option<String>,
pub secret_preview: Option<Option<String>>,
pub expires_at: Option<Option<DateTime<Utc>>>,
pub updated_at: DateTime<Utc>,
pub last_used_at: Option<Option<DateTime<Utc>>>,
}
impl StorageAccessKeyUpdate {
#[must_use]
pub fn new(updated_at: DateTime<Utc>) -> Self {
Self {
status: None,
secret_hash: None,
secret_preview: None,
expires_at: None,
updated_at,
last_used_at: None,
}
}
}
#[derive(Debug, Clone)]
pub struct StoredStorageAccessKey {
pub access_key: StorageAccessKey,
pub secret_hash: String,
}
mod base64_bytes {
use base64::{engine::general_purpose::STANDARD, Engine};
use serde::{Deserialize, Deserializer, Serializer};
pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&STANDARD.encode(bytes))
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
STANDARD.decode(&s).map_err(serde::de::Error::custom)
}
}