Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 89 additions & 75 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bin/nanocl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "nanocl"
version = "0.16.3"
edition = "2021"
authors = ["nanocl contributors <team@next-hat.com>"]
description = "The Self-Sufficient Orchestrator CLI"
description = "Container and virtual machine orchestrator"
readme = "../../README.md"
license = "MIT OR Apache-2.0"
homepage = "https://next-hat.com/nanocl"
Expand Down
13 changes: 12 additions & 1 deletion bin/nanocl/src/commands/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use nanocld_client::stubs::secret::Secret;
use crate::{
config::CliConfig,
models::{
GenericDefaultOpts, SecretArg, SecretCommand, SecretCreateOpts, SecretRow,
GenericDefaultOpts, SecretArg, SecretCommand, SecretCreateOpts,
SecretPatchOpts, SecretRow,
},
};

Expand Down Expand Up @@ -43,6 +44,15 @@ async fn exec_secret_create(
Ok(())
}

async fn exec_secret_patch(
cli_conf: &CliConfig,
opts: &SecretPatchOpts,
) -> IoResult<()> {
let update = opts.clone().try_into()?;
cli_conf.client.patch_secret(&opts.name, &update).await?;
Ok(())
}

/// Function that execute when running `nanocl secret`
pub async fn exec_secret(
cli_conf: &CliConfig,
Expand All @@ -59,5 +69,6 @@ pub async fn exec_secret(
SecretArg::exec_inspect(cli_conf, opts, None).await
}
SecretCommand::Create(opts) => exec_secret_create(cli_conf, opts).await,
SecretCommand::Patch(opts) => exec_secret_patch(cli_conf, opts).await,
}
}
20 changes: 20 additions & 0 deletions bin/nanocl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,26 @@ mod tests {
assert_cli_ok!("secret", "rm", "-y", "test-cli");
}

/// Test Secret patch command for env secrets
#[ntex::test]
async fn secret_patch() {
// Create an env secret
assert_cli_ok!(
"secret",
"create",
"env.test",
"env",
"FOO=bar",
"HELLO=world"
);
// Patch the env secret with a new value for FOO
assert_cli_ok!("secret", "patch", "env.test", "env", "FOO=baz");
// Inspect the secret
assert_cli_ok!("secret", "inspect", "env.test");
// Cleanup
assert_cli_ok!("secret", "rm", "-y", "env.test");
}

