Skip to content

Commit

Permalink
feat: add code ci (#3)
Browse files Browse the repository at this point in the history
* feat: add code ci

Signed-off-by: James Petersen <[email protected]>

* chore: fix cargo test

Signed-off-by: James Petersen <[email protected]>

* chore: fix test and check for existence of certs

Signed-off-by: James Petersen <[email protected]>

---------

Signed-off-by: James Petersen <[email protected]>
  • Loading branch information
found-it authored Dec 11, 2024
1 parent 972cdbe commit e06ae7a
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- main
paths:
- charts/**
- .github/workflows/helm-test.yaml
- .github/workflows/ci-chart.yaml

jobs:
lint-test:
Expand Down
165 changes: 165 additions & 0 deletions .github/workflows/ci-code.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
name: Lint and Test Code

on:
pull_request:
branches:
- main
paths:
- src/**
- .github/workflows/ci-code.yaml

jobs:
rustfmt:
name: rustfmt
runs-on: ubuntu-latest
steps:
- name: harden runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
egress-policy: audit

- name: checkout repository
uses: actions/checkout@6b42224f41ee5dfe5395e27c8b2746f1f9955030 # v4.2.0
with:
submodules: recursive
persist-credentials: false

- name: 'Install stable rust toolchain with rustfmt'
run: |
rustup update --no-self-update stable
rustup default stable
rustup component add rustfmt
- name: 'cargo fmt'
run: cargo fmt --all -- --check

shfmt:
name: shfmt
runs-on: ubuntu-latest
steps:
- name: harden runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
egress-policy: audit

- name: checkout repository
uses: actions/checkout@6b42224f41ee5dfe5395e27c8b2746f1f9955030 # v4.2.0
with:
submodules: recursive
persist-credentials: false

- name: shfmt
run: |
GOBIN=/usr/local/bin go install mvdan.cc/sh/v3/cmd/shfmt@latest
if ! ./hack/code/shfmt.sh; then
echo ""
echo "Please run \`PROTECT_SHFMT_WRITE=true ./hack/code/shfmt.sh\`"
fi
shellcheck:
name: shellcheck
runs-on: ubuntu-latest
steps:
- name: harden runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
egress-policy: audit

- name: checkout repository
uses: actions/checkout@6b42224f41ee5dfe5395e27c8b2746f1f9955030 # v4.2.0
with:
submodules: recursive
persist-credentials: false

- name: shellcheck
run: ./hack/code/shellcheck.sh

full-build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch:
- x86_64
env:
TARGET_ARCH: "${{ matrix.arch }}"
name: 'Full build linux-${{ matrix.arch }}'
steps:
- name: harden runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
egress-policy: audit

- name: checkout repository
uses: actions/checkout@6b42224f41ee5dfe5395e27c8b2746f1f9955030 # v4.2.0
with:
submodules: recursive
persist-credentials: false

- name: 'Install stable rust toolchain'
run: |
rustup update --no-self-update stable
rustup default stable
- name: cargo build
run: cargo build

full-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch:
- x86_64
env:
TARGET_ARCH: "${{ matrix.arch }}"
name: 'Full test linux-${{ matrix.arch }}'
steps:
- name: harden runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
egress-policy: audit

- name: checkout repository
uses: actions/checkout@6b42224f41ee5dfe5395e27c8b2746f1f9955030 # v4.2.0
with:
submodules: recursive
persist-credentials: false

- name: 'Install stable rust toolchain'
run: |
rustup update --no-self-update stable
rustup default stable
- name: 'cargo test'
run: cargo test

full-clippy:
runs-on: ubuntu-latest
strategy:
matrix:
arch:
- x86_64
env:
TARGET_ARCH: "${{ matrix.arch }}"
name: 'Full clippy linux-${{ matrix.arch }}'
steps:
- name: harden runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
egress-policy: audit

- name: checkout repository
uses: actions/checkout@6b42224f41ee5dfe5395e27c8b2746f1f9955030 # v4.2.0
with:
submodules: recursive
persist-credentials: false

- name: 'Install stable rust toolchain with clippy'
run: |
rustup update --no-self-update stable
rustup default stable
rustup component add clippy
- name: 'cargo clippy'
run: cargo clippy
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@ name: Release Artifacts
run-name: 'Release run by ${{ github.actor }}'

on:
# Release unstable from HEAD on every merge
push:
branches:
- main

# Run manually to release unstable from HEAD
workflow_dispatch:

# Official stable versioned release
release:
types:
Expand Down Expand Up @@ -124,22 +116,27 @@ jobs:
- name: Resolve parameters
id: resolve_parameters
run: |
resolved_ref="${{ github.ref }}"
echo "INFO: Resolving short SHA for $resolved_ref"
echo "short_sha=$(git rev-parse --short $resolved_ref)" >> $GITHUB_OUTPUT
echo "INFO: Resolving short SHA for ${GITHUB_REF}"
echo "short_sha=$(git rev-parse --short ${GITHUB_REF})" >> $GITHUB_OUTPUT
echo "INFO: Normalizing repository name (lowercase)"
echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
echo "repository_owner=$(echo ${GITHUB_REPOSITORY_OWNER} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
env:
GITHUB_REF: '${{ github.ref }}'
GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'

- name: Set up Helm
uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2

- name: Publish new helm chart for protect-webhook
run: |
echo ${{ secrets.GITHUB_TOKEN }} | helm registry login ghcr.io --username ${{ github.actor }} --password-stdin
echo ${{ secrets.GITHUB_TOKEN }} | helm registry login ghcr.io --username ${GITHUB_ACTOR} --password-stdin
PROTECT_WEBHOOK_CHART_VERSION_TAG=$(cat charts/protect-webhook/Chart.yaml | grep version: | cut -d " " -f 2)
echo "PROTECT_WEBHOOK_CHART_VERSION_TAG=${PROTECT_WEBHOOK_CHART_VERSION_TAG}" >> $GITHUB_ENV
helm package charts/protect-webhook/ --version="${PROTECT_WEBHOOK_CHART_VERSION_TAG}"
helm push protect-webhook-"${PROTECT_WEBHOOK_CHART_VERSION_TAG}".tgz oci://ghcr.io/${{ steps.resolve_parameters.outputs.repository_owner }}/charts
env:
GITHUB_ACTOR: '${{ github.actor }}'
GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'

- name: Job summary
run: |
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Edera Protect Runtime Class Injector

This repo contains a mutating webhook to inject the `edera` runtime class into a kubernetes manifest.
protect-webhook is a mutating webhook to inject the `edera` runtime class into a kubernetes manifest.

### Why would I want this?
### Uses

Edera Protect provides strong isolation for kubernetes workloads (see [edera.dev](https://edera.dev)
for more details). It does so by utilizing a runtime class name to specify whichworkloads should be
Expand All @@ -11,7 +11,7 @@ use of this webhook to inject it into the manifest upon creation. You also might
every manifest you've ever created. Instead you can just use this mutating webhook to set a runtime
class name for manifests without ever touching their yaml.

### Quickstart
### Installation

You can get started quickly by setting up self-signed certificates and then deploying the helm chart.
It deploys a mutating webhook which needs certs to communicate with the API Server. You can find an
Expand All @@ -24,3 +24,7 @@ helm upgrade --install mutate oci://ghcr.io/edera-dev/charts/protect-webhook \
--create-namespace \
--values ./examples/self-signed-certs/values.yaml
```

### Troubleshooting

If you're running into issues, please file an issue!
7 changes: 7 additions & 0 deletions hack/code/shellcheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
set -e

REAL_SCRIPT="$(realpath "${0}")"
cd "$(dirname "${REAL_SCRIPT}")/../.."

find hack -type f -name '*.sh' -print0 | xargs -0 shellcheck -x
22 changes: 22 additions & 0 deletions hack/code/shfmt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh
set -e

REAL_SCRIPT="$(realpath "${0}")"
cd "$(dirname "${REAL_SCRIPT}")/../.."

# Pulled from the flags resembling the google style guide here
# https://github.com/mvdan/sh/blob/master/cmd/shfmt/shfmt.1.scd#examples
FLAGS="--indent 2 --case-indent --binary-next-line --list"

if [ -z "${PROTECT_SHFMT_WRITE}" ]; then
echo "Running shfmt in diff mode..."
FLAGS="${FLAGS} --diff"
else
echo "Running shfmt in write mode..."
FLAGS="${FLAGS} --write"
fi

echo "shfmt $FLAGS"

# shellcheck disable=SC2086
find . -not -path '*/.*' -type f -name '*.sh' -print0 | xargs -0 shfmt $FLAGS
51 changes: 48 additions & 3 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::Result;
use anyhow::{anyhow, Result};
use log::info;
use std::env;
use std::{env, fs};
use warp::Filter;

mod healthz;
Expand All @@ -13,10 +13,55 @@ fn routes() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection>
.or(healthz::handler())
}

