From d4198b26cfdd03453a355652f2ce4eed215d3628 Mon Sep 17 00:00:00 2001 From: Tim <32556895+Avarei@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:13:04 +0200 Subject: [PATCH] add CompositeResourceDefinition.pkl as helper make getExtraResources return Listing instead of Listing --- Makefile | 2 +- example/inline/composition.yaml | 6 +- pkl/crossplane/CompositionRequest.pkl | 5 +- pkl/crossplane/PklProject | 5 +- .../crds/CompositeResourceDefinition.pkl | 397 ++++++++++++++++++ 5 files changed, 408 insertions(+), 7 deletions(-) create mode 100644 pkl/crossplane/crds/CompositeResourceDefinition.pkl diff --git a/Makefile b/Makefile index 28c2968..ca9709a 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ BRANCH := $(shell git branch --show-current) PKL_BASE_URI := package://pkg.pkl-lang.org PKL_CORE_NAME := crossplane -PKL_CORE_VERSION := 0.0.28 +PKL_CORE_VERSION := 0.0.29 PKL_CORE_REF := ${PKL_CORE_NAME}@${PKL_CORE_VERSION} PKL_CORE_URI := ${PKL_BASE_URI}/${REPO}/${PKL_CORE_REF} diff --git a/example/inline/composition.yaml b/example/inline/composition.yaml index 4ac774a..802f018 100644 --- a/example/inline/composition.yaml +++ b/example/inline/composition.yaml @@ -18,9 +18,9 @@ spec: type: inline # This pkl file is at `pkl/crossplane-example/full.pkl` in this repo inline: | - amends "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/crossplane@0.0.28#/CompositionResponse.pkl" - import "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/crossplane@0.0.28#/Resource.pkl" - import "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/crossplane@0.0.28#/Crossplane.pkl" + amends "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/crossplane@0.0.29#/CompositionResponse.pkl" + import "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/crossplane@0.0.29#/Resource.pkl" + import "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/crossplane@0.0.29#/Crossplane.pkl" import "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/crossplane-example@0.1.18#/crds/XR.pkl" import "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/crossplane-example@0.1.18#/crds/Object.pkl" diff --git a/pkl/crossplane/CompositionRequest.pkl b/pkl/crossplane/CompositionRequest.pkl index bc51766..4ed5593 100644 --- a/pkl/crossplane/CompositionRequest.pkl +++ b/pkl/crossplane/CompositionRequest.pkl @@ -54,8 +54,9 @@ class Resources { items: Listing } -function getExtraResources(name: String): Listing = - extraResources.getOrNull(name).ifNonNull((it: Resources) -> it.items) ?? new Listing {} +function getExtraResources(name: String): Listing = + let (listingWithNil = extraResources.getOrNull(name).ifNonNull((it: Resources) -> it.items) ?? new Listing {}) + listingWithNil.toList().filter((n) -> n != null).toListing() as Listing function getExtraResource(name: String, index: Int):Resource? = getExtraResources(name).toList().getOrNull(index) diff --git a/pkl/crossplane/PklProject b/pkl/crossplane/PklProject index c71a679..0fc6a08 100644 --- a/pkl/crossplane/PklProject +++ b/pkl/crossplane/PklProject @@ -22,7 +22,7 @@ package { authors { "Tim Geimer <32556895+Avarei@users.noreply.github.com>" } - version = "0.0.28" + version = "0.0.29" baseUri = "package://pkg.pkl-lang.org/github.com/avarei/function-pkl/\(name)" packageZipUrl = "https://github.com/Avarei/function-pkl/releases/download/\(name)@\(version)/\(name)@\(version).zip" sourceCode = "https://github.com/Avarei/function-pkl" @@ -38,4 +38,7 @@ dependencies { ["k8s.contrib"] { uri = "package://pkg.pkl-lang.org/pkl-pantry/k8s.contrib@1.0.1" } + ["openapiv3"] { + uri = "package://pkg.pkl-lang.org/pkl-pantry/org.openapis.v3@2.1.1" + } } diff --git a/pkl/crossplane/crds/CompositeResourceDefinition.pkl b/pkl/crossplane/crds/CompositeResourceDefinition.pkl new file mode 100644 index 0000000..f4b8e67 --- /dev/null +++ b/pkl/crossplane/crds/CompositeResourceDefinition.pkl @@ -0,0 +1,397 @@ +/// A CompositeResourceDefinition defines the schema for a new custom Kubernetes API. +/// +/// Read the Crossplane documentation for [more information about +/// CustomResourceDefinitions](https://docs.crossplane.io/latest/concepts/composite-resource-definitions). +/// +/// This module was generated from the CustomResourceDefinition at +/// . +module io.crossplane.apiextensions.v1.CompositeResourceDefinition + +extends "@k8s/K8sResource.pkl" + +import "@k8s/apimachinery/pkg/apis/meta/v1/ObjectMeta.pkl" +import "@openapiv3/Schema.pkl" as Openapiv3Schema + +fixed apiVersion: "apiextensions.crossplane.io/v1" + +fixed kind: "CompositeResourceDefinition" + +/// Standard object's metadata. +/// +/// More info: . +metadata: ObjectMeta? + +/// CompositeResourceDefinitionSpec specifies the desired state of the definition. +spec: Spec? + +/// CompositeResourceDefinitionStatus shows the observed state of the definition. +status: Status? + +/// CompositeResourceDefinitionSpec specifies the desired state of the definition. +class Spec { + /// ClaimNames specifies the names of an optional composite resource claim. When claim names are + /// specified Crossplane will create a namespaced 'composite resource claim' CRD that corresponds to + /// the defined composite resource. This composite resource claim acts as a namespaced proxy for the + /// composite resource; creating, updating, or deleting the claim will create, update, or delete a + /// corresponding composite resource. You may add claim names to an existing + /// CompositeResourceDefinition, but they cannot be changed or removed once they have been set. + claimNames: ClaimNames? + + /// ConnectionSecretKeys is the list of keys that will be exposed to the end user of the defined kind. + /// If the list is empty, all keys will be published. + connectionSecretKeys: Listing? + + /// Conversion defines all conversion settings for the defined Composite resource. + conversion: Conversion? + + /// DefaultCompositeDeletePolicy is the policy used when deleting the Composite that is associated with + /// the Claim if no policy has been specified. + /// + /// Default if undefined: `"Background"` + defaultCompositeDeletePolicy: ("Background"|"Foreground")? + + /// DefaultCompositionRef refers to the Composition resource that will be used in case no composition + /// selector is given. + defaultCompositionRef: DefaultCompositionRef? + + /// DefaultCompositionUpdatePolicy is the policy used when updating composites after a new Composition + /// Revision has been created if no policy has been specified on the composite. + /// + /// Default if undefined: `"Automatic"` + defaultCompositionUpdatePolicy: ("Automatic"|"Manual")? + + /// EnforcedCompositionRef refers to the Composition resource that will be used by all composite + /// instances whose schema is defined by this definition. + enforcedCompositionRef: EnforcedCompositionRef? + + /// Group specifies the API group of the defined composite resource. Composite resources are served + /// under `/apis//...`. Must match the name of the XRD (in the form `.`). + group: String + + /// Metadata specifies the desired metadata for the defined composite resource and claim CRD's. + metadata: Metadata? + + /// Names specifies the resource and kind names of the defined composite resource. + names: Names + + /// Versions is the list of all API versions of the defined composite resource. Version names are used + /// to compute the order in which served versions are listed in API discovery. If the version string is + /// "kube-like", it will sort above non "kube-like" version strings, which are ordered + /// lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major + /// version), then optionally the string "alpha" or "beta" and another number (the minor version). + /// These are sorted first by GA > beta > alpha (where GA is a version with no suffix such as beta or + /// alpha), and then by comparing major version, then minor version. An example sorted list of + /// versions: v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10. + versions: Listing +} + +/// ClaimNames specifies the names of an optional composite resource claim. When claim names are +/// specified Crossplane will create a namespaced 'composite resource claim' CRD that corresponds to the +/// defined composite resource. This composite resource claim acts as a namespaced proxy for the +/// composite resource; creating, updating, or deleting the claim will create, update, or delete a +/// corresponding composite resource. You may add claim names to an existing CompositeResourceDefinition, +/// but they cannot be changed or removed once they have been set. +class ClaimNames { + /// categories is a list of grouped resources this custom resource belongs to (e.g. 'all'). This is + /// published in API discovery documents, and used by clients to support invocations like `kubectl get + /// all`. + categories: Listing? + + /// kind is the serialized kind of the resource. It is normally CamelCase and singular. Custom resource + /// instances will use this value as the `kind` attribute in API calls. + kind: String + + /// listKind is the serialized kind of the list for this resource. Defaults to "`kind`List". + listKind: String? + + /// plural is the plural name of the resource to serve. The custom resources are served under + /// `/apis///.../`. Must match the name of the CustomResourceDefinition (in the + /// form `.`). Must be all lowercase. + plural: String + + /// shortNames are short names for the resource, exposed in API discovery documents, and used by + /// clients to support invocations like `kubectl get `. It must be all lowercase. + shortNames: Listing? + + /// singular is the singular name of the resource. It must be all lowercase. Defaults to lowercased + /// `kind`. + singular: String? +} + +/// Conversion defines all conversion settings for the defined Composite resource. +class Conversion { + /// strategy specifies how custom resources are converted between versions. Allowed values are: - + /// `"None"`: The converter only change the apiVersion and would not touch any other field in the + /// custom resource. - `"Webhook"`: API Server will call to an external webhook to do the conversion. + /// Additional information is needed for this option. This requires spec.preserveUnknownFields to be + /// false, and spec.conversion.webhook to be set. + strategy: String + + /// webhook describes how to call the conversion webhook. Required when `strategy` is set to + /// `"Webhook"`. + webhook: Webhook? +} + +/// webhook describes how to call the conversion webhook. Required when `strategy` is set to `"Webhook"`. +class Webhook { + /// clientConfig is the instructions for how to call the webhook if strategy is `Webhook`. + clientConfig: ClientConfig? + + /// conversionReviewVersions is an ordered list of preferred `ConversionReview` versions the Webhook + /// expects. The API server will use the first version in the list which it supports. If none of the + /// versions specified in this list are supported by API server, conversion will fail for the custom + /// resource. If a persisted Webhook configuration specifies allowed versions and does not include any + /// versions known to the API Server, calls to the webhook will fail. + conversionReviewVersions: Listing +} + +/// clientConfig is the instructions for how to call the webhook if strategy is `Webhook`. +class ClientConfig { + /// caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server + /// certificate. If unspecified, system trust roots on the apiserver are used. + caBundle: String? + + /// service is a reference to the service for this webhook. Either service or url must be specified. + /// + /// If the webhook is running within the cluster, then you should use `service`. + service: Service? + + /// url gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly + /// one of `url` or `service` must be specified. + /// + /// The `host` should not refer to a service running in the cluster; use the `service` field instead. + /// The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot + /// resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address. + /// + /// Please note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care + /// to run this webhook on all hosts which run an apiserver which might need to make calls to this + /// webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster. + /// + /// The scheme must be "https"; the URL must begin with "https://". + /// + /// A path is optional, and if present may be any string permissible in a URL. You may use the path to + /// pass an arbitrary string to the webhook, for example, a cluster identifier. + /// + /// Attempting to use a user or basic auth e.g. "user:password@" is not allowed. Fragments ("#...") and + /// query parameters ("?...") are not allowed, either. + url: String? +} + +/// service is a reference to the service for this webhook. Either service or url must be specified. +/// +/// If the webhook is running within the cluster, then you should use `service`. +class Service { + /// name is the name of the service. Required + name: String + + /// namespace is the namespace of the service. Required + namespace: String + + /// path is an optional URL path at which the webhook will be contacted. + path: String? + + /// port is an optional service port at which the webhook will be contacted. `port` should be a valid + /// port number (1-65535, inclusive). Defaults to 443 for backward compatibility. + port: Int? +} + +/// DefaultCompositionRef refers to the Composition resource that will be used in case no composition +/// selector is given. +class DefaultCompositionRef { + /// Name of the Composition. + name: String +} + +/// EnforcedCompositionRef refers to the Composition resource that will be used by all composite +/// instances whose schema is defined by this definition. +class EnforcedCompositionRef { + /// Name of the Composition. + name: String +} + +/// Metadata specifies the desired metadata for the defined composite resource and claim CRD's. +class Metadata { + /// Annotations is an unstructured key value map stored with a resource that may be set by external + /// tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when + /// modifying objects. More info: + /// https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations + annotations: Mapping? + + /// Map of string keys and values that can be used to organize and categorize (scope and select) + /// objects. May match selectors of replication controllers More info: + /// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels and services. These labels + /// are added to the composite resource and claim CRD's in addition to any labels defined by + /// `CompositionResourceDefinition` `metadata.labels`. + labels: Mapping? +} + +/// Names specifies the resource and kind names of the defined composite resource. +class Names { + /// categories is a list of grouped resources this custom resource belongs to (e.g. 'all'). This is + /// published in API discovery documents, and used by clients to support invocations like `kubectl get + /// all`. + categories: Listing? + + /// kind is the serialized kind of the resource. It is normally CamelCase and singular. Custom resource + /// instances will use this value as the `kind` attribute in API calls. + kind: String + + /// listKind is the serialized kind of the list for this resource. Defaults to "`kind`List". + listKind: String? + + /// plural is the plural name of the resource to serve. The custom resources are served under + /// `/apis///.../`. Must match the name of the CustomResourceDefinition (in the + /// form `.`). Must be all lowercase. + plural: String + + /// shortNames are short names for the resource, exposed in API discovery documents, and used by + /// clients to support invocations like `kubectl get `. It must be all lowercase. + shortNames: Listing? + + /// singular is the singular name of the resource. It must be all lowercase. Defaults to lowercased + /// `kind`. + singular: String? +} + +/// CompositeResourceDefinitionVersion describes a version of an XR. +class Version { + /// AdditionalPrinterColumns specifies additional columns returned in Table output. If no columns are + /// specified, a single column displaying the age of the custom resource is used. See the following + /// link for details: + /// https://kubernetes.io/docs/reference/using-api/api-concepts/#receiving-resources-as-tables + additionalPrinterColumns: Listing? + + /// The deprecated field specifies that this version is deprecated and should not be used. + deprecated: Boolean? + + /// DeprecationWarning specifies the message that should be shown to the user when using this version. + deprecationWarning: String(length <= 256)? + + /// Name of this version, e.g. “v1”, “v2beta1”, etc. Composite resources are served under this version + /// at `/apis///...` if `served` is true. + name: String + + /// Referenceable specifies that this version may be referenced by a Composition in order to configure + /// which resources an XR may be composed of. Exactly one version must be marked as referenceable; all + /// Compositions must target only the referenceable version. The referenceable version must be served. + /// It's mapped to the CRD's `spec.versions[*].storage` field. + referenceable: Boolean + + /// Schema describes the schema used for validation, pruning, and defaulting of this version of the + /// defined composite resource. Fields required by all composite resources will be injected into this + /// schema automatically, and will override equivalently named fields in this schema. Omitting this + /// schema results in a schema that contains only the fields required by all composite resources. + schema: Schema? + + /// Served specifies that this version should be served via REST APIs. + served: Boolean +} + +/// CustomResourceColumnDefinition specifies a column for server side printing. +class AdditionalPrinterColumn { + /// description is a human readable description of this column. + description: String? + + /// format is an optional OpenAPI type definition for this column. The 'name' format is applied to the + /// primary identifier column to assist in clients identifying column is the resource name. See + /// https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for details. + format: String? + + /// jsonPath is a simple JSON path (i.e. with array notation) which is evaluated against each custom + /// resource to produce the value for this column. + jsonPath: String + + /// name is a human readable name for the column. + name: String + + /// priority is an integer defining the relative importance of this column compared to others. Lower + /// numbers are considered higher priority. Columns that may be omitted in limited space scenarios + /// should be given a priority greater than 0. + priority: Int? + + /// type is an OpenAPI type definition for this column. See + /// https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for details. + type: String +} + +/// Schema describes the schema used for validation, pruning, and defaulting of this version of the +/// defined composite resource. Fields required by all composite resources will be injected into this +/// schema automatically, and will override equivalently named fields in this schema. Omitting this +/// schema results in a schema that contains only the fields required by all composite resources. +class Schema { + /// OpenAPIV3Schema is the OpenAPI v3 schema to use for validation and pruning. + openAPIV3Schema: Openapiv3Schema? +} + +/// CompositeResourceDefinitionStatus shows the observed state of the definition. +class Status { + /// Conditions of the resource. + conditions: Listing? + + /// Controllers represents the status of the controllers that power this composite resource definition. + controllers: Controllers? +} + +/// A Condition that may apply to a resource. +class Condition { + /// LastTransitionTime is the last time this condition transitioned from one status to another. + lastTransitionTime: String + + /// A Message containing details about this condition's last transition from one status to another, if + /// any. + message: String? + + /// ObservedGeneration represents the .metadata.generation that the condition was set based upon. For + /// instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration + /// is 9, the condition is out of date with respect to the current state of the instance. + observedGeneration: Int? + + /// A Reason for this condition's last transition from one status to another. + reason: String + + /// Status of this condition; is it currently True, False, or Unknown? + status: String + + /// Type of this condition. At most one of each condition type may apply to a resource at any point in + /// time. + type: String +} + +/// Controllers represents the status of the controllers that power this composite resource definition. +class Controllers { + /// The CompositeResourceClaimTypeRef is the type of composite resource claim that Crossplane is + /// currently reconciling for this definition. Its version will eventually become consistent with the + /// definition's referenceable version. Note that clients may interact with any served type; this is + /// simply the type that Crossplane interacts with. + compositeResourceClaimType: CompositeResourceClaimType? + + /// The CompositeResourceTypeRef is the type of composite resource that Crossplane is currently + /// reconciling for this definition. Its version will eventually become consistent with the + /// definition's referenceable version. Note that clients may interact with any served type; this is + /// simply the type that Crossplane interacts with. + compositeResourceType: CompositeResourceType? +} + +/// The CompositeResourceClaimTypeRef is the type of composite resource claim that Crossplane is +/// currently reconciling for this definition. Its version will eventually become consistent with the +/// definition's referenceable version. Note that clients may interact with any served type; this is +/// simply the type that Crossplane interacts with. +class CompositeResourceClaimType { + /// APIVersion of the type. + apiVersion: String + + /// Kind of the type. + kind: String +} + +/// The CompositeResourceTypeRef is the type of composite resource that Crossplane is currently +/// reconciling for this definition. Its version will eventually become consistent with the definition's +/// referenceable version. Note that clients may interact with any served type; this is simply the type +/// that Crossplane interacts with. +class CompositeResourceType { + /// APIVersion of the type. + apiVersion: String + + /// Kind of the type. + kind: String +}