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* @Nullable */ List