From c59ddff0e4ece63bc5958f9ea54fb2919748c5df Mon Sep 17 00:00:00 2001 From: Eron Wright Date: Fri, 8 Mar 2024 14:54:49 -0800 Subject: [PATCH] ConfigFile V2 (Component) (#2862) This PR implements a new `ConfigFile` resource (v2) as a Pulumi multi-language component (MLC). The new resource is offered side-by-side with the existing (v1) resource; it is not a drop-in replacement at this time. Some notable differences with respect to the previous (overlay) implementations: 1. Implemented as an MLC to have a consistent implementation across SDKs and to extend support for YAML and Java. 2. The component name is used as a prefix for the child resource names. Use the `resourcePrefix` property to override. Note that the `resourcePrefix` is not applied to the Kubernetes object names. 4. Transformations aren't supported (yet). Support for Pulumi-style transformation is being tracked [here](https://github.com/pulumi/pulumi/issues/12996), and Kubernetes-style transformation may come in future. 5. The `file` property is required and the file must exist. Closes #2785 --- CHANGELOG.md | 1 + provider/cmd/pulumi-gen-kubernetes/main.go | 1 + .../pulumi-resource-kubernetes/schema.json | 37 ++- .../pkg/gen/examples/overlays/configFileV2.md | 63 +++++ provider/pkg/gen/overlays.go | 47 ++++ provider/pkg/gen/schema.go | 2 + provider/pkg/provider/provider_construct.go | 1 + provider/pkg/provider/yaml/v2/configfile.go | 99 ++++++++ .../pkg/provider/yaml/v2/configfile_test.go | 159 ++++++++++++ sdk/dotnet/Yaml/V2/ConfigFile.cs | 98 ++++++++ sdk/go/kubernetes/yaml/v2/configFile.go | 230 ++++++++++++++++++ sdk/go/kubernetes/yaml/v2/init.go | 2 + .../pulumi/kubernetes/yaml/v2/ConfigFile.java | 73 ++++++ .../kubernetes/yaml/v2/ConfigFileArgs.java | 159 ++++++++++++ .../{yaml_v2 => yaml/v2}/ConfigGroup.java | 4 +- .../{yaml_v2 => yaml/v2}/ConfigGroupArgs.java | 2 +- sdk/nodejs/tsconfig.json | 1 + sdk/nodejs/yaml/v2/configFile.ts | 84 +++++++ sdk/nodejs/yaml/v2/index.ts | 7 + sdk/python/pulumi_kubernetes/__init__.py | 1 + .../pulumi_kubernetes/yaml/v2/ConfigFile.py | 169 +++++++++++++ .../pulumi_kubernetes/yaml/v2/__init__.py | 1 + 22 files changed, 1236 insertions(+), 5 deletions(-) create mode 100644 provider/pkg/gen/examples/overlays/configFileV2.md create mode 100644 provider/pkg/provider/yaml/v2/configfile.go create mode 100644 provider/pkg/provider/yaml/v2/configfile_test.go create mode 100644 sdk/dotnet/Yaml/V2/ConfigFile.cs create mode 100644 sdk/go/kubernetes/yaml/v2/configFile.go create mode 100644 sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigFile.java create mode 100644 sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigFileArgs.java rename sdk/java/src/main/java/com/pulumi/kubernetes/{yaml_v2 => yaml/v2}/ConfigGroup.java (96%) rename sdk/java/src/main/java/com/pulumi/kubernetes/{yaml_v2 => yaml/v2}/ConfigGroupArgs.java (99%) create mode 100644 sdk/nodejs/yaml/v2/configFile.ts create mode 100644 sdk/python/pulumi_kubernetes/yaml/v2/ConfigFile.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a382ddc74..2fb2ba1886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Use async invokes to avoid hangs/stalls in Python `helm`, `kustomize`, and `yaml` components (https://github.com/pulumi/pulumi-kubernetes/pull/2863) - ConfigGroup V2 (https://github.com/pulumi/pulumi-kubernetes/pull/2844) +- ConfigFile V2 (https://github.com/pulumi/pulumi-kubernetes/pull/2862) ### New Features diff --git a/provider/cmd/pulumi-gen-kubernetes/main.go b/provider/cmd/pulumi-gen-kubernetes/main.go index f3d0733389..f932df64b7 100644 --- a/provider/cmd/pulumi-gen-kubernetes/main.go +++ b/provider/cmd/pulumi-gen-kubernetes/main.go @@ -175,6 +175,7 @@ func generateSchema(swaggerPath string) schema.PackageSpec { // This is to mostly filter resources from the spec. var resourcesToFilterFromTemplate = codegen.NewStringSet( "kubernetes:helm.sh/v3:Release", + "kubernetes:yaml/v2:ConfigFile", "kubernetes:yaml/v2:ConfigGroup", ) diff --git a/provider/cmd/pulumi-resource-kubernetes/schema.json b/provider/cmd/pulumi-resource-kubernetes/schema.json index 1d2bb343da..7b872169af 100644 --- a/provider/cmd/pulumi-resource-kubernetes/schema.json +++ b/provider/cmd/pulumi-resource-kubernetes/schema.json @@ -82,7 +82,8 @@ "storage.k8s.io/v1": "Storage.V1", "storage.k8s.io/v1alpha1": "Storage.V1Alpha1", "storage.k8s.io/v1beta1": "Storage.V1Beta1", - "yaml": "Yaml" + "yaml": "Yaml", + "yaml/v2": "Yaml.V2" }, "packageReferences": { "Glob": "1.1.5", @@ -291,7 +292,8 @@ "settings.k8s.io/v1alpha1": "settings.v1alpha1", "storage.k8s.io/v1": "storage.v1", "storage.k8s.io/v1alpha1": "storage.v1alpha1", - "storage.k8s.io/v1beta1": "storage.v1beta1" + "storage.k8s.io/v1beta1": "storage.v1beta1", + "yaml/v2": "yaml.v2" } }, "nodejs": { @@ -95185,6 +95187,37 @@ } ] }, + "kubernetes:yaml/v2:ConfigFile": { + "description": "ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file.\n\n{{% examples %}}\n## Example Usage\n{{% example %}}\n### Local File\n\n```typescript\nimport * as k8s from \"@pulumi/kubernetes\";\n\nconst example = new k8s.yaml.v2.ConfigFile(\"example\", {\n file: \"foo.yaml\",\n});\n```\n```python\nfrom pulumi_kubernetes.yaml.v2 import ConfigFile\n\nexample = ConfigFile(\n \"example\",\n file=\"foo.yaml\",\n)\n```\n```csharp\nusing System.Threading.Tasks;\nusing Pulumi;\nusing Pulumi.Kubernetes.Yaml.V2;\n\nclass YamlStack : Stack\n{\n public YamlStack()\n {\n var helloWorld = new ConfigFile(\"example\", new ConfigFileArgs\n {\n File = \"foo.yaml\",\n });\n }\n}\n```\n```go\npackage main\n\nimport (\n yamlv2 \"github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml/v2\"\n \"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n pulumi.Run(func(ctx *pulumi.Context) error {\n _, err := yamlv2.NewConfigFile(ctx, \"example\",\n &yamlv2.ConfigFileArgs{\n File: \"foo.yaml\",\n },\n )\n if err != nil {\n return err\n }\n\n return nil\n })\n}\n```\n{{% /example %}}\n{% /examples %}}\n", + "properties": { + "resources": { + "type": "array", + "items": { + "$ref": "pulumi.json#/Any" + }, + "description": "Resources created by the ConfigFile." + } + }, + "type": "object", + "inputProperties": { + "file": { + "type": "string", + "description": "Path or URL to a Kubernetes manifest file. File must exist." + }, + "resourcePrefix": { + "type": "string", + "description": "A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix=\"foo\" would produce a resource named \"foo-resourceName\"." + }, + "skipAwait": { + "type": "boolean", + "description": "Indicates that child resources should skip the await logic." + } + }, + "requiredInputs": [ + "file" + ], + "isComponent": true + }, "kubernetes:yaml/v2:ConfigGroup": { "description": "ConfigGroup creates a set of Kubernetes resources from Kubernetes YAML text. The YAML text\nmay be supplied using any of the following methods:\n\n1. Using a filename or a list of filenames:\n2. Using a file pattern or a list of file patterns:\n3. Using a literal string containing YAML, or a list of such strings:\n4. Any combination of files, patterns, or YAML strings:\n\n{{% examples %}}\n## Example Usage\n{{% example %}}\n### Local File\n\n```typescript\nimport * as k8s from \"@pulumi/kubernetes\";\n\nconst example = new k8s.yaml.v2.ConfigGroup(\"example\", {\n files: \"foo.yaml\",\n});\n```\n```python\nfrom pulumi_kubernetes.yaml.v2 import ConfigGroup\n\nexample = ConfigGroup(\n \"example\",\n files=[\"foo.yaml\"],\n)\n```\n```csharp\nusing System.Threading.Tasks;\nusing Pulumi;\nusing Pulumi.Kubernetes.Yaml.V2;\n\nclass YamlStack : Stack\n{\n public YamlStack()\n {\n var helloWorld = new ConfigGroup(\"example\", new ConfigGroupArgs\n {\n Files = new[] { \"foo.yaml\" }\n });\n }\n}\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml/v2\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := yaml.NewConfigGroup(ctx, \"example\",\n\t\t\t&yaml.ConfigGroupArgs{\n\t\t\t\tFiles: []string{\"foo.yaml\"},\n\t\t\t},\n\t\t)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t})\n}\n```\n{{% /example %}}\n{{% example %}}\n### Multiple Local Files\n\n```typescript\nimport * as k8s from \"@pulumi/kubernetes\";\n\nconst example = new k8s.yaml.v2.ConfigGroup(\"example\", {\n files: [\"foo.yaml\", \"bar.yaml\"],\n});\n```\n```python\nfrom pulumi_kubernetes.yaml.v2 import ConfigGroup\n\nexample = ConfigGroup(\n \"example\",\n files=[\"foo.yaml\", \"bar.yaml\"],\n)\n```\n```csharp\nusing System.Threading.Tasks;\nusing Pulumi;\nusing Pulumi.Kubernetes.Yaml.V2;\n\nclass YamlStack : Stack\n{\n public YamlStack()\n {\n var helloWorld = new ConfigGroup(\"example\", new ConfigGroupArgs\n {\n Files = new[] { \"foo.yaml\", \"bar.yaml\" }\n });\n }\n}\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml/v2\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := yaml.NewConfigGroup(ctx, \"example\",\n\t\t\t&yaml.ConfigGroupArgs{\n\t\t\t\tFiles: []string{\"foo.yaml\", \"bar.yaml\"},\n\t\t\t},\n\t\t)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t})\n}\n```\n{{% /example %}}\n{{% example %}}\n### Local File Pattern\n\n```typescript\nimport * as k8s from \"@pulumi/kubernetes\";\n\nconst example = new k8s.yaml.v2.ConfigGroup(\"example\", {\n files: \"yaml/*.yaml\",\n});\n```\n```python\nfrom pulumi_kubernetes.yaml.v2 import ConfigGroup\n\nexample = ConfigGroup(\n \"example\",\n files=[\"yaml/*.yaml\"],\n)\n```\n```csharp\nusing System.Threading.Tasks;\nusing Pulumi;\nusing Pulumi.Kubernetes.Yaml.V2;\n\nclass YamlStack : Stack\n{\n public YamlStack()\n {\n var helloWorld = new ConfigGroup(\"example\", new ConfigGroupArgs\n {\n Files = new[] { \"yaml/*.yaml\" }\n });\n }\n}\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml/v2\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := yaml.NewConfigGroup(ctx, \"example\",\n\t\t\t&yaml.ConfigGroupArgs{\n\t\t\t\tFiles: []string{\"yaml/*.yaml\"},\n\t\t\t},\n\t\t)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t})\n}\n```\n{{% /example %}}\n{{% example %}}\n### Multiple Local File Patterns\n\n```typescript\nimport * as k8s from \"@pulumi/kubernetes\";\n\nconst example = new k8s.yaml.v2.ConfigGroup(\"example\", {\n files: [\"foo/*.yaml\", \"bar/*.yaml\"],\n});\n```\n```python\nfrom pulumi_kubernetes.yaml.v2 import ConfigGroup\n\nexample = ConfigGroup(\n \"example\",\n files=[\"foo/*.yaml\", \"bar/*.yaml\"],\n)\n```\n```csharp\nusing System.Threading.Tasks;\nusing Pulumi;\nusing Pulumi.Kubernetes.Yaml.V2;\n\nclass YamlStack : Stack\n{\n public YamlStack()\n {\n var helloWorld = new ConfigGroup(\"example\", new ConfigGroupArgs\n {\n Files = new[] { \"foo/*.yaml\", \"bar/*.yaml\" }\n });\n }\n}\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml/v2\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := yaml.NewConfigGroup(ctx, \"example\",\n\t\t\t&yaml.ConfigGroupArgs{\n\t\t\t\tFiles: []string{\"yaml/*.yaml\", \"bar/*.yaml\"},\n\t\t\t},\n\t\t)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t})\n}\n```\n{{% /example %}}\n{{% example %}}\n### Literal YAML String\n\n```typescript\nimport * as k8s from \"@pulumi/kubernetes\";\n\nconst example = new k8s.yaml.v2.ConfigGroup(\"example\", {\n yaml: `\napiVersion: v1\nkind: Namespace\nmetadata:\n name: foo\n`,\n})\n```\n```python\nfrom pulumi_kubernetes.yaml.v2 import ConfigGroup\n\nexample = ConfigGroup(\n \"example\",\n yaml=['''\napiVersion: v1\nkind: Namespace\nmetadata:\n name: foo\n''']\n)\n```\n```csharp\nusing System.Threading.Tasks;\nusing Pulumi;\nusing Pulumi.Kubernetes.Yaml.V2;\n\nclass YamlStack : Stack\n{\n public YamlStack()\n {\n var helloWorld = new ConfigGroup(\"example\", new ConfigGroupArgs\n {\n Yaml = @\"\n apiVersion: v1\n kind: Namespace\n metadata:\n name: foo\n \",\n });\n }\n}\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml/v2\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := yaml.NewConfigGroup(ctx, \"example\",\n\t\t\t&yaml.ConfigGroupArgs{\n\t\t\t\tYAML: []string{\n\t\t\t\t\t`\napiVersion: v1\nkind: Namespace\nmetadata:\n name: foo\n`,\n\t\t\t\t},\n\t\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t})\n}\n```\n{{% /example %}}\n{% /examples %}}\n", "properties": { diff --git a/provider/pkg/gen/examples/overlays/configFileV2.md b/provider/pkg/gen/examples/overlays/configFileV2.md new file mode 100644 index 0000000000..4f28485e93 --- /dev/null +++ b/provider/pkg/gen/examples/overlays/configFileV2.md @@ -0,0 +1,63 @@ +ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file. + +{{% examples %}} +## Example Usage +{{% example %}} +### Local File + +```typescript +import * as k8s from "@pulumi/kubernetes"; + +const example = new k8s.yaml.v2.ConfigFile("example", { + file: "foo.yaml", +}); +``` +```python +from pulumi_kubernetes.yaml.v2 import ConfigFile + +example = ConfigFile( + "example", + file="foo.yaml", +) +``` +```csharp +using System.Threading.Tasks; +using Pulumi; +using Pulumi.Kubernetes.Yaml.V2; + +class YamlStack : Stack +{ + public YamlStack() + { + var helloWorld = new ConfigFile("example", new ConfigFileArgs + { + File = "foo.yaml", + }); + } +} +``` +```go +package main + +import ( + yamlv2 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml/v2" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := yamlv2.NewConfigFile(ctx, "example", + &yamlv2.ConfigFileArgs{ + File: "foo.yaml", + }, + ) + if err != nil { + return err + } + + return nil + }) +} +``` +{{% /example %}} +{% /examples %}} diff --git a/provider/pkg/gen/overlays.go b/provider/pkg/gen/overlays.go index db40834507..a55e994b74 100644 --- a/provider/pkg/gen/overlays.go +++ b/provider/pkg/gen/overlays.go @@ -1061,6 +1061,52 @@ var yamlConfigFileResource = pschema.ResourceSpec{ }, } +//go:embed examples/overlays/configFileV2.md +var configFileV2MD string + +var yamlConfigFileV2Resource = pschema.ResourceSpec{ + IsComponent: true, + ObjectTypeSpec: pschema.ObjectTypeSpec{ + IsOverlay: false, + Description: configFileV2MD, + Properties: map[string]pschema.PropertySpec{ + "resources": { + TypeSpec: pschema.TypeSpec{ + Type: "array", + Items: &pschema.TypeSpec{ + Ref: "pulumi.json#/Any", + }, + }, + Description: "Resources created by the ConfigFile.", + }, + }, + Type: "object", + }, + InputProperties: map[string]pschema.PropertySpec{ + "file": { + TypeSpec: pschema.TypeSpec{ + Type: "string", + }, + Description: "Path or URL to a Kubernetes manifest file. File must exist.", + }, + "resourcePrefix": { + TypeSpec: pschema.TypeSpec{ + Type: "string", + }, + Description: "A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix=\"foo\" would produce a resource named \"foo-resourceName\".", + }, + "skipAwait": { + TypeSpec: pschema.TypeSpec{ + Type: "boolean", + }, + Description: "Indicates that child resources should skip the await logic.", + }, + }, + RequiredInputs: []string{ + "file", + }, +} + //go:embed examples/overlays/configGroup.md var configGroupMD string @@ -1352,6 +1398,7 @@ func init() { resourceOverlays["kubernetes:helm.sh/v3:Release"] = helmV3ReleaseResource resourceOverlays["kubernetes:kustomize:Directory"] = kustomizeDirectoryResource resourceOverlays["kubernetes:yaml:ConfigFile"] = yamlConfigFileResource + resourceOverlays["kubernetes:yaml/v2:ConfigFile"] = yamlConfigFileV2Resource resourceOverlays["kubernetes:yaml:ConfigGroup"] = yamlConfigGroupResource resourceOverlays["kubernetes:yaml/v2:ConfigGroup"] = yamlConfigGroupV2Resource } diff --git a/provider/pkg/gen/schema.go b/provider/pkg/gen/schema.go index 9b29868a3d..436f732a55 100644 --- a/provider/pkg/gen/schema.go +++ b/provider/pkg/gen/schema.go @@ -223,11 +223,13 @@ func PulumiSchema(swagger map[string]any) pschema.PackageSpec { "helm.sh/v2": "Helm.V2", "helm.sh/v3": "Helm.V3", "yaml": "Yaml", + "yaml/v2": "Yaml.V2", "": "Provider", } javaPackages := map[string]string{ "helm.sh/v2": "helm.v2", "helm.sh/v3": "helm.v3", + "yaml/v2": "yaml.v2", } modToPkg := map[string]string{ "apiextensions.k8s.io": "apiextensions", diff --git a/provider/pkg/provider/provider_construct.go b/provider/pkg/provider/provider_construct.go index e3d8286b18..926cb9490e 100644 --- a/provider/pkg/provider/provider_construct.go +++ b/provider/pkg/provider/provider_construct.go @@ -26,6 +26,7 @@ import ( // resourceProviders contains factories for component resource providers. var resourceProviders = map[string]providerresource.ResourceProviderFactory{ + "kubernetes:yaml/v2:ConfigFile": provideryamlv2.NewConfigFileProvider, "kubernetes:yaml/v2:ConfigGroup": provideryamlv2.NewConfigGroupProvider, } diff --git a/provider/pkg/provider/yaml/v2/configfile.go b/provider/pkg/provider/yaml/v2/configfile.go new file mode 100644 index 0000000000..7c4406a44c --- /dev/null +++ b/provider/pkg/provider/yaml/v2/configfile.go @@ -0,0 +1,99 @@ +// Copyright 2016-2024, 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 v2 + +import ( + "context" + "fmt" + + "github.com/pulumi/pulumi-kubernetes/provider/v4/pkg/clients" + providerresource "github.com/pulumi/pulumi-kubernetes/provider/v4/pkg/provider/resource" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi/internals" + pulumiprovider "github.com/pulumi/pulumi/sdk/v3/go/pulumi/provider" +) + +type ConfigFileProvider struct { + clientSet *clients.DynamicClientSet +} + +type ConfigFileArgs struct { + File pulumi.StringInput `pulumi:"file"` + ResourcePrefix pulumi.StringInput `pulumi:"resourcePrefix,optional"` + SkipAwait pulumi.BoolInput `pulumi:"skipAwait,optional"` +} + +type ConfigFileState struct { + pulumi.ResourceState + Resources pulumi.ArrayOutput `pulumi:"resources"` +} + +var _ providerresource.ResourceProvider = &ConfigFileProvider{} + +func NewConfigFileProvider(opts *providerresource.ResourceProviderOptions) providerresource.ResourceProvider { + return &ConfigFileProvider{ + clientSet: opts.ClientSet, + } +} + +func (k *ConfigFileProvider) Construct(ctx *pulumi.Context, typ, name string, inputs pulumiprovider.ConstructInputs, options pulumi.ResourceOption) (*pulumiprovider.ConstructResult, error) { + comp := &ConfigFileState{} + err := ctx.RegisterComponentResource(typ, name, comp, options) + if err != nil { + return nil, err + } + + args := &ConfigFileArgs{} + if err := inputs.CopyTo(args); err != nil { + return nil, fmt.Errorf("setting args: %w", err) + } + + // Check if all the required args are known, and print a warning if not. + result, err := internals.UnsafeAwaitOutput(ctx.Context(), pulumi.All( + args.File, args.ResourcePrefix, args.SkipAwait)) + if err != nil { + return nil, err + } + if !result.Known { + msg := fmt.Sprintf("%s:%s -- Required input properties have unknown values. Preview is incomplete.\n", typ, name) + _ = ctx.Log.Warn(msg, nil) + } + + // Parse the manifest(s) and register the resources. + + comp.Resources = pulumi.All(args.File, args.ResourcePrefix, args.SkipAwait).ApplyTWithContext(ctx.Context(), func(_ context.Context, args []any) (pulumi.ArrayOutput, error) { + // make type assertions to get each value (or the zero value) + file, _ := args[0].(string) + resourcePrefix, hasResourcePrefix := args[1].(string) + skipAwait, _ := args[2].(bool) + + if !hasResourcePrefix { + // use the name of the ConfigFile as the resource prefix to ensure uniqueness + // across multiple instances of the component resource. + resourcePrefix = name + } + + return ParseDecodeYamlFiles(ctx, &ParseArgs{ + Files: []string{file}, + ResourcePrefix: resourcePrefix, + SkipAwait: skipAwait, + }, false, k.clientSet, pulumi.Parent(comp)) + }).(pulumi.ArrayOutput) + + // issue: https://github.com/pulumi/pulumi/issues/15527 + _, _ = internals.UnsafeAwaitOutput(ctx.Context(), comp.Resources) + + return pulumiprovider.NewConstructResult(comp) +} diff --git a/provider/pkg/provider/yaml/v2/configfile_test.go b/provider/pkg/provider/yaml/v2/configfile_test.go new file mode 100644 index 0000000000..000cc0a0b1 --- /dev/null +++ b/provider/pkg/provider/yaml/v2/configfile_test.go @@ -0,0 +1,159 @@ +// Copyright 2016-2024, 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 v2 + +import ( + "context" + "os" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" + providerresource "github.com/pulumi/pulumi-kubernetes/provider/v4/pkg/provider/resource" + . "github.com/pulumi/pulumi-kubernetes/tests/v4/gomega" + "github.com/pulumi/pulumi/sdk/v3/go/common/resource" + "github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin" + pulumiprovider "github.com/pulumi/pulumi/sdk/v3/go/pulumi/provider" + pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go" +) + +var _ = Describe("ConfigFile.Construct", func() { + var tc *componentProviderTestContext + var opts *providerresource.ResourceProviderOptions + var req *pulumirpc.ConstructRequest + var inputs resource.PropertyMap + var k *ConfigFileProvider + + BeforeEach(func() { + tc = newTestContext(GinkgoTB()) + opts = &providerresource.ResourceProviderOptions{} + + // initialize the ConstructRequest to be customized in nested BeforeEach blocks + req = tc.NewConstructRequest() + req.Type = "kubernetes:yaml/v2:ConfigFile" + req.Name = "test" + + // initialize the input PropertyMap to be serialized into the request in JustBeforeEach + inputs = make(resource.PropertyMap) + }) + + JustBeforeEach(func() { + var err error + k = NewConfigFileProvider(opts).(*ConfigFileProvider) + req.Inputs, err = plugin.MarshalProperties(inputs, plugin.MarshalOptions{ + Label: "inputs", KeepSecrets: true, KeepResources: true, KeepUnknowns: true, KeepOutputValues: true, + }) + Expect(err).ShouldNot(HaveOccurred()) + }) + + componentAssertions := func() { + It("should register a component resource", func() { + resp, err := pulumiprovider.Construct(context.Background(), req, tc.EngineConn(), k.Construct) + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.Urn).Should(Equal("urn:pulumi:stack::project::kubernetes:yaml/v2:ConfigFile::test")) + + Expect(tc.monitor.Resources()).To(MatchKeys(IgnoreExtras, Keys{ + "urn:pulumi:stack::project::kubernetes:yaml/v2:ConfigFile::test": MatchProps(IgnoreExtras, Props{ + "id": MatchValue("test"), + }), + })) + }) + } + + Describe("file", func() { + Context("when the input is a valid file", func() { + BeforeEach(func() { + tempDir := GinkgoTB().TempDir() + err := os.WriteFile(filepath.Join(tempDir, "manifest.yaml"), []byte(manifest), 0o600) + Expect(err).ShouldNot(HaveOccurred()) + inputs["file"] = resource.NewStringProperty(filepath.Join(tempDir, "manifest.yaml")) + }) + + componentAssertions() + + It("should provide a 'resources' output property", func(ctx context.Context) { + resp, err := pulumiprovider.Construct(ctx, req, tc.EngineConn(), k.Construct) + Expect(err).ShouldNot(HaveOccurred()) + outputs := unmarshalProperties(GinkgoTB(), resp.State) + Expect(outputs).To(MatchProps(IgnoreExtras, Props{ + "resources": MatchArrayValue(HaveExactElements( + MatchResourceReferenceValue("urn:pulumi:stack::project::kubernetes:yaml/v2:ConfigFile$kubernetes:core/v1:ConfigMap::test-my-map", "test-my-map"), + MatchResourceReferenceValue("urn:pulumi:stack::project::kubernetes:yaml/v2:ConfigFile$kubernetes:stable.example.com/v1:CronTab::test-my-new-cron-object", "test-my-new-cron-object"), + )), + })) + }) + + Context("given a resource prefix", func() { + BeforeEach(func() { + inputs["resourcePrefix"] = resource.NewStringProperty("prefixed") + }) + It("should use the prefix (instead of the component name)", func(ctx context.Context) { + resp, err := pulumiprovider.Construct(ctx, req, tc.EngineConn(), k.Construct) + Expect(err).ShouldNot(HaveOccurred()) + outputs := unmarshalProperties(GinkgoTB(), resp.State) + Expect(outputs).To(MatchProps(IgnoreExtras, Props{ + "resources": MatchArrayValue(HaveExactElements( + MatchResourceReferenceValue("urn:pulumi:stack::project::kubernetes:yaml/v2:ConfigFile$kubernetes:core/v1:ConfigMap::prefixed-my-map", "prefixed-my-map"), + MatchResourceReferenceValue("urn:pulumi:stack::project::kubernetes:yaml/v2:ConfigFile$kubernetes:stable.example.com/v1:CronTab::prefixed-my-new-cron-object", "prefixed-my-new-cron-object"), + )), + })) + }) + }) + + Context("given a blank resource prefix", func() { + BeforeEach(func() { + inputs["resourcePrefix"] = resource.NewStringProperty("") + }) + It("should have no prefix", func(ctx context.Context) { + resp, err := pulumiprovider.Construct(ctx, req, tc.EngineConn(), k.Construct) + Expect(err).ShouldNot(HaveOccurred()) + outputs := unmarshalProperties(GinkgoTB(), resp.State) + Expect(outputs).To(MatchProps(IgnoreExtras, Props{ + "resources": MatchArrayValue(HaveExactElements( + MatchResourceReferenceValue("urn:pulumi:stack::project::kubernetes:yaml/v2:ConfigFile$kubernetes:core/v1:ConfigMap::my-map", "my-map"), + MatchResourceReferenceValue("urn:pulumi:stack::project::kubernetes:yaml/v2:ConfigFile$kubernetes:stable.example.com/v1:CronTab::my-new-cron-object", "my-new-cron-object"), + )), + })) + }) + }) + }) + }) + + Describe("preview", func() { + Context("when the input value(s) are unknown", func() { + BeforeEach(func() { + req.DryRun = true + inputs["file"] = resource.MakeComputed(resource.NewStringProperty("")) + }) + + componentAssertions() + + It("should emit a warning", func(ctx context.Context) { + _, err := pulumiprovider.Construct(ctx, req, tc.EngineConn(), k.Construct) + Expect(err).ShouldNot(HaveOccurred()) + Expect(tc.engine.Logs()).To(HaveLen(1)) + }) + + It("should provide a 'resources' output property", func(ctx context.Context) { + resp, err := pulumiprovider.Construct(ctx, req, tc.EngineConn(), k.Construct) + Expect(err).ShouldNot(HaveOccurred()) + outputs := unmarshalProperties(GinkgoTB(), resp.State) + Expect(outputs).To(MatchProps(IgnoreExtras, Props{ + "resources": BeComputed(), + })) + }) + }) + }) +}) diff --git a/sdk/dotnet/Yaml/V2/ConfigFile.cs b/sdk/dotnet/Yaml/V2/ConfigFile.cs new file mode 100644 index 0000000000..8af6a160cf --- /dev/null +++ b/sdk/dotnet/Yaml/V2/ConfigFile.cs @@ -0,0 +1,98 @@ +// *** WARNING: this file was generated by pulumigen. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Pulumi.Serialization; + +namespace Pulumi.Kubernetes.Yaml.V2 +{ + /// + /// ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file. + /// + /// ## Example Usage + /// ### Local File + /// ```csharp + /// using System.Threading.Tasks; + /// using Pulumi; + /// using Pulumi.Kubernetes.Yaml.V2; + /// + /// class YamlStack : Stack + /// { + /// public YamlStack() + /// { + /// var helloWorld = new ConfigFile("example", new ConfigFileArgs + /// { + /// File = "foo.yaml", + /// }); + /// } + /// } + /// ``` + /// {% /examples %}} + /// + [KubernetesResourceType("kubernetes:yaml/v2:ConfigFile")] + public partial class ConfigFile : global::Pulumi.ComponentResource + { + /// + /// Resources created by the ConfigFile. + /// + [Output("resources")] + public Output> Resources { get; private set; } = null!; + + + /// + /// Create a ConfigFile resource with the given unique name, arguments, and options. + /// + /// + /// The unique name of the resource + /// The arguments used to populate this resource's properties + /// A bag of options that control this resource's behavior + public ConfigFile(string name, Pulumi.Kubernetes.Types.Inputs.Yaml.V2.ConfigFileArgs? args = null, ComponentResourceOptions? options = null) + : base("kubernetes:yaml/v2:ConfigFile", name, args ?? new Pulumi.Kubernetes.Types.Inputs.Yaml.V2.ConfigFileArgs(), MakeResourceOptions(options, ""), remote: true) + { + } + + private static ComponentResourceOptions MakeResourceOptions(ComponentResourceOptions? options, Input? id) + { + var defaultOptions = new ComponentResourceOptions + { + Version = Utilities.Version, + }; + var merged = ComponentResourceOptions.Merge(defaultOptions, options); + // Override the ID if one was specified for consistency with other language SDKs. + merged.Id = id ?? merged.Id; + return merged; + } + } +} +namespace Pulumi.Kubernetes.Types.Inputs.Yaml.V2 +{ + + public class ConfigFileArgs : global::Pulumi.ResourceArgs + { + /// + /// Path or URL to a Kubernetes manifest file. File must exist. + /// + [Input("file", required: true)] + public Input File { get; set; } = null!; + + /// + /// A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + /// + [Input("resourcePrefix")] + public Input? ResourcePrefix { get; set; } + + /// + /// Indicates that child resources should skip the await logic. + /// + [Input("skipAwait")] + public Input? SkipAwait { get; set; } + + public ConfigFileArgs() + { + } + public static new ConfigFileArgs Empty => new ConfigFileArgs(); + } +} diff --git a/sdk/go/kubernetes/yaml/v2/configFile.go b/sdk/go/kubernetes/yaml/v2/configFile.go new file mode 100644 index 0000000000..2ad3275830 --- /dev/null +++ b/sdk/go/kubernetes/yaml/v2/configFile.go @@ -0,0 +1,230 @@ +// Code generated by pulumigen DO NOT EDIT. +// *** WARNING: Do not edit by hand unless you're certain you know what you are doing! *** + +package v2 + +import ( + "context" + "reflect" + + "errors" + "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/utilities" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +// ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file. +// +// ## Example Usage +// ### Local File +// ```go +// package main +// +// import ( +// +// yamlv2 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml/v2" +// "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +// +// ) +// +// func main() { +// pulumi.Run(func(ctx *pulumi.Context) error { +// _, err := yamlv2.NewConfigFile(ctx, "example", +// &yamlv2.ConfigFileArgs{ +// File: "foo.yaml", +// }, +// ) +// if err != nil { +// return err +// } +// +// return nil +// }) +// } +// +// ``` +// {% /examples %}} +type ConfigFile struct { + pulumi.ResourceState + + // Resources created by the ConfigFile. + Resources pulumi.ArrayOutput `pulumi:"resources"` +} + +// NewConfigFile registers a new resource with the given unique name, arguments, and options. +func NewConfigFile(ctx *pulumi.Context, + name string, args *ConfigFileArgs, opts ...pulumi.ResourceOption) (*ConfigFile, error) { + if args == nil { + return nil, errors.New("missing one or more required arguments") + } + + if args.File == nil { + return nil, errors.New("invalid value for required argument 'File'") + } + opts = utilities.PkgResourceDefaultOpts(opts) + var resource ConfigFile + err := ctx.RegisterRemoteComponentResource("kubernetes:yaml/v2:ConfigFile", name, args, &resource, opts...) + if err != nil { + return nil, err + } + return &resource, nil +} + +type configFileArgs struct { + // Path or URL to a Kubernetes manifest file. File must exist. + File string `pulumi:"file"` + // A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + ResourcePrefix *string `pulumi:"resourcePrefix"` + // Indicates that child resources should skip the await logic. + SkipAwait *bool `pulumi:"skipAwait"` +} + +// The set of arguments for constructing a ConfigFile resource. +type ConfigFileArgs struct { + // Path or URL to a Kubernetes manifest file. File must exist. + File pulumi.StringInput + // A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + ResourcePrefix pulumi.StringPtrInput + // Indicates that child resources should skip the await logic. + SkipAwait pulumi.BoolPtrInput +} + +func (ConfigFileArgs) ElementType() reflect.Type { + return reflect.TypeOf((*configFileArgs)(nil)).Elem() +} + +type ConfigFileInput interface { + pulumi.Input + + ToConfigFileOutput() ConfigFileOutput + ToConfigFileOutputWithContext(ctx context.Context) ConfigFileOutput +} + +func (*ConfigFile) ElementType() reflect.Type { + return reflect.TypeOf((**ConfigFile)(nil)).Elem() +} + +func (i *ConfigFile) ToConfigFileOutput() ConfigFileOutput { + return i.ToConfigFileOutputWithContext(context.Background()) +} + +func (i *ConfigFile) ToConfigFileOutputWithContext(ctx context.Context) ConfigFileOutput { + return pulumi.ToOutputWithContext(ctx, i).(ConfigFileOutput) +} + +// ConfigFileArrayInput is an input type that accepts ConfigFileArray and ConfigFileArrayOutput values. +// You can construct a concrete instance of `ConfigFileArrayInput` via: +// +// ConfigFileArray{ ConfigFileArgs{...} } +type ConfigFileArrayInput interface { + pulumi.Input + + ToConfigFileArrayOutput() ConfigFileArrayOutput + ToConfigFileArrayOutputWithContext(context.Context) ConfigFileArrayOutput +} + +type ConfigFileArray []ConfigFileInput + +func (ConfigFileArray) ElementType() reflect.Type { + return reflect.TypeOf((*[]*ConfigFile)(nil)).Elem() +} + +func (i ConfigFileArray) ToConfigFileArrayOutput() ConfigFileArrayOutput { + return i.ToConfigFileArrayOutputWithContext(context.Background()) +} + +func (i ConfigFileArray) ToConfigFileArrayOutputWithContext(ctx context.Context) ConfigFileArrayOutput { + return pulumi.ToOutputWithContext(ctx, i).(ConfigFileArrayOutput) +} + +// ConfigFileMapInput is an input type that accepts ConfigFileMap and ConfigFileMapOutput values. +// You can construct a concrete instance of `ConfigFileMapInput` via: +// +// ConfigFileMap{ "key": ConfigFileArgs{...} } +type ConfigFileMapInput interface { + pulumi.Input + + ToConfigFileMapOutput() ConfigFileMapOutput + ToConfigFileMapOutputWithContext(context.Context) ConfigFileMapOutput +} + +type ConfigFileMap map[string]ConfigFileInput + +func (ConfigFileMap) ElementType() reflect.Type { + return reflect.TypeOf((*map[string]*ConfigFile)(nil)).Elem() +} + +func (i ConfigFileMap) ToConfigFileMapOutput() ConfigFileMapOutput { + return i.ToConfigFileMapOutputWithContext(context.Background()) +} + +func (i ConfigFileMap) ToConfigFileMapOutputWithContext(ctx context.Context) ConfigFileMapOutput { + return pulumi.ToOutputWithContext(ctx, i).(ConfigFileMapOutput) +} + +type ConfigFileOutput struct{ *pulumi.OutputState } + +func (ConfigFileOutput) ElementType() reflect.Type { + return reflect.TypeOf((**ConfigFile)(nil)).Elem() +} + +func (o ConfigFileOutput) ToConfigFileOutput() ConfigFileOutput { + return o +} + +func (o ConfigFileOutput) ToConfigFileOutputWithContext(ctx context.Context) ConfigFileOutput { + return o +} + +// Resources created by the ConfigFile. +func (o ConfigFileOutput) Resources() pulumi.ArrayOutput { + return o.ApplyT(func(v *ConfigFile) pulumi.ArrayOutput { return v.Resources }).(pulumi.ArrayOutput) +} + +type ConfigFileArrayOutput struct{ *pulumi.OutputState } + +func (ConfigFileArrayOutput) ElementType() reflect.Type { + return reflect.TypeOf((*[]*ConfigFile)(nil)).Elem() +} + +func (o ConfigFileArrayOutput) ToConfigFileArrayOutput() ConfigFileArrayOutput { + return o +} + +func (o ConfigFileArrayOutput) ToConfigFileArrayOutputWithContext(ctx context.Context) ConfigFileArrayOutput { + return o +} + +func (o ConfigFileArrayOutput) Index(i pulumi.IntInput) ConfigFileOutput { + return pulumi.All(o, i).ApplyT(func(vs []interface{}) *ConfigFile { + return vs[0].([]*ConfigFile)[vs[1].(int)] + }).(ConfigFileOutput) +} + +type ConfigFileMapOutput struct{ *pulumi.OutputState } + +func (ConfigFileMapOutput) ElementType() reflect.Type { + return reflect.TypeOf((*map[string]*ConfigFile)(nil)).Elem() +} + +func (o ConfigFileMapOutput) ToConfigFileMapOutput() ConfigFileMapOutput { + return o +} + +func (o ConfigFileMapOutput) ToConfigFileMapOutputWithContext(ctx context.Context) ConfigFileMapOutput { + return o +} + +func (o ConfigFileMapOutput) MapIndex(k pulumi.StringInput) ConfigFileOutput { + return pulumi.All(o, k).ApplyT(func(vs []interface{}) *ConfigFile { + return vs[0].(map[string]*ConfigFile)[vs[1].(string)] + }).(ConfigFileOutput) +} + +func init() { + pulumi.RegisterInputType(reflect.TypeOf((*ConfigFileInput)(nil)).Elem(), &ConfigFile{}) + pulumi.RegisterInputType(reflect.TypeOf((*ConfigFileArrayInput)(nil)).Elem(), ConfigFileArray{}) + pulumi.RegisterInputType(reflect.TypeOf((*ConfigFileMapInput)(nil)).Elem(), ConfigFileMap{}) + pulumi.RegisterOutputType(ConfigFileOutput{}) + pulumi.RegisterOutputType(ConfigFileArrayOutput{}) + pulumi.RegisterOutputType(ConfigFileMapOutput{}) +} diff --git a/sdk/go/kubernetes/yaml/v2/init.go b/sdk/go/kubernetes/yaml/v2/init.go index 4c686595bd..03fb389e70 100644 --- a/sdk/go/kubernetes/yaml/v2/init.go +++ b/sdk/go/kubernetes/yaml/v2/init.go @@ -21,6 +21,8 @@ func (m *module) Version() semver.Version { func (m *module) Construct(ctx *pulumi.Context, name, typ, urn string) (r pulumi.Resource, err error) { switch typ { + case "kubernetes:yaml/v2:ConfigFile": + r = &ConfigFile{} case "kubernetes:yaml/v2:ConfigGroup": r = &ConfigGroup{} default: diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigFile.java b/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigFile.java new file mode 100644 index 0000000000..ceb6f2881c --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigFile.java @@ -0,0 +1,73 @@ +// *** WARNING: this file was generated by pulumi-java-gen. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package com.pulumi.kubernetes.yaml.v2; + +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Export; +import com.pulumi.core.annotations.ResourceType; +import com.pulumi.core.internal.Codegen; +import com.pulumi.kubernetes.Utilities; +import com.pulumi.kubernetes.yaml.v2.ConfigFileArgs; +import java.lang.Object; +import java.util.List; +import java.util.Optional; +import javax.annotation.Nullable; + +/** + * ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file. + * + * ## Example Usage + * {% /examples %}} + * + */ +@ResourceType(type="kubernetes:yaml/v2:ConfigFile") +public class ConfigFile extends com.pulumi.resources.ComponentResource { + /** + * Resources created by the ConfigFile. + * + */ + @Export(name="resources", refs={List.class,Object.class}, tree="[0,1]") + private Output> resources; + + /** + * @return Resources created by the ConfigFile. + * + */ + public Output>> resources() { + return Codegen.optional(this.resources); + } + + /** + * + * @param name The _unique_ name of the resulting resource. + */ + public ConfigFile(String name) { + this(name, ConfigFileArgs.Empty); + } + /** + * + * @param name The _unique_ name of the resulting resource. + * @param args The arguments to use to populate this resource's properties. + */ + public ConfigFile(String name, ConfigFileArgs args) { + this(name, args, null); + } + /** + * + * @param name The _unique_ name of the resulting resource. + * @param args The arguments to use to populate this resource's properties. + * @param options A bag of options that control this resource's behavior. + */ + public ConfigFile(String name, ConfigFileArgs args, @Nullable com.pulumi.resources.ComponentResourceOptions options) { + super("kubernetes:yaml/v2:ConfigFile", name, args == null ? ConfigFileArgs.Empty : args, makeResourceOptions(options, Codegen.empty()), true); + } + + private static com.pulumi.resources.ComponentResourceOptions makeResourceOptions(@Nullable com.pulumi.resources.ComponentResourceOptions options, @Nullable Output id) { + var defaultOptions = com.pulumi.resources.ComponentResourceOptions.builder() + .version(Utilities.getVersion()) + .build(); + return com.pulumi.resources.ComponentResourceOptions.merge(defaultOptions, options, id); + } + +} diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigFileArgs.java b/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigFileArgs.java new file mode 100644 index 0000000000..889a4655dc --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigFileArgs.java @@ -0,0 +1,159 @@ +// *** WARNING: this file was generated by pulumi-java-gen. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package com.pulumi.kubernetes.yaml.v2; + +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Import; +import java.lang.Boolean; +import java.lang.String; +import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; + + +public final class ConfigFileArgs extends com.pulumi.resources.ResourceArgs { + + public static final ConfigFileArgs Empty = new ConfigFileArgs(); + + /** + * Path or URL to a Kubernetes manifest file. File must exist. + * + */ + @Import(name="file", required=true) + private Output file; + + /** + * @return Path or URL to a Kubernetes manifest file. File must exist. + * + */ + public Output file() { + return this.file; + } + + /** + * A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + * + */ + @Import(name="resourcePrefix") + private @Nullable Output resourcePrefix; + + /** + * @return A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + * + */ + public Optional> resourcePrefix() { + return Optional.ofNullable(this.resourcePrefix); + } + + /** + * Indicates that child resources should skip the await logic. + * + */ + @Import(name="skipAwait") + private @Nullable Output skipAwait; + + /** + * @return Indicates that child resources should skip the await logic. + * + */ + public Optional> skipAwait() { + return Optional.ofNullable(this.skipAwait); + } + + private ConfigFileArgs() {} + + private ConfigFileArgs(ConfigFileArgs $) { + this.file = $.file; + this.resourcePrefix = $.resourcePrefix; + this.skipAwait = $.skipAwait; + } + + public static Builder builder() { + return new Builder(); + } + public static Builder builder(ConfigFileArgs defaults) { + return new Builder(defaults); + } + + public static final class Builder { + private ConfigFileArgs $; + + public Builder() { + $ = new ConfigFileArgs(); + } + + public Builder(ConfigFileArgs defaults) { + $ = new ConfigFileArgs(Objects.requireNonNull(defaults)); + } + + /** + * @param file Path or URL to a Kubernetes manifest file. File must exist. + * + * @return builder + * + */ + public Builder file(Output file) { + $.file = file; + return this; + } + + /** + * @param file Path or URL to a Kubernetes manifest file. File must exist. + * + * @return builder + * + */ + public Builder file(String file) { + return file(Output.of(file)); + } + + /** + * @param resourcePrefix A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + * + * @return builder + * + */ + public Builder resourcePrefix(@Nullable Output resourcePrefix) { + $.resourcePrefix = resourcePrefix; + return this; + } + + /** + * @param resourcePrefix A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + * + * @return builder + * + */ + public Builder resourcePrefix(String resourcePrefix) { + return resourcePrefix(Output.of(resourcePrefix)); + } + + /** + * @param skipAwait Indicates that child resources should skip the await logic. + * + * @return builder + * + */ + public Builder skipAwait(@Nullable Output skipAwait) { + $.skipAwait = skipAwait; + return this; + } + + /** + * @param skipAwait Indicates that child resources should skip the await logic. + * + * @return builder + * + */ + public Builder skipAwait(Boolean skipAwait) { + return skipAwait(Output.of(skipAwait)); + } + + public ConfigFileArgs build() { + $.file = Objects.requireNonNull($.file, "expected parameter 'file' to be non-null"); + return $; + } + } + +} diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/yaml_v2/ConfigGroup.java b/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigGroup.java similarity index 96% rename from sdk/java/src/main/java/com/pulumi/kubernetes/yaml_v2/ConfigGroup.java rename to sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigGroup.java index 496b963e4c..f370b51be0 100644 --- a/sdk/java/src/main/java/com/pulumi/kubernetes/yaml_v2/ConfigGroup.java +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigGroup.java @@ -1,14 +1,14 @@ // *** WARNING: this file was generated by pulumi-java-gen. *** // *** Do not edit by hand unless you're certain you know what you are doing! *** -package com.pulumi.kubernetes.yaml_v2; +package com.pulumi.kubernetes.yaml.v2; import com.pulumi.core.Output; import com.pulumi.core.annotations.Export; import com.pulumi.core.annotations.ResourceType; import com.pulumi.core.internal.Codegen; import com.pulumi.kubernetes.Utilities; -import com.pulumi.kubernetes.yaml_v2.ConfigGroupArgs; +import com.pulumi.kubernetes.yaml.v2.ConfigGroupArgs; import java.lang.Object; import java.util.List; import java.util.Optional; diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/yaml_v2/ConfigGroupArgs.java b/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigGroupArgs.java similarity index 99% rename from sdk/java/src/main/java/com/pulumi/kubernetes/yaml_v2/ConfigGroupArgs.java rename to sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigGroupArgs.java index c66dc02273..36e6b89c5e 100644 --- a/sdk/java/src/main/java/com/pulumi/kubernetes/yaml_v2/ConfigGroupArgs.java +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/yaml/v2/ConfigGroupArgs.java @@ -1,7 +1,7 @@ // *** WARNING: this file was generated by pulumi-java-gen. *** // *** Do not edit by hand unless you're certain you know what you are doing! *** -package com.pulumi.kubernetes.yaml_v2; +package com.pulumi.kubernetes.yaml.v2; import com.pulumi.core.Output; import com.pulumi.core.annotations.Import; diff --git a/sdk/nodejs/tsconfig.json b/sdk/nodejs/tsconfig.json index 22d7e98a4f..e6365f2a41 100644 --- a/sdk/nodejs/tsconfig.json +++ b/sdk/nodejs/tsconfig.json @@ -485,6 +485,7 @@ "types/output.ts", "utilities.ts", "yaml/index.ts", + "yaml/v2/configFile.ts", "yaml/v2/configGroup.ts", "yaml/v2/index.ts", "yaml/yaml.ts" diff --git a/sdk/nodejs/yaml/v2/configFile.ts b/sdk/nodejs/yaml/v2/configFile.ts new file mode 100644 index 0000000000..db0512e28f --- /dev/null +++ b/sdk/nodejs/yaml/v2/configFile.ts @@ -0,0 +1,84 @@ +// *** WARNING: this file was generated by pulumigen. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +import * as pulumi from "@pulumi/pulumi"; +import * as utilities from "../../utilities"; + +/** + * ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file. + * + * ## Example Usage + * ### Local File + * + * ```typescript + * import * as k8s from "@pulumi/kubernetes"; + * + * const example = new k8s.yaml.v2.ConfigFile("example", { + * file: "foo.yaml", + * }); + * ``` + * {% /examples %}} + */ +export class ConfigFile extends pulumi.ComponentResource { + /** @internal */ + public static readonly __pulumiType = 'kubernetes:yaml/v2:ConfigFile'; + + /** + * Returns true if the given object is an instance of ConfigFile. This is designed to work even + * when multiple copies of the Pulumi SDK have been loaded into the same process. + */ + public static isInstance(obj: any): obj is ConfigFile { + if (obj === undefined || obj === null) { + return false; + } + return obj['__pulumiType'] === ConfigFile.__pulumiType; + } + + /** + * Resources created by the ConfigFile. + */ + public /*out*/ readonly resources!: pulumi.Output; + + /** + * Create a ConfigFile resource with the given unique name, arguments, and options. + * + * @param name The _unique_ name of the resource. + * @param args The arguments to use to populate this resource's properties. + * @param opts A bag of options that control this resource's behavior. + */ + constructor(name: string, args?: ConfigFileArgs, opts?: pulumi.ComponentResourceOptions) { + let resourceInputs: pulumi.Inputs = {}; + opts = opts || {}; + if (!opts.id) { + if ((!args || args.file === undefined) && !opts.urn) { + throw new Error("Missing required property 'file'"); + } + resourceInputs["file"] = args ? args.file : undefined; + resourceInputs["resourcePrefix"] = args ? args.resourcePrefix : undefined; + resourceInputs["skipAwait"] = args ? args.skipAwait : undefined; + resourceInputs["resources"] = undefined /*out*/; + } else { + resourceInputs["resources"] = undefined /*out*/; + } + opts = pulumi.mergeOptions(utilities.resourceOptsDefaults(), opts); + super(ConfigFile.__pulumiType, name, resourceInputs, opts, true /*remote*/); + } +} + +/** + * The set of arguments for constructing a ConfigFile resource. + */ +export interface ConfigFileArgs { + /** + * Path or URL to a Kubernetes manifest file. File must exist. + */ + file: pulumi.Input; + /** + * A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + */ + resourcePrefix?: pulumi.Input; + /** + * Indicates that child resources should skip the await logic. + */ + skipAwait?: pulumi.Input; +} diff --git a/sdk/nodejs/yaml/v2/index.ts b/sdk/nodejs/yaml/v2/index.ts index ac20bb4e86..94983a024b 100644 --- a/sdk/nodejs/yaml/v2/index.ts +++ b/sdk/nodejs/yaml/v2/index.ts @@ -5,6 +5,11 @@ import * as pulumi from "@pulumi/pulumi"; import * as utilities from "../../utilities"; // Export members: +export { ConfigFileArgs } from "./configFile"; +export type ConfigFile = import("./configFile").ConfigFile; +export const ConfigFile: typeof import("./configFile").ConfigFile = null as any; +utilities.lazyLoad(exports, ["ConfigFile"], () => require("./configFile")); + export { ConfigGroupArgs } from "./configGroup"; export type ConfigGroup = import("./configGroup").ConfigGroup; export const ConfigGroup: typeof import("./configGroup").ConfigGroup = null as any; @@ -15,6 +20,8 @@ const _module = { version: utilities.getVersion(), construct: (name: string, type: string, urn: string): pulumi.Resource => { switch (type) { + case "kubernetes:yaml/v2:ConfigFile": + return new ConfigFile(name, undefined, { urn }) case "kubernetes:yaml/v2:ConfigGroup": return new ConfigGroup(name, undefined, { urn }) default: diff --git a/sdk/python/pulumi_kubernetes/__init__.py b/sdk/python/pulumi_kubernetes/__init__.py index 37d9a5f09f..6afec98067 100644 --- a/sdk/python/pulumi_kubernetes/__init__.py +++ b/sdk/python/pulumi_kubernetes/__init__.py @@ -867,6 +867,7 @@ "mod": "yaml/v2", "fqn": "pulumi_kubernetes.yaml.v2", "classes": { + "kubernetes:yaml/v2:ConfigFile": "ConfigFile", "kubernetes:yaml/v2:ConfigGroup": "ConfigGroup" } } diff --git a/sdk/python/pulumi_kubernetes/yaml/v2/ConfigFile.py b/sdk/python/pulumi_kubernetes/yaml/v2/ConfigFile.py new file mode 100644 index 0000000000..07e2f361fe --- /dev/null +++ b/sdk/python/pulumi_kubernetes/yaml/v2/ConfigFile.py @@ -0,0 +1,169 @@ +# coding=utf-8 +# *** WARNING: this file was generated by pulumigen. *** +# *** Do not edit by hand unless you're certain you know what you are doing! *** + +import copy +import warnings +import pulumi +import pulumi.runtime +from typing import Any, Mapping, Optional, Sequence, Union, overload +from ... import _utilities + +__all__ = ['ConfigFileArgs', 'ConfigFile'] + +@pulumi.input_type +class ConfigFileArgs: + def __init__(__self__, *, + file: pulumi.Input[str], + resource_prefix: Optional[pulumi.Input[str]] = None, + skip_await: Optional[pulumi.Input[bool]] = None): + """ + The set of arguments for constructing a ConfigFile resource. + :param pulumi.Input[str] file: Path or URL to a Kubernetes manifest file. File must exist. + :param pulumi.Input[str] resource_prefix: A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + :param pulumi.Input[bool] skip_await: Indicates that child resources should skip the await logic. + """ + pulumi.set(__self__, "file", file) + if resource_prefix is not None: + pulumi.set(__self__, "resource_prefix", resource_prefix) + if skip_await is not None: + pulumi.set(__self__, "skip_await", skip_await) + + @property + @pulumi.getter + def file(self) -> pulumi.Input[str]: + """ + Path or URL to a Kubernetes manifest file. File must exist. + """ + return pulumi.get(self, "file") + + @file.setter + def file(self, value: pulumi.Input[str]): + pulumi.set(self, "file", value) + + @property + @pulumi.getter(name="resourcePrefix") + def resource_prefix(self) -> Optional[pulumi.Input[str]]: + """ + A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + """ + return pulumi.get(self, "resource_prefix") + + @resource_prefix.setter + def resource_prefix(self, value: Optional[pulumi.Input[str]]): + pulumi.set(self, "resource_prefix", value) + + @property + @pulumi.getter(name="skipAwait") + def skip_await(self) -> Optional[pulumi.Input[bool]]: + """ + Indicates that child resources should skip the await logic. + """ + return pulumi.get(self, "skip_await") + + @skip_await.setter + def skip_await(self, value: Optional[pulumi.Input[bool]]): + pulumi.set(self, "skip_await", value) + + +class ConfigFile(pulumi.ComponentResource): + @overload + def __init__(__self__, + resource_name: str, + opts: Optional[pulumi.ResourceOptions] = None, + file: Optional[pulumi.Input[str]] = None, + resource_prefix: Optional[pulumi.Input[str]] = None, + skip_await: Optional[pulumi.Input[bool]] = None, + __props__=None): + """ + ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file. + + ## Example Usage + ### Local File + ```python + from pulumi_kubernetes.yaml.v2 import ConfigFile + + example = ConfigFile( + "example", + file="foo.yaml", + ) + ``` + {% /examples %}} + + :param str resource_name: The name of the resource. + :param pulumi.ResourceOptions opts: Options for the resource. + :param pulumi.Input[str] file: Path or URL to a Kubernetes manifest file. File must exist. + :param pulumi.Input[str] resource_prefix: A prefix for the auto-generated resource names. Defaults to the name of the ConfigFile. Example: A resource created with resourcePrefix="foo" would produce a resource named "foo-resourceName". + :param pulumi.Input[bool] skip_await: Indicates that child resources should skip the await logic. + """ + ... + @overload + def __init__(__self__, + resource_name: str, + args: ConfigFileArgs, + opts: Optional[pulumi.ResourceOptions] = None): + """ + ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file. + + ## Example Usage + ### Local File + ```python + from pulumi_kubernetes.yaml.v2 import ConfigFile + + example = ConfigFile( + "example", + file="foo.yaml", + ) + ``` + {% /examples %}} + + :param str resource_name: The name of the resource. + :param ConfigFileArgs args: The arguments to use to populate this resource's properties. + :param pulumi.ResourceOptions opts: Options for the resource. + """ + ... + def __init__(__self__, resource_name: str, *args, **kwargs): + resource_args, opts = _utilities.get_resource_args_opts(ConfigFileArgs, pulumi.ResourceOptions, *args, **kwargs) + if resource_args is not None: + __self__._internal_init(resource_name, opts, **resource_args.__dict__) + else: + __self__._internal_init(resource_name, *args, **kwargs) + + def _internal_init(__self__, + resource_name: str, + opts: Optional[pulumi.ResourceOptions] = None, + file: Optional[pulumi.Input[str]] = None, + resource_prefix: Optional[pulumi.Input[str]] = None, + skip_await: Optional[pulumi.Input[bool]] = None, + __props__=None): + opts = pulumi.ResourceOptions.merge(_utilities.get_resource_opts_defaults(), opts) + if not isinstance(opts, pulumi.ResourceOptions): + raise TypeError('Expected resource options to be a ResourceOptions instance') + if opts.id is not None: + raise ValueError('ComponentResource classes do not support opts.id') + else: + if __props__ is not None: + raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource') + __props__ = ConfigFileArgs.__new__(ConfigFileArgs) + + if file is None and not opts.urn: + raise TypeError("Missing required property 'file'") + __props__.__dict__["file"] = file + __props__.__dict__["resource_prefix"] = resource_prefix + __props__.__dict__["skip_await"] = skip_await + __props__.__dict__["resources"] = None + super(ConfigFile, __self__).__init__( + 'kubernetes:yaml/v2:ConfigFile', + resource_name, + __props__, + opts, + remote=True) + + @property + @pulumi.getter + def resources(self) -> pulumi.Output[Optional[Sequence[Any]]]: + """ + Resources created by the ConfigFile. + """ + return pulumi.get(self, "resources") + diff --git a/sdk/python/pulumi_kubernetes/yaml/v2/__init__.py b/sdk/python/pulumi_kubernetes/yaml/v2/__init__.py index dff738074e..aa6bbc0db6 100644 --- a/sdk/python/pulumi_kubernetes/yaml/v2/__init__.py +++ b/sdk/python/pulumi_kubernetes/yaml/v2/__init__.py @@ -5,4 +5,5 @@ from ... import _utilities import typing # Export this package's modules as members: +from .ConfigFile import * from .ConfigGroup import *