Skip to content
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

Update rust deps and use openssl 3 #1

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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,572 changes: 1,155 additions & 1,417 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ authors = ["SachinMaharana <[email protected]>"]
edition = "2018"

[dependencies]
kube = { git = "https://github.com/clux/kube-rs", rev = "9ce641324494fe6517e4114ba831793f48eed5a0", default-features = false, features = ["admission", "rustls-tls"] }
# kube = { path = "../kube-rs/kube", default-features = false, features = ["admission", "rustls-tls"] }
kube = { version = "0.88.1", features = ["admission", "rustls-tls"] }
k8s-openapi = { version = "0.21.0", features = ["latest"] }
actix-rt = "2.1.0"
actix-web = { version = "3", features = ["rustls"] }
actix-web = { version = "4", features = ["rustls-0_21"] }
anyhow = "1.0.40"
rustls = "0.18"
k8s-openapi = { version = "0.11.0", default-features = false, features = ["v1_20"] }
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.64"
forgiving-semver = "0.11.0"
Expand All @@ -24,6 +22,8 @@ log = "0.4.0"
env_logger = "0.8.3"
envy = "0.4.2"
futures = "0.3.14"
rustls = "0.21"
rustls-pemfile = "1"

[dependencies.serde_with]
version = "1.8.0"
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rust:1.48 as builder
FROM rust:1.74 as builder
RUN USER=root cargo new --bin image-tag-constraint-controller

WORKDIR /image-tag-constraint-controller
Expand All @@ -15,14 +15,14 @@ RUN cargo chef prepare --recipe-path recipe.json
# RUN cargo clean
# RUN cargo build --release

FROM rust:1.48 as cacher
FROM rust:1.74 as cacher
WORKDIR /image-tag-constraint-controller
RUN cargo install cargo-chef
COPY --from=builder /image-tag-constraint-controller/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json


FROM rust:1.48 as planner
FROM rust:1.74 as planner
WORKDIR /image-tag-constraint-controller
COPY . .
# Copy over the cached dependencies
Expand Down
18 changes: 12 additions & 6 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ binary := "basic-validation-controller"
default_namespace := "default"

cluster-up:
kind create cluster --name {{cluster_name}} --image kindest/node:v1.19.1 --config ./kind-config.yaml
kind create cluster --name {{cluster_name}} --image kindest/node:v1.27.3 --config ./kind-config.yaml
Copy link
Owner

@SachinMaharana SachinMaharana Feb 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can make kindest/node image version as variable, similar to other places in this MR!

sleep "10"
kubectl wait --namespace kube-system --for=condition=ready pod --selector="tier=control-plane" --timeout=180s

certs:
./gencert.sh --service basic-validation-controller --secret webhook-tls-certs --namespace default
./gencert.sh --service basic-validation-controller --secret webhook-tls-certs --namespace {{default_namespace}}

ca default=default_namespace:
#!/bin/bash
CA_BUNDLE=$(kubectl get secrets -n {{default}} webhook-tls-certs -ojson | jq '.data."caCert.pem"')
export CA_BUNDLE=${CA_BUNDLE}
export NAMESPACE={{default}}
cat deploy/webhook.yaml | envsubst > deploy/webhook-ca.yaml
kubectl apply -f deploy/webhook-ca.yaml

Expand All @@ -32,12 +33,17 @@ build-go:
load:
kind --name {{cluster_name}} load docker-image {{docker_user}}/{{binary}}:latest

deploy:
kubectl apply -f deploy/deployment.yaml
kubectl rollout status deployment/{{binary}}
deploy:
#!/bin/bash
export NAMESPACE={{default_namespace}}
export IMAGE={{docker_user}}/{{binary}}
cat deploy/deployment.yaml | envsubst | kubectl apply -f -
kubectl rollout status --namesepace {{default_namespace}} deployment/{{binary}}

debug:
kubectl apply -f deploy/debug.yaml
#!/bin/bash
export NAMESPACE={{default_namespace}}
cat deploy/debug.yaml | envsubst | kubectl apply -f -

cluster-down:
kind delete cluster --name {{cluster_name}}
Expand Down
3 changes: 2 additions & 1 deletion deploy/debug.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: debug
namespace: $NAMESPACE
spec:
selector:
matchLabels:
Expand All @@ -25,7 +26,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: another
namespace: kube-system
namespace: $NAMESPACE
spec:
selector:
matchLabels:
Expand Down
4 changes: 3 additions & 1 deletion deploy/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: basic-validation-controller
namespace: $NAMESPACE
spec:
selector:
matchLabels:
Expand All @@ -18,7 +19,7 @@ spec:

containers:
- name: basic-validation-controller
image: sachinnicky/basic-validation-controller
image: $IMAGE
imagePullPolicy: IfNotPresent
env:
- name: WHITELISTED_REGISTRIES
Expand All @@ -37,6 +38,7 @@ apiVersion: v1
kind: Service
metadata:
name: basic-validation-controller
namespace: $NAMESPACE
spec:
selector:
app: basic-validation-controller
Expand Down
2 changes: 1 addition & 1 deletion deploy/webhook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ webhooks:
caBundle: ${CA_BUNDLE}
service:
name: basic-validation-controller
namespace: default
namespace: ${NAMESPACE}
port: 443
path: "/mutate"
failurePolicy: Ignore
Expand Down
5 changes: 3 additions & 2 deletions gencert.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# reference:
# https://github.com/kubernetes/kubernetes/blob/master/plugin/pkg/admission/webhook/gencerts.sh
set -o errexit
set -x


