Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
e2e: test gpg commit verification
Browse files Browse the repository at this point in the history
  • Loading branch information
hiddeco committed Nov 5, 2019
1 parent ea2999c commit 728128a
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 12 deletions.
1 change: 0 additions & 1 deletion test/e2e/12_sync.bats
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ function setup() {
function teardown() {
# Teardown the created port-forward to gitsrv and restore Git settings.
kill "$git_port_forward_pid"
unset GIT_SSH_COMMAND
# Uninstall Flux and the global resources it installs.
uninstall_flux_with_fluxctl
# Removing the namespace also takes care of removing gitsrv.
Expand Down
6 changes: 4 additions & 2 deletions test/e2e/20_commit_signing.bats
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ load lib/gpg
load lib/install
load lib/poll

tmp_gnupghome=""
git_port_forward_pid=""

function setup() {
Expand All @@ -22,7 +23,6 @@ function setup() {
# Create a temporary GNUPGHOME
tmp_gnupghome=$(mktemp -d)
export GNUPGHOME="$tmp_gnupghome"
defer rm -rf "$tmp_gnupghome"

# Install Flux, with a new GPG key and signing enabled
gpg_key=$(create_gpg_key)
Expand Down Expand Up @@ -68,7 +68,9 @@ function setup() {
function teardown() {
# Teardown the created port-forward to gitsrv and restore Git settings.
kill "$git_port_forward_pid"
unset GIT_SSH_COMMAND
# Kill the agent and remove temporary GNUPGHOME
gpgconf --kill gpg-agent
rm -rf "$tmp_gnupghome"
# Uninstall Flux and the global resources it installs.
uninstall_flux_gpg
# Removing the namespace also takes care of removing Flux and gitsrv.
Expand Down
106 changes: 106 additions & 0 deletions test/e2e/20_commit_verification.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env bats

load lib/defer
load lib/env
load lib/gpg
load lib/install
load lib/poll

tmp_gnupghome=""

function setup() {
kubectl create namespace "${FLUX_NAMESPACE}"

# Create a temporary GNUPGHOME
tmp_gnupghome=$(mktemp -d)
export GNUPGHOME="$tmp_gnupghome"
}

@test "Commits are verified" {
# Create a new GPG key and secret
gpg_key=$(create_gpg_key)
create_secret_from_gpg_key "$gpg_key"

# Install the git server with signed init commit,
# allowing external access
install_git_srv flux-git-deploy git_srv_result true

# Install Flux with the GPG key, and commit verification enabled
install_flux_gpg "$gpg_key" true

# shellcheck disable=SC2154
git_ssh_cmd="${git_srv_result[0]}"
export GIT_SSH_COMMAND="$git_ssh_cmd"

git_port_forward_pid="${git_srv_result[1]}"
defer kill "$git_port_forward_pid"

# Test that the resources from https://github.com/fluxcd/flux-get-started are deployed
poll_until_true 'namespace demo' 'kubectl describe ns/demo'
defer kubectl delete namespace "$DEMO_NAMESPACE"

# Clone the repo
local clone_dir
clone_dir="$(mktemp -d)"
defer rm -rf "$clone_dir"
git clone -b master ssh://git@localhost/git-server/repos/cluster.git "$clone_dir"
cd "$clone_dir"

local sync_tag="flux-sync"
local org_head_hash
org_head_hash=$(git rev-list -n 1 HEAD)
sync_tag_hash=$(git rev-list -n 1 "$sync_tag")

[ "$sync_tag_hash" = "$org_head_hash" ]
run git verify-commit "$sync_tag_hash"
[ "$status" -eq 0 ]

# Add an unsigned change
sed -i'.bak' 's%stefanprodan/podinfo:*%stefanprodan/podinfo:3.1.5)%' "${clone_dir}/workloads/podinfo-dep.yaml"
git -c '[email protected]' -c 'user.name=Foo' commit -am "Bump podinfo"
git push

# Delete tag
git push --delete origin "$sync_tag"

# Sync should warn, and put the tag back at the latest verified commit
run fluxctl --k8s-fwd-ns "${FLUX_NAMESPACE}" sync
[ "$status" -eq 0 ]
[[ "$output" == *"Warning: The branch HEAD in the git repo is not verified"* ]]

git pull -f --tags
sync_tag_hash=$(git rev-list -n 1 "$sync_tag")
[ "$sync_tag_hash" = "$org_head_hash" ]
}

@test "Does not commit on top of invalid commit" {
# Create a new GPG key and secret
gpg_key=$(create_gpg_key)
create_secret_from_gpg_key "$gpg_key"

# Install the git server with _unsigned_ init commit,
# allowing external access
install_git_srv flux-git-deploy git_srv_result false

# Install Flux with the GPG key, and commit verification enabled
install_flux_gpg "$gpg_key" true

# Wait for Flux to report that it sees an invalid commit
poll_until_true 'invalid GPG signature log' "kubectl logs -n ${FLUX_NAMESPACE} deploy/flux-gpg | grep -e 'found invalid GPG signature for commit'"

# Attempt to lock a resource, and confirm it returns an error.
run fluxctl --k8s-fwd-ns "${FLUX_NAMESPACE}" lock --workload demo:deployment/podinfo
[ "$status" -eq 1 ]
[[ "$output" == *"Error: HEAD revision is unsigned"* ]]
}

function teardown() {
# Kill the agent and remove temporary GNUPGHOME
gpgconf --kill gpg-agent
rm -rf "$tmp_gnupghome"
# Although the namespace delete below takes care of removing most Flux
# elements, the global resources will not be removed without this.
uninstall_flux_gpg
# Removing the namespace also takes care of removing Flux and gitsrv.
kubectl delete namespace "$FLUX_NAMESPACE"
}
63 changes: 63 additions & 0 deletions test/e2e/fixtures/gitsrv-gpg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
name: gitsrv
name: gitsrv
spec:
replicas: 1
selector:
matchLabels:
name: gitsrv
template:
metadata:
labels:
name: gitsrv
spec:
containers:
- image: stefanprodan/gitsrv:0.1.0
name: git
env:
- name: REPO
value: "cluster.git"
- name: TAR_URL
value: "https://github.com/fluxcd/flux-get-started/archive/master.tar.gz"
- name: GPG_KEYFILE
value: /git-server/gpg/flux.asc
ports:
- containerPort: 22
name: ssh
protocol: TCP
volumeMounts:
- mountPath: /git-server/gpg
name: git-gpg-keys
- mountPath: /git-server/repos
name: git-server-data
- mountPath: /git-server/keys
name: flux-git-deploy
volumes:
- name: flux-git-deploy
secret:
secretName: $GIT_SECRET_NAME
- name: git-server-data
emptyDir: {}
- name: git-gpg-keys
secret:
secretName: $GPG_SECRET_NAME
---
apiVersion: v1
kind: Service
metadata:
labels:
name: gitsrv
name: gitsrv
spec:
ports:
- name: ssh
port: 22
protocol: TCP
targetPort: ssh
selector:
name: gitsrv
type: ClusterIP
4 changes: 3 additions & 1 deletion test/e2e/fixtures/gitsrv.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ spec:
name: gitsrv
spec:
containers:
- image: stefanprodan/gitsrv:0.0.12
- image: stefanprodan/gitsrv:0.1.0
name: git
env:
- name: REPO
value: "cluster.git"
- name: TAR_URL
value: "https://github.com/fluxcd/flux-get-started/archive/master.tar.gz"
- name: GPG_KEYFILE
value: ""
ports:
- containerPort: 22
name: ssh
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/fixtures/known_hosts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# generated with "ssh-keyscan gitsrv"
gitsrv ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2WoJ2k+WA54pdxw5EGhg9CQBHKDVjHzNNlgRfTGrQBpgQT3/HEBi6BGi2ZmS6o6W9EJfzYzl3PvC+JY6BqcdM8XqbDazC1rkGtlycHd+dFT/TmWvBqJ2Oh+oJNL7IgpjBPJJMdAEc9nzUTTYa7V2A9SeaAyQJKGaftZhHEXTxkxxbWP2an7bzyw9QNCiF/ogQ79DPsp7ly4v4KgeGLSm9AoT/HO5+kJwXX3yQ1hKrFZyhzhaYiwzdApc3iUJtUEz1lKVX+63+WN6qhkbCUjlhfOGyT3qk18sMU6raqKt8uuQeR9f4/xkMXGWQuULhjGwOkju+8Dma8GvnhKKwHf5V
gitsrv ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFhuyD3SzMaTye/OX51Jb3fgZDxhGnXgJQ6oFvSSwqDGDm4fcueHE979xEPolNe9hn6jGg/2DS3xkU8boPKv8mo=
gitsrv ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAbLc9veRHa/l/kK6hmRWMA+QoWd8vLtLHbm4v6wj8XU
gitsrv ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxSccSZ6jNybRRvuNl9Rv4+HNqZ93rPsjRZko5E2kFfd5BMSflISpRK5owVO+YmeggEY3n86hX4CB/dpxYL62ur9QtkYQICL2fmgc40eE6XshsFSuS44PXmv4IrcHkHaqXl7bjbDon8UHLlRPI2ZFPHnvxa1TEth9i0L14tT4NkTbUNQlyAubM1Jxkph64c21zVSbGlaeflTZFbr2+qi0VfC44pxOWy2WMeS+KbApPScQF7LSNhRDXG/mVylOkc4kZfe1N15WOjKGGJiawFCP7/IjbQBoPaPFIAqU++pJ/IuH/Rv5FAZuc+zH1Vw2UtEU3z9STR30DUdqLSW1oEgYr
gitsrv ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBO0Frzlxfern1gNWgnbNK4jDLBcMSuueBuj3n/P2KbHIng5vZocuVlA60YaCwN7bLyWplG/kA8zMVeLI3+Vl5JU=
gitsrv ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIT2f8tK1sXJBRlwyhUpam6dkQmiBxBnMJcKLE1xvap+
25 changes: 20 additions & 5 deletions test/e2e/lib/install.bash
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ flux_gpg_helm_template="helm template --name flux-gpg

function install_flux_gpg() {
local key_id=${1}
local gpg_secret_name=${2:-flux-gpg-signing-key}
local git_verify=${2:-false}
local gpg_secret_name=${3:-flux-gpg-signing-key}

if [ -z "$key_id" ]; then
echo "no key ID provided" >&2
Expand All @@ -95,6 +96,7 @@ function install_flux_gpg() {
--set-string git.config.data="${GITCONFIG}" \
--set-string ssh.known_hosts="${KNOWN_HOSTS}" \
--set-string git.signingKey="$key_id" \
--set-string git.verifySignatures="$git_verify" \
--set-string gpgKeys.secretName="$gpg_secret_name" \
"${FLUX_ROOT_DIR}/chart/flux" |
kubectl --namespace "${FLUX_NAMESPACE}" apply -f - >&3
Expand All @@ -110,22 +112,35 @@ function uninstall_flux_gpg() {
}

function install_git_srv() {
local secret_name=${1:-flux-git-deploy}
local git_secret_name=${1:-flux-git-deploy}
local external_access_result_var=${2}
local gpg_enable=${3:-false}
local gpg_secret_name=${4:-flux-gpg-signing-key}
local gen_dir
gen_dir=$(mktemp -d)

ssh-keygen -t rsa -N "" -f "$gen_dir/id_rsa"
defer rm -rf "$gen_dir"
kubectl create secret generic "$secret_name" \
kubectl create secret generic "$git_secret_name" \
--namespace="${FLUX_NAMESPACE}" \
--from-file="${FIXTURES_DIR}/known_hosts" \
--from-file="$gen_dir/id_rsa" \
--from-file=identity="$gen_dir/id_rsa" \
--from-file="$gen_dir/id_rsa.pub"

sed "s/\$GIT_SECRET_NAME/$secret_name/" < "${E2E_DIR}/fixtures/gitsrv.yaml" | kubectl apply -n "${FLUX_NAMESPACE}" -f -
# wait for the git server to be ready
local template="${E2E_DIR}/fixtures/gitsrv.yaml"
if [ "$gpg_enable" == "true" ]; then
template="${E2E_DIR}/fixtures/gitsrv-gpg.yaml"
fi

(
export GIT_SECRET_NAME=$git_secret_name
export GPG_SECRET_NAME=$gpg_secret_name

envsubst < "$template" | kubectl apply -n "${FLUX_NAMESPACE}" -f - >&3
)

# Wait for the git server to be ready
kubectl -n "${FLUX_NAMESPACE}" rollout status deployment/gitsrv

if [ -n "$external_access_result_var" ]; then
Expand Down

0 comments on commit 728128a

Please sign in to comment.