Skip to content

Commit

Permalink
Add a ready attribute to await Helm Charts (#1364)
Browse files Browse the repository at this point in the history
  • Loading branch information
lblackstone authored Nov 12, 2020
1 parent 64ad71d commit 02cb470
Show file tree
Hide file tree
Showing 41 changed files with 1,685 additions and 430 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Add support for previewing Create and Update operations for API servers that support dry-run (https://github.com/pulumi/pulumi-kubernetes/pull/1355)
- Fix panic introduced in #1355 (https://github.com/pulumi/pulumi-kubernetes/pull/1368)
- Add ready attribute to await Helm charts (https://github.com/pulumi/pulumi-kubernetes/pull/1364)
- Update Helm to v3.4.0 and client-go to v1.19.2 (https://github.com/pulumi/pulumi-kubernetes/pull/1360)
- Update Helm to v3.4.1 and client-go to v1.19.3 (https://github.com/pulumi/pulumi-kubernetes/pull/1365)
- Fix panic when provider is given kubeconfig as an object instead of string (https://github.com/pulumi/pulumi-kubernetes/pull/1373)
Expand Down
2 changes: 2 additions & 0 deletions provider/pkg/gen/nodejs-templates/helm/v2/helm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ export class Chart extends yaml.CollectionComponentResource {
overrides.removeCallback();
}
});

this.ready = this.resources.apply(m => Object.values(m));
}

parseTemplate(
Expand Down
2 changes: 2 additions & 0 deletions provider/pkg/gen/nodejs-templates/helm/v3/helm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ export class Chart extends yaml.CollectionComponentResource {
this.resources = allConfig.apply(cfg => {
return this.parseChart(cfg, releaseName, opts)
});

this.ready = this.resources.apply(m => Object.values(m));
}

parseChart(config: ChartOpts | LocalChartOpts, releaseName: string, opts?: pulumi.ComponentResourceOptions) {
Expand Down
1 change: 1 addition & 0 deletions provider/pkg/gen/nodejs-templates/yaml/yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { getVersion } from "../utilities";

export abstract class CollectionComponentResource extends pulumi.ComponentResource {
resources!: pulumi.Output<{ [key: string]: pulumi.CustomResource }>;
ready!: pulumi.Output<pulumi.CustomResource[]>;

protected constructor(
resourceType: string, name: string, config: any, opts?: pulumi.ComponentResourceOptions,
Expand Down
2 changes: 2 additions & 0 deletions sdk/nodejs/helm/v2/helm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ export class Chart extends yaml.CollectionComponentResource {
overrides.removeCallback();
}
});

this.ready = this.resources.apply(m => Object.values(m));
}

parseTemplate(
Expand Down
2 changes: 2 additions & 0 deletions sdk/nodejs/helm/v3/helm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ export class Chart extends yaml.CollectionComponentResource {
this.resources = allConfig.apply(cfg => {
return this.parseChart(cfg, releaseName, opts)
});

this.ready = this.resources.apply(m => Object.values(m));
}

parseChart(config: ChartOpts | LocalChartOpts, releaseName: string, opts?: pulumi.ComponentResourceOptions) {
Expand Down
1 change: 1 addition & 0 deletions sdk/nodejs/yaml/yaml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { getVersion } from "../utilities";

export abstract class CollectionComponentResource extends pulumi.ComponentResource {
resources!: pulumi.Output<{ [key: string]: pulumi.CustomResource }>;
ready!: pulumi.Output<pulumi.CustomResource[]>;

protected constructor(
resourceType: string, name: string, config: any, opts?: pulumi.ComponentResourceOptions,
Expand Down
34 changes: 31 additions & 3 deletions tests/sdk/nodejs/examples/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"testing"

Expand Down Expand Up @@ -189,13 +190,40 @@ func TestAccHelmLocal(t *testing.T) {
skipIfShort(t)
test := getBaseOptions(t).
With(integration.ProgramTestOptions{
Dir: filepath.Join(getCwd(t), "helm-local", "step1"),
SkipRefresh: true, // Deployment controller changes object out-of-band.
Dir: filepath.Join(getCwd(t), "helm-local", "step1"),
ExpectRefreshChanges: true,
ExtraRuntimeValidation: func(
t *testing.T, stackInfo integration.RuntimeValidationStackInfo,
) {
assert.NotNil(t, stackInfo.Deployment)
assert.Equal(t, 15, len(stackInfo.Deployment.Resources))
assert.Equal(t, 12, len(stackInfo.Deployment.Resources))

// Verify resource creation order using the Event stream. The Chart resources must be created
// first, followed by the dependent ConfigMap. (The ConfigMap doesn't actually need the Chart, but
// it creates almost instantly, so it's a good choice to test creation ordering)
cmRegex := regexp.MustCompile(`ConfigMap::test-.*/nginx-server-block`)
svcRegex := regexp.MustCompile(`Service::test-.*/nginx`)
deployRegex := regexp.MustCompile(`Deployment::test-.*/nginx`)
dependentRegex := regexp.MustCompile(`ConfigMap::foo`)

var configmapFound, serviceFound, deploymentFound, dependentFound bool
for _, e := range stackInfo.Events {
if e.ResOutputsEvent != nil {
switch {
case cmRegex.MatchString(e.ResOutputsEvent.Metadata.URN):
configmapFound = true
case svcRegex.MatchString(e.ResOutputsEvent.Metadata.URN):
serviceFound = true
case deployRegex.MatchString(e.ResOutputsEvent.Metadata.URN):
deploymentFound = true
case dependentRegex.MatchString(e.ResOutputsEvent.Metadata.URN):
dependentFound = true
}
assert.Falsef(t, dependentFound && !(configmapFound && serviceFound && deploymentFound),
"dependent ConfigMap created before all chart resources were ready")
fmt.Println(e.ResOutputsEvent.Metadata.URN)
}
}
},
EditDirs: []integration.EditDir{
{
Expand Down
34 changes: 15 additions & 19 deletions tests/sdk/nodejs/examples/helm-local/step1/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016-2019, Pulumi Corporation.
// Copyright 2016-2020, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -19,40 +19,36 @@ const namespace = new k8s.core.v1.Namespace("test");
const namespaceName = namespace.metadata.name;

function chart(resourcePrefix?: string): k8s.helm.v2.Chart {
return new k8s.helm.v2.Chart("nginx-lego", {
// Represents chart `stable/nginx-lego@v0.3.1`.
path: "nginx-lego",
version: "0.3.1",
return new k8s.helm.v2.Chart("nginx", {
path: "nginx",
namespace: namespaceName,
resourcePrefix: resourcePrefix,
values: {
// Override for the Chart's `values.yml` file. Use `null` to zero out resource requests so it
// can be scheduled on our (wimpy) CI cluster. (Setting these values to `null` is the "normal"
// way to delete values.)
nginx: {resources: null},
default: {resources: null},
lego: {resources: null}
service: { type: "ClusterIP" }
},
transformations: [
// Make every service private to the cluster, i.e., turn all services into ClusterIP instead of
// LoadBalancer.
(obj: any) => {
(obj: any, opts: pulumi.CustomResourceOptions) => {
if (obj.kind == "Service" && obj.apiVersion == "v1") {
if (obj.spec && obj.spec.type && obj.spec.type == "LoadBalancer") {
obj.spec.type = "ClusterIP";
}
opts.additionalSecretOutputs = ["status"];
}
},
}
]
});
}

// Create the first instance of the Chart.
const nginx = chart();

// Create a ConfigMap depending on the Chart. The ConfigMap should not be created until after all of the Chart
// resources are ready.
new k8s.core.v1.ConfigMap("foo", {
metadata: { namespace: namespaceName },
data: {foo: "bar"}
}, {dependsOn: nginx.ready})

// Export the (cluster-private) IP address of the Guestbook frontend.
const frontendServiceSpec = pulumi.all([namespaceName, nginx]).apply(([nsName, nginx]) =>
nginx.getResourceProperty("v1/Service", nsName, "nginx-lego-nginx-lego", "spec"));
nginx.getResourceProperty("v1/Service", nsName, "nginx", "spec"));
export const frontendServiceIP = frontendServiceSpec.clusterIP;

// Deploy a duplicate chart with a different resource prefix to verify that multiple instances of the Chart
Expand Down
16 changes: 0 additions & 16 deletions tests/sdk/nodejs/examples/helm-local/step1/nginx-lego/Chart.yaml

This file was deleted.

82 changes: 0 additions & 82 deletions tests/sdk/nodejs/examples/helm-local/step1/nginx-lego/README.md

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 02cb470

Please sign in to comment.