Skip to content

Commit 4778e7e

Browse files
authored
Merge pull request #5 from jetstack/add-smoke-tests
Add smoke tests
2 parents 34b7a9c + 95b450e commit 4778e7e

File tree

14 files changed

+511
-60
lines changed

14 files changed

+511
-60
lines changed

Dockerfile

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,28 @@
1-
# Doc: https://github.com/GoogleCloudPlatform/marketplace-k8s-app-tools/blob/master/docs/building-deployer-helm.md#build-your-deployer-container
1+
# This Dockerfile allows us to create a "deployer" image. The deployer
2+
# image, using this "ombuild" base image, will contain our Marketplace
3+
# application's Helm chart and will be in charge of doing the "helm install"
4+
# (which is the only thing the deployer image ever does).
5+
#
6+
# See:
7+
# https://github.com/GoogleCloudPlatform/marketplace-k8s-app-tools/blob/4335f9/docs/building-deployer-helm.md#build-your-deployer-container
8+
29
FROM gcr.io/cloud-marketplace-tools/k8s/deployer_helm/onbuild
10+
11+
# The schema,yaml and chart/ have already been added thanks to the
12+
# "onbuild" Dockerfile:
13+
# https://github.com/GoogleCloudPlatform/marketplace-k8s-app-tools/blob/4335f9/marketplace/deployer_helm_base/onbuild/Dockerfile#L4-L12
14+
#
15+
# Since the deployer image must only contain compressed charts, i.e.,
16+
# chart/chart.tar.gz (which is created by the "onbuild" Docker image), and
17+
# a data-test/chart/chart.tar.gz. That is why we need to tar the chart in
18+
# data-test.
19+
COPY data-test/schema.yaml /data-test/schema.yaml
20+
COPY data-test/chart /tmp/data-test/chart.tmp
21+
RUN cd /tmp/data-test \
22+
&& mv chart.tmp/* chart \
23+
&& tar -czvf /tmp/data-test/chart.tar.gz chart \
24+
&& mv chart.tar.gz /data-test/chart/
25+
26+
27+
# If you wonder what magic is this, take a look at:
28+
# https://github.com/GoogleCloudPlatform/marketplace-k8s-app-tools/blob/4335f9/marketplace/deployer_helm_base/onbuild/Dockerfile#L16-L20

README.md

Lines changed: 167 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,57 @@
11

22
# jsp-gcm
33

4+
This is the repository that holds the configuration for our Google
5+
Marketplace solution, [jetstack-secure-for-cert-manager][].
6+
47
**Content:**
58

9+
- [Technical considerations](#technical-considerations)
610
- [Installing and manually testing the deployer](#installing-and-manually-testing-the-deployer)
711
- [Testing and releasing the deployer using Google Cloud Build](#testing-and-releasing-the-deployer-using-google-cloud-build)
12+
- [Debugging deployer and smoke-tests when run in Cloud Build](#debugging-deployer-and-smoke-tests-when-run-in-cloud-build)
813
- [Updating the upstream cert-manager chart version](#updating-the-upstream-cert-manager-chart-version)
914

15+
## Technical considerations
16+
17+
**Retagging cert-manager images:**
18+
19+
In order to abide by the [schema.md][], which states:
20+
21+
> When users deploy your app from Google Cloud Marketplace, the final image
22+
> names may be different, but they will follow **the same release tag** and
23+
> name prefix rule.
24+
25+
This means we do re-tag all our images (cert-manager, cas-issuer, ubbagent,
26+
preflight-agent) using a unified tag that is distinct from the cert-manager
27+
regular version. We call this version the "application version". In the
28+
following example, the application version is `1.0.0` although the
29+
cert-manager-controller is `1.1.0`:
30+
31+
```sh
32+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager:1.0.0
33+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/cert-manager-acmesolver:1.0.0
34+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/cert-manager-cainjector:1.0.0
35+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/cert-manager-google-cas-issuer:1.0.0
36+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/cert-manager-webhook:1.0.0
37+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/deployer:1.0.0
38+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/preflight:1.0.0
39+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/ubbagent:1.0.0
40+
```
41+
42+
**cert-manager-controller is the "primary image":**
43+
44+
The "primary" image is pushed to the "root" of the registry, for example:
45+
46+
```sh
47+
# The primary image "cert-manager-controller":
48+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager:1.0.0
49+
50+
# All other images:
51+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/deployer:1.0.0
52+
gcr.io/jetstack-public/jetstack-secure-for-cert-manager/cert-manager-webhook:1.0.0
53+
```
54+
1055
## Installing and manually testing the deployer
1156

1257
In order to have the google-cas-issuer working, we need to enable [workload
@@ -18,45 +63,42 @@ gcloud container clusters create foo --region us-east1 --num-nodes=1 --preemptib
1863
--workload-pool=$(gcloud config get-value project | tr ':' '/').svc.id.goog
1964
```
2065

21-
This application re-tags the various images (cert-manager, cas-issuer, ubbagent, preflight-agent) using
22-
a unified tag that we call "application version". Although it does not appear to be a requirement for
23-
releasing to the Google Marketplace, we were not able to set "default" tags for each image and thus
24-
resolved to just having a unified tag; this means that we will have to keep this difference in tags when
25-
supporting [jetstack-secure-for-cert-manager][].
26-
27-
[jetstack-secure-for-cert-manager]: https://console.cloud.google.com/partner/editor/jetstack-public/jetstack-secure-for-cert-manager?project=jetstack-public
28-
29-
Re-publish the images to the project:
66+
Now, re-publish the images to the project:
3067

3168
```sh
3269
export REGISTRY=gcr.io/$(gcloud config get-value project | tr ':' '/')
33-
export APP_NAME=jetstack-secure
70+
export SOLUTION=jetstack-secure-for-cert-manager
71+
3472
docker pull quay.io/jetstack/cert-manager-controller:v1.1.0
73+
docker pull quay.io/jetstack/cert-manager-acmesolver:v1.1.0
3574
docker pull quay.io/jetstack/cert-manager-cainjector:v1.1.0
3675
docker pull quay.io/jetstack/cert-manager-webhook:v1.1.0
3776
docker pull quay.io/jetstack/cert-manager-google-cas-issuer:0.1.0
3877
docker pull quay.io/jetstack/preflight:0.1.27
39-
docker tag quay.io/jetstack/cert-manager-controller:v1.1.0 $REGISTRY/$APP_NAME/cert-manager-controller:1.0.0
40-
docker tag quay.io/jetstack/cert-manager-cainjector:v1.1.0 $REGISTRY/$APP_NAME/cert-manager-cainjector:1.0.0
41-
docker tag quay.io/jetstack/cert-manager-webhook:v1.1.0 $REGISTRY/$APP_NAME/cert-manager-webhook:1.0.0
42-
docker tag quay.io/jetstack/cert-manager-google-cas-issuer:latest $REGISTRY/$APP_NAME/cert-manager-google-cas-issuer:1.0.0
43-
docker tag quay.io/jetstack/preflight:latest $REGISTRY/$APP_NAME/cert-manager-preflight:1.0.0
44-
docker push $REGISTRY/$APP_NAME/cert-manager-controller:1.0.0
45-
docker push $REGISTRY/$APP_NAME/cert-manager-cainjector:1.0.0
46-
docker push $REGISTRY/$APP_NAME/cert-manager-webhook:1.0.0
47-
docker push $REGISTRY/$APP_NAME/cert-manager-google-cas-issuer:1.0.0
48-
docker push $REGISTRY/$APP_NAME/cert-manager-preflight:1.0.0
78+
docker pull gcr.io/cloud-marketplace-tools/metering/ubbagent:latest
79+
80+
docker tag quay.io/jetstack/cert-manager-controller:v1.1.0 $REGISTRY/$SOLUTION:1.0.0
81+
docker tag quay.io/jetstack/cert-manager-acmesolver:v1.1.0 $REGISTRY/$SOLUTION/cert-manager-acmesolver:1.0.0
82+
docker tag quay.io/jetstack/cert-manager-cainjector:v1.1.0 $REGISTRY/$SOLUTION/cert-manager-cainjector:1.0.0
83+
docker tag quay.io/jetstack/cert-manager-webhook:v1.1.0 $REGISTRY/$SOLUTION/cert-manager-webhook:1.0.0
84+
docker tag quay.io/jetstack/cert-manager-google-cas-issuer:latest $REGISTRY/$SOLUTION/cert-manager-google-cas-issuer:1.0.0
85+
docker tag quay.io/jetstack/preflight:latest $REGISTRY/$SOLUTION/preflight:1.0.0
86+
docker pull gcr.io/cloud-marketplace-tools/metering/ubbagent:latest $REGISTRY/$SOLUTION/ubbagent:1.0.0
87+
88+
docker push $REGISTRY/$SOLUTION:1.0.0
89+
docker push $REGISTRY/$SOLUTION/cert-manager-acmesolver:1.0.0
90+
docker push $REGISTRY/$SOLUTION/cert-manager-cainjector:1.0.0
91+
docker push $REGISTRY/$SOLUTION/cert-manager-webhook:1.0.0
92+
docker push $REGISTRY/$SOLUTION/cert-manager-google-cas-issuer:1.0.0
93+
docker push $REGISTRY/$SOLUTION/preflight:1.0.0
94+
docker push $REGISTRY/$SOLUTION/ubbagent:1.0.0
4995
```
5096

51-
> Note: although cert-manager's tags are of the form "v1.1.0", we
52-
> use the same JSP version tag for all the Google Marketplace images,
53-
> for consistency with other marketplace packages.
54-
5597
Then, build and push the deployer image:
5698

5799
```sh
58-
docker build --tag $REGISTRY/$APP_NAME/deployer .
59-
docker push $REGISTRY/$APP_NAME/deployer
100+
docker build --tag $REGISTRY/$SOLUTION/deployer:1.0.0 .
101+
docker push $REGISTRY/$SOLUTION/deployer:1.0.0
60102
```
61103

62104
Finally, use `mpdev` to install jetstack-secure to the `test-ns` namespace:
@@ -67,7 +109,7 @@ docker run gcr.io/cloud-marketplace-tools/k8s/dev cat /scripts/dev > /tmp/mpdev
67109

68110
kubectl create ns test-ns
69111
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/marketplace-k8s-app-tools/master/crd/app-crd.yaml
70-
mpdev install --deployer=$REGISTRY/$APP_NAME/deployer --parameters='{"name": "test-ns", "namespace": "test"}'
112+
mpdev install --deployer=$REGISTRY/$SOLUTION/deployer --parameters='{"name": "test-ns", "namespace": "test"}'
71113
```
72114

73115
Now, we need to have access to a CAS root. To create a "root" certificate
@@ -166,7 +208,33 @@ Requirements before running `gcloud builds`:
166208
--workload-pool=$(gcloud config get-value project | tr ':' '/').svc.id.goog
167209
```
168210

169-
2. Go to [IAM and Admin > Permissions for
211+
2. A Google CAS root and subordinate CA as well as a Google service account
212+
that will be "attached" to the Kubernetes service account that will be
213+
created by the deployer:
214+
215+
```sh
216+
gcloud beta privateca roots create my-ca --subject="CN=root,O=my-ca"
217+
gcloud beta privateca subordinates create my-sub-ca --issuer=my-ca --location us-east1 --subject="CN=intermediate,O=my-ca,OU=my-sub-ca"
218+
gcloud iam service-accounts create sa-google-cas-issuer
219+
gcloud beta privateca subordinates add-iam-policy-binding my-sub-ca \
220+
--role=roles/privateca.certificateRequester \
221+
--member=serviceAccount:sa-google-cas-issuer@$(gcloud config get-value project | tr ':' '/').iam.gserviceaccount.com
222+
gcloud iam service-accounts add-iam-policy-binding sa-google-cas-issuer@$(gcloud config get-value project | tr ':' '/').iam.gserviceaccount.com \
223+
--role roles/iam.workloadIdentityUser \
224+
--member "serviceAccount:$(gcloud config get-value project | tr ':' '/').svc.id.goog[test-ns/test-google-cas-issuer-serviceaccount-name]"
225+
```
226+
227+
> Note: the last step which is adding the annotation to the
228+
> google-cas-issuer Kubernetes service account is done in
229+
> `cloudbuild.yml`. The annotation will look like:
230+
>
231+
> ```yaml
232+
> metadata:
233+
> annotations:
234+
> iam.gke.io/gcp-service-account=sa-google-cas-issuer@PROJECT_ID.iam.gserviceaccount.com
235+
> ```
236+
237+
3. Go to [IAM and Admin > Permissions for
170238
project](https://console.cloud.google.com/iam-admin/iam) and configure
171239
the `[email protected]` service account with the
172240
following roles so that it has permission to deploy RBAC configuration
@@ -175,7 +243,7 @@ Requirements before running `gcloud builds`:
175243
- `Kubernetes Engine Admin`
176244
- `Storage Object Admin`
177245
178-
3. Create a bucket that has the same name as your project. To create it,
246+
4. Create a bucket that has the same name as your project. To create it,
179247
run:
180248
181249
```sh
@@ -189,7 +257,73 @@ gcloud builds submit --timeout 1800s --config cloudbuild.yaml \
189257
--substitutions _CLUSTER_NAME=$GKE_CLUSTER_NAME,_CLUSTER_LOCATION=$GKE_CLUSTER_LOCATION
190258
```
191259
192-
This will also verify the application using the [Google Cloud Marketplace verification tool](https://github.com/GoogleCloudPlatform/marketplace-k8s-app-tools/blob/c5899a928a2ac8d5022463c82823284a9e63b177/scripts/verify).
260+
This will run [`mpdev verify`]([Google Cloud Marketplace verification
261+
tool](https://github.com/GoogleCloudPlatform/marketplace-k8s-app-tools/blob/c5899a928a2ac8d5022463c82823284a9e63b177/scripts/verify)),
262+
which runs [smoke tests](/smoke-test.yaml).
263+
264+
Note that debugging `mpdev verify` is quite tricky. In order to inspect the
265+
state of the namespace created by `mpdev verify`, we can artificially pause
266+
`mpdev verify` when it tries to [delete the application](https://github.com/GoogleCloudPlatform/marketplace-k8s-app-tools/blob/4ecf535/scripts/verify#L301-L304):
267+
268+
### Debugging deployer and smoke-tests when run in Cloud Build
269+
270+
There is no official spec for the `smoke-test.yaml` file, although there is
271+
the example [suite.yaml](https://github.com/GoogleCloudPlatform/marketplace-testrunner/blob/4245fa9/specs/testdata/suite.yaml):
272+
273+
```yaml
274+
actions:
275+
- name: {{ .Env.TEST_NAME }}
276+
httpTest:
277+
url: http://{{ .Var.MainVmIp }}:9012
278+
expect:
279+
statusCode:
280+
equals: 200
281+
statusText:
282+
contains: OK
283+
bodyText:
284+
html:
285+
title:
286+
contains: Hello World!
287+
- name: Update success variable
288+
gcp:
289+
setRuntimeConfigVar:
290+
runtimeConfigSelfLink: https://runtimeconfig.googleapis.com/v1beta1/projects/my-project/configs/my-config
291+
variablePath: status/success
292+
base64Value: c3VjY2Vzcwo=
293+
- name: Can echo to stdout and stderr
294+
bashTest:
295+
script: |-
296+
echo "Text1"
297+
>2& echo "Text2"
298+
expect:
299+
exitCode:
300+
equals: 0
301+
notEquals: 1
302+
stdout:
303+
contains: "Text1"
304+
notContains: "Foo"
305+
matches: "T.xt1"
306+
stderr:
307+
contains: "Text2"
308+
notContains: "Foo"
309+
matches: "T.xt2"
310+
```
311+
312+
Unfortunately, the `stdout` or `stderr` output won't be shown whenever a
313+
step fails. Reason: the
314+
[logic in bash.go](https://github.com/GoogleCloudPlatform/marketplace-testrunner/blob/4245fa9/tests/bash.go#L88-L96)
315+
first checks the status code and returns if mismatch, then checks the
316+
stdout and returns if mismatch, and finally checks stderr.
317+
318+
**Workaround:**: add to `smoke-test.yaml` a step that hangs, e.g.:
319+
320+
```yaml
321+
- name: hang for debugging purposes
322+
bashTest:
323+
script: sleep 1200
324+
```
325+
326+
then you can `exec` into the snoke-test pod and debug around.
193327
194328
## Updating the upstream cert-manager chart version
195329
@@ -201,3 +335,6 @@ bump the version of the cert-manager chart in requirements.yaml. Then:
201335
helm repo add jetstack https://charts.jetstack.io
202336
helm dependency build chart/jetstacksecure-mp
203337
```
338+
339+
[schema.md]: https://github.com/GoogleCloudPlatform/marketplace-k8s-app-tools/blob/d9d3a6f/docs/schema.md
340+
[jetstack-secure-for-cert-manager]: https://console.cloud.google.com/partner/editor/jetstack-public/jetstack-secure-for-cert-manager?project=jetstack-public

chart/jetstacksecure-mp/charts/google-cas-issuer/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ maintainers:
1414
- name: "Jetstack Ltd"
1515
1616
url: "https://www.jetstack.io/"
17-
appVersion: "0.1.0"
17+
appVersion: "0.1.0"

chart/jetstacksecure-mp/charts/google-cas-issuer/templates/crds.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{{ if .Values.installCRDs }}
1+
{{- if .Values.installCRDs }}
22
apiVersion: apiextensions.k8s.io/v1beta1
33
kind: CustomResourceDefinition
44
metadata:
@@ -243,4 +243,4 @@ status:
243243
plural: ""
244244
conditions: []
245245
storedVersions: []
246-
{{ end }}
246+
{{- end }}

chart/jetstacksecure-mp/charts/google-cas-issuer/values.yaml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,18 @@ imagePullSecrets: {}
1818
securityContext: {}
1919
podSecurityContext: {}
2020

21-
resources:
22-
{}
23-
# requests:
24-
# cpu: 10m
25-
# memory: 32Mi
26-
2721
nodeSelector: {}
2822
affinity: {}
2923
tolerations: {}
3024

3125
prometheus:
3226
# Enables the creation of the ClusterIP service.
3327
enabled: true
28+
29+
resources:
30+
limits:
31+
cpu: 200m
32+
memory: 200Mi
33+
requests:
34+
cpu: 200m
35+
memory: 200Mi

chart/jetstacksecure-mp/charts/preflight/templates/deployment.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{ if not "disabled-for-now-due-to-missing-configmap" }}
12
apiVersion: apps/v1
23
kind: Deployment
34
metadata:
@@ -29,7 +30,7 @@ spec:
2930
secretName: agent-credentials
3031
containers:
3132
- name: {{ .Chart.Name }}
32-
image: "{{ .Values.image.repository }}:v{{ .Chart.AppVersion }}"
33+
image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}"
3334
args:
3435
- "agent"
3536
- "-c"
@@ -47,3 +48,4 @@ spec:
4748
readOnly: true
4849
resources:
4950
{{- toYaml .Values.resources | nindent 10 }}
51+
{{- end }}

chart/jetstacksecure-mp/templates/application.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ metadata:
1212
spec:
1313
descriptor:
1414
type: Jetstack Secure Platform
15-
version: "1.0.0"
15+
version: "1.1.0-gcm.1" # Must be the same as in the schema.yaml file.
1616
selector:
1717
matchLabels:
1818
app.kubernetes.io/name: "{{ .Release.Name }}"

chart/jetstacksecure-mp/values.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ preflight:
3131

3232
ubbagent:
3333
# reportingSecretName: "some-secret-name"
34-
image: {}
34+
image:
35+
{}
3536
# tag: 1.1.0
3637
# repository: gcr.io/jetstack-public/ubbagent

0 commit comments

Comments
 (0)