Make tilt work with the supervisor app and add more uninstall testing

- Also continue renaming things related to the concierge app
- Enhance the uninstall test to also test uninstalling the supervisor
  and local-user-authenticator apps
This commit is contained in:
Ryan Richard 2020-10-09 14:25:34 -07:00
parent 72b2d02777
commit 34549b779b
13 changed files with 173 additions and 72 deletions

View File

@ -109,7 +109,7 @@ docker build .
1. Create a local Kubernetes cluster using `kind`:
```bash
kind create cluster --image kindest/node:v1.18.8
./hack/kind-up.sh
```
1. Install Pinniped and supporting dependencies using `tilt`:
@ -123,11 +123,11 @@ docker build .
1. Run the Pinniped integration tests:
```bash
source ./hack/lib/tilt/integration-test.env && go test -v -count 1 ./test/integration
source /tmp/integration-test-env && go test -v -count 1 ./test/integration
```
To uninstall the test environment, run `./hack/tilt-down.sh`.
To destroy the local Kubernetes cluster, run `kind delete cluster`.
To destroy the local Kubernetes cluster, run `./hack/kind-down.sh`.
### Observing Tests on the Continuous Integration Environment

View File

@ -4,8 +4,8 @@
#@data/values
---
app_name: pinniped
namespace: pinniped
app_name: pinniped-concierge
namespace: pinniped-concierge
#! Specify how many replicas of the Pinniped server to run.
replicas: 2

11
hack/kind-down.sh Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
# Copyright 2020 the Pinniped contributors. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
cd "${ROOT}"
kind delete cluster --name pinniped

12
hack/kind-up.sh Executable file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Copyright 2020 the Pinniped contributors. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
cd "${ROOT}"
# To choose a specific version of kube, add this option to the command below: `--image kindest/node:v1.18.8`
kind create cluster --config "hack/lib/kind-config/single-node.yaml" --name pinniped

View File

