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

Component option propagation (Python SDK) #2717

Merged
merged 4 commits into from
Jan 4, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## Unreleased
- Fix option propagation in component resources (Python SDK) (https://github.com/pulumi/pulumi-kubernetes/pull/2717)
- Fix option propagation in component resources (.NET SDK) (https://github.com/pulumi/pulumi-kubernetes/pull/2720)
- Fix option propagation in component resources (NodeJS SDK) (https://github.com/pulumi/pulumi-kubernetes/pull/2713)
- Fix option propagation in component resources (Go SDK) (https://github.com/pulumi/pulumi-kubernetes/pull/2709)
Expand Down
13 changes: 5 additions & 8 deletions provider/pkg/gen/python-templates/helm/v3/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from typing import Any, Callable, Optional, Sequence, Tuple, Union

import pulumi.runtime
from pulumi_kubernetes.yaml.yaml import _parse_yaml_document, _skip_await
from pulumi_kubernetes.yaml.yaml import _get_child_options, _get_invoke_options, _parse_yaml_document, _skip_await

from ... import _utilities

Expand Down Expand Up @@ -189,7 +189,8 @@ def omit_resource(obj, opts):

config.release_name = release_name

all_config = pulumi.Output.from_input((config, pulumi.ResourceOptions(parent=self)))
parseOpts = _get_child_options(self, opts)
all_config = pulumi.Output.from_input((config, parseOpts))

# Note: Unlike NodeJS, Python requires that we "pull" on our futures in order to get them scheduled for
# execution. In order to do this, we leverage the engine's RegisterResourceOutputs to wait for the
Expand Down Expand Up @@ -607,12 +608,8 @@ def _parse_chart(all_config: Tuple[Union[ChartOpts, LocalChartOpts], pulumi.Reso

json_opts = config.to_json()

# Rather than using the default provider for the following invoke call, use the version specified
# in package.json.
invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version() if not opts.version else opts.version,
parent=opts.parent if opts.parent else None,
provider=opts.provider if opts.provider else None)

invoke_opts = _get_invoke_options(opts)

transformations = config.transformations if config.transformations is not None else []
if config.skip_await:
transformations.append(_skip_await)
Expand Down
16 changes: 7 additions & 9 deletions provider/pkg/gen/python-templates/kustomize/kustomize.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Any, Callable, Optional, Sequence

import pulumi.runtime
import pulumi_kubernetes as k8s
from pulumi_kubernetes.yaml.yaml import _get_child_options, _get_invoke_options, _parse_yaml_document

from .. import _utilities, _tables

Expand Down Expand Up @@ -98,6 +98,8 @@ def omit_resource(obj, opts):
raise TypeError('Missing resource name argument (for URN creation)')
if not isinstance(name, str):
raise TypeError('Expected resource name to be a string')
if opts is None:
opts = pulumi.ResourceOptions()
if opts and not isinstance(opts, pulumi.ResourceOptions):
raise TypeError('Expected resource options to be a ResourceOptions instance')

Expand All @@ -107,13 +109,9 @@ def omit_resource(obj, opts):
name = f"{resource_prefix}-{name}"
super(Directory, self).__init__("kubernetes:kustomize:Directory", name, __props__, opts)

opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(parent=self))

# Rather than using the default provider for the following invoke call, use the version specified
# in package.json.
invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version(),
provider=opts.provider if opts.provider else None)

child_opts = _get_child_options(self, opts)
invoke_opts = _get_invoke_options(child_opts)

__ret__ = pulumi.runtime.invoke(
'kubernetes:kustomize:directory', {'directory': directory}, invoke_opts)

Expand All @@ -124,7 +122,7 @@ def omit_resource(obj, opts):
# Note: Unlike NodeJS, Python requires that we "pull" on our futures in order to get them scheduled for
# execution. In order to do this, we leverage the engine's RegisterResourceOutputs to wait for the
# resolution of all resources that this YAML document created.
self.resources = k8s.yaml.yaml._parse_yaml_document(result, opts, transformations, resource_prefix)
self.resources = _parse_yaml_document(result, child_opts, transformations, resource_prefix)
self.register_outputs({"resources": self.resources})

def translate_output_property(self, prop: str) -> str:
Expand Down
45 changes: 28 additions & 17 deletions provider/pkg/gen/python-templates/yaml/yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,18 @@ class ConfigGroup(pulumi.ComponentResource):
else:
_files += [f for f in glob(file)]

opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(parent=self))
child_opts = _get_child_options(self, opts)

for file in _files:
cf = ConfigFile(
file, file_id=file, transformations=transformations, resource_prefix=resource_prefix, opts=opts)
file, file_id=file, transformations=transformations, resource_prefix=resource_prefix, opts=child_opts)
# Add any new ConfigFile resources to the ConfigGroup's resources
self.resources = pulumi.Output.all(cf.resources, self.resources).apply(lambda x: {**x[0], **x[1]})

for text in yaml:
# Rather than using the default provider for the following invoke call, use the version specified
# in package.json.
invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version(),
provider=opts.provider if opts.provider else None)

