Skip to content

feat: Support templating the namespace in manifests #355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 23, 2025
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
5 changes: 2 additions & 3 deletions extra/completions/_stackablectl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 2 additions & 6 deletions extra/completions/stackablectl.bash

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions extra/completions/stackablectl.elv

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion extra/completions/stackablectl.fish

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions extra/completions/stackablectl.nu

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 3 additions & 7 deletions rust/stackable-cockpit/src/platform/demo/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,14 @@ impl DemoSpec {
/// - Does the demo support to be installed in the requested namespace?
/// - Does the cluster have enough resources available to run this demo?
#[instrument(skip_all)]
pub async fn check_prerequisites(
&self,
client: &Client,
product_namespace: &str,
) -> Result<(), Error> {
pub async fn check_prerequisites(&self, client: &Client, namespace: &str) -> Result<(), Error> {
debug!("Checking prerequisites before installing demo");

// Returns an error if the demo doesn't support to be installed in the
// requested namespace
if !self.supports_namespace(product_namespace) {
if !self.supports_namespace(namespace) {
return Err(Error::UnsupportedNamespace {
requested: product_namespace.to_string(),
requested: namespace.to_owned(),
supported: self.supported_namespaces.clone(),
});
}
Expand Down
17 changes: 11 additions & 6 deletions rust/stackable-cockpit/src/platform/manifests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,23 @@ pub enum Error {

pub trait InstallManifestsExt {
// TODO (Techassi): This step shouldn't care about templating the manifests nor fetching them from remote
#[instrument(skip_all, fields(%product_namespace))]
#[instrument(skip_all, fields(%namespace))]
#[allow(async_fn_in_trait)]
async fn install_manifests(
manifests: &[ManifestSpec],
parameters: &HashMap<String, String>,
product_namespace: &str,
namespace: &str,
labels: Labels,
client: &Client,
transfer_client: &xfer::Client,
) -> Result<(), Error> {
debug!("Installing manifests");

let mut parameters = parameters.clone();
// We add the NAMESPACE parameter, so that stacks/demos can use that to render e.g. the
// fqdn service names [which contain the namespace].
parameters.insert("NAMESPACE".to_owned(), namespace.to_owned());

for manifest in manifests {
match manifest {
ManifestSpec::HelmChart(helm_file) => {
Expand All @@ -85,7 +90,7 @@ pub trait InstallManifestsExt {
})?;

let helm_chart: helm::Chart = transfer_client
.get(&helm_file, &Template::new(parameters).then(Yaml::new()))
.get(&helm_file, &Template::new(&parameters).then(Yaml::new()))
.await
.context(FileTransferSnafu)?;

Expand All @@ -111,7 +116,7 @@ pub trait InstallManifestsExt {
chart_version: Some(&helm_chart.version),
},
Some(&values_yaml),
product_namespace,
namespace,
true,
)
.context(InstallHelmReleaseSnafu {
Expand All @@ -130,12 +135,12 @@ pub trait InstallManifestsExt {
})?;

let manifests = transfer_client
.get(&path_or_url, &Template::new(parameters))
.get(&path_or_url, &Template::new(&parameters))
.await
.context(FileTransferSnafu)?;

client
.deploy_manifests(&manifests, product_namespace, labels.clone())
.deploy_manifests(&manifests, namespace, labels.clone())
.await
.context(DeployManifestSnafu)?
}
Expand Down
12 changes: 4 additions & 8 deletions rust/stackable-cockpit/src/platform/stack/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,17 @@ impl StackSpec {
/// - Does the stack support to be installed in the requested namespace?
/// - Does the cluster have enough resources available to run this stack?
#[instrument(skip_all)]
pub async fn check_prerequisites(
&self,
client: &Client,
product_namespace: &str,
) -> Result<(), Error> {
pub async fn check_prerequisites(&self, client: &Client, namespace: &str) -> Result<(), Error> {
debug!("Checking prerequisites before installing stack");

// Returns an error if the stack doesn't support to be installed in the
// requested product namespace. When installing a demo, this check is
// already done on the demo spec level, however we still need to check
// here, as stacks can be installed on their own.
if !self.supports_namespace(product_namespace) {
if !self.supports_namespace(namespace) {
return Err(Error::UnsupportedNamespace {
supported: self.supported_namespaces.clone(),
requested: product_namespace.to_string(),
requested: namespace.to_owned(),
});
}

Expand Down Expand Up @@ -204,7 +200,7 @@ impl StackSpec {
&self,
release_list: release::ReleaseList,
operator_namespace: &str,
_product_namespace: &str, // TODO (@NickLarsenNZ): remove this field
_namespace: &str, // TODO (@NickLarsenNZ): remove this field
chart_source: &ChartSourceType,
) -> Result<(), Error> {
info!(self.release, "Trying to install release");
Expand Down
8 changes: 7 additions & 1 deletion rust/stackablectl/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Added

- Pass the stack/demo namespace as a templating variable `NAMESPACE` to manifests.
This should unblock demos to run in all namespaces, as they can template the namespace e.g. for the FQDN of services ([#355]).

### Changed

- Renamed `--product-namespace` argument to `--namespace` ([#373]).
- Renamed `--product-namespace` argument to `--namespace` ([#373], [#355]).
- Kept `--product-namespace` as a hidden alias to be removed in a later release.

### Fixed
Expand All @@ -25,6 +30,7 @@ All notable changes to this project will be documented in this file.
- Improve tracing and log output ([#365]).

[#351]: https://github.com/stackabletech/stackable-cockpit/pull/351
[#355]: https://github.com/stackabletech/stackable-cockpit/pull/355
[#364]: https://github.com/stackabletech/stackable-cockpit/pull/364
[#365]: https://github.com/stackabletech/stackable-cockpit/pull/365

Expand Down
8 changes: 4 additions & 4 deletions rust/stackablectl/src/cmds/stacklet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ pub struct StackletCredentialsArgs {
short = 'n',
global = true,
default_value = DEFAULT_NAMESPACE,
visible_aliases(["product-ns"]),
aliases(["product-ns", "product-namespace"]),
long_help = "Namespace in the cluster used to deploy the products. Use this to select
a different namespace for credential lookup.")]
pub product_namespace: String,
pub namespace: String,
}

#[derive(Debug, Args)]
Expand Down Expand Up @@ -211,7 +211,7 @@ async fn credentials_cmd(args: &StackletCredentialsArgs) -> Result<String, CmdEr

match get_credentials_for_product(
&client,
&args.product_namespace,
&args.namespace,
&args.stacklet_name,
&args.product_name,
)
Expand All @@ -229,7 +229,7 @@ async fn credentials_cmd(args: &StackletCredentialsArgs) -> Result<String, CmdEr

let output = format!(
"Credentials for {} ({}) in namespace '{}':",
args.product_name, args.stacklet_name, args.product_namespace
args.product_name, args.stacklet_name, args.namespace
);

Ok(format!("{}\n\n{}", output, table))
Expand Down
2 changes: 1 addition & 1 deletion rust/stackablectl/src/output/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl ContextExt for ErrorContext {
let mut ctx = tera::Context::new();

ctx.insert("default_operator_namespace", DEFAULT_OPERATOR_NAMESPACE);
ctx.insert("default_product_namespace", DEFAULT_NAMESPACE);
ctx.insert("default_namespace", DEFAULT_NAMESPACE);

ctx.insert("post_hints", &self.post_hints);
ctx.insert("pre_hints", &self.pre_hints);
Expand Down
6 changes: 3 additions & 3 deletions rust/stackablectl/src/output/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::output::{ContextExt, OutputKind};
#[derive(Debug, Default)]
pub struct ResultContext {
used_operator_namespace: String,
used_product_namespace: String,
used_namespace: String,

command_hints: Vec<String>,
post_hints: Vec<String>,
Expand All @@ -20,10 +20,10 @@ impl ContextExt for ResultContext {
let mut ctx = tera::Context::new();

ctx.insert("default_operator_namespace", DEFAULT_OPERATOR_NAMESPACE);
ctx.insert("default_product_namespace", DEFAULT_NAMESPACE);
ctx.insert("default_namespace", DEFAULT_NAMESPACE);

ctx.insert("used_operator_namespace", &self.used_operator_namespace);
ctx.insert("used_product_namespace", &self.used_product_namespace);
ctx.insert("used_namespace", &self.used_namespace);

ctx.insert("command_hints", &self.command_hints);
ctx.insert("post_hints", &self.post_hints);
Expand Down
Loading