|
#!/usr/bin/env bash |
|
set -x |
|
set -e |
|
|
|
# Define kubectl action (apply|delete) |
|
ACTION="apply" |
|
# Config directory to store configs |
|
CONFIG_DIR="/tmp" |
|
# Account for user creation that does not exist local to provisioning |
|
USERNAME="JoeBob" |
|
# Convert to lowercase as Kubernetes requires namespaces, etc. to be lowercase |
|
USERNAME=$(echo "$USERNAME" | awk '{print tolower($0)}') |
|
# Location for certs, configs, etc. to be stored |
|
KUBE_CONFIG_DIR="$CONFIG_DIR/$USERNAME/.kube" |
|
|
|
# Create Kube config directory if it doesn't exist |
|
if [[ ! -d "$KUBE_CONFIG_DIR" ]]; then |
|
mkdir -p "$KUBE_CONFIG_DIR" |
|
fi |
|
|
|
# User's KUBECONFIG file |
|
USER_KUBECONFIG="$KUBE_CONFIG_DIR/config" |
|
|
|
# List of environments to create accounts within |
|
environments=("development" "production") |
|
|
|
# Loop through environments and create user configs |
|
for environment in "${environments[@]}"; do |
|
# Set Kube environment to environment |
|
KUBE_ENV=$environment |
|
|
|
# Set user cert naming based on environment |
|
# The user will have different certs for each cluster environment |
|
USER_CLIENT_CRT="$KUBE_CONFIG_DIR/$USERNAME-$KUBE_ENV.pem" |
|
USER_CLIENT_KEY="$KUBE_CONFIG_DIR/$USERNAME-$KUBE_ENV-key.pem" |
|
USER_CLIENT_CSR="$KUBE_CONFIG_DIR/$USERNAME-$KUBE_ENV.csr" |
|
USER_NAMESPACE="$USERNAME-$KUBE_ENV" |
|
|
|
# Path to CFSSL JSON template |
|
PRIVATE_KEY_TEMPLATE="private_key_template.json" |
|
|
|
# Path to cluster admin configs for managing each cluster |
|
KUBECONFIG_ENV="$HOME/.kube/tet_k8s_$KUBE_ENV.yml" |
|
|
|
# If client certificate signing request does not exist: create and apply |
|
if [[ ! -f "$USER_CLIENT_CSR" ]]; then |
|
envsubst <"$PRIVATE_KEY_TEMPLATE" | cfssl genkey - | cfssljson -bare "${USER_CLIENT_CSR%.*}" |
|
cat <<EOF | kubectl apply --kubeconfig="$KUBECONFIG_ENV" -f - |
|
apiVersion: certificates.k8s.io/v1beta1 |
|
kind: CertificateSigningRequest |
|
metadata: |
|
name: $USERNAME |
|
spec: |
|
username: $USERNAME |
|
groups: |
|
- system:authenticated |
|
request: $(cat "$USER_CLIENT_CSR" | base64 | tr -d '\n') |
|
usages: |
|
- digital signature |
|
- key encipherment |
|
- client auth |
|
EOF |
|
# Approve new certificate request in cluster |
|
kubectl certificate approve "$USERNAME" --kubeconfig="$KUBECONFIG_ENV" |
|
fi |
|
|
|
# Get user certificate from cluster if it does not exist |
|
if [[ ! -f "$USER_CLIENT_CRT" ]]; then |
|
kubectl get csr "$USERNAME" --kubeconfig="$KUBECONFIG_ENV" -o jsonpath='{.status.certificate}' | base64 --decode >"$USER_CLIENT_CRT" |
|
fi |
|
|
|
# Set Kube cluster name including environment |
|
KUBE_CLUSTER_NAME="$(kubectl config view --kubeconfig="$KUBECONFIG_ENV" -o jsonpath='{.clusters[0].name}')-$KUBE_ENV" |
|
# Set cluster server to connect to |
|
KUBE_CLUSTER_SERVER="$(kubectl config view --kubeconfig="$KUBECONFIG_ENV" -o jsonpath='{.clusters[0].cluster.server}')" |
|
# Set cluster certificate file |
|
KUBE_CLUSTER_CA_CERT="$KUBE_CONFIG_DIR/$KUBE_CLUSTER_NAME-ca.pem" |
|
|
|
# Get cluster certificate if it does not exist and save it |
|
if [[ ! -f $KUBE_CLUSTER_CA_CERT ]]; then |
|
kubectl config view --kubeconfig="$KUBECONFIG_ENV" -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' --raw | base64 --decode - >"$KUBE_CLUSTER_CA_CERT" |
|
fi |
|
|
|
# Generate user's KUBECONFIG |
|
kubectl config set-cluster "$KUBE_CLUSTER_NAME" --server="$KUBE_CLUSTER_SERVER" --certificate-authority="$KUBE_CLUSTER_CA_CERT" --kubeconfig="$USER_KUBECONFIG" --embed-certs |
|
kubectl config set-credentials "$USERNAME"-"$KUBE_ENV" --client-certificate="$USER_CLIENT_CRT" --client-key="$USER_CLIENT_KEY" --embed-certs --kubeconfig="$USER_KUBECONFIG" |
|
kubectl config set-context "$KUBE_CLUSTER_NAME" --cluster="$KUBE_CLUSTER_NAME" --namespace="$USER_NAMESPACE" --user="$USERNAME"-"$KUBE_ENV" --kubeconfig="$USER_KUBECONFIG" |
|
|
|
# Manage users cluster namespace |
|
cat <<EOF | kubectl $ACTION --kubeconfig="$KUBECONFIG_ENV" -f - |
|
apiVersion: v1 |
|
kind: Namespace |
|
metadata: |
|
name: $USER_NAMESPACE |
|
EOF |
|
|
|
# Manage users role for their namespace |
|
cat <<EOF | kubectl $ACTION --kubeconfig="$KUBECONFIG_ENV" -f - |
|
apiVersion: rbac.authorization.k8s.io/v1 |
|
kind: Role |
|
metadata: |
|
name: list-deployments |
|
namespace: $USER_NAMESPACE |
|
rules: |
|
- apiGroups: [ apps ] |
|
resources: [ deployments ] |
|
verbs: [ get, list ] |
|
EOF |
|
|
|
# Manage users cluster role |
|
cat <<EOF | kubectl $ACTION --kubeconfig="$KUBECONFIG_ENV" -f - |
|
apiVersion: rbac.authorization.k8s.io/v1 |
|
kind: ClusterRole |
|
metadata: |
|
name: list-deployments |
|
rules: |
|
- apiGroups: [ apps ] |
|
resources: [ deployments ] |
|
verbs: [ get, list ] |
|
EOF |
|
|
|
# Manage users role binding for cluster role |
|
cat <<EOF | kubectl $ACTION --kubeconfig="$KUBECONFIG_ENV" -f - |
|
apiVersion: rbac.authorization.k8s.io/v1 |
|
kind: RoleBinding |
|
metadata: |
|
name: $USERNAME |
|
namespace: $USER_NAMESPACE |
|
roleRef: |
|
apiGroup: rbac.authorization.k8s.io |
|
kind: ClusterRole |
|
name: edit |
|
subjects: |
|
- apiGroup: rbac.authorization.k8s.io |
|
kind: User |
|
name: $USERNAME |
|
EOF |
|
|
|
done |