Skip to content

Commit

Permalink
WIP - Demo supports Conjur OSS and annotation-based authn-k8s
Browse files Browse the repository at this point in the history
Work-in-Progress: Needs testing on minikube/Kind, OpenShift,
and with DAP/appliance image.

This change adds support for:

- Running demo scripts directly on a Conjur OSS cluster that has been
  deployed via Conjur OSS Helm chart.
- Creation of a Conjur CLI pod if it doesn't exist.
- Selectable operation for annotation-based authn-k8s vs.
  host-ID-based authn-k8s.
- Running demo scripts on platforms that do not have a load balancer
  configured (e.g. for testing on KinD or Minikube without having to
  load MetalLB).
- CI for both annotation-based and host-ID based identity authentication
  for GKE and OpenShift.

Addresses Issue #106
  • Loading branch information
diverdane committed Oct 6, 2020
1 parent d310cf5 commit e4f0461
Show file tree
Hide file tree
Showing 22 changed files with 482 additions and 173 deletions.
15 changes: 10 additions & 5 deletions 1_create_test_app_namespace.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@ else
set_namespace $TEST_APP_NAMESPACE_NAME
fi

$cli delete --ignore-not-found rolebinding test-app-conjur-authenticator-role-binding-$CONJUR_NAMESPACE_NAME

sed "s#{{ TEST_APP_NAMESPACE_NAME }}#$TEST_APP_NAMESPACE_NAME#g" ./$PLATFORM/test-app-conjur-authenticator-role-binding.yml |
sed "s#{{ CONJUR_NAMESPACE_NAME }}#$CONJUR_NAMESPACE_NAME#g" |
$cli create -f -
# A Conjur OSS cluster that was deployed via cyberark/conjur-oss-helm-chart
# includes a ClusterRoleBinding (that has cluster-wide scope), so there is no
# need to create a RoleBinding for this namespace.
if [[ $CONJUR_OSS_HELM_INSTALLED != true ]]; then
$cli delete --ignore-not-found rolebinding test-app-conjur-authenticator-role-binding-$CONJUR_NAMESPACE_NAME

sed "s#{{ TEST_APP_NAMESPACE_NAME }}#$TEST_APP_NAMESPACE_NAME#g" ./$PLATFORM/test-app-conjur-authenticator-role-binding.yml |
sed "s#{{ CONJUR_NAMESPACE_NAME }}#$CONJUR_NAMESPACE_NAME#g" |
$cli create -f -
fi

if [[ $PLATFORM == openshift ]]; then
# add permissions for Conjur admin user
Expand Down
68 changes: 65 additions & 3 deletions 2_load_conjur_policies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,57 @@ set -euo pipefail

announce "Generating Conjur policy."

prepare_conjur_cli_image() {
announce "Pulling and pushing Conjur CLI image."

docker pull cyberark/conjur-cli:$CONJUR_VERSION-latest

cli_app_image=$(platform_image conjur-cli)
docker tag cyberark/conjur-cli:$CONJUR_VERSION-latest $cli_app_image

if ! is_minienv; then
docker push $cli_app_image
fi
}

deploy_conjur_cli() {
announce "Deploying Conjur CLI pod."

if is_minienv; then
IMAGE_PULL_POLICY='Never'
else
IMAGE_PULL_POLICY='Always'
fi
if [ "$CONJUR_OSS_HELM_INSTALLED" = "true" ]; then
service_account='conjur-oss'
else
service_account='conjur-cluster'
fi

cli_app_image=$(platform_image conjur-cli)
sed -e "s#{{ CONJUR_SERVICE_ACCOUNT }}#$service_account#g" ./$PLATFORM/conjur-cli.yml |
sed -e "s#{{ DOCKER_IMAGE }}#$cli_app_image#g" |
sed -e "s#{{ IMAGE_PULL_POLICY }}#$IMAGE_PULL_POLICY#g" |
$cli create -f -

conjur_cli_pod=$(get_conjur_cli_pod_name)
wait_for_it 300 "$cli get pod $conjur_cli_pod -o jsonpath='{.status.phase}'| grep -q Running"
}