@ -15,6 +15,10 @@ local_resource(
deps=['../../../cmd', '../../../internal', '../../../pkg', '../../../generated'],
)
#
# local-user-authenticator app
#
# Build a container image for local-user-authenticator, with live-update enabled.
docker_build_with_restart('image/local-user-auth', '.',
dockerfile='local-user-authenticator.Dockerfile',
@ -39,59 +43,106 @@ k8s_resource(
'local-user-authenticator:namespace',
'local-user-authenticator:serviceaccount',
'local-user-authenticator:role',
'local-user-authenticator:rolebinding',
'local-user-authenticator:rolebinding'
],
)
# Build a container image for the Pinniped server, with live-update enabled.
docker_build_with_restart('image/pinniped', '.',
dockerfile='pinniped.Dockerfile',
entrypoint=['/usr/local/bin/pinniped-server'],
live_update=[sync('./build/pinniped-server', '/usr/local/bin/pinniped-server')],
only=['./build/pinniped-server'],
#
# Supervisor app
#
# Build a container image for supervisor, with live-update enabled.
docker_build_with_restart('image/supervisor', '.',
dockerfile='supervisor.Dockerfile',
entrypoint=['/usr/local/bin/pinniped-supervisor'],
live_update=[sync('./build/pinniped-supervisor', '/usr/local/bin/pinniped-supervisor')],
only=['./build/pinniped-supervisor'],
)
# Render the Pinniped server installation manifest using ytt.
# Render the supervisor installation manifest using ytt.
k8s_yaml(local([
'ytt',
'--file', '../../../deploy/supervisor',
'--data-value', 'image_repo=image/supervisor',
'--data-value', 'image_tag=tilt-dev',
'--data-value-yaml', 'replicas=1'
]))
# Collect all the deployed supervisor resources under a "supervisor" resource tab.
k8s_resource(
workload='pinniped-supervisor',
new_name='supervisor',
objects=[
'oidcproviderconfigs.config.pinniped.dev:customresourcedefinition',
'pinniped-supervisor-static-config:configmap',
'pinniped-supervisor:namespace',
'pinniped-supervisor:role',
'pinniped-supervisor:rolebinding',
'pinniped-supervisor:serviceaccount',
],
)
# Build a container image for the Concierge server, with live-update enabled.
docker_build_with_restart('image/concierge', '.',
dockerfile='concierge.Dockerfile',
entrypoint=['/usr/local/bin/pinniped-concierge'],
live_update=[sync('./build/pinniped-concierge', '/usr/local/bin/pinniped-concierge')],
only=['./build/pinniped-concierge'],
)
k8s_yaml('nodeport.yaml')
#
# Concierge app
#
# Render the Concierge server installation manifest using ytt.
k8s_yaml(local([
'sh', '-c',
'ytt --file ../../../deploy/concierge ' +
'--data-value app_name=pinniped-concierge ' +
'--data-value namespace=integration ' +
'--data-value image_repo=image/pinniped ' +
'--data-value image_repo=image/concierge ' +
'--data-value image_tag=tilt-dev ' +
'--data-value kube_cert_agent_image=debian:10.5-slim ' +
'--data-value discovery_url=$(TERM=dumb kubectl cluster-info | awk \'/Kubernetes master/ {print $NF}\') ' +
'--data-value-yaml replicas=1'
]))
# Collect all the deployed local-user-authenticator resources under a "deploy/pinniped" resource tab.
# Collect all the deployed local-user-authenticator resources under a "concierge" resource tab.
k8s_resource(
workload='pinniped',
workload='pinniped-concierge',
new_name='concierge',
objects=[
'integration:namespace',
'pinniped-concierge-aggregated-api-server:clusterrole',
'pinniped-concierge-aggregated-api-server:clusterrolebinding',
'pinniped-concierge-aggregated-api-server:role',
'pinniped-concierge-aggregated-api-server:rolebinding',
'pinniped-concierge-cluster-info-lister-watcher:role',
'pinniped-concierge-cluster-info-lister-watcher:rolebinding',
'pinniped-concierge-config:configmap',
'pinniped-concierge-create-token-credential-requests:clusterrole',
'pinniped-concierge-create-token-credential-requests:clusterrolebinding',
'pinniped-concierge-extension-apiserver-authentication-reader:rolebinding',
'pinniped-concierge-kube-system-pod-read:role',
'pinniped-concierge-kube-system-pod-read:rolebinding',
'pinniped-concierge:clusterrolebinding',
'pinniped-concierge:serviceaccount',
'credentialissuerconfigs.config.pinniped.dev:customresourcedefinition',
'webhookidentityproviders.idp.pinniped.dev:customresourcedefinition',
'pinniped:serviceaccount',
'pinniped-aggregated-api-server:role',
'pinniped-kube-system-pod-read:role',
'pinniped-cluster-info-lister-watcher:role',
'pinniped-aggregated-api-server:clusterrole',
'pinniped-create-token-credential-requests:clusterrole',
'pinniped-aggregated-api-server:rolebinding',
'pinniped-kube-system-pod-read:rolebinding',
'pinniped-extension-apiserver-authentication-reader:rolebinding',
'pinniped-cluster-info-lister-watcher:rolebinding',
'pinniped-aggregated-api-server:clusterrolebinding',
'pinniped-create-token-credential-requests:clusterrolebinding',
'pinniped:clusterrolebinding',
'pinniped-config:configmap',
'v1alpha1.login.pinniped.dev:apiservice',
],
)
#
# Finish setting up cluster and creating integration test env file
#
# Collect environment variables needed to run our integration test suite.
local_resource(
'test-env',
'TILT_MODE=yes ../../prepare-for-integration-tests.sh',
resource_deps=['local-user-auth', 'pinniped'],
resource_deps=['local-user-auth', 'concierge', 'supervisor'],
deps=['../../prepare-for-integration-tests.sh'],
)

View File

@ -5,10 +5,10 @@
FROM debian:10.5-slim
# Copy the binary which was built outside the container.
COPY build/pinniped-server /usr/local/bin/pinniped-server
COPY build/pinniped-concierge /usr/local/bin/pinniped-concierge
# Document the port
EXPOSE 443
# Set the entrypoint
ENTRYPOINT ["/usr/local/bin/pinniped-server"]
ENTRYPOINT ["/usr/local/bin/pinniped-concierge"]

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: pinniped-supervisor-node-port
namespace: pinniped-supervisor
spec:
type: NodePort
selector:
app: pinniped-supervisor
ports:
- port: 80
targetPort: 80
nodePort: 31234

View File

@ -0,0 +1,14 @@
# Copyright 2020 VMware, Inc.
# SPDX-License-Identifier: Apache-2.0
# Use a runtime image based on Debian slim
FROM debian:10.5-slim
# Copy the binary which was built outside the container.
COPY build/pinniped-supervisor /usr/local/bin/pinniped-supervisor
# Document the port
EXPOSE 443
# Set the entrypoint
ENTRYPOINT ["/usr/local/bin/pinniped-supervisor"]

View File

@ -110,17 +110,17 @@ fi
if ! tilt_mode; then
if [[ "$clean_kind" == "yes" ]]; then
log_note "Deleting running kind clusters to prepare from a clean slate..."
kind delete cluster
kind delete cluster --name pinniped
fi
#
# Setup kind and build the app
#
log_note "Checking for running kind clusters..."
if ! kind get clusters | grep -q -e '^kind$'; then
if ! kind get clusters | grep -q -e '^pinniped$'; then
log_note "Creating a kind cluster..."
# single-node.yaml exposes node port 31234 as localhost:12345
kind create cluster --config "$pinniped_path/hack/lib/kind-config/single-node.yaml"
kind create cluster --config "$pinniped_path/hack/lib/kind-config/single-node.yaml" --name pinniped
else
if ! kubectl cluster-info | grep master | grep -q 127.0.0.1; then
log_error "Seems like your kubeconfig is not targeting a local cluster."
@ -157,7 +157,7 @@ if ! tilt_mode; then
# Load it into the cluster
log_note "Loading the app's container image into the kind cluster..."
kind load docker-image "$registry_repo_tag"
kind load docker-image "$registry_repo_tag" --name pinniped
manifest=/tmp/manifest.yaml
@ -178,7 +178,6 @@ if ! tilt_mode; then
fi
test_username="test-username"
test_groups="test-group-0,test-group-1"
set +o pipefail
@ -203,18 +202,19 @@ kubectl create secret generic "$test_username" \
supervisor_app_name="pinniped-supervisor"
supervisor_namespace="pinniped-supervisor"
pushd deploy/supervisor >/dev/null
if ! tilt_mode; then
pushd deploy/supervisor >/dev/null
log_note "Deploying the Pinniped Supervisor app to the cluster..."
ytt --file . \
--data-value "app_name=$supervisor_app_name" \
--data-value "namespace=$supervisor_namespace" \
--data-value "image_repo=$registry_repo" \
--data-value "image_tag=$tag" >"$manifest"
log_note "Deploying the Pinniped Supervisor app to the cluster..."
ytt --file . \
--data-value "app_name=$supervisor_app_name" \
--data-value "namespace=$supervisor_namespace" \
--data-value "image_repo=$registry_repo" \
--data-value "image_tag=$tag" >"$manifest"
kapp deploy --yes --app "pinniped-supervisor" --diff-changes --file "$manifest"
kapp deploy --yes --app "$supervisor_app_name" --diff-changes --file "$manifest"
log_note "Adding NodePort service to expose the Pinniped Supervisor app on the kind node..."
log_note "Adding NodePort service to expose the Pinniped Supervisor app on the kind node..."
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
@ -231,32 +231,30 @@ spec:
nodePort: 31234
EOF
popd >/dev/null
popd >/dev/null
fi
#
# Deploy Pinniped
#
app_name="pinniped"
namespace="integration"
concierge_app_name="pinniped-concierge"
concierge_namespace="integration"
webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate"
webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')"
discovery_url="$(TERM=dumb kubectl cluster-info | awk '/Kubernetes master/ {print $NF}')"
if ! tilt_mode; then
#
# Deploy Pinniped
#
pushd deploy/concierge >/dev/null
log_note "Deploying the Pinniped app to the cluster..."
ytt --file . \
--data-value "app_name=$app_name" \
--data-value "namespace=$namespace" \
--data-value "app_name=$concierge_app_name" \
--data-value "namespace=$concierge_namespace" \
--data-value "image_repo=$registry_repo" \
--data-value "image_tag=$tag" \
--data-value "discovery_url=$discovery_url" >"$manifest"
kapp deploy --yes --app "$app_name" --diff-changes --file "$manifest"
kapp deploy --yes --app "$concierge_app_name" --diff-changes --file "$manifest"
popd >/dev/null
fi
@ -269,8 +267,8 @@ pinniped_cluster_capability_file_content=$(cat "$kind_capabilities_file")
cat <<EOF >/tmp/integration-test-env
# The following env vars should be set before running 'go test -v -count 1 ./test/...'
export PINNIPED_TEST_CONCIERGE_NAMESPACE=${namespace}
export PINNIPED_TEST_CONCIERGE_APP_NAME=${app_name}
export PINNIPED_TEST_CONCIERGE_NAMESPACE=${concierge_namespace}
export PINNIPED_TEST_CONCIERGE_APP_NAME=${concierge_app_name}
export PINNIPED_TEST_USER_USERNAME=${test_username}
export PINNIPED_TEST_USER_GROUPS=${test_groups}
export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password}
@ -304,6 +302,7 @@ log_note
if ! tilt_mode; then
log_note "You can rerun this script to redeploy local production code changes while you are working."
log_note
log_note "To delete the deployments, run 'kapp delete -a local-user-authenticator -y && kapp delete -a pinniped -y'."
log_note "When you're finished, use 'kind delete cluster' to tear down the cluster."
log_note "To delete the deployments, run:"
log_note " kapp delete -a local-user-authenticator -y && kapp delete -a $concierge_app_name -y && kapp delete -a $supervisor_app_name -y"
log_note "When you're finished, use 'kind delete cluster --name pinniped' to tear down the cluster."
fi

