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

e2e: test gpg commit verification #2579

Merged
merged 4 commits into from
Nov 6, 2019
Merged
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
1 change: 0 additions & 1 deletion test/e2e/12_sync.bats
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ function teardown() {
rm -rf "$clone_dir"
# 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
8 changes: 5 additions & 3 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 @@ -66,9 +66,11 @@ function setup() {
}

function teardown() {
# Teardown the created port-forward to gitsrv and restore Git settings.
# Teardown the created port-forward to gitsrv.
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
111 changes: 111 additions & 0 deletions test/e2e/20_commit_verification.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env bats

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

tmp_gnupghome=""
git_port_forward_pid=""
clone_dir=""

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"

# shellcheck disable=SC2030
git_port_forward_pid="${git_srv_result[1]}"

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

# Clone the repo
# shellcheck disable=SC2030
clone_dir="$(mktemp -d)"
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 'user.email=foo@bar.com' -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
install_git_srv flux-git-deploy "" 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() {
# shellcheck disable=SC2031
rm -rf "$clone_dir"
# (Maybe) teardown the created port-forward to gitsrv.
# shellcheck disable=SC2031
kill "$git_port_forward_pid" || true
# 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"
# (Maybe) remove the demo namespace
kubectl delete namespace "$DEMO_NAMESPACE" &> /dev/null || true
}
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
Copy link
Contributor

Choose a reason for hiding this comment

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

Would you be open to using kustomize instead?

@squaremo seems to have been successful using it at #2577

Copy link
Member Author

Choose a reason for hiding this comment

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

💯 was thinking the same when I laid eyes on @squaremo his kustomize boilerplate.

I do not want to spend much more time on this PR at this time though, as the Helm operator really needs my attention. So I would like to propose to merge this as is, and make the adjustment / optimization later.

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense

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.3
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
2 changes: 1 addition & 1 deletion test/e2e/fixtures/gitsrv.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spec:
name: gitsrv
spec:
containers:
- image: stefanprodan/gitsrv:0.0.12
- image: stefanprodan/gitsrv:0.1.3
name: git
env:
- name: REPO
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 AAAAB3NzaC1yc2EAAAADAQABAAABAQC3qgBx5WLHbB+frq8d+iomxrdQPlWcj7NsJSiEz8vYOaRQsQDMtWHHYRt+zBVIH9Q96urBHDZa+B72DsInkO7JxflLVXLenwhNu8u9a0VbbleYnBYWfoNYWv+0tQpilOIasNjA+aLAWsVVjEAPB8RM77QocXnUbthI898f5EbQ1jXLBMPfbY0VRHimqo0EST71q0/PzfQTf/3tWdd8/cqIFfErOp8IEdnAQmJlhlaAMuI6tDAOCGWjSL/JUMQVIvkObWu2a33fm35OD5q+NyCBquM1a11i/M78oKq0xR8l02OcOKtCdPf09cUBwY8yiRRDIa2PVEpmzHcE5YMXY8IL
gitsrv ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBB+7/Q4mchJWXQoc4LCA9RVMcyj673QDHV98D1ZTGeu7iEz7g/mK/V2thcpgD+rsHBh6u5nYwMd9ja3e7YquX2I=
gitsrv ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC/1fXvsyIQmxhcWIhl3VBYylabjKb2669sPODnK0Zbt
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