From 286c98b4d593b04657bfc22eaa67684fd4455abf Mon Sep 17 00:00:00 2001 From: Erik Godding Boye Date: Sun, 1 Dec 2024 14:47:27 +0100 Subject: [PATCH] Introduce ClusterBundle API as a copy of Bundle Signed-off-by: Erik Godding Boye --- .../crd-trust-manager.io_clusterbundles.yaml | 429 +++++++++++++++++ .../crds/trust-manager.io_clusterbundles.yaml | 441 ++++++++++++++++++ pkg/api/doc.go | 19 + pkg/api/v1alpha1/doc.go | 19 + pkg/api/v1alpha1/register.go | 69 +++ pkg/api/v1alpha1/types_cluster_bundle.go | 268 +++++++++++ pkg/api/v1alpha1/zz_generated.deepcopy.go | 323 +++++++++++++ pkg/apis/trust/v1alpha1/doc.go | 1 + 8 files changed, 1569 insertions(+) create mode 100644 deploy/charts/trust-manager/templates/crd-trust-manager.io_clusterbundles.yaml create mode 100644 deploy/crds/trust-manager.io_clusterbundles.yaml create mode 100644 pkg/api/doc.go create mode 100644 pkg/api/v1alpha1/doc.go create mode 100644 pkg/api/v1alpha1/register.go create mode 100644 pkg/api/v1alpha1/types_cluster_bundle.go create mode 100644 pkg/api/v1alpha1/zz_generated.deepcopy.go diff --git a/deploy/charts/trust-manager/templates/crd-trust-manager.io_clusterbundles.yaml b/deploy/charts/trust-manager/templates/crd-trust-manager.io_clusterbundles.yaml new file mode 100644 index 00000000..10a04220 --- /dev/null +++ b/deploy/charts/trust-manager/templates/crd-trust-manager.io_clusterbundles.yaml @@ -0,0 +1,429 @@ +{{- if .Values.crds.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: "clusterbundles.trust-manager.io" + {{- if .Values.crds.keep }} + annotations: + helm.sh/resource-policy: keep + {{- end }} + labels: + {{- include "trust-manager.labels" . | nindent 4 }} +spec: + group: trust-manager.io + names: + kind: ClusterBundle + listKind: ClusterBundleList + plural: clusterbundles + singular: clusterbundle + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Bundle ConfigMap Target Key + jsonPath: .spec.target.configMap.key + name: ConfigMap Target + type: string + - description: Bundle Secret Target Key + jsonPath: .spec.target.secret.key + name: Secret Target + type: string + - description: Bundle has been synced + jsonPath: .status.conditions[?(@.type == "Synced")].status + name: Synced + type: string + - description: Reason Bundle has Synced status + jsonPath: .status.conditions[?(@.type == "Synced")].reason + name: Reason + type: string + - description: Timestamp Bundle was created + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + 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 + type: string + kind: + description: |- + 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 + type: string + metadata: + type: object + spec: + description: Desired state of the Bundle resource. + properties: + sources: + description: Sources is a set of references to data whose data will sync to the target. + items: + description: |- + BundleSource is the set of sources whose data will be appended and synced to + the BundleTarget in all Namespaces. + properties: + configMap: + description: |- + ConfigMap is a reference (by name) to a ConfigMap's `data` key(s), or to a + list of ConfigMap's `data` key(s) using label selector, in the trust Namespace. + properties: + includeAllKeys: + description: |- + IncludeAllKeys is a flag to include all keys in the object's `data` field to be used. False by default. + This field must not be true when `Key` is set. + type: boolean + key: + description: Key of the entry in the object's `data` field to be used. + minLength: 1 + type: string + name: + description: |- + Name is the name of the source object in the trust Namespace. + This field must be left empty when `selector` is set + minLength: 1 + type: string + selector: + description: |- + Selector is the label selector to use to fetch a list of objects. Must not be set + when `Name` is set. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + x-kubernetes-map-type: atomic + inLine: + description: InLine is a simple string to append as the source data. + type: string + secret: + description: |- + Secret is a reference (by name) to a Secret's `data` key(s), or to a + list of Secret's `data` key(s) using label selector, in the trust Namespace. + properties: + includeAllKeys: + description: |- + IncludeAllKeys is a flag to include all keys in the object's `data` field to be used. False by default. + This field must not be true when `Key` is set. + type: boolean + key: + description: Key of the entry in the object's `data` field to be used. + minLength: 1 + type: string + name: + description: |- + Name is the name of the source object in the trust Namespace. + This field must be left empty when `selector` is set + minLength: 1 + type: string + selector: + description: |- + Selector is the label selector to use to fetch a list of objects. Must not be set + when `Name` is set. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + x-kubernetes-map-type: atomic + useDefaultCAs: + description: |- + UseDefaultCAs, when true, requests the default CA bundle to be used as a source. + Default CAs are available if trust-manager was installed via Helm + or was otherwise set up to include a package-injecting init container by using the + "--default-package-location" flag when starting the trust-manager controller. + If default CAs were not configured at start-up, any request to use the default + CAs will fail. + The version of the default CA package which is used for a Bundle is stored in the + defaultCAPackageVersion field of the Bundle's status field. + type: boolean + type: object + x-kubernetes-map-type: atomic + maxItems: 100 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + target: + description: Target is the target location in all namespaces to sync source data to. + properties: + additionalFormats: + description: AdditionalFormats specifies any additional formats to write to the target + properties: + jks: + description: |- + JKS requests a JKS-formatted binary trust bundle to be written to the target. + The bundle has "changeit" as the default password. + For more information refer to this link https://cert-manager.io/docs/faq/#keystore-passwords + properties: + key: + description: Key is the key of the entry in the object's `data` field to be used. + minLength: 1 + type: string + password: + default: changeit + description: Password for JKS trust store + maxLength: 128 + minLength: 1 + type: string + required: + - key + type: object + x-kubernetes-map-type: atomic + pkcs12: + description: |- + PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. + The bundle is by default created without a password. + properties: + key: + description: Key is the key of the entry in the object's `data` field to be used. + minLength: 1 + type: string + password: + default: "" + description: Password for PKCS12 trust store + maxLength: 128 + type: string + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + configMap: + description: |- + ConfigMap is the target ConfigMap in Namespaces that all Bundle source + data will be synced to. + properties: + key: + description: Key is the key of the entry in the object's `data` field to be used. + minLength: 1 + type: string + required: + - key + type: object + namespaceSelector: + description: |- + NamespaceSelector will, if set, only sync the target resource in + Namespaces which match the selector. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + secret: + description: |- + Secret is the target Secret that all Bundle source data will be synced to. + Using Secrets as targets is only supported if enabled at trust-manager startup. + By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace. + properties: + key: + description: Key is the key of the entry in the object's `data` field to be used. + minLength: 1 + type: string + required: + - key + type: object + type: object + required: + - sources + - target + type: object + status: + description: Status of the Bundle. This is set and managed automatically. + properties: + conditions: + description: |- + List of status conditions to indicate the status of the Bundle. + Known condition types are `Bundle`. + items: + description: BundleCondition contains condition information for a Bundle. + properties: + lastTransitionTime: + description: |- + LastTransitionTime is the timestamp corresponding to the last status + change of this condition. + format: date-time + type: string + message: + description: |- + Message is a human-readable description of the details of the last + transition, complementing reason. + maxLength: 32768 + type: string + observedGeneration: + description: |- + If set, this represents the .metadata.generation that the condition was + set based upon. + For instance, if .metadata.generation is currently 12, but the + .status.condition[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the Bundle. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + Reason is a brief machine-readable explanation for the condition's last + transition. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of the condition, known values are (`Synced`). + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + defaultCAVersion: + description: |- + DefaultCAPackageVersion, if set and non-empty, indicates the version information + which was retrieved when the set of default CAs was requested in the bundle + source. This should only be set if useDefaultCAs was set to "true" on a source, + and will be the same for the same version of a bundle with identical certificates. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} \ No newline at end of file diff --git a/deploy/crds/trust-manager.io_clusterbundles.yaml b/deploy/crds/trust-manager.io_clusterbundles.yaml new file mode 100644 index 00000000..2bfef74a --- /dev/null +++ b/deploy/crds/trust-manager.io_clusterbundles.yaml @@ -0,0 +1,441 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: clusterbundles.trust-manager.io +spec: + group: trust-manager.io + names: + kind: ClusterBundle + listKind: ClusterBundleList + plural: clusterbundles + singular: clusterbundle + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Bundle ConfigMap Target Key + jsonPath: .spec.target.configMap.key + name: ConfigMap Target + type: string + - description: Bundle Secret Target Key + jsonPath: .spec.target.secret.key + name: Secret Target + type: string + - description: Bundle has been synced + jsonPath: .status.conditions[?(@.type == "Synced")].status + name: Synced + type: string + - description: Reason Bundle has Synced status + jsonPath: .status.conditions[?(@.type == "Synced")].reason + name: Reason + type: string + - description: Timestamp Bundle was created + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + 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 + type: string + kind: + description: |- + 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 + type: string + metadata: + type: object + spec: + description: Desired state of the Bundle resource. + properties: + sources: + description: Sources is a set of references to data whose data will + sync to the target. + items: + description: |- + BundleSource is the set of sources whose data will be appended and synced to + the BundleTarget in all Namespaces. + properties: + configMap: + description: |- + ConfigMap is a reference (by name) to a ConfigMap's `data` key(s), or to a + list of ConfigMap's `data` key(s) using label selector, in the trust Namespace. + properties: + includeAllKeys: + description: |- + IncludeAllKeys is a flag to include all keys in the object's `data` field to be used. False by default. + This field must not be true when `Key` is set. + type: boolean + key: + description: Key of the entry in the object's `data` field + to be used. + minLength: 1 + type: string + name: + description: |- + Name is the name of the source object in the trust Namespace. + This field must be left empty when `selector` is set + minLength: 1 + type: string + selector: + description: |- + Selector is the label selector to use to fetch a list of objects. Must not be set + when `Name` is set. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + x-kubernetes-map-type: atomic + inLine: + description: InLine is a simple string to append as the source + data. + type: string + secret: + description: |- + Secret is a reference (by name) to a Secret's `data` key(s), or to a + list of Secret's `data` key(s) using label selector, in the trust Namespace. + properties: + includeAllKeys: + description: |- + IncludeAllKeys is a flag to include all keys in the object's `data` field to be used. False by default. + This field must not be true when `Key` is set. + type: boolean + key: + description: Key of the entry in the object's `data` field + to be used. + minLength: 1 + type: string + name: + description: |- + Name is the name of the source object in the trust Namespace. + This field must be left empty when `selector` is set + minLength: 1 + type: string + selector: + description: |- + Selector is the label selector to use to fetch a list of objects. Must not be set + when `Name` is set. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + x-kubernetes-map-type: atomic + useDefaultCAs: + description: |- + UseDefaultCAs, when true, requests the default CA bundle to be used as a source. + Default CAs are available if trust-manager was installed via Helm + or was otherwise set up to include a package-injecting init container by using the + "--default-package-location" flag when starting the trust-manager controller. + If default CAs were not configured at start-up, any request to use the default + CAs will fail. + The version of the default CA package which is used for a Bundle is stored in the + defaultCAPackageVersion field of the Bundle's status field. + type: boolean + type: object + x-kubernetes-map-type: atomic + maxItems: 100 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + target: + description: Target is the target location in all namespaces to sync + source data to. + properties: + additionalFormats: + description: AdditionalFormats specifies any additional formats + to write to the target + properties: + jks: + description: |- + JKS requests a JKS-formatted binary trust bundle to be written to the target. + The bundle has "changeit" as the default password. + For more information refer to this link https://cert-manager.io/docs/faq/#keystore-passwords + properties: + key: + description: Key is the key of the entry in the object's + `data` field to be used. + minLength: 1 + type: string + password: + default: changeit + description: Password for JKS trust store + maxLength: 128 + minLength: 1 + type: string + required: + - key + type: object + x-kubernetes-map-type: atomic + pkcs12: + description: |- + PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. + The bundle is by default created without a password. + properties: + key: + description: Key is the key of the entry in the object's + `data` field to be used. + minLength: 1 + type: string + password: + default: "" + description: Password for PKCS12 trust store + maxLength: 128 + type: string + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + configMap: + description: |- + ConfigMap is the target ConfigMap in Namespaces that all Bundle source + data will be synced to. + properties: + key: + description: Key is the key of the entry in the object's `data` + field to be used. + minLength: 1 + type: string + required: + - key + type: object + namespaceSelector: + description: |- + NamespaceSelector will, if set, only sync the target resource in + Namespaces which match the selector. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + secret: + description: |- + Secret is the target Secret that all Bundle source data will be synced to. + Using Secrets as targets is only supported if enabled at trust-manager startup. + By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace. + properties: + key: + description: Key is the key of the entry in the object's `data` + field to be used. + minLength: 1 + type: string + required: + - key + type: object + type: object + required: + - sources + - target + type: object + status: + description: Status of the Bundle. This is set and managed automatically. + properties: + conditions: + description: |- + List of status conditions to indicate the status of the Bundle. + Known condition types are `Bundle`. + items: + description: BundleCondition contains condition information for + a Bundle. + properties: + lastTransitionTime: + description: |- + LastTransitionTime is the timestamp corresponding to the last status + change of this condition. + format: date-time + type: string + message: + description: |- + Message is a human-readable description of the details of the last + transition, complementing reason. + maxLength: 32768 + type: string + observedGeneration: + description: |- + If set, this represents the .metadata.generation that the condition was + set based upon. + For instance, if .metadata.generation is currently 12, but the + .status.condition[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the Bundle. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + Reason is a brief machine-readable explanation for the condition's last + transition. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of the condition, known values are (`Synced`). + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + defaultCAVersion: + description: |- + DefaultCAPackageVersion, if set and non-empty, indicates the version information + which was retrieved when the set of default CAs was requested in the bundle + source. This should only be set if useDefaultCAs was set to "true" on a source, + and will be the same for the same version of a bundle with identical certificates. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/pkg/api/doc.go b/pkg/api/doc.go new file mode 100644 index 00000000..9002cc53 --- /dev/null +++ b/pkg/api/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2021 The cert-manager Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package api + +const GroupName = "trust-manager.io" diff --git a/pkg/api/v1alpha1/doc.go b/pkg/api/v1alpha1/doc.go new file mode 100644 index 00000000..5cae1d25 --- /dev/null +++ b/pkg/api/v1alpha1/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2021 The cert-manager Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +kubebuilder:object:generate=true +// +groupName=trust-manager.io +package v1alpha1 diff --git a/pkg/api/v1alpha1/register.go b/pkg/api/v1alpha1/register.go new file mode 100644 index 00000000..1d5af00c --- /dev/null +++ b/pkg/api/v1alpha1/register.go @@ -0,0 +1,69 @@ +/* +Copyright 2021 The cert-manager Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes/scheme" + + "github.com/cert-manager/trust-manager/pkg/api" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: api.GroupName, Version: "v1alpha1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme + + GlobalScheme *runtime.Scheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addKnownTypes) + + GlobalScheme = runtime.NewScheme() + if err := scheme.AddToScheme(GlobalScheme); err != nil { + panic(fmt.Sprintf("failed to add k8s.io scheme: %s", err)) + } + if err := AddToScheme(GlobalScheme); err != nil { + panic(fmt.Sprintf("failed to add trust-manager.io scheme: %s", err)) + } +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ClusterBundle{}, + &ClusterBundleList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/pkg/api/v1alpha1/types_cluster_bundle.go b/pkg/api/v1alpha1/types_cluster_bundle.go new file mode 100644 index 00000000..49d619a1 --- /dev/null +++ b/pkg/api/v1alpha1/types_cluster_bundle.go @@ -0,0 +1,268 @@ +/* +Copyright 2021 The cert-manager Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ClusterBundleKind = "ClusterBundle" + +var BundleLabelKey = "trust-manager.io/bundle" +var BundleHashAnnotationKey = "trust-manager.io/hash" + +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="ConfigMap Target",type="string",JSONPath=".spec.target.configMap.key",description="Bundle ConfigMap Target Key" +// +kubebuilder:printcolumn:name="Secret Target",type="string",JSONPath=".spec.target.secret.key",description="Bundle Secret Target Key" +// +kubebuilder:printcolumn:name="Synced",type="string",JSONPath=`.status.conditions[?(@.type == "Synced")].status`,description="Bundle has been synced" +// +kubebuilder:printcolumn:name="Reason",type="string",JSONPath=`.status.conditions[?(@.type == "Synced")].reason`,description="Reason Bundle has Synced status" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Timestamp Bundle was created" +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster +// +genclient +// +genclient:nonNamespaced + +type ClusterBundle struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Desired state of the Bundle resource. + Spec BundleSpec `json:"spec"` + + // Status of the Bundle. This is set and managed automatically. + // +optional + Status BundleStatus `json:"status"` +} + +// +kubebuilder:object:root=true +type ClusterBundleList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterBundle `json:"items"` +} + +// BundleSpec defines the desired state of a Bundle. +type BundleSpec struct { + // Sources is a set of references to data whose data will sync to the target. + // +listType=atomic + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=100 + Sources []BundleSource `json:"sources"` + + // Target is the target location in all namespaces to sync source data to. + Target BundleTarget `json:"target"` +} + +// BundleSource is the set of sources whose data will be appended and synced to +// the BundleTarget in all Namespaces. +// +structType=atomic +type BundleSource struct { + // ConfigMap is a reference (by name) to a ConfigMap's `data` key(s), or to a + // list of ConfigMap's `data` key(s) using label selector, in the trust Namespace. + // +optional + ConfigMap *SourceObjectKeySelector `json:"configMap,omitempty"` + + // Secret is a reference (by name) to a Secret's `data` key(s), or to a + // list of Secret's `data` key(s) using label selector, in the trust Namespace. + // +optional + Secret *SourceObjectKeySelector `json:"secret,omitempty"` + + // InLine is a simple string to append as the source data. + // +optional + InLine *string `json:"inLine,omitempty"` + + // UseDefaultCAs, when true, requests the default CA bundle to be used as a source. + // Default CAs are available if trust-manager was installed via Helm + // or was otherwise set up to include a package-injecting init container by using the + // "--default-package-location" flag when starting the trust-manager controller. + // If default CAs were not configured at start-up, any request to use the default + // CAs will fail. + // The version of the default CA package which is used for a Bundle is stored in the + // defaultCAPackageVersion field of the Bundle's status field. + // +optional + UseDefaultCAs *bool `json:"useDefaultCAs,omitempty"` +} + +// BundleTarget is the target resource that the Bundle will sync all source +// data to. +type BundleTarget struct { + // ConfigMap is the target ConfigMap in Namespaces that all Bundle source + // data will be synced to. + // +optional + ConfigMap *KeySelector `json:"configMap,omitempty"` + + // Secret is the target Secret that all Bundle source data will be synced to. + // Using Secrets as targets is only supported if enabled at trust-manager startup. + // By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace. + // +optional + Secret *KeySelector `json:"secret,omitempty"` + + // AdditionalFormats specifies any additional formats to write to the target + // +optional + AdditionalFormats *AdditionalFormats `json:"additionalFormats,omitempty"` + + // NamespaceSelector will, if set, only sync the target resource in + // Namespaces which match the selector. + // +optional + NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"` +} + +// AdditionalFormats specifies any additional formats to write to the target +type AdditionalFormats struct { + // JKS requests a JKS-formatted binary trust bundle to be written to the target. + // The bundle has "changeit" as the default password. + // For more information refer to this link https://cert-manager.io/docs/faq/#keystore-passwords + // +optional + JKS *JKS `json:"jks,omitempty"` + // PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. + // The bundle is by default created without a password. + // +optional + PKCS12 *PKCS12 `json:"pkcs12,omitempty"` +} + +// JKS specifies additional target JKS files +// +structType=atomic +type JKS struct { + KeySelector `json:",inline"` + + // Password for JKS trust store + //+optional + //+kubebuilder:validation:MinLength=1 + //+kubebuilder:validation:MaxLength=128 + //+kubebuilder:default=changeit + Password *string `json:"password"` +} + +// PKCS12 specifies additional target PKCS#12 files +// +structType=atomic +type PKCS12 struct { + KeySelector `json:",inline"` + + // Password for PKCS12 trust store + //+optional + //+kubebuilder:validation:MaxLength=128 + //+kubebuilder:default="" + Password *string `json:"password,omitempty"` +} + +// SourceObjectKeySelector is a reference to a source object and its `data` key(s) +// in the trust Namespace. +// +structType=atomic +type SourceObjectKeySelector struct { + // Name is the name of the source object in the trust Namespace. + // This field must be left empty when `selector` is set + //+optional + // +kubebuilder:validation:MinLength=1 + Name string `json:"name,omitempty"` + + // Selector is the label selector to use to fetch a list of objects. Must not be set + // when `Name` is set. + //+optional + Selector *metav1.LabelSelector `json:"selector,omitempty"` + + // Key of the entry in the object's `data` field to be used. + //+optional + // +kubebuilder:validation:MinLength=1 + Key string `json:"key,omitempty"` + + // IncludeAllKeys is a flag to include all keys in the object's `data` field to be used. False by default. + // This field must not be true when `Key` is set. + //+optional + IncludeAllKeys bool `json:"includeAllKeys,omitempty"` +} + +// KeySelector is a reference to a key for some map data object. +type KeySelector struct { + // Key is the key of the entry in the object's `data` field to be used. + // +kubebuilder:validation:MinLength=1 + Key string `json:"key"` +} + +// BundleStatus defines the observed state of the Bundle. +type BundleStatus struct { + // List of status conditions to indicate the status of the Bundle. + // Known condition types are `Bundle`. + // +listType=map + // +listMapKey=type + // +optional + Conditions []BundleCondition `json:"conditions,omitempty"` + + // DefaultCAPackageVersion, if set and non-empty, indicates the version information + // which was retrieved when the set of default CAs was requested in the bundle + // source. This should only be set if useDefaultCAs was set to "true" on a source, + // and will be the same for the same version of a bundle with identical certificates. + // +optional + DefaultCAPackageVersion *string `json:"defaultCAVersion,omitempty"` +} + +// BundleCondition contains condition information for a Bundle. +type BundleCondition struct { + // Type of the condition, known values are (`Synced`). + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + Type string `json:"type"` + + // Status of the condition, one of True, False, Unknown. + // +kubebuilder:validation:Enum=True;False;Unknown + Status metav1.ConditionStatus `json:"status"` + + // LastTransitionTime is the timestamp corresponding to the last status + // change of this condition. + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Format=date-time + LastTransitionTime metav1.Time `json:"lastTransitionTime"` + + // Reason is a brief machine-readable explanation for the condition's last + // transition. + // The value should be a CamelCase string. + // This field may not be empty. + // +kubebuilder:validation:MaxLength=1024 + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:Pattern=`^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$` + Reason string `json:"reason"` + + // Message is a human-readable description of the details of the last + // transition, complementing reason. + // +optional + // +kubebuilder:validation:MaxLength=32768 + Message string `json:"message,omitempty"` + + // If set, this represents the .metadata.generation that the condition was + // set based upon. + // For instance, if .metadata.generation is currently 12, but the + // .status.condition[x].observedGeneration is 9, the condition is out of date + // with respect to the current state of the Bundle. + // +optional + // +kubebuilder:validation:Minimum=0 + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +const ( + // DefaultJKSPassword is the default password that Java uses; it's a Java convention to use this exact password. + // Since we're not storing anything secret in the JKS files we generate, this password is not a meaningful security measure + // but seems often to be expected by applications consuming JKS files + DefaultJKSPassword = "changeit" + // DefaultPKCS12Password is the empty string, that will create a password-less PKCS12 truststore. + // Password-less PKCS is the new default Java truststore from Java 18. + // By password-less, it means the certificates are not encrypted, and it contains no MacData for integrity check. + DefaultPKCS12Password = "" + + // BundleConditionSynced indicates that the Bundle has successfully synced + // all source bundle data to the Bundle target in all Namespaces. + BundleConditionSynced string = "Synced" +) diff --git a/pkg/api/v1alpha1/zz_generated.deepcopy.go b/pkg/api/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000..37f9083c --- /dev/null +++ b/pkg/api/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,323 @@ +//go:build !ignore_autogenerated + +/* +Copyright The cert-manager Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdditionalFormats) DeepCopyInto(out *AdditionalFormats) { + *out = *in + if in.JKS != nil { + in, out := &in.JKS, &out.JKS + *out = new(JKS) + (*in).DeepCopyInto(*out) + } + if in.PKCS12 != nil { + in, out := &in.PKCS12, &out.PKCS12 + *out = new(PKCS12) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdditionalFormats. +func (in *AdditionalFormats) DeepCopy() *AdditionalFormats { + if in == nil { + return nil + } + out := new(AdditionalFormats) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BundleCondition) DeepCopyInto(out *BundleCondition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleCondition. +func (in *BundleCondition) DeepCopy() *BundleCondition { + if in == nil { + return nil + } + out := new(BundleCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BundleSource) DeepCopyInto(out *BundleSource) { + *out = *in + if in.ConfigMap != nil { + in, out := &in.ConfigMap, &out.ConfigMap + *out = new(SourceObjectKeySelector) + (*in).DeepCopyInto(*out) + } + if in.Secret != nil { + in, out := &in.Secret, &out.Secret + *out = new(SourceObjectKeySelector) + (*in).DeepCopyInto(*out) + } + if in.InLine != nil { + in, out := &in.InLine, &out.InLine + *out = new(string) + **out = **in + } + if in.UseDefaultCAs != nil { + in, out := &in.UseDefaultCAs, &out.UseDefaultCAs + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleSource. +func (in *BundleSource) DeepCopy() *BundleSource { + if in == nil { + return nil + } + out := new(BundleSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BundleSpec) DeepCopyInto(out *BundleSpec) { + *out = *in + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make([]BundleSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Target.DeepCopyInto(&out.Target) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleSpec. +func (in *BundleSpec) DeepCopy() *BundleSpec { + if in == nil { + return nil + } + out := new(BundleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BundleStatus) DeepCopyInto(out *BundleStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]BundleCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DefaultCAPackageVersion != nil { + in, out := &in.DefaultCAPackageVersion, &out.DefaultCAPackageVersion + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleStatus. +func (in *BundleStatus) DeepCopy() *BundleStatus { + if in == nil { + return nil + } + out := new(BundleStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BundleTarget) DeepCopyInto(out *BundleTarget) { + *out = *in + if in.ConfigMap != nil { + in, out := &in.ConfigMap, &out.ConfigMap + *out = new(KeySelector) + **out = **in + } + if in.Secret != nil { + in, out := &in.Secret, &out.Secret + *out = new(KeySelector) + **out = **in + } + if in.AdditionalFormats != nil { + in, out := &in.AdditionalFormats, &out.AdditionalFormats + *out = new(AdditionalFormats) + (*in).DeepCopyInto(*out) + } + if in.NamespaceSelector != nil { + in, out := &in.NamespaceSelector, &out.NamespaceSelector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleTarget. +func (in *BundleTarget) DeepCopy() *BundleTarget { + if in == nil { + return nil + } + out := new(BundleTarget) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBundle) DeepCopyInto(out *ClusterBundle) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBundle. +func (in *ClusterBundle) DeepCopy() *ClusterBundle { + if in == nil { + return nil + } + out := new(ClusterBundle) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterBundle) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBundleList) DeepCopyInto(out *ClusterBundleList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterBundle, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBundleList. +func (in *ClusterBundleList) DeepCopy() *ClusterBundleList { + if in == nil { + return nil + } + out := new(ClusterBundleList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterBundleList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JKS) DeepCopyInto(out *JKS) { + *out = *in + out.KeySelector = in.KeySelector + if in.Password != nil { + in, out := &in.Password, &out.Password + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JKS. +func (in *JKS) DeepCopy() *JKS { + if in == nil { + return nil + } + out := new(JKS) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeySelector) DeepCopyInto(out *KeySelector) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeySelector. +func (in *KeySelector) DeepCopy() *KeySelector { + if in == nil { + return nil + } + out := new(KeySelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PKCS12) DeepCopyInto(out *PKCS12) { + *out = *in + out.KeySelector = in.KeySelector + if in.Password != nil { + in, out := &in.Password, &out.Password + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PKCS12. +func (in *PKCS12) DeepCopy() *PKCS12 { + if in == nil { + return nil + } + out := new(PKCS12) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourceObjectKeySelector) DeepCopyInto(out *SourceObjectKeySelector) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceObjectKeySelector. +func (in *SourceObjectKeySelector) DeepCopy() *SourceObjectKeySelector { + if in == nil { + return nil + } + out := new(SourceObjectKeySelector) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/trust/v1alpha1/doc.go b/pkg/apis/trust/v1alpha1/doc.go index 67d05ad6..4da2a5b4 100644 --- a/pkg/apis/trust/v1alpha1/doc.go +++ b/pkg/apis/trust/v1alpha1/doc.go @@ -16,4 +16,5 @@ limitations under the License. // +kubebuilder:object:generate=true // +groupName=trust.cert-manager.io +// +k8s:conversion-gen=github.com/cert-manager/trust-manager/pkg/api/v1alpha1 package v1alpha1