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

Support chart.v3 previews when cluster is unreachable #2992

Merged
merged 6 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 12 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Unreleased

- Fix Release behavior to deep merge `valueYamlFiles` to match Helm. (https://github.com/pulumi/pulumi-kubernetes/pull/2963)
- Fix Chart previews when the cluster is unreachable. (https://github.com/pulumi/pulumi-kubernetes/pull/2992)
- Fix a panic that could occur when a missing field became `null`. (https://github.com/pulumi/pulumi-kubernetes/issues/1970)
- Add field manager's name to server-side apply conflict errors. (https://github.com/pulumi/pulumi-kubernetes/pull/2983)

Expand Down Expand Up @@ -58,32 +59,32 @@ Note that transformations aren't supported in this release (see https://github.c
- Fix option propagation in component resources (Go SDK) (https://github.com/pulumi/pulumi-kubernetes/pull/2709)

### Breaking Changes
In previous versions of the pulumi-kubernetes .NET SDK, the `ConfigFile` and `ConfigGroup` component resources inadvertently assigned the wrong parent to the child resource(s).
In previous versions of the pulumi-kubernetes .NET SDK, the `ConfigFile` and `ConfigGroup` component resources inadvertently assigned the wrong parent to the child resource(s).
This would happen when the component resource itself had a parent; the child would be assigned that same parent. This also had the effect of disregarding the component resource's provider in favor of the parent's provider.

For example, here's a before/after look at the component hierarchy:

Before:

```
├─ pkg:index:MyComponent parent
│ ├─ kubernetes:core/v1:ConfigMap cg-options-cg-options-cm-1
├─ pkg:index:MyComponent parent
│ ├─ kubernetes:core/v1:ConfigMap cg-options-cg-options-cm-1
│ ├─ kubernetes:yaml:ConfigFile cg-options-testdata/options/configgroup/manifest.yaml
│ ├─ kubernetes:core/v1:ConfigMap cg-options-configgroup-cm-1
│ ├─ kubernetes:yaml:ConfigFile cg-options-testdata/options/configgroup/empty.yaml
│ └─ kubernetes:yaml:ConfigGroup cg-options
│ ├─ kubernetes:core/v1:ConfigMap cg-options-configgroup-cm-1
│ ├─ kubernetes:yaml:ConfigFile cg-options-testdata/options/configgroup/empty.yaml
│ └─ kubernetes:yaml:ConfigGroup cg-options
```

After:

```
└─ pkg:index:MyComponent parent
└─ kubernetes:yaml:ConfigGroup cg-options
└─ pkg:index:MyComponent parent
└─ kubernetes:yaml:ConfigGroup cg-options
├─ kubernetes:yaml:ConfigFile cg-options-testdata/options/configgroup/manifest.yaml
│ └─ kubernetes:core/v1:ConfigMap cg-options-configgroup-cm-1
└─ kubernetes:core/v1:ConfigMap cg-options-cg-options-cm-1
│ └─ kubernetes:core/v1:ConfigMap cg-options-configgroup-cm-1
└─ kubernetes:core/v1:ConfigMap cg-options-cg-options-cm-1
```

This release addresses this issue and attempts to heal existing stacks using aliases. This is effective at avoiding a replacement except in the case where the child was created with the wrong provider. In this case, __Pulumi will suggest a replacement of the child resource(s), such that they use the correct provider__.

## 4.6.1 (December 14, 2023)
Expand Down
12 changes: 8 additions & 4 deletions provider/pkg/provider/invoke_helm_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package provider

import (
"context"
"errors"
"fmt"
"net/url"
Expand All @@ -24,6 +25,8 @@ import (
"strings"

"github.com/pulumi/pulumi-kubernetes/provider/v4/pkg/clients"
"github.com/pulumi/pulumi-kubernetes/provider/v4/pkg/host"
"github.com/pulumi/pulumi/sdk/v3/go/common/diag"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
logger "github.com/pulumi/pulumi/sdk/v3/go/common/util/logging"
"helm.sh/helm/v3/pkg/action"
Expand Down Expand Up @@ -77,7 +80,7 @@ type HelmChartOpts struct {

// helmTemplate performs Helm fetch/pull + template operations and returns the resulting YAML manifest based on the
// provided chart options.
func helmTemplate(opts HelmChartOpts, clientSet *clients.DynamicClientSet) (string, error) {
func helmTemplate(h host.HostClient, opts HelmChartOpts, clientSet *clients.DynamicClientSet) (string, error) {
tempDir, err := os.MkdirTemp("", "helm")
if err != nil {
return "", err
Expand All @@ -87,6 +90,7 @@ func helmTemplate(opts HelmChartOpts, clientSet *clients.DynamicClientSet) (stri
chart := &chart{
opts: opts,
chartDir: tempDir,
host: h,
}

// If the 'home' option is specified, set the HELM_HOME env var for the duration of the invoke and then reset it
Expand Down Expand Up @@ -130,6 +134,7 @@ type chart struct {
opts HelmChartOpts
chartDir string
helmHome *string // Previous setting of HELM_HOME env var (if any)
host host.HostClient
}

// fetch runs the `helm fetch` action to fetch a Chart from a remote URL.
Expand Down Expand Up @@ -259,9 +264,8 @@ func (c *chart) template(clientSet *clients.DynamicClientSet) (string, error) {
}

if clientSet != nil && clientSet.DiscoveryClientCached != nil {
err = setKubeVersionAndAPIVersions(clientSet, installAction)
if err != nil {
return "", err
if err := setKubeVersionAndAPIVersions(clientSet, installAction); err != nil {
_ = c.host.Log(context.Background(), diag.Warning, "", fmt.Sprintf("unable to determine cluster's API version: %s", err))
}
}

Expand Down
2 changes: 1 addition & 1 deletion provider/pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ func (k *kubeProvider) Invoke(ctx context.Context,
return nil, fmt.Errorf("failed to unmarshal 'jsonOpts': %w", err)
}

text, err := helmTemplate(opts, k.clientSet)
text, err := helmTemplate(k.host, opts, k.clientSet)
if err != nil {
return nil, fmt.Errorf("failed to generate YAML for specified Helm chart: %w", err)
}
Expand Down
3 changes: 3 additions & 0 deletions tests/sdk/nodejs/helm-preview-unreachable/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: helm-preview-unreachable
runtime: nodejs
description: A minimal Kubernetes TypeScript Pulumi program
32 changes: 32 additions & 0 deletions tests/sdk/nodejs/helm-preview-unreachable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as k8s from "@pulumi/kubernetes";

const kubeconfig = `
apiVersion: v1
clusters:
- cluster:
server: 127.0.0.1:1
name: helm-preview-unreachable
contexts:
- context:
cluster: helm-preview-unreachable
name: default
current-context: default
kind: Config
`;

const namespace = new k8s.core.v1.Namespace("ns", {});

const provider = new k8s.Provider("k8s", { kubeconfig: kubeconfig });

new k8s.helm.v3.Chart(
"template",
{
chart: "redis",
fetchOpts: {
repo: "https://raw.githubusercontent.com/bitnami/charts/eb5f9a9513d987b519f0ecd732e7031241c50328/bitnami",
},
version: "13.0.0",
namespace: namespace.metadata.name,
},
{ provider }
);
11 changes: 11 additions & 0 deletions tests/sdk/nodejs/helm-preview-unreachable/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "helm-preview-unreachable",
"devDependencies": {
"@types/node": "^10.0.0"
},
"dependencies": {
"@pulumi/pulumi": "^3.0.0",
"@pulumi/kubernetes": "latest",
"@pulumi/random": "^4.15.1"
}
}
18 changes: 18 additions & 0 deletions tests/sdk/nodejs/helm-preview-unreachable/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts"
]
}
11 changes: 11 additions & 0 deletions tests/sdk/nodejs/helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,14 @@ func clearGrpcLog(t *testing.T, pt *pulumitest.PulumiTest) {
t.Fatalf("failed to clear gRPC log: %s", err)
}
}

func TestPreviewWithUnreachableCluster(t *testing.T) {
t.Parallel()

test := pulumitest.NewPulumiTest(t, "helm-preview-unreachable")
t.Cleanup(func() {
test.Destroy()
})

test.Preview()
}
Loading