* Env vars written using same quotes (single vs double) as the user passes

* fmt

* trim start matches '-'

* ts client version
This commit is contained in:
Maxwell Becker
2024-10-22 14:41:17 -04:00
committed by GitHub
parent c0d6d96b64
commit f9b2994d44
20 changed files with 159 additions and 94 deletions

24
Cargo.lock generated
View File

@@ -41,7 +41,7 @@ dependencies = [
[[package]]
name = "alerter"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"axum",
@@ -943,7 +943,7 @@ dependencies = [
[[package]]
name = "command"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"komodo_client",
"run_command",
@@ -1355,7 +1355,7 @@ dependencies = [
[[package]]
name = "environment_file"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"thiserror",
]
@@ -1439,7 +1439,7 @@ dependencies = [
[[package]]
name = "formatting"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"serror",
]
@@ -1571,7 +1571,7 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "git"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"command",
@@ -2191,7 +2191,7 @@ dependencies = [
[[package]]
name = "komodo_cli"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"clap",
@@ -2207,7 +2207,7 @@ dependencies = [
[[package]]
name = "komodo_client"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"async_timing_util",
@@ -2238,7 +2238,7 @@ dependencies = [
[[package]]
name = "komodo_core"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"async_timing_util",
@@ -2296,7 +2296,7 @@ dependencies = [
[[package]]
name = "komodo_periphery"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"async_timing_util",
@@ -2383,7 +2383,7 @@ dependencies = [
[[package]]
name = "logger"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"komodo_client",
@@ -3089,7 +3089,7 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "periphery_client"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"komodo_client",
@@ -4863,7 +4863,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "update_logger"
version = "1.16.1"
version = "1.16.2"
dependencies = [
"anyhow",
"komodo_client",

View File

@@ -9,7 +9,7 @@ members = [
]
[workspace.package]
version = "1.16.1"
version = "1.16.2"
edition = "2021"
authors = ["mbecker20 <becker.maxh@gmail.com>"]
license = "GPL-3.0-or-later"

View File

@@ -97,7 +97,10 @@ impl Resolve<RunAction, (User, Update)> for State {
// Keep this stage name as is, the UI will find the latest update log by matching the stage name
"Execute Action",
None,
format!("deno run --allow-read --allow-net --allow-import {}", path.display()),
format!(
"deno run --allow-read --allow-net --allow-import {}",
path.display()
),
false,
)
.await;

View File

@@ -69,15 +69,16 @@ impl Resolve<GetAlertersSummary, User> for State {
GetAlertersSummary {}: GetAlertersSummary,
user: User,
) -> anyhow::Result<GetAlertersSummaryResponse> {
let query =
match resource::get_resource_object_ids_for_user::<Alerter>(&user)
.await?
{
Some(ids) => doc! {
"_id": { "$in": ids }
},
None => Document::new(),
};
let query = match resource::get_resource_object_ids_for_user::<
Alerter,
>(&user)
.await?
{
Some(ids) => doc! {
"_id": { "$in": ids }
},
None => Document::new(),
};
let total = db_client()
.alerters
.count_documents(query)

View File

@@ -69,15 +69,16 @@ impl Resolve<GetBuildersSummary, User> for State {
GetBuildersSummary {}: GetBuildersSummary,
user: User,
) -> anyhow::Result<GetBuildersSummaryResponse> {
let query =
match resource::get_resource_object_ids_for_user::<Builder>(&user)
.await?
{
Some(ids) => doc! {
"_id": { "$in": ids }
},
None => Document::new(),
};
let query = match resource::get_resource_object_ids_for_user::<
Builder,
>(&user)
.await?
{
Some(ids) => doc! {
"_id": { "$in": ids }
},
None => Document::new(),
};
let total = db_client()
.builders
.count_documents(query)

View File

@@ -130,7 +130,7 @@ impl Resolve<RenameRepo, User> for State {
let server =
resource::get::<Server>(&repo.config.server_id).await?;
let log = match periphery_client(&server)?
.request(api::git::RenameRepo {
curr_name: to_komodo_name(&repo.name),

View File

@@ -182,11 +182,10 @@ impl AllResourcesById {
id_to_tags, match_tags,
)
.await?,
actions:
crate::resource::get_id_to_resource_map::<Action>(
id_to_tags, match_tags,
)
.await?,
actions: crate::resource::get_id_to_resource_map::<Action>(
id_to_tags, match_tags,
)
.await?,
builders: crate::resource::get_id_to_resource_map::<Builder>(
id_to_tags, match_tags,
)

View File

@@ -1,12 +1,15 @@
use anyhow::{anyhow, Context};
use command::run_komodo_command;
use formatting::format_serror;
use komodo_client::entities::{
build::{Build, BuildConfig},
environment_vars_from_str, get_image_name, optional_string,
to_komodo_name,
update::Log,
EnvironmentVar, Version,
use komodo_client::{
entities::{
build::{Build, BuildConfig},
environment_vars_from_str, get_image_name, optional_string,
to_komodo_name,
update::Log,
EnvironmentVar, Version,
},
parsers::QUOTE_PATTERN,
};
use periphery_client::api::build::{
self, PruneBuilders, PruneBuildx,
@@ -101,8 +104,9 @@ impl Resolve<build::Build> for State {
let secret_args = environment_vars_from_str(secret_args)
.context("Invalid secret_args")?;
let _secret_args =
let command_secret_args =
parse_secret_args(&secret_args, *skip_secret_interp)?;
let labels = parse_labels(
&environment_vars_from_str(labels).context("Invalid labels")?,
);
@@ -118,7 +122,7 @@ impl Resolve<build::Build> for State {
// Construct command
let command = format!(
"docker{buildx} build{build_args}{_secret_args}{extra_args}{labels}{image_tags} -f {dockerfile_path} .{push_command}",
"docker{buildx} build{build_args}{command_secret_args}{extra_args}{labels}{image_tags} -f {dockerfile_path} .{push_command}",
);
if *skip_secret_interp {
@@ -190,7 +194,16 @@ fn image_tags(
fn parse_build_args(build_args: &[EnvironmentVar]) -> String {
build_args
.iter()
.map(|p| format!(" --build-arg {}=\"{}\"", p.variable, p.value))
.map(|p| {
if p.value.starts_with(QUOTE_PATTERN)
&& p.value.ends_with(QUOTE_PATTERN)
{
// If the value already wrapped in quotes, don't wrap it again
format!(" --build-arg {}={}", p.variable, p.value)
} else {
format!(" --build-arg {}=\"{}\"", p.variable, p.value)
}
})
.collect::<Vec<_>>()
.join("")
}

View File

@@ -1,14 +1,17 @@
use anyhow::Context;
use command::run_komodo_command;
use formatting::format_serror;
use komodo_client::entities::{
deployment::{
conversions_from_str, extract_registry_domain, Conversion,
Deployment, DeploymentConfig, DeploymentImage, RestartMode,
use komodo_client::{
entities::{
deployment::{
conversions_from_str, extract_registry_domain, Conversion,
Deployment, DeploymentConfig, DeploymentImage, RestartMode,
},
environment_vars_from_str, to_komodo_name,
update::Log,
EnvironmentVar,
},
environment_vars_from_str, to_komodo_name,
update::Log,
EnvironmentVar,
parsers::QUOTE_PATTERN,
};
use periphery_client::api::container::{Deploy, RemoveContainer};
use resolver_api::Resolve;
@@ -175,7 +178,16 @@ fn parse_conversions(
fn parse_environment(environment: &[EnvironmentVar]) -> String {
environment
.iter()
.map(|p| format!(" --env {}=\"{}\"", p.variable, p.value))
.map(|p| {
if p.value.starts_with(QUOTE_PATTERN)
&& p.value.ends_with(QUOTE_PATTERN)
{
// If the value already wrapped in quotes, don't wrap it again
format!(" --env {}={}", p.variable, p.value)
} else {
format!(" --env {}=\"{}\"", p.variable, p.value)
}
})
.collect::<Vec<_>>()
.join("")
}

View File

@@ -1,5 +1,8 @@
use anyhow::Context;
use komodo_client::entities::{EnvironmentVar, SearchCombinator};
use komodo_client::{
entities::{EnvironmentVar, SearchCombinator},
parsers::QUOTE_PATTERN,
};
use crate::config::periphery_config;
@@ -43,7 +46,16 @@ pub fn parse_extra_args(extra_args: &[String]) -> String {
pub fn parse_labels(labels: &[EnvironmentVar]) -> String {
labels
.iter()
.map(|p| format!(" --label {}=\"{}\"", p.variable, p.value))
.map(|p| {
if p.value.starts_with(QUOTE_PATTERN)
&& p.value.ends_with(QUOTE_PATTERN)
{
// If the value already wrapped in quotes, don't wrap it again
format!(" --label {}={}", p.variable, p.value)
} else {
format!(" --label {}=\"{}\"", p.variable, p.value)
}
})
.collect::<Vec<_>>()
.join("")
}

View File

@@ -46,7 +46,7 @@ async fn task(
request: crate::api::PeripheryRequest,
) -> anyhow::Result<String> {
let variant = request.extract_variant();
let res =
State
.resolve_request(request, ())

View File

@@ -12,7 +12,7 @@
//! - X-Api-Secret: `your_api_secret`
//! - Use either Authorization *or* X-Api-Key and X-Api-Secret to authenticate requests.
//! - Body: JSON specifying the request type (`type`) and the parameters (`params`).
//!
//!
//! You can create API keys for your user, or for a Service User with limited permissions,
//! from the Komodo UI Settings page.
//!
@@ -31,11 +31,11 @@
//!
//! The request's parent module (eg. [read], [mod@write]) determines the http path which
//! must be used for the requests. For example, requests under [read] are made using http path `/read`.
//!
//!
//! ## Curl Example
//!
//!
//! Putting it all together, here is an example `curl` for [write::UpdateBuild], to update the version:
//!
//!
//! ```text
//! curl --header "Content-Type: application/json" \
//! --header "X-Api-Key: your_api_key" \

View File

@@ -3,7 +3,10 @@ use resolver_api::derive::Request;
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
use crate::entities::{builder::{Builder, PartialBuilderConfig}, update::Update};
use crate::entities::{
builder::{Builder, PartialBuilderConfig},
update::Update,
};
use super::KomodoWriteRequest;
@@ -94,4 +97,4 @@ pub struct RenameBuilder {
pub id: String,
/// The new name.
pub name: String,
}
}

View File

@@ -3,9 +3,10 @@ use resolver_api::derive::Request;
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
use crate::entities::{procedure::{
Procedure, _PartialProcedureConfig,
}, update::Update};
use crate::entities::{
procedure::{Procedure, _PartialProcedureConfig},
update::Update,
};
use super::KomodoWriteRequest;
@@ -108,4 +109,4 @@ pub struct RenameProcedure {
pub id: String,
/// The new name.
pub name: String,
}
}

View File

@@ -4,7 +4,9 @@ use serde::{Deserialize, Serialize};
use typeshare::typeshare;
use crate::entities::{
repo::{Repo, _PartialRepoConfig}, update::Update, NoData
repo::{Repo, _PartialRepoConfig},
update::Update,
NoData,
};
use super::KomodoWriteRequest;

View File

@@ -3,9 +3,10 @@ use resolver_api::derive::Request;
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
use crate::entities::{server_template::{
PartialServerTemplateConfig, ServerTemplate,
}, update::Update};
use crate::entities::{
server_template::{PartialServerTemplateConfig, ServerTemplate},
update::Update,
};
use super::KomodoWriteRequest;
@@ -96,4 +97,4 @@ pub struct RenameServerTemplate {
pub id: String,
/// The new name.
pub name: String,
}
}

View File

@@ -46,7 +46,7 @@ pub type UpdateUserPasswordResponse = NoData;
/// **Admin only**. Delete a user.
/// Admins can delete any non-admin user.
/// Only Super Admin can delete an admin.
/// No users can delete a Super Admin user.
/// No users can delete a Super Admin user.
/// User cannot delete themselves.
/// Response: [NoData].
#[typeshare]

View File

@@ -34,10 +34,10 @@ use serde::Deserialize;
pub mod api;
pub mod busy;
pub mod deserializers;
pub mod entities;
pub mod parsers;
pub mod ws;
pub mod deserializers;
mod request;

View File

@@ -1,24 +1,40 @@
use anyhow::Context;
pub const QUOTE_PATTERN: &[char] = &['"', '\''];
/// Parses a list of key value pairs from a multiline string
///
/// Example source:
/// ```text
/// # Supports comments
/// KEY_1 = value_1 # end of line comments
///
///
/// # Supports string wrapped values
/// KEY_2="value_2"
/// 'KEY_3 = value_3'
///
///
/// # Also supports yaml list formats
/// - KEY_4: 'value_4'
/// - "KEY_5=value_5"
///
/// # Wrapping outer quotes are removed while inner quotes are preserved
/// "KEY_6 = 'value_6'"
/// ```
///
/// Note this preserves the wrapping string around value.
/// Writing environment file should format the value exactly as it comes in,
/// including the given wrapping quotes.
///
/// Returns:
/// ```text
/// [("KEY_1", "value_1"), ("KEY_2", "value_2"), ("KEY_3", "value_3"), ("KEY_4", "value_4"), ("KEY_5", "value_5")]
/// [
/// ("KEY_1", "value_1"),
/// ("KEY_2", "\"value_2\""),
/// ("KEY_3", "value_3"),
/// ("KEY_4", "'value_4'"),
/// ("KEY_5", "value_5"),
/// ("KEY_6", "'value_6'"),
/// ]
/// ```
pub fn parse_key_value_list(
input: &str,
@@ -46,13 +62,6 @@ pub fn parse_key_value_list(
// Remove preceding '-' (yaml list)
.trim_start_matches('-')
.trim();
// Remove wrapping quotes (from yaml list)
let line = if let Some(line) = line.strip_prefix(['"', '\'']) {
line.strip_suffix(['"', '\'']).unwrap_or(line)
} else {
line
};
// Remove any preceding '"' (from yaml list) (wrapping quotes open)
let (key, value) = line
.split_once(['=', ':'])
.with_context(|| {
@@ -61,15 +70,23 @@ pub fn parse_key_value_list(
)
})
.map(|(key, value)| {
let key = key.trim();
let value = value.trim();
// Remove wrapping quotes around value
let value =
if let Some(value) = value.strip_prefix(['"', '\'']) {
value.strip_suffix(['"', '\'']).unwrap_or(value)
} else {
value
};
(key.trim().to_string(), value.trim().to_string())
// Remove wrapping quotes when around key AND value
let (key, value) = if key.starts_with(QUOTE_PATTERN)
&& !key.ends_with(QUOTE_PATTERN)
&& value.ends_with(QUOTE_PATTERN)
{
(
key.strip_prefix(QUOTE_PATTERN).unwrap().trim(),
value.strip_suffix(QUOTE_PATTERN).unwrap().trim(),
)
} else {
(key, value)
};
(key.to_string(), value.to_string())
})?;
anyhow::Ok((key, value))
})

View File

@@ -1,6 +1,6 @@
{
"name": "komodo_client",
"version": "1.16.1",
"version": "1.16.2",
"description": "Komodo client package",
"homepage": "https://komo.do",
"main": "dist/lib.js",