@leverege/build-tools 2.43.12 → 2.45.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/helmup.sh CHANGED
@@ -43,6 +43,7 @@ AUXILIARY=(
43
43
  pubsub-pulse
44
44
  push-notifier
45
45
  pusher
46
+ transponder-dh
46
47
  vin-decoder-server
47
48
  )
48
49
 
@@ -53,6 +54,7 @@ SYSTEM=(
53
54
  postgres
54
55
  timescale-db
55
56
  preemptible-killer
57
+ reflector
56
58
  reloader
57
59
  traefik
58
60
  velero
@@ -84,14 +86,31 @@ CATNAMI
84
86
  addHelmRepo bitnami $BITNAMI_URL
85
87
  }
86
88
 
89
+ # Accepts 3 paramaters - 1 mandatory.
90
+ # bindWorkloadIdentity <Service Account> <Namespace> <Target Service Account>
91
+ # where:
92
+ # Service Account = SA to receive the binding
93
+ # Namespace = optional - uses the default namespace if unspecified
94
+ # Target Service Account = SA to receive the workload binding
95
+ #
96
+ # We typically have a one to one binding for SA and target SA (and target seems
97
+ # like a poor choice of word), so for api-server running in the default namespace:
98
+ # bindWorkloadIdentity api-server
99
+ #
100
+ # but in the case of services like transponder which has various flavors but
101
+ # only the single trandponder services account we woul do:
102
+ # bindWorkloadIdentity transponder default tranponder-rt
103
+ #
87
104
  function bindWorkloadIdentity() {
88
105
  SVC_ACCT=$1
89
106
  NAMESPACE=${2:-default}
107
+ BOUND_SVC_ACCT=${3:-$SVC_ACCT}
90
108
  SVC_ACCT_EMAIL="${SVC_ACCT}@${GCP_PROJECT_ID}.iam.gserviceaccount.com"
91
109
 
92
110
  cat<<WORKLOAD_ID
93
111
  Binding workload identity IAM policy
94
- Service Account : `color g $SVC_ACCT`
112
+ Target Svc Acct : `color g $SVC_ACCT`
113
+ Bound Svc Acct : `color g $BOUND_SVC_ACCT`
95
114
  Project : `color g $GCP_PROJECT_ID`
96
115
  Namespace : `color g $NAMESPACE`
97
116
  Service Email : `color g $SVC_ACCT_EMAIL`
@@ -100,38 +119,40 @@ WORKLOAD_ID
100
119
 
101
120
  gcloud iam service-accounts add-iam-policy-binding \
102
121
  --project $GCP_PROJECT_ID \
103
- --member "serviceAccount:$GCP_PROJECT_ID.svc.id.goog[${NAMESPACE}/${SVC_ACCT}]" \
122
+ --member "serviceAccount:$GCP_PROJECT_ID.svc.id.goog[${NAMESPACE}/${BOUND_SVC_ACCT}]" \
104
123
  --role roles/iam.workloadIdentityUser $SVC_ACCT_EMAIL
105
124
  warnOnError $? "gcloud workload identity binding may have failed"
125
+
126
+ sleep 2 # give the policy a chance to propagate
106
127
 
107
128
  # Verify the Kubernetes SA and create it if necessary
108
- printf "\nChecking for the $NAMESPACE/$SVC_ACCT k8s SA\n"
129
+ printf "\nChecking for the `color g $NAMESPACE/$SVC_ACCT` k8s SA\n"
109
130
  kubectl get sa -n $NAMESPACE $SVC_ACCT &> $DEVNULL
110
131
  if [[ $? -eq 1 ]];
111
132
  then
112
- printf "Creating the k8s $SVC_ACCT SA in $NAMESPACE\n"
133
+ printf "Creating the k8s `color g $SVC_ACCT` SA in `color g $NAMESPACE`\n"
113
134
  kubectl create sa $SVC_ACCT -n $NAMESPACE
114
135
  fi
115
136
 
116
- printf "\nAnnotating the k8s SA $NAMESPACE/@$SVC_ACCT\n"
137
+ printf "\nAnnotating the k8s SA `color g $NAMESPACE/@$SVC_ACCT`\n"
117
138
  kubectl annotate serviceaccount $SVC_ACCT \
118
139
  --namespace $NAMESPACE --overwrite \
119
140
  "iam.gke.io/gcp-service-account=$SVC_ACCT_EMAIL"
120
141
  warnOnError $? "Failed to annotate service account $NAMESPACE/$SVC_ACCT - things may fail"
121
- }
122
142
 
