Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
6 changes: 5 additions & 1 deletion rust/stackable-cockpit/src/platform/operator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ pub enum SpecParseError {
#[snafu(display("empty operator spec input"))]
EmptyInput,

#[snafu(display("invalid operator name {name:?}"))]
#[snafu(display(
"invalid operator name {name:?}. \
It could be the case that this version of stackablectl is too old to know about this particular operator, \
in which case you should update it."
))]
InvalidName { name: String },
}

Expand Down
59 changes: 55 additions & 4 deletions rust/stackablectl/src/cmds/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Possible valid values are:

Use \"stackablectl operator list\" to list available versions for all operators
Use \"stackablectl operator describe <OPERATOR>\" to get available versions for one operator")]
operators: Vec<operator::OperatorSpec>,
operators: Vec<coffee::OperatorOrCoffee>,

/// Namespace in the cluster used to deploy the operators
#[arg(long, default_value = DEFAULT_OPERATOR_NAMESPACE, visible_aliases(["operator-ns"]))]
Expand Down Expand Up @@ -315,6 +315,24 @@ async fn install_cmd(args: &OperatorInstallArgs, cli: &Cli) -> Result<String, Cm
info!("Installing operator(s)");
Span::current().pb_set_message("Installing operator(s)");

let operators: Vec<&operator::OperatorSpec> = args
.operators
.iter()
.filter_map(|operator| match operator {
coffee::OperatorOrCoffee::Coffee => {
indicatif_println!("{}", coffee::COFFEE_ASCII_ART);
None
}
coffee::OperatorOrCoffee::Operator(spec) => Some(spec),
})
.collect();

// In case no operators need to be installed (e.g. coffee was already installed), there is no
// need to connect to Kubernetes and potentially produce error messages.
if operators.is_empty() {
return Ok(String::new());
}

args.local_cluster
.install_if_needed()
.await
Expand All @@ -328,7 +346,7 @@ async fn install_cmd(args: &OperatorInstallArgs, cli: &Cli) -> Result<String, Cm
namespace: args.operator_namespace.clone(),
})?;

for operator in &args.operators {
for operator in &operators {
operator
.install(
&args.operator_namespace,
Expand All @@ -349,8 +367,8 @@ async fn install_cmd(args: &OperatorInstallArgs, cli: &Cli) -> Result<String, Cm
)
.with_output(format!(
"Installed {num_of_operators} {suffix}",
num_of_operators = args.operators.len(),
suffix = if args.operators.len() == 1 {
num_of_operators = operators.len(),
suffix = if operators.len() == 1 {
"operator"
} else {
"operators"
Expand Down Expand Up @@ -597,3 +615,36 @@ where
None => Ok(vec![]),
}
}

mod coffee {
use std::str::FromStr;

pub const COFFEE_ASCII_ART: &str = r#"
) )
( (
.------.
| |]
\ /
`----'

Psst... "coffee" is not an operator, but we get it.
Stackable runs on coffee too. Have a great day! ☕
"#;

#[derive(Clone, Debug)]
pub enum OperatorOrCoffee {
Operator(super::operator::OperatorSpec),
Coffee,
}

impl FromStr for OperatorOrCoffee {
type Err = super::operator::SpecParseError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"coffee" | "coffe" => Ok(OperatorOrCoffee::Coffee),
_ => s.parse().map(OperatorOrCoffee::Operator),
}
}
}
}
Loading