Skip to content

Commit 4404e8a

Browse files
committed
chore: copy argocd sync resources from openapi generated
1 parent cd711ce commit 4404e8a

15 files changed

+112
-28
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,3 @@ dist
224224

225225
# OpenAPI generator
226226
openapitools.json
227-
src/argo-cd

Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@ lazy_static = "1.5.0"
1010
log = "0.4.22"
1111
postgres = "0.19.7"
1212
rand = "0.9.0-alpha.1"
13+
reqwest = { version = "0.12.5", features = ["json"] }
1314
serde = { version = "1.0.203", features = ["derive"] }
15+
serde_json = "1.0.120"
1416
serde_yaml = "0.9.34+deprecated"
1517
tokio = { version = "1.38.0", features = ["macros", "rt"] }
1618
vaultrs = "0.7.2"
19+
url = "2.5.2"
1720

1821
[dev-dependencies]
1922
assert_cmd = "2.0.14"
2023
predicates = "3.1.0"
21-
reqwest = { version = "0.12.5", features = ["json"] }
2224
serde_json = "1.0.120"
2325
testcontainers = { version = "0.20.0", features = ["blocking"] }
2426
testcontainers-modules = { version = "0.8.0", features = ["blocking", "hashicorp_vault", "k3s", "postgres"] }

DEVELOPMENT.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,17 @@ npm ci --cache .npm
5454

5555
6. Generate ArgoCD client sources:
5656