pub async fn start() -> Result<()> {
fn set_certs_dir() -> Result<String> {
let certs_dir = env::var("WEBHOOK_CERTS_DIR").unwrap_or("/certs".to_string());

let meta = match fs::metadata(&certs_dir) {
Err(e) => return Err(anyhow!("Error reading metadata for {}: {}", certs_dir, e)),
Ok(meta) => meta,
};

if !meta.is_dir() {
return Err(anyhow!("{} is not a directory", certs_dir));
}

Ok(certs_dir)
}

fn set_crt_file() -> Result<String> {
let crt_file = env::var("WEBHOOK_CRT_FILE").unwrap_or("tls.crt".to_string());

let meta = match fs::metadata(&crt_file) {
Err(e) => return Err(anyhow!("Error reading metadata for {}: {}", crt_file, e)),
Ok(meta) => meta,
};

if !meta.is_file() {
return Err(anyhow!("{} is not a file", crt_file));
}

Ok(crt_file)
}

fn set_key_file() -> Result<String> {
let key_file = env::var("WEBHOOK_KEY_FILE").unwrap_or("tls.key".to_string());

let meta = match fs::metadata(&key_file) {
Err(e) => return Err(anyhow!("Error reading metadata for {}: {}", key_file, e)),
Ok(meta) => meta,
};

if !meta.is_file() {
return Err(anyhow!("{} is not a file", key_file));
}

Ok(key_file)
}

pub async fn start() -> Result<()> {
let certs_dir = set_certs_dir()?;
let crt_file = set_crt_file()?;
let key_file = set_key_file()?;
info!("configured certs directory to: {}", certs_dir);

// TODO: Make healthz and livez listen on http rather than https if they need to do more
Expand Down
6 changes: 5 additions & 1 deletion src/server/mutate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ mod tests {
let admission_review = AdmissionReview {
request: Some(AdmissionRequest {
uid: "test-uid".to_string(),
name: "test-name".to_string(),
namespace: "test-namespace".to_string(),
}),
};

Expand Down Expand Up @@ -138,7 +140,9 @@ mod tests {

let admission_review = json!({
"request": {
"uid": "test-uid"
"uid": "test-uid",
"name": "test-name",
"namespace": "test-namespace",
}
});

Expand Down

0 comments on commit e06ae7a

Please sign in to comment.