diff --git a/pkg/apparchive/helm-v1beta2.go b/pkg/apparchive/helm-v1beta2.go index d89e7f00df..6621c679cc 100644 --- a/pkg/apparchive/helm-v1beta2.go +++ b/pkg/apparchive/helm-v1beta2.go @@ -146,6 +146,12 @@ func WriteV1Beta2HelmCharts(opts WriteV1Beta2HelmChartsOptions) error { return errors.Wrap(err, "failed to write values file") } + if !opts.ProcessImageOptions.RewriteImages { + // a registry is not configured (which means it's an online installation) + // there's no need to process/copy/track the images as they will be pulled from the internet. + continue + } + chartImages, err := findV1Beta2HelmChartImages(opts, &helmChart, chartDir) if err != nil { return errors.Wrap(err, "failed to find chart images") @@ -167,11 +173,14 @@ func WriteV1Beta2HelmCharts(opts WriteV1Beta2HelmChartsOptions) error { return errors.Wrap(err, "failed to update installation images") } - if !opts.ProcessImageOptions.RewriteImages || opts.ProcessImageOptions.IsAirgap { - // if an on-prem registry is not configured (which means it's an online installation) - // there's no need to process/copy the images as they will be pulled from their original registries or through the replicated proxy. - // if an on-prem registry is configured, but it's an airgap installation, we also don't need to process/copy the images - // as they will be pushed from the airgap bundle. + if !opts.ProcessImageOptions.CopyImages { + // registry is read-only, skip copying images. + continue + } + + if opts.ProcessImageOptions.IsAirgap { + // a registry is configured but it's an airgap installation. + // we don't need to process/copy the images as they will be pushed from the airgap bundle. continue } diff --git a/pkg/pull/pull.go b/pkg/pull/pull.go index 830f1b33ca..2feccaaca2 100644 --- a/pkg/pull/pull.go +++ b/pkg/pull/pull.go @@ -363,7 +363,7 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { if err := kotsutil.WriteKotsKinds(renderedKotsKindsMap, u.GetKotsKindsDir(writeUpstreamOptions)); err != nil { return "", errors.Wrap(err, "failed to write the rendered kots kinds") } - if processImageOptions.RewriteImages && processImageOptions.IsAirgap { + if processImageOptions.CopyImages && processImageOptions.IsAirgap { // if this is an airgap install, we still need to process the images if err := image.CopyAirgapImages(processImageOptions, log); err != nil { return "", errors.Wrap(err, "failed to copy airgap images") diff --git a/pkg/tests/pull/cases/required-helm-values/testcase.yaml b/pkg/tests/pull/cases/required-helm-values/testcase.yaml new file mode 100644 index 0000000000..32e8a5ee3e --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/testcase.yaml @@ -0,0 +1,11 @@ +Name: test required helm values +PullOptions: + Namespace: app-namespace + ExcludeAdminConsole: true + Silent: true + LocalPath: cases/required-helm-values/upstream + RootDir: cases/required-helm-values/results + SharedPassword: dummy-pass + RewriteImages: false + Downstreams: + - this-cluster \ No newline at end of file diff --git a/pkg/tests/pull/cases/required-helm-values/upstream/kots-app.yaml b/pkg/tests/pull/cases/required-helm-values/upstream/kots-app.yaml new file mode 100644 index 0000000000..d10ce3862d --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/upstream/kots-app.yaml @@ -0,0 +1,8 @@ +apiVersion: kots.io/v1beta1 +kind: Application +metadata: + name: my-app + annotations: + kots.io/exclude: "true" +spec: + title: my-app diff --git a/pkg/tests/pull/cases/required-helm-values/upstream/my-required-chart-0.1.0.tgz b/pkg/tests/pull/cases/required-helm-values/upstream/my-required-chart-0.1.0.tgz new file mode 100644 index 0000000000..a8db59cd89 Binary files /dev/null and b/pkg/tests/pull/cases/required-helm-values/upstream/my-required-chart-0.1.0.tgz differ diff --git a/pkg/tests/pull/cases/required-helm-values/upstream/my-required-chart.yaml b/pkg/tests/pull/cases/required-helm-values/upstream/my-required-chart.yaml new file mode 100644 index 0000000000..a9b030ec94 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/upstream/my-required-chart.yaml @@ -0,0 +1,18 @@ +apiVersion: kots.io/v1beta2 +kind: HelmChart +metadata: + name: my-required-chart + annotations: + kots.io/exclude: "true" +spec: + chart: + name: my-required-chart + chartVersion: 0.1.0 + releaseName: my-required-chart-release + values: + requiredvalue: this is a required value + optionalValues: + - when: 'repl{{ "true" }}' + recursiveMerge: true + values: + my-optional-value: my-optional-value diff --git a/pkg/tests/pull/cases/required-helm-values/upstream/userdata/config.yaml b/pkg/tests/pull/cases/required-helm-values/upstream/userdata/config.yaml new file mode 100644 index 0000000000..fbbf7d0972 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/upstream/userdata/config.yaml @@ -0,0 +1,10 @@ +apiVersion: kots.io/v1beta1 +kind: ConfigValues +metadata: + creationTimestamp: null + name: my-app +spec: + values: + hostname: + value: "my-app.somebigbank.com" +status: {} diff --git a/pkg/tests/pull/cases/required-helm-values/upstream/userdata/license.yaml b/pkg/tests/pull/cases/required-helm-values/upstream/userdata/license.yaml new file mode 100644 index 0000000000..25cc45c08b --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/upstream/userdata/license.yaml @@ -0,0 +1,47 @@ +apiVersion: kots.io/v1beta1 +kind: License +metadata: + name: testcustomer +spec: + appSlug: my-app + channelID: 1vusIYZLAVxMG6q760OJmRKj5i5 + channelName: My Channel + customerName: Test Customer + endpoint: https://replicated.app + entitlements: + bool_field: + title: Bool Field + value: true + valueType: Boolean + expires_at: + description: License Expiration + title: Expiration + value: "2030-07-27T00:00:00Z" + valueType: String + hidden_field: + isHidden: true + title: Hidden Field + value: this is secret + valueType: String + int_field: + title: Int Field + value: 123 + valueType: Integer + string_field: + title: StringField + value: single line text + valueType: String + text_field: + title: Text Field + value: |- + multi + line + text + valueType: Text + isAirgapSupported: true + isGitOpsSupported: true + isSnapshotSupported: true + licenseID: 1vusOokxAVp1tkRGuyxnF23PJcq + licenseSequence: 7 + licenseType: prod + signature: eyJsaWNlbnNlRGF0YSI6ImV5SmhjR2xXWlhKemFXOXVJam9pYTI5MGN5NXBieTkyTVdKbGRHRXhJaXdpYTJsdVpDSTZJa3hwWTJWdWMyVWlMQ0p0WlhSaFpHRjBZU0k2ZXlKdVlXMWxJam9pZEdWemRHTjFjM1J2YldWeUluMHNJbk53WldNaU9uc2liR2xqWlc1elpVbEVJam9pTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54SWl3aWJHbGpaVzV6WlZSNWNHVWlPaUp3Y205a0lpd2lZM1Z6ZEc5dFpYSk9ZVzFsSWpvaVZHVnpkQ0JEZFhOMGIyMWxjaUlzSW1Gd2NGTnNkV2NpT2lKdGVTMWhjSEFpTENKamFHRnVibVZzU1VRaU9pSXhkblZ6U1ZsYVRFRldlRTFITm5FM05qQlBTbTFTUzJvMWFUVWlMQ0pqYUdGdWJtVnNUbUZ0WlNJNklrMTVJRU5vWVc1dVpXd2lMQ0pzYVdObGJuTmxVMlZ4ZFdWdVkyVWlPamNzSW1WdVpIQnZhVzUwSWpvaWFIUjBjSE02THk5eVpYQnNhV05oZEdWa0xtRndjQ0lzSW1WdWRHbDBiR1Z0Wlc1MGN5STZleUppYjI5c1gyWnBaV3hrSWpwN0luUnBkR3hsSWpvaVFtOXZiQ0JHYVdWc1pDSXNJblpoYkhWbElqcDBjblZsTENKMllXeDFaVlI1Y0dVaU9pSkNiMjlzWldGdUluMHNJbVY0Y0dseVpYTmZZWFFpT25zaWRHbDBiR1VpT2lKRmVIQnBjbUYwYVc5dUlpd2laR1Z6WTNKcGNIUnBiMjRpT2lKTWFXTmxibk5sSUVWNGNHbHlZWFJwYjI0aUxDSjJZV3gxWlNJNklqSXdNekF0TURjdE1qZFVNREE2TURBNk1EQmFJaXdpZG1Gc2RXVlVlWEJsSWpvaVUzUnlhVzVuSW4wc0ltaHBaR1JsYmw5bWFXVnNaQ0k2ZXlKMGFYUnNaU0k2SWtocFpHUmxiaUJHYVdWc1pDSXNJblpoYkhWbElqb2lkR2hwY3lCcGN5QnpaV055WlhRaUxDSjJZV3gxWlZSNWNHVWlPaUpUZEhKcGJtY2lMQ0pwYzBocFpHUmxiaUk2ZEhKMVpYMHNJbWx1ZEY5bWFXVnNaQ0k2ZXlKMGFYUnNaU0k2SWtsdWRDQkdhV1ZzWkNJc0luWmhiSFZsSWpveE1qTXNJblpoYkhWbFZIbHdaU0k2SWtsdWRHVm5aWElpZlN3aWMzUnlhVzVuWDJacFpXeGtJanA3SW5ScGRHeGxJam9pVTNSeWFXNW5SbWxsYkdRaUxDSjJZV3gxWlNJNkluTnBibWRzWlNCc2FXNWxJSFJsZUhRaUxDSjJZV3gxWlZSNWNHVWlPaUpUZEhKcGJtY2lmU3dpZEdWNGRGOW1hV1ZzWkNJNmV5SjBhWFJzWlNJNklsUmxlSFFnUm1sbGJHUWlMQ0oyWVd4MVpTSTZJbTExYkhScFhHNXNhVzVsWEc1MFpYaDBJaXdpZG1Gc2RXVlVlWEJsSWpvaVZHVjRkQ0o5ZlN3aWFYTkJhWEpuWVhCVGRYQndiM0owWldRaU9uUnlkV1VzSW1selIybDBUM0J6VTNWd2NHOXlkR1ZrSWpwMGNuVmxMQ0pwYzFOdVlYQnphRzkwVTNWd2NHOXlkR1ZrSWpwMGNuVmxmWDA9IiwiaW5uZXJTaWduYXR1cmUiOiJleUpzYVdObGJuTmxVMmxuYm1GMGRYSmxJam9pYUhneE1XTXZUR1ozUTNoVE5YRmtRWEJGU1hGdVRrMU9NMHBLYTJzNFZHZFhSVVpzVDFKVlJ6UjJjR1YzZEZoV1YzbG1lamRZY0hBd1ExazJZamRyUVRSS2N6TklhR3d3YkZJMFdUQTFMemN2UVVkQ2FEZFZNSGczUkhaTVozUXpVM00wYm5GTFZTdFhXRXBTVHpKWVFVRnZSME4xZFRWR1RGcHJRVWhYY1RSUVFtMXphSFY2Y1ZsdmNucHhlbGhGWVZWVlpFUlVkVXhDTW1nNWFIZ3dXRWhQUmxwUk16bHVkbTlPUjJaT2R5OTRTVmRaZEhSUGRYZHZhMncyTVZsb1JVeFZlRmQxU1ZSRmMwTlVhM2xtTVRNd09IazVSbFJzWlRKeVYyZEVlSEZNYTBSUFNXVXlPRWwzUzJSQkwySXdWVUl5VEZGbVRWcHdWemwyUTNCSkwybHlWek5uYmpaeU5WWjNWMjB2U1dweWJtNDNSelJrVmpadVYzcFRkMGhQUTJSdWEwMTRNRXQ1VVVOa0wxQjFaWEpUYjNSdVEwOXRTMDEzWlRSTGJqaERkMU5YVVRRNGRURkRNbTFpV1VzeGRYTlpOM1YzUFQwaUxDSndkV0pzYVdOTFpYa2lPaUl0TFMwdExVSkZSMGxPSUZCVlFreEpReUJMUlZrdExTMHRMVnh1VFVsSlFrbHFRVTVDWjJ0eGFHdHBSemwzTUVKQlVVVkdRVUZQUTBGUk9FRk5TVWxDUTJkTFEwRlJSVUZ6TkhKdlVIcDFhV1JNZVhOMmIxWTJkemxhTkZ4dVdHRmliME5tWTJNeGFHZFZhQ3N3V1VkS2NFNURSVXhyTjBaTFF5OTJhemR6ZERsR05tY3dUMjlrU0VSbGVYZFJXa2hLZFU1TVpsUnNRbEJHUTJOaU5seHVObTlzVEZOeWNGQTRjbFUzU0d4SGJsRkVSMFJNYVhkS1EyaGtSRGRVVUdSM2FXdHBkMHRGY201aldqaEdaalZsU25vd2RETmlUWFpyVDJaVVluSkJiRnh1WWtGQ1kwbzVNVmxVT1hKdVVXOXFkVWN4UldKUVRqaEZWblI2TWxZNE5IZHViR2Q0TUhCd2JEVjRPSFpOYlhwcE1ISnVibEZVV1VGamJ6WnFhMnBJTTF4dVRuTlVkWE4xUzFkdlJGUjVNWE5yZGtSUk9IbEJZV0ptWTNNME4zWnNRazAwU0RGT1JFNHZSSFJhWWxZdllubDJia0o2YkM4eFZrVnpURmRqWlZWcFRGeHVSWEYxT0VkeWF5dFFVRGQyUkdSd2JFUjNjWFpQV2t4RmRYazNkamhuUm01U09WUlVSV3ByTlVvNWRuWlVTR2RtU25VemVubEVPR2xLWTBSRE5YcHFPVnh1YjFGSlJFRlJRVUpjYmkwdExTMHRSVTVFSUZCVlFreEpReUJMUlZrdExTMHRMVnh1SWl3aWEyVjVVMmxuYm1GMGRYSmxJam9pWlhsS2VtRlhaSFZaV0ZJeFkyMVZhVTlwU2pCUldIQjJXVE5LVms1NmFGaFNSMlJzVVRKb2NtTklXa1ZVVlRsRldqQktXVTFGUmtaVFJFNUZVMGhLYkUxclRUTkxNSEJFVkROR2VGTnROVVJVVlRWVlltMDFiVnBGUm5sWldIQjZaRVJqTVZaSGFFeFBXRUpVVWtacmRrd3diek5aTUZaSlVteFdWRXd5T1VoV1JXeHNWa1ZPTUZSSE1WWlJNR04zVkd4R2JGa3pTblJUUm1zMFZVWk9hMVpWU2pCVU1WbDNZbXQwY0ZSclZuQmpia0poVFZjNWFtSldiSEZaYTNob1UyeHNWV0pGUmtWWGJVWnZWakZLVUZkcWJGSmhXRVp1V2xkb1EyRnVRak5TUjNNd1lWWkpOVTVXVmxkV1ZUVnlUMGhLYjFsVlRYbGhiVGcwVjBkYWVGbHFWbFppYlhoeFpFWkZkMDU1Y3pCaFZsSkpWRVpPTm1WRk1IcGxWWFJ2VFVaR1ZtRXdWVFJSVnpsSFVsaEtVRTFZUmxCU01WcFJVMVJDTmxsV2FIcFdWWEJ0WTBSU2JFMVVRazlPVjNSU1ZucFdUMU5XWTNaU1ZYUkZVMGhzYlU5VmJGaGtNMUl3WTFWc1lXTlhSakJTYTA1RVlVWmtjbUo2VmtSU00wSllUREkxUmsxWVl6SmxWM1JKVlZoQk1sVXhTbEppU0Zwd1VrVXdNRlpFVWt0VU1rWnNVVmQwYzFSV1VrMVVWV055V1RCYVRHSXpaRTlUVm05NVlraE9SR1JzVG5aUmFrWmFaVmRPVGxOVlNteGFiRXB1Wld0U2RVMHhSVGxRVTBselNXMWtjMkl5U21oaVJYUnNaVlZzYTBscWIybFpiVkpzV2xSVk1rNVVXWGRaTWxwcFRrUk9hazlYU1hsUFIwcHRUMVJvYkZsWFRtaGFiVVV5VGtSWmFXWlJQVDBpZlE9PSJ9 diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/base/kustomization.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/base/kustomization.yaml new file mode 100644 index 0000000000..baba5aa644 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/base/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +metadata: + annotations: + kots.io/kustomization: base diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/helm/my-required-chart-release/my-required-chart-0.1.0.tgz b/pkg/tests/pull/cases/required-helm-values/wantResults/helm/my-required-chart-release/my-required-chart-0.1.0.tgz new file mode 100644 index 0000000000..a8db59cd89 Binary files /dev/null and b/pkg/tests/pull/cases/required-helm-values/wantResults/helm/my-required-chart-release/my-required-chart-0.1.0.tgz differ diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/helm/my-required-chart-release/values.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/helm/my-required-chart-release/values.yaml new file mode 100644 index 0000000000..a03624eb9a --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/helm/my-required-chart-release/values.yaml @@ -0,0 +1,2 @@ +my-optional-value: my-optional-value +requiredvalue: this is a required value diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/kots-app.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/kots-app.yaml new file mode 100644 index 0000000000..d10ce3862d --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/kots-app.yaml @@ -0,0 +1,8 @@ +apiVersion: kots.io/v1beta1 +kind: Application +metadata: + name: my-app + annotations: + kots.io/exclude: "true" +spec: + title: my-app diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/my-required-chart.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/my-required-chart.yaml new file mode 100644 index 0000000000..e4aa4aedff --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/my-required-chart.yaml @@ -0,0 +1,18 @@ +apiVersion: kots.io/v1beta2 +kind: HelmChart +metadata: + name: my-required-chart + annotations: + kots.io/exclude: "true" +spec: + chart: + name: my-required-chart + chartVersion: 0.1.0 + releaseName: my-required-chart-release + values: + requiredvalue: this is a required value + optionalValues: + - when: 'true' + recursiveMerge: true + values: + my-optional-value: my-optional-value diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/config.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/config.yaml new file mode 100644 index 0000000000..8fac6db08a --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/config.yaml @@ -0,0 +1,10 @@ +apiVersion: kots.io/v1beta1 +kind: ConfigValues +metadata: + creationTimestamp: null + name: my-app +spec: + values: + hostname: + value: my-app.somebigbank.com +status: {} diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/installation.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/installation.yaml new file mode 100644 index 0000000000..a66901984c --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/installation.yaml @@ -0,0 +1,9 @@ +apiVersion: kots.io/v1beta1 +kind: Installation +metadata: + creationTimestamp: null + name: my-app +spec: + channelID: 1vusIYZLAVxMG6q760OJmRKj5i5 + channelName: My Channel +status: {} diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/license.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/license.yaml new file mode 100644 index 0000000000..9fa3a14d7f --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/kotsKinds/userdata/license.yaml @@ -0,0 +1,49 @@ +apiVersion: kots.io/v1beta1 +kind: License +metadata: + creationTimestamp: null + name: testcustomer +spec: + appSlug: my-app + channelID: 1vusIYZLAVxMG6q760OJmRKj5i5 + channelName: My Channel + customerName: Test Customer + endpoint: https://replicated.app + entitlements: + bool_field: + title: Bool Field + value: true + valueType: Boolean + expires_at: + description: License Expiration + title: Expiration + value: "2030-07-27T00:00:00Z" + valueType: String + hidden_field: + isHidden: true + title: Hidden Field + value: this is secret + valueType: String + int_field: + title: Int Field + value: 123 + valueType: Integer + string_field: + title: StringField + value: single line text + valueType: String + text_field: + title: Text Field + value: |- + multi + line + text + valueType: Text + isAirgapSupported: true + isGitOpsSupported: true + isSnapshotSupported: true + licenseID: 1vusOokxAVp1tkRGuyxnF23PJcq + licenseSequence: 7 + licenseType: prod + signature: eyJsaWNlbnNlRGF0YSI6ImV5SmhjR2xXWlhKemFXOXVJam9pYTI5MGN5NXBieTkyTVdKbGRHRXhJaXdpYTJsdVpDSTZJa3hwWTJWdWMyVWlMQ0p0WlhSaFpHRjBZU0k2ZXlKdVlXMWxJam9pZEdWemRHTjFjM1J2YldWeUluMHNJbk53WldNaU9uc2liR2xqWlc1elpVbEVJam9pTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54SWl3aWJHbGpaVzV6WlZSNWNHVWlPaUp3Y205a0lpd2lZM1Z6ZEc5dFpYSk9ZVzFsSWpvaVZHVnpkQ0JEZFhOMGIyMWxjaUlzSW1Gd2NGTnNkV2NpT2lKdGVTMWhjSEFpTENKamFHRnVibVZzU1VRaU9pSXhkblZ6U1ZsYVRFRldlRTFITm5FM05qQlBTbTFTUzJvMWFUVWlMQ0pqYUdGdWJtVnNUbUZ0WlNJNklrMTVJRU5vWVc1dVpXd2lMQ0pzYVdObGJuTmxVMlZ4ZFdWdVkyVWlPamNzSW1WdVpIQnZhVzUwSWpvaWFIUjBjSE02THk5eVpYQnNhV05oZEdWa0xtRndjQ0lzSW1WdWRHbDBiR1Z0Wlc1MGN5STZleUppYjI5c1gyWnBaV3hrSWpwN0luUnBkR3hsSWpvaVFtOXZiQ0JHYVdWc1pDSXNJblpoYkhWbElqcDBjblZsTENKMllXeDFaVlI1Y0dVaU9pSkNiMjlzWldGdUluMHNJbVY0Y0dseVpYTmZZWFFpT25zaWRHbDBiR1VpT2lKRmVIQnBjbUYwYVc5dUlpd2laR1Z6WTNKcGNIUnBiMjRpT2lKTWFXTmxibk5sSUVWNGNHbHlZWFJwYjI0aUxDSjJZV3gxWlNJNklqSXdNekF0TURjdE1qZFVNREE2TURBNk1EQmFJaXdpZG1Gc2RXVlVlWEJsSWpvaVUzUnlhVzVuSW4wc0ltaHBaR1JsYmw5bWFXVnNaQ0k2ZXlKMGFYUnNaU0k2SWtocFpHUmxiaUJHYVdWc1pDSXNJblpoYkhWbElqb2lkR2hwY3lCcGN5QnpaV055WlhRaUxDSjJZV3gxWlZSNWNHVWlPaUpUZEhKcGJtY2lMQ0pwYzBocFpHUmxiaUk2ZEhKMVpYMHNJbWx1ZEY5bWFXVnNaQ0k2ZXlKMGFYUnNaU0k2SWtsdWRDQkdhV1ZzWkNJc0luWmhiSFZsSWpveE1qTXNJblpoYkhWbFZIbHdaU0k2SWtsdWRHVm5aWElpZlN3aWMzUnlhVzVuWDJacFpXeGtJanA3SW5ScGRHeGxJam9pVTNSeWFXNW5SbWxsYkdRaUxDSjJZV3gxWlNJNkluTnBibWRzWlNCc2FXNWxJSFJsZUhRaUxDSjJZV3gxWlZSNWNHVWlPaUpUZEhKcGJtY2lmU3dpZEdWNGRGOW1hV1ZzWkNJNmV5SjBhWFJzWlNJNklsUmxlSFFnUm1sbGJHUWlMQ0oyWVd4MVpTSTZJbTExYkhScFhHNXNhVzVsWEc1MFpYaDBJaXdpZG1Gc2RXVlVlWEJsSWpvaVZHVjRkQ0o5ZlN3aWFYTkJhWEpuWVhCVGRYQndiM0owWldRaU9uUnlkV1VzSW1selIybDBUM0J6VTNWd2NHOXlkR1ZrSWpwMGNuVmxMQ0pwYzFOdVlYQnphRzkwVTNWd2NHOXlkR1ZrSWpwMGNuVmxmWDA9IiwiaW5uZXJTaWduYXR1cmUiOiJleUpzYVdObGJuTmxVMmxuYm1GMGRYSmxJam9pYUhneE1XTXZUR1ozUTNoVE5YRmtRWEJGU1hGdVRrMU9NMHBLYTJzNFZHZFhSVVpzVDFKVlJ6UjJjR1YzZEZoV1YzbG1lamRZY0hBd1ExazJZamRyUVRSS2N6TklhR3d3YkZJMFdUQTFMemN2UVVkQ2FEZFZNSGczUkhaTVozUXpVM00wYm5GTFZTdFhXRXBTVHpKWVFVRnZSME4xZFRWR1RGcHJRVWhYY1RSUVFtMXphSFY2Y1ZsdmNucHhlbGhGWVZWVlpFUlVkVXhDTW1nNWFIZ3dXRWhQUmxwUk16bHVkbTlPUjJaT2R5OTRTVmRaZEhSUGRYZHZhMncyTVZsb1JVeFZlRmQxU1ZSRmMwTlVhM2xtTVRNd09IazVSbFJzWlRKeVYyZEVlSEZNYTBSUFNXVXlPRWwzUzJSQkwySXdWVUl5VEZGbVRWcHdWemwyUTNCSkwybHlWek5uYmpaeU5WWjNWMjB2U1dweWJtNDNSelJrVmpadVYzcFRkMGhQUTJSdWEwMTRNRXQ1VVVOa0wxQjFaWEpUYjNSdVEwOXRTMDEzWlRSTGJqaERkMU5YVVRRNGRURkRNbTFpV1VzeGRYTlpOM1YzUFQwaUxDSndkV0pzYVdOTFpYa2lPaUl0TFMwdExVSkZSMGxPSUZCVlFreEpReUJMUlZrdExTMHRMVnh1VFVsSlFrbHFRVTVDWjJ0eGFHdHBSemwzTUVKQlVVVkdRVUZQUTBGUk9FRk5TVWxDUTJkTFEwRlJSVUZ6TkhKdlVIcDFhV1JNZVhOMmIxWTJkemxhTkZ4dVdHRmliME5tWTJNeGFHZFZhQ3N3V1VkS2NFNURSVXhyTjBaTFF5OTJhemR6ZERsR05tY3dUMjlrU0VSbGVYZFJXa2hLZFU1TVpsUnNRbEJHUTJOaU5seHVObTlzVEZOeWNGQTRjbFUzU0d4SGJsRkVSMFJNYVhkS1EyaGtSRGRVVUdSM2FXdHBkMHRGY201aldqaEdaalZsU25vd2RETmlUWFpyVDJaVVluSkJiRnh1WWtGQ1kwbzVNVmxVT1hKdVVXOXFkVWN4UldKUVRqaEZWblI2TWxZNE5IZHViR2Q0TUhCd2JEVjRPSFpOYlhwcE1ISnVibEZVV1VGamJ6WnFhMnBJTTF4dVRuTlVkWE4xUzFkdlJGUjVNWE5yZGtSUk9IbEJZV0ptWTNNME4zWnNRazAwU0RGT1JFNHZSSFJhWWxZdllubDJia0o2YkM4eFZrVnpURmRqWlZWcFRGeHVSWEYxT0VkeWF5dFFVRGQyUkdSd2JFUjNjWFpQV2t4RmRYazNkamhuUm01U09WUlVSV3ByTlVvNWRuWlVTR2RtU25VemVubEVPR2xLWTBSRE5YcHFPVnh1YjFGSlJFRlJRVUpjYmkwdExTMHRSVTVFSUZCVlFreEpReUJMUlZrdExTMHRMVnh1SWl3aWEyVjVVMmxuYm1GMGRYSmxJam9pWlhsS2VtRlhaSFZaV0ZJeFkyMVZhVTlwU2pCUldIQjJXVE5LVms1NmFGaFNSMlJzVVRKb2NtTklXa1ZVVlRsRldqQktXVTFGUmtaVFJFNUZVMGhLYkUxclRUTkxNSEJFVkROR2VGTnROVVJVVlRWVlltMDFiVnBGUm5sWldIQjZaRVJqTVZaSGFFeFBXRUpVVWtacmRrd3diek5aTUZaSlVteFdWRXd5T1VoV1JXeHNWa1ZPTUZSSE1WWlJNR04zVkd4R2JGa3pTblJUUm1zMFZVWk9hMVpWU2pCVU1WbDNZbXQwY0ZSclZuQmpia0poVFZjNWFtSldiSEZaYTNob1UyeHNWV0pGUmtWWGJVWnZWakZLVUZkcWJGSmhXRVp1V2xkb1EyRnVRak5TUjNNd1lWWkpOVTVXVmxkV1ZUVnlUMGhLYjFsVlRYbGhiVGcwVjBkYWVGbHFWbFppYlhoeFpFWkZkMDU1Y3pCaFZsSkpWRVpPTm1WRk1IcGxWWFJ2VFVaR1ZtRXdWVFJSVnpsSFVsaEtVRTFZUmxCU01WcFJVMVJDTmxsV2FIcFdWWEJ0WTBSU2JFMVVRazlPVjNSU1ZucFdUMU5XWTNaU1ZYUkZVMGhzYlU5VmJGaGtNMUl3WTFWc1lXTlhSakJTYTA1RVlVWmtjbUo2VmtSU00wSllUREkxUmsxWVl6SmxWM1JKVlZoQk1sVXhTbEppU0Zwd1VrVXdNRlpFVWt0VU1rWnNVVmQwYzFSV1VrMVVWV055V1RCYVRHSXpaRTlUVm05NVlraE9SR1JzVG5aUmFrWmFaVmRPVGxOVlNteGFiRXB1Wld0U2RVMHhSVGxRVTBselNXMWtjMkl5U21oaVJYUnNaVlZzYTBscWIybFpiVkpzV2xSVk1rNVVXWGRaTWxwcFRrUk9hazlYU1hsUFIwcHRUMVJvYkZsWFRtaGFiVVV5VGtSWmFXWlJQVDBpZlE9PSJ9 +status: {} diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/downstreams/this-cluster/kustomization.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/downstreams/this-cluster/kustomization.yaml new file mode 100644 index 0000000000..73a609d8fa --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/downstreams/this-cluster/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +bases: +- ../../midstream +kind: Kustomization diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/backup-label-transformer.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/backup-label-transformer.yaml new file mode 100644 index 0000000000..c3acc6c5b9 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/backup-label-transformer.yaml @@ -0,0 +1,39 @@ +apiVersion: builtin +kind: LabelTransformer +metadata: + name: backup-label-transformer +labels: + kots.io/app-slug: my-app + kots.io/backup: velero +fieldSpecs: +- path: metadata/labels + create: true +- version: v1 + kind: ReplicationController + path: spec/template/metadata/labels + create: true +- kind: Deployment + path: spec/template/metadata/labels + create: true +- kind: ReplicaSet + path: spec/template/metadata/labels + create: true +- kind: DaemonSet + path: spec/template/metadata/labels + create: true +- group: apps + kind: StatefulSet + path: spec/template/metadata/labels + create: true +- group: batch + kind: Job + path: spec/template/metadata/labels + create: true +- group: batch + kind: CronJob + path: spec/jobTemplate/metadata/labels + create: true +- group: batch + kind: CronJob + path: spec/jobTemplate/spec/template/metadata/labels + create: true diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/kustomization.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/kustomization.yaml new file mode 100644 index 0000000000..bb6f5b2615 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +bases: +- ../../base +commonAnnotations: + kots.io/app-slug: my-app +kind: Kustomization +resources: +- secret.yaml +transformers: +- backup-label-transformer.yaml diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/secret.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/secret.yaml new file mode 100644 index 0000000000..4d81bc057f --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/overlays/midstream/secret.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +data: + .dockerconfigjson: eyJhdXRocyI6eyJwcm94eS5yZXBsaWNhdGVkLmNvbSI6eyJhdXRoIjoiTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54T2pGMmRYTlBiMnQ0UVZad01YUnJVa2QxZVhodVJqSXpVRXBqY1E9PSJ9LCJyZWdpc3RyeS5yZXBsaWNhdGVkLmNvbSI6eyJhdXRoIjoiTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54T2pGMmRYTlBiMnQ0UVZad01YUnJVa2QxZVhodVJqSXpVRXBqY1E9PSJ9fX0= +kind: Secret +metadata: + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-9999" + kots.io/creation-phase: "-9999" + creationTimestamp: null + name: my-app-registry + namespace: app-namespace +type: kubernetes.io/dockerconfigjson + +--- +apiVersion: v1 +data: + .dockerconfigjson: eyJhdXRocyI6eyJwcm94eS5yZXBsaWNhdGVkLmNvbSI6eyJhdXRoIjoiTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54T2pGMmRYTlBiMnQ0UVZad01YUnJVa2QxZVhodVJqSXpVRXBqY1E9PSJ9LCJyZWdpc3RyeS5yZXBsaWNhdGVkLmNvbSI6eyJhdXRoIjoiTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54T2pGMmRYTlBiMnQ0UVZad01YUnJVa2QxZVhodVJqSXpVRXBqY1E9PSJ9fX0= +kind: Secret +metadata: + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-9999" + kots.io/creation-phase: "-9999" + creationTimestamp: null + name: kotsadm-replicated-registry + namespace: app-namespace +type: kubernetes.io/dockerconfigjson diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/helm/my-required-chart-release/all.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/helm/my-required-chart-release/all.yaml new file mode 100644 index 0000000000..8af1b60221 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/helm/my-required-chart-release/all.yaml @@ -0,0 +1,20 @@ +--- +# Source: my-required-chart/templates/my-chart-configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-chart-configmap +data: + requiredkey: this is a required value +--- +# Source: my-required-chart/templates/my-chart-pod.yaml +apiVersion: v1 +kind: Pod +metadata: + name: my-chart-pod +spec: + containers: + - name: my-chart-container + image: nginx:1.23 + ports: + - containerPort: 80 diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/kotsadm-replicated-registry-secret.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/kotsadm-replicated-registry-secret.yaml new file mode 100644 index 0000000000..6f52289831 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/kotsadm-replicated-registry-secret.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +data: + .dockerconfigjson: eyJhdXRocyI6eyJwcm94eS5yZXBsaWNhdGVkLmNvbSI6eyJhdXRoIjoiTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54T2pGMmRYTlBiMnQ0UVZad01YUnJVa2QxZVhodVJqSXpVRXBqY1E9PSJ9LCJyZWdpc3RyeS5yZXBsaWNhdGVkLmNvbSI6eyJhdXRoIjoiTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54T2pGMmRYTlBiMnQ0UVZad01YUnJVa2QxZVhodVJqSXpVRXBqY1E9PSJ9fX0= +kind: Secret +metadata: + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-9999" + kots.io/app-slug: my-app + kots.io/creation-phase: "-9999" + creationTimestamp: null + labels: + kots.io/app-slug: my-app + kots.io/backup: velero + name: kotsadm-replicated-registry + namespace: app-namespace +type: kubernetes.io/dockerconfigjson \ No newline at end of file diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/my-app-registry-secret.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/my-app-registry-secret.yaml new file mode 100644 index 0000000000..a8b369b451 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/rendered/this-cluster/my-app-registry-secret.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +data: + .dockerconfigjson: eyJhdXRocyI6eyJwcm94eS5yZXBsaWNhdGVkLmNvbSI6eyJhdXRoIjoiTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54T2pGMmRYTlBiMnQ0UVZad01YUnJVa2QxZVhodVJqSXpVRXBqY1E9PSJ9LCJyZWdpc3RyeS5yZXBsaWNhdGVkLmNvbSI6eyJhdXRoIjoiTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54T2pGMmRYTlBiMnQ0UVZad01YUnJVa2QxZVhodVJqSXpVRXBqY1E9PSJ9fX0= +kind: Secret +metadata: + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-9999" + kots.io/app-slug: my-app + kots.io/creation-phase: "-9999" + creationTimestamp: null + labels: + kots.io/app-slug: my-app + kots.io/backup: velero + name: my-app-registry + namespace: app-namespace +type: kubernetes.io/dockerconfigjson diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/kots-app.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/kots-app.yaml new file mode 100644 index 0000000000..d10ce3862d --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/kots-app.yaml @@ -0,0 +1,8 @@ +apiVersion: kots.io/v1beta1 +kind: Application +metadata: + name: my-app + annotations: + kots.io/exclude: "true" +spec: + title: my-app diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/my-required-chart-0.1.0.tgz b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/my-required-chart-0.1.0.tgz new file mode 100644 index 0000000000..a8db59cd89 Binary files /dev/null and b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/my-required-chart-0.1.0.tgz differ diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/my-required-chart.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/my-required-chart.yaml new file mode 100644 index 0000000000..a9b030ec94 --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/my-required-chart.yaml @@ -0,0 +1,18 @@ +apiVersion: kots.io/v1beta2 +kind: HelmChart +metadata: + name: my-required-chart + annotations: + kots.io/exclude: "true" +spec: + chart: + name: my-required-chart + chartVersion: 0.1.0 + releaseName: my-required-chart-release + values: + requiredvalue: this is a required value + optionalValues: + - when: 'repl{{ "true" }}' + recursiveMerge: true + values: + my-optional-value: my-optional-value diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/config.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/config.yaml new file mode 100644 index 0000000000..8fac6db08a --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/config.yaml @@ -0,0 +1,10 @@ +apiVersion: kots.io/v1beta1 +kind: ConfigValues +metadata: + creationTimestamp: null + name: my-app +spec: + values: + hostname: + value: my-app.somebigbank.com +status: {} diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/installation.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/installation.yaml new file mode 100644 index 0000000000..a66901984c --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/installation.yaml @@ -0,0 +1,9 @@ +apiVersion: kots.io/v1beta1 +kind: Installation +metadata: + creationTimestamp: null + name: my-app +spec: + channelID: 1vusIYZLAVxMG6q760OJmRKj5i5 + channelName: My Channel +status: {} diff --git a/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/license.yaml b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/license.yaml new file mode 100644 index 0000000000..9fa3a14d7f --- /dev/null +++ b/pkg/tests/pull/cases/required-helm-values/wantResults/upstream/userdata/license.yaml @@ -0,0 +1,49 @@ +apiVersion: kots.io/v1beta1 +kind: License +metadata: + creationTimestamp: null + name: testcustomer +spec: + appSlug: my-app + channelID: 1vusIYZLAVxMG6q760OJmRKj5i5 + channelName: My Channel + customerName: Test Customer + endpoint: https://replicated.app + entitlements: + bool_field: + title: Bool Field + value: true + valueType: Boolean + expires_at: + description: License Expiration + title: Expiration + value: "2030-07-27T00:00:00Z" + valueType: String + hidden_field: + isHidden: true + title: Hidden Field + value: this is secret + valueType: String + int_field: + title: Int Field + value: 123 + valueType: Integer + string_field: + title: StringField + value: single line text + valueType: String + text_field: + title: Text Field + value: |- + multi + line + text + valueType: Text + isAirgapSupported: true + isGitOpsSupported: true + isSnapshotSupported: true + licenseID: 1vusOokxAVp1tkRGuyxnF23PJcq + licenseSequence: 7 + licenseType: prod + signature: eyJsaWNlbnNlRGF0YSI6ImV5SmhjR2xXWlhKemFXOXVJam9pYTI5MGN5NXBieTkyTVdKbGRHRXhJaXdpYTJsdVpDSTZJa3hwWTJWdWMyVWlMQ0p0WlhSaFpHRjBZU0k2ZXlKdVlXMWxJam9pZEdWemRHTjFjM1J2YldWeUluMHNJbk53WldNaU9uc2liR2xqWlc1elpVbEVJam9pTVhaMWMwOXZhM2hCVm5BeGRHdFNSM1Y1ZUc1R01qTlFTbU54SWl3aWJHbGpaVzV6WlZSNWNHVWlPaUp3Y205a0lpd2lZM1Z6ZEc5dFpYSk9ZVzFsSWpvaVZHVnpkQ0JEZFhOMGIyMWxjaUlzSW1Gd2NGTnNkV2NpT2lKdGVTMWhjSEFpTENKamFHRnVibVZzU1VRaU9pSXhkblZ6U1ZsYVRFRldlRTFITm5FM05qQlBTbTFTUzJvMWFUVWlMQ0pqYUdGdWJtVnNUbUZ0WlNJNklrMTVJRU5vWVc1dVpXd2lMQ0pzYVdObGJuTmxVMlZ4ZFdWdVkyVWlPamNzSW1WdVpIQnZhVzUwSWpvaWFIUjBjSE02THk5eVpYQnNhV05oZEdWa0xtRndjQ0lzSW1WdWRHbDBiR1Z0Wlc1MGN5STZleUppYjI5c1gyWnBaV3hrSWpwN0luUnBkR3hsSWpvaVFtOXZiQ0JHYVdWc1pDSXNJblpoYkhWbElqcDBjblZsTENKMllXeDFaVlI1Y0dVaU9pSkNiMjlzWldGdUluMHNJbVY0Y0dseVpYTmZZWFFpT25zaWRHbDBiR1VpT2lKRmVIQnBjbUYwYVc5dUlpd2laR1Z6WTNKcGNIUnBiMjRpT2lKTWFXTmxibk5sSUVWNGNHbHlZWFJwYjI0aUxDSjJZV3gxWlNJNklqSXdNekF0TURjdE1qZFVNREE2TURBNk1EQmFJaXdpZG1Gc2RXVlVlWEJsSWpvaVUzUnlhVzVuSW4wc0ltaHBaR1JsYmw5bWFXVnNaQ0k2ZXlKMGFYUnNaU0k2SWtocFpHUmxiaUJHYVdWc1pDSXNJblpoYkhWbElqb2lkR2hwY3lCcGN5QnpaV055WlhRaUxDSjJZV3gxWlZSNWNHVWlPaUpUZEhKcGJtY2lMQ0pwYzBocFpHUmxiaUk2ZEhKMVpYMHNJbWx1ZEY5bWFXVnNaQ0k2ZXlKMGFYUnNaU0k2SWtsdWRDQkdhV1ZzWkNJc0luWmhiSFZsSWpveE1qTXNJblpoYkhWbFZIbHdaU0k2SWtsdWRHVm5aWElpZlN3aWMzUnlhVzVuWDJacFpXeGtJanA3SW5ScGRHeGxJam9pVTNSeWFXNW5SbWxsYkdRaUxDSjJZV3gxWlNJNkluTnBibWRzWlNCc2FXNWxJSFJsZUhRaUxDSjJZV3gxWlZSNWNHVWlPaUpUZEhKcGJtY2lmU3dpZEdWNGRGOW1hV1ZzWkNJNmV5SjBhWFJzWlNJNklsUmxlSFFnUm1sbGJHUWlMQ0oyWVd4MVpTSTZJbTExYkhScFhHNXNhVzVsWEc1MFpYaDBJaXdpZG1Gc2RXVlVlWEJsSWpvaVZHVjRkQ0o5ZlN3aWFYTkJhWEpuWVhCVGRYQndiM0owWldRaU9uUnlkV1VzSW1selIybDBUM0J6VTNWd2NHOXlkR1ZrSWpwMGNuVmxMQ0pwYzFOdVlYQnphRzkwVTNWd2NHOXlkR1ZrSWpwMGNuVmxmWDA9IiwiaW5uZXJTaWduYXR1cmUiOiJleUpzYVdObGJuTmxVMmxuYm1GMGRYSmxJam9pYUhneE1XTXZUR1ozUTNoVE5YRmtRWEJGU1hGdVRrMU9NMHBLYTJzNFZHZFhSVVpzVDFKVlJ6UjJjR1YzZEZoV1YzbG1lamRZY0hBd1ExazJZamRyUVRSS2N6TklhR3d3YkZJMFdUQTFMemN2UVVkQ2FEZFZNSGczUkhaTVozUXpVM00wYm5GTFZTdFhXRXBTVHpKWVFVRnZSME4xZFRWR1RGcHJRVWhYY1RSUVFtMXphSFY2Y1ZsdmNucHhlbGhGWVZWVlpFUlVkVXhDTW1nNWFIZ3dXRWhQUmxwUk16bHVkbTlPUjJaT2R5OTRTVmRaZEhSUGRYZHZhMncyTVZsb1JVeFZlRmQxU1ZSRmMwTlVhM2xtTVRNd09IazVSbFJzWlRKeVYyZEVlSEZNYTBSUFNXVXlPRWwzUzJSQkwySXdWVUl5VEZGbVRWcHdWemwyUTNCSkwybHlWek5uYmpaeU5WWjNWMjB2U1dweWJtNDNSelJrVmpadVYzcFRkMGhQUTJSdWEwMTRNRXQ1VVVOa0wxQjFaWEpUYjNSdVEwOXRTMDEzWlRSTGJqaERkMU5YVVRRNGRURkRNbTFpV1VzeGRYTlpOM1YzUFQwaUxDSndkV0pzYVdOTFpYa2lPaUl0TFMwdExVSkZSMGxPSUZCVlFreEpReUJMUlZrdExTMHRMVnh1VFVsSlFrbHFRVTVDWjJ0eGFHdHBSemwzTUVKQlVVVkdRVUZQUTBGUk9FRk5TVWxDUTJkTFEwRlJSVUZ6TkhKdlVIcDFhV1JNZVhOMmIxWTJkemxhTkZ4dVdHRmliME5tWTJNeGFHZFZhQ3N3V1VkS2NFNURSVXhyTjBaTFF5OTJhemR6ZERsR05tY3dUMjlrU0VSbGVYZFJXa2hLZFU1TVpsUnNRbEJHUTJOaU5seHVObTlzVEZOeWNGQTRjbFUzU0d4SGJsRkVSMFJNYVhkS1EyaGtSRGRVVUdSM2FXdHBkMHRGY201aldqaEdaalZsU25vd2RETmlUWFpyVDJaVVluSkJiRnh1WWtGQ1kwbzVNVmxVT1hKdVVXOXFkVWN4UldKUVRqaEZWblI2TWxZNE5IZHViR2Q0TUhCd2JEVjRPSFpOYlhwcE1ISnVibEZVV1VGamJ6WnFhMnBJTTF4dVRuTlVkWE4xUzFkdlJGUjVNWE5yZGtSUk9IbEJZV0ptWTNNME4zWnNRazAwU0RGT1JFNHZSSFJhWWxZdllubDJia0o2YkM4eFZrVnpURmRqWlZWcFRGeHVSWEYxT0VkeWF5dFFVRGQyUkdSd2JFUjNjWFpQV2t4RmRYazNkamhuUm01U09WUlVSV3ByTlVvNWRuWlVTR2RtU25VemVubEVPR2xLWTBSRE5YcHFPVnh1YjFGSlJFRlJRVUpjYmkwdExTMHRSVTVFSUZCVlFreEpReUJMUlZrdExTMHRMVnh1SWl3aWEyVjVVMmxuYm1GMGRYSmxJam9pWlhsS2VtRlhaSFZaV0ZJeFkyMVZhVTlwU2pCUldIQjJXVE5LVms1NmFGaFNSMlJzVVRKb2NtTklXa1ZVVlRsRldqQktXVTFGUmtaVFJFNUZVMGhLYkUxclRUTkxNSEJFVkROR2VGTnROVVJVVlRWVlltMDFiVnBGUm5sWldIQjZaRVJqTVZaSGFFeFBXRUpVVWtacmRrd3diek5aTUZaSlVteFdWRXd5T1VoV1JXeHNWa1ZPTUZSSE1WWlJNR04zVkd4R2JGa3pTblJUUm1zMFZVWk9hMVpWU2pCVU1WbDNZbXQwY0ZSclZuQmpia0poVFZjNWFtSldiSEZaYTNob1UyeHNWV0pGUmtWWGJVWnZWakZLVUZkcWJGSmhXRVp1V2xkb1EyRnVRak5TUjNNd1lWWkpOVTVXVmxkV1ZUVnlUMGhLYjFsVlRYbGhiVGcwVjBkYWVGbHFWbFppYlhoeFpFWkZkMDU1Y3pCaFZsSkpWRVpPTm1WRk1IcGxWWFJ2VFVaR1ZtRXdWVFJSVnpsSFVsaEtVRTFZUmxCU01WcFJVMVJDTmxsV2FIcFdWWEJ0WTBSU2JFMVVRazlPVjNSU1ZucFdUMU5XWTNaU1ZYUkZVMGhzYlU5VmJGaGtNMUl3WTFWc1lXTlhSakJTYTA1RVlVWmtjbUo2VmtSU00wSllUREkxUmsxWVl6SmxWM1JKVlZoQk1sVXhTbEppU0Zwd1VrVXdNRlpFVWt0VU1rWnNVVmQwYzFSV1VrMVVWV055V1RCYVRHSXpaRTlUVm05NVlraE9SR1JzVG5aUmFrWmFaVmRPVGxOVlNteGFiRXB1Wld0U2RVMHhSVGxRVTBselNXMWtjMkl5U21oaVJYUnNaVlZzYTBscWIybFpiVkpzV2xSVk1rNVVXWGRaTWxwcFRrUk9hazlYU1hsUFIwcHRUMVJvYkZsWFRtaGFiVVV5VGtSWmFXWlJQVDBpZlE9PSJ9 +status: {}