invoke_opts = _get_invoke_options(child_opts)
__ret__ = invoke_yaml_decode(text, invoke_opts)
resources = _parse_yaml_document(__ret__, opts, transformations, resource_prefix)
resources = _parse_yaml_document(__ret__, child_opts, transformations, resource_prefix)
# Add any new YAML resources to the ConfigGroup's resources
self.resources = pulumi.Output.all(resources, self.resources).apply(lambda x: {**x[0], **x[1]})

Expand Down Expand Up @@ -334,23 +330,19 @@ class ConfigFile(pulumi.ComponentResource):
else:
text = _read_file(file)

opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(parent=self))
child_opts = _get_child_options(self, opts)

transformations = transformations if transformations is not None else []
if skip_await:
transformations.append(_skip_await)

# Rather than using the default provider for the following invoke call, use the version specified
# in package.json.
invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version(),
provider=opts.provider if opts.provider else None)


invoke_opts = _get_invoke_options(child_opts)
__ret__ = invoke_yaml_decode(text, invoke_opts)

# Note: Unlike NodeJS, Python requires that we "pull" on our futures in order to get them scheduled for
# execution. In order to do this, we leverage the engine's RegisterResourceOutputs to wait for the
# resolution of all resources that this YAML document created.
self.resources = _parse_yaml_document(__ret__, opts, transformations, resource_prefix)
self.resources = _parse_yaml_document(__ret__, child_opts, transformations, resource_prefix)
self.register_outputs({"resources": self.resources})

def translate_output_property(self, prop: str) -> str:
Expand Down Expand Up @@ -410,7 +402,26 @@ def _read_file(path: str) -> str:
def _build_resources_dict(objs: Sequence[pulumi.Output]) -> Mapping[pulumi.Output, pulumi.Output]:
return {key: value for key, value in objs}


def _get_child_options(parent: pulumi.Resource, opts: pulumi.ResourceOptions):
if not opts:
opts = pulumi.ResourceOptions()
child_opts = pulumi.ResourceOptions(parent=parent)
if opts.version is not None:
child_opts.version = opts.version
if opts.plugin_download_url is not None:
child_opts.plugin_download_url = opts.plugin_download_url
return child_opts

def _get_invoke_options(opts: pulumi.ResourceOptions):
if not opts:
opts = pulumi.ResourceOptions()
return pulumi.InvokeOptions(
parent=opts.parent if opts.parent else None,
provider=opts.provider if opts.provider else None,
version=_utilities.get_version() if not opts.version else opts.version,
plugin_download_url=opts.plugin_download_url if opts.plugin_download_url else None
)

def _parse_yaml_document(
objects, opts: Optional[pulumi.ResourceOptions] = None,
transformations: Optional[Sequence[Callable]] = None,
Expand Down
13 changes: 5 additions & 8 deletions sdk/python/pulumi_kubernetes/helm/v3/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from typing import Any, Callable, Optional, Sequence, Tuple, Union

import pulumi.runtime
from pulumi_kubernetes.yaml.yaml import _parse_yaml_document, _skip_await
from pulumi_kubernetes.yaml.yaml import _get_child_options, _get_invoke_options, _parse_yaml_document, _skip_await

from ... import _utilities

Expand Down Expand Up @@ -189,7 +189,8 @@ def omit_resource(obj, opts):

config.release_name = release_name

all_config = pulumi.Output.from_input((config, pulumi.ResourceOptions(parent=self)))
parseOpts = _get_child_options(self, opts)
all_config = pulumi.Output.from_input((config, parseOpts))

# Note: Unlike NodeJS, Python requires that we "pull" on our futures in order to get them scheduled for
# execution. In order to do this, we leverage the engine's RegisterResourceOutputs to wait for the
Expand Down Expand Up @@ -607,12 +608,8 @@ def _parse_chart(all_config: Tuple[Union[ChartOpts, LocalChartOpts], pulumi.Reso

json_opts = config.to_json()

# Rather than using the default provider for the following invoke call, use the version specified
# in package.json.
invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version() if not opts.version else opts.version,
parent=opts.parent if opts.parent else None,
provider=opts.provider if opts.provider else None)

invoke_opts = _get_invoke_options(opts)

transformations = config.transformations if config.transformations is not None else []
if config.skip_await:
transformations.append(_skip_await)
Expand Down
16 changes: 7 additions & 9 deletions sdk/python/pulumi_kubernetes/kustomize/kustomize.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Any, Callable, Optional, Sequence

import pulumi.runtime
import pulumi_kubernetes as k8s
from pulumi_kubernetes.yaml.yaml import _get_child_options, _get_invoke_options, _parse_yaml_document

from .. import _utilities, _tables

Expand Down Expand Up @@ -98,6 +98,8 @@ def omit_resource(obj, opts):
raise TypeError('Missing resource name argument (for URN creation)')
if not isinstance(name, str):
raise TypeError('Expected resource name to be a string')
if opts is None:
opts = pulumi.ResourceOptions()
if opts and not isinstance(opts, pulumi.ResourceOptions):
raise TypeError('Expected resource options to be a ResourceOptions instance')

Expand All @@ -107,13 +109,9 @@ def omit_resource(obj, opts):
name = f"{resource_prefix}-{name}"
super(Directory, self).__init__("kubernetes:kustomize:Directory", name, __props__, opts)

opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(parent=self))

# Rather than using the default provider for the following invoke call, use the version specified
# in package.json.
invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version(),
provider=opts.provider if opts.provider else None)

