Skip to content

Commit d0513ad

Browse files
committed
Add registry pull credentials to challenge namespaces
Pull secrets are namespace-scoped, so need to be present in all of our namespaces that use our images. Also update deployments to use these pull secrets. Signed-off-by: Robert Detjens <[email protected]>
1 parent bd3e348 commit d0513ad

File tree

7 files changed

+57
-5
lines changed

7 files changed

+57
-5
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ rust-s3 = { version = "0.35.1", default-features = false, features = [
3939
minijinja = { version = "2.6.0", features = ["json"] }
4040
duct = "0.13.7"
4141
fastrand = "2.3.0"
42+
base64ct = { version = "1.7.3", features = ["alloc"] }
4243

4344

4445
[dev-dependencies]

src/asset_files/challenge_templates/deployment.yaml.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ spec:
1919
labels:
2020
rctf/part-of: "{{ slug }}-{{ pod.name }}"
2121
spec:
22+
imagePullSecrets:
23+
- name: "rcds-{{ slug }}-pull"
2224
containers:
2325
- name: "{{ pod.name }}"
2426
image: "{{ pod_image }}"

src/asset_files/challenge_templates/namespace.yaml.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
apiVersion: v1
33
kind: Namespace
44
metadata:
5-
name: rcds-{{ slug }}
5+
name: "rcds-{{ slug }}"
66
annotations:
77
app.kubernetes.io/managed-by: rcds
88
rctf/challenge: "{{ chal.name }}"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v1
2+
kind: Secret
3+
type: kubernetes.io/dockerconfigjson
4+
metadata:
5+
name: "rcds-{{ slug }}-pull"
6+
namespace: "rcds-{{ slug }}"
7+
stringData:
8+
.dockerconfigjson: |
9+
{
10+
"auths": {
11+
"{{ registry_domain }}": {
12+
"auth": "{{ creds_b64 }}"
13+
}
14+
}
15+
}

src/deploy/kubernetes/mod.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use std::path::PathBuf;
22
use std::time::Duration;
33

44
use anyhow::{anyhow, bail, Context, Error, Ok, Result};
5+
use base64ct::{Base64, Encoding};
6+
use bollard::auth::DockerCredentials;
57
use itertools::Itertools;
68
use minijinja;
79
use tokio::time::timeout;
@@ -17,7 +19,7 @@ use crate::utils::{render_strict, TryJoinAll};
1719
pub mod templates;
1820

1921
/// How and where a challenge was deployed/exposed at
20-
pub struct DeployResult {
22+
pub struct KubeDeployResult {
2123
// challenges could have multiple exposed services
2224
pub exposed: Vec<PodDeployResult>,
2325
}
@@ -31,7 +33,7 @@ pub enum PodDeployResult {
3133
pub async fn deploy_challenges(
3234
profile_name: &str,
3335
build_results: &[(&ChallengeConfig, BuildResult)],
34-
) -> Result<Vec<DeployResult>> {
36+
) -> Result<Vec<KubeDeployResult>> {
3537
let profile = get_profile_config(profile_name)?;
3638

3739
// Kubernetes deployment needs to:
@@ -65,7 +67,7 @@ pub async fn deploy_challenges(
6567
async fn deploy_single_challenge(
6668
profile_name: &str,
6769
chal: &ChallengeConfig,
68-
) -> Result<DeployResult> {
70+
) -> Result<KubeDeployResult> {
6971
info!(" deploying chal {:?}...", chal.directory);
7072
// render templates
7173

@@ -90,7 +92,29 @@ async fn deploy_single_challenge(
9092
.try_join_all()
9193
.await?;
9294

93-
let results = DeployResult { exposed: vec![] };
95+
// add image pull credentials to the new namespace
96+
debug!(
97+
"applying namespace pull credentials for chal {:?}",
98+
chal.directory
99+
);
100+
101+
let registry = &get_config()?.registry;
102+
let creds_manifest = render_strict(
103+
templates::IMAGE_PULL_CREDS_SECRET,
104+
minijinja::context! {
105+
slug => chal.slugify(),
106+
registry_domain => registry.domain,
107+
creds_b64 => Base64::encode_string(format!("{}:{}",
108+
registry.cluster.user,
109+
registry.cluster.pass,
110+
).as_bytes()),
111+
},
112+
)?;
113+
apply_manifest_yaml(&kube, &creds_manifest).await?;
114+
115+
// namespace boilerplate over, deploy actual challenge pods
116+
117+
let results = KubeDeployResult { exposed: vec![] };
94118

95119
for pod in &chal.pods {
96120
let pod_image = chal.container_tag_for_pod(profile_name, &pod.name)?;

src/deploy/kubernetes/templates.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ pub static CHALLENGE_SERVICE_HTTP: &str =
1111

1212
pub static CHALLENGE_SERVICE_TCP: &str =
1313
include_str!("../../asset_files/challenge_templates/tcp.yaml.j2");
14+
15+
pub static IMAGE_PULL_CREDS_SECRET: &str =
16+
include_str!("../../asset_files/challenge_templates/pull-secret.yaml.j2");

0 commit comments

Comments
 (0)