From d2348ea2ddabd5bb4d5ac873a59d92a5d30a9e88 Mon Sep 17 00:00:00 2001 From: Timon Borter Date: Tue, 9 Jul 2024 22:07:41 +0200 Subject: [PATCH] ci: remove github services for devcontainers --- .github/workflows/build.yml | 16 ------------- Cargo.toml | 7 ++++-- dev/podman.sh | 0 src/config.rs | 1 + src/vault.rs | 1 + src/workflow.rs | 5 +---- tests/common/mod.rs | 45 +++++++++++++++++++++++++++++++++++++ tests/init_vault.rs | 29 +++++++++++++++++++++--- tests/rotate.rs | 11 +++++++++ 9 files changed, 90 insertions(+), 25 deletions(-) mode change 100755 => 100644 dev/podman.sh create mode 100644 tests/common/mod.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3246bbf..529fc3e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,22 +18,6 @@ jobs: build: name: 'Rust Build' runs-on: ubuntu-latest - services: - postgres: - image: postgres:12.19-alpine3.20 - ports: - - 5432:5432 - env: - POSTGRES_DB: demo - POSTGRES_USER: demo - POSTGRES_PASSWORD: demo_password - vault: - image: hashicorp/vault:1.17.1 - ports: - - 8200:8200 - options: --cap-add=IPC_LOCK - env: - VAULT_DEV_ROOT_TOKEN_ID: 'root-token' steps: - name: Check out code uses: actions/checkout@v4 diff --git a/Cargo.toml b/Cargo.toml index 869f4f8..74c05aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,15 +8,18 @@ clap = { version = "4.5.8", features = ["derive"] } env_logger = "0.11.3" lazy_static = "1.5.0" log = "0.4.22" +postgres = "0.19.7" +rand = "0.9.0-alpha.1" serde = { version = "1.0.203", features = ["derive"] } serde_yaml = "0.9.34+deprecated" tokio = { version = "1.38.0", features = ["macros", "rt"] } vaultrs = "0.7.2" -rand = "0.9.0-alpha.1" -postgres = "0.19.7" [dev-dependencies] assert_cmd = "2.0.14" predicates = "3.1.0" reqwest = { version = "0.12.5", features = ["json"] } serde_json = "1.0.120" +tempfile = "3.10.1" +testcontainers = { version = "0.20.0", features = ["blocking"] } +testcontainers-modules = { version = "0.8.0", features = ["blocking", "postgres"] } diff --git a/dev/podman.sh b/dev/podman.sh old mode 100755 new mode 100644 diff --git a/src/config.rs b/src/config.rs index 89b4040..fed9f85 100644 --- a/src/config.rs +++ b/src/config.rs @@ -35,6 +35,7 @@ pub(crate) fn read_config(config_path: PathBuf) -> Config { serde_yaml::from_str(&config_data).expect("Failed to parse configuration") } +#[cfg(test)] mod tests { use super::*; diff --git a/src/vault.rs b/src/vault.rs index 0c36aea..7926224 100644 --- a/src/vault.rs +++ b/src/vault.rs @@ -99,6 +99,7 @@ fn get_vault_client(config: &Config) -> VaultClient { vault_client } +#[cfg(test)] mod tests { use super::*; use crate::config::PostgresConfig; diff --git a/src/workflow.rs b/src/workflow.rs index 12505cc..7a6e431 100644 --- a/src/workflow.rs +++ b/src/workflow.rs @@ -1,7 +1,4 @@ -use std::fmt::format; - use log::{debug, trace}; -use vaultrs::auth::userpass::user::update_password; use crate::cli::RotateArgs; use crate::config::Config; @@ -90,9 +87,9 @@ fn update_passive_user_postgres_password( debug!("Successfully rotated PostgreSQL password of passive user"); } +#[cfg(test)] mod tests { use super::*; - use postgres::Client; #[test] fn switch_active_user_user1_active() { diff --git a/tests/common/mod.rs b/tests/common/mod.rs new file mode 100644 index 0000000..4416d50 --- /dev/null +++ b/tests/common/mod.rs @@ -0,0 +1,45 @@ +use std::fs::File; +use std::io::Write; + +use tempfile::tempdir; +use testcontainers::{ + core::{IntoContainerPort, WaitFor}, + Container, GenericImage, ImageExt, +}; +use testcontainers_modules::postgres::Postgres; +use testcontainers_modules::{postgres, testcontainers::runners::SyncRunner}; + +pub(crate) fn postgres_container() -> Container { + postgres::Postgres::default() + .with_env_var("POSTGRES_DB", "demo") + .with_env_var("POSTGRES_USER", "demo") + .with_env_var("POSTGRES_PASSWORD", "demo_password") + .start() + .expect("PostgreSQL database started") +} + +pub(crate) fn vault_container() -> Container { + GenericImage::new("hashicorp/vault", "1.17.1") + .with_exposed_port(8200.tcp()) + .with_wait_for(WaitFor::message_on_stdout( + "==> Vault server started! Log data will stream in below", + )) + .with_env_var("VAULT_DEV_ROOT_TOKEN_ID", "root-token") + .start() + .expect("Vault started") +} + +pub(crate) fn write_string_to_tempfile(content: &str) -> String { + let temp_dir = tempdir().expect("Failed to get tmp dir"); + let filename = format!("temp_file_{}", rand::random::()); + + let mut filepath = temp_dir.path().to_path_buf(); + filepath.push(filename); + + let mut file = File::create(&filepath).expect("Failed to create tmp file"); + + file.write_all(content.as_bytes()) + .expect("Failed to write into tmp file"); + + filepath.to_string_lossy().to_string() +} diff --git a/tests/init_vault.rs b/tests/init_vault.rs index aa73b1e..c1a8e7d 100644 --- a/tests/init_vault.rs +++ b/tests/init_vault.rs @@ -9,16 +9,37 @@ use reqwest::{Client, Response}; use serde_json::Value; use tokio::runtime::{Builder, Runtime}; +mod common; + lazy_static! { static ref BIN_PATH: PathBuf = cargo_bin(env!("CARGO_PKG_NAME")); } #[test] fn init_vault_new_path() { + let vault_container = common::vault_container(); + + let host_ip = vault_container.get_host().unwrap(); + let host_port = vault_container.get_host_port_ipv4(8200).unwrap(); + Command::new(&*BIN_PATH) .arg("init-vault") .arg("-c") - .arg("tests/resources/init_vault/new_path.yml") + // language=yaml + .arg(common::write_string_to_tempfile( + format!( + " +postgres: + host: 'localhost' + port: 5432 + database: 'demo' +vault: + address: 'http://{host_ip}:{host_port}' + path: 'init/vault/new/path' +" + ) + .as_str(), + )) .env("VAULT_TOKEN", "root-token") .assert() .success() @@ -27,10 +48,10 @@ fn init_vault_new_path() { )); let client = Client::new(); - let url = "http://localhost:8200/v1/secret/data/init/vault/new/path"; + let url = format!("http://{host_ip}:{host_port}/v1/secret/data/init/vault/new/path"); let rt: Runtime = create_tokio_runtime(); - let json = read_secret_as_json(client, url, rt); + let json = read_secret_as_json(client, url.as_str(), rt); assert_json_value_equals(&json, "postgresql_active_user", "TBD"); assert_json_value_equals(&json, "postgresql_active_user_password", "TBD"); @@ -42,6 +63,8 @@ fn init_vault_new_path() { #[test] fn init_vault_invalid_url() { + common::vault_container(); + Command::new(&*BIN_PATH) .arg("init-vault") .arg("-c") diff --git a/tests/rotate.rs b/tests/rotate.rs index cac04eb..0e10719 100644 --- a/tests/rotate.rs +++ b/tests/rotate.rs @@ -11,6 +11,8 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use tokio::runtime::{Builder, Runtime}; +mod common; + lazy_static! { static ref BIN_PATH: PathBuf = cargo_bin(env!("CARGO_PKG_NAME")); } @@ -32,6 +34,9 @@ struct VaultSecretDTO { #[test] fn rotate_secrets() { + common::vault_container(); + common::postgres_container(); + let http_client = Client::new(); let url = "http://localhost:8200/v1/secret/data/rotate/secrets"; @@ -103,6 +108,9 @@ fn rotate_secrets() { #[test] fn rotate_invalid_initialized_secret() { + common::vault_container(); + common::postgres_container(); + let http_client = Client::new(); let url = "http://localhost:8200/v1/secret/data/rotate/invalid/initialized/secret"; @@ -123,6 +131,9 @@ fn rotate_invalid_initialized_secret() { #[test] fn rotate_non_existing_secret() { + common::vault_container(); + common::postgres_container(); + Command::new(&*BIN_PATH) .arg("rotate") .arg("-c")