Skip to content

Commit

Permalink
Add experimental helmChart support to kustomize.Directory (#2471)
Browse files Browse the repository at this point in the history
This adds experimental support for the `helmChart` plugin feature for kustomize. Enable the feature using `PULUMI_K8S_KUSTOMIZE_HELM="true"`. Requires the `helm` binary to be on the system PATH.
---------

Co-authored-by: Levi Blackstone <levi@pulumi.com>
  • Loading branch information
jturolla and lblackstone authored Jun 29, 2023
1 parent 9060c68 commit 34fd609
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 0 deletions.
21 changes: 21 additions & 0 deletions provider/pkg/provider/invoke_kustomize.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
package provider

import (
"fmt"
"os"
"strings"

"github.com/pkg/errors"
"github.com/pulumi/pulumi-kubernetes/provider/v3/pkg/clients"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)

Expand Down Expand Up @@ -51,10 +55,27 @@ func kustomizeDirectory(directory string, clientSet *clients.DynamicClientSet) (
opts := krusty.MakeDefaultOptions()
opts.DoLegacyResourceSort = true

// TODO: kustomize helmChart support is currently enabled via an undocumented feature flag.
// See https://github.com/pulumi/pulumi-kubernetes/issues/2470 for additional details.
enableHelmChartSupport := false
helmPath := "helm" // TODO: support this as a parameter to kustomize.Directory; this won't work for Windows
if v, ok := os.LookupEnv("PULUMI_K8S_KUSTOMIZE_HELM"); ok && cmdutil.IsTruthy(v) {
enableHelmChartSupport = true
}
// Add support for helmCharts plugin
// See https://github.com/kubernetes-sigs/kustomize/blob/v3.3.1/examples/chart.md for more details.
if enableHelmChartSupport {
opts.PluginConfig = types.EnabledPluginConfig(types.BploUseStaticallyLinked)
opts.PluginConfig.HelmConfig.Command = helmPath
}

k := krusty.MakeKustomizer(opts)

rm, err := k.Run(fSys, path)
if err != nil {
if enableHelmChartSupport && strings.Contains(err.Error(), `(is 'helm' installed?)`) {
err = fmt.Errorf("the helmCharts feature requires %q binary to be on the system PATH", helmPath)
}
return nil, errors.Wrapf(err, "kustomize failed for directory %q", path)
}

Expand Down
3 changes: 3 additions & 0 deletions tests/sdk/nodejs/kustomizeHelmChart/step1/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: kustomizeHelmChart
runtime: nodejs
description: Test kustomize helmChart support
35 changes: 35 additions & 0 deletions tests/sdk/nodejs/kustomizeHelmChart/step1/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2016-2023, 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.

import * as k8s from "@pulumi/kubernetes";

const provider = new k8s.Provider("k8s");

// Create test namespace to allow test parallelism.
const namespace = new k8s.core.v1.Namespace("test-namespace", {}, {provider});

new k8s.kustomize.Directory("moria", {
directory: "moria/base",
transformations: [
(obj: any) => {
if (obj !== undefined) {
if (obj.metadata !== undefined) {
obj.metadata.namespace = namespace;
} else {
obj.metadata = {namespace: namespace};
}
}
},
]
}, {provider});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
helmCharts:
- name: minecraft
includeCRDs: false
valuesInline:
minecraftServer:
eula: true
difficulty: hard
rcon:
enabled: true
releaseName: moria
version: 3.1.3
repo: https://itzg.github.io/minecraft-server-charts
14 changes: 14 additions & 0 deletions tests/sdk/nodejs/kustomizeHelmChart/step1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "kustomize",
"version": "0.1.0",
"dependencies": {
"@pulumi/pulumi": "latest"
},
"devDependencies": {
"@types/node": "^9.3.0"
},
"peerDependencies": {
"@pulumi/kubernetes": "latest"
},
"license": "MIT"
}
21 changes: 21 additions & 0 deletions tests/sdk/nodejs/kustomizeHelmChart/step1/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"outDir": "bin",
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"sourceMap": true,
"stripInternal": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true,
"strictNullChecks": true
},
"files": [
"index.ts"
]
}
25 changes: 25 additions & 0 deletions tests/sdk/nodejs/nodejs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,31 @@ func TestKustomize(t *testing.T) {
integration.ProgramTest(t, &test)
}

// TestKustomizeHelmChart verifies the helmChart plugin support for Kustomize. This requires the `helm` binary to be
// on the system PATH to succeed.
// Example based on https://github.com/kubernetes-sigs/kustomize/blob/v3.3.1/examples/chart.md
func TestKustomizeHelmChart(t *testing.T) {
test := baseOptions.With(integration.ProgramTestOptions{
Dir: filepath.Join("kustomizeHelmChart", "step1"),
// Just test that the plugin integration is working with preview
SkipUpdate: true,
SkipRefresh: true,
SkipEmptyPreviewUpdate: true,
SkipExportImport: true,
OrderedConfig: []integration.ConfigValue{
{
Key: "pulumi:disable-default-providers[0]",
Value: "kubernetes",
Path: true,
},
},
Env: []string{
"PULUMI_K8S_KUSTOMIZE_HELM=true", // This experimental feature is currently gated behind a feature flag.
},
})
integration.ProgramTest(t, &test)
}

func TestNamespace(t *testing.T) {
var nmPodName, defaultPodName string
test := baseOptions.With(integration.ProgramTestOptions{
Expand Down

0 comments on commit 34fd609

Please sign in to comment.