From 8bf4956741844676b45c70789dfdb16601eb21c1 Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Sat, 21 Oct 2023 23:40:49 +0200 Subject: [PATCH] Fixes #23627: Add configuration file parser to rudder-package --- relay/sources/Makefile | 15 +- relay/sources/rudder-package/Cargo.lock | 24 +++ relay/sources/rudder-package/Cargo.toml | 1 + .../sources/rudder-package/src/rpkg/config.rs | 155 ++++++++++++++++++ relay/sources/rudder-package/src/rpkg/mod.rs | 4 +- .../rudder-package/tests/rudder-pkg.conf | 7 + .../tests/rudder-pkg.proxy.conf | 7 + 7 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 relay/sources/rudder-package/src/rpkg/config.rs create mode 100644 relay/sources/rudder-package/tests/rudder-pkg.conf create mode 100644 relay/sources/rudder-package/tests/rudder-pkg.proxy.conf diff --git a/relay/sources/Makefile b/relay/sources/Makefile index e0858962a4a..da79fc73b83 100644 --- a/relay/sources/Makefile +++ b/relay/sources/Makefile @@ -48,14 +48,21 @@ target/man/rudder-relayd.1.gz: CACHE=cache() { [ -x ../../../../../build-caching ] && ../../../../../build-caching "$$@"; [ -x ../../../../../../build-caching ] && ../../../../../../build-caching "$$@" ; } ; cache build: man rudder-pkg/rudder_plugins_key.pub autocomplete/rudder-pkg.sh - # Build relayd - mkdir -p ../../../../../.cargo/ relayd/target/ + # Build rust binaries + mkdir -p ../../../../../.cargo/ relayd/target/ rudder-package/target/ $(CACHE) get ../../../../../.cargo/ name=cargo major=$(RUDDER_MAJOR_VERSION) || true + ### relayd $(CACHE) get relayd/target/ --with-env name=relayd major=$(RUDDER_MAJOR_VERSION) || true cd relayd && make build # the cache is always updated and cargo will rebuild only what is needed - $(CACHE) put ../../../../../.cargo/ name=cargo major=$(RUDDER_MAJOR_VERSION) || true $(CACHE) put relayd/target/ --with-env name=relayd major=$(RUDDER_MAJOR_VERSION) || true + ### rudder-package + $(CACHE) get rudder-package/target/ --with-env name=rudder-package major=$(RUDDER_MAJOR_VERSION) || true + cd rudder-package && make build + # the cache is always updated and cargo will rebuild only what is needed + $(CACHE) put rudder-package/target/ --with-env name=rudder-package major=$(RUDDER_MAJOR_VERSION) || true + ### common + $(CACHE) put ../../../../../.cargo/ name=cargo major=$(RUDDER_MAJOR_VERSION) || true ifeq ($(SELINUX),true) # Build SELinux policy package @@ -108,6 +115,8 @@ install: build # Install man pages install -m 644 target/man/rudder-relayd.1.gz $(DESTDIR)/opt/rudder/share/man/man1/ + # rudder-package binary + install -m 755 rudder-package/target/release/rudder-package $(DESTDIR)/opt/rudder/bin/rudder-package # rudder packaging install -m 755 rudder-pkg/rudder-pkg $(DESTDIR)/opt/rudder/share/commands/package ln -ns ../share/commands/package $(DESTDIR)/opt/rudder/bin/rudder-pkg diff --git a/relay/sources/rudder-package/Cargo.lock b/relay/sources/rudder-package/Cargo.lock index 3b93fa708ad..2cfead5cbc0 100644 --- a/relay/sources/rudder-package/Cargo.lock +++ b/relay/sources/rudder-package/Cargo.lock @@ -340,6 +340,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" +[[package]] +name = "result" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194d8e591e405d1eecf28819740abed6d719d1a2db87fc0bcdedee9a26d55560" + [[package]] name = "rstest" version = "0.18.2" @@ -381,6 +387,7 @@ dependencies = [ "pretty_assertions", "rstest", "serde", + "serde_ini", "serde_json", "serde_toml", "tar", @@ -451,6 +458,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_ini" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb236687e2bb073a7521c021949be944641e671b8505a94069ca37b656c81139" +dependencies = [ + "result", + "serde", + "void", +] + [[package]] name = "serde_json" version = "1.0.107" @@ -518,6 +536,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "walkdir" version = "2.4.0" diff --git a/relay/sources/rudder-package/Cargo.toml b/relay/sources/rudder-package/Cargo.toml index 8770f16eec1..d578bba763f 100644 --- a/relay/sources/rudder-package/Cargo.toml +++ b/relay/sources/rudder-package/Cargo.toml @@ -18,6 +18,7 @@ lzma-rs = "0.3.0" pretty_assertions = "1.4.0" rstest = "0.18.2" serde = { version = "1.0.189", features = ["derive"] } +serde_ini = "0.2.0" serde_json = "1.0.107" serde_toml = "0.0.1" tar = "0.4.40" diff --git a/relay/sources/rudder-package/src/rpkg/config.rs b/relay/sources/rudder-package/src/rpkg/config.rs new file mode 100644 index 00000000000..2d1b609a037 --- /dev/null +++ b/relay/sources/rudder-package/src/rpkg/config.rs @@ -0,0 +1,155 @@ +use std::{fs::read_to_string, path::Path}; + +use anyhow::Result; +use serde::{Deserialize, Serialize}; + +const PUBLIC_REPO_URL: &str = "https://repository.rudder.io/plugins"; +const PRIVATE_REPO_URL: &str = "https://download.rudder.io/plugins"; + +/// Wrapper as the default config has a "Rudder" section +#[derive(Deserialize, Debug, PartialEq, Eq)] +#[serde(rename_all = "PascalCase")] +struct RawConfiguration { + #[serde(default)] + rudder: RudderSection, +} + +// Note, "key = " lines produce Some("") when using Option +// So let's use String everywhere and clean afterwards. +#[derive(Deserialize, Debug, PartialEq, Eq, Default)] +struct RudderSection { + #[serde(default)] + url: String, + #[serde(default)] + username: String, + #[serde(default)] + password: String, + #[serde(default)] + proxy_url: String, + #[serde(default)] + proxy_user: String, + #[serde(default)] + proxy_password: String, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +pub struct Credentials { + username: String, + password: String, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +pub struct Configuration { + url: String, + credentials: Option, + proxy: Option, +} + +impl Configuration { + fn parse(src: &str) -> Result { + let parsed: RawConfiguration = serde_ini::from_str(src)?; + Ok(Configuration::from(parsed)) + } + + pub fn read(path: &Path) -> Result { + let c = read_to_string(path)?; + Self::parse(&c) + } +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +pub struct ProxyConfiguration { + url: String, + credentials: Option, +} + +impl From for Configuration { + fn from(raw: RawConfiguration) -> Self { + let r = raw.rudder; + let credentials = match (r.username.is_empty(), r.password.is_empty()) { + (false, false) => Some(Credentials { + username: r.username, + password: r.password, + }), + _ => None, + }; + let proxy_credentials = match (r.proxy_user.is_empty(), r.proxy_password.is_empty()) { + (false, false) => Some(Credentials { + username: r.proxy_user, + password: r.proxy_password, + }), + _ => None, + }; + let proxy = match (r.proxy_url.is_empty(), proxy_credentials) { + (false, credentials) => Some(ProxyConfiguration { + url: r.proxy_url, + credentials, + }), + _ => None, + }; + let url = if r.url.is_empty() { + if credentials.is_some() { + PRIVATE_REPO_URL.to_owned() + } else { + PUBLIC_REPO_URL.to_owned() + } + } else { + r.url + }; + Self { + url, + credentials, + proxy, + } + } +} + +#[cfg(test)] +mod tests { + use crate::rpkg::config::{Configuration, Credentials, ProxyConfiguration}; + use pretty_assertions::assert_eq; + use std::path::Path; + + #[test] + fn it_parses_default_config_file() { + let reference = Configuration { + url: "https://download.rudder.io/plugins".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + proxy: None, + }; + let conf = Configuration::read(Path::new("./tests/rudder-pkg.conf")).unwrap(); + assert_eq!(reference, conf); + } + #[test] + fn it_parses_empty_config_file() { + let reference = Configuration { + url: "https://repository.rudder.io/plugins".to_string(), + credentials: None, + proxy: None, + }; + let conf = Configuration::parse("").unwrap(); + assert_eq!(reference, conf); + } + #[test] + fn it_parses_full_config_file() { + let reference = Configuration { + url: "https://download2.rudder.io/plugins".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + proxy: Some(ProxyConfiguration { + url: "http://22.29.35.56".to_string(), + credentials: Some(Credentials { + username: "mario".to_string(), + password: "daisy".to_string(), + }), + }), + }; + let conf = Configuration::read(Path::new("./tests/rudder-pkg.proxy.conf")).unwrap(); + assert_eq!(reference, conf); + } +} diff --git a/relay/sources/rudder-package/src/rpkg/mod.rs b/relay/sources/rudder-package/src/rpkg/mod.rs index 68d60d9958d..e16ace840ad 100644 --- a/relay/sources/rudder-package/src/rpkg/mod.rs +++ b/relay/sources/rudder-package/src/rpkg/mod.rs @@ -1,10 +1,12 @@ pub mod database; pub use database::Database; pub mod archive; +pub mod config; pub mod plugin; pub mod repo_index; pub mod webapp_xml; -const PACKAGES_FOLDER: &str = "/var/rudder/packagesA"; +const PACKAGES_FOLDER: &str = "/var/rudder/packages"; const WEBAPP_XML_PATH: &str = "/opt/rudder/share/webapps/rudder.xml"; const PACKAGES_DATABASE_PATH: &str = "/var/rudder/packages/index.json"; +const CONFIG_PATH: &str = "/opt/rudder/etc/rudder-pkg/rudder-pkg.conf"; diff --git a/relay/sources/rudder-package/tests/rudder-pkg.conf b/relay/sources/rudder-package/tests/rudder-pkg.conf new file mode 100644 index 00000000000..1edabd1a3f7 --- /dev/null +++ b/relay/sources/rudder-package/tests/rudder-pkg.conf @@ -0,0 +1,7 @@ +[Rudder] +url = https://download.rudder.io/plugins +username = user +password = password +proxy_url = +proxy_user = +proxy_password = diff --git a/relay/sources/rudder-package/tests/rudder-pkg.proxy.conf b/relay/sources/rudder-package/tests/rudder-pkg.proxy.conf new file mode 100644 index 00000000000..fec8293796d --- /dev/null +++ b/relay/sources/rudder-package/tests/rudder-pkg.proxy.conf @@ -0,0 +1,7 @@ +[Rudder] +url = https://download2.rudder.io/plugins +username = user +password = password +proxy_url = http://22.29.35.56 +proxy_user = mario +proxy_password = daisy