mirror of
https://github.com/moghtech/komodo.git
synced 2026-08-09 17:41:49 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7406c292a1 | ||
|
|
427475651c | ||
|
|
ae0c8bf98a | ||
|
|
a7592f4561 | ||
|
|
a199c8fe27 | ||
|
|
f7296c73b1 | ||
|
|
0eaf8b5f01 | ||
|
|
6919582f69 |
+1
-4
@@ -1,5 +1,2 @@
|
||||
[alias]
|
||||
xtask = "run --package xtask --"
|
||||
|
||||
[build]
|
||||
rustflags = ["-Wunused-crate-dependencies"]
|
||||
rustflags = ["-Wunused-crate-dependencies"]
|
||||
Generated
+830
-1666
File diff suppressed because it is too large
Load Diff
+29
-31
@@ -3,19 +3,21 @@ resolver = "2"
|
||||
members = [
|
||||
"bin/*",
|
||||
"lib/*",
|
||||
"xtask",
|
||||
"client/core/rs",
|
||||
"client/periphery/rs",
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "2.2.0"
|
||||
version = "2.1.1"
|
||||
edition = "2024"
|
||||
authors = ["mbecker20 <becker.maxh@gmail.com>"]
|
||||
license = "GPL-3.0-or-later"
|
||||
repository = "https://github.com/moghtech/komodo"
|
||||
homepage = "https://komo.do"
|
||||
|
||||
[profile.release]
|
||||
strip = "debuginfo"
|
||||
|
||||
[workspace.dependencies]
|
||||
# LOCAL
|
||||
komodo_client = { path = "client/core/rs" }
|
||||
@@ -31,29 +33,29 @@ git = { path = "lib/git" }
|
||||
|
||||
# MOGH
|
||||
slack = { version = "2.0.0", package = "slack_client_rs", default-features = false, features = ["rustls"] }
|
||||
mogh_error = { version = "1.0.4", default-features = false }
|
||||
mogh_error = { version = "1.0.3", default-features = false }
|
||||
derive_default_builder = "0.1.8"
|
||||
async_timing_util = "1.1.0"
|
||||
mogh_auth_client = "1.5.0"
|
||||
mogh_auth_server = "1.5.0"
|
||||
mogh_auth_client = "1.2.2"
|
||||
mogh_auth_server = "1.2.13"
|
||||
mogh_secret_file = "1.0.1"
|
||||
mogh_validations = "1.0.1"
|
||||
mogh_rate_limit = "1.0.1"
|
||||
partial_derive2 = "0.5.0"
|
||||
partial_derive2 = "0.4.5"
|
||||
mongo_indexed = "2.0.2"
|
||||
mogh_resolver = "1.0.0"
|
||||
mogh_config = "1.1.0"
|
||||
mogh_config = "1.0.5"
|
||||
mogh_logger = "1.3.3"
|
||||
mogh_server = "1.5.0"
|
||||
mogh_server = "1.4.5"
|
||||
toml_pretty = "2.0.0"
|
||||
mogh_cache = "1.1.2"
|
||||
mogh_cache = "1.1.1"
|
||||
mogh_pki = "1.1.3"
|
||||
mungos = "3.2.2"
|
||||
svi = "1.2.0"
|
||||
|
||||
# ASYNC
|
||||
reqwest = { version = "0.13.3", default-features = false, features = ["json", "stream", "form", "query", "rustls"] }
|
||||
tokio = { version = "1.52.2", features = ["full"] }
|
||||
reqwest = { version = "0.13.2", default-features = false, features = ["json", "stream", "form", "query", "rustls"] }
|
||||
tokio = { version = "1.50.0", features = ["full"] }
|
||||
tokio-util = { version = "0.7.18", features = ["io", "codec"] }
|
||||
tokio-stream = { version = "0.1.18", features = ["sync"] }
|
||||
pin-project-lite = "0.2.17"
|
||||
@@ -62,16 +64,16 @@ arc-swap = "1.9.0"
|
||||
|
||||
# SERVER
|
||||
tokio-tungstenite = { version = "0.29.0", features = ["rustls-tls-native-roots"] }
|
||||
axum = { version = "0.8.9", features = ["ws", "json", "macros"] }
|
||||
axum-extra = { version = "0.12.6", features = ["typed-header"] }
|
||||
axum = { version = "0.8.8", features = ["ws", "json", "macros"] }
|
||||
axum-extra = { version = "0.12.5", features = ["typed-header"] }
|
||||
|
||||
# OPENAPI
|
||||
utoipa-scalar = { version = "0.3.0", features = ["axum"] }
|
||||
utoipa = "5.5.0"
|
||||
utoipa = "5.4.0"
|
||||
|
||||
# SER/DE
|
||||
ipnetwork = { version = "0.21.1", features = ["serde"] }
|
||||
indexmap = { version = "2.14.0", features = ["serde"] }
|
||||
indexmap = { version = "2.13.0", features = ["serde"] }
|
||||
serde = { version = "1.0.227", features = ["derive"] }
|
||||
strum = { version = "0.28.0", features = ["derive"] }
|
||||
bson = { version = "2.15.0" } # must keep in sync with mongodb version
|
||||
@@ -89,34 +91,34 @@ thiserror = "2.0.18"
|
||||
tracing = "0.1.44"
|
||||
|
||||
# CONFIG
|
||||
clap = { version = "4.6.1", features = ["derive"] }
|
||||
clap = { version = "4.5.60", features = ["derive"] }
|
||||
dotenvy = "0.15.7"
|
||||
envy = "0.4.2"
|
||||
|
||||
# CRYPTO / AUTH
|
||||
uuid = { version = "1.23.1", features = ["v4", "fast-rng", "serde"] }
|
||||
rustls = { version = "0.23.40", features = ["aws-lc-rs"] }
|
||||
uuid = { version = "1.23.0", features = ["v4", "fast-rng", "serde"] }
|
||||
rustls = { version = "0.23.37", features = ["aws-lc-rs"] }
|
||||
data-encoding = "2.10.0"
|
||||
urlencoding = "2.1.3"
|
||||
bcrypt = "0.19.0"
|
||||
hmac = "0.13.0"
|
||||
sha1 = "0.11.0"
|
||||
sha2 = "0.11.0"
|
||||
rand = "0.10.1"
|
||||
hmac = "0.12.1"
|
||||
sha1 = "0.10.6"
|
||||
sha2 = "0.10.9"
|
||||
rand = "0.10.0"
|
||||
hex = "0.4.3"
|
||||
|
||||
# SYSTEM
|
||||
hickory-resolver = "0.26.1"
|
||||
hickory-resolver = "0.25.2"
|
||||
portable-pty = "0.9.0"
|
||||
shell-escape = "0.1.5"
|
||||
crossterm = "0.29.0"
|
||||
bollard = "0.21.0"
|
||||
bollard = "0.20.2"
|
||||
sysinfo = "0.38.4"
|
||||
shlex = "1.3.0"
|
||||
|
||||
# CLOUD
|
||||
aws-config = "1.8.16"
|
||||
aws-sdk-ec2 = "1.224.0"
|
||||
aws-config = "1.8.15"
|
||||
aws-sdk-ec2 = "1.220.1"
|
||||
aws-credential-types = "1.2.14"
|
||||
|
||||
## CRON
|
||||
@@ -126,8 +128,7 @@ chrono = "0.4.44"
|
||||
croner = "3.0.1"
|
||||
|
||||
# MISC
|
||||
async-compression = { version = "0.4.42", features = ["tokio", "gzip"] }
|
||||
schemars = { version = "1.2.1", features = ["indexmap2"] }
|
||||
async-compression = { version = "0.4.41", features = ["tokio", "gzip"] }
|
||||
derive_builder = "0.20.2"
|
||||
comfy-table = "7.2.2"
|
||||
typeshare = "1.0.5"
|
||||
@@ -135,6 +136,3 @@ wildcard = "0.3.0"
|
||||
colored = "3.1.1"
|
||||
bytes = "1.11.1"
|
||||
regex = "1.12.3"
|
||||
|
||||
[profile.release]
|
||||
strip = "debuginfo"
|
||||
@@ -1,7 +1,7 @@
|
||||
## Builds the Komodo Core, Periphery, and Util binaries
|
||||
## for a specific architecture. Requires OpenSSL 3 or later.
|
||||
|
||||
FROM rust:1.95.0-bookworm AS builder
|
||||
FROM rust:1.94.1-bookworm AS builder
|
||||
RUN cargo install cargo-strip
|
||||
|
||||
WORKDIR /builder
|
||||
@@ -12,7 +12,6 @@ COPY ./client/periphery ./client/periphery
|
||||
COPY ./bin/core ./bin/core
|
||||
COPY ./bin/periphery ./bin/periphery
|
||||
COPY ./bin/cli ./bin/cli
|
||||
COPY ./xtask ./xtask
|
||||
|
||||
# Compile bin
|
||||
RUN \
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
## Uses chef for dependency caching to help speed up back-to-back builds.
|
||||
|
||||
FROM lukemathwalker/cargo-chef:latest-rust-1.95.0-bookworm AS chef
|
||||
FROM lukemathwalker/cargo-chef:latest-rust-1.94.1-bookworm AS chef
|
||||
WORKDIR /builder
|
||||
|
||||
# Plan just the RECIPE to see if things have changed
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM rust:1.95.0-trixie AS builder
|
||||
FROM rust:1.94.1-bullseye AS builder
|
||||
RUN cargo install cargo-strip
|
||||
|
||||
WORKDIR /builder
|
||||
|
||||
@@ -9,7 +9,7 @@ ARG AARCH64_BINARIES=${BINARIES_IMAGE}-aarch64
|
||||
FROM ${X86_64_BINARIES} AS x86_64
|
||||
FROM ${AARCH64_BINARIES} AS aarch64
|
||||
|
||||
FROM debian:trixie-slim
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## All in one, multi stage compile + runtime Docker build for your architecture.
|
||||
|
||||
# Build Core
|
||||
FROM rust:1.95.0-trixie AS core-builder
|
||||
FROM rust:1.94.1-trixie AS core-builder
|
||||
RUN cargo install cargo-strip
|
||||
|
||||
WORKDIR /builder
|
||||
@@ -11,7 +11,6 @@ COPY ./client/core/rs ./client/core/rs
|
||||
COPY ./client/periphery ./client/periphery
|
||||
COPY ./bin/core ./bin/core
|
||||
COPY ./bin/cli ./bin/cli
|
||||
COPY ./xtask ./xtask
|
||||
|
||||
# Compile app
|
||||
RUN cargo build -p komodo_core --release && \
|
||||
@@ -59,8 +58,7 @@ ENV KOMODO_CLI_CONFIG_PATHS="/config"
|
||||
# This ensures any `komodo.cli.*` takes precedence over the Core `/config/*config.*`
|
||||
ENV KOMODO_CLI_CONFIG_KEYWORDS="*config.*,*komodo.cli*.*"
|
||||
|
||||
ENTRYPOINT [ "entrypoint.sh" ]
|
||||
CMD [ "core" ]
|
||||
CMD [ "/bin/bash", "-c", "update-ca-certificates && core" ]
|
||||
|
||||
# Label to prevent Komodo from stopping with StopAllContainers
|
||||
LABEL komodo.skip="true"
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
use std::time::Instant;
|
||||
|
||||
use axum::{Router, extract::Path, http::HeaderMap, routing::post};
|
||||
use derive_variants::{EnumVariants, ExtractVariant};
|
||||
use komodo_client::{api::auth::*, entities::user::User};
|
||||
use reqwest::StatusCode;
|
||||
use resolver_api::Resolve;
|
||||
use response::Response;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use serror::{AddStatusCode, Json};
|
||||
use typeshare::typeshare;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
auth::{
|
||||
get_user_id_from_headers,
|
||||
github::{self, client::github_oauth_client},
|
||||
google::{self, client::google_oauth_client},
|
||||
oidc::{self, client::oidc_client},
|
||||
},
|
||||
config::core_config,
|
||||
helpers::query::get_user,
|
||||
state::jwt_client,
|
||||
};
|
||||
|
||||
use super::Variant;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AuthArgs {
|
||||
pub headers: HeaderMap,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Resolve, EnumVariants,
|
||||
)]
|
||||
#[args(AuthArgs)]
|
||||
#[response(Response)]
|
||||
#[error(serror::Error)]
|
||||
#[variant_derive(Debug)]
|
||||
#[serde(tag = "type", content = "params")]
|
||||
#[allow(clippy::enum_variant_names, clippy::large_enum_variant)]
|
||||
pub enum AuthRequest {
|
||||
GetLoginOptions(GetLoginOptions),
|
||||
SignUpLocalUser(SignUpLocalUser),
|
||||
LoginLocalUser(LoginLocalUser),
|
||||
ExchangeForJwt(ExchangeForJwt),
|
||||
GetUser(GetUser),
|
||||
}
|
||||
|
||||
pub fn router() -> Router {
|
||||
let mut router = Router::new()
|
||||
.route("/", post(handler))
|
||||
.route("/{variant}", post(variant_handler));
|
||||
|
||||
if core_config().local_auth {
|
||||
info!("🔑 Local Login Enabled");
|
||||
}
|
||||
|
||||
if github_oauth_client().is_some() {
|
||||
info!("🔑 Github Login Enabled");
|
||||
router = router.nest("/github", github::router())
|
||||
}
|
||||
|
||||
if google_oauth_client().is_some() {
|
||||
info!("🔑 Google Login Enabled");
|
||||
router = router.nest("/google", google::router())
|
||||
}
|
||||
|
||||
if core_config().oidc_enabled {
|
||||
info!("🔑 OIDC Login Enabled");
|
||||
router = router.nest("/oidc", oidc::router())
|
||||
}
|
||||
|
||||
router
|
||||
}
|
||||
|
||||
async fn variant_handler(
|
||||
headers: HeaderMap,
|
||||
Path(Variant { variant }): Path<Variant>,
|
||||
Json(params): Json<serde_json::Value>,
|
||||
) -> serror::Result<axum::response::Response> {
|
||||
let req: AuthRequest = serde_json::from_value(json!({
|
||||
"type": variant,
|
||||
"params": params,
|
||||
}))?;
|
||||
handler(headers, Json(req)).await
|
||||
}
|
||||
|
||||
#[instrument(name = "AuthHandler", level = "debug", skip(headers))]
|
||||
async fn handler(
|
||||
headers: HeaderMap,
|
||||
Json(request): Json<AuthRequest>,
|
||||
) -> serror::Result<axum::response::Response> {
|
||||
let timer = Instant::now();
|
||||
let req_id = Uuid::new_v4();
|
||||
debug!(
|
||||
"/auth request {req_id} | METHOD: {:?}",
|
||||
request.extract_variant()
|
||||
);
|
||||
let res = request.resolve(&AuthArgs { headers }).await;
|
||||
if let Err(e) = &res {
|
||||
debug!("/auth request {req_id} | error: {:#}", e.error);
|
||||
}
|
||||
let elapsed = timer.elapsed();
|
||||
debug!("/auth request {req_id} | resolve time: {elapsed:?}");
|
||||
res.map(|res| res.0)
|
||||
}
|
||||
|
||||
fn login_options_response() -> GetLoginOptionsResponse {
|
||||
let config = core_config();
|
||||
GetLoginOptionsResponse {
|
||||
local: config.local_auth,
|
||||
github: github_oauth_client().is_some(),
|
||||
google: google_oauth_client().is_some(),
|
||||
oidc: oidc_client().load().is_some(),
|
||||
registration_disabled: config.disable_user_registration,
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolve<AuthArgs> for GetLoginOptions {
|
||||
#[instrument(name = "GetLoginOptions", level = "debug", skip(self))]
|
||||
async fn resolve(
|
||||
self,
|
||||
_: &AuthArgs,
|
||||
) -> serror::Result<GetLoginOptionsResponse> {
|
||||
Ok(login_options_response())
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolve<AuthArgs> for ExchangeForJwt {
|
||||
#[instrument(name = "ExchangeForJwt", level = "debug", skip(self))]
|
||||
async fn resolve(
|
||||
self,
|
||||
_: &AuthArgs,
|
||||
) -> serror::Result<ExchangeForJwtResponse> {
|
||||
jwt_client()
|
||||
.redeem_exchange_token(&self.token)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolve<AuthArgs> for GetUser {
|
||||
#[instrument(name = "GetUser", level = "debug", skip(self))]
|
||||
async fn resolve(
|
||||
self,
|
||||
AuthArgs { headers }: &AuthArgs,
|
||||
) -> serror::Result<User> {
|
||||
let user_id = get_user_id_from_headers(headers)
|
||||
.await
|
||||
.status_code(StatusCode::UNAUTHORIZED)?;
|
||||
get_user(&user_id)
|
||||
.await
|
||||
.status_code(StatusCode::UNAUTHORIZED)
|
||||
}
|
||||
}
|
||||
@@ -509,10 +509,10 @@ pub async fn validate_cancel_build(
|
||||
)?;
|
||||
|
||||
match (latest_build, latest_cancel) {
|
||||
(Some(build), Some(cancel))
|
||||
if cancel.start_ts > build.start_ts =>
|
||||
{
|
||||
return Err(anyhow!("Build has already been cancelled"));
|
||||
(Some(build), Some(cancel)) => {
|
||||
if cancel.start_ts > build.start_ts {
|
||||
return Err(anyhow!("Build has already been cancelled"));
|
||||
}
|
||||
}
|
||||
(None, _) => return Err(anyhow!("No build in progress")),
|
||||
_ => {}
|
||||
|
||||
@@ -698,12 +698,13 @@ pub async fn validate_cancel_repo_build(
|
||||
)?;
|
||||
|
||||
match (latest_build, latest_cancel) {
|
||||
(Some(build), Some(cancel))
|
||||
if cancel.start_ts > build.start_ts =>
|
||||
{
|
||||
return Err(anyhow!("Repo build has already been cancelled"));
|
||||
(Some(build), Some(cancel)) => {
|
||||
if cancel.start_ts > build.start_ts {
|
||||
return Err(anyhow!(
|
||||
"Repo build has already been cancelled"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
(None, _) => return Err(anyhow!("No repo build in progress")),
|
||||
_ => {}
|
||||
};
|
||||
|
||||
@@ -283,7 +283,6 @@ impl Resolve<ExecuteArgs> for RunSync {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
// New resource types need to be added here manually.
|
||||
if deploy_cache.is_empty()
|
||||
&& resource_sync_deltas.no_changes()
|
||||
&& server_deltas.no_changes()
|
||||
@@ -340,7 +339,10 @@ impl Resolve<ExecuteArgs> for RunSync {
|
||||
)
|
||||
.await,
|
||||
);
|
||||
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
ResourceSync::execute_sync_updates(resource_sync_deltas).await,
|
||||
);
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Server::execute_sync_updates(server_deltas).await,
|
||||
@@ -354,43 +356,38 @@ impl Resolve<ExecuteArgs> for RunSync {
|
||||
Action::execute_sync_updates(action_deltas).await,
|
||||
);
|
||||
|
||||
// Depends on server
|
||||
// Dependent on server
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Swarm::execute_sync_updates(swarm_deltas).await,
|
||||
);
|
||||
// Depends on server
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Builder::execute_sync_updates(builder_deltas).await,
|
||||
);
|
||||
// Depends on server / builder
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Repo::execute_sync_updates(repo_deltas).await,
|
||||
);
|
||||
|
||||
// Depends on builder / repo
|
||||
// Dependant on builder
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Build::execute_sync_updates(build_deltas).await,
|
||||
);
|
||||
// Depends on server / repo
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Stack::execute_sync_updates(stack_deltas).await,
|
||||
);
|
||||
// Depends on repo
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
ResourceSync::execute_sync_updates(resource_sync_deltas).await,
|
||||
);
|
||||
// Depends on server / build
|
||||
|
||||
// Dependant on server / build
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Deployment::execute_sync_updates(deployment_deltas).await,
|
||||
);
|
||||
// Depends on everything
|
||||
// stack only depends on server, but maybe will depend on build later.
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Stack::execute_sync_updates(stack_deltas).await,
|
||||
);
|
||||
|
||||
// Dependant on everything
|
||||
maybe_extend(
|
||||
&mut update.logs,
|
||||
Procedure::execute_sync_updates(procedure_deltas).await,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use anyhow::{Context, anyhow};
|
||||
use axum::http::HeaderMap;
|
||||
use hex::ToHex;
|
||||
use hmac::{Hmac, KeyInit as _, Mac};
|
||||
use hmac::{Hmac, Mac};
|
||||
use serde::Deserialize;
|
||||
use sha2::Sha256;
|
||||
|
||||
|
||||
@@ -555,9 +555,8 @@ impl Resolve<WriteArgs> for RefreshStackCache {
|
||||
&mut services,
|
||||
) {
|
||||
warn!(
|
||||
stack = stack.id,
|
||||
stack_name = stack.name,
|
||||
"Failed to extract stack services | {e:#}",
|
||||
"failed to extract stack services, things won't works correctly. stack: {} | {e:#}",
|
||||
stack.name
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -776,13 +775,7 @@ pub async fn check_stack_for_update_inner(
|
||||
|
||||
if image.is_empty() ||
|
||||
// Images with a hardcoded digest can't have update.
|
||||
image.contains('@') ||
|
||||
// Services explicitly excluded from global auto-update checks.
|
||||
// Manual checks should still evaluate all services.
|
||||
(wait_for_auto_update &&
|
||||
stack.config.auto_update_skip_services.contains(
|
||||
&service.service_name,
|
||||
))
|
||||
image.contains('@')
|
||||
{
|
||||
service.image_digest = None;
|
||||
continue;
|
||||
|
||||
@@ -205,20 +205,6 @@ impl AuthImpl for KomodoAuthImpl {
|
||||
core_config().disable_user_registration
|
||||
}
|
||||
|
||||
fn local_registration_disabled(&self) -> bool {
|
||||
let config = core_config();
|
||||
config
|
||||
.disable_local_user_registration
|
||||
.unwrap_or(config.disable_user_registration)
|
||||
}
|
||||
|
||||
fn oidc_registration_disabled(&self) -> bool {
|
||||
let config = core_config();
|
||||
config
|
||||
.disable_oidc_user_registration
|
||||
.unwrap_or(config.disable_user_registration)
|
||||
}
|
||||
|
||||
fn validate_username(
|
||||
&self,
|
||||
username: &str,
|
||||
@@ -362,7 +348,6 @@ impl AuthImpl for KomodoAuthImpl {
|
||||
additional_audiences: config
|
||||
.oidc_additional_audiences
|
||||
.clone(),
|
||||
auto_redirect: config.oidc_auto_redirect,
|
||||
}
|
||||
});
|
||||
Some(&OIDC_CONFIG)
|
||||
|
||||
@@ -235,9 +235,6 @@ pub fn core_config() -> &'static CoreConfig {
|
||||
env.komodo_oidc_additional_audiences,
|
||||
)
|
||||
.unwrap_or(config.oidc_additional_audiences),
|
||||
oidc_auto_redirect: env
|
||||
.komodo_oidc_auto_redirect
|
||||
.unwrap_or(config.oidc_auto_redirect),
|
||||
google_oauth: NamedOauthConfig {
|
||||
enabled: env
|
||||
.komodo_google_oauth_enabled
|
||||
@@ -315,21 +312,6 @@ pub fn core_config() -> &'static CoreConfig {
|
||||
session_allow_cross_site: env
|
||||
.komodo_session_allow_cross_site
|
||||
.unwrap_or(config.session_allow_cross_site),
|
||||
x_content_type_options: env
|
||||
.komodo_x_content_type_options
|
||||
.unwrap_or(config.x_content_type_options),
|
||||
x_frame_options: env
|
||||
.komodo_x_frame_options
|
||||
.unwrap_or(config.x_frame_options),
|
||||
x_xss_protection: env
|
||||
.komodo_x_xss_protection
|
||||
.unwrap_or(config.x_xss_protection),
|
||||
referrer_policy: env
|
||||
.komodo_referrer_policy
|
||||
.unwrap_or(config.referrer_policy),
|
||||
content_security_policy: env
|
||||
.komodo_content_security_policy
|
||||
.unwrap_or(config.content_security_policy),
|
||||
resource_poll_interval: env
|
||||
.komodo_resource_poll_interval
|
||||
.unwrap_or(config.resource_poll_interval),
|
||||
@@ -363,12 +345,6 @@ pub fn core_config() -> &'static CoreConfig {
|
||||
disable_user_registration: env
|
||||
.komodo_disable_user_registration
|
||||
.unwrap_or(config.disable_user_registration),
|
||||
disable_local_user_registration: env
|
||||
.komodo_disable_local_user_registration
|
||||
.or(config.disable_local_user_registration),
|
||||
disable_oidc_user_registration: env
|
||||
.komodo_disable_oidc_user_registration
|
||||
.or(config.disable_oidc_user_registration),
|
||||
disable_non_admin_create: env
|
||||
.komodo_disable_non_admin_create
|
||||
.unwrap_or(config.disable_non_admin_create),
|
||||
|
||||
@@ -38,6 +38,8 @@ pub fn extract_services_into_res(
|
||||
"failed to parse service names from compose contents",
|
||||
)?;
|
||||
|
||||
let mut services = Vec::with_capacity(compose.services.capacity());
|
||||
|
||||
for (
|
||||
service_name,
|
||||
ComposeService {
|
||||
@@ -47,29 +49,17 @@ pub fn extract_services_into_res(
|
||||
},
|
||||
) in compose.services
|
||||
{
|
||||
if let Some(existing) =
|
||||
res.iter_mut().find(|s| s.service_name == service_name)
|
||||
{
|
||||
// Override any defined fields
|
||||
if let Some(container_name) = container_name {
|
||||
existing.container_name = container_name;
|
||||
}
|
||||
if let Some(image) = image {
|
||||
existing.image = image;
|
||||
}
|
||||
} else {
|
||||
res.push(StackServiceNames {
|
||||
container_name: container_name.unwrap_or_else(|| {
|
||||
format!("{project_name}-{service_name}")
|
||||
}),
|
||||
image_digest: service_image_digests
|
||||
.get(&service_name)
|
||||
.cloned(),
|
||||
image: image.unwrap_or_default(),
|
||||
service_name,
|
||||
});
|
||||
}
|
||||
let image = image.unwrap_or_default();
|
||||
services.push(StackServiceNames {
|
||||
container_name: container_name
|
||||
.unwrap_or_else(|| format!("{project_name}-{service_name}")),
|
||||
image_digest: service_image_digests.get(&service_name).cloned(),
|
||||
service_name,
|
||||
image,
|
||||
});
|
||||
}
|
||||
|
||||
res.extend(services);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -458,41 +458,6 @@ impl ToToml for Builder {
|
||||
toml.push_str("\nparams = {}");
|
||||
}
|
||||
}
|
||||
|
||||
fn edit_config_object(
|
||||
_resource: &ResourceToml<Self::PartialConfig>,
|
||||
config: IndexMap<String, serde_json::Value>,
|
||||
) -> anyhow::Result<IndexMap<String, serde_json::Value>> {
|
||||
config
|
||||
.into_iter()
|
||||
.map(|(key, value)| {
|
||||
#[allow(clippy::single_match)]
|
||||
match key.as_str() {
|
||||
"params" => match value {
|
||||
serde_json::Value::Object(obj) => Ok((
|
||||
key,
|
||||
serde_json::Value::Object(
|
||||
obj
|
||||
.into_iter()
|
||||
.map(|(key, value)| {
|
||||
match key.as_str() {
|
||||
"server_id" => {
|
||||
return (String::from("server"), value);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
(key, value)
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
)),
|
||||
value => Ok((key, value)),
|
||||
},
|
||||
_ => Ok((key, value)),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToToml for Procedure {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## All in one, multi stage compile + runtime Docker build for your architecture.
|
||||
|
||||
FROM rust:1.95.0-trixie AS builder
|
||||
FROM rust:1.94.1-trixie AS builder
|
||||
RUN cargo install cargo-strip
|
||||
|
||||
WORKDIR /builder
|
||||
@@ -9,7 +9,6 @@ COPY ./lib ./lib
|
||||
COPY ./client/core/rs ./client/core/rs
|
||||
COPY ./client/periphery ./client/periphery
|
||||
COPY ./bin/periphery ./bin/periphery
|
||||
COPY ./xtask ./xtask
|
||||
|
||||
# Compile app
|
||||
RUN cargo build -p komodo_periphery --release && cargo strip
|
||||
|
||||
@@ -271,11 +271,7 @@ impl Resolve<crate::api::Args> for build::Build {
|
||||
"Pre Build",
|
||||
pre_build_path.as_path(),
|
||||
&pre_build.command,
|
||||
if pre_build.shell_mode {
|
||||
KomodoCommandMode::Shell
|
||||
} else {
|
||||
KomodoCommandMode::Multiline
|
||||
},
|
||||
KomodoCommandMode::Multiline,
|
||||
&replacers,
|
||||
)
|
||||
.instrument(span)
|
||||
|
||||
@@ -490,11 +490,7 @@ impl Resolve<crate::api::Args> for ComposeUp {
|
||||
"Pre Deploy",
|
||||
pre_deploy_path.as_path(),
|
||||
&stack.config.pre_deploy.command,
|
||||
if stack.config.pre_deploy.shell_mode {
|
||||
KomodoCommandMode::Shell
|
||||
} else {
|
||||
KomodoCommandMode::Multiline
|
||||
},
|
||||
KomodoCommandMode::Multiline,
|
||||
&replacers,
|
||||
)
|
||||
.instrument(span)
|
||||
@@ -764,11 +760,7 @@ impl Resolve<crate::api::Args> for ComposeUp {
|
||||
"Post Deploy",
|
||||
post_deploy_path.as_path(),
|
||||
&stack.config.post_deploy.command,
|
||||
if stack.config.post_deploy.shell_mode {
|
||||
KomodoCommandMode::Shell
|
||||
} else {
|
||||
KomodoCommandMode::Multiline
|
||||
},
|
||||
KomodoCommandMode::Multiline,
|
||||
&replacers,
|
||||
)
|
||||
.instrument(span)
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::state::container_stats;
|
||||
|
||||
use super::{
|
||||
DockerClient, convert_health_config, convert_mount,
|
||||
convert_resources_ulimits,
|
||||
convert_mount_point_type, convert_resources_ulimits,
|
||||
};
|
||||
|
||||
impl DockerClient {
|
||||
@@ -360,7 +360,10 @@ impl DockerClient {
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|mount| MountPoint {
|
||||
typ: mount.typ,
|
||||
typ: mount
|
||||
.typ
|
||||
.map(convert_mount_point_type)
|
||||
.unwrap_or_default(),
|
||||
name: mount.name,
|
||||
source: mount.source,
|
||||
destination: mount.destination,
|
||||
@@ -479,9 +482,6 @@ fn convert_summary_container_state(
|
||||
bollard::config::ContainerSummaryStateEnum::EXITED => {
|
||||
ContainerStateStatusEnum::Exited
|
||||
}
|
||||
bollard::config::ContainerSummaryStateEnum::STOPPING => {
|
||||
ContainerStateStatusEnum::Stopping
|
||||
}
|
||||
bollard::config::ContainerSummaryStateEnum::REMOVING => {
|
||||
ContainerStateStatusEnum::Removing
|
||||
}
|
||||
@@ -516,9 +516,6 @@ fn convert_container_state_status(
|
||||
bollard::config::ContainerStateStatusEnum::REMOVING => {
|
||||
ContainerStateStatusEnum::Removing
|
||||
}
|
||||
bollard::config::ContainerStateStatusEnum::STOPPING => {
|
||||
ContainerStateStatusEnum::Stopping
|
||||
}
|
||||
bollard::config::ContainerStateStatusEnum::DEAD => {
|
||||
ContainerStateStatusEnum::Dead
|
||||
}
|
||||
|
||||
@@ -150,14 +150,17 @@ fn convert_mount(mount: bollard::models::Mount) -> Mount {
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_mount_type(typ: bollard::config::MountType) -> MountType {
|
||||
fn convert_mount_type(
|
||||
typ: bollard::config::MountTypeEnum,
|
||||
) -> MountTypeEnum {
|
||||
match typ {
|
||||
bollard::config::MountType::BIND => MountType::Bind,
|
||||
bollard::config::MountType::VOLUME => MountType::Volume,
|
||||
bollard::config::MountType::IMAGE => MountType::Image,
|
||||
bollard::config::MountType::TMPFS => MountType::Tmpfs,
|
||||
bollard::config::MountType::NPIPE => MountType::Npipe,
|
||||
bollard::config::MountType::CLUSTER => MountType::Cluster,
|
||||
bollard::config::MountTypeEnum::EMPTY => MountTypeEnum::Empty,
|
||||
bollard::config::MountTypeEnum::BIND => MountTypeEnum::Bind,
|
||||
bollard::config::MountTypeEnum::VOLUME => MountTypeEnum::Volume,
|
||||
bollard::config::MountTypeEnum::IMAGE => MountTypeEnum::Image,
|
||||
bollard::config::MountTypeEnum::TMPFS => MountTypeEnum::Tmpfs,
|
||||
bollard::config::MountTypeEnum::NPIPE => MountTypeEnum::Npipe,
|
||||
bollard::config::MountTypeEnum::CLUSTER => MountTypeEnum::Cluster,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +192,32 @@ fn convert_mount_propogation(
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_mount_point_type(
|
||||
typ: bollard::config::MountPointTypeEnum,
|
||||
) -> MountTypeEnum {
|
||||
match typ {
|
||||
bollard::config::MountPointTypeEnum::EMPTY => {
|
||||
MountTypeEnum::Empty
|
||||
}
|
||||
bollard::config::MountPointTypeEnum::BIND => MountTypeEnum::Bind,
|
||||
bollard::config::MountPointTypeEnum::VOLUME => {
|
||||
MountTypeEnum::Volume
|
||||
}
|
||||
bollard::config::MountPointTypeEnum::IMAGE => {
|
||||
MountTypeEnum::Image
|
||||
}
|
||||
bollard::config::MountPointTypeEnum::TMPFS => {
|
||||
MountTypeEnum::Tmpfs
|
||||
}
|
||||
bollard::config::MountPointTypeEnum::NPIPE => {
|
||||
MountTypeEnum::Npipe
|
||||
}
|
||||
bollard::config::MountPointTypeEnum::CLUSTER => {
|
||||
MountTypeEnum::Cluster
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_health_config(
|
||||
config: bollard::models::HealthConfig,
|
||||
) -> HealthConfig {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use bollard::query_parameters::ListVolumesOptions;
|
||||
use komodo_client::entities::docker::{
|
||||
Topology, container::ContainerListItem, volume::*,
|
||||
PortBinding, container::ContainerListItem, volume::*,
|
||||
};
|
||||
|
||||
use crate::docker::DockerClient;
|
||||
@@ -108,8 +108,8 @@ impl DockerClient {
|
||||
}).collect(),
|
||||
accessibility_requirements: mode
|
||||
.accessibility_requirements.map(|req| ClusterVolumeSpecAccessModeAccessibilityRequirements {
|
||||
requisite: req.requisite.map(|v| v.into_iter().map(|t| Topology { segments: t.segments }).collect()),
|
||||
preferred: req.preferred.map(|v| v.into_iter().map(|t| Topology { segments: t.segments }).collect()),
|
||||
requisite: req.requisite.unwrap_or_default().into_iter().map(|map| map.into_iter().map(|(k, v)| (k, v.unwrap_or_default().into_iter().map(|p| PortBinding { host_ip: p.host_ip, host_port: p.host_port }).collect())).collect()).collect(),
|
||||
preferred: req.preferred.unwrap_or_default().into_iter().map(|map| map.into_iter().map(|(k, v)| (k, v.unwrap_or_default().into_iter().map(|p| PortBinding { host_ip: p.host_ip, host_port: p.host_port }).collect())).collect()).collect(),
|
||||
}),
|
||||
capacity_range: mode.capacity_range.map(|range| ClusterVolumeSpecAccessModeCapacityRange {
|
||||
required_bytes: range.required_bytes,
|
||||
@@ -128,7 +128,7 @@ impl DockerClient {
|
||||
capacity_bytes: info.capacity_bytes,
|
||||
volume_context: info.volume_context.unwrap_or_default(),
|
||||
volume_id: info.volume_id,
|
||||
accessible_topology: info.accessible_topology.map(|v| v.into_iter().map(|t| Topology { segments: t.segments }).collect()),
|
||||
accessible_topology: info.accessible_topology.unwrap_or_default().into_iter().map(|map| map.into_iter().map(|(k, v)| (k, v.unwrap_or_default().into_iter().map(|p| PortBinding { host_ip: p.host_ip, host_port: p.host_port }).collect())).collect()).collect(),
|
||||
}),
|
||||
publish_status: volume
|
||||
.publish_status
|
||||
|
||||
@@ -189,11 +189,7 @@ pub async fn handle_post_repo_execution(
|
||||
"On Clone",
|
||||
path.as_path(),
|
||||
on_clone.command,
|
||||
if on_clone.shell_mode {
|
||||
KomodoCommandMode::Shell
|
||||
} else {
|
||||
KomodoCommandMode::Multiline
|
||||
},
|
||||
KomodoCommandMode::Multiline,
|
||||
&replacers,
|
||||
)
|
||||
.await
|
||||
@@ -218,11 +214,7 @@ pub async fn handle_post_repo_execution(
|
||||
"On Pull",
|
||||
path.as_path(),
|
||||
on_pull.command,
|
||||
if on_pull.shell_mode {
|
||||
KomodoCommandMode::Shell
|
||||
} else {
|
||||
KomodoCommandMode::Multiline
|
||||
},
|
||||
KomodoCommandMode::Multiline,
|
||||
&replacers,
|
||||
)
|
||||
.await
|
||||
@@ -284,31 +276,37 @@ pub fn registry_token(
|
||||
// Public IP over DNS
|
||||
// ====================
|
||||
|
||||
type OpenDNSResolver = hickory_resolver::TokioResolver;
|
||||
type OpenDNSResolver = hickory_resolver::Resolver<
|
||||
hickory_resolver::name_server::TokioConnectionProvider,
|
||||
>;
|
||||
|
||||
fn opendns_resolver() -> &'static OpenDNSResolver {
|
||||
static OPENDNS_RESOLVER: OnceLock<OpenDNSResolver> =
|
||||
OnceLock::new();
|
||||
OPENDNS_RESOLVER.get_or_init(|| {
|
||||
// OpenDNS resolver ipv4s.
|
||||
let name_servers = [
|
||||
// OpenDNS resolver ipv4s
|
||||
let ips = [
|
||||
IpAddr::from_str("208.67.220.220").unwrap(),
|
||||
IpAddr::from_str("208.67.222.222").unwrap(),
|
||||
]
|
||||
.into_iter()
|
||||
.map(hickory_resolver::config::NameServerConfig::udp_and_tcp)
|
||||
.collect();
|
||||
];
|
||||
|
||||
// trust_negative_responses=true means NXDOMAIN/empty NOERROR from an
|
||||
// authoritative upstream won’t be retried on other servers.
|
||||
let ns =
|
||||
hickory_resolver::config::NameServerConfigGroup::from_ips_clear(
|
||||
&ips, 53, true,
|
||||
);
|
||||
|
||||
hickory_resolver::Resolver::builder_with_config(
|
||||
hickory_resolver::config::ResolverConfig::from_parts(
|
||||
None,
|
||||
vec![],
|
||||
name_servers,
|
||||
ns,
|
||||
),
|
||||
hickory_resolver::name_server::TokioConnectionProvider::default(
|
||||
),
|
||||
hickory_resolver::net::runtime::TokioRuntimeProvider::default(),
|
||||
)
|
||||
.build()
|
||||
.expect("Failed to build OpenDNS resolver")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -321,7 +319,7 @@ pub async fn resolve_host_public_ip() -> anyhow::Result<String> {
|
||||
.context(
|
||||
"Failed to query OpenDNS resolvers for host public IP",
|
||||
)?
|
||||
.iter()
|
||||
.into_iter()
|
||||
.map(|ip| ip.to_string())
|
||||
.next()
|
||||
.context("OpenDNS call for public IP didn't return anything")
|
||||
|
||||
@@ -14,7 +14,6 @@ repository.workspace = true
|
||||
blocking = ["reqwest/blocking"]
|
||||
mongo = ["dep:mongo_indexed"]
|
||||
utoipa = ["dep:utoipa", "mogh_auth_client/utoipa", "mogh_error/utoipa"]
|
||||
schemars = ["dep:schemars"]
|
||||
logger = ["dep:mogh_logger"]
|
||||
cli = ["logger", "dep:mogh_pki",]
|
||||
core = ["mongo", "utoipa", "logger", "dep:mogh_server"]
|
||||
@@ -34,7 +33,6 @@ partial_derive2.workspace = true
|
||||
mogh_resolver.workspace = true
|
||||
# external
|
||||
ipnetwork = { workspace = true, optional = true }
|
||||
schemars = { workspace = true, optional = true }
|
||||
utoipa = { workspace = true, optional = true }
|
||||
tokio-tungstenite.workspace = true
|
||||
derive_builder.workspace = true
|
||||
|
||||
@@ -28,7 +28,6 @@ pub fn run_action() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -69,7 +68,6 @@ pub fn batch_run_action() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -27,7 +27,6 @@ pub fn test_alerter() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -57,7 +56,6 @@ pub fn send_alert() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -39,7 +39,6 @@ pub fn run_build() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -68,7 +67,6 @@ pub fn batch_run_build() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -108,7 +106,6 @@ pub fn cancel_build() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -34,7 +34,6 @@ pub fn deploy() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -69,7 +68,6 @@ pub fn batch_deploy() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -107,7 +105,6 @@ pub fn pull_deployment() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -138,7 +135,6 @@ pub fn start_deployment() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -169,7 +165,6 @@ pub fn restart_deployment() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -200,7 +195,6 @@ pub fn pause_deployment() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -234,7 +228,6 @@ pub fn unpause_deployment() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -265,7 +258,6 @@ pub fn stop_deployment() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -303,7 +295,6 @@ pub fn destroy_deployment() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -336,7 +327,6 @@ pub fn batch_destroy_deployment() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -28,7 +28,6 @@ pub fn clear_repo_cache() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -61,7 +60,6 @@ pub fn backup_core_database() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -94,7 +92,6 @@ pub fn global_auto_update() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -128,7 +125,6 @@ pub fn rotate_all_server_keys() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -159,7 +155,6 @@ pub fn rotate_core_keys() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -78,7 +78,6 @@ pub trait KomodoExecuteRequest: HasResponse {}
|
||||
utoipa::ToSchema
|
||||
))
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(tag = "type", content = "params")]
|
||||
pub enum Execution {
|
||||
/// The "null" execution. Does nothing.
|
||||
@@ -216,7 +215,6 @@ pub enum Execution {
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Parser)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct Sleep {
|
||||
#[serde(default)]
|
||||
pub duration_ms: I64,
|
||||
|
||||
@@ -27,7 +27,6 @@ pub fn run_procedure() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -56,7 +55,6 @@ pub fn batch_run_procedure() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -35,7 +35,6 @@ pub fn clone_repo() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -64,7 +63,6 @@ pub fn batch_clone_repo() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -107,7 +105,6 @@ pub fn pull_repo() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -136,7 +133,6 @@ pub fn batch_pull_repo() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -183,7 +179,6 @@ pub fn build_repo() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -212,7 +207,6 @@ pub fn batch_build_repo() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -252,7 +246,6 @@ pub fn cancel_repo_build() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -31,7 +31,6 @@ pub fn start_container() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -64,7 +63,6 @@ pub fn restart_container() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -97,7 +95,6 @@ pub fn pause_container() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -132,7 +129,6 @@ pub fn unpause_container() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -165,7 +161,6 @@ pub fn stop_container() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -203,7 +198,6 @@ pub fn destroy_container() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -238,7 +232,6 @@ pub fn start_all_containers() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -267,7 +260,6 @@ pub fn restart_all_containers() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -296,7 +288,6 @@ pub fn pause_all_containers() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -325,7 +316,6 @@ pub fn unpause_all_containers() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -354,7 +344,6 @@ pub fn stop_all_containers() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -385,7 +374,6 @@ pub fn prune_containers() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -417,7 +405,6 @@ pub fn delete_network() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -450,7 +437,6 @@ pub fn prune_networks() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -480,7 +466,6 @@ pub fn delete_image() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -513,7 +498,6 @@ pub fn prune_images() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -543,7 +527,6 @@ pub fn delete_volume() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -576,7 +559,6 @@ pub fn prune_volumes() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -607,7 +589,6 @@ pub fn prune_docker_builders() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -638,7 +619,6 @@ pub fn prune_buildx() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -669,7 +649,6 @@ pub fn prune_system() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -27,7 +27,6 @@ pub fn deploy_stack() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -65,7 +64,6 @@ pub fn batch_deploy_stack() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -105,7 +103,6 @@ pub fn deploy_stack_if_changed() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -137,7 +134,6 @@ pub fn batch_deploy_stack_if_changed() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -175,7 +171,6 @@ pub fn pull_stack() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -208,7 +203,6 @@ pub fn batch_pull_stack() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -246,7 +240,6 @@ pub fn start_stack() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -279,7 +272,6 @@ pub fn restart_stack() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -312,7 +304,6 @@ pub fn pause_stack() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -347,7 +338,6 @@ pub fn unpause_stack() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -380,7 +370,6 @@ pub fn stop_stack() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -415,7 +404,6 @@ pub fn destroy_stack() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -453,7 +441,6 @@ pub fn run_stack_service() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -518,7 +505,6 @@ pub fn batch_destroy_stack() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(BatchExecutionResponse)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -35,7 +35,6 @@ pub fn remove_swarm_nodes() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -70,7 +69,6 @@ pub fn update_swarm_node() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -117,7 +115,6 @@ pub fn remove_swarm_stacks() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -160,7 +157,6 @@ pub fn remove_swarm_services() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -195,7 +191,6 @@ pub fn create_swarm_config() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -245,7 +240,6 @@ pub fn rotate_swarm_config() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -280,7 +274,6 @@ pub fn remove_swarm_configs() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -315,7 +308,6 @@ pub fn create_swarm_secret() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -367,7 +359,6 @@ pub fn rotate_swarm_secret() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
@@ -402,7 +393,6 @@ pub fn remove_swarm_secrets() {}
|
||||
Serialize, Deserialize, Debug, Clone, PartialEq, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -27,7 +27,6 @@ pub fn run_sync() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoExecuteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -144,7 +144,7 @@ pub struct GetCoreInfoResponse {
|
||||
pub enable_fancy_toml: bool,
|
||||
/// TZ identifier Core is using, if manually set.
|
||||
pub timezone: String,
|
||||
/// Public key for Core / Periphery authentication.
|
||||
/// Default public key allowing this Core to authenticate to Periphery agents.
|
||||
pub public_key: String,
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ pub struct CreateOnboardingKey {
|
||||
#[serde(default)]
|
||||
pub expires: I64,
|
||||
/// Optionally specify an existing private key, otherwise
|
||||
/// generate fresh key. This key is not stored directly,
|
||||
/// only the public key.
|
||||
/// generate fresh key.
|
||||
pub private_key: Option<String>,
|
||||
/// Default tags to apply to Servers created using this key.
|
||||
#[serde(default)]
|
||||
|
||||
@@ -242,7 +242,6 @@ pub fn commit_sync() {}
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Resolve, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(Update)]
|
||||
#[error(mogh_error::Error)]
|
||||
|
||||
@@ -81,10 +81,6 @@ pub type _PartialActionConfig = PartialActionConfig;
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct ActionConfig {
|
||||
|
||||
@@ -74,10 +74,6 @@ pub struct Alert {
|
||||
utoipa::ToSchema
|
||||
))
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
strum_discriminants(derive(schemars::JsonSchema))
|
||||
)]
|
||||
#[serde(tag = "type", content = "data")]
|
||||
pub enum AlertData {
|
||||
/// A null alert
|
||||
@@ -386,7 +382,6 @@ impl Default for AlertDataVariant {
|
||||
EnumString,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
#[strum(serialize_all = "UPPERCASE")]
|
||||
pub enum SeverityLevel {
|
||||
|
||||
@@ -45,10 +45,6 @@ pub type _PartialAlerterConfig = PartialAlerterConfig;
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct AlerterConfig {
|
||||
@@ -153,7 +149,6 @@ impl utoipa::ToSchema for PartialAlerterConfig {}
|
||||
utoipa::ToSchema
|
||||
))
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(tag = "type", content = "params")]
|
||||
pub enum AlerterEndpoint {
|
||||
/// Send alert serialized to JSON to an http endpoint.
|
||||
@@ -184,7 +179,6 @@ impl Default for AlerterEndpoint {
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Builder,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct CustomAlerterEndpoint {
|
||||
/// The http/s endpoint to send the POST to
|
||||
#[serde(default = "default_custom_url")]
|
||||
@@ -210,7 +204,6 @@ fn default_custom_url() -> String {
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Builder,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct SlackAlerterEndpoint {
|
||||
/// The Slack app webhook url
|
||||
#[serde(default = "default_slack_url")]
|
||||
@@ -238,7 +231,6 @@ fn default_slack_url() -> String {
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Builder,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct DiscordAlerterEndpoint {
|
||||
/// The Discord webhook url
|
||||
#[serde(default = "default_discord_url")]
|
||||
@@ -266,7 +258,6 @@ fn default_discord_url() -> String {
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Builder,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct NtfyAlerterEndpoint {
|
||||
/// The ntfy topic URL
|
||||
#[serde(default = "default_ntfy_url")]
|
||||
@@ -297,7 +288,6 @@ fn default_ntfy_url() -> String {
|
||||
Debug, Clone, PartialEq, Serialize, Deserialize, Builder,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct PushoverAlerterEndpoint {
|
||||
/// The pushover URL including application and user tokens in parameters.
|
||||
#[serde(default = "default_pushover_url")]
|
||||
|
||||
@@ -260,30 +260,18 @@ pub type _PartialBuildConfig = PartialBuildConfig;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct BuildConfig {
|
||||
/// Which builder is used to build the image.
|
||||
#[serde(default, alias = "builder")]
|
||||
#[partial_attr(serde(alias = "builder"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "builder"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub builder_id: String,
|
||||
|
||||
/// The current version of the build.
|
||||
#[serde(default)]
|
||||
#[builder(default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(default, schema_with = "version_schema"))
|
||||
)]
|
||||
pub version: Version,
|
||||
|
||||
/// Whether to automatically increment the patch on every build.
|
||||
@@ -535,26 +523,6 @@ fn default_webhook_enabled() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(feature = "schemars")]
|
||||
fn version_schema(
|
||||
_: &mut schemars::SchemaGenerator,
|
||||
) -> schemars::Schema {
|
||||
schemars::json_schema!({
|
||||
"description": "The current version of the build.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/Version"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
impl Default for BuildConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -609,7 +577,6 @@ impl utoipa::ToSchema for PartialBuildConfig {}
|
||||
Debug, Clone, Default, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct ImageRegistryConfig {
|
||||
/// Specify the registry provider domain, eg `docker.io`.
|
||||
/// If not provided, will not push to any registry.
|
||||
|
||||
@@ -125,7 +125,6 @@ impl Default for BuilderConfig {
|
||||
utoipa::ToSchema
|
||||
))
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(tag = "type", content = "params")]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum PartialBuilderConfig {
|
||||
@@ -371,10 +370,13 @@ pub type _PartialUrlBuilderConfig = PartialUrlBuilderConfig;
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
not(feature = "utoipa"),
|
||||
partial_derive(Serialize, Deserialize, Debug, Clone, Default)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "utoipa",
|
||||
partial_derive(Serialize, Deserialize, Debug, Clone, Default,)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
@@ -449,20 +451,12 @@ pub type _PartialServerBuilderConfig = PartialServerBuilderConfig;
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct ServerBuilderConfig {
|
||||
/// The server id of the builder
|
||||
#[serde(default, alias = "server")]
|
||||
#[partial_attr(serde(alias = "server"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "server"))
|
||||
)]
|
||||
pub server_id: String,
|
||||
}
|
||||
|
||||
@@ -491,10 +485,6 @@ pub type _PartialAwsBuilderConfig = PartialAwsBuilderConfig;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct AwsBuilderConfig {
|
||||
|
||||
@@ -124,10 +124,6 @@ pub struct Env {
|
||||
pub komodo_enable_new_users: Option<bool>,
|
||||
/// Override `disable_user_registration`
|
||||
pub komodo_disable_user_registration: Option<bool>,
|
||||
/// Override `disable_local_user_registration`
|
||||
pub komodo_disable_local_user_registration: Option<bool>,
|
||||
/// Override `disable_oidc_user_registration`
|
||||
pub komodo_disable_oidc_user_registration: Option<bool>,
|
||||
/// Override `lock_login_credentials_for`
|
||||
pub komodo_lock_login_credentials_for: Option<Vec<String>>,
|
||||
/// Override `disable_confirm_dialog`
|
||||
@@ -174,8 +170,6 @@ pub struct Env {
|
||||
pub komodo_oidc_additional_audiences: Option<Vec<String>>,
|
||||
/// Override `oidc_additional_audiences` from file
|
||||
pub komodo_oidc_additional_audiences_file: Option<PathBuf>,
|
||||
/// Override `oidc_auto_redirect`
|
||||
pub komodo_oidc_auto_redirect: Option<bool>,
|
||||
|
||||
/// Override `google_oauth.enabled`
|
||||
pub komodo_google_oauth_enabled: Option<bool>,
|
||||
@@ -213,17 +207,6 @@ pub struct Env {
|
||||
/// Override `session_allow_cross_site`
|
||||
pub komodo_session_allow_cross_site: Option<bool>,
|
||||
|
||||
/// Override `x_content_type_options`
|
||||
pub komodo_x_content_type_options: Option<String>,
|
||||
/// Override `x_frame_options`
|
||||
pub komodo_x_frame_options: Option<String>,
|
||||
/// Override `x_xss_protection`
|
||||
pub komodo_x_xss_protection: Option<String>,
|
||||
/// Override `x_referrer_policy`
|
||||
pub komodo_referrer_policy: Option<String>,
|
||||
/// Override `content_security_policy`
|
||||
pub komodo_content_security_policy: Option<String>,
|
||||
|
||||
/// Override `database.uri`
|
||||
#[serde(alias = "komodo_mongo_uri")]
|
||||
pub komodo_database_uri: Option<String>,
|
||||
@@ -474,20 +457,6 @@ pub struct CoreConfig {
|
||||
#[serde(default)]
|
||||
pub disable_user_registration: bool,
|
||||
|
||||
/// Disable local (username/password) user registration only.
|
||||
/// When set, the "Sign Up" button is hidden and local signups are blocked,
|
||||
/// but OIDC and other external provider signups are still allowed.
|
||||
/// If not set, falls back to `disable_user_registration`.
|
||||
#[serde(default)]
|
||||
pub disable_local_user_registration: Option<bool>,
|
||||
|
||||
/// Disable OIDC user registration only.
|
||||
/// When set, new users cannot register via OIDC,
|
||||
/// but local and other provider signups are still allowed.
|
||||
/// If not set, falls back to `disable_user_registration`.
|
||||
#[serde(default)]
|
||||
pub disable_oidc_user_registration: Option<bool>,
|
||||
|
||||
/// List of usernames for which the update username / password
|
||||
/// APIs are disabled. Used by demo to lock the 'demo' : 'demo' login.
|
||||
///
|
||||
@@ -556,12 +525,6 @@ pub struct CoreConfig {
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub oidc_additional_audiences: Vec<String>,
|
||||
|
||||
/// Automatically redirect unauthenticated users to the OIDC provider
|
||||
/// instead of showing the login page.
|
||||
/// Users can bypass the redirect by appending `?disableAutoLogin` to the login URL.
|
||||
#[serde(default)]
|
||||
pub oidc_auto_redirect: bool,
|
||||
|
||||
// =========
|
||||
// = Oauth =
|
||||
// =========
|
||||
@@ -608,37 +571,6 @@ pub struct CoreConfig {
|
||||
#[serde(default)]
|
||||
pub session_allow_cross_site: bool,
|
||||
|
||||
// ====================
|
||||
// = Security Headers =
|
||||
// ====================
|
||||
/// `X-Content-Type-Options` header value.
|
||||
/// Default is `nosniff`. Set as empty string
|
||||
/// to omit the header.
|
||||
#[serde(default = "default_x_content_type_options")]
|
||||
pub x_content_type_options: String,
|
||||
/// `X-Frame-Options` header value. Return an empty string to
|
||||
/// omit the header entirely and allow iframe on any origin. Use `"SAMEORIGIN"` to allow
|
||||
/// same-origin embedding only. Defaults to `"DENY"`.
|
||||
#[serde(default = "default_x_frame_options")]
|
||||
pub x_frame_options: String,
|
||||
/// `X-XSS-PROTECTION` header value. Return an empty string to
|
||||
/// omit the header entirely. Default: `1; mode=block`
|
||||
#[serde(default = "default_x_xss_protection")]
|
||||
pub x_xss_protection: String,
|
||||
/// Apply Referrer Policy directives.
|
||||
/// If empty string, no header is applied.
|
||||
/// Default: `strict-origin-when-cross-origin`
|
||||
#[serde(default = "default_referrer_policy")]
|
||||
pub referrer_policy: String,
|
||||
/// Apply Content Security Policy directives.
|
||||
/// If empty string, no header is applied.
|
||||
/// Default: None
|
||||
///
|
||||
/// Example:
|
||||
/// `default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'`
|
||||
#[serde(default)]
|
||||
pub content_security_policy: String,
|
||||
|
||||
// ============
|
||||
// = Webhooks =
|
||||
// ============
|
||||
@@ -835,22 +767,6 @@ fn default_auth_rate_limit_window_seconds() -> u64 {
|
||||
15
|
||||
}
|
||||
|
||||
fn default_x_content_type_options() -> String {
|
||||
String::from("nosniff")
|
||||
}
|
||||
|
||||
fn default_x_frame_options() -> String {
|
||||
String::from("DENY")
|
||||
}
|
||||
|
||||
fn default_x_xss_protection() -> String {
|
||||
String::from("1; mode=block")
|
||||
}
|
||||
|
||||
fn default_referrer_policy() -> String {
|
||||
String::from("strict-origin-when-cross-origin")
|
||||
}
|
||||
|
||||
fn default_sync_directory() -> PathBuf {
|
||||
PathBuf::from("/syncs")
|
||||
}
|
||||
@@ -910,8 +826,6 @@ impl Default for CoreConfig {
|
||||
transparent_mode: Default::default(),
|
||||
enable_new_users: Default::default(),
|
||||
disable_user_registration: Default::default(),
|
||||
disable_local_user_registration: Default::default(),
|
||||
disable_oidc_user_registration: Default::default(),
|
||||
lock_login_credentials_for: Default::default(),
|
||||
disable_non_admin_create: Default::default(),
|
||||
jwt_secret: Default::default(),
|
||||
@@ -923,7 +837,6 @@ impl Default for CoreConfig {
|
||||
oidc_client_secret: Default::default(),
|
||||
oidc_use_full_email: Default::default(),
|
||||
oidc_additional_audiences: Default::default(),
|
||||
oidc_auto_redirect: Default::default(),
|
||||
google_oauth: Default::default(),
|
||||
github_oauth: Default::default(),
|
||||
auth_rate_limit_disabled: Default::default(),
|
||||
@@ -934,11 +847,6 @@ impl Default for CoreConfig {
|
||||
cors_allowed_origins: Default::default(),
|
||||
cors_allow_credentials: Default::default(),
|
||||
session_allow_cross_site: Default::default(),
|
||||
x_content_type_options: default_x_content_type_options(),
|
||||
x_frame_options: default_x_frame_options(),
|
||||
x_xss_protection: default_x_xss_protection(),
|
||||
referrer_policy: default_referrer_policy(),
|
||||
content_security_policy: Default::default(),
|
||||
webhook_secret: Default::default(),
|
||||
webhook_base_url: Default::default(),
|
||||
logging: Default::default(),
|
||||
@@ -1001,10 +909,6 @@ impl CoreConfig {
|
||||
enable_fancy_toml: config.enable_fancy_toml,
|
||||
enable_new_users: config.enable_new_users,
|
||||
disable_user_registration: config.disable_user_registration,
|
||||
disable_local_user_registration: config
|
||||
.disable_local_user_registration,
|
||||
disable_oidc_user_registration: config
|
||||
.disable_oidc_user_registration,
|
||||
disable_non_admin_create: config.disable_non_admin_create,
|
||||
lock_login_credentials_for: config.lock_login_credentials_for,
|
||||
local_auth: config.local_auth,
|
||||
@@ -1028,7 +932,6 @@ impl CoreConfig {
|
||||
.iter()
|
||||
.map(|aud| empty_or_redacted(aud))
|
||||
.collect(),
|
||||
oidc_auto_redirect: config.oidc_auto_redirect,
|
||||
google_oauth: NamedOauthConfig {
|
||||
enabled: config.google_oauth.enabled,
|
||||
client_id: empty_or_redacted(&config.google_oauth.client_id),
|
||||
@@ -1051,11 +954,6 @@ impl CoreConfig {
|
||||
cors_allowed_origins: config.cors_allowed_origins,
|
||||
cors_allow_credentials: config.cors_allow_credentials,
|
||||
session_allow_cross_site: config.session_allow_cross_site,
|
||||
x_content_type_options: config.x_content_type_options,
|
||||
x_frame_options: config.x_frame_options,
|
||||
x_xss_protection: config.x_xss_protection,
|
||||
referrer_policy: config.referrer_policy,
|
||||
content_security_policy: config.content_security_policy,
|
||||
webhook_secret: empty_or_redacted(&config.webhook_secret),
|
||||
webhook_base_url: config.webhook_base_url,
|
||||
database: config.database.sanitized(),
|
||||
@@ -1134,21 +1032,6 @@ impl mogh_server::ServerConfig for &CoreConfig {
|
||||
fn ssl_cert_file(&self) -> &str {
|
||||
&self.ssl_cert_file
|
||||
}
|
||||
fn x_content_type_options(&self) -> &str {
|
||||
&self.x_content_type_options
|
||||
}
|
||||
fn x_frame_options(&self) -> &str {
|
||||
&self.x_frame_options
|
||||
}
|
||||
fn x_xss_protection(&self) -> &str {
|
||||
&self.x_xss_protection
|
||||
}
|
||||
fn referrer_policy(&self) -> &str {
|
||||
&self.referrer_policy
|
||||
}
|
||||
fn content_security_policy(&self) -> &str {
|
||||
&self.content_security_policy
|
||||
}
|
||||
}
|
||||
|
||||
impl mogh_server::cors::CorsConfig for &CoreConfig {
|
||||
|
||||
@@ -119,7 +119,6 @@ impl DatabaseConfig {
|
||||
Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct GitProvider {
|
||||
/// The git provider domain. Default: `github.com`.
|
||||
#[serde(default = "default_git_provider")]
|
||||
@@ -153,7 +152,6 @@ fn default_git_https() -> bool {
|
||||
Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct DockerRegistry {
|
||||
/// The docker provider domain. Default: `docker.io`.
|
||||
#[serde(default = "default_docker_provider")]
|
||||
@@ -184,7 +182,6 @@ fn default_docker_provider() -> String {
|
||||
Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct ProviderAccount {
|
||||
/// The account username. Required.
|
||||
#[serde(alias = "account")]
|
||||
|
||||
@@ -80,10 +80,6 @@ pub type _PartialDeploymentConfig = PartialDeploymentConfig;
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct DeploymentConfig {
|
||||
@@ -93,10 +89,6 @@ pub struct DeploymentConfig {
|
||||
/// swarm_id overrides server_id and the Deployment will be in Swarm mode.
|
||||
#[serde(default, alias = "swarm")]
|
||||
#[partial_attr(serde(alias = "swarm"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "swarm"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub swarm_id: String,
|
||||
|
||||
@@ -106,10 +98,6 @@ pub struct DeploymentConfig {
|
||||
/// swarm_id overrides server_id and the Deployment will be in Swarm mode.
|
||||
#[serde(default, alias = "server")]
|
||||
#[partial_attr(serde(alias = "server"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "server"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub server_id: String,
|
||||
|
||||
@@ -367,7 +355,6 @@ impl utoipa::ToSchema for PartialDeploymentConfig {}
|
||||
utoipa::ToSchema
|
||||
))
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(tag = "type", content = "params")]
|
||||
pub enum DeploymentImage {
|
||||
/// Deploy any external image.
|
||||
@@ -381,7 +368,6 @@ pub enum DeploymentImage {
|
||||
Build {
|
||||
/// The id of the Build
|
||||
#[serde(default, alias = "build")]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "build"))]
|
||||
build_id: String,
|
||||
/// Use a custom / older version of the image produced by the build.
|
||||
/// if version is 0.0.0, this means `latest` image.
|
||||
@@ -464,8 +450,6 @@ pub enum DeploymentState {
|
||||
Created,
|
||||
/// Server mode only. Container is in restart loop
|
||||
Restarting,
|
||||
/// Server mode only. Container is in the process of stopping
|
||||
Stopping,
|
||||
/// Server mode only. Container is being removed
|
||||
Removing,
|
||||
/// Server mode only. Container is paused
|
||||
@@ -493,7 +477,6 @@ impl From<ContainerStateStatusEnum> for DeploymentState {
|
||||
ContainerStateStatusEnum::Restarting => {
|
||||
DeploymentState::Restarting
|
||||
}
|
||||
ContainerStateStatusEnum::Stopping => DeploymentState::Stopping,
|
||||
ContainerStateStatusEnum::Removing => DeploymentState::Removing,
|
||||
ContainerStateStatusEnum::Exited => DeploymentState::Exited,
|
||||
ContainerStateStatusEnum::Dead => DeploymentState::Dead,
|
||||
@@ -517,7 +500,6 @@ impl From<ContainerStateStatusEnum> for DeploymentState {
|
||||
AsRefStr,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum RestartMode {
|
||||
#[default]
|
||||
#[serde(rename = "no")]
|
||||
|
||||
@@ -8,8 +8,8 @@ use typeshare::typeshare;
|
||||
use crate::entities::{I64, Usize};
|
||||
|
||||
use super::{
|
||||
ContainerConfig, GraphDriverData, Mount, PortBinding,
|
||||
ResourcesUlimits,
|
||||
ContainerConfig, GraphDriverData, Mount, MountTypeEnum,
|
||||
PortBinding, ResourcesUlimits,
|
||||
};
|
||||
|
||||
/// Container summary returned by container list apis.
|
||||
@@ -294,7 +294,6 @@ pub enum ContainerStateStatusEnum {
|
||||
Paused,
|
||||
Restarting,
|
||||
Exited,
|
||||
Stopping,
|
||||
Removing,
|
||||
Dead,
|
||||
#[default]
|
||||
@@ -859,8 +858,8 @@ pub enum HostConfigCgroupnsModeEnum {
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
pub struct MountPoint {
|
||||
/// The mount type: - `bind` a mount of a file or directory from the host into the container. - `volume` a docker volume with the given `Name`. - `tmpfs` a `tmpfs`. - `npipe` a named pipe from the host into the container. - `cluster` a Swarm cluster volume
|
||||
#[serde(rename = "Type")]
|
||||
pub typ: Option<String>,
|
||||
#[serde(default, rename = "Type")]
|
||||
pub typ: MountTypeEnum,
|
||||
|
||||
/// Name is the name reference to the underlying data defined by `Source` e.g., the volume name.
|
||||
#[serde(rename = "Name")]
|
||||
|
||||
@@ -267,7 +267,7 @@ pub struct Mount {
|
||||
/// - `tmpfs` Create a tmpfs with the given options. The mount source cannot be specified for tmpfs. - `npipe` Mounts a named pipe from the host into the container. Must exist prior to creating the container.
|
||||
/// - `cluster` a Swarm cluster volume
|
||||
#[serde(default, rename = "Type")]
|
||||
pub typ: MountType,
|
||||
pub typ: MountTypeEnum,
|
||||
|
||||
/// Whether the mount should be read-only.
|
||||
#[serde(rename = "ReadOnly")]
|
||||
@@ -301,8 +301,10 @@ pub struct Mount {
|
||||
Default,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
pub enum MountType {
|
||||
pub enum MountTypeEnum {
|
||||
#[default]
|
||||
#[serde(rename = "")]
|
||||
Empty,
|
||||
#[serde(rename = "bind")]
|
||||
Bind,
|
||||
#[serde(rename = "volume")]
|
||||
@@ -641,15 +643,3 @@ pub struct TlsInfo {
|
||||
#[serde(rename = "CertIssuerPublicKey")]
|
||||
pub cert_issuer_public_key: Option<String>,
|
||||
}
|
||||
|
||||
/// A map of topological domains to topological segments. For in depth details, see documentation for the Topology object in the CSI specification.
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug, Clone, Default, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
pub struct Topology {
|
||||
#[serde(rename = "Segments")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub segments: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
@@ -129,7 +129,6 @@ pub struct NodeSpec {
|
||||
ValueEnum,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum NodeSpecRoleEnum {
|
||||
#[default]
|
||||
#[serde(rename = "")]
|
||||
@@ -156,7 +155,6 @@ pub enum NodeSpecRoleEnum {
|
||||
ValueEnum,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum NodeSpecAvailabilityEnum {
|
||||
#[default]
|
||||
#[serde(rename = "")]
|
||||
|
||||
@@ -3,9 +3,9 @@ use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::entities::{I64, docker::Topology};
|
||||
use crate::entities::I64;
|
||||
|
||||
use super::ObjectVersion;
|
||||
use super::{ObjectVersion, PortBinding};
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
@@ -145,8 +145,8 @@ pub struct ClusterVolumeInfo {
|
||||
pub volume_id: Option<String>,
|
||||
|
||||
/// The topology this volume is actually accessible from.
|
||||
#[serde(rename = "AccessibleTopology")]
|
||||
pub accessible_topology: Option<Vec<Topology>>,
|
||||
#[serde(default, rename = "AccessibleTopology")]
|
||||
pub accessible_topology: Vec<Topology>,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
@@ -319,14 +319,17 @@ pub struct ClusterVolumeSpecAccessModeSecrets {
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
pub struct ClusterVolumeSpecAccessModeAccessibilityRequirements {
|
||||
/// A list of required topologies, at least one of which the volume must be accessible from.
|
||||
#[serde(rename = "Requisite")]
|
||||
pub requisite: Option<Vec<Topology>>,
|
||||
#[serde(default, rename = "Requisite")]
|
||||
pub requisite: Vec<Topology>,
|
||||
|
||||
/// A list of topologies that the volume should attempt to be provisioned in.
|
||||
#[serde(rename = "Preferred")]
|
||||
pub preferred: Option<Vec<Topology>>,
|
||||
#[serde(default, rename = "Preferred")]
|
||||
pub preferred: Vec<Topology>,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
pub type Topology = HashMap<String, Vec<PortBinding>>;
|
||||
|
||||
/// The desired capacity that the volume should be created with. If empty, the plugin will decide the capacity.
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
|
||||
@@ -103,7 +103,6 @@ pub type _Serror = Serror;
|
||||
Debug, Clone, Default, PartialEq, Serialize, Deserialize, Parser,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct NoData {}
|
||||
|
||||
pub trait MergePartial: Sized {
|
||||
@@ -211,14 +210,11 @@ pub struct __Serror {
|
||||
Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct SystemCommand {
|
||||
#[serde(default)]
|
||||
pub path: String,
|
||||
#[serde(default, deserialize_with = "file_contents_deserializer")]
|
||||
pub command: String,
|
||||
#[serde(default)]
|
||||
pub shell_mode: bool,
|
||||
}
|
||||
|
||||
impl SystemCommand {
|
||||
@@ -242,7 +238,6 @@ impl SystemCommand {
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Debug, Clone, Copy, Default, PartialEq)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct Version {
|
||||
pub major: i32,
|
||||
pub minor: i32,
|
||||
@@ -493,7 +488,6 @@ impl ImageDigest {
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct MaintenanceWindow {
|
||||
/// Name for the maintenance window (required)
|
||||
pub name: String,
|
||||
@@ -926,7 +920,6 @@ pub enum DayOfWeek {
|
||||
Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum MaintenanceScheduleType {
|
||||
/// Daily at the specified time
|
||||
#[default]
|
||||
@@ -1371,7 +1364,6 @@ pub enum SearchCombinator {
|
||||
EnumString,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
#[strum(serialize_all = "UPPERCASE")]
|
||||
pub enum TerminationSignal {
|
||||
@@ -1429,11 +1421,6 @@ pub enum TerminationSignal {
|
||||
utoipa::ToSchema,
|
||||
))
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
strum_discriminants(derive(schemars::JsonSchema))
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(tag = "type", content = "id")]
|
||||
pub enum ResourceTarget {
|
||||
System(String),
|
||||
@@ -1590,7 +1577,6 @@ impl ResourceTargetVariant {
|
||||
Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum ScheduleFormat {
|
||||
#[default]
|
||||
English,
|
||||
@@ -1602,7 +1588,6 @@ pub enum ScheduleFormat {
|
||||
Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum FileFormat {
|
||||
#[default]
|
||||
|
||||
@@ -118,7 +118,6 @@ impl UserTarget {
|
||||
Default,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum PermissionLevel {
|
||||
/// No permissions.
|
||||
#[default]
|
||||
@@ -157,7 +156,6 @@ impl Default for &PermissionLevel {
|
||||
Ord,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum SpecificPermission {
|
||||
/// On **Server**
|
||||
/// - Access the terminal apis
|
||||
@@ -195,7 +193,6 @@ impl SpecificPermission {
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct PermissionLevelAndSpecifics {
|
||||
pub level: PermissionLevel,
|
||||
#[cfg_attr(feature = "utoipa", schema(value_type = Vec<SpecificPermission>))]
|
||||
|
||||
@@ -82,20 +82,12 @@ pub type _PartialProcedureConfig = PartialProcedureConfig;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Partial, Builder)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct ProcedureConfig {
|
||||
/// The stages to be run by the procedure.
|
||||
#[serde(default, alias = "stage")]
|
||||
#[partial_attr(serde(alias = "stage"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "stage"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub stages: Vec<ProcedureStage>,
|
||||
|
||||
@@ -215,7 +207,6 @@ impl utoipa::ToSchema for PartialProcedureConfig {}
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct ProcedureStage {
|
||||
/// A name for the procedure
|
||||
pub name: String,
|
||||
@@ -231,7 +222,6 @@ pub struct ProcedureStage {
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct EnabledExecution {
|
||||
/// The execution request to run.
|
||||
pub execution: Execution,
|
||||
|
||||
@@ -113,30 +113,18 @@ pub type _PartialRepoConfig = PartialRepoConfig;
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct RepoConfig {
|
||||
/// The server to clone the repo on.
|
||||
#[serde(default, alias = "server")]
|
||||
#[partial_attr(serde(alias = "server"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "server"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub server_id: String,
|
||||
|
||||
/// Attach a builder to 'build' the repo.
|
||||
#[serde(default, alias = "builder")]
|
||||
#[partial_attr(serde(alias = "builder"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "builder"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub builder_id: String,
|
||||
|
||||
|
||||
@@ -96,10 +96,6 @@ pub type _PartialServerConfig = PartialServerConfig;
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct ServerConfig {
|
||||
|
||||
@@ -293,10 +293,6 @@ pub type _PartialStackConfig = PartialStackConfig;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct StackConfig {
|
||||
@@ -306,10 +302,6 @@ pub struct StackConfig {
|
||||
/// swarm_id overrides server_id and the Stack will be in Swarm mode.
|
||||
#[serde(default, alias = "swarm")]
|
||||
#[partial_attr(serde(alias = "swarm"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "swarm"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub swarm_id: String,
|
||||
|
||||
@@ -319,10 +311,6 @@ pub struct StackConfig {
|
||||
/// swarm_id overrides server_id and the Stack will be in Swarm mode.
|
||||
#[serde(default, alias = "server")]
|
||||
#[partial_attr(serde(alias = "server"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "server"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub server_id: String,
|
||||
|
||||
@@ -383,17 +371,6 @@ pub struct StackConfig {
|
||||
#[builder(default)]
|
||||
pub auto_update_all_services: bool,
|
||||
|
||||
/// Ignore certain services during Global Auto Update polling.
|
||||
/// Services listed here are skipped only in the global auto-update flow.
|
||||
/// Manual checks still include all services.
|
||||
#[serde(default, deserialize_with = "string_list_deserializer")]
|
||||
#[partial_attr(serde(
|
||||
default,
|
||||
deserialize_with = "option_string_list_deserializer"
|
||||
))]
|
||||
#[builder(default)]
|
||||
pub auto_update_skip_services: Vec<String>,
|
||||
|
||||
/// Whether to run `docker compose down` before `compose up`.
|
||||
#[serde(default)]
|
||||
#[builder(default)]
|
||||
@@ -711,7 +688,6 @@ impl Default for StackConfig {
|
||||
poll_for_updates: Default::default(),
|
||||
auto_update: Default::default(),
|
||||
auto_update_all_services: Default::default(),
|
||||
auto_update_skip_services: Default::default(),
|
||||
ignore_services: Default::default(),
|
||||
pre_deploy: Default::default(),
|
||||
post_deploy: Default::default(),
|
||||
@@ -939,7 +915,6 @@ pub struct StackRemoteFileContents {
|
||||
Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum StackFileRequires {
|
||||
/// Diff requires service redeploy.
|
||||
#[serde(alias = "redeploy")]
|
||||
@@ -958,7 +933,6 @@ pub enum StackFileRequires {
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct AdditionalEnvFile {
|
||||
/// File path relative to run directory
|
||||
pub path: String,
|
||||
@@ -1038,7 +1012,6 @@ impl<'de> Deserialize<'de> for AdditionalEnvFile {
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct StackFileDependency {
|
||||
/// Specify the file
|
||||
pub path: String,
|
||||
|
||||
@@ -82,10 +82,6 @@ pub type _PartialSwarmConfig = PartialSwarmConfig;
|
||||
)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct SwarmConfig {
|
||||
@@ -94,10 +90,6 @@ pub struct SwarmConfig {
|
||||
/// tries the next Server.
|
||||
#[serde(default, alias = "servers")]
|
||||
#[partial_attr(serde(alias = "servers"))]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_attr(schemars(rename = "servers"))
|
||||
)]
|
||||
#[builder(default)]
|
||||
pub server_ids: Vec<String>,
|
||||
|
||||
|
||||
@@ -186,10 +186,6 @@ pub type _PartialResourceSyncConfig = PartialResourceSyncConfig;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Builder, Partial)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[partial_derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
partial_derive(schemars::JsonSchema)
|
||||
)]
|
||||
#[diff_derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[partial(skip_serializing_none, from, diff)]
|
||||
pub struct ResourceSyncConfig {
|
||||
|
||||
@@ -26,134 +26,102 @@ use super::{
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "Resources"))]
|
||||
pub struct ResourcesToml {
|
||||
/// Declare a swarm
|
||||
#[serde(
|
||||
default,
|
||||
alias = "swarm",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "swarm"))]
|
||||
pub swarms: Vec<ResourceToml<_PartialSwarmConfig>>,
|
||||
|
||||
/// Declare a server
|
||||
#[serde(
|
||||
default,
|
||||
alias = "server",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "server"))]
|
||||
pub servers: Vec<ResourceToml<_PartialServerConfig>>,
|
||||
|
||||
/// Declare a stack
|
||||
#[serde(
|
||||
default,
|
||||
alias = "stack",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "stack"))]
|
||||
pub stacks: Vec<ResourceToml<_PartialStackConfig>>,
|
||||
|
||||
/// Declare a deployment
|
||||
#[serde(
|
||||
default,
|
||||
alias = "deployment",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "deployment"))]
|
||||
pub deployments: Vec<ResourceToml<_PartialDeploymentConfig>>,
|
||||
|
||||
/// Declare a build
|
||||
#[serde(
|
||||
default,
|
||||
alias = "stack",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
pub stacks: Vec<ResourceToml<_PartialStackConfig>>,
|
||||
|
||||
#[serde(
|
||||
default,
|
||||
alias = "build",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "build"))]
|
||||
pub builds: Vec<ResourceToml<_PartialBuildConfig>>,
|
||||
|
||||
/// Declare a repo
|
||||
#[serde(
|
||||
default,
|
||||
alias = "repo",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "repo"))]
|
||||
pub repos: Vec<ResourceToml<_PartialRepoConfig>>,
|
||||
|
||||
/// Declare a procedure
|
||||
#[serde(
|
||||
default,
|
||||
alias = "procedure",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "procedure"))]
|
||||
pub procedures: Vec<ResourceToml<_PartialProcedureConfig>>,
|
||||
|
||||
/// Declare an action
|
||||
#[serde(
|
||||
default,
|
||||
alias = "action",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "action"))]
|
||||
pub actions: Vec<ResourceToml<_PartialActionConfig>>,
|
||||
|
||||
/// Declare an alerter
|
||||
#[serde(
|
||||
default,
|
||||
alias = "alerter",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "alerter"))]
|
||||
pub alerters: Vec<ResourceToml<_PartialAlerterConfig>>,
|
||||
|
||||
/// Declare a builder
|
||||
#[serde(
|
||||
default,
|
||||
alias = "builder",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "builder"))]
|
||||
pub builders: Vec<ResourceToml<_PartialBuilderConfig>>,
|
||||
|
||||
/// Declare a resource sync
|
||||
#[serde(
|
||||
default,
|
||||
alias = "resource_sync",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
schemars(rename = "resource_sync")
|
||||
)]
|
||||
pub resource_syncs: Vec<ResourceToml<_PartialResourceSyncConfig>>,
|
||||
|
||||
/// Declare a user group
|
||||
#[serde(
|
||||
default,
|
||||
alias = "user_group",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "user_group"))]
|
||||
pub user_groups: Vec<UserGroupToml>,
|
||||
|
||||
/// Declare a variable
|
||||
#[serde(
|
||||
default,
|
||||
alias = "variable",
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", schemars(rename = "variable"))]
|
||||
pub variables: Vec<Variable>,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct ResourceToml<PartialConfig: Default> {
|
||||
/// The resource name. Required
|
||||
pub name: String,
|
||||
@@ -197,7 +165,6 @@ fn is_false(b: &bool) -> bool {
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct UserGroupToml {
|
||||
/// User group name
|
||||
pub name: String,
|
||||
@@ -224,7 +191,6 @@ pub struct UserGroupToml {
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct PermissionToml {
|
||||
/// Id can be:
|
||||
/// - resource name. `id = "abcd-build"`
|
||||
|
||||
@@ -6,7 +6,6 @@ use typeshare::typeshare;
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[cfg_attr(
|
||||
feature = "mongo",
|
||||
derive(mongo_indexed::derive::MongoIndexed)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "komodo_client",
|
||||
"version": "2.2.0",
|
||||
"version": "2.1.1",
|
||||
"description": "Komodo client package",
|
||||
"homepage": "https://komo.do",
|
||||
"main": "dist/lib.js",
|
||||
@@ -13,7 +13,7 @@
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"mogh_auth_client": "^1.5.0"
|
||||
"mogh_auth_client": "^1.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^6.0.2"
|
||||
|
||||
@@ -612,7 +612,6 @@ export interface ImageRegistryConfig {
|
||||
export interface SystemCommand {
|
||||
path?: string;
|
||||
command?: string;
|
||||
shell_mode?: boolean;
|
||||
}
|
||||
|
||||
/** The build configuration. */
|
||||
@@ -1428,8 +1427,6 @@ export enum DeploymentState {
|
||||
Created = "created",
|
||||
/** Server mode only. Container is in restart loop */
|
||||
Restarting = "restarting",
|
||||
/** Server mode only. Container is in the process of stopping */
|
||||
Stopping = "stopping",
|
||||
/** Server mode only. Container is being removed */
|
||||
Removing = "removing",
|
||||
/** Server mode only. Container is paused */
|
||||
@@ -2473,12 +2470,6 @@ export interface StackConfig {
|
||||
* Komodo will redeploy the whole Stack (all services).
|
||||
*/
|
||||
auto_update_all_services?: boolean;
|
||||
/**
|
||||
* Ignore certain services during Global Auto Update polling.
|
||||
* Services listed here are skipped only in the global auto-update flow.
|
||||
* Manual checks still include all services.
|
||||
*/
|
||||
auto_update_skip_services?: string[];
|
||||
/** Whether to run `docker compose down` before `compose up`. */
|
||||
destroy_before_deploy?: boolean;
|
||||
/** Whether to skip secret interpolation into the stack environment variables. */
|
||||
@@ -2965,7 +2956,6 @@ export enum ContainerStateStatusEnum {
|
||||
Paused = "paused",
|
||||
Restarting = "restarting",
|
||||
Exited = "exited",
|
||||
Stopping = "stopping",
|
||||
Removing = "removing",
|
||||
Dead = "dead",
|
||||
Empty = "",
|
||||
@@ -3097,7 +3087,8 @@ export interface RestartPolicy {
|
||||
MaximumRetryCount?: I64;
|
||||
}
|
||||
|
||||
export enum MountType {
|
||||
export enum MountTypeEnum {
|
||||
Empty = "",
|
||||
Bind = "bind",
|
||||
Volume = "volume",
|
||||
Image = "image",
|
||||
@@ -3169,7 +3160,7 @@ export interface Mount {
|
||||
* - `tmpfs` Create a tmpfs with the given options. The mount source cannot be specified for tmpfs. - `npipe` Mounts a named pipe from the host into the container. Must exist prior to creating the container.
|
||||
* - `cluster` a Swarm cluster volume
|
||||
*/
|
||||
Type?: MountType;
|
||||
Type?: MountTypeEnum;
|
||||
/** Whether the mount should be read-only. */
|
||||
ReadOnly?: boolean;
|
||||
/** The consistency requirement for the mount: `default`, `consistent`, `cached`, or `delegated`. */
|
||||
@@ -3342,7 +3333,7 @@ export interface GraphDriverData {
|
||||
/** MountPoint represents a mount point configuration inside the container. This is used for reporting the mountpoints in use by a container. */
|
||||
export interface MountPoint {
|
||||
/** The mount type: - `bind` a mount of a file or directory from the host into the container. - `volume` a docker volume with the given `Name`. - `tmpfs` a `tmpfs`. - `npipe` a named pipe from the host into the container. - `cluster` a Swarm cluster volume */
|
||||
Type?: string;
|
||||
Type?: MountTypeEnum;
|
||||
/** Name is the name reference to the underlying data defined by `Source` e.g., the volume name. */
|
||||
Name?: string;
|
||||
/** Source location of the mount. For volumes, this contains the storage location of the volume (within `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains the source (host) part of the bind-mount. For `tmpfs` mount points, this field is empty. */
|
||||
@@ -4302,10 +4293,7 @@ export interface ClusterVolumeSpecAccessModeSecrets {
|
||||
Secret?: string;
|
||||
}
|
||||
|
||||
/** A map of topological domains to topological segments. For in depth details, see documentation for the Topology object in the CSI specification. */
|
||||
export interface Topology {
|
||||
Segments?: Record<string, string>;
|
||||
}
|
||||
export type Topology = Record<string, PortBinding[]>;
|
||||
|
||||
/** Requirements for the accessible topology of the volume. These fields are optional. For an in-depth description of what these fields mean, see the CSI specification. */
|
||||
export interface ClusterVolumeSpecAccessModeAccessibilityRequirements {
|
||||
@@ -6828,8 +6816,7 @@ export interface CreateOnboardingKey {
|
||||
expires?: I64;
|
||||
/**
|
||||
* Optionally specify an existing private key, otherwise
|
||||
* generate fresh key. This key is not stored directly,
|
||||
* only the public key.
|
||||
* generate fresh key.
|
||||
*/
|
||||
private_key?: string;
|
||||
/** Default tags to apply to Servers created using this key. */
|
||||
@@ -7451,31 +7438,18 @@ export interface UserGroupToml {
|
||||
|
||||
/** Specifies resources to sync on Komodo */
|
||||
export interface ResourcesToml {
|
||||
/** Declare a swarm */
|
||||
swarms?: ResourceToml<_PartialSwarmConfig>[];
|
||||
/** Declare a server */
|
||||
servers?: ResourceToml<_PartialServerConfig>[];
|
||||
/** Declare a stack */
|
||||
stacks?: ResourceToml<_PartialStackConfig>[];
|
||||
/** Declare a deployment */
|
||||
deployments?: ResourceToml<_PartialDeploymentConfig>[];
|
||||
/** Declare a build */
|
||||
stacks?: ResourceToml<_PartialStackConfig>[];
|
||||
builds?: ResourceToml<_PartialBuildConfig>[];
|
||||
/** Declare a repo */
|
||||
repos?: ResourceToml<_PartialRepoConfig>[];
|
||||
/** Declare a procedure */
|
||||
procedures?: ResourceToml<_PartialProcedureConfig>[];
|
||||
/** Declare an action */
|
||||
actions?: ResourceToml<_PartialActionConfig>[];
|
||||
/** Declare an alerter */
|
||||
alerters?: ResourceToml<_PartialAlerterConfig>[];
|
||||
/** Declare a builder */
|
||||
builders?: ResourceToml<_PartialBuilderConfig>[];
|
||||
/** Declare a resource sync */
|
||||
resource_syncs?: ResourceToml<_PartialResourceSyncConfig>[];
|
||||
/** Declare a user group */
|
||||
user_groups?: UserGroupToml[];
|
||||
/** Declare a variable */
|
||||
variables?: Variable[];
|
||||
}
|
||||
|
||||
@@ -7764,7 +7738,7 @@ export interface GetCoreInfoResponse {
|
||||
enable_fancy_toml: boolean;
|
||||
/** TZ identifier Core is using, if manually set. */
|
||||
timezone: string;
|
||||
/** Public key for Core / Periphery authentication. */
|
||||
/** Default public key allowing this Core to authenticate to Periphery agents. */
|
||||
public_key: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ jwt-decode@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b"
|
||||
integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==
|
||||
|
||||
mogh_auth_client@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/mogh_auth_client/-/mogh_auth_client-1.5.0.tgz#f54b8ae35648d5bf1e60d7b67fcdcef45b0ccd7a"
|
||||
integrity sha512-eUQmx682AzJRaY4QJSALtIGxXzg2r2Tr8exnDeFMrNe0Ibn4Oqm3h9SkOzYiqqZjKQ13wvHm0RoxT2QKo+908g==
|
||||
mogh_auth_client@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/mogh_auth_client/-/mogh_auth_client-1.2.1.tgz#c8b5e9da101dc8da7b30586e5c5463f5f7a95edb"
|
||||
integrity sha512-8uUjgqagwbMW8BKtTRzfQ4txpw+54hqLszbIvcYf99murVIQu5+NsRZ8/vjP/fOMawgXJXCVsR6O2lamm1BCnQ==
|
||||
dependencies:
|
||||
jwt-decode "^4.0.0"
|
||||
|
||||
|
||||
+1
-2
@@ -145,7 +145,6 @@ PERIPHERY_CORE_PUBLIC_KEYS=file:/config/keys/core.pub
|
||||
## ------ ./my_stack_2
|
||||
## --- ./repos
|
||||
## ------ ./my_repo_1
|
||||
## --- ./builds
|
||||
PERIPHERY_ROOT_DIRECTORY=/etc/komodo
|
||||
|
||||
## Specify whether to disable the terminals feature
|
||||
@@ -165,4 +164,4 @@ PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname
|
||||
## Prettier logging with empty lines between logs
|
||||
PERIPHERY_LOGGING_PRETTY=false
|
||||
## More human readable logging of startup config (multi-line)
|
||||
PERIPHERY_PRETTY_STARTUP_CONFIG=false
|
||||
PERIPHERY_PRETTY_STARTUP_CONFIG=false
|
||||
+3
-60
@@ -167,20 +167,6 @@ init_admin_password = "changeme"
|
||||
## Default: false
|
||||
disable_user_registration = false
|
||||
|
||||
## Disable local (username/password) user registration only.
|
||||
## When set to true, the "Sign Up" button is hidden and local signups are blocked,
|
||||
## but OIDC and other external provider signups may still be allowed.
|
||||
## If not set, falls back to `disable_user_registration`.
|
||||
## Env: KOMODO_DISABLE_LOCAL_USER_REGISTRATION
|
||||
# disable_local_user_registration = true
|
||||
|
||||
## Disable OIDC user registration only.
|
||||
## When set to true, new users cannot register via OIDC,
|
||||
## but local and other provider signups may still be allowed.
|
||||
## If not set, falls back to `disable_user_registration`.
|
||||
## Env: KOMODO_DISABLE_OIDC_USER_REGISTRATION
|
||||
# disable_oidc_user_registration = true
|
||||
|
||||
## New users will be automatically enabled when they sign up.
|
||||
## Otherwise, new users will be disabled on first login.
|
||||
## The first user to login will always be enabled on creation.
|
||||
@@ -281,13 +267,6 @@ oidc_use_full_email = false
|
||||
## Default: empty
|
||||
oidc_additional_audiences = []
|
||||
|
||||
## Automatically redirect unauthenticated users to the OIDC provider
|
||||
## instead of showing the login page.
|
||||
## Users can bypass the redirect by appending `?disableAutoLogin` to the login URL.
|
||||
## Env: KOMODO_OIDC_AUTO_REDIRECT
|
||||
## Default: false
|
||||
oidc_auto_redirect = false
|
||||
|
||||
#########
|
||||
# OAUTH #
|
||||
#########
|
||||
@@ -345,9 +324,9 @@ auth_rate_limit_max_attempts = 5
|
||||
## Default: 15
|
||||
auth_rate_limit_window_seconds = 15
|
||||
|
||||
############################
|
||||
# CORS / SESSION / HEADERS #
|
||||
############################
|
||||
##################
|
||||
# CORS / SESSION #
|
||||
##################
|
||||
|
||||
## Specifically set list of CORS allowed origins.
|
||||
## If empty, allows all origins (`*`).
|
||||
@@ -364,44 +343,8 @@ cors_allow_credentials = false
|
||||
|
||||
## Enabling this sets 'SameSite=None', which allows externally
|
||||
## hosted UIs to use the login flows.
|
||||
## Env: KOMODO_SESSION_ALLOW_CROSS_SITE
|
||||
## Default: false
|
||||
session_allow_cross_site = false
|
||||
|
||||
## `X-Content-Type-Options` header value.
|
||||
## Set as empty string to omit the header.
|
||||
## Env: KOMODO_X_CONTENT_TYPE_OPTIONS
|
||||
## Default: "nosniff"
|
||||
x_content_type_options = "nosniff"
|
||||
|
||||
## `X-Frame-Options` header value.
|
||||
## Set as empty string to omit the header.
|
||||
## Use "SAMEORIGIN" to allow same-origin embedding only.
|
||||
## Env: KOMODO_X_FRAME_OPTIONS
|
||||
## Default: "DENY"
|
||||
x_frame_options = "DENY"
|
||||
|
||||
## `X-Xss-Protection` header value.
|
||||
## Set as empty string to omit the header.
|
||||
## Env: KOMODO_X_XSS_PROTECTION
|
||||
## Default: "1; mode=block"
|
||||
x_xss_protection = "1; mode=block"
|
||||
|
||||
## Apply Referrer Policy directives.
|
||||
## If empty string, no header is applied.
|
||||
## Env: KOMODO_REFERRER_POLICY
|
||||
## Default: "strict-origin-when-cross-origin"
|
||||
referrer_policy = "strict-origin-when-cross-origin"
|
||||
|
||||
## Apply Content Security Policy directives.
|
||||
## If empty string, no header is applied.
|
||||
## Env: KOMODO_CONTENT_SECURITY_POLICY
|
||||
## Default: ""
|
||||
##
|
||||
## Example:
|
||||
## `default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'`
|
||||
content_security_policy = ""
|
||||
|
||||
##################
|
||||
# POLL INTERVALS #
|
||||
##################
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
## ------ ./my_stack_2
|
||||
## --- ./repos
|
||||
## ------ ./my_repo_1
|
||||
## --- ./builds
|
||||
## Each specific sub-directory (like ./stacks) can be overridden below.
|
||||
## Env: PERIPHERY_ROOT_DIRECTORY
|
||||
## Default: /etc/komodo
|
||||
@@ -292,4 +291,4 @@ pretty_startup_config = false
|
||||
## Provide periphery-based secrets
|
||||
# [secrets]
|
||||
# SECRET_1 = "value_1"
|
||||
# SECRET_2 = "value_2"
|
||||
# SECRET_2 = "value_2"
|
||||
@@ -141,7 +141,7 @@ Core and Periphery authenticate using automatically generated public/private key
|
||||
|
||||
### How it works
|
||||
|
||||
1. When you create an **onboarding key** in the UI or API, Komodo Core generates a key pair, and the private key is returned once to the user as the "onboarding key".
|
||||
1. When you create an **onboarding key** in the UI or API, Komodo Core generates a key pair, and the private key is returned once the the user as the "onboarding key".
|
||||
2. When Periphery first connects using the onboarding key, it generates its own key pair, and sends just the public key to Core.
|
||||
Core stores this public key for each Server.
|
||||
3. All subsequent communication is authenticated by performing a
|
||||
@@ -163,7 +163,7 @@ Keys can also be specified inline in config instead of as file paths.
|
||||
### Automatic key rotation
|
||||
|
||||
Komodo supports automatic rotation of the Periphery key pairs.
|
||||
When triggered, already connected Periphery agents generate a new key pair and send the public key to Komodo Core,
|
||||
When triggered, already connected Periphery agents generate a new key pair and sends the new public key to Komodo Core,
|
||||
which updates its expected public key for that server.
|
||||
|
||||
Each Server has an `auto_rotate_keys` setting (default: `true`) that controls whether it participates in the bulk `RotateAllServerKeys` operation.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM rust:1.95.0-trixie as builder
|
||||
FROM rust:1.94.1-bullseye as builder
|
||||
WORKDIR /builder
|
||||
|
||||
COPY . .
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM rust:1.95.0-trixie as builder
|
||||
FROM rust:1.94.1-bullseye as builder
|
||||
WORKDIR /builder
|
||||
|
||||
COPY . .
|
||||
|
||||
@@ -0,0 +1,836 @@
|
||||
import { KOMODO_BASE_URL } from "@main";
|
||||
import { KomodoClient, Types } from "komodo_client";
|
||||
import {
|
||||
AuthResponses,
|
||||
ExecuteResponses,
|
||||
ReadResponses,
|
||||
UserResponses,
|
||||
WriteResponses,
|
||||
} from "komodo_client/dist/responses";
|
||||
import {
|
||||
UseMutationOptions,
|
||||
UseQueryOptions,
|
||||
useMutation,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
} from "@tanstack/react-query";
|
||||
import { UsableResource } from "@types";
|
||||
import { useToast } from "@ui/use-toast";
|
||||
import { atom, useAtom } from "jotai";
|
||||
import { atomFamily } from "jotai/utils";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { has_minimum_permissions, RESOURCE_TARGETS } from "./utils";
|
||||
|
||||
export const atomWithStorage = <T>(key: string, init: T) => {
|
||||
const stored = localStorage.getItem(key);
|
||||
const inner = atom(stored ? JSON.parse(stored) : init);
|
||||
|
||||
return atom(
|
||||
(get) => get(inner),
|
||||
(_, set, newValue) => {
|
||||
set(inner, newValue);
|
||||
localStorage.setItem(key, JSON.stringify(newValue));
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
type LoginTokens = {
|
||||
/** Current User ID */
|
||||
current: string | undefined;
|
||||
/** Array of logged in user ids / tokens */
|
||||
tokens: Array<Types.JwtResponse>;
|
||||
};
|
||||
|
||||
const LOGIN_TOKENS_KEY = "komodo-auth-tokens-v1";
|
||||
|
||||
export const LOGIN_TOKENS = (() => {
|
||||
const stored = localStorage.getItem(LOGIN_TOKENS_KEY);
|
||||
|
||||
let tokens: LoginTokens = stored
|
||||
? JSON.parse(stored)
|
||||
: { current: undefined, tokens: [] };
|
||||
|
||||
const update_local_storage = () => {
|
||||
localStorage.setItem(LOGIN_TOKENS_KEY, JSON.stringify(tokens));
|
||||
};
|
||||
|
||||
const accounts = () => {
|
||||
const current = tokens.tokens.find((t) => t.user_id === tokens.current);
|
||||
const filtered = tokens.tokens.filter((t) => t.user_id !== tokens.current);
|
||||
return current ? [current, ...filtered] : filtered;
|
||||
};
|
||||
|
||||
const add_and_change = (user_id: string, jwt: string) => {
|
||||
const filtered = tokens.tokens.filter((t) => t.user_id !== user_id);
|
||||
filtered.push({ user_id, jwt });
|
||||
filtered.sort();
|
||||
tokens = {
|
||||
current: user_id,
|
||||
tokens: filtered,
|
||||
};
|
||||
update_local_storage();
|
||||
};
|
||||
|
||||
const remove = (user_id: string) => {
|
||||
const filtered = tokens.tokens.filter((t) => t.user_id !== user_id);
|
||||
tokens = {
|
||||
current:
|
||||
tokens.current === user_id ? filtered[0]?.user_id : tokens.current,
|
||||
tokens: filtered,
|
||||
};
|
||||
update_local_storage();
|
||||
};
|
||||
|
||||
const remove_all = () => {
|
||||
tokens = {
|
||||
current: undefined,
|
||||
tokens: [],
|
||||
};
|
||||
update_local_storage();
|
||||
};
|
||||
|
||||
const change = (to_id: string) => {
|
||||
tokens = {
|
||||
current: to_id,
|
||||
tokens: tokens.tokens,
|
||||
};
|
||||
update_local_storage();
|
||||
};
|
||||
|
||||
return {
|
||||
jwt: () =>
|
||||
tokens.current
|
||||
? (tokens.tokens.find((t) => t.user_id === tokens.current)?.jwt ?? "")
|
||||
: "",
|
||||
accounts,
|
||||
add_and_change,
|
||||
remove,
|
||||
remove_all,
|
||||
change,
|
||||
};
|
||||
})();
|
||||
|
||||
export const komodo_client = () =>
|
||||
KomodoClient(KOMODO_BASE_URL, {
|
||||
type: "jwt",
|
||||
params: { jwt: LOGIN_TOKENS.jwt() },
|
||||
});
|
||||
|
||||
// ============== RESOLVER ==============
|
||||
|
||||
export const useLoginOptions = () => {
|
||||
return useQuery({
|
||||
queryKey: ["GetLoginOptions"],
|
||||
queryFn: () => komodo_client().auth("GetLoginOptions", {}),
|
||||
refetchInterval: 30_000,
|
||||
});
|
||||
};
|
||||
|
||||
export const useUser = () => {
|
||||
const userReset = useUserReset();
|
||||
const hasJwt = !!LOGIN_TOKENS.jwt();
|
||||
|
||||
const query = useQuery({
|
||||
queryKey: ["GetUser"],
|
||||
queryFn: () => komodo_client().auth("GetUser", {}),
|
||||
refetchInterval: 30_000,
|
||||
enabled: hasJwt,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (query.data && query.error) {
|
||||
userReset();
|
||||
}
|
||||
}, [query.data, query.error]);
|
||||
|
||||
return query;
|
||||
};
|
||||
|
||||
export const useUserInvalidate = () => {
|
||||
const qc = useQueryClient();
|
||||
return () => {
|
||||
qc.invalidateQueries({ queryKey: ["GetUser"] });
|
||||
};
|
||||
};
|
||||
|
||||
export const useUserReset = () => {
|
||||
const qc = useQueryClient();
|
||||
return () => {
|
||||
qc.resetQueries({ queryKey: ["GetUser"] });
|
||||
};
|
||||
};
|
||||
|
||||
export const useRead = <
|
||||
T extends Types.ReadRequest["type"],
|
||||
R extends Extract<Types.ReadRequest, { type: T }>,
|
||||
P extends R["params"],
|
||||
C extends Omit<
|
||||
UseQueryOptions<
|
||||
ReadResponses[R["type"]],
|
||||
unknown,
|
||||
ReadResponses[R["type"]],
|
||||
(T | P)[]
|
||||
>,
|
||||
"queryFn" | "queryKey"
|
||||
>,
|
||||
>(
|
||||
type: T,
|
||||
params: P,
|
||||
config?: C
|
||||
) => {
|
||||
const hasJwt = !!LOGIN_TOKENS.jwt();
|
||||
return useQuery({
|
||||
queryKey: [type, params],
|
||||
queryFn: () => komodo_client().read<T, R>(type, params),
|
||||
enabled: hasJwt && (config?.enabled !== false),
|
||||
...config,
|
||||
});
|
||||
};
|
||||
|
||||
export const useInvalidate = () => {
|
||||
const qc = useQueryClient();
|
||||
return <
|
||||
Type extends Types.ReadRequest["type"],
|
||||
Params extends Extract<Types.ReadRequest, { type: Type }>["params"],
|
||||
>(
|
||||
...keys: Array<[Type] | [Type, Params]>
|
||||
) => keys.forEach((key) => qc.invalidateQueries({ queryKey: key }));
|
||||
};
|
||||
|
||||
export const useManageUser = <
|
||||
T extends Types.UserRequest["type"],
|
||||
R extends Extract<Types.UserRequest, { type: T }>,
|
||||
P extends R["params"],
|
||||
C extends Omit<
|
||||
UseMutationOptions<UserResponses[T], unknown, P, unknown>,
|
||||
"mutationKey" | "mutationFn"
|
||||
>,
|
||||
>(
|
||||
type: T,
|
||||
config?: C
|
||||
) => {
|
||||
const { toast } = useToast();
|
||||
return useMutation({
|
||||
mutationKey: [type],
|
||||
mutationFn: (params: P) => komodo_client().user<T, R>(type, params),
|
||||
onError: (e: { result: { error?: string; trace?: string[] } }, v, c) => {
|
||||
console.log("Auth error:", e);
|
||||
const msg = e.result?.error ?? "Unknown error. See console.";
|
||||
const detail = e.result?.trace
|
||||
?.map((msg) => msg[0].toUpperCase() + msg.slice(1))
|
||||
.join(" | ");
|
||||
let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + " | " : "";
|
||||
if (detail) {
|
||||
msg_log += detail + " | ";
|
||||
}
|
||||
toast({
|
||||
title: `Request ${type} Failed`,
|
||||
description: `${msg_log}See console for details`,
|
||||
variant: "destructive",
|
||||
});
|
||||
config?.onError && config.onError(e, v, c);
|
||||
},
|
||||
...config,
|
||||
});
|
||||
};
|
||||
|
||||
export const useWrite = <
|
||||
T extends Types.WriteRequest["type"],
|
||||
R extends Extract<Types.WriteRequest, { type: T }>,
|
||||
P extends R["params"],
|
||||
C extends Omit<
|
||||
UseMutationOptions<WriteResponses[R["type"]], unknown, P, unknown>,
|
||||
"mutationKey" | "mutationFn"
|
||||
>,
|
||||
>(
|
||||
type: T,
|
||||
config?: C
|
||||
) => {
|
||||
const { toast } = useToast();
|
||||
return useMutation({
|
||||
mutationKey: [type],
|
||||
mutationFn: (params: P) => komodo_client().write<T, R>(type, params),
|
||||
onError: (e: { result: { error?: string; trace?: string[] } }, v, c) => {
|
||||
console.log("Write error:", e);
|
||||
const msg = e.result.error ?? "Unknown error. See console.";
|
||||
const detail = e.result?.trace
|
||||
?.map((msg) => msg[0].toUpperCase() + msg.slice(1))
|
||||
.join(" | ");
|
||||
let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + " | " : "";
|
||||
if (detail) {
|
||||
msg_log += detail + " | ";
|
||||
}
|
||||
toast({
|
||||
title: `Write request ${type} failed`,
|
||||
description: `${msg_log}See console for details`,
|
||||
variant: "destructive",
|
||||
});
|
||||
config?.onError && config.onError(e, v, c);
|
||||
},
|
||||
...config,
|
||||
});
|
||||
};
|
||||
|
||||
export const useExecute = <
|
||||
T extends Types.ExecuteRequest["type"],
|
||||
R extends Extract<Types.ExecuteRequest, { type: T }>,
|
||||
P extends R["params"],
|
||||
C extends Omit<
|
||||
UseMutationOptions<ExecuteResponses[T], unknown, P, unknown>,
|
||||
"mutationKey" | "mutationFn"
|
||||
>,
|
||||
>(
|
||||
type: T,
|
||||
config?: C
|
||||
) => {
|
||||
const { toast } = useToast();
|
||||
return useMutation({
|
||||
mutationKey: [type],
|
||||
mutationFn: (params: P) => komodo_client().execute<T, R>(type, params),
|
||||
onError: (e: { result: { error?: string; trace?: string[] } }, v, c) => {
|
||||
console.log("Execute error:", e);
|
||||
const msg = e.result.error ?? "Unknown error. See console.";
|
||||
const detail = e.result?.trace
|
||||
?.map((msg) => msg[0].toUpperCase() + msg.slice(1))
|
||||
.join(" | ");
|
||||
let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + " | " : "";
|
||||
if (detail) {
|
||||
msg_log += detail + " | ";
|
||||
}
|
||||
toast({
|
||||
title: `Execute request ${type} failed`,
|
||||
description: `${msg_log}See console for details`,
|
||||
variant: "destructive",
|
||||
});
|
||||
config?.onError && config.onError(e, v, c);
|
||||
},
|
||||
...config,
|
||||
});
|
||||
};
|
||||
|
||||
export const useAuth = <
|
||||
T extends Types.AuthRequest["type"],
|
||||
R extends Extract<Types.AuthRequest, { type: T }>,
|
||||
P extends R["params"],
|
||||
C extends Omit<
|
||||
UseMutationOptions<AuthResponses[T], unknown, P, unknown>,
|
||||
"mutationKey" | "mutationFn"
|
||||
>,
|
||||
>(
|
||||
type: T,
|
||||
config?: C
|
||||
) => {
|
||||
const { toast } = useToast();
|
||||
return useMutation({
|
||||
mutationKey: [type],
|
||||
mutationFn: (params: P) => komodo_client().auth<T, R>(type, params),
|
||||
onError: (e: { result: { error?: string; trace?: string[] } }, v, c) => {
|
||||
console.log("Auth error:", e);
|
||||
const msg = e.result.error ?? "Unknown error. See console.";
|
||||
const detail = e.result?.trace
|
||||
?.map((msg) => msg[0].toUpperCase() + msg.slice(1))
|
||||
.join(" | ");
|
||||
let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + " | " : "";
|
||||
if (detail) {
|
||||
msg_log += detail + " | ";
|
||||
}
|
||||
toast({
|
||||
title: `Auth request ${type} failed`,
|
||||
description: `${msg_log}See console for details`,
|
||||
variant: "destructive",
|
||||
});
|
||||
config?.onError && config.onError(e, v, c);
|
||||
},
|
||||
...config,
|
||||
});
|
||||
};
|
||||
|
||||
// ============== UTILITY ==============
|
||||
|
||||
export const useResourceParamType = () => {
|
||||
const type = useParams().type;
|
||||
if (!type) return undefined;
|
||||
if (type === "resource-syncs") return "ResourceSync";
|
||||
return (type[0].toUpperCase() + type.slice(1, -1)) as UsableResource;
|
||||
};
|
||||
|
||||
type ResourceMap = {
|
||||
[Resource in UsableResource]: Types.ResourceListItem<unknown>[] | undefined;
|
||||
};
|
||||
|
||||
export const useAllResources = (): ResourceMap => {
|
||||
return {
|
||||
Server: useRead("ListServers", {}).data,
|
||||
Stack: useRead("ListStacks", {}).data,
|
||||
Deployment: useRead("ListDeployments", {}).data,
|
||||
Build: useRead("ListBuilds", {}).data,
|
||||
Repo: useRead("ListRepos", {}).data,
|
||||
Procedure: useRead("ListProcedures", {}).data,
|
||||
Action: useRead("ListActions", {}).data,
|
||||
Builder: useRead("ListBuilders", {}).data,
|
||||
Alerter: useRead("ListAlerters", {}).data,
|
||||
ResourceSync: useRead("ListResourceSyncs", {}).data,
|
||||
};
|
||||
};
|
||||
|
||||
// Returns true if Komodo has no resources.
|
||||
export const useNoResources = () => {
|
||||
const resources = useAllResources();
|
||||
for (const target of RESOURCE_TARGETS) {
|
||||
if (resources[target] && resources[target].length) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/** returns function that takes a resource target and checks if it exists */
|
||||
export const useCheckResourceExists = () => {
|
||||
const resources = useAllResources();
|
||||
return (target: Types.ResourceTarget) => {
|
||||
return (
|
||||
resources[target.type as UsableResource]?.some(
|
||||
(resource) => resource.id === target.id
|
||||
) || false
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export const useFilterResources = <Info>(
|
||||
resources?: Types.ResourceListItem<Info>[],
|
||||
search?: string
|
||||
) => {
|
||||
const tags = useTagsFilter();
|
||||
const searchSplit = search?.toLowerCase()?.split(" ") || [];
|
||||
return (
|
||||
resources?.filter(
|
||||
(resource) =>
|
||||
tags.every((tag: string) => resource.tags.includes(tag)) &&
|
||||
(searchSplit.length > 0
|
||||
? searchSplit.every((search) =>
|
||||
resource.name.toLowerCase().includes(search)
|
||||
)
|
||||
: true)
|
||||
) ?? []
|
||||
);
|
||||
};
|
||||
|
||||
export const usePushRecentlyViewed = ({ type, id }: Types.ResourceTarget) => {
|
||||
const userInvalidate = useUserInvalidate();
|
||||
|
||||
const push = useManageUser("PushRecentlyViewed", {
|
||||
onSuccess: userInvalidate,
|
||||
}).mutate;
|
||||
|
||||
const exists = useRead(`List${type as UsableResource}s`, {}).data?.find(
|
||||
(r) => r.id === id
|
||||
)
|
||||
? true
|
||||
: false;
|
||||
|
||||
useEffect(() => {
|
||||
exists && push({ resource: { type, id } });
|
||||
}, [exists, push]);
|
||||
|
||||
return () => push({ resource: { type, id } });
|
||||
};
|
||||
|
||||
export const useSetTitle = (more?: string) => {
|
||||
const info = useRead("GetCoreInfo", {}).data;
|
||||
const title = more ? `${more} | ${info?.title}` : info?.title;
|
||||
useEffect(() => {
|
||||
if (title) {
|
||||
document.title = title;
|
||||
}
|
||||
}, [title]);
|
||||
};
|
||||
|
||||
const tagsAtom = atomWithStorage<string[]>("tags-v0", []);
|
||||
|
||||
export const useTags = () => {
|
||||
const [tags, setTags] = useAtom<string[]>(tagsAtom);
|
||||
|
||||
const add_tag = (tag_id: string) => setTags([...tags, tag_id]);
|
||||
const remove_tag = (tag_id: string) =>
|
||||
setTags(tags.filter((id) => id !== tag_id));
|
||||
const toggle_tag = (tag_id: string) => {
|
||||
if (tags.includes(tag_id)) {
|
||||
remove_tag(tag_id);
|
||||
} else {
|
||||
add_tag(tag_id);
|
||||
}
|
||||
};
|
||||
const clear_tags = () => setTags([]);
|
||||
|
||||
return {
|
||||
tags,
|
||||
add_tag,
|
||||
remove_tag,
|
||||
toggle_tag,
|
||||
clear_tags,
|
||||
};
|
||||
};
|
||||
|
||||
export const useTagsFilter = () => {
|
||||
const [tags] = useAtom<string[]>(tagsAtom);
|
||||
return tags;
|
||||
};
|
||||
|
||||
export type LocalStorageSetter<T> = (state: T) => T;
|
||||
|
||||
export const useLocalStorage = <T>(
|
||||
key: string,
|
||||
init: T
|
||||
): [T, (state: T | LocalStorageSetter<T>) => void] => {
|
||||
const stored = localStorage.getItem(key);
|
||||
const parsed = stored ? (JSON.parse(stored) as T) : undefined;
|
||||
const [state, inner_set] = useState<T>(parsed ?? init);
|
||||
const set = (state: T | LocalStorageSetter<T>) => {
|
||||
inner_set((prev_state) => {
|
||||
const new_val =
|
||||
typeof state === "function"
|
||||
? (state as LocalStorageSetter<T>)(prev_state)
|
||||
: state;
|
||||
localStorage.setItem(key, JSON.stringify(new_val));
|
||||
return new_val;
|
||||
});
|
||||
};
|
||||
return [state, set];
|
||||
};
|
||||
|
||||
export const useKeyListener = (listenKey: string, onPress: () => void) => {
|
||||
useEffect(() => {
|
||||
const keydown = (e: KeyboardEvent) => {
|
||||
// This will ignore Shift + listenKey if it is sent from input / textarea
|
||||
const target = e.target as any;
|
||||
if (target.matches("input") || target.matches("textarea")) return;
|
||||
|
||||
if (e.key === listenKey) {
|
||||
e.preventDefault();
|
||||
onPress();
|
||||
}
|
||||
};
|
||||
document.addEventListener("keydown", keydown);
|
||||
return () => document.removeEventListener("keydown", keydown);
|
||||
});
|
||||
};
|
||||
|
||||
export const useShiftKeyListener = (listenKey: string, onPress: () => void) => {
|
||||
useEffect(() => {
|
||||
const keydown = (e: KeyboardEvent) => {
|
||||
// This will ignore Shift + listenKey if it is sent from input / textarea
|
||||
const target = e.target as any;
|
||||
if (target.matches("input") || target.matches("textarea")) return;
|
||||
|
||||
if (e.shiftKey && e.key === listenKey) {
|
||||
e.preventDefault();
|
||||
onPress();
|
||||
}
|
||||
};
|
||||
document.addEventListener("keydown", keydown);
|
||||
return () => document.removeEventListener("keydown", keydown);
|
||||
});
|
||||
};
|
||||
|
||||
/** Listens for ctrl (or CMD on mac) + the listenKey */
|
||||
export const useCtrlKeyListener = (listenKey: string, onPress: () => void) => {
|
||||
useEffect(() => {
|
||||
const keydown = (e: KeyboardEvent) => {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === listenKey) {
|
||||
e.preventDefault();
|
||||
onPress();
|
||||
}
|
||||
};
|
||||
document.addEventListener("keydown", keydown);
|
||||
return () => document.removeEventListener("keydown", keydown);
|
||||
});
|
||||
};
|
||||
|
||||
export interface PromptHotkeysConfig {
|
||||
/** Function to call when Enter is pressed (confirm action) */
|
||||
onConfirm?: () => void;
|
||||
/** Function to call when Escape is pressed (cancel/close action) */
|
||||
onCancel?: () => void;
|
||||
/** Whether the hotkeys are enabled. Defaults to true */
|
||||
enabled?: boolean;
|
||||
/** Whether to ignore hotkeys when inside input/textarea elements. Defaults to true */
|
||||
ignoreInputs?: boolean;
|
||||
/** Whether the confirm action is disabled (e.g., form validation failed) */
|
||||
confirmDisabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that provides standard prompt/dialog hotkey behavior:
|
||||
* - Enter: Confirm/submit action
|
||||
* - Escape: Cancel/close action
|
||||
*/
|
||||
export const usePromptHotkeys = ({
|
||||
enabled = true,
|
||||
onConfirm,
|
||||
onCancel,
|
||||
ignoreInputs = true,
|
||||
confirmDisabled = false,
|
||||
}: PromptHotkeysConfig) => {
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
|
||||
const findConfirmButton = (): HTMLButtonElement | null => {
|
||||
const dialogContainers = document.querySelectorAll('[role="dialog"], [data-state="open"], .dialog-content');
|
||||
for (const container of dialogContainers) {
|
||||
const button = container.querySelector('[data-confirm-button]:not([disabled])') as HTMLButtonElement;
|
||||
if (button) return button;
|
||||
}
|
||||
|
||||
return document.querySelector('[data-confirm-button]:not([disabled])') as HTMLButtonElement;
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (ignoreInputs) {
|
||||
const target = e.target as HTMLElement;
|
||||
if (
|
||||
target.tagName === "INPUT" ||
|
||||
target.tagName === "TEXTAREA" ||
|
||||
target.tagName === "SELECT" ||
|
||||
target.isContentEditable
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (e.key) {
|
||||
case "Enter":
|
||||
if (onConfirm && !confirmDisabled) {
|
||||
e.preventDefault();
|
||||
const confirmButton = findConfirmButton();
|
||||
if (confirmButton) {
|
||||
confirmButton.click();
|
||||
} else {
|
||||
onConfirm();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Escape":
|
||||
if (onCancel) {
|
||||
e.preventDefault();
|
||||
onCancel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", handleKeyDown);
|
||||
return () => document.removeEventListener("keydown", handleKeyDown);
|
||||
}, [enabled, onConfirm, onCancel, ignoreInputs, confirmDisabled]);
|
||||
};
|
||||
|
||||
export type WebhookIntegration = "Github" | "Gitlab";
|
||||
export type WebhookIntegrations = {
|
||||
[key: string]: WebhookIntegration;
|
||||
};
|
||||
|
||||
const WEBHOOK_INTEGRATIONS_ATOM = atomWithStorage<WebhookIntegrations>(
|
||||
"webhook-integrations-v2",
|
||||
{}
|
||||
);
|
||||
|
||||
export const useWebhookIntegrations = () => {
|
||||
const [integrations, setIntegrations] = useAtom<WebhookIntegrations>(
|
||||
WEBHOOK_INTEGRATIONS_ATOM
|
||||
);
|
||||
return {
|
||||
integrations,
|
||||
setIntegration: (provider: string, integration: WebhookIntegration) =>
|
||||
setIntegrations({
|
||||
...integrations,
|
||||
[provider]: integration,
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
export const getWebhookIntegration = (
|
||||
integrations: WebhookIntegrations,
|
||||
git_provider: string
|
||||
) => {
|
||||
return integrations[git_provider]
|
||||
? integrations[git_provider]
|
||||
: git_provider.includes("gitlab")
|
||||
? "Gitlab"
|
||||
: "Github";
|
||||
};
|
||||
|
||||
export type WebhookIdOrName = "Id" | "Name";
|
||||
|
||||
const WEBHOOK_ID_OR_NAME_ATOM = atomWithStorage<WebhookIdOrName>(
|
||||
"webhook-id-or-name-v1",
|
||||
"Id"
|
||||
);
|
||||
|
||||
export const useWebhookIdOrName = () => {
|
||||
return useAtom<WebhookIdOrName>(WEBHOOK_ID_OR_NAME_ATOM);
|
||||
};
|
||||
|
||||
export type Dimensions = { width: number; height: number };
|
||||
export const useWindowDimensions = () => {
|
||||
const [dimensions, setDimensions] = useState<Dimensions>({
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
useEffect(() => {
|
||||
const callback = () => {
|
||||
setDimensions({
|
||||
width: window.screen.availWidth,
|
||||
height: window.screen.availHeight,
|
||||
});
|
||||
};
|
||||
callback();
|
||||
window.addEventListener("resize", callback);
|
||||
return () => {
|
||||
window.removeEventListener("resize", callback);
|
||||
};
|
||||
}, []);
|
||||
return dimensions;
|
||||
};
|
||||
|
||||
const selected_resources = atomFamily((_: UsableResource) =>
|
||||
atom<string[]>([])
|
||||
);
|
||||
export const useSelectedResources = (type: UsableResource) =>
|
||||
useAtom(selected_resources(type));
|
||||
|
||||
const filter_by_update_available = atomWithStorage<boolean>(
|
||||
"update-available-filter-v1",
|
||||
false
|
||||
);
|
||||
export const useFilterByUpdateAvailable: () => [boolean, () => void] = () => {
|
||||
const [filter, set] = useAtom<boolean>(filter_by_update_available);
|
||||
return [filter, () => set(!filter)];
|
||||
};
|
||||
|
||||
export const usePermissions = ({ type, id }: Types.ResourceTarget) => {
|
||||
const user = useUser().data;
|
||||
const perms = useRead("GetPermission", { target: { type, id } }).data as
|
||||
| Types.PermissionLevelAndSpecifics
|
||||
| Types.PermissionLevel
|
||||
| undefined;
|
||||
const info = useRead("GetCoreInfo", {}).data;
|
||||
const ui_write_disabled = info?.ui_write_disabled ?? false;
|
||||
const disable_non_admin_create = info?.disable_non_admin_create ?? false;
|
||||
|
||||
const level =
|
||||
(perms && typeof perms === "string" ? perms : perms?.level) ??
|
||||
Types.PermissionLevel.None;
|
||||
const specific =
|
||||
(perms && typeof perms === "string" ? [] : perms?.specific) ?? [];
|
||||
|
||||
const canWrite = !ui_write_disabled && level === Types.PermissionLevel.Write;
|
||||
const canExecute = has_minimum_permissions(
|
||||
{ level, specific },
|
||||
Types.PermissionLevel.Execute
|
||||
);
|
||||
|
||||
const [
|
||||
specificLogs,
|
||||
specificInspect,
|
||||
specificTerminal,
|
||||
specificAttach,
|
||||
specificProcesses,
|
||||
] = [
|
||||
specific.includes(Types.SpecificPermission.Logs),
|
||||
specific.includes(Types.SpecificPermission.Inspect),
|
||||
specific.includes(Types.SpecificPermission.Terminal),
|
||||
specific.includes(Types.SpecificPermission.Attach),
|
||||
specific.includes(Types.SpecificPermission.Processes),
|
||||
];
|
||||
|
||||
const canCreate =
|
||||
type === "Server"
|
||||
? user?.admin ||
|
||||
(!disable_non_admin_create && user?.create_server_permissions)
|
||||
: type === "Build"
|
||||
? user?.admin ||
|
||||
(!disable_non_admin_create && user?.create_build_permissions)
|
||||
: type === "Alerter" ||
|
||||
type === "Builder" ||
|
||||
type === "Procedure" ||
|
||||
type === "Action"
|
||||
? user?.admin
|
||||
: user?.admin || !disable_non_admin_create;
|
||||
|
||||
return {
|
||||
canWrite,
|
||||
canExecute,
|
||||
canCreate,
|
||||
specific,
|
||||
specificLogs,
|
||||
specificInspect,
|
||||
specificTerminal,
|
||||
specificAttach,
|
||||
specificProcesses,
|
||||
};
|
||||
};
|
||||
|
||||
const templatesQueryBehaviorAtom =
|
||||
atomWithStorage<Types.TemplatesQueryBehavior>(
|
||||
"templates-query-behavior-v0",
|
||||
Types.TemplatesQueryBehavior.Exclude
|
||||
);
|
||||
|
||||
export const useTemplatesQueryBehavior = () =>
|
||||
useAtom<Types.TemplatesQueryBehavior>(templatesQueryBehaviorAtom);
|
||||
|
||||
export type SettingsView =
|
||||
| "Variables"
|
||||
| "Tags"
|
||||
| "Providers"
|
||||
| "Users"
|
||||
| "Profile";
|
||||
|
||||
const viewAtom = atomWithStorage<SettingsView>("settings-view-v2", "Variables");
|
||||
|
||||
export const useSettingsView = () => useAtom<SettingsView>(viewAtom);
|
||||
|
||||
/**
|
||||
* Map of unique host ports to array of formatted full port map spec
|
||||
* Formatted ex: 0.0.0.0:3000:3000/tcp
|
||||
*/
|
||||
export type PortsMap = { [host_port: string]: Array<Types.Port> };
|
||||
|
||||
export const useContainerPortsMap = (ports: Types.Port[]) => {
|
||||
return useMemo(() => {
|
||||
const map: PortsMap = {};
|
||||
for (const port of ports) {
|
||||
if (!port.PublicPort || !port.PrivatePort) continue;
|
||||
if (map[port.PublicPort]) {
|
||||
map[port.PublicPort].push(port);
|
||||
} else {
|
||||
map[port.PublicPort] = [port];
|
||||
}
|
||||
}
|
||||
for (const key in map) {
|
||||
map[key].sort();
|
||||
}
|
||||
return map;
|
||||
}, [ports]);
|
||||
};
|
||||
|
||||
/**
|
||||
* A custom React hook that debounces a value, delaying its update until after
|
||||
* a specified period of inactivity. This is useful for performance optimization
|
||||
* in scenarios like search inputs, form validation, or API calls.
|
||||
*/
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedValue(value);
|
||||
}, delay);
|
||||
|
||||
return () => {
|
||||
clearTimeout(handler);
|
||||
};
|
||||
}, [value, delay]);
|
||||
|
||||
return debouncedValue;
|
||||
}
|
||||
@@ -167,13 +167,8 @@ fn shell() -> &'static str {
|
||||
String::from("/bin/bash")
|
||||
} else if PathBuf::from("/usr/bin/bash").exists() {
|
||||
String::from("/usr/bin/bash")
|
||||
} else if PathBuf::from("/bin/sh").exists() {
|
||||
String::from("/bin/sh")
|
||||
} else if PathBuf::from("/usr/bin/sh").exists() {
|
||||
String::from("/usr/bin/sh")
|
||||
} else {
|
||||
// try to use sh wherever it is on host by name.
|
||||
String::from("sh")
|
||||
String::from("/bin/sh")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -24,13 +24,6 @@ cd ../docsite && yarn && \
|
||||
cd ../client/core/ts && yarn
|
||||
"""
|
||||
|
||||
[gen-resource-schema]
|
||||
alias = "grs"
|
||||
description = "generates resource toml definitions for edition autosuggest"
|
||||
cmd = """
|
||||
cargo xtask generate resource-schema --pretty --file=./ui/public/schema/resources.json
|
||||
"""
|
||||
|
||||
[gen-client]
|
||||
alias = "gc"
|
||||
description = "generates typescript types and build the ts client"
|
||||
|
||||
+13
-15
@@ -10,36 +10,34 @@
|
||||
"build-client": "cd ../client/core/ts && yarn && yarn build && yarn link"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mantine/core": "^9.0.0",
|
||||
"@mantine/form": "^9.0.0",
|
||||
"@mantine/hooks": "^9.0.0",
|
||||
"@mantine/notifications": "^9.0.0",
|
||||
"@mantine/spotlight": "^9.0.0",
|
||||
"@mantine/core": "^8.3.15",
|
||||
"@mantine/form": "^8.3.15",
|
||||
"@mantine/hooks": "^8.3.15",
|
||||
"@mantine/notifications": "^8.3.15",
|
||||
"@mantine/spotlight": "^8.3.15",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@tanstack/react-query": "^5.96.1",
|
||||
"@tanstack/react-query": "^5.90.21",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@xterm/addon-fit": "^0.11.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"ansi-to-html": "^0.7.2",
|
||||
"jotai": "^2.19.0",
|
||||
"jotai": "^2.18.0",
|
||||
"jotai-family": "^1.0.1",
|
||||
"jotai-location": "^0.6.2",
|
||||
"lucide-react": "^1.7.0",
|
||||
"mogh_auth_client": "^1.5.0",
|
||||
"mogh_ui": "^0.5.1",
|
||||
"lucide-react": "^1.6.0",
|
||||
"monaco-editor": "^0.55.1",
|
||||
"monaco-yaml": "^5.4.1",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-minimal-pie-chart": "^9.1.2",
|
||||
"react-router-dom": "^7.14.0",
|
||||
"react-router-dom": "^7.13.0",
|
||||
"react-xtermjs": "^1.0.10",
|
||||
"recharts": "^3.8.1",
|
||||
"sanitize-html": "^2.17.2",
|
||||
"recharts": "^3.7.0",
|
||||
"sanitize-html": "^2.17.1",
|
||||
"shell-quote": "^1.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^25.5.0",
|
||||
"@types/node": "^25.3.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/sanitize-html": "^2.16.0",
|
||||
@@ -49,7 +47,7 @@
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-preset-mantine": "^1.18.0",
|
||||
"postcss-simple-vars": "^7.0.1",
|
||||
"sass-embedded": "^1.99.0",
|
||||
"sass-embedded": "^1.97.3",
|
||||
"typescript": "^6.0.2",
|
||||
"vite": "^8.0.2"
|
||||
},
|
||||
|
||||
Vendored
+8
-34
@@ -607,7 +607,6 @@ export interface ImageRegistryConfig {
|
||||
export interface SystemCommand {
|
||||
path?: string;
|
||||
command?: string;
|
||||
shell_mode?: boolean;
|
||||
}
|
||||
/** The build configuration. */
|
||||
export interface BuildConfig {
|
||||
@@ -1569,8 +1568,6 @@ export declare enum DeploymentState {
|
||||
Created = "created",
|
||||
/** Server mode only. Container is in restart loop */
|
||||
Restarting = "restarting",
|
||||
/** Server mode only. Container is in the process of stopping */
|
||||
Stopping = "stopping",
|
||||
/** Server mode only. Container is being removed */
|
||||
Removing = "removing",
|
||||
/** Server mode only. Container is paused */
|
||||
@@ -2617,12 +2614,6 @@ export interface StackConfig {
|
||||
* Komodo will redeploy the whole Stack (all services).
|
||||
*/
|
||||
auto_update_all_services?: boolean;
|
||||
/**
|
||||
* Ignore certain services during Global Auto Update polling.
|
||||
* Services listed here are skipped only in the global auto-update flow.
|
||||
* Manual checks still include all services.
|
||||
*/
|
||||
auto_update_skip_services?: string[];
|
||||
/** Whether to run `docker compose down` before `compose up`. */
|
||||
destroy_before_deploy?: boolean;
|
||||
/** Whether to skip secret interpolation into the stack environment variables. */
|
||||
@@ -3082,7 +3073,6 @@ export declare enum ContainerStateStatusEnum {
|
||||
Paused = "paused",
|
||||
Restarting = "restarting",
|
||||
Exited = "exited",
|
||||
Stopping = "stopping",
|
||||
Removing = "removing",
|
||||
Dead = "dead",
|
||||
Empty = ""
|
||||
@@ -3199,7 +3189,8 @@ export interface RestartPolicy {
|
||||
/** If `on-failure` is used, the number of times to retry before giving up. */
|
||||
MaximumRetryCount?: I64;
|
||||
}
|
||||
export declare enum MountType {
|
||||
export declare enum MountTypeEnum {
|
||||
Empty = "",
|
||||
Bind = "bind",
|
||||
Volume = "volume",
|
||||
Image = "image",
|
||||
@@ -3265,7 +3256,7 @@ export interface Mount {
|
||||
* - `tmpfs` Create a tmpfs with the given options. The mount source cannot be specified for tmpfs. - `npipe` Mounts a named pipe from the host into the container. Must exist prior to creating the container.
|
||||
* - `cluster` a Swarm cluster volume
|
||||
*/
|
||||
Type?: MountType;
|
||||
Type?: MountTypeEnum;
|
||||
/** Whether the mount should be read-only. */
|
||||
ReadOnly?: boolean;
|
||||
/** The consistency requirement for the mount: `default`, `consistent`, `cached`, or `delegated`. */
|
||||
@@ -3433,7 +3424,7 @@ export interface GraphDriverData {
|
||||
/** MountPoint represents a mount point configuration inside the container. This is used for reporting the mountpoints in use by a container. */
|
||||
export interface MountPoint {
|
||||
/** The mount type: - `bind` a mount of a file or directory from the host into the container. - `volume` a docker volume with the given `Name`. - `tmpfs` a `tmpfs`. - `npipe` a named pipe from the host into the container. - `cluster` a Swarm cluster volume */
|
||||
Type?: string;
|
||||
Type?: MountTypeEnum;
|
||||
/** Name is the name reference to the underlying data defined by `Source` e.g., the volume name. */
|
||||
Name?: string;
|
||||
/** Source location of the mount. For volumes, this contains the storage location of the volume (within `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains the source (host) part of the bind-mount. For `tmpfs` mount points, this field is empty. */
|
||||
@@ -4307,10 +4298,7 @@ export interface ClusterVolumeSpecAccessModeSecrets {
|
||||
/** Secret is the swarm Secret object from which to read data. This can be a Secret name or ID. The Secret data is retrieved by swarm and used as the value of the key-value pair passed to the plugin. */
|
||||
Secret?: string;
|
||||
}
|
||||
/** A map of topological domains to topological segments. For in depth details, see documentation for the Topology object in the CSI specification. */
|
||||
export interface Topology {
|
||||
Segments?: Record<string, string>;
|
||||
}
|
||||
export type Topology = Record<string, PortBinding[]>;
|
||||
/** Requirements for the accessible topology of the volume. These fields are optional. For an in-depth description of what these fields mean, see the CSI specification. */
|
||||
export interface ClusterVolumeSpecAccessModeAccessibilityRequirements {
|
||||
/** A list of required topologies, at least one of which the volume must be accessible from. */
|
||||
@@ -6575,8 +6563,7 @@ export interface CreateOnboardingKey {
|
||||
expires?: I64;
|
||||
/**
|
||||
* Optionally specify an existing private key, otherwise
|
||||
* generate fresh key. This key is not stored directly,
|
||||
* only the public key.
|
||||
* generate fresh key.
|
||||
*/
|
||||
private_key?: string;
|
||||
/** Default tags to apply to Servers created using this key. */
|
||||
@@ -7145,31 +7132,18 @@ export interface UserGroupToml {
|
||||
}
|
||||
/** Specifies resources to sync on Komodo */
|
||||
export interface ResourcesToml {
|
||||
/** Declare a swarm */
|
||||
swarms?: ResourceToml<_PartialSwarmConfig>[];
|
||||
/** Declare a server */
|
||||
servers?: ResourceToml<_PartialServerConfig>[];
|
||||
/** Declare a stack */
|
||||
stacks?: ResourceToml<_PartialStackConfig>[];
|
||||
/** Declare a deployment */
|
||||
deployments?: ResourceToml<_PartialDeploymentConfig>[];
|
||||
/** Declare a build */
|
||||
stacks?: ResourceToml<_PartialStackConfig>[];
|
||||
builds?: ResourceToml<_PartialBuildConfig>[];
|
||||
/** Declare a repo */
|
||||
repos?: ResourceToml<_PartialRepoConfig>[];
|
||||
/** Declare a procedure */
|
||||
procedures?: ResourceToml<_PartialProcedureConfig>[];
|
||||
/** Declare an action */
|
||||
actions?: ResourceToml<_PartialActionConfig>[];
|
||||
/** Declare an alerter */
|
||||
alerters?: ResourceToml<_PartialAlerterConfig>[];
|
||||
/** Declare a builder */
|
||||
builders?: ResourceToml<_PartialBuilderConfig>[];
|
||||
/** Declare a resource sync */
|
||||
resource_syncs?: ResourceToml<_PartialResourceSyncConfig>[];
|
||||
/** Declare a user group */
|
||||
user_groups?: UserGroupToml[];
|
||||
/** Declare a variable */
|
||||
variables?: Variable[];
|
||||
}
|
||||
/**
|
||||
@@ -7434,7 +7408,7 @@ export interface GetCoreInfoResponse {
|
||||
enable_fancy_toml: boolean;
|
||||
/** TZ identifier Core is using, if manually set. */
|
||||
timezone: string;
|
||||
/** Public key for Core / Periphery authentication. */
|
||||
/** Default public key allowing this Core to authenticate to Periphery agents. */
|
||||
public_key: string;
|
||||
}
|
||||
/** Get a specific deployment by name or id. Response: [Deployment]. */
|
||||
|
||||
+10
-12
@@ -253,8 +253,6 @@ export var DeploymentState;
|
||||
DeploymentState["Created"] = "created";
|
||||
/** Server mode only. Container is in restart loop */
|
||||
DeploymentState["Restarting"] = "restarting";
|
||||
/** Server mode only. Container is in the process of stopping */
|
||||
DeploymentState["Stopping"] = "stopping";
|
||||
/** Server mode only. Container is being removed */
|
||||
DeploymentState["Removing"] = "removing";
|
||||
/** Server mode only. Container is paused */
|
||||
@@ -420,7 +418,6 @@ export var ContainerStateStatusEnum;
|
||||
ContainerStateStatusEnum["Paused"] = "paused";
|
||||
ContainerStateStatusEnum["Restarting"] = "restarting";
|
||||
ContainerStateStatusEnum["Exited"] = "exited";
|
||||
ContainerStateStatusEnum["Stopping"] = "stopping";
|
||||
ContainerStateStatusEnum["Removing"] = "removing";
|
||||
ContainerStateStatusEnum["Dead"] = "dead";
|
||||
ContainerStateStatusEnum["Empty"] = "";
|
||||
@@ -441,15 +438,16 @@ export var RestartPolicyNameEnum;
|
||||
RestartPolicyNameEnum["UnlessStopped"] = "unless-stopped";
|
||||
RestartPolicyNameEnum["OnFailure"] = "on-failure";
|
||||
})(RestartPolicyNameEnum || (RestartPolicyNameEnum = {}));
|
||||
export var MountType;
|
||||
(function (MountType) {
|
||||
MountType["Bind"] = "bind";
|
||||
MountType["Volume"] = "volume";
|
||||
MountType["Image"] = "image";
|
||||
MountType["Tmpfs"] = "tmpfs";
|
||||
MountType["Npipe"] = "npipe";
|
||||
MountType["Cluster"] = "cluster";
|
||||
})(MountType || (MountType = {}));
|
||||
export var MountTypeEnum;
|
||||
(function (MountTypeEnum) {
|
||||
MountTypeEnum["Empty"] = "";
|
||||
MountTypeEnum["Bind"] = "bind";
|
||||
MountTypeEnum["Volume"] = "volume";
|
||||
MountTypeEnum["Image"] = "image";
|
||||
MountTypeEnum["Tmpfs"] = "tmpfs";
|
||||
MountTypeEnum["Npipe"] = "npipe";
|
||||
MountTypeEnum["Cluster"] = "cluster";
|
||||
})(MountTypeEnum || (MountTypeEnum = {}));
|
||||
export var MountBindOptionsPropagationEnum;
|
||||
(function (MountBindOptionsPropagationEnum) {
|
||||
MountBindOptionsPropagationEnum["Empty"] = "";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ import { Suspense } from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import Topbar from "@/app/topbar";
|
||||
import Sidebar from "@/app/sidebar";
|
||||
import { LoadingScreen } from "mogh_ui";
|
||||
import LoadingScreen from "@/ui/loading-screen";
|
||||
import UpdateDetails from "@/components/updates/details";
|
||||
import AlertDetails from "@/components/alerts/details";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import { usableResourcePath } from "@/lib/utils";
|
||||
import { SIDEBAR_RESOURCES } from "@/resources";
|
||||
import { Button, Divider, ScrollArea, Stack, Text } from "@mantine/core";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useRead } from "@/lib/hooks";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import { ActionIcon, Box, Center, Menu } from "@mantine/core";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import AlertList from "@/components/alerts/list";
|
||||
|
||||
@@ -9,8 +9,8 @@ import {
|
||||
SimpleGrid,
|
||||
Text,
|
||||
} from "@mantine/core";
|
||||
import { Link } from "react-router-dom";
|
||||
import { ThemeToggle } from "mogh_ui";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import ThemeToggle from "@/ui/theme-toggle";
|
||||
import UserDropdown from "@/app/topbar/user-dropdown";
|
||||
import TopbarUpdates from "@/app/topbar/updates";
|
||||
import OmniSearch from "@/app/topbar/omni-search";
|
||||
@@ -27,6 +27,7 @@ const Topbar = ({
|
||||
opened: boolean;
|
||||
toggle: () => void;
|
||||
}) => {
|
||||
const nav = useNavigate();
|
||||
const version = useRead("GetVersion", {}, { refetchInterval: 30_000 }).data
|
||||
?.version;
|
||||
return (
|
||||
@@ -45,22 +46,21 @@ const Topbar = ({
|
||||
{/** LEFT AREA */}
|
||||
<Group gap="xs" wrap="nowrap" w="fit-content">
|
||||
<Burger opened={opened} onClick={toggle} hiddenFrom="sm" size="sm" />
|
||||
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
renderRoot={(props) => <Link to="/" {...props} />}
|
||||
onClick={() => nav("/")}
|
||||
size="lg"
|
||||
hiddenFrom="md"
|
||||
>
|
||||
<img src="/mogh-512x512.png" width={32} alt="moghtech" />
|
||||
</ActionIcon>
|
||||
|
||||
<Button
|
||||
variant="subtle"
|
||||
renderRoot={(props) => <Link to="/" {...props} />}
|
||||
c="inherit"
|
||||
leftSection={
|
||||
<img src="/mogh-512x512.png" width={32} alt="moghtech" />
|
||||
}
|
||||
onClick={() => nav("/")}
|
||||
size="lg"
|
||||
visibleFrom="md"
|
||||
>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useSettingsView } from "@/lib/hooks";
|
||||
import { useSettingsView, useShiftKeyListener } from "@/lib/hooks";
|
||||
import {
|
||||
ActionIcon,
|
||||
Divider,
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
} from "@mantine/core";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import { Keyboard } from "lucide-react";
|
||||
import { useShiftKeyListener } from "mogh_ui";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export default function KeyboardShortcuts() {
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
import { ButtonLink, ButtonLinkProps } from "mogh_ui";
|
||||
import { Button, ButtonProps } from "@mantine/core";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export interface TopbarLinkProps extends ButtonLinkProps {
|
||||
export interface TopbarLinkProps extends ButtonProps {
|
||||
to: string;
|
||||
}
|
||||
|
||||
export default function TopbarLink({ to, ...props }: TopbarLinkProps) {
|
||||
return <ButtonLink visibleFrom="md" to={to} {...props} />;
|
||||
return (
|
||||
<Button
|
||||
visibleFrom="md"
|
||||
variant="subtle"
|
||||
px="xs"
|
||||
fz="sm"
|
||||
className="hover-underline"
|
||||
renderRoot={(props) => <Link to={to} target="_blank" {...props} />}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
useSettingsView,
|
||||
useUser,
|
||||
} from "@/lib/hooks";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import { terminalLink, usableResourcePath } from "@/lib/utils";
|
||||
import { RESOURCE_TARGETS, ResourceComponents } from "@/resources";
|
||||
import {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ActionIcon, Badge, Button, Group } from "@mantine/core";
|
||||
import { Spotlight, spotlight } from "@mantine/spotlight";
|
||||
import { useOmniSearch } from "./hooks";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { useShiftKeyListener } from "mogh_ui";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import { useShiftKeyListener } from "@/lib/hooks";
|
||||
import classes from "./index.module.scss";
|
||||
|
||||
export default function OmniSearch({}: {}) {
|
||||
@@ -40,7 +40,6 @@ export default function OmniSearch({}: {}) {
|
||||
query={search}
|
||||
onQueryChange={setSearch}
|
||||
clearQueryOnClose={false}
|
||||
radius="sm"
|
||||
>
|
||||
<Spotlight.Search
|
||||
leftSection={<ICONS.Search size="1.3rem" />}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useRead, useUser, useUserInvalidate, useWrite } from "@/lib/hooks";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import {
|
||||
ActionIcon,
|
||||
Center,
|
||||
|
||||
@@ -21,7 +21,7 @@ import { useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { MoghAuth } from "komodo_client";
|
||||
import { useRead, useUser, useUserInvalidate } from "@/lib/hooks";
|
||||
import { hexColorByIntention } from "mogh_ui";
|
||||
import { hexColorByIntention } from "@/lib/color";
|
||||
|
||||
export default function UserDropdown() {
|
||||
const [_, setRerender] = useState(false);
|
||||
@@ -104,7 +104,7 @@ export default function UserDropdown() {
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
nav(
|
||||
`/login?${new URLSearchParams({ backto: `${location.pathname}${location.search}`, disableAutoLogin: "true" })}`,
|
||||
`/login?${new URLSearchParams({ backto: `${location.pathname}${location.search}` })}`,
|
||||
);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { hexColorByIntention } from "@/lib/color";
|
||||
import { useWebsocketConnected, useWebsocketReconnect } from "@/lib/socket";
|
||||
import { ActionIcon, Box, HoverCard, Text } from "@mantine/core";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { Circle } from "lucide-react";
|
||||
import { hexColorByIntention } from "mogh_ui";
|
||||
|
||||
export default function WebsocketStatus() {
|
||||
const connected = useWebsocketConnected();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { BoxProps, Flex, FlexProps, Group, Stack } from "@mantine/core";
|
||||
import { Types } from "komodo_client";
|
||||
import { AlertTriangle, Check } from "lucide-react";
|
||||
import { fmtDate, fmtUpperCamelcase } from "mogh_ui";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { fmtDate, fmtUpperCamelcase } from "@/lib/formatting";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import { useAlertDetails } from "./details";
|
||||
import AlertLevel from "./level";
|
||||
import ResourceLink from "@/resources/link";
|
||||
import { hexColorByIntention } from "mogh_ui";
|
||||
import { hexColorByIntention } from "@/lib/color";
|
||||
|
||||
export default function AlertCard({
|
||||
alert,
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import { fmtDateWithMinutes, fmtDuration, fmtUpperCamelcase } from "mogh_ui";
|
||||
import {
|
||||
fmtDateWithMinutes,
|
||||
fmtDuration,
|
||||
fmtUpperCamelcase,
|
||||
} from "@/lib/formatting";
|
||||
import { useInvalidate, useRead, useUser, useWrite } from "@/lib/hooks";
|
||||
import { ResourceComponents, UsableResource } from "@/resources";
|
||||
import { ActionIcon, Drawer, Group, Stack, Text } from "@mantine/core";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import { Clock, Link2 } from "lucide-react";
|
||||
import { CopyButton } from "mogh_ui";
|
||||
import { MonacoEditor } from "mogh_ui";
|
||||
import { LoadingScreen } from "mogh_ui";
|
||||
import CopyButton from "@/ui/copy-button";
|
||||
import { MonacoEditor } from "@/components/monaco";
|
||||
import LoadingScreen from "@/ui/loading-screen";
|
||||
import { atom, useAtom } from "jotai";
|
||||
import ResourceLink from "@/resources/link";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { ConfirmButton } from "mogh_ui";
|
||||
import ConfirmButton from "@/ui/confirm-button";
|
||||
import { To, useLocation, useNavigate } from "react-router-dom";
|
||||
|
||||
const alertDetailsAtom = atom<string>();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { alertLevelIntention } from "@/lib/color";
|
||||
import { StatusBadge } from "mogh_ui";
|
||||
import StatusBadge from "@/ui/status-badge";
|
||||
import { Types } from "komodo_client";
|
||||
|
||||
export default function AlertLevel({
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useRead } from "@/lib/hooks";
|
||||
import { Types } from "komodo_client";
|
||||
import AlertCard from "./card";
|
||||
import { Button, Box, BoxProps, Stack } from "@mantine/core";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export interface AlertListProps extends BoxProps {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useInvalidate, useWrite } from "@/lib/hooks";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { useInvalidate, useManageAuth, useWrite } from "@/lib/hooks";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import CopyText from "@/ui/copy-text";
|
||||
import {
|
||||
Button,
|
||||
Group,
|
||||
@@ -12,7 +13,6 @@ import {
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import { Types } from "komodo_client";
|
||||
import { useState } from "react";
|
||||
import { CopyText, useManageAuth } from "mogh_ui";
|
||||
|
||||
const ONE_DAY_MS = 1000 * 60 * 60 * 24;
|
||||
type ExpiresOptions = "90 days" | "180 days" | "1 year" | "Never";
|
||||
@@ -133,20 +133,12 @@ export default function NewApiKey({ userId }: { userId?: string }) {
|
||||
|
||||
<Group justify="space-between" wrap="nowrap">
|
||||
<Text>Key</Text>
|
||||
<CopyText
|
||||
content={created.key}
|
||||
label="API key"
|
||||
w={{ base: 200, lg: 250 }}
|
||||
/>
|
||||
<CopyText content={created.key} label="API key" w={{ base: 200, lg: 250 }} />
|
||||
</Group>
|
||||
|
||||
<Group justify="space-between" wrap="nowrap">
|
||||
<Text>Secret</Text>
|
||||
<CopyText
|
||||
content={created.secret}
|
||||
label="API secret"
|
||||
w={{ base: 200, lg: 250 }}
|
||||
/>
|
||||
<CopyText content={created.secret} label="API secret" w={{ base: 200, lg: 250 }} />
|
||||
</Group>
|
||||
|
||||
<Group justify="end" onClick={close}>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { Section, SectionProps, useManageAuth } from "mogh_ui";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import Section, { SectionProps } from "@/ui/section";
|
||||
import NewApiKey from "./new";
|
||||
import ApiKeysTable from "./table";
|
||||
import { useInvalidate, useRead, useWrite } from "@/lib/hooks";
|
||||
import { useInvalidate, useManageAuth, useRead, useWrite } from "@/lib/hooks";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { Box } from "@mantine/core";
|
||||
|
||||
@@ -47,6 +47,7 @@ export default function ApiKeysSection({
|
||||
isPending={isPending}
|
||||
title="API Keys"
|
||||
titleFz="h3"
|
||||
|
||||
icon={<ICONS.Key size="1.2rem" />}
|
||||
titleRight={
|
||||
<Box ml="md">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { ConfirmButton } from "mogh_ui";
|
||||
import { CopyText } from "mogh_ui";
|
||||
import { DataTable } from "mogh_ui";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import ConfirmButton from "@/ui/confirm-button";
|
||||
import CopyText from "@/ui/copy-text";
|
||||
import { DataTable } from "@/ui/data-table";
|
||||
import { Text } from "@mantine/core";
|
||||
import { Types } from "komodo_client";
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { fmtUpperCamelcase } from "mogh_ui";
|
||||
import { fmtUpperCamelcase } from "@/lib/formatting";
|
||||
import { useExecute, useSelectedResources, useWrite } from "@/lib/hooks";
|
||||
import { usableResourceExecuteKey } from "@/lib/utils";
|
||||
import { sendCopyNotification, usableResourceExecuteKey } from "@/lib/utils";
|
||||
import { UsableResource } from "@/resources";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
import { Types } from "komodo_client";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
import { FC, useState } from "react";
|
||||
import { sendCopyNotification } from "mogh_ui";
|
||||
|
||||
type Request = Types.ExecuteRequest["type"] | Types.WriteRequest["type"];
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useRead } from "@/lib/hooks";
|
||||
import { ConfigItem } from "mogh_ui";
|
||||
import { ConfigItem } from "@/ui/config/item";
|
||||
import { Select, SelectProps } from "@mantine/core";
|
||||
|
||||
export interface AccountSelectorProps extends Omit<SelectProps, "onSelect"> {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useRead } from "@/lib/hooks";
|
||||
import { filterBySplit } from "mogh_ui";
|
||||
import { useRead, useSearchCombobox } from "@/lib/hooks";
|
||||
import { filterBySplit } from "@/lib/utils";
|
||||
import { Button, Combobox } from "@mantine/core";
|
||||
import { ICONS } from "@/lib/icons";
|
||||
import { useSearchCombobox } from "mogh_ui";
|
||||
import { ICONS } from "@/theme/icons";
|
||||
|
||||
export interface AddExtraArgProps {
|
||||
type: "Deployment" | "Build" | "Stack" | "StackBuild";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user