Skip to content
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

Respect service type in environment and pipeline variable patching, add dry run #37

Merged
merged 18 commits into from
Oct 15, 2024
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ pippo -c <pippo.json> -p <program-id> -e <environment-id> log save --service <sv
pippo -c <pippo.json> -p <program-id> -e <environment-id> log tail --service <svc> --log <log>
```

### dry-run mode

You can pass the flag `--dry-run` on the command line to preview the changes for
* environment variables
* pipeline variables

### CI mode

Since updating running pipelines or environments that are currently updating is not possible pippo will normally wait until it is possible.
Expand Down
40 changes: 37 additions & 3 deletions src/clap_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use crate::client::CloudManagerClient;
use crate::config::CloudManagerConfig;
use crate::encryption::{decrypt, encrypt};
use crate::logs::{download_log, tail_log};
use crate::models::{Domain, LogType, ServiceType};
use crate::models::{
Domain, EnvironmentVariableServiceType, LogType, PipelineVariableServiceType, ServiceType,
};
use crate::variables::{
get_env_vars, get_pipeline_vars, set_env_vars_from_file, set_pipeline_vars_from_file,
};
Expand Down Expand Up @@ -71,7 +73,8 @@ pub async fn init_cli() {
"🚀 Patching environment variables from input file {}\n",
input
);
set_env_vars_from_file(input, &mut cm_client, cli.ci_mode).await;
set_env_vars_from_file(input, &mut cm_client, cli.ci_mode, cli.dry_run_mode)
.await;
process::exit(0);
}
}
Expand All @@ -94,6 +97,17 @@ pub async fn init_cli() {
.await
.unwrap();
println!("{}", serde_json::to_string_pretty(&env_vars).unwrap());
if let Some(vf) = env_vars.variables.iter().find(|vf| {
vf.service == EnvironmentVariableServiceType::Invalid
}) {
eprintln!(
"{:>8} {} '{}: {}'",
"⚠".yellow(),
"WARN, invalid service type detected for variable".yellow(),
vf.name,
vf.service
);
}
}
} else {
eprintln!("❌ You have to provide a valid Cloud Manager environment ID to run this command!");
Expand Down Expand Up @@ -206,7 +220,13 @@ pub async fn init_cli() {
{
if let PipelineVarsCommands::Set { input } = &pipeline_vars_command {
println!("🚀 Patching pipeline variables from input file {}\n", input);
set_pipeline_vars_from_file(input, &mut cm_client, cli.ci_mode).await;
set_pipeline_vars_from_file(
input,
&mut cm_client,
cli.ci_mode,
cli.dry_run_mode,
)
.await;
process::exit(0);
}
}
Expand Down Expand Up @@ -276,10 +296,24 @@ pub async fn init_cli() {
get_pipeline_vars(&mut cm_client, program_id, &pipeline_id)
.await
.unwrap();

println!(
"{}",
serde_json::to_string_pretty(&pipeline_vars).unwrap()
);
if let Some(vf) = pipeline_vars
.variables
.iter()
.find(|vf| vf.service == PipelineVariableServiceType::Invalid)
{
eprintln!(
"{:>8} {} '{}: {}'",
"⚠".yellow(),
"WARN, invalid service type detected for variable".yellow(),
vf.name,
vf.service
);
}
}
} else {
eprintln!("❌ You have to provide a valid Cloud Manager pipeline ID to run this command!");
Expand Down
4 changes: 4 additions & 0 deletions src/clap_models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub struct Cli {
#[clap(long = "ci", global = true, action = ArgAction::SetTrue )]
pub ci_mode: bool,

/// Only log but to not apply any changes
#[clap(long = "dry-run", global = true, action = ArgAction::SetTrue )]
pub dry_run_mode: bool,

#[clap(subcommand)]
pub command: Option<Commands>,
}
Expand Down
120 changes: 105 additions & 15 deletions src/models.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
use std::fmt;
use strum_macros::{EnumString, IntoStaticStr};

// Common models used across multiple modules
Expand Down Expand Up @@ -30,37 +31,113 @@ pub struct DomainConfig {
#[derive(Debug, Deserialize, Serialize)]
pub struct EnvironmentsConfig {
pub id: u32,
pub variables: Vec<Variable>,
pub variables: Vec<EnvironmentVariable>,
pub domains: Option<Vec<DomainConfig>>,
}

/// Model for a pipeline's ID and all its variables that will be read from the configuration YAML
#[derive(Debug, Deserialize, Serialize)]
pub struct PipelinesConfig {
pub id: u32,
pub variables: Vec<Variable>,
pub variables: Vec<PipelineVariable>,
}

/// Model for common cloud manager variables

/// Possible types that a variable can have
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum VariableType {
String,
SecretString,
}

/// Model for all information about a Cloud Manager environment variable
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Variable {
pub struct EnvironmentVariable {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
#[serde(rename(deserialize = "type", serialize = "type"))]
pub variable_type: VariableType,
#[serde(skip_serializing_if = "Option::is_none")]
pub service: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
#[serde(
default = "EnvironmentVariableServiceType::default",
skip_serializing_if = "environment_variable_skip_serializing"
)]
pub service: EnvironmentVariableServiceType,
}

/// Possible types that a variable can have
/// Possible service types that an environment variable can have
#[derive(Clone, Debug, Deserialize, Serialize, IntoStaticStr, EnumString, PartialEq, Eq)]
#[strum(serialize_all = "lowercase")]
#[serde(rename_all = "lowercase")]
pub enum EnvironmentVariableServiceType {
All,
Author,
Publish,
Preview,
#[serde(other)]
Invalid,
}

impl fmt::Display for EnvironmentVariableServiceType {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"{}",
format!("{}", serde_json::to_string(self).unwrap().to_string())
)
}
}
fn environment_variable_skip_serializing(t: &EnvironmentVariableServiceType) -> bool {
*t == EnvironmentVariableServiceType::All
}

impl EnvironmentVariableServiceType {
fn default() -> Self {
EnvironmentVariableServiceType::All
}
}

/// Model for all information about a Cloud Manager pipeline variable
/// Model for all information about a Cloud Manager environment variable
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct PipelineVariable {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
#[serde(rename(deserialize = "type", serialize = "type"))]
pub variable_type: VariableType,
#[serde(default = "PipelineVariableServiceType::default")]
pub service: PipelineVariableServiceType,
}

/// Possible service types that an pipeline variable can have
#[derive(Clone, Debug, Deserialize, Serialize, IntoStaticStr, EnumString, PartialEq, Eq)]
#[strum(serialize_all = "camelCase")]
#[serde(rename_all = "camelCase")]
pub enum VariableType {
String,
SecretString,
pub enum PipelineVariableServiceType {
Build,
UiTest,
FunctionalTest,
#[serde(other)]
Invalid,
}

impl fmt::Display for PipelineVariableServiceType {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"{}",
format!("{}", serde_json::to_string(self).unwrap().to_string())
)
}
}

impl PipelineVariableServiceType {
fn default() -> Self {
PipelineVariableServiceType::Build
}
}

/// Model for the necessary JWT claims to retrieve an Adobe access token
Expand Down Expand Up @@ -139,15 +216,28 @@ pub struct Environment {

/// Struct to serialize the response of requesting /api/program/{id}/environment/{id}/variables
#[derive(Debug, Deserialize, Serialize)]
pub struct VariablesResponse {
pub struct EnvironmentVariablesResponse {
#[serde(rename(deserialize = "_embedded", serialize = "_embedded"))]
pub variables_list: EnvironmentVariablesList,
}

/// Struct to serialize the response of requesting /api/program/{id}/environment/{id}/variables
#[derive(Debug, Deserialize, Serialize)]
pub struct PipelineVariablesResponse {
#[serde(rename(deserialize = "_embedded", serialize = "_embedded"))]
pub variables_list: VariablesList,
pub variables_list: PipelineVariablesList,
}

/// Struct that holds a list of variables
#[derive(Debug, Deserialize, Serialize)]
pub struct EnvironmentVariablesList {
pub variables: Vec<EnvironmentVariable>,
}

/// Struct that holds a list of variables
#[derive(Debug, Deserialize, Serialize)]
pub struct VariablesList {
pub variables: Vec<Variable>,
pub struct PipelineVariablesList {
pub variables: Vec<PipelineVariable>,
}

// Models for representing Cloud Manager pipelines and descendant objects
Expand Down
Loading
Loading