configure_conjur_cli() {
announce "Configuring Conjur CLI pod."

if [[ "$CONJUR_OSS_HELM_INSTALLED" == "true" ]]; then
conjur_service='conjur-oss'
else
conjur_service='conjur-master'
fi
conjur_url=${CONJUR_APPLIANCE_URL:-https://$conjur_service.$CONJUR_NAMESPACE_NAME.svc.cluster.local}

$cli exec $1 -- bash -c "yes yes | conjur init -a $CONJUR_ACCOUNT -u $conjur_url"
$cli exec $1 -- conjur authn login -u admin -p $CONJUR_ADMIN_PASSWORD
}

pushd policy
mkdir -p ./generated

Expand Down Expand Up @@ -36,18 +87,29 @@ popd
# Create the random database password
password=$(openssl rand -hex 12)

if [[ "${DEPLOY_MASTER_CLUSTER}" == "true" ]]; then

announce "Loading Conjur policy."
if [[ "${DEPLOY_MASTER_CLUSTER}" == "true" || "${CONJUR_OSS_HELM_INSTALLED}" == "true" ]]; then

set_namespace "$CONJUR_NAMESPACE_NAME"


announce "Finding or creating a Conjur CLI pod"
conjur_cli_pod=$(get_conjur_cli_pod_name)
if [ -z "$conjur_cli_pod" ]; then
prepare_conjur_cli_image
deploy_conjur_cli
conjur_cli_pod=$(get_conjur_cli_pod_name)
configure_conjur_cli $conjur_cli_pod
fi

announce "Loading Conjur policy."

$cli exec $conjur_cli_pod -- rm -rf /policy
$cli cp ./policy $conjur_cli_pod:/policy

$cli exec $conjur_cli_pod -- \
bash -c "
conjur_appliance_url=${CONJUR_APPLIANCE_URL:-https://conjur-oss.$CONJUR_NAMESPACE_NAME.svc.cluster.local}
CONJUR_ACCOUNT=${CONJUR_ACCOUNT} \
CONJUR_ADMIN_PASSWORD=${CONJUR_ADMIN_PASSWORD} \
DB_PASSWORD=${password} \
TEST_APP_NAMESPACE_NAME=${TEST_APP_NAMESPACE_NAME} \
Expand Down
6 changes: 5 additions & 1 deletion 3_init_conjur_cert_authority.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ set_namespace $CONJUR_NAMESPACE_NAME

conjur_master=$(get_master_pod_name)

$cli exec $conjur_master -- chpst -u conjur conjur-plugin-service possum rake authn_k8s:ca_init["conjur/authn-k8s/$AUTHENTICATOR_ID"]
if [[ "$CONJUR_OSS_HELM_INSTALLED" == "true" ]]; then
$cli exec $conjur_master -c conjur-oss -- bash -c "CONJUR_ACCOUNT=$CONJUR_ACCOUNT rake authn_k8s:ca_init['conjur/authn-k8s/$AUTHENTICATOR_ID']"
else
$cli exec $conjur_master -- chpst -u conjur conjur-plugin-service possum rake authn_k8s:ca_init["conjur/authn-k8s/$AUTHENTICATOR_ID"]
fi

echo "Certificate authority initialized."
17 changes: 11 additions & 6 deletions 4_store_conjur_cert.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ set_namespace $CONJUR_NAMESPACE_NAME

echo "Retrieving Conjur certificate."

if $cli get pods --selector role=follower --no-headers; then
follower_pod_name=$($cli get pods --selector role=follower --no-headers | awk '{ print $1 }' | head -1)
ssl_cert=$($cli exec $follower_pod_name -- cat /opt/conjur/etc/ssl/conjur.pem)
if [[ "$CONJUR_OSS_HELM_INSTALLED" == "true" ]]; then
master_pod_name=$(get_master_pod_name)
ssl_cert=$($cli exec -c "conjur-oss-nginx" $master_pod_name -- cat /opt/conjur/etc/ssl/cert/tls.crt)
else
echo "Regular follower not found. Trying to assume a decomposed follower..."
follower_pod_name=$($cli get pods --selector role=decomposed-follower --no-headers | awk '{ print $1 }' | head -1)
ssl_cert=$($cli exec -c "nginx" $follower_pod_name -- cat /opt/conjur/etc/ssl/cert/tls.crt)
if $cli get pods --selector role=follower --no-headers; then
follower_pod_name=$($cli get pods --selector role=follower --no-headers | awk '{ print $1 }' | head -1)
ssl_cert=$($cli exec $follower_pod_name -- cat /opt/conjur/etc/ssl/conjur.pem)
else
echo "Regular follower not found. Trying to assume a decomposed follower..."
follower_pod_name=$($cli get pods --selector role=decomposed-follower --no-headers | awk '{ print $1 }' | head -1)
ssl_cert=$($cli exec -c "nginx" $follower_pod_name -- cat /opt/conjur/etc/ssl/cert/tls.crt)
fi
fi

set_namespace $TEST_APP_NAMESPACE_NAME
Expand Down
25 changes: 21 additions & 4 deletions 6_deploy_test_app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,24 @@ init_connection_specs() {
secretless_image="cyberark/secretless-broker"
fi

conjur_follower_name=${CONJUR_FOLLOWER_NAME:-conjur-follower}
conjur_appliance_url=https://$conjur_follower_name.$CONJUR_NAMESPACE_NAME.svc.cluster.local/api
conjur_authenticator_url=https://$conjur_follower_name.$CONJUR_NAMESPACE_NAME.svc.cluster.local/api/authn-k8s/$URLENCODED_AUTHN_ID
if [[ "$CONJUR_OSS_HELM_INSTALLED" == "true" ]]; then
conjur_appliance_url=${CONJUR_APPLIANCE_URL:-https://conjur-oss.$CONJUR_NAMESPACE_NAME.svc.cluster.local}
else
conjur_follower_name=${CONJUR_FOLLOWER_NAME:-conjur-follower}
conjur_appliance_url=https://$conjur_follower_name.$CONJUR_NAMESPACE_NAME.svc.cluster.local/api
fi
conjur_authenticator_url="$conjur_appliance_url/authn-k8s/$URLENCODED_AUTHN_ID"

conjur_authn_login_prefix=host/conjur/authn-k8s/$AUTHENTICATOR_ID/apps/$TEST_APP_NAMESPACE_NAME/$CONJUR_AUTHN_LOGIN_RESOURCE
if [[ "$ANNOTATION_BASED_AUTHN" == "true" ]]; then
# For annotation-based Kubernetes authentication, the host ID to be used
# for authenticating is an application name.
conjur_authn_login_prefix=host/conjur/authn-k8s/$AUTHENTICATOR_ID/apps
else
# For host-ID-based Kubernetes authentication, the host ID to be used
# for authenticating is in the form:
# <namespace-name>/<kubernetes-resource>/<resource-name>
conjur_authn_login_prefix=host/conjur/authn-k8s/$AUTHENTICATOR_ID/apps/$TEST_APP_NAMESPACE_NAME/$CONJUR_AUTHN_LOGIN_RESOURCE
fi
}

###########################
Expand Down Expand Up @@ -145,6 +158,7 @@ deploy_sidecar_app() {
sed "s#{{ TEST_APP_NAMESPACE_NAME }}#$TEST_APP_NAMESPACE_NAME#g" |
sed "s#{{ AUTHENTICATOR_ID }}#$AUTHENTICATOR_ID#g" |
sed "s#{{ CONFIG_MAP_NAME }}#$TEST_APP_NAMESPACE_NAME#g" |
sed "s#{{ SERVICE_TYPE }}#$(app_service_type)#g" |
$cli create -f -

if [[ "$PLATFORM" == "openshift" ]]; then
Expand Down Expand Up @@ -180,6 +194,7 @@ deploy_init_container_app() {
sed "s#{{ TEST_APP_NAMESPACE_NAME }}#$TEST_APP_NAMESPACE_NAME#g" |
sed "s#{{ AUTHENTICATOR_ID }}#$AUTHENTICATOR_ID#g" |
sed "s#{{ CONFIG_MAP_NAME }}#$TEST_APP_NAMESPACE_NAME#g" |
sed "s#{{ SERVICE_TYPE }}#$(app_service_type)#g" |
$cli create -f -

if [[ "$PLATFORM" == "openshift" ]]; then
Expand Down Expand Up @@ -217,6 +232,7 @@ deploy_init_container_app_with_host_outside_apps() {
sed "s#{{ TEST_APP_NAMESPACE_NAME }}#$TEST_APP_NAMESPACE_NAME#g" |
sed "s#{{ AUTHENTICATOR_ID }}#$AUTHENTICATOR_ID#g" |
sed "s#{{ CONFIG_MAP_NAME }}#$TEST_APP_NAMESPACE_NAME#g" |
sed "s#{{ SERVICE_TYPE }}#$(app_service_type)#g" |
$cli create -f -

if [[ "$PLATFORM" == "openshift" ]]; then
Expand Down Expand Up @@ -267,6 +283,7 @@ deploy_secretless_app() {
sed "s#{{ CONFIG_MAP_NAME }}#$TEST_APP_NAMESPACE_NAME#g" |
sed "s#{{ CONJUR_ACCOUNT }}#$CONJUR_ACCOUNT#g" |
sed "s#{{ CONJUR_APPLIANCE_URL }}#$conjur_appliance_url#g" |
sed "s#{{ SERVICE_TYPE }}#$(app_service_type)#g" |
$cli create -f -

if [[ "$PLATFORM" == "openshift" ]]; then
Expand Down
61 changes: 48 additions & 13 deletions 7_verify_authentication.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ set -euo pipefail

. utils.sh

init_bash_lib

RETRIES=150
# Seconds
RETRY_WAIT=2

# Dump some kubernetes resources if this script exits prematurely
KUBE_RESOURCE_DUMP_ON_EXIT=true

function finish {
readonly PIDS=(
"SIDECAR_PORT_FORWARD_PID"
Expand All @@ -16,6 +20,23 @@ function finish {
"SECRETLESS_PORT_FORWARD_PID"
)

if [[ "$KUBE_RESOURCE_DUMP_ON_EXIT" == "true" ]]; then
echo "Status of pods in namespace $TEST_APP_NAMESPACE_NAME:"
$cli get -n $TEST_APP_NAMESPACE_NAME pods
echo "Display pods in namespace $TEST_APP_NAMESPACE_NAME:"
$cli get -n $TEST_APP_NAMESPACE_NAME pods -o yaml
echo "Services:in namespace $TEST_APP_NAMESPACE_NAME:"
$cli get -n $TEST_APP_NAMESPACE_NAME svc
echo "ServiceAccounts:in namespace $TEST_APP_NAMESPACE_NAME:"
$cli get -n $TEST_APP_NAMESPACE_NAME serviceaccounts
echo "Deployments in namespace $TEST_APP_NAMESPACE_NAME:"
$cli get -n $TEST_APP_NAMESPACE_NAME deployments
if [[ "$PLATFORM" == "openshift" ]]; then
echo "DeploymentConfigs in namespace $TEST_APP_NAMESPACE_NAME:"
$cli get -n $TEST_APP_NAMESPACE_NAME deploymentconfigs
fi
fi

set +u

echo -e "\n\nStopping all port-forwarding"
Expand Down Expand Up @@ -73,22 +94,34 @@ if [[ "$PLATFORM" == "openshift" ]]; then
secretless_url="localhost:8083"
init_url_with_host_outside_apps="localhost:8084"
else
echo "Waiting for services to become available"
check_services(){
[[ -n "$(service_ip "test-app-summon-init")" ]] &&
[[ -n "$(service_ip "test-app-with-host-outside-apps-branch-summon-init")" ]] &&
[[ -n "$(service_ip "test-app-summon-sidecar")" ]] &&
[[ -n "$(service_ip "test-app-secretless")" ]]
}
bl_retry_constant "${RETRIES}" "${RETRY_WAIT}" check_services

init_url=$(service_ip test-app-summon-init):8080
init_url_with_host_outside_apps=$(service_ip test-app-with-host-outside-apps-branch-summon-init):8080
sidecar_url=$(service_ip test-app-summon-sidecar):8080
secretless_url=$(service_ip test-app-secretless):8080
if [[ "$TEST_APP_NODEPORT_SVCS" == "false" ]]; then
echo "Waiting for external IPs to become available"
check_services(){
[[ -n "$(external_ip "test-app-summon-init")" ]] &&
[[ -n "$(external_ip "test-app-with-host-outside-apps-branch-summon-init")" ]] &&
[[ -n "$(external_ip "test-app-summon-sidecar")" ]] &&
[[ -n "$(external_ip "test-app-secretless")" ]]
}
bl_retry_constant "${RETRIES}" "${RETRY_WAIT}" check_services

init_url=$(external_ip test-app-summon-init):8080
init_url_with_host_outside_apps=$(external_ip test-app-with-host-outside-apps-branch-summon-init):8080
sidecar_url=$(external_ip test-app-summon-sidecar):8080
secretless_url=$(external_ip test-app-secretless):8080
else
# Else assume NodePort service type. Use a URL of the form
# <any-node-IP>:<service-node-port>
# The IP address of any node in the cluster will work for NodePort access.
node_ip="$($cli get nodes -o jsonpath='{.items[0].status.addresses[0].address}')"
init_url="$node_ip:$(get_nodeport test-app-summon-init)"
init_url_with_host_outside_apps="$node_ip:$(get_nodeport test-app-with-host-outside-apps-branch-summon-init)"
sidecar_url="$node_ip:$(get_nodeport test-app-summon-sidecar)"
secretless_url="$node_ip:$(get_nodeport test-app-secretless)"
fi
fi

echo "Waiting for urls to be ready"

check_urls(){
(
curl -sS --connect-timeout 3 "$init_url" &&
Expand Down Expand Up @@ -135,3 +168,5 @@ curl "$sidecar_url"/pets

echo -e "\n\nQuerying secretless app\n"
curl "$secretless_url"/pets

KUBE_RESOURCE_DUMP_ON_EXIT=false
Loading

0 comments on commit e4f0461

Please sign in to comment.