123
- function generatePassword() {
124
- RANDOMPW=`openssl rand -base64 12`
125
- echo $RANDOMPW
143
+ sleep 2 # give the annotation a chance to propagate before exiting
126
144
  }
127
145
 
128
146
  function createNamespaceIfNeeded() {
129
147
  # Check the namespace exists in kubernetes
130
- kubectl get namespace $1 &> $DEVNULL
148
+ local NS=$1
149
+ kubectl get namespace $NS &> $DEVNULL
131
150
  if [[ $? -eq 1 ]];
132
151
  then
133
- printf "\n*** Creating $1 namespace ***\n\n"
134
- kubectl create namespace $1
152
+ printf "\n*** Creating $NS namespace ***\n\n"
153
+ kubectl create namespace $NS
154
+ # annotate to tell the network policy to allow redis access from NS
155
+ kubectl label namespaces $NS redis=external
135
156
  fi
136
157
  }
137
158
 
@@ -456,6 +477,65 @@ NEED_MANAGED_SECRET
456
477
  fi
457
478
  }
458
479
 
480
+ # See => https://github.com/emberstack/kubernetes-reflector
481
+ function reflectSecretIntoNamespaces() {
482
+ local SECRET="$1"
483
+ local SOURCE_NS="$2"
484
+ local REFLECT_INTO_NS="$3"
485
+
486
+ printf "\nReflecting secret `color y "$SOURCE_NS/$SECRET"` into `color g "$REFLECT_INTO_NS"` namespace\n"
487
+
488
+ kubectl annotate secrets $SECRET -n $SOURCE_NS \
489
+ reflector.v1.k8s.emberstack.com/reflection-allowed="true" &> $DEVNULL
490
+ kubectl annotate secrets $SECRET -n $SOURCE_NS \
491
+ reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces="$REFLECT_INTO_NS" &> $DEVNULL
492
+
493
+ cat<<REFLECTED_SECRET | kubectl apply -f -
494
+ apiVersion: v1
495
+ kind: Secret
496
+ metadata:
497
+ name: $SECRET
498
+ namespace: "$REFLECT_INTO_NS"
499
+ annotations:
500
+ reflector.v1.k8s.emberstack.com/reflects: "$SOURCE_NS/$SECRET"
501
+ REFLECTED_SECRET
502
+ }
503
+
504
+ # This function is used to randomly generate the postgresql database passwords
505
+ # for the postgres and imagine users in a cnpg operator configuration. Since
506
+ # the resultant passwords will live in the cnpg-operands namespace they will
507
+ # be mirrored to the default namespace via the reflector service. Lastly, the
508
+ # service account will have workload identity bound to it in the cnpg-operands
509
+ # namespace.
510
+ function initializeCnpgOperand() {
511
+ local CNPG_SERVICE="$1"
512
+ local CNPG_NAMESPACE="cnpg-operands"
513
+ local CNPG_SVC_ACCT="$CNPG_NAMESPACE-sa"
514
+ local IMAGINE_PW_NAME="$CNPG_SERVICE-imagine-pw"
515
+ local POSTGRES_PW_NAME="$CNPG_SERVICE-postgres-pw"
516
+
517
+ printf "\nCreating imagine db password for `color g $CNPG_SERVICE`\n"
518
+ kubectl create secret generic -n $CNPG_NAMESPACE "$IMAGINE_PW_NAME" \
519
+ --from-literal=username="imagine" \
520
+ --from-literal=password="$(generatePassword)" &> $DEVNULL
521
+ warnOnError $? "the `color y $IMAGINE_PW_NAME` secret may already exist"
522
+
523
+ # reflect the secret to default namespace
524
+ reflectSecretIntoNamespaces $IMAGINE_PW_NAME $CNPG_NAMESPACE "default"
525
+
526
+ printf "\nCreating postgres db password for `color g $CNPG_SERVICE`\n"
527
+ kubectl create secret generic -n $CNPG_NAMESPACE "$POSTGRES_PW_NAME" \
528
+ --from-literal=username="postgres" \
529
+ --from-literal=password="$(generatePassword)" &> $DEVNULL
530
+ warnOnError $? "the `color y $POSTGRES_PW_NAME` secret may already exist"
531
+
532
+ # reflect the secret to default namespace
533
+ reflectSecretIntoNamespaces $POSTGRES_PW_NAME $CNPG_NAMESPACE "default"
534
+
535
+ printf "\nBinding `color g $CNPG_SERVICE` to the `color y "$CNPG_SVC_ACCT"` SA\n"
536
+ bindWorkloadIdentity $CNPG_SVC_ACCT $CNPG_NAMESPACE $CNPG_SERVICE
537
+ }
538
+
459
539
  function installCnpgOperatorEnvironment() {
460
540
  # See => https://github.com/cloudnative-pg/charts
461
541
 
@@ -469,24 +549,29 @@ function installCnpgOperatorEnvironment() {
469
549
  kubectl delete serviceaccounts -n $CNPG_NAMESPACE $CNPG_SVC_ACCT &> $DEVNULL
470
550
  gcloud --quiet iam service-accounts delete $CNPG_SVC_EMAIL --project $GCP_PROJECT_ID&> $DEVNULL
471
551
 
552
+ # Create the operands namespace and annotate to allow redis access
472
553
  createNamespaceIfNeeded $CNPG_NAMESPACE
473
554
 
474
555
  # Create GCP SA and bind policies
475
- printf "\nCreating the gcloud $CNPG_SVC_ACCT service account (SA)\n"
556
+ printf "\nCreating the gcloud `color g $CNPG_SVC_ACCT` service account (SA)\n"
476
557
  gcloud iam service-accounts create $CNPG_SVC_ACCT \
477
558
  --project "$GCP_PROJECT_ID" \
478
559
  --description "CNPG Operands SA" \
479
560
  --display-name "CNPG Operands SA" &> $DEVNULL
480
- warnOnError $? "the GCP SA $CNPG_SVC_ACCT may already exist"
561
+ warnOnError $? "the GCP SA `color y $CNPG_SVC_ACCT` may already exist"
481
562
 
482
563
  CNPG_OPS_ROLE="cnpg.operands"
483
- printf "\nCreating the $CNPG_OPS_ROLE IAM role\n"
564
+ printf "\nCreating the `color g $CNPG_OPS_ROLE` IAM role\n"
484
565
  ## Attach roles
485
566
  ROLE_PERMISSIONS=(
486
567
  iam.serviceAccounts.actAs
568
+ iam.serviceAccounts.get
487
569
  iam.serviceAccounts.getAccessToken
570
+ iam.serviceAccounts.getOpenIdToken
571
+ iam.serviceAccounts.implicitDelegation
572
+ iam.serviceAccounts.list
488
573
  iam.serviceAccounts.signBlob
489
- orgpolicy.policy.get
574
+ iam.serviceAccounts.signJwt
490
575
  resourcemanager.projects.get
491
576
  storage.buckets.create
492
577
  storage.buckets.get
@@ -507,7 +592,7 @@ function installCnpgOperatorEnvironment() {
507
592
  if [ $? -ne 0 ];
508
593
  then
509
594
  # assume error is that role exists so try updating instead
510
- printf "\nUpdating roles on the SA\n"
595
+ printf "\nUpdating the permissions on the `color g $CNPG_OPS_ROLE` IAM role\n"
511
596
  gcloud iam roles update $CNPG_OPS_ROLE \
512
597
  --project $GCP_PROJECT_ID \
513
598
  --title "CNPG Operands" \
@@ -515,22 +600,45 @@ function installCnpgOperatorEnvironment() {
515
600
  fi
516
601
  warnOnError $? "Failed to add roles to $CNPG_OPS_ROLE - perhaps they already exist?"
517
602
 
518
- printf "\nBinding IAM role to the SA\n"
603
+ printf "\nBinding IAM role to the SA `color g $CNPG_SVC_EMAIL`\n"
519
604
  gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
520
- --project $GCP_PROJECT_ID \
521
- --member serviceAccount:$CNPG_SVC_EMAIL \
522
- --condition 'None' \
523
- --role "roles/owner" &> $DEVNULL # temp bind to Owner
524
- # --role "roles/storage.admin" &> $DEVNULL
525
- # --role "roles/owner" &> $DEVNULL
605
+ --member="serviceAccount:$CNPG_SVC_EMAIL" \
606
+ --role "roles/storage.admin" &> $DEVNULL
526
607
  # --role projects/$GCP_PROJECT_ID/roles/$CNPG_OPS_ROLE &> $DEVNULL
608
+ # --role "roles/storage.admin" &> $DEVNULL
527
609
  warnOnError $? "gcloud problem binding IAM policy"
528
610
 
529
- sleep 2 # give the IAM binding a chance to complete before moving on
611
+ printf "\nBinding IAM the Token Creator role to the SA `color g $CNPG_SVC_EMAIL`\n"
612
+ gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
613
+ --member="serviceAccount:$CNPG_SVC_EMAIL" \
614
+ --role="roles/iam.serviceAccountTokenCreator"
615
+
616
+ # workload binding will be performed by each cnpg operand on startup
617
+
618
+ BARMAN_BUCKET="gs://$GCP_PROJECT_ID-barman"
619
+ gsutil ls -p $GCP_PROJECT_ID -b $BARMAN_BUCKET &> $DEVNULL
620
+ if [ "$?" -eq 0 ];
621
+ then
622
+ printf "\nBarman bucket `color g "$BARMAN_BUCKET"` already exists - skipping recreation\n"
623
+ else
624
+ printf "\nCreating a bucket for barman backups: `color g $BARMAN_BUCKET`\n"
625
+ gsutil mb -l $GCE_REGION $BARMAN_BUCKET &> $DEVNULL
626
+ gsutil iam ch serviceAccount:$CNPG_SVC_EMAIL:objectAdmin $BARMAN_BUCKET
627
+ gsutil ubla set on $BARMAN_BUCKET # uniform bucket access
628
+ fi
530
629
 
531
- bindWorkloadIdentity $CNPG_SVC_ACCT $CNPG_NAMESPACE
630
+ # define the snapshot storage class
631
+ printf "\nApplying the CNPG VolumeSnapshotClass `color g cnpg-snapshotclass` definition\n"
632
+ cat<<EOSNAPSC | kubectl apply -f -
633
+ apiVersion: snapshot.storage.k8s.io/v1
634
+ kind: VolumeSnapshotClass
635
+ metadata:
636
+ name: cnpg-snapshotclass
637
+ driver: pd.csi.storage.gke.io
638
+ deletionPolicy: Delete
639
+ EOSNAPSC
532
640
 
533
- gsutil iam ch serviceAccount:$CNPG_SVC_EMAIL:objectAdmin gs://$GCP_PROJECT_ID-barman
641
+ sleep 2 # hold up processing for a moment to allow IAM mods to propagate
534
642
  }
535
643
 
536
644
  function installVeleroEnvironment() {
@@ -546,10 +654,10 @@ function installVeleroEnvironment() {
546
654
 
547
655
  ## Create a bucket
548
656
  BUCKET="$GCP_PROJECT_ID-velero-$VELERO_HELM_CHART"
549
- GCE_REGION=`overwhelm -k GCE_REGION`
550
657
  printf "\nCreating storage bucket `color g $BUCKET` in `color g $GCE_REGION`\n"
551
658
  gsutil mb -l $GCE_REGION gs://$BUCKET/ &> $DEVNULL
552
659
  warnOnError $? "Bucket failed to create or already exists - go check it\n"
660
+ gsutil ubla set on gs://$BUCKET &> $DEVNULL
553
661
 
554
662
  ## Create a service account
555
663
  printf "\nCreating the service account\n"
@@ -692,7 +800,7 @@ function doInstall() {
692
800
 
693
801
  local INVOKED_AS=`basename $0`
694
802
  # set the dry-run flag on what
695
- [ "$INVOKED_AS" == "helmwhat" ] && HELM_WHAT="--dry-run --debug"
803
+ [ "$INVOKED_AS" == "helmwhat" ] && HELM_WHAT="--dry-run --debug" && K8S_WHAT="--dry-run=server -o yaml"
696
804
 
697
805
  # helminit is used to redeploy an existing service
698
806
  if [ "$INVOKED_AS" == "helminit" ] && [[ $(isLeveregeService $SERVICE) -eq 1 ]];
@@ -754,6 +862,16 @@ CATBACKUP
754
862
  installDefaultConfigs
755
863
  ;;
756
864
 
865
+ db-postgres-*|db-timescale-*)
866
+ if [ ! -d $SERVICE ];
867
+ then
868
+ # this code only executes on the first deployment
869
+ initializeCnpgOperand $SERVICE
870
+ bootstrapLocalSetup $SERVICE
871
+ kubectl apply -f $SERVICE/$SERVICE.yaml $K8S_WHAT
872
+ fi
873
+ ;;
874
+
757
875
  db-curator-dh)
758
876
  # db-curator-dh is a variant of db-curator with diff controlled in values-local.yaml
759
877
  HELMUP="helm upgrade --install $SERVICE leverege/db-curator --values $SERVICE/values.yaml $CHARTVER $HELM_WHAT"
@@ -806,6 +924,13 @@ CATBACKUP
806
924
  bootstrapLocalSetup $SERVICE
807
925
  ;;
808
926
 
927
+ "reflector")
928
+ showInstalling "Secrets/ConfigMap Namespace Reflector"
929
+ addHelmRepo emberstack https://emberstack.github.io/helm-charts
930
+ helm upgrade --install reflector emberstack/reflector
931
+ removeHelmRepo emberstack
932
+ ;;
933
+
809
934
  "reloader")
810
935
  showInstalling "Stakater ConfigMap Reloader"
811
936
  addHelmRepo stakater https://stakater.github.io/stakater-charts
@@ -924,6 +1049,8 @@ overwhelm
924
1049
 
925
1050
  # The project id is used in a lot of places so just set it here
926
1051
  GCP_PROJECT_ID="$(getProjectIdFromK8sContext)"
1052
+ # Same for the region, but not as prevalent
1053
+ GCE_REGION=`overwhelm -k GCE_REGION`
927
1054
 
928
1055
  doInstall $@
929
1056
  cd - &> $DEVNULL
package/src/k8x.sh CHANGED
@@ -1,18 +1,21 @@
1
1
  #!/bin/bash
2
2
 
3
3
  cmd=${@:-"bash"}
4
+ ns="default"
4
5
 
5
6
  [ "$cmd" = "redis" ] || [ "$cmd" = "redis-cli" ] && FZFQ="--query=redis" && cmd='redis-cli'
6
7
 
7
8
  [ "$cmd" = "pgsql" ] && FZFQ="--query=postgresql" && cmd='psql -U postgres'
8
9
 
10
+ [ "$cmd" = "cnpg" ] && ns="cnpg-operands" && cmd="bash"
11
+
9
12
  [ -f overwhelm.yaml ] && [ -f package.json ] && npm run ahoy
10
13
 
11
14
  [ ! -x "$(command -v fzf)" ] && printf "\n***ERROR: Missing fzf fuzzy matcher => brew install fzf\n\n" && exit 1
12
15
 
13
- pod=$(kubectl -n default get pods -owide | fzf $FZFQ | awk '{print $1}')
16
+ pod=$(kubectl -n $ns get pods -owide | fzf $FZFQ | awk '{print $1}')
14
17
 
15
- kubecmd="kubectl exec -it $pod -- $cmd"
18
+ kubecmd="kubectl exec -n $ns -it $pod -- $cmd"
16
19
  echo " run=[${kubecmd}]"
17
20
 
18
21
  eval ${kubecmd}