#[ntex::test]
async fn virtual_machine() {
assert_cli_ok!(
Expand Down
8 changes: 7 additions & 1 deletion bin/nanocl/src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,15 @@ pub use uninstall::*;
pub use vm::*;
pub use vm_image::*;

const LONG_ABOUT: &str = r#"Nanocl is a modern, self-sufficient orchestrator for containers and virtual machines.
It delivers a clean dev→prod workflow with declarative Statefiles (YAML/TOML/JSON) and opinionated, predictable defaults.
Built in Rust for performance and safety, it keeps operational overhead low while remaining powerful and extensible.
Manage cargoes, resources, jobs, and VMs with dynamic routing, DNS, and end-to-end TLS.
Start local on a single node and scale out when ready — simple to learn, production-grade by design."#;

/// Cli available options and commands
#[derive(Parser)]
#[clap(about, version, name = "nanocl")]
#[clap(name = "nanocl", version, about, long_about = LONG_ABOUT)]
pub struct Cli {
/// Nanocld host default: unix://run/nanocl/nanocl.sock
#[clap(long, short = 'H')]
Expand Down
72 changes: 71 additions & 1 deletion bin/nanocl/src/models/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde::Serialize;
use tabled::Tabled;

use nanocl_error::io::IoError;
use nanocld_client::stubs::secret::{Secret, SecretPartial};
use nanocld_client::stubs::secret::{Secret, SecretPartial, SecretUpdate};

use super::{GenericInspectOpts, GenericListOpts, GenericRemoveOpts};

Expand All @@ -21,6 +21,8 @@ pub enum SecretCommand {
Inspect(GenericInspectOpts),
/// Create a new secret
Create(SecretCreateOpts),
/// Update a secret data
Patch(SecretPatchOpts),
}

/// `nanocl secret` available arguments
Expand Down Expand Up @@ -159,6 +161,74 @@ pub struct SecretCreateOpts {
pub kind: SecretKindCreateCommand,
}

/// Kind for patching secret data
#[derive(Clone, Subcommand)]
pub enum SecretKindPatchCommand {
/// Update env secret values
Env(EnvCreateOpts),
/// Update TLS secret values
Tls(TlsCreateOpts),
/// Update container registry secret values
ContainerRegistry(ContainerRegistryCreateOpts),
}

/// `nanocl secret patch` available options
#[derive(Clone, Parser)]
pub struct SecretPatchOpts {
/// Name of your secret to update
pub name: String,
/// New data of the secret according to its kind
#[clap(subcommand)]
pub kind: SecretKindPatchCommand,
}

impl TryFrom<SecretPatchOpts> for SecretUpdate {
type Error = IoError;

fn try_from(opts: SecretPatchOpts) -> Result<Self, Self::Error> {
let data = match &opts.kind {
SecretKindPatchCommand::Env(env) => serde_json::to_value(&env.values)?,
SecretKindPatchCommand::Tls(tls) => {
let mut cert = tls.certificate.clone();
let mut cert_key = tls.certificate_key.clone();
let mut cert_client = tls.certificate_client.clone();
if cert.is_none() && tls.certificate_path.is_none() {
return Err(IoError::interrupted("Certificate", "is required"));
}
if cert_key.is_none() && tls.certificate_key_path.is_none() {
return Err(IoError::interrupted("Certificate key", "is required"));
}
if let Some(certificate_path) = &tls.certificate_path {
cert = Some(std::fs::read_to_string(certificate_path)?);
}
if let Some(certificate_key_path) = &tls.certificate_key_path {
cert_key = Some(std::fs::read_to_string(certificate_key_path)?);
}
if let Some(certificate_client_path) = &tls.certificate_client_path {
cert_client = Some(std::fs::read_to_string(certificate_client_path)?);
}
let tls = TlsCreateOpts {
certificate: cert,
certificate_key: cert_key,
certificate_client: cert_client,
certificate_path: None,
certificate_key_path: None,
certificate_client_path: None,
..tls.clone()
};
serde_json::to_value(tls)?
}
SecretKindPatchCommand::ContainerRegistry(container_registry) => {
serde_json::to_value(container_registry)?
}
};
Ok(SecretUpdate {
metadata: None,
data,
})
}
}

/// A row of the secret table
#[derive(Tabled)]
#[tabled(rename_all = "UPPERCASE")]
Expand Down
7 changes: 6 additions & 1 deletion bin/ncdns/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ nanocl_utils = { version = "0.7", features = ["build_tools"] }
serde_yaml = "0.9"

[dependencies]
nanocl_error = { version = "0.5", features = ["io", "http", "http_client"] }
nanocl_error = { version = "0.5", features = [
"io",
"http",
"http_client",
"serde_json",
] }
log = "0.4"
clap = { version = "4.5", features = ["derive"] }
ntex = { version = "2", features = ["tokio", "openssl"] }
Expand Down
8 changes: 6 additions & 2 deletions doc/man/nanocl-backup.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
---
title: Backup
sidebar_position: 2
sidebar_position: 1
---

# Backup

# NAME

backup - Backup the current state

## SYNOPSIS

**backup** \[**-o**\|**--output-dir**\] \[**-y**\|**--yes**\]
Expand All @@ -16,7 +20,7 @@ Backup the current state

## OPTIONS

**-o**, **--output-dir**=*OUTPUT_DIR*
**-o**, **--output-dir** *\<OUTPUT_DIR\>*
Directory where to write the backup default to the current directory

**-y**, **--yes**
Expand Down
10 changes: 7 additions & 3 deletions doc/man/nanocl-cargo-create.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
---
title: Cargo create
sidebar_position: 4
sidebar_position: 2
---

# Cargo create

# NAME

create - Create a new cargo

## SYNOPSIS

**create** \[**-v**\|**--volume**\] \[**-e**\|**--env**\]
Expand All @@ -16,10 +20,10 @@ Create a new cargo

## OPTIONS

**-v**, **--volume**=*VOLUMES*
**-v**, **--volume** *\<VOLUMES\>*
Volumes of the cargo

**-e**, **--env**=*ENV*
**-e**, **--env** *\<ENV\>*
Environment variables of the cargo

**-h**, **--help**
Expand Down
14 changes: 9 additions & 5 deletions doc/man/nanocl-cargo-exec.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
---
title: Cargo exec
sidebar_position: 5
sidebar_position: 3
---

# Cargo exec

# NAME

exec - Execute a command inside a cargo

## SYNOPSIS

**exec** \[**-t**\|**--tty**\] \[**--detach-keys**\] \[**-e **\]
Expand All @@ -20,19 +24,19 @@ Execute a command inside a cargo
**-t**, **--tty**
Allocate a pseudo-TTY

**--detach-keys**=*DETACH_KEYS*
**--detach-keys** *\<DETACH_KEYS\>*
Override the key sequence for detaching a container

**-e**=*ENV*
**-e** *\<ENV\>*
Set environment variables

**--privileged**
Give extended privileges to the command

**-u**=*USER*
**-u** *\<USER\>*
Username or UID (format: "\<name\|uid\>\[:\<group\|gid\>\]")

**-w**, **--workdir**=*WORKING_DIR*
**-w**, **--workdir** *\<WORKING_DIR\>*
Working directory inside the container

**-h**, **--help**
Expand Down
6 changes: 5 additions & 1 deletion doc/man/nanocl-cargo-history.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
---
title: Cargo history
sidebar_position: 6
sidebar_position: 4
---

# Cargo history

# NAME

history - List cargo history

## SYNOPSIS

**history** \[**-h**\|**--help**\] \<*NAME*\>
Expand Down
43 changes: 43 additions & 0 deletions doc/man/nanocl-cargo-image.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: Cargo image
sidebar_position: 5
---

# Cargo image

# NAME

nanocl cargo image - \`nanocl cargo image\` available arguments

## SYNOPSIS

**nanocl cargo image** \[**-h**\|**--help**\] \<*subcommands*\>

## DESCRIPTION

\`nanocl cargo image\` available arguments

## OPTIONS

**-h**, **--help**
Print help

# SUBCOMMANDS

nanocl cargo image-list(1)
List cargo images

nanocl cargo image-pull(1)
Pull a new cargo image

nanocl cargo image-remove(1)
Remove an existing cargo image

nanocl cargo image-inspect(1)
Inspect a cargo image

nanocl cargo image-import(1)
Import a cargo image from a tarball

nanocl cargo image-help(1)
Print this message or the help of the given subcommand(s)
8 changes: 6 additions & 2 deletions doc/man/nanocl-cargo-inspect.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
---
title: Cargo inspect
sidebar_position: 7
sidebar_position: 6
---

# Cargo inspect

# NAME

inspect - Inspect a cargo by its name

## SYNOPSIS

**inspect** \[**--display**\] \[**-h**\|**--help**\] \<*KEY*\>
Expand All @@ -15,7 +19,7 @@ Inspect a cargo by its name

## OPTIONS

**--display**=*DISPLAY*
**--display** *\<DISPLAY\>*
Display format


Expand Down
Loading
Loading