Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional resourcePrefix param for Chart #599

Merged
merged 9 commits into from
Jun 20, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Improvements

- Enable multiple instances of Helm charts per stack (https://github.com/pulumi/pulumi-kubernetes/pull/599).
- Enable multiple instances of YAML manifests per stack (https://github.com/pulumi/pulumi-kubernetes/pull/594).

### Bug fixes
Expand Down
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ require (
github.com/google/gofuzz v1.0.0 // indirect
github.com/googleapis/gnostic v0.2.0
github.com/gophercloud/gophercloud v0.0.0-20190418141522-bb98932a7b3a // indirect
github.com/grpc/grpc-go v0.0.0-00010101000000-000000000000 // indirect
github.com/imdario/mergo v0.3.7 // indirect
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3
github.com/json-iterator/go v1.1.6 // indirect
github.com/mitchellh/go-wordwrap v1.0.0
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.8.1
github.com/pulumi/pulumi v0.17.15
github.com/stretchr/testify v1.2.2
Expand All @@ -31,7 +29,6 @@ require (
k8s.io/kube-openapi v0.0.0-20190418160015-6b3d3b2d5666
k8s.io/kubernetes v1.14.1
k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7 // indirect
sigs.k8s.io/kustomize v1.0.11 // indirect
)

replace (
Expand Down
28 changes: 26 additions & 2 deletions go.sum

Large diffs are not rendered by default.

25 changes: 24 additions & 1 deletion pkg/gen/python-templates/helm/v2/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ class ChartOpts:
creation. Allows customization of the chart behaviour without directly modifying the chart itself.
"""

resource_prefix: Optional[str]
"""
Optional prefix for the auto-generated resource names.
Example: A resource created with resource_prefix="foo" would produce a resource named "foo-resourceName".
"""

repo: Optional[pulumi.Input[str]]
"""
The repository containing the desired chart. If not provided, [chart] must be a fully qualified
Expand All @@ -206,6 +212,7 @@ def __init__(self,
namespace: Optional[pulumi.Input[str]] = None,
values: Optional[pulumi.Inputs] = None,
transformations: Optional[List[Callable]] = None,
resource_prefix: Optional[str] = None,
repo: Optional[pulumi.Input[str]] = None,
version: Optional[pulumi.Input[str]] = None,
fetch_opts: Optional[pulumi.Input[FetchOpts]] = None) -> None:
Expand All @@ -218,6 +225,8 @@ def __init__(self,
:param Optional[List[Callable] transformations: Optional list of transformations to apply to
resources that will be created by this chart prior to creation. Allows customization of the
chart behaviour without directly modifying the chart itself.
:param Optional[str] resource_prefix: An optional prefix for the auto-generated resource names.
Example: A resource created with resource_prefix="foo" would produce a resource named "foo-resourceName".
:param Optional[pulumi.Input[str]] repo: The repository containing the desired chart. If not
provided, [chart] must be a fully qualified chart URL or repo/chartname.
:param Optional[pulumi.Input[str]] version: The version of the chart to deploy. If not provided,
Expand All @@ -229,6 +238,7 @@ def __init__(self,
self.namespace = namespace
self.values = values
self.transformations = transformations
self.resource_prefix = resource_prefix
self.repo = repo
self.version = version
self.fetch_opts = fetch_opts
Expand Down Expand Up @@ -260,11 +270,18 @@ class LocalChartOpts:
creation. Allows customization of the chart behaviour without directly modifying the chart itself.
"""

resource_prefix: Optional[str]
"""
Optional prefix for the auto-generated resource names.
Example: A resource created with resource_prefix="foo" would produce a resource named "foo-resourceName".
"""

def __init__(self,
path: pulumi.Input[str],
namespace: Optional[pulumi.Input[str]] = None,
values: Optional[pulumi.Inputs] = None,
transformations: Optional[List[Callable]] = None) -> None:
transformations: Optional[List[Callable]] = None,
resource_prefix: Optional[str] = None) -> None:
"""
:param pulumi.Input[str] path: The path to the chart directory which contains the
`Chart.yaml` file.
Expand All @@ -273,11 +290,14 @@ def __init__(self,
:param Optional[List[Callable]] transformations: Optional list of transformations to apply to
resources that will be created by this chart prior to creation. Allows customization of the
chart behaviour without directly modifying the chart itself.
:param Optional[str] resource_prefix: An optional prefix for the auto-generated resource names.
Example: A resource created with resource_prefix="foo" would produce a resource named "foo-resourceName".
lblackstone marked this conversation as resolved.
Show resolved Hide resolved
"""
self.path = path
self.namespace = namespace
self.values = values
self.transformations = transformations
self.resource_prefix = resource_prefix


def _parse_chart(all_config: Tuple[str, Union[ChartOpts, LocalChartOpts], pulumi.ResourceOptions]) -> pulumi.Output:
Expand Down Expand Up @@ -402,6 +422,9 @@ def __init__(self, release_name: str,

__props__ = dict()

if config.resource_prefix:
release_name = f"{config.resource_prefix}-{release_name}"

super(Chart, self).__init__(
"kubernetes:helm.sh/v2:Chart",
release_name,
Expand Down
13 changes: 11 additions & 2 deletions sdk/nodejs/helm/v2/helm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ interface BaseChartOpts {
* creation. Allows customization of the chart behaviour without directly modifying the chart itself.
*/
transformations?: ((o: any, opts: pulumi.CustomResourceOptions) => void)[];

/**
* An optional prefix for the auto-generated resource names.
* Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName".
*/
resourcePrefix?: string
}

export interface ChartOpts extends BaseChartOpts {
Expand Down Expand Up @@ -107,6 +113,9 @@ export class Chart extends yaml.CollectionComponentResource {
config: ChartOpts | LocalChartOpts,
opts?: pulumi.ComponentResourceOptions
) {
if (config.resourcePrefix !== undefined) {
releaseName = `${config.resourcePrefix}-${releaseName}`
}
super("kubernetes:helm.sh/v2:Chart", releaseName, config, opts);

const allConfig = pulumi.output(config);
Expand Down Expand Up @@ -180,7 +189,7 @@ export class Chart extends yaml.CollectionComponentResource {
parseTemplate(
yamlStream: string,
transformations: ((o: any, opts: pulumi.CustomResourceOptions) => void)[] | undefined,
dependsOn: pulumi.Resource[]
dependsOn: pulumi.Resource[],
): pulumi.Output<{ [key: string]: pulumi.CustomResource }> {
// NOTE: We must manually split the YAML stream because of js-yaml#456. Perusing the
// code and the spec, it looks like a YAML stream is delimited by `^---`, though it is
Expand All @@ -196,7 +205,7 @@ export class Chart extends yaml.CollectionComponentResource {
return yaml.parse(
{
yaml: objs.map(o => jsyaml.safeDump(o)),
transformations: transformations || []
transformations: transformations || [],
},
{ parent: this, dependsOn: dependsOn }
);
Expand Down
25 changes: 24 additions & 1 deletion sdk/python/pulumi_kubernetes/helm/v2/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ class ChartOpts:
creation. Allows customization of the chart behaviour without directly modifying the chart itself.
"""

resource_prefix: Optional[str]
"""
Optional prefix for the auto-generated resource names.
Example: A resource created with resource_prefix="foo" would produce a resource named "foo-resourceName".
"""

repo: Optional[pulumi.Input[str]]
"""
The repository containing the desired chart. If not provided, [chart] must be a fully qualified
Expand All @@ -206,6 +212,7 @@ def __init__(self,
namespace: Optional[pulumi.Input[str]] = None,
values: Optional[pulumi.Inputs] = None,
transformations: Optional[List[Callable]] = None,
resource_prefix: Optional[str] = None,
repo: Optional[pulumi.Input[str]] = None,
version: Optional[pulumi.Input[str]] = None,
fetch_opts: Optional[pulumi.Input[FetchOpts]] = None) -> None:
Expand All @@ -218,6 +225,8 @@ def __init__(self,
:param Optional[List[Callable] transformations: Optional list of transformations to apply to
resources that will be created by this chart prior to creation. Allows customization of the
chart behaviour without directly modifying the chart itself.
:param Optional[str] resource_prefix: An optional prefix for the auto-generated resource names.
Example: A resource created with resource_prefix="foo" would produce a resource named "foo-resourceName".
:param Optional[pulumi.Input[str]] repo: The repository containing the desired chart. If not
provided, [chart] must be a fully qualified chart URL or repo/chartname.
:param Optional[pulumi.Input[str]] version: The version of the chart to deploy. If not provided,
Expand All @@ -229,6 +238,7 @@ def __init__(self,
self.namespace = namespace
self.values = values
self.transformations = transformations
self.resource_prefix = resource_prefix
self.repo = repo
self.version = version
self.fetch_opts = fetch_opts
Expand Down Expand Up @@ -260,11 +270,18 @@ class LocalChartOpts:
creation. Allows customization of the chart behaviour without directly modifying the chart itself.
"""

resource_prefix: Optional[str]
"""
Optional prefix for the auto-generated resource names.
Example: A resource created with resource_prefix="foo" would produce a resource named "foo-resourceName".
"""

def __init__(self,
path: pulumi.Input[str],
namespace: Optional[pulumi.Input[str]] = None,
values: Optional[pulumi.Inputs] = None,
transformations: Optional[List[Callable]] = None) -> None:
transformations: Optional[List[Callable]] = None,
resource_prefix: Optional[str] = None) -> None:
"""
:param pulumi.Input[str] path: The path to the chart directory which contains the
`Chart.yaml` file.
Expand All @@ -273,11 +290,14 @@ def __init__(self,
:param Optional[List[Callable]] transformations: Optional list of transformations to apply to
resources that will be created by this chart prior to creation. Allows customization of the
chart behaviour without directly modifying the chart itself.
:param Optional[str] resource_prefix: An optional prefix for the auto-generated resource names.
Example: A resource created with resource_prefix="foo" would produce a resource named "foo-resourceName".
"""
self.path = path
self.namespace = namespace
self.values = values
self.transformations = transformations
self.resource_prefix = resource_prefix


def _parse_chart(all_config: Tuple[str, Union[ChartOpts, LocalChartOpts], pulumi.ResourceOptions]) -> pulumi.Output:
Expand Down Expand Up @@ -402,6 +422,9 @@ def __init__(self, release_name: str,

__props__ = dict()

if config.resource_prefix:
release_name = f"{config.resource_prefix}-{release_name}"

super(Chart, self).__init__(
"kubernetes:helm.sh/v2:Chart",
release_name,
Expand Down
16 changes: 14 additions & 2 deletions tests/examples/examples_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
// Copyright 2016-2018, Pulumi Corporation. All rights reserved.
// Copyright 2016-2019, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package examples

Expand Down Expand Up @@ -157,7 +169,7 @@ func TestExamples(t *testing.T) {
t *testing.T, stackInfo integration.RuntimeValidationStackInfo,
) {
assert.NotNil(t, stackInfo.Deployment)
assert.Equal(t, 9, len(stackInfo.Deployment.Resources))
assert.Equal(t, 15, len(stackInfo.Deployment.Resources))
lblackstone marked this conversation as resolved.
Show resolved Hide resolved
},
}),

Expand Down
36 changes: 36 additions & 0 deletions tests/examples/helm-local/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,39 @@ const nginx = new k8s.helm.v2.Chart("simple-nginx-local", {
const frontendServiceSpec = pulumi.all([namespaceName, nginx]).apply(([nsName, nginx]) =>
nginx.getResourceProperty("v1/Service", nsName, "simple-nginx-local-nginx", "spec"));
export const frontendServiceIP = frontendServiceSpec.clusterIP;

// Deploy a duplicate chart with a different resource prefix to verify that multiple instances of the Chart
// can be managed in the same stack.
new k8s.helm.v2.Chart("simple-nginx-local", {
// Represents chart `stable/nginx-lego@v0.3.1`.
path: "nginx-lego",
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 }
},
transformations: [
// Make every service private to the cluster, i.e., turn all services into ClusterIP instead of
// LoadBalancer.
(obj: any) => {
if (obj.kind == "Service" && obj.apiVersion == "v1") {
if (obj.spec && obj.spec.type && obj.spec.type == "LoadBalancer") {
obj.spec.type = "ClusterIP";
}
}
},
// Put every resource in the created namespace.
(obj: any) => {
if (obj.metadata !== undefined) {
obj.metadata.namespace = namespaceName
} else {
obj.metadata = {namespace: namespaceName}
}
}
],
resourcePrefix: "dup"
lblackstone marked this conversation as resolved.
Show resolved Hide resolved
});

6 changes: 5 additions & 1 deletion tests/examples/python/helm/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@
# limitations under the License.
from pulumi_kubernetes.helm.v2 import Chart, ChartOpts

Chart("nginx-ingress", ChartOpts("stable/nginx-ingress"))
Chart("unbound", ChartOpts("stable/unbound"))

# Deploy a duplicate chart with a different resource prefix to verify that multiple instances of the Chart
# can be managed in the same stack.
Chart("unbound", ChartOpts("stable/unbound", resource_prefix="dup"))
9 changes: 5 additions & 4 deletions tests/examples/python/python_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestYaml(t *testing.T) {
ExpectRefreshChanges: true,
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
assert.NotNil(t, stackInfo.Deployment)
assert.Equal(t, 24, len(stackInfo.Deployment.Resources))
assert.Equal(t, 14, len(stackInfo.Deployment.Resources))

sort.Slice(stackInfo.Deployment.Resources, func(i, j int) bool {
ri := stackInfo.Deployment.Resources[i]
Expand Down Expand Up @@ -139,11 +139,11 @@ func TestYaml(t *testing.T) {
// first ConfigFile.

// Verify the provider resource.
provRes := stackInfo.Deployment.Resources[22]
provRes := stackInfo.Deployment.Resources[12]
assert.True(t, providers.IsProviderType(provRes.URN.Type()))

// Verify root resource.
stackRes := stackInfo.Deployment.Resources[23]
stackRes := stackInfo.Deployment.Resources[13]
lblackstone marked this conversation as resolved.
Show resolved Hide resolved
assert.Equal(t, resource.RootStackType, stackRes.URN.Type())

// TODO[pulumi/pulumi#2782] Testing of secrets blocked on a bug in Python support for secrets.
Expand Down Expand Up @@ -288,7 +288,8 @@ func TestHelm(t *testing.T) {
t.FailNow()
}
options := baseOptions.With(integration.ProgramTestOptions{
Dir: filepath.Join(cwd, "helm"),
Dir: filepath.Join(cwd, "helm"),
ExpectRefreshChanges: true,
lblackstone marked this conversation as resolved.
Show resolved Hide resolved
})
integration.ProgramTest(t, &options)
}
14 changes: 7 additions & 7 deletions tests/examples/python/yaml-test/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ def secret_status(obj, opts):
],
)

# Create resources from standard Kubernetes guestbook YAML example in the test namespace.
# Create resources from a simple YAML manifest in a test namespace.
cf_url = ConfigFile(
"guestbook",
file_id="https://raw.githubusercontent.com/pulumi/pulumi-kubernetes/master/tests/examples/yaml-guestbook/yaml"
"/guestbook.yaml",
"deployment",
file_id="https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/controllers/"
"nginx-deployment.yaml",
transformations=[set_namespace(ns)],
)
cf_url2 = ConfigFile(
"guestbook",
file_id="https://raw.githubusercontent.com/pulumi/pulumi-kubernetes/master/tests/examples/yaml-guestbook/yaml"
"/guestbook.yaml",
"deployment",
file_id="https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/controllers/"
"nginx-deployment.yaml",
transformations=[set_namespace(ns2)],
resource_prefix="dup"
)
16 changes: 8 additions & 8 deletions tests/integration/yaml-url/step1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ new k8s.yaml.ConfigFile("guestbook", {
new k8s.yaml.ConfigFile("guestbook", {
file: "https://raw.githubusercontent.com/pulumi/pulumi-kubernetes/master/tests/examples/yaml-guestbook/yaml/guestbook.yaml",
transformations: [
(obj: any) => {
if (obj !== undefined) {
if (obj.metadata !== undefined) {
obj.metadata.namespace = namespace2.metadata.name;
} else {
obj.metadata = {namespace: namespace2.metadata.name}
(obj: any) => {
if (obj !== undefined) {
if (obj.metadata !== undefined) {
obj.metadata.namespace = namespace2.metadata.name;
} else {
obj.metadata = {namespace: namespace2.metadata.name}
}
}
}
}
],
],
resourcePrefix: "dup"
lblackstone marked this conversation as resolved.
Show resolved Hide resolved
});