View File

@ -5,5 +5,7 @@
set -euo pipefail
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
cd "${ROOT}"
exec tilt up -f ./hack/lib/tilt/Tiltfile --stream
exec tilt up -f ./hack/lib/tilt/Tiltfile

View File

@ -32,7 +32,7 @@ func TestFromPath(t *testing.T) {
durationSeconds: 3600
renewBeforeSeconds: 2400
names:
servingCertificateSecret: pinniped-api-tls-serving-certificate
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
credentialIssuerConfig: pinniped-config
apiService: pinniped-api
kubeCertAgentPrefix: kube-cert-agent-prefix
@ -52,7 +52,7 @@ func TestFromPath(t *testing.T) {
},
},
NamesConfig: api.NamesConfigSpec{
ServingCertificateSecret: "pinniped-api-tls-serving-certificate",
ServingCertificateSecret: "pinniped-concierge-api-tls-serving-certificate",
CredentialIssuerConfig: "pinniped-config",
APIService: "pinniped-api",
},
@ -68,7 +68,7 @@ func TestFromPath(t *testing.T) {
yaml: here.Doc(`
---
names:
servingCertificateSecret: pinniped-api-tls-serving-certificate
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
credentialIssuerConfig: pinniped-config
apiService: pinniped-api
`),
@ -83,7 +83,7 @@ func TestFromPath(t *testing.T) {
},
},
NamesConfig: api.NamesConfigSpec{
ServingCertificateSecret: "pinniped-api-tls-serving-certificate",
ServingCertificateSecret: "pinniped-concierge-api-tls-serving-certificate",
CredentialIssuerConfig: "pinniped-config",
APIService: "pinniped-api",
},
@ -103,7 +103,7 @@ func TestFromPath(t *testing.T) {
yaml: here.Doc(`
---
names:
servingCertificateSecret: pinniped-api-tls-serving-certificate
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
credentialIssuerConfig: pinniped-config
`),
wantError: "validate names: missing required names: apiService",
@ -113,7 +113,7 @@ func TestFromPath(t *testing.T) {
yaml: here.Doc(`
---
names:
servingCertificateSecret: pinniped-api-tls-serving-certificate
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
apiService: pinniped-api
`),
wantError: "validate names: missing required names: credentialIssuerConfig",
@ -137,7 +137,7 @@ func TestFromPath(t *testing.T) {
durationSeconds: 2400
renewBeforeSeconds: 3600
names:
servingCertificateSecret: pinniped-api-tls-serving-certificate
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
credentialIssuerConfig: pinniped-config
apiService: pinniped-api
`),
@ -152,7 +152,7 @@ func TestFromPath(t *testing.T) {
durationSeconds: 2400
renewBeforeSeconds: -10
names:
servingCertificateSecret: pinniped-api-tls-serving-certificate
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
credentialIssuerConfig: pinniped-config
apiService: pinniped-api
`),
@ -167,7 +167,7 @@ func TestFromPath(t *testing.T) {
durationSeconds: 2400
renewBeforeSeconds: -10
names:
servingCertificateSecret: pinniped-api-tls-serving-certificate
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
credentialIssuerConfig: pinniped-config
apiService: pinniped-api
`),

View File

@ -20,8 +20,7 @@ import (
func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
env := library.IntegrationEnv(t)
const defaultServingCertResourceName = "pinniped-api-tls-serving-certificate"
defaultServingCertResourceName := env.ConciergeAppName + "-api-tls-serving-certificate"
tests := []struct {
name string