CN_BASE="basic-validation-controller"
Expand Down Expand Up @@ -72,7 +73,7 @@ set -o errexit
# Create a server certiticate
openssl genrsa -out ${TMP_DIR}/serverKey.pem 2048
# Note the CN is the DNS name of the service of the webhook.
openssl req -new -key ${TMP_DIR}/serverKey.pem -out ${TMP_DIR}/server.csr -subj "/CN=${basic-validation-controller}.${namespace}.svc" -config ${TMP_DIR}/server.conf -addext "subjectAltName = DNS:${service}.${namespace}.svc"
openssl req -new -key ${TMP_DIR}/serverKey.pem -out ${TMP_DIR}/server.csr -subj "/CN=${basic-validation-controller}.${namespace}.svc" -config ${TMP_DIR}/server.conf

openssl x509 -req -in ${TMP_DIR}/server.csr -CA ${TMP_DIR}/caCert.pem -CAkey ${TMP_DIR}/caKey.pem -CAcreateserial -out ${TMP_DIR}/serverCert.pem -days 100000 -extensions SAN -extensions v3_req -extfile ${TMP_DIR}/server.conf

Expand All @@ -81,4 +82,4 @@ kubectl create secret --namespace=${namespace} generic ${SECRET_NAME} --from-fil

# Clean up after we're done.
echo "Deleting ${TMP_DIR}."
# rm -rf ${TMP_DIR}
# rm -rf ${TMP_DIR}
2 changes: 0 additions & 2 deletions kind-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,3 @@ kubeadmConfigPatches:
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
55 changes: 35 additions & 20 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use actix_web::http::header::ContentType;
use actix_web::{get, http, post, web, App, HttpRequest, HttpResponse, HttpServer, Responder};
use anyhow::anyhow;
use anyhow::Result;
use k8s_openapi::apimachinery::pkg::apis::meta::v1::Status;
use kube::api::{
admission::{AdmissionRequest, AdmissionResponse, AdmissionReview},
DynamicObject,
};
use rustls::internal::pemfile::{certs, rsa_private_keys};
use rustls::{NoClientAuth, ServerConfig};
use kube::api::DynamicObject;
use kube::core::admission::{AdmissionRequest, AdmissionResponse, AdmissionReview};
use kube::core::Status;
use rustls::{Certificate, PrivateKey, ServerConfig};
use rustls_pemfile::{certs, pkcs8_private_keys };
use serde::Deserialize;
use serde_json::{json, Value};
use serde_with::CommaSeparator;
Expand All @@ -26,7 +25,7 @@ struct Environment {
#[get("/health")]
async fn health() -> impl Responder {
HttpResponse::Ok()
.header(http::header::CONTENT_TYPE, "application/json")
.content_type(ContentType::json())
.json(json!({"message": "ok"}))
}

Expand Down Expand Up @@ -116,24 +115,27 @@ async fn handle_mutate(
);
resp.allowed = false;
resp.result = Status {
message: Some(format!(
message: format!(
"{} image comes from an untrusted registry! only images from {:?} are allowed",
image_name, whitelisted_registries
)),
),
..Default::default()
};
break;
}
}
return HttpResponse::Ok().json(resp.into_review());
HttpResponse::Ok().json(resp.into_review())
}

fn get_image_name(container: &Value) -> Option<&str> {
container.get("image").and_then(|image_name| image_name.as_str())
container
.get("image")
.and_then(|image_name| image_name.as_str())
}

fn get_containers(pod: &Value) -> Option<&Vec<Value>> {
pod.get("containers").and_then(|container| container.as_array())
pod.get("containers")
.and_then(|container| container.as_array())
}

#[actix_web::main]
Expand All @@ -147,15 +149,28 @@ async fn main() -> Result<(), anyhow::Error> {
tracing_subscriber::fmt().with_env_filter(filter).init();

info!("Started http server: 0.0.0.0:8443");
let mut config = ServerConfig::new(NoClientAuth::new());
let cert_file = &mut BufReader::new(File::open("./certs/serverCert.pem")?);
let key_file = &mut BufReader::new(File::open("./certs/serverKey.pem")?);
let cert_chain = certs(cert_file).expect("error in cert");
let mut keys = rsa_private_keys(key_file).expect("error in key");
config.set_single_cert(cert_chain, keys.remove(0))?;
let cert_file = &mut BufReader::new(File::open("/certs/serverCert.pem")?);
let key_file = &mut BufReader::new(File::open("/certs/serverKey.pem")?);

// convert files to key/cert objects
let cert_chain = certs(cert_file)
.unwrap()
.into_iter()
.map(Certificate)
.collect();
let mut keys: Vec<PrivateKey> = pkcs8_private_keys(key_file)
.unwrap()
.into_iter()
.map(PrivateKey)
.collect();
let config = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(cert_chain, keys.remove(0))
.expect("error in config");

HttpServer::new(|| App::new().service(handle_mutate).service(health))
.bind_rustls("0.0.0.0:8443", config)?
.bind_rustls_021("0.0.0.0:8443", config)?
.run()
.await?;
Ok(())
Expand Down