Skip to content

Changes to make damctf work #52

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

Closed
wants to merge 13 commits into from
Closed
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
2 changes: 1 addition & 1 deletion src/access_handlers/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use minijinja;
use tokio;
use tracing::{debug, error, info, trace, warn};

use crate::clients::{docker, render_strict};
use crate::configparser::{get_config, get_profile_config};
use crate::{clients::docker, utils::render_strict};

/// container registry / daemon access checks
#[tokio::main(flavor = "current_thread")] // make this a sync function
Expand Down
8 changes: 8 additions & 0 deletions src/asset_files/challenge_templates/http.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ metadata:
namespace: "rcds-{{ slug }}"
annotations:
app.kubernetes.io/managed-by: rcds
cert-manager.io/cluster-issuer: letsencrypt
spec:
ingressClassName: beavercds
rules:
Expand All @@ -39,3 +40,10 @@ spec:
port:
number: {{ p.internal }}
{% endfor -%}

tls:
- hosts:
{%- for p in http_ports %}
- "{{ p.expose.http }}.{{ domain }}"
{% endfor -%}
secretName: "rcds-tls-{{ slug }}-{{ pod.name }}"
8 changes: 8 additions & 0 deletions src/asset_files/challenge_templates/tcp.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ metadata:
# still use separate domain for these, since exposed LoadBalancer services
# will all have different ips from each other
external-dns.alpha.kubernetes.io/hostname: "{{ slug }}.{{ domain }}"

# aws-specific annotations for lb options
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rules: "true"

spec:
type: LoadBalancer
selector:
Expand Down
11 changes: 6 additions & 5 deletions src/asset_files/setup_manifests/external-dns.helm.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
rbac:
create: true

{{ provider_credentials }}

# Watch these resources for new DNS records
sources:
- service
Expand All @@ -20,10 +18,10 @@ txtOwnerId: "k8s-external-dns"
txtPrefix: "k8s-owner."

extraArgs:
# ignore any services with internal ips
#exclude-target-net: "10.0.0.0/8"
# special character replacement
txt-wildcard-replacement: star
- --txt-wildcard-replacement=star
# use CNAME instead of ALIAS for alb targets
- --aws-prefer-cname

## Limit external-dns resources
resources:
Expand All @@ -34,3 +32,6 @@ resources:
cpu: 10m

logLevel: debug

# assign last to override any previous values if required
{{ provider_credentials }}
9 changes: 9 additions & 0 deletions src/asset_files/setup_manifests/ingress-nginx.helm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ controller:
ingressClassResource:
name: beavercds

# set variety of annotations needed for the cloud providers

annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rules: "true"

# nginx values for tcp ports will be set separately in other values file
# this will make it easier for `deploy` to update those values without
# subsequent calls to `cluster-setup` overwriting changes.
10 changes: 5 additions & 5 deletions src/asset_files/setup_manifests/letsencrypt.issuers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory"
server: https://acme-v02.api.letsencrypt.org/directory
# TODO: use user email?
email: beavercds-prod@example.com
email: beavercds-prod@{{ chal_domain }}
privateKeySecretRef:
name: letsencrypt-secret
solvers:
- http01:
ingress:
class: nginx
ingressClassName: beavercds

---
apiVersion: cert-manager.io/v1
Expand All @@ -23,10 +23,10 @@ spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
# TODO: use user email?
email: beavercds-staging@example.com
email: beavercds-staging@{{ chal_domain }}
privateKeySecretRef:
name: letsencrypt-staging-secret
solvers:
- http01:
ingress:
class: nginx
ingressClassName: beavercds
16 changes: 0 additions & 16 deletions src/clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,19 +345,3 @@ pub async fn wait_for_status(client: &kube::Client, object: &DynamicObject) -> R

Ok(())
}

//
// Minijinja strict rendering with error
//

/// Similar to minijinja.render!(), but return Error if any undefined values.
pub fn render_strict(template: &str, context: minijinja::Value) -> Result<String> {
let mut strict_env = minijinja::Environment::new();
// error on any undefined template variables
strict_env.set_undefined_behavior(minijinja::UndefinedBehavior::Strict);

let r = strict_env
.render_str(template, context)
.context(format!("could not render template {:?}", template))?;
Ok(r)
}
47 changes: 34 additions & 13 deletions src/cluster_setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use tracing::{debug, error, info, trace, warn};

use crate::clients::{apply_manifest_yaml, kube_client};
use crate::configparser::{config, get_config, get_profile_config};
use crate::utils::render_strict;

