diff --git a/CHANGELOG.md b/CHANGELOG.md index 726f59e8ff..a60f12c50f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ ## Unreleased -- Update to pulumi-java v0.12.0 #3025 (https://github.com/pulumi/pulumi-kubernetes/pull/3025) +- Update to pulumi-java v0.12.0 (https://github.com/pulumi/pulumi-kubernetes/pull/3025) - Fixed a panic that occurs when diffing Job resources containing `replaceUnready` annotations and an unreachable cluster connection. (https://github.com/pulumi/pulumi-kubernetes/pull/3024) +- CustomResource for Java SDK (https://github.com/pulumi/pulumi-kubernetes/pull/3020) ## 4.12.0 (May 21, 2024) diff --git a/Makefile b/Makefile index fe1b0ee038..077033fd98 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,8 @@ python_sdk:: java_sdk:: PACKAGE_VERSION := $(shell pulumictl convert-version --language generic -v "$(VERSION_GENERIC)") java_sdk:: bin/pulumi-java-gen - $(WORKING_DIR)/bin/$(JAVA_GEN) generate --schema $(SCHEMA_FILE) --out sdk/java --build gradle-nexus + $(WORKING_DIR)/bin/$(JAVA_GEN) generate --schema $(SCHEMA_FILE) --overlay provider/pkg/gen/java-templates \ + --out sdk/java --build gradle-nexus cd ${PACKDIR}/java/ && \ echo "module fake_java_module // Exclude this directory from Go tools\n\ngo 1.17" > go.mod && \ gradle --console=plain build diff --git a/examples/java/customresource/Pulumi.yaml b/examples/java/customresource/Pulumi.yaml new file mode 100644 index 0000000000..57f6cbec56 --- /dev/null +++ b/examples/java/customresource/Pulumi.yaml @@ -0,0 +1,7 @@ +name: example +runtime: java +description: An example for com.pulumi.kubernetes.apiextensions.CustomResource +config: + pulumi:tags: + value: + pulumi:template: "" diff --git a/examples/java/customresource/pom.xml b/examples/java/customresource/pom.xml new file mode 100644 index 0000000000..7b3f51ab81 --- /dev/null +++ b/examples/java/customresource/pom.xml @@ -0,0 +1,97 @@ + + + 4.0.0 + + com.pulumi + issue-2787-javaa + 1.0-SNAPSHOT + + + UTF-8 + 11 + 11 + 11 + myproject.App + + + + + + com.pulumi + pulumi + (,1.0] + + + com.pulumi + kubernetes + (,5.0] + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + + true + ${mainClass} + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + + true + ${mainClass} + + + + jar-with-dependencies + + + + + make-my-jar-with-dependencies + package + + single + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + ${mainClass} + ${mainArgs} + + + + org.apache.maven.plugins + maven-wrapper-plugin + 3.1.0 + + 3.8.5 + + + + + diff --git a/examples/java/customresource/src/main/java/myproject/App.java b/examples/java/customresource/src/main/java/myproject/App.java new file mode 100644 index 0000000000..8a87f4978c --- /dev/null +++ b/examples/java/customresource/src/main/java/myproject/App.java @@ -0,0 +1,299 @@ +package myproject; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import javax.annotation.Nullable; + +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.core.annotations.CustomType; +import com.pulumi.core.annotations.Export; +import com.pulumi.core.annotations.Import; +import com.pulumi.kubernetes.apiextensions.CustomResource; +import com.pulumi.kubernetes.apiextensions.CustomResourceArgs; +import com.pulumi.kubernetes.apiextensions.CustomResourceArgsBase; +import com.pulumi.kubernetes.meta.v1.inputs.ObjectMetaArgs; + +/** + * Demonstration of working with custom resources in the Java SDK. + * Prerequisites: + * - cert-manager v1.x installed in your Kubernetes cluster. + * + * This example deploys a cert-manager.io/v1 Issuer to your Kubernetes cluster. + * Two different ways of defining the Issuer are demonstrated: + * - Using the CustomResource class directly. + * - Using a custom Issuer class that extends CustomResource, to provide a + * type-safe API. + */ +public class App { + public static void main(String[] args) { + Pulumi.run(ctx -> { + var issuer1 = new CustomResource("issuer1", CustomResourceArgs.builder() + .apiVersion("cert-manager.io/v1") + .kind("Issuer") + .metadata(ObjectMetaArgs.builder().build()) + .build()); + ctx.export("issuer1_name", issuer1.metadata().applyValue(s -> s.name())); + + var issuer2 = new Issuer("issuer2", IssuerArgs.builder() + .metadata(ObjectMetaArgs.builder().build()) + .spec(Inputs.IssuerSpecArgs.builder() + .selfSigned(Inputs.SelfSignedArgs.builder().build()) + .build()) + .build()); + + ctx.export("issuer2_name", issuer2.metadata().applyValue(s -> s.name())); + ctx.export("issuer2_selfsigned", issuer2.spec().applyValue(s -> s.selfSigned().isPresent())); + }); + } +} + +class Issuer extends CustomResource { + /** + * The spec of the Issuer. + */ + @Export(name = "spec", refs = { Outputs.IssuerSpec.class }, tree = "[0]") + private Output spec; + + public Output spec() { + return this.spec; + } + + public Issuer(String name, @Nullable IssuerArgs args) { + super(name, makeArgs(args)); + } + + public Issuer(String name, @Nullable IssuerArgs args, + @Nullable com.pulumi.resources.CustomResourceOptions options) { + super(name, makeArgs(args), options); + } + + protected Issuer(String name, Output id, + @Nullable com.pulumi.resources.CustomResourceOptions options) { + super(name, "cert-manager.io/v1", "Issuer", id, options); + } + + private static IssuerArgs makeArgs(@Nullable IssuerArgs args) { + var builder = args == null ? IssuerArgs.builder() : IssuerArgs.builder(args); + return builder + .apiVersion("cert-manager.io/v1") + .kind("Issuer") + .build(); + } + + public static Issuer get(String name, Output id, + @Nullable com.pulumi.resources.CustomResourceOptions options) { + return new Issuer(name, id, options); + } +} + +class IssuerArgs extends CustomResourceArgsBase { + /** + * The spec of the Issuer. + */ + @Import(name = "spec", required = true) + @Nullable + private Output spec; + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(IssuerArgs defaults) { + return new Builder(defaults); + } + + static class Builder extends CustomResourceArgsBase.Builder { + public Builder() { + super(new IssuerArgs()); + } + + public Builder(IssuerArgs defaults) { + super(new IssuerArgs(), defaults); + } + + public Builder spec(@Nullable Output spec) { + $.spec = spec; + return this; + } + + public Builder spec(Inputs.IssuerSpecArgs spec) { + return spec(Output.of(spec)); + } + + @Override + protected void copy(IssuerArgs args) { + super.copy(args); + $.spec = args.spec; + } + } +} + +class Inputs { + public static final class IssuerSpecArgs extends com.pulumi.resources.ResourceArgs { + + public static final IssuerSpecArgs Empty = new IssuerSpecArgs(); + + @Import(name = "selfSigned") + private @Nullable Output selfSigned; + + public Optional> selfSigned() { + return Optional.ofNullable(this.selfSigned); + } + + private IssuerSpecArgs() { + } + + private IssuerSpecArgs(IssuerSpecArgs $) { + this.selfSigned = $.selfSigned; + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(IssuerSpecArgs defaults) { + return new Builder(defaults); + } + + public static final class Builder { + private IssuerSpecArgs $; + + public Builder() { + $ = new IssuerSpecArgs(); + } + + public Builder(IssuerSpecArgs defaults) { + $ = new IssuerSpecArgs(Objects.requireNonNull(defaults)); + } + + public Builder selfSigned(@Nullable Output selfSigned) { + $.selfSigned = selfSigned; + return this; + } + + public Builder selfSigned(SelfSignedArgs selfSigned) { + return selfSigned(Output.of(selfSigned)); + } + + public IssuerSpecArgs build() { + return $; + } + } + } + + public static final class SelfSignedArgs extends com.pulumi.resources.ResourceArgs { + + public static final SelfSignedArgs Empty = new SelfSignedArgs(); + + private SelfSignedArgs() { + } + + private SelfSignedArgs(SelfSignedArgs $) { + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(SelfSignedArgs defaults) { + return new Builder(defaults); + } + + public static final class Builder { + private SelfSignedArgs $; + + public Builder() { + $ = new SelfSignedArgs(); + } + + public Builder(SelfSignedArgs defaults) { + $ = new SelfSignedArgs(Objects.requireNonNull(defaults)); + } + + public SelfSignedArgs build() { + return $; + } + } + } +} + +class Outputs { + @CustomType + static final class IssuerSpec { + + private @Nullable SelfSigned selfSigned; + + private IssuerSpec() { + } + + public Optional selfSigned() { + return Optional.ofNullable(this.selfSigned); + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(IssuerSpec defaults) { + return new Builder(defaults); + } + + @CustomType.Builder + public static final class Builder { + private @Nullable SelfSigned selfSigned; + + public Builder() { + } + + public Builder(IssuerSpec defaults) { + Objects.requireNonNull(defaults); + this.selfSigned = defaults.selfSigned; + } + + @CustomType.Setter + public Builder selfSigned(@Nullable SelfSigned selfSigned) { + this.selfSigned = selfSigned; + return this; + } + + public IssuerSpec build() { + final var _resultValue = new IssuerSpec(); + _resultValue.selfSigned = selfSigned; + return _resultValue; + } + } + } + + @CustomType + static final class SelfSigned { + + private SelfSigned() { + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(SelfSigned defaults) { + return new Builder(defaults); + } + + @CustomType.Builder + public static final class Builder { + public Builder() { + } + + public Builder(SelfSigned defaults) { + Objects.requireNonNull(defaults); + } + + public SelfSigned build() { + final var _resultValue = new SelfSigned(); + return _resultValue; + } + } + } +} diff --git a/provider/cmd/pulumi-resource-kubernetes/schema.json b/provider/cmd/pulumi-resource-kubernetes/schema.json index 3825ee5d1e..bb3e850936 100644 --- a/provider/cmd/pulumi-resource-kubernetes/schema.json +++ b/provider/cmd/pulumi-resource-kubernetes/schema.json @@ -237,6 +237,10 @@ "respectSchemaVersion": true }, "java": { + "dependencies": { + "com.google.guava:guava": "32.1.2-jre", + "net.bytebuddy:byte-buddy": "1.14.15" + }, "packages": { "admissionregistration.k8s.io/v1": "admissionregistration.v1", "admissionregistration.k8s.io/v1alpha1": "admissionregistration.v1alpha1", diff --git a/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResource.java b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResource.java new file mode 100644 index 0000000000..573ec88ed4 --- /dev/null +++ b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResource.java @@ -0,0 +1,155 @@ +// *** 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.apiextensions; + +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import javax.annotation.Nullable; + +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.core.internal.Internal; +import com.pulumi.core.internal.OutputInternal; +import com.pulumi.kubernetes.Utilities; +import com.pulumi.kubernetes.meta.v1.outputs.ObjectMeta; +import com.pulumi.resources.ResourceArgs; + +/** + * CustomResource represents an instance of a CustomResourceDefinition (CRD). For example, the + * CoreOS Prometheus operator exposes a CRD `monitoring.coreos.com/ServiceMonitor`; to + * instantiate this as a Pulumi resource, one could call `new CustomResource`, passing the + * `ServiceMonitor` resource definition as an argument. + */ +@ResourceType(type="kubernetes:apiextensions:CustomResource") +public class CustomResource extends com.pulumi.resources.CustomResource { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + @Export(name="apiVersion", refs={String.class}, tree="[0]") + private Output apiVersion; + + /** + * @return APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + public Output apiVersion() { + return this.apiVersion; + } + + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + @Export(name="kind", refs={String.class}, tree="[0]") + private Output kind; + + /** + * @return Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + public Output kind() { + return this.kind; + } + + /** + * Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + @Export(name="metadata", refs={ObjectMeta.class}, tree="[0]") + private Output metadata; + + /** + * @return Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + public Output metadata() { + return this.metadata; + } + + /** + * + * @param name The _unique_ name of the resulting resource. + */ + public CustomResource(String name) { + this(name, CustomResourceArgs.Empty); + } + + /** + * + * @param name The _unique_ name of the resulting resource. + * @param args The arguments to use to populate this resource's properties. + */ + public CustomResource(String name, @Nullable CustomResourceArgsBase 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 CustomResource(String name, @Nullable CustomResourceArgsBase args, @Nullable com.pulumi.resources.CustomResourceOptions options) { + super(makeType(args), name, makeArgs(args), makeResourceOptions(options, Codegen.empty())); + } + + protected CustomResource(String name, String apiVersion, String kind, Output id, + @Nullable com.pulumi.resources.CustomResourceOptions options) { + super(String.format("kubernetes:%s:%s", apiVersion, kind), name, null, makeResourceOptions(options, id)); + } + + private static String makeType(@Nullable CustomResourceArgsBase args) { + String apiVersion = args.apiVersion().map(Internal::of).map(CustomResource::getOutputValue).orElse(""); + String kind = args.kind().map(Internal::of).map(CustomResource::getOutputValue).orElse(""); + return String.format("kubernetes:%s:%s", apiVersion, kind); + } + + private static String getOutputValue(OutputInternal o) { + try { + return o.getValueOrDefault("").get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + private static ResourceArgs makeArgs(@Nullable CustomResourceArgsBase args) { + if (args == null) { + return null; + } + if (args.otherFields().isEmpty() || args.otherFields().get().isEmpty()) { + // optimization: if there are no "other" fields, we can just return the args as-is. + // Otherwise we generate a subclass of ResourceArgs that includes the "other" fields. + return args; + } + return Util.generateResourceArgs(args, args.otherFields().get()); + } + + private static com.pulumi.resources.CustomResourceOptions makeResourceOptions( + @Nullable com.pulumi.resources.CustomResourceOptions options, @Nullable Output id) { + var defaultOptions = com.pulumi.resources.CustomResourceOptions.builder() + .version(Utilities.getVersion()) + .build(); + return com.pulumi.resources.CustomResourceOptions.merge(defaultOptions, options, id); + } + + /** + * Get the state of an existing `CustomResource` resource, as identified by `id`. + * Typically this ID is of the form [namespace]/[name]; if [namespace] is omitted, + * then (per Kubernetes convention) the ID becomes default/[name]. + * + * @param name The _unique_ name of the resulting resource. + * @param apiVersion The API version of the CustomResource we wish to select, as defined by the CRD. + * @param kind The kind of the CustomResource we wish to select, as defined by the CRD. + * @param id An ID for the Kubernetes resource to retrieve. + * @param options Optional settings to control the behavior of the CustomResource. + */ + public static CustomResource get(String name, String apiVersion, String kind, Output id, + @Nullable com.pulumi.resources.CustomResourceOptions options) { + return new CustomResource(name, apiVersion, kind, id, options); + } +} diff --git a/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgs.java b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgs.java new file mode 100644 index 0000000000..b342836b16 --- /dev/null +++ b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgs.java @@ -0,0 +1,34 @@ +// *** 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.apiextensions; + +/** + * The set of arguments for constructing a CustomResource resource. + * + * NOTE: This type is fairly loose, since other than `apiVersion` and `kind`, + * there are no fields required across all CRDs. Use otherFields(...) to specify + * additional fields. + */ +public final class CustomResourceArgs extends CustomResourceArgsBase { + + public static final CustomResourceArgs Empty = new CustomResourceArgs(); + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(CustomResourceArgs defaults) { + return new Builder(defaults); + } + + public static final class Builder extends CustomResourceArgsBase.Builder { + public Builder() { + super(new CustomResourceArgs()); + } + + public Builder(CustomResourceArgs defaults) { + super(new CustomResourceArgs(), defaults); + } + } +} diff --git a/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgsBase.java b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgsBase.java new file mode 100644 index 0000000000..81d901788c --- /dev/null +++ b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgsBase.java @@ -0,0 +1,204 @@ +// *** 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.apiextensions; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import javax.annotation.Nullable; + +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Import; +import com.pulumi.core.internal.Codegen; +import com.pulumi.kubernetes.meta.v1.inputs.ObjectMetaArgs; + +/** + * CustomResourceArgsBase is the base class for a user-defined + * CustomResourceArgs. + */ +public abstract class CustomResourceArgsBase extends com.pulumi.resources.ResourceArgs { + + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + @Import(name="apiVersion") + @Nullable Output apiVersion; + + /** + * @return APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + public Optional> apiVersion() { + return Optional.ofNullable(this.apiVersion); + } + + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + @Import(name="kind") + @Nullable Output kind; + + /** + * @return Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + public Optional> kind() { + return Optional.ofNullable(this.kind); + } + + /** + * Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + @Import(name="metadata") + @Nullable Output metadata; + + /** + * @return Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + public Optional> metadata() { + return Optional.ofNullable(this.metadata); + } + + /** + * Untyped map that holds any user-defined fields. + * + */ + @Nullable Map> otherFields; + + /** + * @return Untyped map that holds any user-defined fields. + * + */ + public Optional>> otherFields() { + return Optional.ofNullable(this.otherFields); + } + + protected CustomResourceArgsBase() { + } + + public static class Builder> { + protected T $; + + protected Builder(T $) { + this.$ = $; + } + + protected Builder(T $, T defaults) { + this($); + copy(Objects.requireNonNull(defaults)); + } + + protected void copy(T args) { + $.apiVersion = args.apiVersion; + $.kind = args.kind; + $.metadata = args.metadata; + $.otherFields = args.otherFields; + } + + /** + * @param apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + * @return builder + * + */ + public U apiVersion(@Nullable Output apiVersion) { + $.apiVersion = apiVersion; + return (U) this; + } + + /** + * @param apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + * @return builder + * + */ + public U apiVersion(String apiVersion) { + return apiVersion(Output.of(apiVersion)); + } + + /** + * @param kind Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + * @return builder + * + */ + public U kind(@Nullable Output kind) { + $.kind = kind; + return (U) this; + } + + /** + * @param kind Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + * @return builder + * + */ + public U kind(String kind) { + return kind(Output.of(kind)); + } + + /** + * @param metadata Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + * @return builder + * + */ + public U metadata(@Nullable Output metadata) { + $.metadata = metadata; + return (U) this; + } + + /** + * @param metadata Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + * @return builder + * + */ + public U metadata(ObjectMetaArgs metadata) { + return metadata(Output.of(metadata)); + } + + /** + * @param fields Untyped map that holds any user-defined fields (which may be Output values). + * + * @return builder + * + */ + public U otherFields(Map fields) { + var map = $.otherFields != null ? new LinkedHashMap($.otherFields) : new LinkedHashMap(); + for (var entry : fields.entrySet()) { + var value = entry.getValue(); + map.put(entry.getKey(), (value instanceof Output) ? (Output) value : Output.of(value)); + } + $.otherFields = map; + return (U) this; + } + + /** + * @param field The user-defined field name. + * @param value The field value, which may be an Output value. + * @return builder + * + */ + public U otherField(String field, Object value) { + var map = $.otherFields != null ? new LinkedHashMap($.otherFields) : new LinkedHashMap(); + map.put(field, value instanceof Output ? value : Output.of(value)); + $.otherFields = map; + return (U) this; + } + + public T build() { + $.apiVersion = Codegen.stringProp("apiVersion").output().arg($.apiVersion).getNullable(); + $.kind = Codegen.stringProp("kind").output().arg($.kind).getNullable(); + return (T) $; + } + } + +} diff --git a/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatch.java b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatch.java new file mode 100644 index 0000000000..c8ae3ea09b --- /dev/null +++ b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatch.java @@ -0,0 +1,140 @@ +// *** 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.apiextensions; + +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import javax.annotation.Nullable; + +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.core.internal.Internal; +import com.pulumi.core.internal.OutputInternal; +import com.pulumi.kubernetes.Utilities; +import com.pulumi.kubernetes.meta.v1.outputs.ObjectMetaPatch; +import com.pulumi.resources.ResourceArgs; + +/** + * Patch resources are used to modify existing Kubernetes resources by using + * Server-Side Apply updates. The name of the resource must be specified, but all other properties are optional. More than + * one patch may be applied to the same resource, and a random FieldManager name will be used for each Patch resource. + * Conflicts will result in an error by default, but can be forced using the "pulumi.com/patchForce" annotation. See the + * [Server-Side Apply Docs](https://www.pulumi.com/registry/packages/kubernetes/how-to-guides/managing-resources-with-server-side-apply/) for + * additional information about using Server-Side Apply to manage Kubernetes resources with Pulumi. + * + * CustomResourcePatch represents an instance of a CustomResourceDefinition (CRD). For example, the + * CoreOS Prometheus operator exposes a CRD `monitoring.coreos.com/ServiceMonitor`; to + * instantiate this as a Pulumi resource, one could call `new CustomResourcePatch`, passing the + * `ServiceMonitor` resource definition as an argument. + */ +@ResourceType(type="kubernetes:apiextensions:CustomResourcePatch") +public class CustomResourcePatch extends com.pulumi.resources.CustomResource { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + @Export(name="apiVersion", refs={String.class}, tree="[0]") + private Output apiVersion; + + /** + * @return APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + public Output> apiVersion() { + return Codegen.optional(this.apiVersion); + } + + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + @Export(name="kind", refs={String.class}, tree="[0]") + private Output kind; + + /** + * @return Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + public Output> kind() { + return Codegen.optional(this.kind); + } + /** + * Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + @Export(name="metadata", refs={ObjectMetaPatch.class}, tree="[0]") + private Output metadata; + + /** + * @return Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + public Output> metadata() { + return Codegen.optional(this.metadata); + } + + /** + * + * @param name The _unique_ name of the resulting resource. + */ + public CustomResourcePatch(String name) { + this(name, CustomResourcePatchArgs.Empty); + } + + /** + * + * @param name The _unique_ name of the resulting resource. + * @param args The arguments to use to populate this resource's properties. + */ + public CustomResourcePatch(String name, @Nullable CustomResourcePatchArgsBase 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 CustomResourcePatch(String name, @Nullable CustomResourcePatchArgsBase args, @Nullable com.pulumi.resources.CustomResourceOptions options) { + super(makeType(args), name, makeArgs(args), makeResourceOptions(options, Codegen.empty())); + } + + private static String makeType(@Nullable CustomResourcePatchArgsBase args) { + String apiVersion = args.apiVersion().map(Internal::of).map(CustomResourcePatch::getOutputValue).orElse(""); + String kind = args.kind().map(Internal::of).map(CustomResourcePatch::getOutputValue).orElse(""); + return String.format("kubernetes:%s:%sPatch", apiVersion, kind); + } + + private static String getOutputValue(OutputInternal o) { + try { + return o.getValueOrDefault("").get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + private static ResourceArgs makeArgs(@Nullable CustomResourcePatchArgsBase args) { + if (args == null) { + return null; + } + if (args.otherFields().isEmpty() || args.otherFields().get().isEmpty()) { + // optimization: if there are no "other" fields, we can just use the args as-is. + // Otherwise we generate a subclass of ResourceArgs that includes the "other" fields. + return args; + } + return Util.generateResourceArgs(args, args.otherFields().get()); + } + + private static com.pulumi.resources.CustomResourceOptions makeResourceOptions( + @Nullable com.pulumi.resources.CustomResourceOptions options, @Nullable Output id) { + var defaultOptions = com.pulumi.resources.CustomResourceOptions.builder() + .version(Utilities.getVersion()) + .build(); + return com.pulumi.resources.CustomResourceOptions.merge(defaultOptions, options, id); + } +} diff --git a/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgs.java b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgs.java new file mode 100644 index 0000000000..51ed968a70 --- /dev/null +++ b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgs.java @@ -0,0 +1,34 @@ +// *** 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.apiextensions; + +/** + * The set of arguments for constructing a CustomResourcePatch resource. + * + * NOTE: This type is fairly loose, since other than `apiVersion` and `kind`, + * there are no fields required across all CRDs. Use otherFields(...) to specify + * additional fields. + */ +public final class CustomResourcePatchArgs extends CustomResourcePatchArgsBase { + + public static final CustomResourcePatchArgs Empty = new CustomResourcePatchArgs(); + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(CustomResourcePatchArgs defaults) { + return new Builder(defaults); + } + + public static final class Builder extends CustomResourcePatchArgsBase.Builder { + public Builder() { + super(new CustomResourcePatchArgs()); + } + + public Builder(CustomResourcePatchArgs defaults) { + super(new CustomResourcePatchArgs(), defaults); + } + } +} diff --git a/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgsBase.java b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgsBase.java new file mode 100644 index 0000000000..bdac6ddb53 --- /dev/null +++ b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgsBase.java @@ -0,0 +1,204 @@ +// *** 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.apiextensions; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import javax.annotation.Nullable; + +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Import; +import com.pulumi.core.internal.Codegen; +import com.pulumi.kubernetes.meta.v1.inputs.ObjectMetaPatchArgs; + +/** + * CustomResourcePatchArgsBase is the base class for a user-defined + * CustomResourcePatchArgs. + */ +public abstract class CustomResourcePatchArgsBase extends com.pulumi.resources.ResourceArgs { + + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + @Import(name="apiVersion") + @Nullable Output apiVersion; + + /** + * @return APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + public Optional> apiVersion() { + return Optional.ofNullable(this.apiVersion); + } + + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + @Import(name="kind") + @Nullable Output kind; + + /** + * @return Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + public Optional> kind() { + return Optional.ofNullable(this.kind); + } + + /** + * Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + @Import(name="metadata") + @Nullable Output metadata; + + /** + * @return Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + public Optional> metadata() { + return Optional.ofNullable(this.metadata); + } + + /** + * Untyped map that holds any user-defined fields. + * + */ + @Nullable Map> otherFields; + + /** + * @return Untyped map that holds any user-defined fields. + * + */ + public Optional>> otherFields() { + return Optional.ofNullable(this.otherFields); + } + + protected CustomResourcePatchArgsBase() { + } + + public static class Builder> { + protected T $; + + protected Builder(T $) { + this.$ = $; + } + + protected Builder(T $, T defaults) { + this($); + copy(Objects.requireNonNull(defaults)); + } + + protected void copy(T args) { + $.apiVersion = args.apiVersion; + $.kind = args.kind; + $.metadata = args.metadata; + $.otherFields = args.otherFields; + } + + /** + * @param apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + * @return builder + * + */ + public U apiVersion(@Nullable Output apiVersion) { + $.apiVersion = apiVersion; + return (U) this; + } + + /** + * @param apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + * @return builder + * + */ + public U apiVersion(String apiVersion) { + return apiVersion(Output.of(apiVersion)); + } + + /** + * @param kind Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + * @return builder + * + */ + public U kind(@Nullable Output kind) { + $.kind = kind; + return (U) this; + } + + /** + * @param kind Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + * @return builder + * + */ + public U kind(String kind) { + return kind(Output.of(kind)); + } + + /** + * @param metadata Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + * @return builder + * + */ + public U metadata(@Nullable Output metadata) { + $.metadata = metadata; + return (U) this; + } + + /** + * @param metadata Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + * @return builder + * + */ + public U metadata(ObjectMetaPatchArgs metadata) { + return metadata(Output.of(metadata)); + } + + /** + * @param fields Untyped map that holds any user-defined fields (which may be Output values). + * + * @return builder + * + */ + public U otherFields(Map fields) { + var map = $.otherFields != null ? new LinkedHashMap($.otherFields) : new LinkedHashMap(); + for (var entry : fields.entrySet()) { + var value = entry.getValue(); + map.put(entry.getKey(), (value instanceof Output) ? (Output) value : Output.of(value)); + } + $.otherFields = map; + return (U) this; + } + + /** + * @param field The user-defined field name. + * @param value The field value, which may be an Output value. + * @return builder + * + */ + public U otherField(String field, Object value) { + var map = $.otherFields != null ? new LinkedHashMap($.otherFields) : new LinkedHashMap(); + map.put(field, value instanceof Output ? value : Output.of(value)); + $.otherFields = map; + return (U) this; + } + + public T build() { + $.apiVersion = Codegen.stringProp("apiVersion").output().arg($.apiVersion).getNullable(); + $.kind = Codegen.stringProp("kind").output().arg($.kind).getNullable(); + return (T) $; + } + } + +} diff --git a/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/Util.java b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/Util.java new file mode 100644 index 0000000000..9a9491fbfb --- /dev/null +++ b/provider/pkg/gen/java-templates/src/main/java/com/pulumi/kubernetes/apiextensions/Util.java @@ -0,0 +1,99 @@ +// *** 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.apiextensions; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.pulumi.core.Either; +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Import; +import com.pulumi.core.internal.annotations.ImportMetadata; +import com.pulumi.resources.ResourceArgs; + +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.description.annotation.AnnotationDescription; +import net.bytebuddy.implementation.FieldAccessor; +import net.bytebuddy.implementation.Implementation; +import net.bytebuddy.implementation.MethodCall; + +class Util { + private Util() { + } + + /** + * Generates a ResourceArgs containing the union of inputs in 'args' and 'others'. + * + * @param args a ResourceArgs containing fields with @Import annotations. + * @param others a map of additional inputs to include in the generated ResourceArgs. + * @return + */ + public static ResourceArgs generateResourceArgs(ResourceArgs args, Map> others) { + // define a field for each Java field that has an @Import annotation, and copy the annotation. + var importFields = + ImportMetadata.of(args.getClass()).values().stream() + .map(info -> new ImportField(info.getFieldOutput(args), Either.ofLeft(info.getAnnotation()))); + // define a field for each input in 'others' map, with a simple @Import annotation. + var otherFields = + others.entrySet().stream() + .map(entry -> new ImportField(Optional.ofNullable(entry.getValue()), Either.ofRight( + AnnotationDescription.Builder.ofType(Import.class).define("name", entry.getKey()).build()))); + List fields = + Stream.concat(importFields, otherFields) + .collect(Collectors.toList()); + + try { + // define a dynamic subclass of ResourceArgs with a field for each input property + // and a constructor that takes the property values and assigns them to the fields. + var t = new ByteBuddy().subclass(ResourceArgs.class); + Implementation.Composable c = MethodCall.invoke(ResourceArgs.class.getConstructor()); + + var paramTypes = new ArrayList>(); + var paramValues = new ArrayList(); + + for (var arg : fields) { + // define a field of type Output with @Import(name="foo") + var fieldName = String.format("f%d", paramTypes.size()); + var f = t.defineField(fieldName, Output.class, Modifier.PUBLIC); + t = arg.importAnnotation.either(a -> f.annotateField(a), ad -> f.annotateField(ad)); + + // bind the field to the corresponding constructor parameter + c = c.andThen(FieldAccessor.ofField(fieldName).setsArgumentAt(paramTypes.size())); + + paramTypes.add(Output.class); + paramValues.add(arg.value.map(v -> v instanceof Output ? v : Output.ofNullable(v)).orElse(null)); + } + + return (ResourceArgs) t + .defineConstructor(Modifier.PUBLIC).withParameters(paramTypes).intercept(c) + .make() + .load(Util.class.getClassLoader()) + .getLoaded().getConstructors()[0] + .newInstance(paramValues.toArray()); + + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException + | InvocationTargetException e) { + throw new RuntimeException("Unable to generate ResourceArgs", e); + } + } + + private static class ImportField { + public Optional value; + public Either importAnnotation; + + public ImportField(Optional value, Either importAnnotation) { + this.value = value; + this.importAnnotation = importAnnotation; + } + } +} diff --git a/provider/pkg/gen/schema.go b/provider/pkg/gen/schema.go index a7beb8f54e..1aa658d5f8 100644 --- a/provider/pkg/gen/schema.go +++ b/provider/pkg/gen/schema.go @@ -481,6 +481,10 @@ additional information about using Server-Side Apply to manage Kubernetes resour pkg.Language["java"] = rawMessage(map[string]any{ "packages": javaPackages, + "dependencies": map[string]string{ + "net.bytebuddy:byte-buddy": "1.14.15", + "com.google.guava:guava": "32.1.2-jre", + }, }) pkg.Language["go"] = rawMessage(map[string]any{ diff --git a/sdk/java/build.gradle b/sdk/java/build.gradle index b02b9401d1..98043252e8 100644 --- a/sdk/java/build.gradle +++ b/sdk/java/build.gradle @@ -44,7 +44,9 @@ repositories { dependencies { implementation("com.google.code.findbugs:jsr305:3.0.2") implementation("com.google.code.gson:gson:2.8.9") + implementation("com.google.guava:guava:32.1.2-jre") implementation("com.pulumi:pulumi:0.12.0") + implementation("net.bytebuddy:byte-buddy:1.14.15") } task sourcesJar(type: Jar) { diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResource.java b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResource.java new file mode 100644 index 0000000000..573ec88ed4 --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResource.java @@ -0,0 +1,155 @@ +// *** 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.apiextensions; + +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import javax.annotation.Nullable; + +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.core.internal.Internal; +import com.pulumi.core.internal.OutputInternal; +import com.pulumi.kubernetes.Utilities; +import com.pulumi.kubernetes.meta.v1.outputs.ObjectMeta; +import com.pulumi.resources.ResourceArgs; + +/** + * CustomResource represents an instance of a CustomResourceDefinition (CRD). For example, the + * CoreOS Prometheus operator exposes a CRD `monitoring.coreos.com/ServiceMonitor`; to + * instantiate this as a Pulumi resource, one could call `new CustomResource`, passing the + * `ServiceMonitor` resource definition as an argument. + */ +@ResourceType(type="kubernetes:apiextensions:CustomResource") +public class CustomResource extends com.pulumi.resources.CustomResource { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + @Export(name="apiVersion", refs={String.class}, tree="[0]") + private Output apiVersion; + + /** + * @return APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + public Output apiVersion() { + return this.apiVersion; + } + + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + @Export(name="kind", refs={String.class}, tree="[0]") + private Output kind; + + /** + * @return Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + public Output kind() { + return this.kind; + } + + /** + * Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + @Export(name="metadata", refs={ObjectMeta.class}, tree="[0]") + private Output metadata; + + /** + * @return Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + public Output metadata() { + return this.metadata; + } + + /** + * + * @param name The _unique_ name of the resulting resource. + */ + public CustomResource(String name) { + this(name, CustomResourceArgs.Empty); + } + + /** + * + * @param name The _unique_ name of the resulting resource. + * @param args The arguments to use to populate this resource's properties. + */ + public CustomResource(String name, @Nullable CustomResourceArgsBase 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 CustomResource(String name, @Nullable CustomResourceArgsBase args, @Nullable com.pulumi.resources.CustomResourceOptions options) { + super(makeType(args), name, makeArgs(args), makeResourceOptions(options, Codegen.empty())); + } + + protected CustomResource(String name, String apiVersion, String kind, Output id, + @Nullable com.pulumi.resources.CustomResourceOptions options) { + super(String.format("kubernetes:%s:%s", apiVersion, kind), name, null, makeResourceOptions(options, id)); + } + + private static String makeType(@Nullable CustomResourceArgsBase args) { + String apiVersion = args.apiVersion().map(Internal::of).map(CustomResource::getOutputValue).orElse(""); + String kind = args.kind().map(Internal::of).map(CustomResource::getOutputValue).orElse(""); + return String.format("kubernetes:%s:%s", apiVersion, kind); + } + + private static String getOutputValue(OutputInternal o) { + try { + return o.getValueOrDefault("").get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + private static ResourceArgs makeArgs(@Nullable CustomResourceArgsBase args) { + if (args == null) { + return null; + } + if (args.otherFields().isEmpty() || args.otherFields().get().isEmpty()) { + // optimization: if there are no "other" fields, we can just return the args as-is. + // Otherwise we generate a subclass of ResourceArgs that includes the "other" fields. + return args; + } + return Util.generateResourceArgs(args, args.otherFields().get()); + } + + private static com.pulumi.resources.CustomResourceOptions makeResourceOptions( + @Nullable com.pulumi.resources.CustomResourceOptions options, @Nullable Output id) { + var defaultOptions = com.pulumi.resources.CustomResourceOptions.builder() + .version(Utilities.getVersion()) + .build(); + return com.pulumi.resources.CustomResourceOptions.merge(defaultOptions, options, id); + } + + /** + * Get the state of an existing `CustomResource` resource, as identified by `id`. + * Typically this ID is of the form [namespace]/[name]; if [namespace] is omitted, + * then (per Kubernetes convention) the ID becomes default/[name]. + * + * @param name The _unique_ name of the resulting resource. + * @param apiVersion The API version of the CustomResource we wish to select, as defined by the CRD. + * @param kind The kind of the CustomResource we wish to select, as defined by the CRD. + * @param id An ID for the Kubernetes resource to retrieve. + * @param options Optional settings to control the behavior of the CustomResource. + */ + public static CustomResource get(String name, String apiVersion, String kind, Output id, + @Nullable com.pulumi.resources.CustomResourceOptions options) { + return new CustomResource(name, apiVersion, kind, id, options); + } +} diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgs.java b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgs.java new file mode 100644 index 0000000000..b342836b16 --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgs.java @@ -0,0 +1,34 @@ +// *** 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.apiextensions; + +/** + * The set of arguments for constructing a CustomResource resource. + * + * NOTE: This type is fairly loose, since other than `apiVersion` and `kind`, + * there are no fields required across all CRDs. Use otherFields(...) to specify + * additional fields. + */ +public final class CustomResourceArgs extends CustomResourceArgsBase { + + public static final CustomResourceArgs Empty = new CustomResourceArgs(); + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(CustomResourceArgs defaults) { + return new Builder(defaults); + } + + public static final class Builder extends CustomResourceArgsBase.Builder { + public Builder() { + super(new CustomResourceArgs()); + } + + public Builder(CustomResourceArgs defaults) { + super(new CustomResourceArgs(), defaults); + } + } +} diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgsBase.java b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgsBase.java new file mode 100644 index 0000000000..81d901788c --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourceArgsBase.java @@ -0,0 +1,204 @@ +// *** 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.apiextensions; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import javax.annotation.Nullable; + +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Import; +import com.pulumi.core.internal.Codegen; +import com.pulumi.kubernetes.meta.v1.inputs.ObjectMetaArgs; + +/** + * CustomResourceArgsBase is the base class for a user-defined + * CustomResourceArgs. + */ +public abstract class CustomResourceArgsBase extends com.pulumi.resources.ResourceArgs { + + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + @Import(name="apiVersion") + @Nullable Output apiVersion; + + /** + * @return APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + public Optional> apiVersion() { + return Optional.ofNullable(this.apiVersion); + } + + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + @Import(name="kind") + @Nullable Output kind; + + /** + * @return Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + public Optional> kind() { + return Optional.ofNullable(this.kind); + } + + /** + * Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + @Import(name="metadata") + @Nullable Output metadata; + + /** + * @return Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + public Optional> metadata() { + return Optional.ofNullable(this.metadata); + } + + /** + * Untyped map that holds any user-defined fields. + * + */ + @Nullable Map> otherFields; + + /** + * @return Untyped map that holds any user-defined fields. + * + */ + public Optional>> otherFields() { + return Optional.ofNullable(this.otherFields); + } + + protected CustomResourceArgsBase() { + } + + public static class Builder> { + protected T $; + + protected Builder(T $) { + this.$ = $; + } + + protected Builder(T $, T defaults) { + this($); + copy(Objects.requireNonNull(defaults)); + } + + protected void copy(T args) { + $.apiVersion = args.apiVersion; + $.kind = args.kind; + $.metadata = args.metadata; + $.otherFields = args.otherFields; + } + + /** + * @param apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + * @return builder + * + */ + public U apiVersion(@Nullable Output apiVersion) { + $.apiVersion = apiVersion; + return (U) this; + } + + /** + * @param apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + * @return builder + * + */ + public U apiVersion(String apiVersion) { + return apiVersion(Output.of(apiVersion)); + } + + /** + * @param kind Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + * @return builder + * + */ + public U kind(@Nullable Output kind) { + $.kind = kind; + return (U) this; + } + + /** + * @param kind Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + * @return builder + * + */ + public U kind(String kind) { + return kind(Output.of(kind)); + } + + /** + * @param metadata Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + * @return builder + * + */ + public U metadata(@Nullable Output metadata) { + $.metadata = metadata; + return (U) this; + } + + /** + * @param metadata Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + * @return builder + * + */ + public U metadata(ObjectMetaArgs metadata) { + return metadata(Output.of(metadata)); + } + + /** + * @param fields Untyped map that holds any user-defined fields (which may be Output values). + * + * @return builder + * + */ + public U otherFields(Map fields) { + var map = $.otherFields != null ? new LinkedHashMap($.otherFields) : new LinkedHashMap(); + for (var entry : fields.entrySet()) { + var value = entry.getValue(); + map.put(entry.getKey(), (value instanceof Output) ? (Output) value : Output.of(value)); + } + $.otherFields = map; + return (U) this; + } + + /** + * @param field The user-defined field name. + * @param value The field value, which may be an Output value. + * @return builder + * + */ + public U otherField(String field, Object value) { + var map = $.otherFields != null ? new LinkedHashMap($.otherFields) : new LinkedHashMap(); + map.put(field, value instanceof Output ? value : Output.of(value)); + $.otherFields = map; + return (U) this; + } + + public T build() { + $.apiVersion = Codegen.stringProp("apiVersion").output().arg($.apiVersion).getNullable(); + $.kind = Codegen.stringProp("kind").output().arg($.kind).getNullable(); + return (T) $; + } + } + +} diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatch.java b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatch.java new file mode 100644 index 0000000000..c8ae3ea09b --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatch.java @@ -0,0 +1,140 @@ +// *** 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.apiextensions; + +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import javax.annotation.Nullable; + +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.core.internal.Internal; +import com.pulumi.core.internal.OutputInternal; +import com.pulumi.kubernetes.Utilities; +import com.pulumi.kubernetes.meta.v1.outputs.ObjectMetaPatch; +import com.pulumi.resources.ResourceArgs; + +/** + * Patch resources are used to modify existing Kubernetes resources by using + * Server-Side Apply updates. The name of the resource must be specified, but all other properties are optional. More than + * one patch may be applied to the same resource, and a random FieldManager name will be used for each Patch resource. + * Conflicts will result in an error by default, but can be forced using the "pulumi.com/patchForce" annotation. See the + * [Server-Side Apply Docs](https://www.pulumi.com/registry/packages/kubernetes/how-to-guides/managing-resources-with-server-side-apply/) for + * additional information about using Server-Side Apply to manage Kubernetes resources with Pulumi. + * + * CustomResourcePatch represents an instance of a CustomResourceDefinition (CRD). For example, the + * CoreOS Prometheus operator exposes a CRD `monitoring.coreos.com/ServiceMonitor`; to + * instantiate this as a Pulumi resource, one could call `new CustomResourcePatch`, passing the + * `ServiceMonitor` resource definition as an argument. + */ +@ResourceType(type="kubernetes:apiextensions:CustomResourcePatch") +public class CustomResourcePatch extends com.pulumi.resources.CustomResource { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + @Export(name="apiVersion", refs={String.class}, tree="[0]") + private Output apiVersion; + + /** + * @return APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + public Output> apiVersion() { + return Codegen.optional(this.apiVersion); + } + + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + @Export(name="kind", refs={String.class}, tree="[0]") + private Output kind; + + /** + * @return Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + public Output> kind() { + return Codegen.optional(this.kind); + } + /** + * Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + @Export(name="metadata", refs={ObjectMetaPatch.class}, tree="[0]") + private Output metadata; + + /** + * @return Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + public Output> metadata() { + return Codegen.optional(this.metadata); + } + + /** + * + * @param name The _unique_ name of the resulting resource. + */ + public CustomResourcePatch(String name) { + this(name, CustomResourcePatchArgs.Empty); + } + + /** + * + * @param name The _unique_ name of the resulting resource. + * @param args The arguments to use to populate this resource's properties. + */ + public CustomResourcePatch(String name, @Nullable CustomResourcePatchArgsBase 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 CustomResourcePatch(String name, @Nullable CustomResourcePatchArgsBase args, @Nullable com.pulumi.resources.CustomResourceOptions options) { + super(makeType(args), name, makeArgs(args), makeResourceOptions(options, Codegen.empty())); + } + + private static String makeType(@Nullable CustomResourcePatchArgsBase args) { + String apiVersion = args.apiVersion().map(Internal::of).map(CustomResourcePatch::getOutputValue).orElse(""); + String kind = args.kind().map(Internal::of).map(CustomResourcePatch::getOutputValue).orElse(""); + return String.format("kubernetes:%s:%sPatch", apiVersion, kind); + } + + private static String getOutputValue(OutputInternal o) { + try { + return o.getValueOrDefault("").get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + private static ResourceArgs makeArgs(@Nullable CustomResourcePatchArgsBase args) { + if (args == null) { + return null; + } + if (args.otherFields().isEmpty() || args.otherFields().get().isEmpty()) { + // optimization: if there are no "other" fields, we can just use the args as-is. + // Otherwise we generate a subclass of ResourceArgs that includes the "other" fields. + return args; + } + return Util.generateResourceArgs(args, args.otherFields().get()); + } + + private static com.pulumi.resources.CustomResourceOptions makeResourceOptions( + @Nullable com.pulumi.resources.CustomResourceOptions options, @Nullable Output id) { + var defaultOptions = com.pulumi.resources.CustomResourceOptions.builder() + .version(Utilities.getVersion()) + .build(); + return com.pulumi.resources.CustomResourceOptions.merge(defaultOptions, options, id); + } +} diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgs.java b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgs.java new file mode 100644 index 0000000000..51ed968a70 --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgs.java @@ -0,0 +1,34 @@ +// *** 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.apiextensions; + +/** + * The set of arguments for constructing a CustomResourcePatch resource. + * + * NOTE: This type is fairly loose, since other than `apiVersion` and `kind`, + * there are no fields required across all CRDs. Use otherFields(...) to specify + * additional fields. + */ +public final class CustomResourcePatchArgs extends CustomResourcePatchArgsBase { + + public static final CustomResourcePatchArgs Empty = new CustomResourcePatchArgs(); + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(CustomResourcePatchArgs defaults) { + return new Builder(defaults); + } + + public static final class Builder extends CustomResourcePatchArgsBase.Builder { + public Builder() { + super(new CustomResourcePatchArgs()); + } + + public Builder(CustomResourcePatchArgs defaults) { + super(new CustomResourcePatchArgs(), defaults); + } + } +} diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgsBase.java b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgsBase.java new file mode 100644 index 0000000000..bdac6ddb53 --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/CustomResourcePatchArgsBase.java @@ -0,0 +1,204 @@ +// *** 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.apiextensions; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import javax.annotation.Nullable; + +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Import; +import com.pulumi.core.internal.Codegen; +import com.pulumi.kubernetes.meta.v1.inputs.ObjectMetaPatchArgs; + +/** + * CustomResourcePatchArgsBase is the base class for a user-defined + * CustomResourcePatchArgs. + */ +public abstract class CustomResourcePatchArgsBase extends com.pulumi.resources.ResourceArgs { + + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + @Import(name="apiVersion") + @Nullable Output apiVersion; + + /** + * @return APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + */ + public Optional> apiVersion() { + return Optional.ofNullable(this.apiVersion); + } + + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + @Import(name="kind") + @Nullable Output kind; + + /** + * @return Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + */ + public Optional> kind() { + return Optional.ofNullable(this.kind); + } + + /** + * Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + @Import(name="metadata") + @Nullable Output metadata; + + /** + * @return Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + */ + public Optional> metadata() { + return Optional.ofNullable(this.metadata); + } + + /** + * Untyped map that holds any user-defined fields. + * + */ + @Nullable Map> otherFields; + + /** + * @return Untyped map that holds any user-defined fields. + * + */ + public Optional>> otherFields() { + return Optional.ofNullable(this.otherFields); + } + + protected CustomResourcePatchArgsBase() { + } + + public static class Builder> { + protected T $; + + protected Builder(T $) { + this.$ = $; + } + + protected Builder(T $, T defaults) { + this($); + copy(Objects.requireNonNull(defaults)); + } + + protected void copy(T args) { + $.apiVersion = args.apiVersion; + $.kind = args.kind; + $.metadata = args.metadata; + $.otherFields = args.otherFields; + } + + /** + * @param apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + * @return builder + * + */ + public U apiVersion(@Nullable Output apiVersion) { + $.apiVersion = apiVersion; + return (U) this; + } + + /** + * @param apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + * + * @return builder + * + */ + public U apiVersion(String apiVersion) { + return apiVersion(Output.of(apiVersion)); + } + + /** + * @param kind Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + * @return builder + * + */ + public U kind(@Nullable Output kind) { + $.kind = kind; + return (U) this; + } + + /** + * @param kind Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + * + * @return builder + * + */ + public U kind(String kind) { + return kind(Output.of(kind)); + } + + /** + * @param metadata Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + * @return builder + * + */ + public U metadata(@Nullable Output metadata) { + $.metadata = metadata; + return (U) this; + } + + /** + * @param metadata Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + * + * @return builder + * + */ + public U metadata(ObjectMetaPatchArgs metadata) { + return metadata(Output.of(metadata)); + } + + /** + * @param fields Untyped map that holds any user-defined fields (which may be Output values). + * + * @return builder + * + */ + public U otherFields(Map fields) { + var map = $.otherFields != null ? new LinkedHashMap($.otherFields) : new LinkedHashMap(); + for (var entry : fields.entrySet()) { + var value = entry.getValue(); + map.put(entry.getKey(), (value instanceof Output) ? (Output) value : Output.of(value)); + } + $.otherFields = map; + return (U) this; + } + + /** + * @param field The user-defined field name. + * @param value The field value, which may be an Output value. + * @return builder + * + */ + public U otherField(String field, Object value) { + var map = $.otherFields != null ? new LinkedHashMap($.otherFields) : new LinkedHashMap(); + map.put(field, value instanceof Output ? value : Output.of(value)); + $.otherFields = map; + return (U) this; + } + + public T build() { + $.apiVersion = Codegen.stringProp("apiVersion").output().arg($.apiVersion).getNullable(); + $.kind = Codegen.stringProp("kind").output().arg($.kind).getNullable(); + return (T) $; + } + } + +} diff --git a/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/Util.java b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/Util.java new file mode 100644 index 0000000000..9a9491fbfb --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/kubernetes/apiextensions/Util.java @@ -0,0 +1,99 @@ +// *** 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.apiextensions; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.pulumi.core.Either; +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Import; +import com.pulumi.core.internal.annotations.ImportMetadata; +import com.pulumi.resources.ResourceArgs; + +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.description.annotation.AnnotationDescription; +import net.bytebuddy.implementation.FieldAccessor; +import net.bytebuddy.implementation.Implementation; +import net.bytebuddy.implementation.MethodCall; + +class Util { + private Util() { + } + + /** + * Generates a ResourceArgs containing the union of inputs in 'args' and 'others'. + * + * @param args a ResourceArgs containing fields with @Import annotations. + * @param others a map of additional inputs to include in the generated ResourceArgs. + * @return + */ + public static ResourceArgs generateResourceArgs(ResourceArgs args, Map> others) { + // define a field for each Java field that has an @Import annotation, and copy the annotation. + var importFields = + ImportMetadata.of(args.getClass()).values().stream() + .map(info -> new ImportField(info.getFieldOutput(args), Either.ofLeft(info.getAnnotation()))); + // define a field for each input in 'others' map, with a simple @Import annotation. + var otherFields = + others.entrySet().stream() + .map(entry -> new ImportField(Optional.ofNullable(entry.getValue()), Either.ofRight( + AnnotationDescription.Builder.ofType(Import.class).define("name", entry.getKey()).build()))); + List fields = + Stream.concat(importFields, otherFields) + .collect(Collectors.toList()); + + try { + // define a dynamic subclass of ResourceArgs with a field for each input property + // and a constructor that takes the property values and assigns them to the fields. + var t = new ByteBuddy().subclass(ResourceArgs.class); + Implementation.Composable c = MethodCall.invoke(ResourceArgs.class.getConstructor()); + + var paramTypes = new ArrayList>(); + var paramValues = new ArrayList(); + + for (var arg : fields) { + // define a field of type Output with @Import(name="foo") + var fieldName = String.format("f%d", paramTypes.size()); + var f = t.defineField(fieldName, Output.class, Modifier.PUBLIC); + t = arg.importAnnotation.either(a -> f.annotateField(a), ad -> f.annotateField(ad)); + + // bind the field to the corresponding constructor parameter + c = c.andThen(FieldAccessor.ofField(fieldName).setsArgumentAt(paramTypes.size())); + + paramTypes.add(Output.class); + paramValues.add(arg.value.map(v -> v instanceof Output ? v : Output.ofNullable(v)).orElse(null)); + } + + return (ResourceArgs) t + .defineConstructor(Modifier.PUBLIC).withParameters(paramTypes).intercept(c) + .make() + .load(Util.class.getClassLoader()) + .getLoaded().getConstructors()[0] + .newInstance(paramValues.toArray()); + + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException + | InvocationTargetException e) { + throw new RuntimeException("Unable to generate ResourceArgs", e); + } + } + + private static class ImportField { + public Optional value; + public Either importAnnotation; + + public ImportField(Optional value, Either importAnnotation) { + this.value = value; + this.importAnnotation = importAnnotation; + } + } +}