From c28ff3b0a24cf69e48499e001e366f482340ba0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pab=C3=B3n?= Date: Fri, 18 Sep 2020 09:36:48 -0700 Subject: [PATCH] pxc-useradd added as component --- component/useradd/pxc-useradd | 220 ++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100755 component/useradd/pxc-useradd diff --git a/component/useradd/pxc-useradd b/component/useradd/pxc-useradd new file mode 100755 index 00000000..226d521a --- /dev/null +++ b/component/useradd/pxc-useradd @@ -0,0 +1,220 @@ +#!/bin/bash +# +# Copyright © 2020 Portworx +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# USE ONLY FOR DEVELOPMENT +# Implementation of the blog: https://www.openlogic.com/blog/granting-user-access-your-kubernetes-cluster + +function fail() { + echo "$1" + exit 1 +} + +# run() from BATS testing system +function runorfail() { + local origFlags="$-" + set +eET + local origIFS="$IFS" + echo $@ + output="$("$@" 2>&1)" + if [ $? -ne 0 ]; then + fail "Failed to execute ${*}" + fi + IFS=$'\n' lines=($output) + IFS="$origIFS" + set "-$origFlags" +} + +# Creats a user in Kubernetes only. Use createUserKubeconfig() instead to create a full +# kubeconfig for the new user. +function createUser() { + local username="$1" + local location="$2" + + runorfail openssl req -new -newkey rsa:4096 -nodes \ + -keyout ${location}/${username}-k8s.key \ + -out ${location}/${username}-k8s.csr \ + -subj "/CN=${username}/O=${ORGANIZATION}" + + cat < ${location}/${username}-kubeconfig.crt + if [ $? -ne 0 ] ; then + fail "Failed to get certificate for user" + fi +} + +# Creates a new Kubernetes user only able to access their namespace with the +# same name. The kubeconfig for this user must be passed in. +function createUserKubeconfig() { + local user="$1" + local location="$2" + local cafile="$3" + local kubeconfig="${location}/${user}-kubeconfig.conf" + + echo ">>> Registering ${user}" + + # create certs for user + createUser "$user" "$location" + + # Create namespace + if ! kubectl --context=$CONTEXT get namespace ${NAMESPACE} > /dev/null 2>&1 ; then + runorfail kubectl create namespace ${NAMESPACE} --context=$CONTEXT + fi + + # Enable user to use their namespace + runorfail kubectl create rolebinding ${user}-admin \ + --context=$CONTEXT \ + --namespace=${NAMESPACE} \ + --clusterrole=admin \ + --user=${user} + + # Enable token to have API access + runorfail kubectl create rolebinding default-access-rest \ + --context=$CONTEXT \ + --namespace=${NAMESPACE} \ + --clusterrole=admin \ + --serviceaccount=${user}:default + + echo ">>> Creating ${kubeconfig}" + + # Create config for user + kubectl config set-cluster $cluster \ + --server=$address \ + --certificate-authority=$cafile \ + --embed-certs=true \ + --kubeconfig=${kubeconfig} + kubectl config set-credentials \ + ${user} \ + --client-certificate=${location}/${user}-kubeconfig.crt \ + --client-key=${location}/${user}-k8s.key \ + --embed-certs \ + --kubeconfig=${kubeconfig} + kubectl --kubeconfig=${kubeconfig} config set-context ${user} \ + --cluster=${cluster} \ + --user=${user} \ + --namespace=${NAMESPACE} + kubectl --kubeconfig=${kubeconfig} config use-context ${user} + + echo "" + echo ">>> Kubeconfig ready: ${kubeconfig}" +} + +function usage() { + echo " +Creates a new Kubernetes user and creating a new kubeconfig + +Usage: + kubectl pxc useradd [flags] + +Flags: + -h, --help help for create + --name Name of user + --namespace Specify the new namespace for the user (default: user name) + --organization Name of the organization (default: portworx) + --px-secret Name of secret to contain the Portworx token (default: px-user-token) + --outdir Directory where to place the created files (default: .) + --kubeconfig Specify the kubeconfig to use (optional) + --context Specify the context to use (optional) +" + exit 1 +} + +parsed=$(getopt -o h -n "kubectl pxc useradd" --long name:,namespace:,help,organization:,px-secret:,outdir:,context:,kubeconfig: -- "$@" ) +if [ $? -ne 0 ] ; then + usage +fi + +eval set -- "$parsed" + +NAME="" +ORGANIZATION="portworx" +PXSECRET="px-user-token" +NAMESPACE="" +CONTEXT="" +OUTDIR="." + +while true; do + case "$1" in + --organization) ORGANIZATION="$2"; shift 2 ;; + --namespace) NAMESPACE="$2"; shift 2 ;; + --name) NAME="$2"; shift 2 ;; + --px-secret) PXSECRET="$2"; shift 2 ;; + --outdir) OUTDIR="$2"; shift 2 ;; + --context) CONTEXT="$2"; shift 2;; + --kubeconfig) export KUBECONFIG="$2"; shift 2;; + -h | --help) usage;; + --) shift; break ;; + *) usage; break ;; + esac +done + +if [ "$NAME" = "" ] ; then + echo "Must provide a user name" + exit 1 +fi + +if [ "$NAMESPACE" = "" ] ; then + NAMESPACE="$NAME" +fi + +if [ "$CONTEXT" = "" ] ; then + CONTEXT=$(kubectl config view --raw -o jsonpath="{.current-context}") +fi + +if [ "$OUTDIR" != "." -a ! -d "$OUTDIR" ] ; then + runorfail mkdir $OUTDIR +fi + +# Check that kubectl config works +if ! kubectl --context=$CONTEXT version --short=true > /dev/null 2>&1 ; then + fail "kubectl failed to communicate with Kubernetes. Is the kubeconfig setup correctly?" +fi + +# Use the current context cluster address and CA Cert data +cafile=/tmp/cacert.$$ +cluster=$(kubectl config view --raw -o jsonpath="{.contexts[?(@.name==\"$CONTEXT\")].context.cluster}") +address=$(kubectl config view --raw -o jsonpath="{.clusters[?(@.name==\"$cluster\")].cluster.server}") +cacert_data=$(kubectl config view --raw -o jsonpath="{.clusters[?(@.name==\"$cluster\")].cluster.certificate-authority-data}") +if [ -z ${cacert_data} ] ; then + fail "No CA cert data found in cluster ${cluster}" +elif [ ! -f ${cacert_data} ] ; then + echo ${cacert_data} | base64 -d > $cafile + delete_cafile=$cafile +else + cafile=$cacert_data +fi + +createUserKubeconfig "${NAME}" "${OUTDIR}" "${cafile}" + +# Cleanup +if [ -f $delete_cafile ] ; then + rm -f $delete_cafile > /dev/null 2>&1 +fi \ No newline at end of file