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

#2563: Expose Helm --kube-version argument for contextless diffs #2593

Merged
merged 9 commits into from
Oct 19, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ yarn.lock
ci-scripts
/nuget/
**/.DS_Store
dist

sdk/java/build
sdk/java/.gradle
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Unreleased

- helm.v3.ChartOpts: Add KubeVersion field that can be passed to avoid asking the kubernetes API server for the version (https://github.com/pulumi/pulumi-kubernetes/pull/2593)

## 4.4.0 (October 12, 2023)

- Fix normalizing fields with empty objects/slices (https://github.com/pulumi/pulumi-kubernetes/pull/2576)
Expand Down
5 changes: 5 additions & 0 deletions provider/pkg/gen/_go-templates/helm/v3/pulumiTypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ type ChartArgs struct {
SkipCRDRendering pulumi.BoolInput
// The optional namespace to install chart resources into.
Namespace pulumi.StringInput
// By default, the kubernetes version is derived from your k8s context, this allows it to be overridden.
// Warning: This option should not be used unless you have a good reason to not use the auto-discovered
// version as it is much more bug-prone.
KubeVersion pulumi.StringInput
// Overrides for chart values.
Values pulumi.MapInput
// Transformations is an optional list of transformations to apply to Kubernetes resource definitions
Expand Down Expand Up @@ -167,6 +171,7 @@ type chartArgs struct {
Repo string `json:"repo,omitempty" pulumi:"repo"`
Chart string `json:"chart,omitempty" pulumi:"chart"`
Version string `json:"version,omitempty" pulumi:"version"`
KubeVersion string `json:"kube_version,omitempty" pulumi:"kubeVersion"`
FetchArgs fetchArgs `json:"fetch_opts,omitempty" pulumi:"fetchArgs"`
Path string `json:"path,omitempty" pulumi:"path"`
}
Expand Down
7 changes: 7 additions & 0 deletions provider/pkg/gen/dotnet-templates/helm/ChartBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,13 @@ public InputList<string> ApiVersions
/// </summary>
public Input<string>? Namespace { get; set; }

/// <summary>
/// By default, the kubernetes version is derived from your k8s context, this allows it to be overridden.
/// Warning: This option should not be used unless you have a good reason to not use the auto-discovered
/// version as it is much more bug-prone.
/// </summary>
public Input<string>? KubeVersion { get; set; }

private InputMap<object>? _values;

/// <summary>
Expand Down
25 changes: 14 additions & 11 deletions provider/pkg/gen/dotnet-templates/helm/Unwraps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ internal class BaseChartArgsUnwrap
public bool? SkipCRDRendering { get; set; }
public bool? SkipAwait { get; set; }
public string? Namespace { get; set; }
public string? KubeVersion { get; set; }
public ImmutableDictionary<string, object> Values { get; set; } = null!;
public List<TransformationAction> Transformations { get; set; } = null!;
public string? ResourcePrefix { get; set; }
Expand Down Expand Up @@ -70,24 +71,25 @@ internal static class Extensions
public static Output<Union<ChartArgsUnwrap, LocalChartArgsUnwrap>> Unwrap(this Union<ChartArgs, LocalChartArgs> options)
{
return options.Match(
v => Output.Tuple(v.ApiVersions, v.Namespace.ToNullable(), v.Values, v.Repo.ToNullable(), v.Chart, v.Version.ToNullable(), v.FetchOptions.Unwrap(), new InputList<bool?> { v.IncludeTestHookResources.ToNullable(), v.SkipCRDRendering.ToNullable(), v.SkipAwait.ToNullable() }).Apply(vs =>
v => Output.Tuple(v.ApiVersions, v.Values, v.Chart, v.FetchOptions.Unwrap(), new InputList<string?> { v.Namespace.ToNullable(), v.Repo.ToNullable(), v.Version.ToNullable(), v.KubeVersion.ToNullable() }, new InputList<bool?> { v.IncludeTestHookResources.ToNullable(), v.SkipCRDRendering.ToNullable(), v.SkipAwait.ToNullable() }).Apply(vs =>
Union<ChartArgsUnwrap, LocalChartArgsUnwrap>.FromT0(
new ChartArgsUnwrap
{
ApiVersions = vs.Item1,
Namespace = vs.Item2,
Values = vs.Item3,
Values = vs.Item2,
Chart = vs.Item3,
FetchOptions = vs.Item4,
Namespace = vs.Item5[0],
Repo = vs.Item5[1],
Version = vs.Item5[2],
KubeVersion = vs.Item5[3],
IncludeTestHookResources = vs.Item6[0],
SkipCRDRendering = vs.Item6[1],
SkipAwait = vs.Item6[2],
Transformations = v.Transformations,
ResourcePrefix = v.ResourcePrefix,
Repo = vs.Item4,
Chart = vs.Item5,
Version = vs.Item6,
FetchOptions = vs.Item7,
IncludeTestHookResources = vs.Item8[0],
SkipCRDRendering = vs.Item8[1],
SkipAwait = vs.Item8[2]
})),
v => Output.Tuple(v.ApiVersions, v.IncludeTestHookResources.ToNullable(), v.SkipCRDRendering.ToNullable(), v.SkipAwait.ToNullable(), v.Namespace.ToNullable(), v.Values).Apply(vs =>
v => Output.Tuple(v.ApiVersions, v.IncludeTestHookResources.ToNullable(), v.SkipCRDRendering.ToNullable(), v.SkipAwait.ToNullable(), v.Namespace.ToNullable(), v.Values, v.KubeVersion.ToNullable()).Apply(vs =>
Union<ChartArgsUnwrap, LocalChartArgsUnwrap>.FromT1(
new LocalChartArgsUnwrap
{
Expand All @@ -97,6 +99,7 @@ internal static class Extensions
SkipAwait = vs.Item4,
Namespace = vs.Item5,
Values = vs.Item6,
KubeVersion = vs.Item7,
Transformations = v.Transformations,
ResourcePrefix = v.ResourcePrefix,
Path = v.Path
Expand Down
4 changes: 4 additions & 0 deletions provider/pkg/gen/dotnet-templates/helm/v3/Chart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ private static string GetName(Union<ChartArgs, LocalChartArgs> config, string re
SkipCRDRendering = cfgBase.SkipCRDRendering,
Namespace = cfgBase.Namespace,
Values = cfgBase.Values,
KubeVersion = cfgBase.KubeVersion,
ReleaseName = releaseName,
Repo = cfg.Repo,
Chart = cfg.Chart,
Expand Down Expand Up @@ -353,6 +354,7 @@ private static string GetName(Union<ChartArgs, LocalChartArgs> config, string re
SkipCRDRendering = cfgBase.SkipCRDRendering,
Namespace = cfgBase.Namespace,
Values = cfgBase.Values,
KubeVersion = cfgBase.KubeVersion,
ReleaseName = releaseName,
Path = cfg.Path,
};
Expand Down Expand Up @@ -396,6 +398,8 @@ internal class JsonOpts
[JsonPropertyName("chart")]
public string? Chart { get; set; }
[JsonPropertyName("version")]
public string? KubeVersion { get; set; }
[JsonPropertyName("kube_version")]
public string? Version { get; set; }
[JsonPropertyName("fetch_opts")]
public JsonOptsFetch? FetchOptions { get; set; }
Expand Down
10 changes: 10 additions & 0 deletions provider/pkg/gen/nodejs-templates/helm/v3/helm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ export class Chart extends yaml.CollectionComponentResource {
obj["skip_crd_rendering"] = value;
break;
}
case "kubeVersion": {
obj["kube_version"] = value;
break;
}
case "releaseName": {
obj["release_name"] = value;
break;
Expand Down Expand Up @@ -277,6 +281,12 @@ interface BaseChartOpts {
* The optional namespace to install chart resources into.
*/
namespace?: pulumi.Input<string>;
/**
* By default, the kubernetes version is derived from your k8s context, this allows it to be overridden.
* Warning: This option should not be used unless you have a good reason to not use the auto-discovered
* version as it is much more bug-prone.
*/
kubeVersion?: pulumi.Input<string>;
/**
* Overrides for chart values.
*/
Expand Down
30 changes: 25 additions & 5 deletions provider/pkg/gen/python-templates/helm/v3/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,12 @@ class BaseChartOpts:
Warning: This option should not be used if you have resources depending on Outputs from the Chart.
"""

kube_version: Optional[pulumi.Input[str]]
"""
By default, the kubernetes version is derived from your k8s context, this allows it to be overridden.
Warning: This option should not be used unless you have a good reason to not use the auto-discovered version as it is much more bug-prone.
"""

def __init__(self,
namespace: Optional[pulumi.Input[str]] = None,
values: Optional[pulumi.Inputs] = None,
Expand All @@ -423,7 +429,8 @@ def __init__(self,
api_versions: Optional[Sequence[pulumi.Input[str]]] = None,
include_test_hook_resources: Optional[pulumi.Input[bool]] = None,
skip_crd_rendering: Optional[pulumi.Input[bool]] = None,
skip_await: Optional[pulumi.Input[bool]] = None):
skip_await: Optional[pulumi.Input[bool]] = None,
kube_version: Optional[pulumi.Input[str]] = None):
"""
:param Optional[pulumi.Input[str]] namespace: Optional namespace to install chart resources into.
:param Optional[pulumi.Inputs] values: Optional overrides for chart values.
Expand All @@ -442,6 +449,9 @@ def __init__(self,
:param Optional[pulumi.Input[bool]] skip_await: Skip await logic for all resources in this Chart. Resources
will be marked ready as soon as they are created. Warning: This option should not be used if you have
resources depending on Outputs from the Chart.
:param Optional[pulumi.Input[str]] kube_version: By default, the kubernetes version is derived from your k8s
context, this allows it to be overridden. Warning: This option should not be used unless you have a
good reason to not use the auto-discovered version as it is much more bug-prone.
"""
self.namespace = namespace
self.include_test_hook_resources = include_test_hook_resources
Expand All @@ -451,6 +461,7 @@ def __init__(self,
self.transformations = transformations
self.resource_prefix = resource_prefix
self.api_versions = api_versions
self.kube_version = kube_version

def to_json(self):
return pulumi.Output.from_input(self.__dict__).apply(
Expand Down Expand Up @@ -497,7 +508,8 @@ def __init__(self,
api_versions: Optional[Sequence[pulumi.Input[str]]] = None,
include_test_hook_resources: Optional[pulumi.Input[bool]] = None,
skip_crd_rendering: Optional[pulumi.Input[bool]] = None,
skip_await: Optional[pulumi.Input[bool]] = None):
skip_await: Optional[pulumi.Input[bool]] = None,
kube_version: Optional[pulumi.Input[str]] = None):
"""
:param pulumi.Input[str] chart: The name of the chart to deploy. If `repo` is provided, this chart name
will be prefixed by the repo name.
Expand Down Expand Up @@ -526,9 +538,12 @@ def __init__(self,
:param Optional[pulumi.Input[bool]] skip_await: Skip await logic for all resources in this Chart. Resources
will be marked ready as soon as they are created. Warning: This option should not be used if you have
resources depending on Outputs from the Chart.
:param Optional[pulumi.Input[str]] kube_version: By default, the kubernetes version is derived from your k8s
context, this allows it to be overridden. Warning: This option should not be used unless you have a
good reason to not use the auto-discovered version as it is much more bug-prone.
"""
super(ChartOpts, self).__init__(namespace, values, transformations, resource_prefix, api_versions,
include_test_hook_resources, skip_crd_rendering, skip_await)
include_test_hook_resources, skip_crd_rendering, skip_await, kube_version)
self.chart = chart
self.repo = repo
self.version = version
Expand All @@ -554,7 +569,9 @@ def __init__(self,
api_versions: Optional[Sequence[pulumi.Input[str]]] = None,
include_test_hook_resources: Optional[pulumi.Input[bool]] = None,
skip_crd_rendering: Optional[pulumi.Input[bool]] = None,
skip_await: Optional[pulumi.Input[bool]] = None):
skip_await: Optional[pulumi.Input[bool]] = None,
kube_version: Optional[pulumi.Input[str]] = None):

"""
:param pulumi.Input[str] path: The path to the chart directory which contains the
`Chart.yaml` file.
Expand All @@ -575,10 +592,13 @@ def __init__(self,
:param Optional[pulumi.Input[bool]] skip_await: Skip await logic for all resources in this Chart. Resources
will be marked ready as soon as they are created. Warning: This option should not be used if you have
resources depending on Outputs from the Chart.
:param Optional[pulumi.Input[str]] kube_version: By default, the kubernetes version is derived from your k8s
context, this allows it to be overridden. Warning: This option should not be used unless you have a
good reason to not use the auto-discovered version as it is much more bug-prone.
"""

super(LocalChartOpts, self).__init__(namespace, values, transformations, resource_prefix, api_versions,
include_test_hook_resources, skip_crd_rendering, skip_await)
include_test_hook_resources, skip_crd_rendering, skip_await, kube_version)
self.path = path


Expand Down
53 changes: 32 additions & 21 deletions provider/pkg/provider/invoke_helm_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type HelmChartOpts struct {
Version string `json:"version,omitempty"`
HelmChartDebug bool `json:"helm_chart_debug,omitempty"`
HelmRegistryConfig string `json:"helm_registry_config,omitempty"`
KubeVersion string `json:"kube_version,omitempty"`
}

// helmTemplate performs Helm fetch/pull + template operations and returns the resulting YAML manifest based on the
Expand Down Expand Up @@ -242,39 +243,49 @@ func (c *chart) template(clientSet *clients.DynamicClientSet) (string, error) {
installAction.ReleaseName = c.opts.ReleaseName
installAction.Version = c.opts.Version

// Preserve backward compatibility
if c.opts.KubeVersion != "" {
var kubeVersion *chartutil.KubeVersion
if kubeVersion, err = chartutil.ParseKubeVersion(c.opts.KubeVersion); err != nil {
return "", fmt.Errorf("could not get parse kube_version %q from chart options: %w", c.opts.KubeVersion, err)
}
installAction.KubeVersion = kubeVersion
}

// Preserve backward compatibility so APIVersions can be explicitly passed
if len(c.opts.APIVersions) > 0 {
installAction.APIVersions = c.opts.APIVersions
} else if clientSet != nil {
// The following code to discover Kubernetes version and API versions comes
// from the Helm project:
// https://github.com/helm/helm/blob/d7b4c38c42cb0b77f1bcebf9bb4ae7695a10da0b/pkg/action/action.go#L239
}

if clientSet != nil {
dc := clientSet.DiscoveryClientCached

dc.Invalidate()
kubeVersion, err := dc.ServerVersion()
if err != nil {
return "", fmt.Errorf("could not get server version from Kubernetes: %w", err)
// The following code to discover Kubernetes version and API versions comes
// from the Helm project:
// https://github.com/helm/helm/blob/d7b4c38c42cb0b77f1bcebf9bb4ae7695a10da0b/pkg/action/action.go#L239
if installAction.KubeVersion == nil {
kubeVersion, err := dc.ServerVersion()
if err != nil {
return "", fmt.Errorf("could not get server version from Kubernetes: %w", err)
}
installAction.KubeVersion = &chartutil.KubeVersion{
Version: kubeVersion.GitVersion,
Major: kubeVersion.Major,
Minor: kubeVersion.Minor,
}
}
// Client-Go emits an error when an API service is registered but unimplemented.
// Since the discovery client continues building the API object, it is correctly
// populated with all valid APIs.
// See https://github.com/kubernetes/kubernetes/issues/72051#issuecomment-521157642
apiVersions, err := action.GetVersionSet(dc)
if err != nil {
if !discovery.IsGroupDiscoveryFailedError(err) {
return "", fmt.Errorf("could not get apiVersions from Kubernetes: %w", err)
if installAction.APIVersions == nil {
apiVersions, err := action.GetVersionSet(dc)
if err != nil {
if !discovery.IsGroupDiscoveryFailedError(err) {
return "", fmt.Errorf("could not get apiVersions from Kubernetes: %w", err)
}
}
installAction.APIVersions = apiVersions
}

installAction.KubeVersion = &chartutil.KubeVersion{
Version: kubeVersion.GitVersion,
Major: kubeVersion.Major,
Minor: kubeVersion.Minor,
}

installAction.APIVersions = apiVersions
}

chartName, err := func() (string, error) {
Expand Down
7 changes: 7 additions & 0 deletions sdk/dotnet/Helm/ChartBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,13 @@ public InputList<string> ApiVersions
/// </summary>
public Input<string>? Namespace { get; set; }

/// <summary>
/// By default, the kubernetes version is derived from your k8s context, this allows it to be overridden.
/// Warning: This option should not be used unless you have a good reason to not use the auto-discovered
/// version as it is much more bug-prone.
/// </summary>
public Input<string>? KubeVersion { get; set; }

private InputMap<object>? _values;

/// <summary>
Expand Down