57-
```shell
57+
This last step is only needed if either:
58+
59+
- Argo-CD was upgraded or
60+
- You want to check the copied sources contained in [`src/argocd`](./src/argocd)
5861

62+
```shell
63+
npm run openapi:generate:argocd
5964
```
6065

66+
Note that the output of the generator is available in [`target/argo-cd`](target/argo-cd).
67+
6168
## Environment Setup
6269

6370
`propeller` requires the following components for development:

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,15 @@ If you don't provide the argument, the tool will default to `config.yml` in the
5757
The configuration file is in YAML format and has the following structure:
5858

5959
```yaml
60+
argo_cd:
61+
application: 'sut'
62+
base_url: 'http://localhost'
6063
postgres:
6164
host: 'localhost' # Replace with your database host
6265
port: 5432 # Replace with your database port
6366
database: 'demo' # Replace with your database
6467
vault:
65-
address: 'http://localhost:8200' # Replace with your Vault address
68+
base_url: 'http://localhost:8200' # Replace with your Vault address
6669
path: 'path/to/my/secret' # Replace with the desired path in Vault
6770
```
6871

dev/config.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
argo_cd:
2+
application: 'sut'
3+
base_url: 'http://localhost'
14
postgres:
25
host: 'localhost'
36
port: 5432
47
database: 'demo'
58
vault:
6-
address: 'http://localhost:8200'
9+
base_url: 'http://localhost:8200'
710
path: 'path/to/my/secret'

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"license": "Apache-2.0",
1515
"author": "PostFinance AG",
1616
"scripts": {
17-
"openapi:generate:argocd": "openapi-generator-cli generate -i argo-cd/assets/swagger.json -g rust -o src/argo-cd",
17+
"openapi:generate:argocd": "openapi-generator-cli generate -i argo-cd/assets/swagger.json -g rust -o target/argo-cd",
1818
"prepare": "husky",
1919
"prettier": "prettier \"{,.github/workflows/,dev/}*.{md,js,json,yml}\"",
2020
"prettier:check": "npm run prettier -- --check",

src/argo_cd.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use reqwest::Client;
2+
use tokio::runtime::{Builder, Runtime};
3+
4+
use crate::config::{ArgoConfig, Config};
5+
6+
pub(crate) struct ArgoCD {
7+
argo_config: ArgoConfig,
8+
client: Client,
9+
rt: Runtime,
10+
}
11+
12+
impl ArgoCD {
13+
pub(crate) fn init(config: &Config) -> ArgoCD {
14+
ArgoCD {
15+
argo_config: config.argo_cd.clone(),
16+
client: Client::new(),
17+
rt: Builder::new_current_thread()
18+
.enable_all()
19+
.build()
20+
.expect("Failed to build ArgoCD connection"),
21+
}
22+
}
23+
24+
pub(crate) fn sync(&mut self) {
25+
let local_var_uri_str = format!(
26+
"{}/api/v1/applications/{name}/sync",
27+
self.argo_config.base_url,
28+
name = urlencode(self.argo_config.application.as_str())
29+
);
30+
let mut local_var_req_builder = self
31+
.client
32+
.request(reqwest::Method::POST, local_var_uri_str.as_str());
33+
34+
local_var_req_builder = local_var_req_builder.json("&body"); // TODO
35+
36+
let local_var_req = local_var_req_builder
37+
.build()
38+
.expect("Failed to build ArgoCD sync request");
39+
let local_var_resp = self
40+
.rt
41+
.block_on(self.client.execute(local_var_req))
42+
.expect("Failed to sync ArgoCD");
43+
44+
let local_var_status = local_var_resp.status();
45+
let local_var_content = self
46+
.rt
47+
.block_on(local_var_resp.text())
48+
.unwrap_or_else(|_| panic!("Failed to sync ArgoCD"));
49+
50+
if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
51+
panic!("Failed to sync ArgoCD: {local_var_content}")
52+
}
53+
}
54+
}
55+
56+
pub fn urlencode<T: AsRef<str>>(s: T) -> String {
57+
::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect()
58+
}

src/config.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@ use std::{fs::File, io::Read, path::PathBuf};
44

55
#[derive(Deserialize, Debug)]
66
pub(crate) struct Config {
7+
pub(crate) argo_cd: ArgoConfig,
78
pub(crate) postgres: PostgresConfig,
89
pub(crate) vault: VaultConfig,
910
}
1011

12+
#[derive(Clone, Deserialize, Debug)]
13+
pub(crate) struct ArgoConfig {
14+
pub(crate) application: String,
15+
pub(crate) base_url: String,
16+
}
17+
1118
#[derive(Clone, Deserialize, Debug)]
1219
pub(crate) struct VaultConfig {
13-
pub(crate) address: String,
20+
pub(crate) base_url: String,
1421
pub(crate) path: String,
1522
}
1623

src/main.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use clap::Parser;
22
use env_logger::{Env, DEFAULT_WRITE_STYLE_ENV};
33

4-
use config::Config;
5-
4+
use crate::argo_cd::ArgoCD;
65
use crate::cli::{CliArgs, Command};
7-
use crate::config::read_config;
6+
use crate::config::{read_config, Config};
87
use crate::vault::Vault;
98
use crate::workflow::rotate_secrets_using_switch_method;
109

10+
mod argo_cd;
1111
mod cli;
1212
mod config;
1313
mod database;
@@ -28,8 +28,9 @@ fn main() {
2828
}
2929
Command::Rotate(rotate_args) => {
3030
let config: Config = read_config(rotate_args.base.config_path.clone());
31+
let mut argo_cd: ArgoCD = ArgoCD::init(&config);
3132
let mut vault: Vault = Vault::connect(&config);
32-
rotate_secrets_using_switch_method(&rotate_args, &config, &mut vault)
33+
rotate_secrets_using_switch_method(&rotate_args, &config, &mut argo_cd, &mut vault)
3334
}
3435
}
3536
}

src/vault.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn get_vault_client(config: &Config) -> VaultClient {
8989

9090
let vault_client: VaultClient = VaultClient::new(
9191
VaultClientSettingsBuilder::default()
92-
.address(config.vault.address.clone())
92+
.address(config.vault.base_url.clone())
9393
.token(vault_token)
9494
.build()
9595
.unwrap(),
@@ -110,15 +110,15 @@ mod tests {
110110
let config = Config {
111111
postgres: mock_postgres_config(),
112112
vault: VaultConfig {
113-
address: "http://localhost:8200".to_string(),
113+
base_url: "http://localhost:8200".to_string(),
114114
path: "path/to/my/secret".to_string(),
115115
},
116116
};
117117
env::set_var(VAULT_TOKEN, "test_token"); // Mock environment variable
118118

119119
let vault = Vault::connect(&config);
120120

121-
assert_eq!(vault.vault_config.address, config.vault.address);
121+
assert_eq!(vault.vault_config.base_url, config.vault.base_url);
122122
assert_eq!(vault.vault_config.path, config.vault.path);
123123
}
124124

@@ -128,7 +128,7 @@ mod tests {
128128
let config = Config {
129129
postgres: mock_postgres_config(),
130130
vault: VaultConfig {
131-
address: "http://localhost:8200".to_string(),
131+
base_url: "http://localhost:8200".to_string(),
132132
path: "path/to/my/secret".to_string(),
133133
},
134134
};
@@ -142,7 +142,7 @@ mod tests {
142142
let config = Config {
143143
postgres: mock_postgres_config(),
144144
vault: VaultConfig {
145-
address: "http://localhost:8200".to_string(),
145+
base_url: "http://localhost:8200".to_string(),
146146
path: "path/to/my/secret".to_string(),
147147
},
148148
};
@@ -152,7 +152,7 @@ mod tests {
152152

153153
assert_eq!(
154154
vault_client.settings().address.to_string(),
155-
config.vault.address + "/"
155+
config.vault.base_url + "/"
156156
);
157157
}
158158

src/workflow.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use log::{debug, trace};
22

3+
use crate::argo_cd::ArgoCD;
34
use crate::cli::RotateArgs;
45
use crate::config::Config;
56
use crate::database::PostgresClient;
@@ -9,16 +10,19 @@ use crate::vault::{Vault, VaultStructure};
910
pub(crate) fn rotate_secrets_using_switch_method(
1011
rotate_args: &RotateArgs,
1112
config: &Config,
13+
argo_cd: &mut ArgoCD,
1214
vault: &mut Vault,
1315
) {
1416
let db: PostgresClient = PostgresClient::init(config);
1517

1618
debug!("Starting 'switch' workflow");
1719

18-
let vault_path = config.vault.clone().path;
19-
let mut secret: VaultStructure = vault
20-
.read_secret()
21-
.unwrap_or_else(|_| panic!("Failed to read path '{vault_path}' - did you init Vault?"));
20+
let mut secret: VaultStructure = vault.read_secret().unwrap_or_else(|_| {
21+
panic!(
22+
"Failed to read path '{}' - did you init Vault?",
23+
config.vault.clone().path
24+
)
25+
});
2226

2327
if secret.postgresql_active_user != secret.postgresql_user_1
2428
&& secret.postgresql_active_user != secret.postgresql_user_2
@@ -37,7 +41,7 @@ pub(crate) fn rotate_secrets_using_switch_method(
3741

3842
debug!("Active and passive users switched and synchronized into Vault");
3943

40-
// TODO: Trigger ArgoCD Sync
44+
argo_cd.sync();
4145

4246
let new_password: String = generate_random_password(rotate_args.password_length);
4347

tests/init_vault.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ postgres:
3434
port: 5432
3535
database: 'demo'
3636
vault:
37-
address: 'http://{vault_host}:{vault_port}'
37+
base_url: 'http://{vault_host}:{vault_port}'
3838
path: 'init/vault/new/path'
3939
"
4040
)
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
vault:
2-
address: 'http://localhost:1234'
2+
base_url: 'http://localhost:1234'
33
path: 'config/missing/postgresql'

tests/resources/init_vault/invalid_url.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ postgres:
33
port: 5432
44
database: 'demo'
55
vault:
6-
address: 'http://localhost:1234'
6+
base_url: 'http://localhost:1234'
77
path: 'init/vault/invalid/url'

tests/rotate.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ postgres:
7777
port: {postgres_port}
7878
database: 'demo'
7979
vault:
80-
address: 'http://{vault_host}:{vault_port}'
80+
base_url: 'http://{vault_host}:{vault_port}'
8181
path: 'rotate/secrets'
8282
"
8383
)
@@ -176,7 +176,7 @@ postgres:
176176
port: {postgres_port}
177177
database: 'demo'
178178
vault:
179-
address: 'http://{vault_host}:{vault_port}'
179+
base_url: 'http://{vault_host}:{vault_port}'
180180
path: 'rotate/invalid/initialized/secret'
181181
"
182182
)
@@ -217,7 +217,7 @@ postgres:
217217
port: {postgres_port}
218218
database: 'demo'
219219
vault:
220-
address: 'http://{vault_host}:{vault_port}'
220+
base_url: 'http://{vault_host}:{vault_port}'
221221
path: 'rotate/non/existing/path'
222222
"
223223
)

0 commit comments

Comments
 (0)