This repository has been archived by the owner on Sep 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
xk_util.rake
197 lines (178 loc) · 8.39 KB
/
xk_util.rake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# This task rotates target args[:secret].
#
# New value for the secret can be set via env var TF_VAR_secret_name,
# otherwise new value will be generated automatically.
# Old secret value will be set to TF_VAR_secret_name_rotated until rotation is finished.
#
# Arbitrary command to execute after rotation can be set with :cmd argument.
task :rotate_secret, [:encryption_key, :secret, :cmd] => [:configure, :configure_secrets] do |taskname, args|
if args[:encryption_key].nil? || args[:encryption_key].size == 0
puts " ERROR: Argument :encryption_key not present!"
raise
elsif args[:secret].nil? || args[:secret].size == 0
puts " ERROR: Argument :secret not present!"
raise
end
if @secrets.collected_secrets[args[:encryption_key]].nil?
puts " ERROR: Encryption key '#{args[:encryption_key]}' does not exist!"
raise
elsif args[:secret] and ENV["TF_VAR_#{args[:secret]}"].nil?
puts " ERROR: Secret '#{args[:secret]}' does not exist!"
raise
end
Rake::Task["set_secrets"].invoke
ENV["TF_VAR_#{args[:secret]}_rotated"] = ENV["TF_VAR_#{args[:secret]}"]
ENV["TF_VAR_#{args[:secret]}"] = ""
rotate_secrets = true
@secrets.set_secrets(rotate_secrets)
sh_filter "#{@exekube_cmd} #{args[:cmd]}" if args[:cmd]
end
# This task rotates KMS key and associated secrets file for target args[:encryption_key].
task :rotate_secrets_key, [:encryption_key] => [:configure, :configure_secrets] do |taskname, args|
if args[:encryption_key].nil? || args[:encryption_key].size == 0
puts " ERROR: Argument :encryption_key not present!"
raise
end
if @secrets.collected_secrets[args[:encryption_key]].nil?
puts " ERROR: Encryption key '#{args[:encryption_key]}' does not exist!"
raise
end
Rake::Task["set_secrets"].invoke
new_version_id = @secrets.create_key_version(args[:encryption_key])
rotate_secrets = true
@secrets.set_secrets(rotate_secrets)
@secrets.disable_non_primary_key_versions(args[:encryption_key], new_version_id)
end
# This is an EXPERIMENTAL helper for moving between regions, but it is not very smart and it
# is strongly coupled with the gcp-secret-mgmt module (e.g. if resource names
# change there, they will also need to change here).
task :import_keyring => [:configure, :configure_secrets] do
# Remove and then import the Keyring
sh "#{@exekube_cmd} sh -c ' \
terragrunt state rm module.gcp-secret-mgmt.google_kms_key_ring.key_ring \
--terragrunt-working-dir /project/live/#{@env}/secret-mgmt &&\
terragrunt import module.gcp-secret-mgmt.google_kms_key_ring.key_ring \
projects/#{ENV["TF_VAR_project_id"]}/locations/#{ENV["TF_VAR_infra_region"]}/keyRings/#{ENV["TF_VAR_keyring_name"]} \
--terragrunt-working-dir /project/live/#{@env}/secret-mgmt \
'"
# Remove and then import the Keys
secrets_config = @secrets.load_secrets_config()
secrets_config["encryption_keys"].each_with_index do |key_name, index|
sh "#{@exekube_cmd} sh -c ' \
terragrunt state rm module.gcp-secret-mgmt.google_kms_crypto_key.encryption_keys[#{index}] \
--terragrunt-working-dir /project/live/#{@env}/secret-mgmt &&\
terragrunt import module.gcp-secret-mgmt.google_kms_crypto_key.encryption_keys[#{index}] \
projects/#{ENV["TF_VAR_project_id"]}/locations/#{ENV["TF_VAR_infra_region"]}/keyRings/#{ENV["TF_VAR_keyring_name"]}/cryptoKeys/#{key_name} \
--terragrunt-working-dir /project/live/#{@env}/secret-mgmt \
'"
end
end
# This task destroy all keys except current one for projectowner's SA.
# It does nothing in case local SA credentials not present.
task :destroy_sa_keys => [@gcp_creds_file, :configure_extra_tf_vars] do
sh "
if [ \"$TF_VAR_serviceaccount_key\" != \"\" ] && [ -f $TF_VAR_serviceaccount_key ]; then \
existing_keys=$(gcloud iam service-accounts keys list \
--iam-account projectowner@\"$TF_VAR_project_id\".iam.gserviceaccount.com \
--managed-by user | grep -oE \"^[a-z0-9]+\"); \
current_key=$(cat $TF_VAR_serviceaccount_key 2>/dev/null | jq -r '.private_key_id'); \
for key in $existing_keys; do \
if [ \"$key\" != \"$current_key\" ]; then \
yes | gcloud iam service-accounts keys delete \
--iam-account projectowner@\"$TF_VAR_project_id\".iam.gserviceaccount.com $key; \
fi \
done
fi
"
end
task :display_cluster_state => [:configure, :configure_secrets, :set_secrets] do
puts
puts "**************"
puts "Cluster state:"
puts "**************"
puts
cmds = [
"kubectl -n gpii get all -o wide",
"kubectl -n gpii get pv -o wide",
"kubectl -n gpii get pvc -o wide",
"kubectl -n gpii get events -o wide",
"kubectl -n locust get all -o wide",
"kubectl -n locust get events -o wide",
# The 'terraform' disks are root partitions. Filter those out to reduce
# some clutter.
"gcloud compute disks list --filter 'NOT name:gke-k8s-cluster-terraform' --format json",
]
dev_cmds = [
# Only run this in dev because a) we expect to see weird behavior in
# ephemeral clusters, not long-lived clusters and b) 'kubectl exec'
# generates an alert, which is not ok in stg/prd.
"kubectl exec --namespace gpii couchdb-couchdb-0 -c couchdb -- curl -s http://$TF_VAR_secret_couchdb_admin_username:$TF_VAR_secret_couchdb_admin_password@127.0.0.1:5984/_membership | jq .",
"kubectl exec --namespace gpii couchdb-couchdb-1 -c couchdb -- curl -s http://$TF_VAR_secret_couchdb_admin_username:$TF_VAR_secret_couchdb_admin_password@127.0.0.1:5984/_membership | jq .",
]
if @env == "dev"
cmds.concat(dev_cmds)
end
for cmd in cmds
sh "timeout -t 30 #{cmd}"
end
end
task :display_universal_image_info => [:configure] do
sh "#{@exekube_cmd} sh -c ' \
UNIVERSAL_CI_URL=\"https://ci.gpii.net\";
UNIVERSAL_REPO=\"https://github.com/gpii/universal\";
RELEASE_JOB_URL=\"$UNIVERSAL_CI_URL/job/docker-gpii-universal-master-release\";
UPSTREAM_JOB_URL=\"$UNIVERSAL_CI_URL/job/docker-gpii-universal-master\";
LOOKUP_BUILDS=\"20\";
PREFERENCES_IMAGE_SHA=$(kubectl -n gpii get deployment preferences -o json 2> /dev/null | jq -r \".spec.template.spec.containers[0].image\" | grep -o \"sha256:.*\");
if [ \"$?\" != \"0\" ]; then
echo
echo \"Unable to retrieve data from K8s cluster!\";
echo \"Try running \\\`rake display_cluster_state\\\` for debug info.\";
echo
exit 1;
fi
echo
echo \"Preferences image SHA:\";
echo \"$PREFERENCES_IMAGE_SHA\";
RELEASE_BUILD=$(curl -f \"$RELEASE_JOB_URL/lastBuild/api/json\" 2> /dev/null | jq -r \".id\");
RELEASE_BUILD_LIMIT=$((RELEASE_BUILD - LOOKUP_BUILDS));
while [ \"$RELEASE_BUILD\" != \"\" ] && [ \"$RELEASE_BUILD\" -gt \"$RELEASE_BUILD_LIMIT\" ]; do
SHA_FOUND=$(curl -f \"$RELEASE_JOB_URL/$RELEASE_BUILD/consoleText\" 2> /dev/null | grep -so \"$PREFERENCES_IMAGE_SHA\" || true);
if [ \"$SHA_FOUND\" == \"$PREFERENCES_IMAGE_SHA\" ]; then
UPSTREAM_JOB_NUMBER=$(curl -f \"$RELEASE_JOB_URL/$RELEASE_BUILD/api/json\" 2> /dev/null | jq -r \".actions[] | select (.causes[0].upstreamBuild != null) | .causes[0].upstreamBuild\");
GITHUB_LINK=\"$UNIVERSAL_REPO/commit/$(curl -f \"$UPSTREAM_JOB_URL/$UPSTREAM_JOB_NUMBER/api/json\" 2> /dev/null | jq -r \".actions[] | select (.lastBuiltRevision.SHA1 != null) | .lastBuiltRevision.SHA1\")\";
echo
echo \"Release job that built the image:\";
echo \"$RELEASE_JOB_URL/$RELEASE_BUILD\";
echo
echo \"Upstream job:\";
echo \"$UPSTREAM_JOB_URL/$UPSTREAM_JOB_NUMBER\";
RELEASE_BUILD=1;
fi
RELEASE_BUILD=$((RELEASE_BUILD - 1));
done
if [ \"$GITHUB_LINK\" == \"\" ]; then
echo
echo \"Unable to get CI data for target image SHA in last $LOOKUP_BUILDS builds!\";
echo
exit 1;
fi
echo
echo \"Commit to gpii/universal that triggered image build:\";
echo \"$GITHUB_LINK\";
echo
'", verbose: false
end
# This task attaches the owner role to the current user
task :grant_owner_role => [@gcp_creds_file, :configure_extra_tf_vars] do
sh "
gcloud projects add-iam-policy-binding \"$TF_VAR_project_id\" --member user:\"$TF_VAR_auth_user_email\" --role roles/owner
"
end
# This task removes the owner role to the current user
task :revoke_owner_role => [@gcp_creds_file, :configure_extra_tf_vars] do
sh "
gcloud projects remove-iam-policy-binding \"$TF_VAR_project_id\" --member user:\"$TF_VAR_auth_user_email\" --role roles/owner
"
end
# vim: et ts=2 sw=2: