diff --git a/machineconfiguration/v1/Makefile b/machineconfiguration/v1/Makefile new file mode 100644 index 00000000000..7cd8eee901e --- /dev/null +++ b/machineconfiguration/v1/Makefile @@ -0,0 +1,3 @@ +.PHONY: test +test: + make -C ../../tests test GINKGO_EXTRA_ARGS=--focus="machineconfiguration.openshift.io/v1" diff --git a/machineconfiguration/v1/custom.machineconfigpool.testsuite.yaml b/machineconfiguration/v1/custom.machineconfigpool.testsuite.yaml new file mode 100644 index 00000000000..80f474d8bde --- /dev/null +++ b/machineconfiguration/v1/custom.machineconfigpool.testsuite.yaml @@ -0,0 +1,27 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "[Custom] MachineConfigPool" +crd: 0000_80_machine-config_01_machineconfigpools-CustomNoUpgrade.crd.yaml +tests: + onCreate: + - name: Should be able to create a minimal MachineConfigPool + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigPool + spec: {} # No spec is required for a MachineConfigPool + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigPool + spec: {} + - name: Should be able to add a PinnedImageSet + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigPool + spec: + pinnedImageSets: + - name: test-pinnedimageset + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigPool + spec: + pinnedImageSets: + - name: test-pinnedimageset diff --git a/machineconfiguration/v1/stable.machineconfigpool.testsuite.yaml b/machineconfiguration/v1/stable.machineconfigpool.testsuite.yaml index 300daa548c8..fba5e7a93e5 100644 --- a/machineconfiguration/v1/stable.machineconfigpool.testsuite.yaml +++ b/machineconfiguration/v1/stable.machineconfigpool.testsuite.yaml @@ -1,6 +1,6 @@ apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this -name: "[Stable] MachineConfigPool" -crd: 0000_80_machine-config_01_machineconfigpools.crd.yaml +name: "[Default] MachineConfigPool" +crd: 0000_80_machine-config_01_machineconfigpools-Default.crd.yaml tests: onCreate: - name: Should be able to create a minimal MachineConfigPool diff --git a/machineconfiguration/v1/techpreview.machineconfigpool.testsuite.yaml b/machineconfiguration/v1/techpreview.machineconfigpool.testsuite.yaml new file mode 100644 index 00000000000..aed5e416da2 --- /dev/null +++ b/machineconfiguration/v1/techpreview.machineconfigpool.testsuite.yaml @@ -0,0 +1,27 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "[TechPreview] MachineConfigPool" +crd: 0000_80_machine-config_01_machineconfigpools-TechPreviewNoUpgrade.crd.yaml +tests: + onCreate: + - name: Should be able to create a minimal MachineConfigPool + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigPool + spec: {} # No spec is required for a MachineConfigPool + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigPool + spec: {} + - name: Should be able to add a PinnedImageSet + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigPool + spec: + pinnedImageSets: + - name: test-pinnedimageset + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigPool + spec: + pinnedImageSets: + - name: test-pinnedimageset diff --git a/machineconfiguration/v1/types.go b/machineconfiguration/v1/types.go index 3d76a7126b1..5b1b196df6d 100644 --- a/machineconfiguration/v1/types.go +++ b/machineconfiguration/v1/types.go @@ -421,6 +421,44 @@ type MachineConfigPoolSpec struct { // The targeted MachineConfig object for the machine config pool. // +optional Configuration MachineConfigPoolStatusConfiguration `json:"configuration"` + + // pinnedImageSets specifies a sequence of PinnedImageSetRef objects for the + // pool. Nodes within this pool will preload and pin images defined in the + // PinnedImageSet. Before pulling images the MachineConfigDaemon will ensure + // the total uncompressed size of all the images does not exceed available + // resources. If the total size of the images exceeds the available + // resources the controller will report a Degraded status to the + // MachineConfigPool and not attempt to pull any images. Also to help ensure + // the kubelet can mitigate storage risk, the pinned_image configuration and + // subsequent service reload will happen only after all of the images have + // been pulled for each set. Images from multiple PinnedImageSets are loaded + // and pinned sequentially as listed. Duplicate and existing images will be + // skipped. + // + // Any failure to prefetch or pin images will result in a Degraded pool. + // Resolving these failures is the responsibility of the user. The admin + // should be proactive in ensuring adequate storage and proper image + // authentication exists in advance. + // +openshift:enable:FeatureGate=PinnedImages + // +optional + // +listType=map + // +listMapKey=name + PinnedImageSets []PinnedImageSetRef `json:"pinnedImageSets,omitempty"` +} + +type PinnedImageSetRef struct { + // name is a reference to the name of a PinnedImageSet. Must adhere to + // RFC-1123 (https://tools.ietf.org/html/rfc1123). + // Made up of one of more period-separated (.) segments, where each segment + // consists of alphanumeric characters and hyphens (-), must begin and end + // with an alphanumeric character, and is at most 63 characters in length. + // The total length of the name must not exceed 253 characters. + // +openshift:enable:FeatureGate=PinnedImages + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$` + // +kubebuilder:validation:Required + Name string `json:"name"` } // MachineConfigPoolStatus is the status for MachineConfigPool resource. diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-CustomNoUpgrade.crd.yaml new file mode 100644 index 00000000000..81385e0b3bd --- /dev/null +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-CustomNoUpgrade.crd.yaml @@ -0,0 +1,553 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/1453 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + release.openshift.io/feature-set: CustomNoUpgrade + labels: + openshift.io/operator-managed: "" + name: machineconfigpools.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigPool + listKind: MachineConfigPoolList + plural: machineconfigpools + shortNames: + - mcp + singular: machineconfigpool + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.configuration.name + name: Config + type: string + - description: When all the machines in the pool are updated to the correct machine + config. + jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - description: When at least one of machine is not either not updated or is in + the process of updating to the desired machine config. + jsonPath: .status.conditions[?(@.type=="Updating")].status + name: Updating + type: string + - description: When progress is blocked on updating one or more nodes or the pool + configuration is failing. + jsonPath: .status.conditions[?(@.type=="Degraded")].status + name: Degraded + type: string + - description: Total number of machines in the machine config pool + jsonPath: .status.machineCount + name: MachineCount + type: number + - description: Total number of ready machines targeted by the pool + jsonPath: .status.readyMachineCount + name: ReadyMachineCount + type: number + - description: Total number of machines targeted by the pool that have the CurrentMachineConfig + as their config + jsonPath: .status.updatedMachineCount + name: UpdatedMachineCount + type: number + - description: Total number of machines marked degraded (or unreconcilable) + jsonPath: .status.degradedMachineCount + name: DegradedMachineCount + type: number + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: "MachineConfigPool describes a pool of MachineConfigs. \n Compatibility + level 1: Stable within a major release for a minimum of 12 months or 3 minor + releases (whichever is longer)." + 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: MachineConfigPoolSpec is the spec for MachineConfigPool resource. + properties: + configuration: + description: The targeted MachineConfig object for the machine config + pool. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + source: + description: source is the list of MachineConfig objects that + were used to generate the single MachineConfig object specified + in `content`. + items: + description: "ObjectReference contains enough information to + let you inspect or modify the referred object. --- New uses + of this type are discouraged because of difficulty describing + its usage when embedded in APIs. 1. Ignored fields. It includes + many fields which are not generally honored. For instance, + ResourceVersion and FieldPath are both very rarely valid in + actual usage. 2. Invalid usage help. It is impossible to + add specific help for individual usage. In most embedded + usages, there are particular restrictions like, \"must refer + only to types A and B\" or \"UID not honored\" or \"name must + be restricted\". Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, + the validation rules are different by usage, which makes it + hard for users to predict what will happen. 4. The fields + are both imprecise and overly precise. Kind is not a precise + mapping to a URL. This can produce ambiguity during interpretation + and require a REST mapping. In most cases, the dependency + is on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an + underspecified API type they do not control. \n Instead of + using this type, create a locally provided and used type that + is well-focused on your reference. For example, ServiceReferences + for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this pod). + This syntax is chosen only to have some well-defined way + of referencing a part of an object. TODO: this design + is not final and this field is subject to change in the + future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + machineConfigSelector: + description: machineConfigSelector specifies a label selector for + MachineConfigs. Refer https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + on how label and selectors work. + 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 + required: + - key + - operator + type: object + type: array + 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 + maxUnavailable: + anyOf: + - type: integer + - type: string + description: "maxUnavailable defines either an integer number or percentage + of nodes in the pool that can go Unavailable during an update. This + includes nodes Unavailable for any reason, including user initiated + cordons, failing nodes, etc. The default value is 1. \n A value + larger than 1 will mean multiple nodes going unavailable during + the update, which may affect your workload stress on the remaining + nodes. You cannot set this value to 0 to stop updates (it will default + back to 1); to stop updates, use the 'paused' property instead. + Drain will respect Pod Disruption Budgets (PDBs) such as etcd quorum + guards, even if maxUnavailable is greater than one." + x-kubernetes-int-or-string: true + nodeSelector: + description: nodeSelector specifies a label selector for Machines + 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 + required: + - key + - operator + type: object + type: array + 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 + paused: + description: paused specifies whether or not changes to this machine + config pool should be stopped. This includes generating new desiredMachineConfig + and update of machines. + type: boolean + pinnedImageSets: + description: "pinnedImageSets specifies a sequence of PinnedImageSetRef + objects for the pool. Nodes within this pool will preload and pin + images defined in the PinnedImageSet. Before pulling images the + MachineConfigDaemon will ensure the total uncompressed size of all + the images does not exceed available resources. If the total size + of the images exceeds the available resources the controller will + report a Degraded status to the MachineConfigPool and not attempt + to pull any images. Also to help ensure the kubelet can mitigate + storage risk, the pinned_image configuration and subsequent service + reload will happen only after all of the images have been pulled + for each set. Images from multiple PinnedImageSets are loaded and + pinned sequentially as listed. Duplicate and existing images will + be skipped. \n Any failure to prefetch or pin images will result + in a Degraded pool. Resolving these failures is the responsibility + of the user. The admin should be proactive in ensuring adequate + storage and proper image authentication exists in advance." + items: + properties: + name: + description: name is a reference to the name of a PinnedImageSet. Must + adhere to RFC-1123 (https://tools.ietf.org/html/rfc1123). + Made up of one of more period-separated (.) segments, where + each segment consists of alphanumeric characters and hyphens + (-), must begin and end with an alphanumeric character, and + is at most 63 characters in length. The total length of the + name must not exceed 253 characters. + maxLength: 253 + minLength: 1 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: MachineConfigPoolStatus is the status for MachineConfigPool + resource. + properties: + certExpirys: + description: certExpirys keeps track of important certificate expiration + data + items: + description: ceryExpiry contains the bundle name and the expiry + date + properties: + bundle: + description: bundle is the name of the bundle in which the subject + certificate resides + type: string + expiry: + description: expiry is the date after which the certificate + will no longer be valid + format: date-time + type: string + subject: + description: subject is the subject of the certificate + type: string + required: + - bundle + - subject + type: object + type: array + x-kubernetes-list-type: atomic + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: MachineConfigPoolCondition contains condition information + for an MachineConfigPool. + properties: + lastTransitionTime: + description: lastTransitionTime is the timestamp corresponding + to the last status change of this condition. + format: date-time + nullable: true + type: string + message: + description: message is a human readable description of the + details of the last transition, complementing reason. + type: string + reason: + description: reason is a brief machine readable explanation + for the condition's last transition. + type: string + status: + description: status of the condition, one of ('True', 'False', + 'Unknown'). + type: string + type: + description: type of the condition, currently ('Done', 'Updating', + 'Failed'). + type: string + type: object + type: array + x-kubernetes-list-type: atomic + configuration: + description: configuration represents the current MachineConfig object + for the machine config pool. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + source: + description: source is the list of MachineConfig objects that + were used to generate the single MachineConfig object specified + in `content`. + items: + description: "ObjectReference contains enough information to + let you inspect or modify the referred object. --- New uses + of this type are discouraged because of difficulty describing + its usage when embedded in APIs. 1. Ignored fields. It includes + many fields which are not generally honored. For instance, + ResourceVersion and FieldPath are both very rarely valid in + actual usage. 2. Invalid usage help. It is impossible to + add specific help for individual usage. In most embedded + usages, there are particular restrictions like, \"must refer + only to types A and B\" or \"UID not honored\" or \"name must + be restricted\". Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, + the validation rules are different by usage, which makes it + hard for users to predict what will happen. 4. The fields + are both imprecise and overly precise. Kind is not a precise + mapping to a URL. This can produce ambiguity during interpretation + and require a REST mapping. In most cases, the dependency + is on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an + underspecified API type they do not control. \n Instead of + using this type, create a locally provided and used type that + is well-focused on your reference. For example, ServiceReferences + for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this pod). + This syntax is chosen only to have some well-defined way + of referencing a part of an object. TODO: this design + is not final and this field is subject to change in the + future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + degradedMachineCount: + description: degradedMachineCount represents the total number of machines + marked degraded (or unreconcilable). A node is marked degraded if + applying a configuration failed.. + format: int32 + type: integer + machineCount: + description: machineCount represents the total number of machines + in the machine config pool. + format: int32 + type: integer + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + readyMachineCount: + description: readyMachineCount represents the total number of ready + machines targeted by the pool. + format: int32 + type: integer + unavailableMachineCount: + description: unavailableMachineCount represents the total number of + unavailable (non-ready) machines targeted by the pool. A node is + marked unavailable if it is in updating state or NodeReady condition + is false. + format: int32 + type: integer + updatedMachineCount: + description: updatedMachineCount represents the total number of machines + targeted by the pool that have the CurrentMachineConfig as their + config. + format: int32 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-Default.crd.yaml similarity index 99% rename from machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools.crd.yaml rename to machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-Default.crd.yaml index c54fdbd6b9e..39434c3d499 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-Default.crd.yaml @@ -7,6 +7,7 @@ metadata: include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" include.release.openshift.io/single-node-developer: "true" + release.openshift.io/feature-set: Default labels: openshift.io/operator-managed: "" name: machineconfigpools.machineconfiguration.openshift.io diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-TechPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 00000000000..5356610e12f --- /dev/null +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigpools-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,553 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/1453 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + release.openshift.io/feature-set: TechPreviewNoUpgrade + labels: + openshift.io/operator-managed: "" + name: machineconfigpools.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigPool + listKind: MachineConfigPoolList + plural: machineconfigpools + shortNames: + - mcp + singular: machineconfigpool + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.configuration.name + name: Config + type: string + - description: When all the machines in the pool are updated to the correct machine + config. + jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - description: When at least one of machine is not either not updated or is in + the process of updating to the desired machine config. + jsonPath: .status.conditions[?(@.type=="Updating")].status + name: Updating + type: string + - description: When progress is blocked on updating one or more nodes or the pool + configuration is failing. + jsonPath: .status.conditions[?(@.type=="Degraded")].status + name: Degraded + type: string + - description: Total number of machines in the machine config pool + jsonPath: .status.machineCount + name: MachineCount + type: number + - description: Total number of ready machines targeted by the pool + jsonPath: .status.readyMachineCount + name: ReadyMachineCount + type: number + - description: Total number of machines targeted by the pool that have the CurrentMachineConfig + as their config + jsonPath: .status.updatedMachineCount + name: UpdatedMachineCount + type: number + - description: Total number of machines marked degraded (or unreconcilable) + jsonPath: .status.degradedMachineCount + name: DegradedMachineCount + type: number + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: "MachineConfigPool describes a pool of MachineConfigs. \n Compatibility + level 1: Stable within a major release for a minimum of 12 months or 3 minor + releases (whichever is longer)." + 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: MachineConfigPoolSpec is the spec for MachineConfigPool resource. + properties: + configuration: + description: The targeted MachineConfig object for the machine config + pool. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + source: + description: source is the list of MachineConfig objects that + were used to generate the single MachineConfig object specified + in `content`. + items: + description: "ObjectReference contains enough information to + let you inspect or modify the referred object. --- New uses + of this type are discouraged because of difficulty describing + its usage when embedded in APIs. 1. Ignored fields. It includes + many fields which are not generally honored. For instance, + ResourceVersion and FieldPath are both very rarely valid in + actual usage. 2. Invalid usage help. It is impossible to + add specific help for individual usage. In most embedded + usages, there are particular restrictions like, \"must refer + only to types A and B\" or \"UID not honored\" or \"name must + be restricted\". Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, + the validation rules are different by usage, which makes it + hard for users to predict what will happen. 4. The fields + are both imprecise and overly precise. Kind is not a precise + mapping to a URL. This can produce ambiguity during interpretation + and require a REST mapping. In most cases, the dependency + is on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an + underspecified API type they do not control. \n Instead of + using this type, create a locally provided and used type that + is well-focused on your reference. For example, ServiceReferences + for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this pod). + This syntax is chosen only to have some well-defined way + of referencing a part of an object. TODO: this design + is not final and this field is subject to change in the + future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + machineConfigSelector: + description: machineConfigSelector specifies a label selector for + MachineConfigs. Refer https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + on how label and selectors work. + 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 + required: + - key + - operator + type: object + type: array + 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 + maxUnavailable: + anyOf: + - type: integer + - type: string + description: "maxUnavailable defines either an integer number or percentage + of nodes in the pool that can go Unavailable during an update. This + includes nodes Unavailable for any reason, including user initiated + cordons, failing nodes, etc. The default value is 1. \n A value + larger than 1 will mean multiple nodes going unavailable during + the update, which may affect your workload stress on the remaining + nodes. You cannot set this value to 0 to stop updates (it will default + back to 1); to stop updates, use the 'paused' property instead. + Drain will respect Pod Disruption Budgets (PDBs) such as etcd quorum + guards, even if maxUnavailable is greater than one." + x-kubernetes-int-or-string: true + nodeSelector: + description: nodeSelector specifies a label selector for Machines + 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 + required: + - key + - operator + type: object + type: array + 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 + paused: + description: paused specifies whether or not changes to this machine + config pool should be stopped. This includes generating new desiredMachineConfig + and update of machines. + type: boolean + pinnedImageSets: + description: "pinnedImageSets specifies a sequence of PinnedImageSetRef + objects for the pool. Nodes within this pool will preload and pin + images defined in the PinnedImageSet. Before pulling images the + MachineConfigDaemon will ensure the total uncompressed size of all + the images does not exceed available resources. If the total size + of the images exceeds the available resources the controller will + report a Degraded status to the MachineConfigPool and not attempt + to pull any images. Also to help ensure the kubelet can mitigate + storage risk, the pinned_image configuration and subsequent service + reload will happen only after all of the images have been pulled + for each set. Images from multiple PinnedImageSets are loaded and + pinned sequentially as listed. Duplicate and existing images will + be skipped. \n Any failure to prefetch or pin images will result + in a Degraded pool. Resolving these failures is the responsibility + of the user. The admin should be proactive in ensuring adequate + storage and proper image authentication exists in advance." + items: + properties: + name: + description: name is a reference to the name of a PinnedImageSet. Must + adhere to RFC-1123 (https://tools.ietf.org/html/rfc1123). + Made up of one of more period-separated (.) segments, where + each segment consists of alphanumeric characters and hyphens + (-), must begin and end with an alphanumeric character, and + is at most 63 characters in length. The total length of the + name must not exceed 253 characters. + maxLength: 253 + minLength: 1 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: MachineConfigPoolStatus is the status for MachineConfigPool + resource. + properties: + certExpirys: + description: certExpirys keeps track of important certificate expiration + data + items: + description: ceryExpiry contains the bundle name and the expiry + date + properties: + bundle: + description: bundle is the name of the bundle in which the subject + certificate resides + type: string + expiry: + description: expiry is the date after which the certificate + will no longer be valid + format: date-time + type: string + subject: + description: subject is the subject of the certificate + type: string + required: + - bundle + - subject + type: object + type: array + x-kubernetes-list-type: atomic + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: MachineConfigPoolCondition contains condition information + for an MachineConfigPool. + properties: + lastTransitionTime: + description: lastTransitionTime is the timestamp corresponding + to the last status change of this condition. + format: date-time + nullable: true + type: string + message: + description: message is a human readable description of the + details of the last transition, complementing reason. + type: string + reason: + description: reason is a brief machine readable explanation + for the condition's last transition. + type: string + status: + description: status of the condition, one of ('True', 'False', + 'Unknown'). + type: string + type: + description: type of the condition, currently ('Done', 'Updating', + 'Failed'). + type: string + type: object + type: array + x-kubernetes-list-type: atomic + configuration: + description: configuration represents the current MachineConfig object + for the machine config pool. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + source: + description: source is the list of MachineConfig objects that + were used to generate the single MachineConfig object specified + in `content`. + items: + description: "ObjectReference contains enough information to + let you inspect or modify the referred object. --- New uses + of this type are discouraged because of difficulty describing + its usage when embedded in APIs. 1. Ignored fields. It includes + many fields which are not generally honored. For instance, + ResourceVersion and FieldPath are both very rarely valid in + actual usage. 2. Invalid usage help. It is impossible to + add specific help for individual usage. In most embedded + usages, there are particular restrictions like, \"must refer + only to types A and B\" or \"UID not honored\" or \"name must + be restricted\". Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, + the validation rules are different by usage, which makes it + hard for users to predict what will happen. 4. The fields + are both imprecise and overly precise. Kind is not a precise + mapping to a URL. This can produce ambiguity during interpretation + and require a REST mapping. In most cases, the dependency + is on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an + underspecified API type they do not control. \n Instead of + using this type, create a locally provided and used type that + is well-focused on your reference. For example, ServiceReferences + for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this pod). + This syntax is chosen only to have some well-defined way + of referencing a part of an object. TODO: this design + is not final and this field is subject to change in the + future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + degradedMachineCount: + description: degradedMachineCount represents the total number of machines + marked degraded (or unreconcilable). A node is marked degraded if + applying a configuration failed.. + format: int32 + type: integer + machineCount: + description: machineCount represents the total number of machines + in the machine config pool. + format: int32 + type: integer + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + readyMachineCount: + description: readyMachineCount represents the total number of ready + machines targeted by the pool. + format: int32 + type: integer + unavailableMachineCount: + description: unavailableMachineCount represents the total number of + unavailable (non-ready) machines targeted by the pool. A node is + marked unavailable if it is in updating state or NodeReady condition + is false. + format: int32 + type: integer + updatedMachineCount: + description: updatedMachineCount represents the total number of machines + targeted by the pool that have the CurrentMachineConfig as their + config. + format: int32 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/machineconfiguration/v1/zz_generated.deepcopy.go b/machineconfiguration/v1/zz_generated.deepcopy.go index 180027a84e4..d89627b91dd 100644 --- a/machineconfiguration/v1/zz_generated.deepcopy.go +++ b/machineconfiguration/v1/zz_generated.deepcopy.go @@ -730,6 +730,11 @@ func (in *MachineConfigPoolSpec) DeepCopyInto(out *MachineConfigPoolSpec) { **out = **in } in.Configuration.DeepCopyInto(&out.Configuration) + if in.PinnedImageSets != nil { + in, out := &in.PinnedImageSets, &out.PinnedImageSets + *out = make([]PinnedImageSetRef, len(*in)) + copy(*out, *in) + } return } @@ -843,3 +848,19 @@ func (in *NetworkInfo) DeepCopy() *NetworkInfo { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PinnedImageSetRef) DeepCopyInto(out *PinnedImageSetRef) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PinnedImageSetRef. +func (in *PinnedImageSetRef) DeepCopy() *PinnedImageSetRef { + if in == nil { + return nil + } + out := new(PinnedImageSetRef) + in.DeepCopyInto(out) + return out +} diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml index 8c9734bf5ff..a10144da5a2 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml @@ -110,7 +110,8 @@ machineconfigpools.machineconfiguration.openshift.io: CRDName: machineconfigpools.machineconfiguration.openshift.io Capability: "" Category: "" - FeatureGates: [] + FeatureGates: + - PinnedImages FilenameOperatorName: machine-config FilenameOperatorOrdering: "01" FilenameRunLevel: "0000_80" diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfigpools.machineconfiguration.openshift.io/PinnedImages.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfigpools.machineconfiguration.openshift.io/PinnedImages.yaml new file mode 100644 index 00000000000..955a4550934 --- /dev/null +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfigpools.machineconfiguration.openshift.io/PinnedImages.yaml @@ -0,0 +1,552 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/1453 + api.openshift.io/filename-cvo-runlevel: "0000_80" + api.openshift.io/filename-operator: machine-config + api.openshift.io/filename-ordering: "01" + feature-gate.release.openshift.io/PinnedImages: "true" + labels: + openshift.io/operator-managed: "" + name: machineconfigpools.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigPool + listKind: MachineConfigPoolList + plural: machineconfigpools + shortNames: + - mcp + singular: machineconfigpool + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.configuration.name + name: Config + type: string + - description: When all the machines in the pool are updated to the correct machine + config. + jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - description: When at least one of machine is not either not updated or is in + the process of updating to the desired machine config. + jsonPath: .status.conditions[?(@.type=="Updating")].status + name: Updating + type: string + - description: When progress is blocked on updating one or more nodes or the pool + configuration is failing. + jsonPath: .status.conditions[?(@.type=="Degraded")].status + name: Degraded + type: string + - description: Total number of machines in the machine config pool + jsonPath: .status.machineCount + name: MachineCount + type: number + - description: Total number of ready machines targeted by the pool + jsonPath: .status.readyMachineCount + name: ReadyMachineCount + type: number + - description: Total number of machines targeted by the pool that have the CurrentMachineConfig + as their config + jsonPath: .status.updatedMachineCount + name: UpdatedMachineCount + type: number + - description: Total number of machines marked degraded (or unreconcilable) + jsonPath: .status.degradedMachineCount + name: DegradedMachineCount + type: number + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: "MachineConfigPool describes a pool of MachineConfigs. \n Compatibility + level 1: Stable within a major release for a minimum of 12 months or 3 minor + releases (whichever is longer)." + 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: MachineConfigPoolSpec is the spec for MachineConfigPool resource. + properties: + configuration: + description: The targeted MachineConfig object for the machine config + pool. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + source: + description: source is the list of MachineConfig objects that + were used to generate the single MachineConfig object specified + in `content`. + items: + description: "ObjectReference contains enough information to + let you inspect or modify the referred object. --- New uses + of this type are discouraged because of difficulty describing + its usage when embedded in APIs. 1. Ignored fields. It includes + many fields which are not generally honored. For instance, + ResourceVersion and FieldPath are both very rarely valid in + actual usage. 2. Invalid usage help. It is impossible to + add specific help for individual usage. In most embedded + usages, there are particular restrictions like, \"must refer + only to types A and B\" or \"UID not honored\" or \"name must + be restricted\". Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, + the validation rules are different by usage, which makes it + hard for users to predict what will happen. 4. The fields + are both imprecise and overly precise. Kind is not a precise + mapping to a URL. This can produce ambiguity during interpretation + and require a REST mapping. In most cases, the dependency + is on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an + underspecified API type they do not control. \n Instead of + using this type, create a locally provided and used type that + is well-focused on your reference. For example, ServiceReferences + for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this pod). + This syntax is chosen only to have some well-defined way + of referencing a part of an object. TODO: this design + is not final and this field is subject to change in the + future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + machineConfigSelector: + description: machineConfigSelector specifies a label selector for + MachineConfigs. Refer https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + on how label and selectors work. + 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 + required: + - key + - operator + type: object + type: array + 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 + maxUnavailable: + anyOf: + - type: integer + - type: string + description: "maxUnavailable defines either an integer number or percentage + of nodes in the pool that can go Unavailable during an update. This + includes nodes Unavailable for any reason, including user initiated + cordons, failing nodes, etc. The default value is 1. \n A value + larger than 1 will mean multiple nodes going unavailable during + the update, which may affect your workload stress on the remaining + nodes. You cannot set this value to 0 to stop updates (it will default + back to 1); to stop updates, use the 'paused' property instead. + Drain will respect Pod Disruption Budgets (PDBs) such as etcd quorum + guards, even if maxUnavailable is greater than one." + x-kubernetes-int-or-string: true + nodeSelector: + description: nodeSelector specifies a label selector for Machines + 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 + required: + - key + - operator + type: object + type: array + 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 + paused: + description: paused specifies whether or not changes to this machine + config pool should be stopped. This includes generating new desiredMachineConfig + and update of machines. + type: boolean + pinnedImageSets: + description: "pinnedImageSets specifies a sequence of PinnedImageSetRef + objects for the pool. Nodes within this pool will preload and pin + images defined in the PinnedImageSet. Before pulling images the + MachineConfigDaemon will ensure the total uncompressed size of all + the images does not exceed available resources. If the total size + of the images exceeds the available resources the controller will + report a Degraded status to the MachineConfigPool and not attempt + to pull any images. Also to help ensure the kubelet can mitigate + storage risk, the pinned_image configuration and subsequent service + reload will happen only after all of the images have been pulled + for each set. Images from multiple PinnedImageSets are loaded and + pinned sequentially as listed. Duplicate and existing images will + be skipped. \n Any failure to prefetch or pin images will result + in a Degraded pool. Resolving these failures is the responsibility + of the user. The admin should be proactive in ensuring adequate + storage and proper image authentication exists in advance." + items: + properties: + name: + description: name is a reference to the name of a PinnedImageSet. Must + adhere to RFC-1123 (https://tools.ietf.org/html/rfc1123). + Made up of one of more period-separated (.) segments, where + each segment consists of alphanumeric characters and hyphens + (-), must begin and end with an alphanumeric character, and + is at most 63 characters in length. The total length of the + name must not exceed 253 characters. + maxLength: 253 + minLength: 1 + pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$ + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: MachineConfigPoolStatus is the status for MachineConfigPool + resource. + properties: + certExpirys: + description: certExpirys keeps track of important certificate expiration + data + items: + description: ceryExpiry contains the bundle name and the expiry + date + properties: + bundle: + description: bundle is the name of the bundle in which the subject + certificate resides + type: string + expiry: + description: expiry is the date after which the certificate + will no longer be valid + format: date-time + type: string + subject: + description: subject is the subject of the certificate + type: string + required: + - bundle + - subject + type: object + type: array + x-kubernetes-list-type: atomic + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: MachineConfigPoolCondition contains condition information + for an MachineConfigPool. + properties: + lastTransitionTime: + description: lastTransitionTime is the timestamp corresponding + to the last status change of this condition. + format: date-time + nullable: true + type: string + message: + description: message is a human readable description of the + details of the last transition, complementing reason. + type: string + reason: + description: reason is a brief machine readable explanation + for the condition's last transition. + type: string + status: + description: status of the condition, one of ('True', 'False', + 'Unknown'). + type: string + type: + description: type of the condition, currently ('Done', 'Updating', + 'Failed'). + type: string + type: object + type: array + x-kubernetes-list-type: atomic + configuration: + description: configuration represents the current MachineConfig object + for the machine config pool. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + source: + description: source is the list of MachineConfig objects that + were used to generate the single MachineConfig object specified + in `content`. + items: + description: "ObjectReference contains enough information to + let you inspect or modify the referred object. --- New uses + of this type are discouraged because of difficulty describing + its usage when embedded in APIs. 1. Ignored fields. It includes + many fields which are not generally honored. For instance, + ResourceVersion and FieldPath are both very rarely valid in + actual usage. 2. Invalid usage help. It is impossible to + add specific help for individual usage. In most embedded + usages, there are particular restrictions like, \"must refer + only to types A and B\" or \"UID not honored\" or \"name must + be restricted\". Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, + the validation rules are different by usage, which makes it + hard for users to predict what will happen. 4. The fields + are both imprecise and overly precise. Kind is not a precise + mapping to a URL. This can produce ambiguity during interpretation + and require a REST mapping. In most cases, the dependency + is on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an + underspecified API type they do not control. \n Instead of + using this type, create a locally provided and used type that + is well-focused on your reference. For example, ServiceReferences + for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this pod). + This syntax is chosen only to have some well-defined way + of referencing a part of an object. TODO: this design + is not final and this field is subject to change in the + future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + degradedMachineCount: + description: degradedMachineCount represents the total number of machines + marked degraded (or unreconcilable). A node is marked degraded if + applying a configuration failed.. + format: int32 + type: integer + machineCount: + description: machineCount represents the total number of machines + in the machine config pool. + format: int32 + type: integer + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + readyMachineCount: + description: readyMachineCount represents the total number of ready + machines targeted by the pool. + format: int32 + type: integer + unavailableMachineCount: + description: unavailableMachineCount represents the total number of + unavailable (non-ready) machines targeted by the pool. A node is + marked unavailable if it is in updating state or NodeReady condition + is false. + format: int32 + type: integer + updatedMachineCount: + description: updatedMachineCount represents the total number of machines + targeted by the pool that have the CurrentMachineConfig as their + config. + format: int32 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/machineconfiguration/v1/zz_generated.swagger_doc_generated.go b/machineconfiguration/v1/zz_generated.swagger_doc_generated.go index d1151c23b4f..8923b78b8b1 100644 --- a/machineconfiguration/v1/zz_generated.swagger_doc_generated.go +++ b/machineconfiguration/v1/zz_generated.swagger_doc_generated.go @@ -279,6 +279,7 @@ var map_MachineConfigPoolSpec = map[string]string{ "paused": "paused specifies whether or not changes to this machine config pool should be stopped. This includes generating new desiredMachineConfig and update of machines.", "maxUnavailable": "maxUnavailable defines either an integer number or percentage of nodes in the pool that can go Unavailable during an update. This includes nodes Unavailable for any reason, including user initiated cordons, failing nodes, etc. The default value is 1.\n\nA value larger than 1 will mean multiple nodes going unavailable during the update, which may affect your workload stress on the remaining nodes. You cannot set this value to 0 to stop updates (it will default back to 1); to stop updates, use the 'paused' property instead. Drain will respect Pod Disruption Budgets (PDBs) such as etcd quorum guards, even if maxUnavailable is greater than one.", "configuration": "The targeted MachineConfig object for the machine config pool.", + "pinnedImageSets": "pinnedImageSets specifies a sequence of PinnedImageSetRef objects for the pool. Nodes within this pool will preload and pin images defined in the PinnedImageSet. Before pulling images the MachineConfigDaemon will ensure the total uncompressed size of all the images does not exceed available resources. If the total size of the images exceeds the available resources the controller will report a Degraded status to the MachineConfigPool and not attempt to pull any images. Also to help ensure the kubelet can mitigate storage risk, the pinned_image configuration and subsequent service reload will happen only after all of the images have been pulled for each set. Images from multiple PinnedImageSets are loaded and pinned sequentially as listed. Duplicate and existing images will be skipped.\n\nAny failure to prefetch or pin images will result in a Degraded pool. Resolving these failures is the responsibility of the user. The admin should be proactive in ensuring adequate storage and proper image authentication exists in advance.", } func (MachineConfigPoolSpec) SwaggerDoc() map[string]string { @@ -335,4 +336,12 @@ func (NetworkInfo) SwaggerDoc() map[string]string { return map_NetworkInfo } +var map_PinnedImageSetRef = map[string]string{ + "name": "name is a reference to the name of a PinnedImageSet. Must adhere to RFC-1123 (https://tools.ietf.org/html/rfc1123). Made up of one of more period-separated (.) segments, where each segment consists of alphanumeric characters and hyphens (-), must begin and end with an alphanumeric character, and is at most 63 characters in length. The total length of the name must not exceed 253 characters.", +} + +func (PinnedImageSetRef) SwaggerDoc() map[string]string { + return map_PinnedImageSetRef +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/machineconfiguration/v1alpha1/custom.pinnedimageset.testsuite.yaml b/machineconfiguration/v1alpha1/custom.pinnedimageset.testsuite.yaml new file mode 100644 index 00000000000..43917d9e274 --- /dev/null +++ b/machineconfiguration/v1alpha1/custom.pinnedimageset.testsuite.yaml @@ -0,0 +1,98 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "[Custom] PinnedImageSet" +crd: 0000_80_machine-config_01_pinnedimagesets-CustomNoUpgrade.crd.yaml +tests: + onCreate: + - name: Should be able to create a minimal PinnedImageSet + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset + spec: + pinnedImages: + - name: "example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306" + - name: "example.com:5000/project/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + - name: "example.com/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + - name: "my-registry.local/project/my-image@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + expected: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset + spec: + pinnedImages: + - name: "example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306" + - name: "example.com:5000/project/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + - name: "example.com/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + - name: "my-registry.local/project/my-image@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: Invalid image referenced by tag + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset + spec: + pinnedImages: + - name: "example.io/my-project/image-v1.0_23:latest" + expectedError: "Invalid value: \"string\": the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" + - name: Invalid empty image + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset + spec: + pinnedImages: + - name: "" + expectedError: "Invalid value: \"\": spec.pinnedImages[0].name in body should be at least 1 chars long" + - name: Should reject a malformed SHA256 digest + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-bad-digest length + spec: + pinnedImages: + - name: "example.io/bad-digest/image@sha256:12345" + expectedError: "Invalid value: \"string\": the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" + - name: Should accept multiple images with different registries and namespaces + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-multiple-registries + spec: + pinnedImages: + - name: "docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: "quay.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + expected: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-multiple-registries + spec: + pinnedImages: + - name: "docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: "quay.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: Should reject images without a registry specified + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-no-registry + spec: + pinnedImages: + - name: "my-project/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + expectedError: "Invalid value: \"string\": the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme" + - name: Should reject duplicate images + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-duplicates + spec: + pinnedImages: + - name: "docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: "docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + expectedError: "Duplicate value: map[string]interface {}{\"name\":\"docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\"}" diff --git a/machineconfiguration/v1alpha1/register.go b/machineconfiguration/v1alpha1/register.go index b18dfac66ee..c60f521f940 100644 --- a/machineconfiguration/v1alpha1/register.go +++ b/machineconfiguration/v1alpha1/register.go @@ -26,6 +26,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(GroupVersion, &MachineConfigNode{}, &MachineConfigNodeList{}, + &PinnedImageSet{}, + &PinnedImageSetList{}, ) metav1.AddToGroupVersion(scheme, GroupVersion) return nil diff --git a/machineconfiguration/v1alpha1/techpreview.pinnedimageset.testsuite.yaml b/machineconfiguration/v1alpha1/techpreview.pinnedimageset.testsuite.yaml new file mode 100644 index 00000000000..41ef4e31f26 --- /dev/null +++ b/machineconfiguration/v1alpha1/techpreview.pinnedimageset.testsuite.yaml @@ -0,0 +1,98 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "[TechPreview] PinnedImageSet" +crd: 0000_80_machine-config_01_pinnedimagesets-TechPreviewNoUpgrade.crd.yaml +tests: + onCreate: + - name: Should be able to create a minimal PinnedImageSet + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset + spec: + pinnedImages: + - name: "example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306" + - name: "example.com:5000/project/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + - name: "example.com/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + - name: "my-registry.local/project/my-image@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + expected: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset + spec: + pinnedImages: + - name: "example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306" + - name: "example.com:5000/project/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + - name: "example.com/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + - name: "my-registry.local/project/my-image@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: Invalid image referenced by tag + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset + spec: + pinnedImages: + - name: "example.io/my-project/image-v1.0_23:latest" + expectedError: "Invalid value: \"string\": the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" + - name: Invalid empty image + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset + spec: + pinnedImages: + - name: "" + expectedError: "Invalid value: \"\": spec.pinnedImages[0].name in body should be at least 1 chars long" + - name: Should reject a malformed SHA256 digest + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-bad-digest length + spec: + pinnedImages: + - name: "example.io/bad-digest/image@sha256:12345" + expectedError: "Invalid value: \"string\": the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" + - name: Should accept multiple images with different registries and namespaces + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-multiple-registries + spec: + pinnedImages: + - name: "docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: "quay.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + expected: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-multiple-registries + spec: + pinnedImages: + - name: "docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: "quay.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: Should reject images without a registry specified + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-no-registry + spec: + pinnedImages: + - name: "my-project/image@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" + expectedError: "Invalid value: \"string\": the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme" + - name: Should reject duplicate images + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: PinnedImageSet + metadata: + name: test-pinnedimageset-duplicates + spec: + pinnedImages: + - name: "docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + - name: "docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + expectedError: "Duplicate value: map[string]interface {}{\"name\":\"docker.io/project/name@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\"}" \ No newline at end of file diff --git a/machineconfiguration/v1alpha1/types_pinnedimageset.go b/machineconfiguration/v1alpha1/types_pinnedimageset.go new file mode 100644 index 00000000000..47e50a083b3 --- /dev/null +++ b/machineconfiguration/v1alpha1/types_pinnedimageset.go @@ -0,0 +1,81 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:resource:path=pinnedimagesets,scope=Cluster +// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/1713 +// +openshift:file-pattern=cvoRunLevel=0000_80,operatorName=machine-config,operatorOrdering=01 +// +openshift:enable:FeatureGate=PinnedImages +// +kubebuilder:metadata:labels=openshift.io/operator-managed= + +// PinnedImageSet describes a set of images that should be pinned by CRI-O and +// pulled to the nodes which are members of the declared MachineConfigPools. +// +// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. +// +openshift:compatibility-gen:level=4 +type PinnedImageSet struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // spec describes the configuration of this pinned image set. + // +kubebuilder:validation:Required + Spec PinnedImageSetSpec `json:"spec"` +} + +// PinnedImageSetSpec defines the desired state of a PinnedImageSet. +type PinnedImageSetSpec struct { + // pinnedImages is a list of OCI Image referenced by digest that should be + // pinned and pre-loaded by the nodes of a MachineConfigPool. + // Translates into a new file inside the /etc/crio/crio.conf.d directory + // with content similar to this: + // + // pinned_images = [ + // "quay.io/openshift-release-dev/ocp-release@sha256:...", + // "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...", + // "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...", + // ... + // ] + // + // These image references should all be by digest, tags aren't allowed. + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=500 + // +listType=map + // +listMapKey=name + PinnedImages []PinnedImageRef `json:"pinnedImages"` +} + +type PinnedImageRef struct { + // name is an OCI Image referenced by digest. + // + // The format of the image ref is: + // host[:port][/namespace]/name@sha256: + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=447 + // +kubebuilder:validation:XValidation:rule=`self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')`,message="the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" + // +kubebuilder:validation:XValidation:rule=`self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme" + Name string `json:"name"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PinnedImageSetList is a list of PinnedImageSet resources +// +// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. +// +openshift:compatibility-gen:level=4 +type PinnedImageSetList struct { + metav1.TypeMeta `json:",inline"` + + // metadata is the standard list's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ListMeta `json:"metadata"` + + Items []PinnedImageSet `json:"items"` +} diff --git a/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_pinnedimagesets-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_pinnedimagesets-CustomNoUpgrade.crd.yaml new file mode 100644 index 00000000000..50d10d3ecc9 --- /dev/null +++ b/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_pinnedimagesets-CustomNoUpgrade.crd.yaml @@ -0,0 +1,86 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/1713 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + release.openshift.io/feature-set: CustomNoUpgrade + labels: + openshift.io/operator-managed: "" + name: pinnedimagesets.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: PinnedImageSet + listKind: PinnedImageSetList + plural: pinnedimagesets + singular: pinnedimageset + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: "PinnedImageSet describes a set of images that should be pinned + by CRI-O and pulled to the nodes which are members of the declared MachineConfigPools. + \n Compatibility level 4: No compatibility is provided, the API can change + at any point for any reason. These capabilities should not be used by applications + needing long term support." + 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: spec describes the configuration of this pinned image set. + properties: + pinnedImages: + description: "pinnedImages is a list of OCI Image referenced by digest + that should be pinned and pre-loaded by the nodes of a MachineConfigPool. + Translates into a new file inside the /etc/crio/crio.conf.d directory + with content similar to this: \n pinned_images = [ \"quay.io/openshift-release-dev/ocp-release@sha256:...\", + \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\", \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\", + ... ] \n These image references should all be by digest, tags aren't + allowed." + items: + properties: + name: + description: "name is an OCI Image referenced by digest. \n + The format of the image ref is: host[:port][/namespace]/name@sha256:" + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$') + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$') + required: + - name + type: object + maxItems: 500 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - pinnedImages + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_pinnedimagesets-TechPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_pinnedimagesets-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 00000000000..3075bb2f82e --- /dev/null +++ b/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_pinnedimagesets-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,86 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/1713 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + release.openshift.io/feature-set: TechPreviewNoUpgrade + labels: + openshift.io/operator-managed: "" + name: pinnedimagesets.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: PinnedImageSet + listKind: PinnedImageSetList + plural: pinnedimagesets + singular: pinnedimageset + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: "PinnedImageSet describes a set of images that should be pinned + by CRI-O and pulled to the nodes which are members of the declared MachineConfigPools. + \n Compatibility level 4: No compatibility is provided, the API can change + at any point for any reason. These capabilities should not be used by applications + needing long term support." + 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: spec describes the configuration of this pinned image set. + properties: + pinnedImages: + description: "pinnedImages is a list of OCI Image referenced by digest + that should be pinned and pre-loaded by the nodes of a MachineConfigPool. + Translates into a new file inside the /etc/crio/crio.conf.d directory + with content similar to this: \n pinned_images = [ \"quay.io/openshift-release-dev/ocp-release@sha256:...\", + \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\", \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\", + ... ] \n These image references should all be by digest, tags aren't + allowed." + items: + properties: + name: + description: "name is an OCI Image referenced by digest. \n + The format of the image ref is: host[:port][/namespace]/name@sha256:" + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$') + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$') + required: + - name + type: object + maxItems: 500 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - pinnedImages + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/machineconfiguration/v1alpha1/zz_generated.deepcopy.go b/machineconfiguration/v1alpha1/zz_generated.deepcopy.go index d2ab9b91afd..d1761442001 100644 --- a/machineconfiguration/v1alpha1/zz_generated.deepcopy.go +++ b/machineconfiguration/v1alpha1/zz_generated.deepcopy.go @@ -161,3 +161,100 @@ func (in *MachineConfigNodeStatusMachineConfigVersion) DeepCopy() *MachineConfig in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PinnedImageRef) DeepCopyInto(out *PinnedImageRef) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PinnedImageRef. +func (in *PinnedImageRef) DeepCopy() *PinnedImageRef { + if in == nil { + return nil + } + out := new(PinnedImageRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PinnedImageSet) DeepCopyInto(out *PinnedImageSet) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PinnedImageSet. +func (in *PinnedImageSet) DeepCopy() *PinnedImageSet { + if in == nil { + return nil + } + out := new(PinnedImageSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PinnedImageSet) 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 *PinnedImageSetList) DeepCopyInto(out *PinnedImageSetList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PinnedImageSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PinnedImageSetList. +func (in *PinnedImageSetList) DeepCopy() *PinnedImageSetList { + if in == nil { + return nil + } + out := new(PinnedImageSetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PinnedImageSetList) 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 *PinnedImageSetSpec) DeepCopyInto(out *PinnedImageSetSpec) { + *out = *in + if in.PinnedImages != nil { + in, out := &in.PinnedImages, &out.PinnedImages + *out = make([]PinnedImageRef, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PinnedImageSetSpec. +func (in *PinnedImageSetSpec) DeepCopy() *PinnedImageSetSpec { + if in == nil { + return nil + } + out := new(PinnedImageSetSpec) + in.DeepCopyInto(out) + return out +} diff --git a/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests.yaml b/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests.yaml index 68f01404bb0..b374a4f0d1e 100644 --- a/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests.yaml +++ b/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests.yaml @@ -68,3 +68,27 @@ machineconfignodes.machineconfiguration.openshift.io: - MachineConfigNodes Version: v1alpha1 +pinnedimagesets.machineconfiguration.openshift.io: + Annotations: {} + ApprovedPRNumber: https://github.com/openshift/api/pull/1713 + CRDName: pinnedimagesets.machineconfiguration.openshift.io + Capability: "" + Category: "" + FeatureGates: + - PinnedImages + FilenameOperatorName: machine-config + FilenameOperatorOrdering: "01" + FilenameRunLevel: "0000_80" + GroupName: machineconfiguration.openshift.io + HasStatus: false + KindName: PinnedImageSet + Labels: + openshift.io/operator-managed: "" + PluralName: pinnedimagesets + PrinterColumns: [] + Scope: Cluster + ShortNames: null + TopLevelFeatureGates: + - PinnedImages + Version: v1alpha1 + diff --git a/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests/pinnedimagesets.machineconfiguration.openshift.io/PinnedImages.yaml b/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests/pinnedimagesets.machineconfiguration.openshift.io/PinnedImages.yaml new file mode 100644 index 00000000000..8ef4fcf2c34 --- /dev/null +++ b/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests/pinnedimagesets.machineconfiguration.openshift.io/PinnedImages.yaml @@ -0,0 +1,85 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/1713 + api.openshift.io/filename-cvo-runlevel: "0000_80" + api.openshift.io/filename-operator: machine-config + api.openshift.io/filename-ordering: "01" + feature-gate.release.openshift.io/PinnedImages: "true" + labels: + openshift.io/operator-managed: "" + name: pinnedimagesets.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: PinnedImageSet + listKind: PinnedImageSetList + plural: pinnedimagesets + singular: pinnedimageset + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: "PinnedImageSet describes a set of images that should be pinned + by CRI-O and pulled to the nodes which are members of the declared MachineConfigPools. + \n Compatibility level 4: No compatibility is provided, the API can change + at any point for any reason. These capabilities should not be used by applications + needing long term support." + 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: spec describes the configuration of this pinned image set. + properties: + pinnedImages: + description: "pinnedImages is a list of OCI Image referenced by digest + that should be pinned and pre-loaded by the nodes of a MachineConfigPool. + Translates into a new file inside the /etc/crio/crio.conf.d directory + with content similar to this: \n pinned_images = [ \"quay.io/openshift-release-dev/ocp-release@sha256:...\", + \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\", \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\", + ... ] \n These image references should all be by digest, tags aren't + allowed." + items: + properties: + name: + description: "name is an OCI Image referenced by digest. \n + The format of the image ref is: host[:port][/namespace]/name@sha256:" + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$') + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$') + required: + - name + type: object + maxItems: 500 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - pinnedImages + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/machineconfiguration/v1alpha1/zz_generated.swagger_doc_generated.go b/machineconfiguration/v1alpha1/zz_generated.swagger_doc_generated.go index 0044c9c4b61..401bff14b86 100644 --- a/machineconfiguration/v1alpha1/zz_generated.swagger_doc_generated.go +++ b/machineconfiguration/v1alpha1/zz_generated.swagger_doc_generated.go @@ -79,4 +79,39 @@ func (MachineConfigNodeStatusMachineConfigVersion) SwaggerDoc() map[string]strin return map_MachineConfigNodeStatusMachineConfigVersion } +var map_PinnedImageRef = map[string]string{ + "name": "name is an OCI Image referenced by digest.\n\nThe format of the image ref is: host[:port][/namespace]/name@sha256:", +} + +func (PinnedImageRef) SwaggerDoc() map[string]string { + return map_PinnedImageRef +} + +var map_PinnedImageSet = map[string]string{ + "": "PinnedImageSet describes a set of images that should be pinned by CRI-O and pulled to the nodes which are members of the declared MachineConfigPools.\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", + "spec": "spec describes the configuration of this pinned image set.", +} + +func (PinnedImageSet) SwaggerDoc() map[string]string { + return map_PinnedImageSet +} + +var map_PinnedImageSetList = map[string]string{ + "": "PinnedImageSetList is a list of PinnedImageSet resources\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", + "metadata": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", +} + +func (PinnedImageSetList) SwaggerDoc() map[string]string { + return map_PinnedImageSetList +} + +var map_PinnedImageSetSpec = map[string]string{ + "": "PinnedImageSetSpec defines the desired state of a PinnedImageSet.", + "pinnedImages": "pinnedImages is a list of OCI Image referenced by digest that should be pinned and pre-loaded by the nodes of a MachineConfigPool. Translates into a new file inside the /etc/crio/crio.conf.d directory with content similar to this:\n\n pinned_images = [\n \"quay.io/openshift-release-dev/ocp-release@sha256:...\",\n \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\",\n \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\",\n ...\n ]\n\nThese image references should all be by digest, tags aren't allowed.", +} + +func (PinnedImageSetSpec) SwaggerDoc() map[string]string { + return map_PinnedImageSetSpec +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 33efff5c013..aa264a4a55f 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -755,6 +755,10 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/machineconfiguration/v1alpha1.MachineConfigNodeSpecMachineConfigVersion": schema_openshift_api_machineconfiguration_v1alpha1_MachineConfigNodeSpecMachineConfigVersion(ref), "github.com/openshift/api/machineconfiguration/v1alpha1.MachineConfigNodeStatus": schema_openshift_api_machineconfiguration_v1alpha1_MachineConfigNodeStatus(ref), "github.com/openshift/api/machineconfiguration/v1alpha1.MachineConfigNodeStatusMachineConfigVersion": schema_openshift_api_machineconfiguration_v1alpha1_MachineConfigNodeStatusMachineConfigVersion(ref), + "github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageRef": schema_openshift_api_machineconfiguration_v1alpha1_PinnedImageRef(ref), + "github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageSet": schema_openshift_api_machineconfiguration_v1alpha1_PinnedImageSet(ref), + "github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageSetList": schema_openshift_api_machineconfiguration_v1alpha1_PinnedImageSetList(ref), + "github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageSetSpec": schema_openshift_api_machineconfiguration_v1alpha1_PinnedImageSetSpec(ref), "github.com/openshift/api/monitoring/v1.AlertRelabelConfig": schema_openshift_api_monitoring_v1_AlertRelabelConfig(ref), "github.com/openshift/api/monitoring/v1.AlertRelabelConfigList": schema_openshift_api_monitoring_v1_AlertRelabelConfigList(ref), "github.com/openshift/api/monitoring/v1.AlertRelabelConfigSpec": schema_openshift_api_monitoring_v1_AlertRelabelConfigSpec(ref), @@ -38554,6 +38558,158 @@ func schema_openshift_api_machineconfiguration_v1alpha1_MachineConfigNodeStatusM } } +func schema_openshift_api_machineconfiguration_v1alpha1_PinnedImageRef(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "name is an OCI Image referenced by digest.\n\nThe format of the image ref is: host[:port][/namespace]/name@sha256:", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name"}, + }, + }, + } +} + +func schema_openshift_api_machineconfiguration_v1alpha1_PinnedImageSet(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PinnedImageSet describes a set of images that should be pinned by CRI-O and pulled to the nodes which are members of the declared MachineConfigPools.\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "spec describes the configuration of this pinned image set.", + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageSetSpec"), + }, + }, + }, + Required: []string{"spec"}, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageSetSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_openshift_api_machineconfiguration_v1alpha1_PinnedImageSetList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PinnedImageSetList is a list of PinnedImageSet resources\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageSet"), + }, + }, + }, + }, + }, + }, + Required: []string{"metadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageSet", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_openshift_api_machineconfiguration_v1alpha1_PinnedImageSetSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PinnedImageSetSpec defines the desired state of a PinnedImageSet.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "pinnedImages": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "name", + }, + "x-kubernetes-list-type": "map", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "pinnedImages is a list of OCI Image referenced by digest that should be pinned and pre-loaded by the nodes of a MachineConfigPool. Translates into a new file inside the /etc/crio/crio.conf.d directory with content similar to this:\n\n pinned_images = [\n \"quay.io/openshift-release-dev/ocp-release@sha256:...\",\n \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\",\n \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\",\n ...\n ]\n\nThese image references should all be by digest, tags aren't allowed.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageRef"), + }, + }, + }, + }, + }, + }, + Required: []string{"pinnedImages"}, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/machineconfiguration/v1alpha1.PinnedImageRef"}, + } +} + func schema_openshift_api_monitoring_v1_AlertRelabelConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/openapi/openapi.json b/openapi/openapi.json index 9d885c38910..85a69ed8d7e 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -22370,6 +22370,96 @@ } } }, + "com.github.openshift.api.machineconfiguration.v1alpha1.PinnedImageRef": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "description": "name is an OCI Image referenced by digest.\n\nThe format of the image ref is: host[:port][/namespace]/name@sha256:", + "type": "string", + "default": "" + } + } + }, + "com.github.openshift.api.machineconfiguration.v1alpha1.PinnedImageSet": { + "description": "PinnedImageSet describes a set of images that should be pinned by CRI-O and pulled to the nodes which are members of the declared MachineConfigPools.\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", + "type": "object", + "required": [ + "spec" + ], + "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": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + }, + "spec": { + "description": "spec describes the configuration of this pinned image set.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.machineconfiguration.v1alpha1.PinnedImageSetSpec" + } + } + }, + "com.github.openshift.api.machineconfiguration.v1alpha1.PinnedImageSetList": { + "description": "PinnedImageSetList is a list of PinnedImageSet resources\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", + "type": "object", + "required": [ + "metadata", + "items" + ], + "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" + }, + "items": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.machineconfiguration.v1alpha1.PinnedImageSet" + } + }, + "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": { + "description": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + } + }, + "com.github.openshift.api.machineconfiguration.v1alpha1.PinnedImageSetSpec": { + "description": "PinnedImageSetSpec defines the desired state of a PinnedImageSet.", + "type": "object", + "required": [ + "pinnedImages" + ], + "properties": { + "pinnedImages": { + "description": "pinnedImages is a list of OCI Image referenced by digest that should be pinned and pre-loaded by the nodes of a MachineConfigPool. Translates into a new file inside the /etc/crio/crio.conf.d directory with content similar to this:\n\n pinned_images = [\n \"quay.io/openshift-release-dev/ocp-release@sha256:...\",\n \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\",\n \"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...\",\n ...\n ]\n\nThese image references should all be by digest, tags aren't allowed.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.machineconfiguration.v1alpha1.PinnedImageRef" + }, + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + } + } + }, "com.github.openshift.api.monitoring.v1.AlertRelabelConfig": { "description": "AlertRelabelConfig defines a set of relabel configs for alerts.\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", "type": "object",