// Deploy cluster resources needed for challenges to work.
//
Expand All @@ -40,7 +41,8 @@ pub async fn install_ingress(profile: &config::ProfileConfig) -> Result<()> {
install_helm_chart(
profile,
"ingress-nginx",
Some("https://kubernetes.github.io/ingress-nginx"),
"https://kubernetes.github.io/ingress-nginx",
None,
"ingress-nginx",
INGRESS_NAMESPACE,
VALUES,
Expand All @@ -57,7 +59,8 @@ pub async fn install_certmanager(profile: &config::ProfileConfig) -> Result<()>
install_helm_chart(
profile,
"cert-manager",
Some("https://charts.jetstack.io"),
"https://charts.jetstack.io",
None,
"cert-manager",
INGRESS_NAMESPACE,
VALUES,
Expand All @@ -67,9 +70,17 @@ pub async fn install_certmanager(profile: &config::ProfileConfig) -> Result<()>
let client = kube_client(profile).await?;

// letsencrypt and letsencrypt-staging
const ISSUERS_YAML: &str =
const ISSUERS_TEMPLATE: &str =
include_str!("../asset_files/setup_manifests/letsencrypt.issuers.yaml");
apply_manifest_yaml(&client, ISSUERS_YAML).await?;

let issuers_yaml = render_strict(
ISSUERS_TEMPLATE,
minijinja::context! {
chal_domain => profile.challenges_domain
},
)?;

apply_manifest_yaml(&client, &issuers_yaml).await?;

Ok(())
}
Expand All @@ -81,16 +92,20 @@ pub async fn install_extdns(profile: &config::ProfileConfig) -> Result<()> {
include_str!("../asset_files/setup_manifests/external-dns.helm.yaml.j2");

// add profile dns: field directly to chart values
let values = minijinja::render!(
let values = render_strict(
VALUES_TEMPLATE,
provider_credentials => serde_yml::to_string(&profile.dns)?,
chal_domain => profile.challenges_domain
);
minijinja::context! {
provider_credentials => serde_yml::to_string(&profile.dns)?,
chal_domain => profile.challenges_domain
},
)?;

trace!("deploying templated external-dns values:\n{}", values);

install_helm_chart(
profile,
"oci://registry-1.docker.io/bitnamicharts/external-dns",
"external-dns",
"https://kubernetes-sigs.github.io/external-dns",
None,
"external-dns",
INGRESS_NAMESPACE,
Expand All @@ -106,20 +121,26 @@ pub async fn install_extdns(profile: &config::ProfileConfig) -> Result<()> {
fn install_helm_chart(
profile: &config::ProfileConfig,
chart: &str,
repo: Option<&str>,
repo: &str,
version: Option<&str>,
release_name: &str,
namespace: &str,
values: &str,
) -> Result<()> {
// make sure `helm` is available to run
duct::cmd!("helm", "version")
.read()
.context("helm binary is not available")?;

// write values to tempfile
let mut temp_values = tempfile::Builder::new()
.prefix(release_name)
.suffix(".values.yaml")
.tempfile()?;
temp_values.write_all(values.as_bytes())?;

let repo_arg = match repo {
Some(r) => format!("--repo {r}"),
let version_arg = match version {
Some(v) => format!("--version {v}"),
None => "".to_string(),
};

Expand All @@ -134,7 +155,7 @@ fn install_helm_chart(
r#"
upgrade --install
{release_name}
{chart} {repo_arg}
{chart} --repo {repo} {version_arg}
--namespace {namespace} --create-namespace
--values {}
--wait --timeout 1m
Expand Down
14 changes: 6 additions & 8 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Result;
use itertools::Itertools;
use std::process::exit;
use tracing::{debug, error, info, trace, warn};
Expand All @@ -6,15 +7,12 @@ use crate::builder::build_challenges;
use crate::configparser::{get_config, get_profile_config};

#[tokio::main(flavor = "current_thread")] // make this a sync function
pub async fn run(profile_name: &str, push: &bool, extract: &bool) {
pub async fn run(profile_name: &str, push: &bool, extract: &bool) -> Result<()> {
info!("building images...");

let results = match build_challenges(profile_name, *push, *extract).await {
Ok(results) => results,
Err(e) => {
error!("{e:?}");
exit(1)
}
};
let results = build_challenges(profile_name, *push, *extract).await?;

info!("images built successfully!");

Ok(())
}
15 changes: 12 additions & 3 deletions src/commands/check_access.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
use anyhow::{Context, Error, Result};
use anyhow::{bail, Context, Error, Result};
use itertools::Itertools;
use std::process::exit;
use tracing::{debug, error, info, trace, warn};

use crate::access_handlers as access;
use crate::configparser::{get_config, get_profile_config};

pub fn run(profile: &str, kubernetes: &bool, frontend: &bool, registry: &bool, bucket: &bool) {
pub fn run(
profile: &str,
kubernetes: &bool,
frontend: &bool,
registry: &bool,
bucket: &bool,
) -> Result<()> {
// if user did not give a specific check, check all of them
let check_all = !kubernetes && !frontend && !registry && !bucket;

Expand Down Expand Up @@ -36,6 +42,7 @@ pub fn run(profile: &str, kubernetes: &bool, frontend: &bool, registry: &bool, b
debug!("access results: {results:?}");

// die if there were any errors
// TODO: figure out how to return this error directly
let mut should_exit = false;
for (profile, result) in results.iter() {
match result {
Expand All @@ -48,8 +55,10 @@ pub fn run(profile: &str, kubernetes: &bool, frontend: &bool, registry: &bool, b
}
}
if should_exit {
exit(1);
bail!("config validation failed");
}

Ok(())
}

/// checks a single profile (`profile`) for the given accesses
Expand Down
21 changes: 7 additions & 14 deletions src/commands/cluster_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,15 @@ use crate::cluster_setup as setup;
use crate::configparser::{get_config, get_profile_config};

#[tokio::main(flavor = "current_thread")] // make this a sync function
pub async fn run(profile_name: &str) {
pub async fn run(profile_name: &str) -> Result<()> {
info!("setting up cluster...");
let config = get_profile_config(profile_name).unwrap();

if let Err(e) = setup::install_ingress(config).await {
error!("{e:?}");
exit(1);
}
if let Err(e) = setup::install_certmanager(config).await {
error!("{e:?}");
exit(1);
}
if let Err(e) = setup::install_extdns(config).await {
error!("{e:?}");
exit(1);
}
setup::install_ingress(config).await?;
setup::install_certmanager(config).await?;
setup::install_extdns(config).await?;

info!("charts deployed!")
info!("charts deployed!");

Ok(())
}
Loading