diff --git a/deploy/common.sh b/deploy/common.sh new file mode 100644 index 000000000..042e4acac --- /dev/null +++ b/deploy/common.sh @@ -0,0 +1,4 @@ +function get_needed_roles() +{ + echo "roles/compute.storageAdmin roles/iam.serviceAccountUser projects/${PROJECT}/roles/gcp_compute_persistent_disk_csi_driver_custom_role" +} diff --git a/deploy/kubernetes/deploy-driver.sh b/deploy/kubernetes/deploy-driver.sh index 27c0c2fdc..533ee4a9a 100755 --- a/deploy/kubernetes/deploy-driver.sh +++ b/deploy/kubernetes/deploy-driver.sh @@ -16,6 +16,35 @@ set -o errexit readonly PKGDIR="${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver" readonly KUBEDEPLOY="${PKGDIR}/deploy/kubernetes" +. $(dirname $0)/../common.sh + +function check_service_account() +{ + # Using bash magic to parse JSON for IAM + # Grepping for a line with client email returning anything quoted after the colon + readonly IAM_NAME=$(grep -Po '"client_email": *\K"[^"]*"' ${GCE_PD_SA_DIR}/cloud-sa.json | tr -d '"') + # Grepping anything after the @ tell the first . as the project name + readonly PROJECT=$(grep -Po '.*@\K[^.]+'<<<${IAM_NAME}) + readonly GOTTEN_BIND_ROLES=$(gcloud projects get-iam-policy ${PROJECT} --flatten="bindings[].members" --format='table(bindings.role)' --filter="bindings.members:${IAM_NAME}") + readonly BIND_ROLES=$(get_needed_roles) + MISSING_ROLES=false + for role in ${BIND_ROLES} + do + if ! grep -q $role <<<${GOTTEN_BIND_ROLES} ; + then + echo "Missing role: $role" + MISSING_ROLES=true + fi + done + if [ "${MISSING_ROLES}" = true ]; + then + echo "Cannot deploy with missing roles in service account, please run setup-project.sh to setup Service Account" + exit 1 + fi +} + +check_service_account + if ! kubectl get secret cloud-sa; then kubectl create secret generic cloud-sa --from-file="${GCE_PD_SA_DIR}/cloud-sa.json" diff --git a/deploy/setup-project.sh b/deploy/setup-project.sh index 619d2d3aa..b0ac460ba 100755 --- a/deploy/setup-project.sh +++ b/deploy/setup-project.sh @@ -17,39 +17,67 @@ set -o nounset set -o errexit +. $(dirname $0)/common.sh + readonly PKGDIR="${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver" readonly KUBEDEPLOY="${PKGDIR}/deploy/kubernetes" -readonly BIND_ROLES="roles/compute.storageAdmin roles/iam.serviceAccountUser projects/${PROJECT}/roles/gcp_compute_persistent_disk_csi_driver_custom_role" +readonly BIND_ROLES=$(get_needed_roles) readonly IAM_NAME="${GCE_PD_SA_NAME}@${PROJECT}.iam.gserviceaccount.com" +# Check if SA exists +CREATE_SA=true +SA_JSON=$(gcloud iam service-accounts list --filter="name:${IAM_NAME}" --format="json") +if [ "[]" != "${SA_JSON}" ]; +then + CREATE_SA=false + echo "Service account ${IAM_NAME} exists. Would you like to create a new one (y) or reuse the existing one (n)" + read -p "(y/n)" -n 1 -r REPLY + echo + if [[ ${REPLY} =~ ^[Yy]$ ]]; + then + CREATE_SA=true + fi +fi + +if [ "${CREATE_SA}" = true ]; +then + # Delete Service Account Key + if [ -f "${GCE_PD_SA_DIR}/cloud-sa.json" ]; + then + rm "${GCE_PD_SA_DIR}/cloud-sa.json" + fi + # Delete ALL EXISTING Bindings + gcloud projects get-iam-policy "${PROJECT}" --format json > "${PKGDIR}/deploy/iam.json" + sed -i "/serviceAccount:${IAM_NAME}/d" "${PKGDIR}/deploy/iam.json" + gcloud projects set-iam-policy "${PROJECT}" "${PKGDIR}/deploy/iam.json" + rm -f "${PKGDIR}/deploy/iam.json" + # Delete Service Account + gcloud iam service-accounts delete "${IAM_NAME}" --project "${PROJECT}" --quiet || true + + # Create new Service Account + gcloud iam service-accounts create "${GCE_PD_SA_NAME}" --project "${PROJECT}" +fi + # Create or Update Custom Role if gcloud iam roles describe gcp_compute_persistent_disk_csi_driver_custom_role --project "${PROJECT}"; then gcloud iam roles update gcp_compute_persistent_disk_csi_driver_custom_role --quiet \ - --project "${PROJECT}" \ - --file "${PKGDIR}/deploy/gcp-compute-persistent-disk-csi-driver-custom-role.yaml" + --project "${PROJECT}" \ + --file "${PKGDIR}/deploy/gcp-compute-persistent-disk-csi-driver-custom-role.yaml" else gcloud iam roles create gcp_compute_persistent_disk_csi_driver_custom_role --quiet \ - --project "${PROJECT}" \ - --file "${PKGDIR}/deploy/gcp-compute-persistent-disk-csi-driver-custom-role.yaml" + --project "${PROJECT}" \ + --file "${PKGDIR}/deploy/gcp-compute-persistent-disk-csi-driver-custom-role.yaml" fi -# Delete Service Account Key -if [ -f "${GCE_PD_SA_DIR}/cloud-sa.json" ]; then - rm "${GCE_PD_SA_DIR}/cloud-sa.json" -fi -# Delete ALL EXISTING Bindings -gcloud projects get-iam-policy "${PROJECT}" --format json > "${PKGDIR}/deploy/iam.json" -sed -i "/serviceAccount:${IAM_NAME}/d" "${PKGDIR}/deploy/iam.json" -gcloud projects set-iam-policy "${PROJECT}" "${PKGDIR}/deploy/iam.json" -rm -f "${PKGDIR}/deploy/iam.json" -# Delete Service Account -gcloud iam service-accounts delete "${IAM_NAME}" --project "${PROJECT}" --quiet || true - -# Create new Service Account and Keys -gcloud iam service-accounts create "${GCE_PD_SA_NAME}" --project "${PROJECT}" +# Bind service account to roles for role in ${BIND_ROLES} do gcloud projects add-iam-policy-binding "${PROJECT}" --member serviceAccount:"${IAM_NAME}" --role ${role} done -gcloud iam service-accounts keys create "${GCE_PD_SA_DIR}/cloud-sa.json" --iam-account "${IAM_NAME}" --project "${PROJECT}" + +# Export key if needed +if [ "${CREATE_SA}" = true ]; +then + gcloud iam service-accounts keys create "${GCE_PD_SA_DIR}/cloud-sa.json" --iam-account "${IAM_NAME}" --project "${PROJECT}" +fi