From af97f8f1b47c35b366964e37c52c28244c12344d Mon Sep 17 00:00:00 2001 From: Alex Clemmer Date: Wed, 19 Dec 2018 19:12:36 -0800 Subject: [PATCH] Add `apiextensions.CustomResource#get` Fixes #323. --- pkg/gen/nodejs-templates/provider.ts.mustache | 60 ++++++++++++++++++- sdk/nodejs/provider.ts | 60 ++++++++++++++++++- tests/integration/get/get_test.go | 26 +++++--- tests/integration/get/step1/index.ts | 38 +++++++++++- 4 files changed, 172 insertions(+), 12 deletions(-) diff --git a/pkg/gen/nodejs-templates/provider.ts.mustache b/pkg/gen/nodejs-templates/provider.ts.mustache index a59f038079..ef2895b183 100644 --- a/pkg/gen/nodejs-templates/provider.ts.mustache +++ b/pkg/gen/nodejs-templates/provider.ts.mustache @@ -290,12 +290,54 @@ export namespace apiextensions { * fields required across all CRDs. */ export interface CustomResourceArgs { - apiVersion: pulumi.Input, - kind: pulumi.Input + /** + * 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/api-conventions.md#resources + */ + apiVersion: pulumi.Input; + + /** + * 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/api-conventions.md#types-kinds + */ + kind: pulumi.Input; + + /** + * Standard object metadata; More info: + * https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata. + */ metadata?: pulumi.Input; [othersFields: string]: pulumi.Input; } + /** + * CustomResourceGetOptions uniquely identifies a Kubernetes CustomResource, primarily for use + * in supplied to `apiextensions.CustomResource#get`. + */ + export interface CustomResourceGetOptions { + /** + * apiVersion is the API version of the apiExtensions.CustomResource we wish to select, + * as specified by the CustomResourceDefinition that defines it on the API server. + */ + apiVersion: pulumi.Input; + + /** + * kind is the kind of the apiextensions.CustomResource we wish to select, as specified by + * the CustomResourceDefinition that defines it on the API server. + */ + kind: pulumi.Input + + /** + * An ID for the Kubernetes resource to retrive. Takes the form / or + * . + */ + id: pulumi.Input; + } + /** * CustomResource represents an instance of a CustomResourceDefinition (CRD). For example, the * CoreOS Prometheus operator exposes a CRD `monitoring.coreos.com/ServiceMonitor`; to @@ -325,6 +367,20 @@ export namespace apiextensions { */ public readonly metadata: pulumi.Output; + /** + * Get the state of an existing `CustomResource`, as identified by `id`. + * Typically this ID is of the form /; if is omitted, then (per + * Kubernetes convention) the ID becomes default/. + * + * Pulumi will keep track of this resource using `name` as the Pulumi ID. + * + * @param name _Unique_ name used to register this resource with Pulumi. + * @param opts Uniquely specifies a CustomResource to select. + */ + public static get(name: string, opts: CustomResourceGetOptions): CustomResource { + return new CustomResource(name, {apiVersion: opts.apiVersion, kind: opts.kind}, { id: opts.id }); + } + public getInputs(): CustomResourceArgs { return this.__inputs; } private readonly __inputs: CustomResourceArgs; diff --git a/sdk/nodejs/provider.ts b/sdk/nodejs/provider.ts index 8946231efd..0897bc2802 100755 --- a/sdk/nodejs/provider.ts +++ b/sdk/nodejs/provider.ts @@ -3306,12 +3306,54 @@ export namespace apiextensions { * fields required across all CRDs. */ export interface CustomResourceArgs { - apiVersion: pulumi.Input, - kind: pulumi.Input + /** + * 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/api-conventions.md#resources + */ + apiVersion: pulumi.Input; + + /** + * 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/api-conventions.md#types-kinds + */ + kind: pulumi.Input; + + /** + * Standard object metadata; More info: + * https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata. + */ metadata?: pulumi.Input; [othersFields: string]: pulumi.Input; } + /** + * CustomResourceGetOptions uniquely identifies a Kubernetes CustomResource, primarily for use + * in supplied to `apiextensions.CustomResource#get`. + */ + export interface CustomResourceGetOptions { + /** + * apiVersion is the API version of the apiExtensions.CustomResource we wish to select, + * as specified by the CustomResourceDefinition that defines it on the API server. + */ + apiVersion: pulumi.Input; + + /** + * kind is the kind of the apiextensions.CustomResource we wish to select, as specified by + * the CustomResourceDefinition that defines it on the API server. + */ + kind: pulumi.Input + + /** + * An ID for the Kubernetes resource to retrive. Takes the form / or + * . + */ + id: pulumi.Input; + } + /** * CustomResource represents an instance of a CustomResourceDefinition (CRD). For example, the * CoreOS Prometheus operator exposes a CRD `monitoring.coreos.com/ServiceMonitor`; to @@ -3341,6 +3383,20 @@ export namespace apiextensions { */ public readonly metadata: pulumi.Output; + /** + * Get the state of an existing `CustomResource`, as identified by `id`. + * Typically this ID is of the form /; if is omitted, then (per + * Kubernetes convention) the ID becomes default/. + * + * Pulumi will keep track of this resource using `name` as the Pulumi ID. + * + * @param name _Unique_ name used to register this resource with Pulumi. + * @param opts Uniquely specifies a CustomResource to select. + */ + public static get(name: string, opts: CustomResourceGetOptions): CustomResource { + return new CustomResource(name, {apiVersion: opts.apiVersion, kind: opts.kind}, { id: opts.id }); + } + public getInputs(): CustomResourceArgs { return this.__inputs; } private readonly __inputs: CustomResourceArgs; diff --git a/tests/integration/get/get_test.go b/tests/integration/get/get_test.go index 04fc36bc6c..1e7e6de039 100644 --- a/tests/integration/get/get_test.go +++ b/tests/integration/get/get_test.go @@ -14,8 +14,6 @@ import ( "github.com/stretchr/testify/assert" ) -var step1Name interface{} - func TestGet(t *testing.T) { kubectx := os.Getenv("KUBERNETES_CONTEXT") @@ -29,24 +27,38 @@ func TestGet(t *testing.T) { Quick: true, ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) { assert.NotNil(t, stackInfo.Deployment) - assert.Equal(t, 3, len(stackInfo.Deployment.Resources)) + assert.Equal(t, 6, len(stackInfo.Deployment.Resources)) tests.SortResourcesByURN(stackInfo) - stackRes := stackInfo.Deployment.Resources[2] + stackRes := stackInfo.Deployment.Resources[5] assert.Equal(t, resource.RootStackType, stackRes.URN.Type()) - provRes := stackInfo.Deployment.Resources[1] + provRes := stackInfo.Deployment.Resources[4] assert.True(t, providers.IsProviderType(provRes.URN.Type())) // // Assert we can use .get to retrieve the Kubernetes dashboard Service. // - pod := stackInfo.Deployment.Resources[0] + pod := stackInfo.Deployment.Resources[1] assert.Equal(t, "kube-dashboard", string(pod.URN.Name())) - step1Name, _ = openapi.Pluck(pod.Outputs, "metadata", "name") + step1Name, _ := openapi.Pluck(pod.Outputs, "metadata", "name") assert.Equal(t, "kubernetes", step1Name.(string)) + + // + // Assert we can use .get to retrieve CRDs. + // + + crd := stackInfo.Deployment.Resources[0] + assert.Equal(t, "crontab", string(crd.URN.Name())) + + ct1 := stackInfo.Deployment.Resources[2] + assert.Equal(t, "my-new-cron-object", string(ct1.URN.Name())) + + ct2 := stackInfo.Deployment.Resources[3] + assert.Equal(t, "my-new-cron-object-get", string(ct2.URN.Name())) + }, }) } diff --git a/tests/integration/get/step1/index.ts b/tests/integration/get/step1/index.ts index 229f45c042..142dd4eb39 100644 --- a/tests/integration/get/step1/index.ts +++ b/tests/integration/get/step1/index.ts @@ -6,4 +6,40 @@ import * as k8s from "@pulumi/kubernetes"; // `get`s the Kubernetes Dashboard, which is deployed by default in minikube. // -const dashboard = k8s.core.v1.Service.get("kube-dashboard", "kubernetes"); +k8s.core.v1.Service.get("kube-dashboard", "kubernetes"); + +// +// Create a CustomResourceDefinition, a CustomResource, and then `.get` it. +// + +const ct = new k8s.apiextensions.v1beta1.CustomResourceDefinition("crontab", { + metadata: { name: "crontabs.stable.example.com" }, + spec: { + group: "stable.example.com", + version: "v1", + scope: "Namespaced", + names: { + plural: "crontabs", + singular: "crontab", + kind: "CronTab", + shortNames: ["ct"] + } + } +}); + +new k8s.apiextensions.CustomResource( + "my-new-cron-object", + { + apiVersion: "stable.example.com/v1", + kind: "CronTab", + metadata: { name: "my-new-cron-object" }, + spec: { cronSpec: "* * * * */5", image: "my-awesome-cron-image" } + }, + { dependsOn: ct } +); + +const ctObj = k8s.apiextensions.CustomResource.get("my-new-cron-object-get", { + apiVersion: "stable.example.com/v1", + kind: "CronTab", + id: "my-new-cron-object" +});