child_opts = _get_child_options(self, opts)
invoke_opts = _get_invoke_options(child_opts)

__ret__ = pulumi.runtime.invoke(
'kubernetes:kustomize:directory', {'directory': directory}, invoke_opts)

Expand All @@ -124,7 +122,7 @@ def omit_resource(obj, opts):
# Note: Unlike NodeJS, Python requires that we "pull" on our futures in order to get them scheduled for
# execution. In order to do this, we leverage the engine's RegisterResourceOutputs to wait for the
# resolution of all resources that this YAML document created.
self.resources = k8s.yaml.yaml._parse_yaml_document(result, opts, transformations, resource_prefix)
self.resources = _parse_yaml_document(result, child_opts, transformations, resource_prefix)
self.register_outputs({"resources": self.resources})

def translate_output_property(self, prop: str) -> str:
Expand Down
45 changes: 28 additions & 17 deletions sdk/python/pulumi_kubernetes/yaml/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,18 @@ def omit_resource(obj, opts):
else:
_files += [f for f in glob(file)]

opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(parent=self))
child_opts = _get_child_options(self, opts)

for file in _files:
cf = ConfigFile(
file, file_id=file, transformations=transformations, resource_prefix=resource_prefix, opts=opts)
file, file_id=file, transformations=transformations, resource_prefix=resource_prefix, opts=child_opts)
# Add any new ConfigFile resources to the ConfigGroup's resources
self.resources = pulumi.Output.all(cf.resources, self.resources).apply(lambda x: {**x[0], **x[1]})

for text in yaml:
# Rather than using the default provider for the following invoke call, use the version specified
# in package.json.
invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version(),
provider=opts.provider if opts.provider else None)

invoke_opts = _get_invoke_options(child_opts)
__ret__ = invoke_yaml_decode(text, invoke_opts)
resources = _parse_yaml_document(__ret__, opts, transformations, resource_prefix)
resources = _parse_yaml_document(__ret__, child_opts, transformations, resource_prefix)
# Add any new YAML resources to the ConfigGroup's resources
self.resources = pulumi.Output.all(resources, self.resources).apply(lambda x: {**x[0], **x[1]})

Expand Down Expand Up @@ -334,23 +330,19 @@ def omit_resource(obj, opts):
else:
text = _read_file(file)

opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(parent=self))
child_opts = _get_child_options(self, opts)

transformations = transformations if transformations is not None else []
if skip_await:
transformations.append(_skip_await)

# Rather than using the default provider for the following invoke call, use the version specified
# in package.json.
invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version(),
provider=opts.provider if opts.provider else None)


invoke_opts = _get_invoke_options(child_opts)
__ret__ = invoke_yaml_decode(text, invoke_opts)

# Note: Unlike NodeJS, Python requires that we "pull" on our futures in order to get them scheduled for
# execution. In order to do this, we leverage the engine's RegisterResourceOutputs to wait for the
# resolution of all resources that this YAML document created.
self.resources = _parse_yaml_document(__ret__, opts, transformations, resource_prefix)
self.resources = _parse_yaml_document(__ret__, child_opts, transformations, resource_prefix)
self.register_outputs({"resources": self.resources})

def translate_output_property(self, prop: str) -> str:
Expand Down Expand Up @@ -410,7 +402,26 @@ def _read_file(path: str) -> str:
def _build_resources_dict(objs: Sequence[pulumi.Output]) -> Mapping[pulumi.Output, pulumi.Output]:
return {key: value for key, value in objs}


def _get_child_options(parent: pulumi.Resource, opts: pulumi.ResourceOptions):
if not opts:
opts = pulumi.ResourceOptions()
child_opts = pulumi.ResourceOptions(parent=parent)
if opts.version is not None:
child_opts.version = opts.version
if opts.plugin_download_url is not None:
child_opts.plugin_download_url = opts.plugin_download_url
return child_opts

def _get_invoke_options(opts: pulumi.ResourceOptions):
if not opts:
opts = pulumi.ResourceOptions()
return pulumi.InvokeOptions(
parent=opts.parent if opts.parent else None,
provider=opts.provider if opts.provider else None,
version=_utilities.get_version() if not opts.version else opts.version,
plugin_download_url=opts.plugin_download_url if opts.plugin_download_url else None
)

def _parse_yaml_document(
objects, opts: Optional[pulumi.ResourceOptions] = None,
transformations: Optional[Sequence[Callable]] = None,
Expand Down
8 changes: 8 additions & 0 deletions tests/sdk/python/options/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: options-test
runtime:
name: python
options:
virtualenv: venv
description: Test options propagation with component resources.
config:
pulumi:disable-default-providers: [kubernetes]
Loading
Loading