diff --git a/.dockerignore b/.dockerignore index 9af8280..3d30b07 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,11 +1,29 @@ # More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file -# Ignore everything by default and re-include only needed files -** +# Ignore build artifacts and unnecessary files +bin/ +testbin/ +*.test +*.out +coverage.out -# Re-include Go source files (but not *_test.go) -!**/*.go +# Ignore git and IDE files +.git +.gitignore +.idea +.vscode +*.swp +*.swo + +# Ignore documentation +*.md +docs/ + +# Ignore CI/CD files +.github/ + +# Ignore test binaries **/*_test.go -# Re-include Go module files +# Re-include essential files !go.mod -!go.sum +!go.sum \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 6466c48..f77f45a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,13 +19,15 @@ COPY . . # was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO # the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, # by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. -RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager /workspace/cmd/main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details FROM gcr.io/distroless/static:nonroot WORKDIR / COPY --from=builder /workspace/manager . -USER 65532:65532 +COPY --from=builder /workspace/templates . +USER 1001:1001 ENTRYPOINT ["/manager"] + diff --git a/Makefile b/Makefile index 8df4122..e7e5b73 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ endif # Be aware that the target commands are only tested with Docker which is # scaffolded by default. However, you might want to replace it to use other # tools. (i.e. podman) -CONTAINER_TOOL ?= docker +CONTAINER_TOOL ?= podman # Setting SHELL to bash allows bash commands to be executed by recipes. # Options are set to exit when a recipe line exits non-zero or a piped command fails. diff --git a/api/v1alpha1/nodeswap_types.go b/api/v1alpha1/nodeswap_types.go index fbe278e..c83f584 100644 --- a/api/v1alpha1/nodeswap_types.go +++ b/api/v1alpha1/nodeswap_types.go @@ -21,19 +21,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -type KubeSwapMode string - -const ( - KubeSwapLimited KubeSwapMode = "Limited" - KubeSwapUnlimited KubeSwapMode = "Unlimited" -) - -// KubeletConfig defines swap related configuration for kubelet -type KubeletConfig struct { - // +kubebuilder:validation:Type=string - SwapMode KubeSwapMode `json:"swapMode,omitempty"` -} - type SwapType string const ( @@ -82,13 +69,9 @@ type NodeSwapSpec struct { // More info: https://book.kubebuilder.io/reference/markers/crd-validation.html // Label selector for Machines on which swap will be deployed. - NodeSelector *metav1.LabelSelector `json:"nodeSelector,omitempty"` + MachineConfigPoolSelector string `json:"machineConfigPoolSelector,omitempty"` Swaps Swaps `json:"swaps,omitempty"` - - // +optional - KubeletConfig *KubeletConfig `json:"kubeletConfig,omitempty"` - // +optional LogLevel *int32 `json:"logLevel,omitempty"` } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 0b05436..a52c34f 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -25,21 +25,6 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubeletConfig) DeepCopyInto(out *KubeletConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletConfig. -func (in *KubeletConfig) DeepCopy() *KubeletConfig { - if in == nil { - return nil - } - out := new(KubeletConfig) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeSwap) DeepCopyInto(out *NodeSwap) { *out = *in @@ -102,11 +87,6 @@ func (in *NodeSwapList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeSwapSpec) DeepCopyInto(out *NodeSwapSpec) { *out = *in - if in.NodeSelector != nil { - in, out := &in.NodeSelector, &out.NodeSelector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } if in.Swaps != nil { in, out := &in.Swaps, &out.Swaps *out = make(Swaps, len(*in)) @@ -114,11 +94,6 @@ func (in *NodeSwapSpec) DeepCopyInto(out *NodeSwapSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.KubeletConfig != nil { - in, out := &in.KubeletConfig, &out.KubeletConfig - *out = new(KubeletConfig) - **out = **in - } if in.LogLevel != nil { in, out := &in.LogLevel, &out.LogLevel *out = new(int32) diff --git a/cmd/main.go b/cmd/main.go index 002927e..87eccb7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -37,9 +37,12 @@ import ( nodeswapv1alpha1 "github.com/openshift-virtualization/swap-operator/api/v1alpha1" "github.com/openshift-virtualization/swap-operator/internal/controller" + mcfgv1 "github.com/openshift/api/machineconfiguration/v1" // +kubebuilder:scaffold:imports ) +var templateDir string + var ( scheme = runtime.NewScheme() setupLog = ctrl.Log.WithName("setup") @@ -49,6 +52,8 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(nodeswapv1alpha1.AddToScheme(scheme)) + + utilruntime.Must(mcfgv1.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme } @@ -76,6 +81,7 @@ func main() { flag.StringVar(&metricsCertPath, "metrics-cert-path", "", "The directory that contains the metrics server certificate.") flag.StringVar(&metricsCertName, "metrics-cert-name", "tls.crt", "The name of the metrics server certificate file.") + flag.StringVar(&templateDir, "template-dir", "/templates", "The directory that contains the templates.") flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.") flag.BoolVar(&enableHTTP2, "enable-http2", false, "If set, HTTP/2 will be enabled for the metrics and webhook servers") @@ -87,6 +93,12 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + // Validate template directory exists + if _, err := os.Stat(templateDir); err != nil { + panic(err) + } + setupLog.Info("validated template directory", "path", templateDir) + // if the enable-http2 flag is false (the default), http/2 should be disabled // due to its vulnerabilities. More specifically, disabling http/2 will // prevent from being vulnerable to the HTTP/2 Stream Cancellation and @@ -179,8 +191,9 @@ func main() { } if err := (&controller.NodeSwapReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + TemplateDir: templateDir, // Add this line }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "NodeSwap") os.Exit(1) diff --git a/config/crd/bases/node-swap.openshift.io_nodeswaps.yaml b/config/crd/bases/node-swap.openshift.io_nodeswaps.yaml index 594cef3..09cc6b4 100644 --- a/config/crd/bases/node-swap.openshift.io_nodeswaps.yaml +++ b/config/crd/bases/node-swap.openshift.io_nodeswaps.yaml @@ -39,62 +39,12 @@ spec: spec: description: NodeSwapSpec defines the desired state of NodeSwap properties: - kubeletConfig: - description: KubeletConfig defines swap related configuration for - kubelet - properties: - swapMode: - type: string - type: object logLevel: format: int32 type: integer - nodeSelector: + machineConfigPoolSelector: description: Label selector for Machines on which swap will be deployed. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic + type: string swaps: items: properties: diff --git a/config/crd/external/0000_80_machine-config_01_containerruntimeconfigs.crd.yaml b/config/crd/external/0000_80_machine-config_01_containerruntimeconfigs.crd.yaml new file mode 100644 index 0000000..0ef5e23 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_containerruntimeconfigs.crd.yaml @@ -0,0 +1,196 @@ +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" + labels: + openshift.io/operator-managed: "" + name: containerruntimeconfigs.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: ContainerRuntimeConfig + listKind: ContainerRuntimeConfigList + plural: containerruntimeconfigs + shortNames: + - ctrcfg + singular: containerruntimeconfig + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + ContainerRuntimeConfig describes a customized Container Runtime configuration. + + 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: spec contains the desired container runtime configuration. + properties: + containerRuntimeConfig: + description: containerRuntimeConfig defines the tuneables of the container + runtime. + properties: + defaultRuntime: + description: |- + defaultRuntime is the name of the OCI runtime to be used as the default for containers. + Allowed values are `runc` and `crun`. + When set to `runc`, OpenShift will use runc to execute the container + When set to `crun`, OpenShift will use crun to execute the container + When omitted, this means no opinion and the platform is left to choose a reasonable default, + which is subject to change over time. Currently, the default is `crun`. + enum: + - crun + - runc + type: string + logLevel: + description: |- + logLevel specifies the verbosity of the logs based on the level it is set to. + Options are fatal, panic, error, warn, info, and debug. + type: string + logSizeMax: + anyOf: + - type: integer + - type: string + description: |- + logSizeMax specifies the Maximum size allowed for the container log file. + Negative numbers indicate that no size limit is imposed. + If it is positive, it must be >= 8192 to match/exceed conmon's read buffer. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + overlaySize: + anyOf: + - type: integer + - type: string + description: |- + overlaySize specifies the maximum size of a container image. + This flag can be used to set quota on the size of container images. (default: 10GB) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + pidsLimit: + description: pidsLimit specifies the maximum number of processes + allowed in a container + format: int64 + type: integer + type: object + machineConfigPoolSelector: + description: |- + machineConfigPoolSelector selects which pools the ContainerRuntimeConfig shoud apply to. + A nil selector will result in no pools being selected. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - containerRuntimeConfig + type: object + status: + description: status contains observed information about the container + runtime configuration. + properties: + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: ContainerRuntimeConfigCondition defines the state of + the ContainerRuntimeConfig + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + nullable: true + type: string + message: + description: |- + message provides additional information about the current condition. + This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are PascalCase + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_controllerconfigs-CustomNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_controllerconfigs-CustomNoUpgrade.crd.yaml new file mode 100644 index 0000000..cc8b2d9 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_controllerconfigs-CustomNoUpgrade.crd.yaml @@ -0,0 +1,3311 @@ +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" + release.openshift.io/feature-set: CustomNoUpgrade + labels: + openshift.io/operator-managed: "" + name: controllerconfigs.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: ControllerConfig + listKind: ControllerConfigList + plural: controllerconfigs + singular: controllerconfig + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + ControllerConfig describes configuration for MachineConfigController. + This is currently only used to drive the MachineConfig objects generated by the TemplateController. + + 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: spec contains the desired controller config configuration. + properties: + additionalTrustBundle: + description: |- + additionalTrustBundle is a certificate bundle that will be added to the nodes + trusted certificate store. + format: byte + nullable: true + type: string + baseOSContainerImage: + description: baseOSContainerImage is the new-format container image + for operating system updates. + type: string + baseOSExtensionsContainerImage: + description: baseOSExtensionsContainerImage is the matching extensions + container for the new-format container + type: string + cloudProviderCAData: + description: cloudProviderCAData specifies the cloud provider CA data + format: byte + nullable: true + type: string + cloudProviderConfig: + description: cloudProviderConfig is the configuration for the given + cloud provider + type: string + clusterDNSIP: + description: clusterDNSIP is the cluster DNS IP address + type: string + dns: + description: dns holds the cluster dns details + nullable: true + 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: + description: |- + metadata is the standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + type: object + spec: + description: spec holds user settable values for configuration + properties: + baseDomain: + description: |- + baseDomain is the base domain of the cluster. All managed DNS records will + be sub-domains of this base. + + For example, given the base domain `openshift.example.com`, an API server + DNS record may be created for `cluster-api.openshift.example.com`. + + Once set, this field cannot be changed. + type: string + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for DNS. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + properties: + aws: + description: aws contains DNS configuration specific to + the Amazon Web Services cloud provider. + properties: + privateZoneIAMRole: + description: |- + privateZoneIAMRole contains the ARN of an IAM role that should be assumed when performing + operations on the cluster's private hosted zone specified in the cluster DNS config. + When left empty, no role should be assumed. + pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$ + type: string + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + Allowed values: "", "AWS". + + Individual components may not support all platforms, + and must handle unrecognized platforms with best-effort defaults. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + x-kubernetes-validations: + - message: allowed values are '' and 'AWS' + rule: self in ['','AWS'] + required: + - type + type: object + x-kubernetes-validations: + - message: aws configuration is required when platform is + AWS, and forbidden otherwise + rule: 'has(self.type) && self.type == ''AWS'' ? has(self.aws) + : !has(self.aws)' + privateZone: + description: |- + privateZone is the location where all the DNS records that are only available internally + to the cluster exist. + + If this field is nil, no private records should be created. + + Once set, this field cannot be changed. + properties: + id: + description: |- + id is the identifier that can be used to find the DNS hosted zone. + + on AWS zone can be fetched using `ID` as id in [1] + on Azure zone can be fetched using `ID` as a pre-determined name in [2], + on GCP zone can be fetched using `ID` as a pre-determined name in [3]. + + [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options + [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show + [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get + type: string + tags: + additionalProperties: + type: string + description: |- + tags can be used to query the DNS hosted zone. + + on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, + + [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options + type: object + type: object + publicZone: + description: |- + publicZone is the location where all the DNS records that are publicly accessible to + the internet exist. + + If this field is nil, no public records should be created. + + Once set, this field cannot be changed. + properties: + id: + description: |- + id is the identifier that can be used to find the DNS hosted zone. + + on AWS zone can be fetched using `ID` as id in [1] + on Azure zone can be fetched using `ID` as a pre-determined name in [2], + on GCP zone can be fetched using `ID` as a pre-determined name in [3]. + + [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options + [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show + [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get + type: string + tags: + additionalProperties: + type: string + description: |- + tags can be used to query the DNS hosted zone. + + on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, + + [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options + type: object + type: object + type: object + status: + description: status holds observed values from the cluster. They + may not be overridden. + type: object + required: + - spec + type: object + x-kubernetes-embedded-resource: true + etcdDiscoveryDomain: + description: etcdDiscoveryDomain is deprecated, use Infra.Status.EtcdDiscoveryDomain + instead + type: string + imageRegistryBundleData: + description: imageRegistryBundleData is the ImageRegistryData + items: + description: ImageRegistryBundle contains information for writing + image registry certificates + properties: + data: + description: data holds the contents of the bundle that will + be written to the file location + format: byte + type: string + file: + description: file holds the name of the file where the bundle + will be written to disk + type: string + required: + - data + - file + type: object + type: array + x-kubernetes-list-type: atomic + imageRegistryBundleUserData: + description: imageRegistryBundleUserData is Image Registry Data provided + by the user + items: + description: ImageRegistryBundle contains information for writing + image registry certificates + properties: + data: + description: data holds the contents of the bundle that will + be written to the file location + format: byte + type: string + file: + description: file holds the name of the file where the bundle + will be written to disk + type: string + required: + - data + - file + type: object + type: array + x-kubernetes-list-type: atomic + images: + additionalProperties: + type: string + description: images is map of images that are used by the controller + to render templates under ./templates/ + type: object + infra: + description: infra holds the infrastructure details + nullable: true + 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: + description: |- + metadata is the standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + type: object + spec: + description: spec holds user settable values for configuration + properties: + cloudConfig: + description: |- + cloudConfig is a reference to a ConfigMap containing the cloud provider configuration file. + This configuration file is used to configure the Kubernetes cloud provider integration + when using the built-in cloud provider integration or the external cloud controller manager. + The namespace for this config map is openshift-config. + + cloudConfig should only be consumed by the kube_cloud_config controller. + The controller is responsible for using the user configuration in the spec + for various platforms and combining that with the user provided ConfigMap in this field + to create a stitched kube cloud config. + The controller generates a ConfigMap `kube-cloud-config` in `openshift-config-managed` namespace + with the kube cloud config is stored in `cloud.conf` key. + All the clients are expected to use the generated ConfigMap only. + properties: + key: + description: key allows pointing to a specific key/value + inside of the configmap. This is useful for logical + file references. + type: string + name: + type: string + type: object + platformSpec: + description: |- + platformSpec holds desired information specific to the underlying + infrastructure provider. + properties: + alibabaCloud: + description: alibabaCloud contains settings specific to + the Alibaba Cloud infrastructure provider. + type: object + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints list contains custom endpoints which will override default + service endpoint of AWS Services. + There must be only one ServiceEndpoint for a service. + items: + description: |- + AWSServiceEndpoint store the configuration of a custom url to + override existing defaults of AWS Services. + properties: + name: + description: |- + name is the name of the AWS service. + The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html + This must be provided and cannot be empty. + pattern: ^[a-z0-9-]+$ + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + pattern: ^https:// + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + azure: + description: azure contains settings specific to the Azure + infrastructure provider. + type: object + baremetal: + description: baremetal contains settings specific to the + BareMetal platform. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + equinixMetal: + description: equinixMetal contains settings specific to + the Equinix Metal infrastructure provider. + type: object + external: + description: |- + ExternalPlatformType represents generic infrastructure provider. + Platform-specific components should be supplemented separately. + properties: + platformName: + default: Unknown + description: |- + platformName holds the arbitrary string representing the infrastructure provider name, expected to be set at the installation time. + This field is solely for informational and reporting purposes and is not expected to be used for decision-making. + type: string + x-kubernetes-validations: + - message: platform name cannot be changed once set + rule: oldSelf == 'Unknown' || self == oldSelf + type: object + gcp: + description: gcp contains settings specific to the Google + Cloud Platform infrastructure provider. + type: object + ibmcloud: + description: ibmcloud contains settings specific to the + IBMCloud infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of an IBM service. These endpoints are used by components + within the cluster when trying to reach the IBM Cloud Services that have been + overridden. The CCCMO reads in the IBMCloudPlatformSpec and validates each + endpoint is resolvable. Once validated, the cloud config and IBMCloudPlatformStatus + are updated to reflect the same custom endpoints. + A maximum of 13 service endpoints overrides are supported. + items: + description: |- + IBMCloudServiceEndpoint stores the configuration of a custom url to + override existing defaults of IBM Cloud Services. + properties: + name: + description: |- + name is the name of the IBM Cloud service. + Possible values are: CIS, COS, COSConfig, DNSServices, GlobalCatalog, GlobalSearch, GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController, ResourceManager, or VPC. + For example, the IBM Cloud Private IAM service could be configured with the + service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` + Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured + with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com` + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. The path must follow the pattern + /v[0,9]+ or /api/v[0,9]+ + maxLength: 300 + type: string + x-kubernetes-validations: + - message: url must use https scheme + rule: url(self).getScheme() == "https" + - message: url path must match /v[0,9]+ or /api/v[0,9]+ + rule: matches((url(self).getEscapedPath()), + '^/(api/)?v[0-9]+/{0,1}$') + - message: url must be a valid absolute URL + rule: isURL(self) + required: + - name + - url + type: object + maxItems: 13 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + kubevirt: + description: kubevirt contains settings specific to the + kubevirt infrastructure provider. + type: object + nutanix: + description: nutanix contains settings specific to the + Nutanix infrastructure provider. + properties: + failureDomains: + description: |- + failureDomains configures failure domains information for the Nutanix platform. + When set, the failure domains defined here may be used to spread Machines across + prism element clusters to improve fault tolerance of the cluster. + items: + description: NutanixFailureDomain configures failure + domain information for the Nutanix platform. + properties: + cluster: + description: |- + cluster is to identify the cluster (the Prism Element under management of the Prism Central), + in which the Machine's VM will be created. The cluster identifier (uuid or name) can be obtained + from the Prism Central console or using the prism_central API. + properties: + name: + description: name is the resource name in + the PC. It cannot be empty if the type + is Name. + type: string + type: + description: type is the identifier type + to use for this resource. + enum: + - UUID + - Name + type: string + uuid: + description: uuid is the UUID of the resource + in the PC. It cannot be empty if the type + is UUID. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: uuid configuration is required when + type is UUID, and forbidden otherwise + rule: 'has(self.type) && self.type == ''UUID'' + ? has(self.uuid) : !has(self.uuid)' + - message: name configuration is required when + type is Name, and forbidden otherwise + rule: 'has(self.type) && self.type == ''Name'' + ? has(self.name) : !has(self.name)' + name: + description: |- + name defines the unique name of a failure domain. + Name is required and must be at most 64 characters in length. + It must consist of only lower case alphanumeric characters and hyphens (-). + It must start and end with an alphanumeric character. + This value is arbitrary and is used to identify the failure domain within the platform. + maxLength: 64 + minLength: 1 + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?' + type: string + subnets: + description: |- + subnets holds a list of identifiers (one or more) of the cluster's network subnets + If the feature gate NutanixMultiSubnets is enabled, up to 32 subnets may be configured. + for the Machine's VM to connect to. The subnet identifiers (uuid or name) can be + obtained from the Prism Central console or using the prism_central API. + items: + description: NutanixResourceIdentifier holds + the identity of a Nutanix PC resource (cluster, + image, subnet, etc.) + properties: + name: + description: name is the resource name + in the PC. It cannot be empty if the + type is Name. + type: string + type: + description: type is the identifier type + to use for this resource. + enum: + - UUID + - Name + type: string + uuid: + description: uuid is the UUID of the resource + in the PC. It cannot be empty if the + type is UUID. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: uuid configuration is required + when type is UUID, and forbidden otherwise + rule: 'has(self.type) && self.type == ''UUID'' + ? has(self.uuid) : !has(self.uuid)' + - message: name configuration is required + when type is Name, and forbidden otherwise + rule: 'has(self.type) && self.type == ''Name'' + ? has(self.name) : !has(self.name)' + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: each subnet must be unique + rule: self.all(x, self.exists_one(y, x == + y)) + required: + - cluster + - name + - subnets + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + prismCentral: + description: |- + prismCentral holds the endpoint address and port to access the Nutanix Prism Central. + When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. + Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the + proxy spec.noProxy list. + properties: + address: + description: address is the endpoint address (DNS + name or IP address) of the Nutanix Prism Central + or Element (cluster) + maxLength: 256 + type: string + port: + description: port is the port number to access + the Nutanix Prism Central or Element (cluster) + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + prismElements: + description: |- + prismElements holds one or more endpoint address and port data to access the Nutanix + Prism Elements (clusters) of the Nutanix Prism Central. Currently we only support one + Prism Element (cluster) for an OpenShift cluster, where all the Nutanix resources (VMs, subnets, volumes, etc.) + used in the OpenShift cluster are located. In the future, we may support Nutanix resources (VMs, etc.) + spread over multiple Prism Elements (clusters) of the Prism Central. + items: + description: NutanixPrismElementEndpoint holds the + name and endpoint data for a Prism Element (cluster) + properties: + endpoint: + description: |- + endpoint holds the endpoint address and port data of the Prism Element (cluster). + When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. + Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the + proxy spec.noProxy list. + properties: + address: + description: address is the endpoint address + (DNS name or IP address) of the Nutanix + Prism Central or Element (cluster) + maxLength: 256 + type: string + port: + description: port is the port number to + access the Nutanix Prism Central or Element + (cluster) + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + name: + description: |- + name is the name of the Prism Element (cluster). This value will correspond with + the cluster field configured on other resources (eg Machines, PVCs, etc). + maxLength: 256 + type: string + required: + - endpoint + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - prismCentral + - prismElements + type: object + openstack: + description: openstack contains settings specific to the + OpenStack infrastructure provider. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + ovirt: + description: ovirt contains settings specific to the oVirt + infrastructure provider. + type: object + powervs: + description: powervs contains settings specific to the + IBM Power Systems Virtual Servers infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of a Power VS service. + items: + description: |- + PowervsServiceEndpoint stores the configuration of a custom url to + override existing defaults of PowerVS Services. + properties: + name: + description: |- + name is the name of the Power VS service. + Few of the services are + IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api + ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller + Power Cloud - https://cloud.ibm.com/apidocs/power-cloud + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - Power + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + format: uri + pattern: ^https:// + type: string + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. This + value controls whether infrastructure automation such as service load + balancers, dynamic volume provisioning, machine creation and deletion, and + other integrations are enabled. If None, no infrastructure automation is + enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + and must handle unrecognized platforms as None if they do not support that platform. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + vsphere: + description: vsphere contains settings specific to the + VSphere infrastructure provider. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + failureDomains: + description: |- + failureDomains contains the definition of region, zone and the vCenter topology. + If this is omitted failure domains (regions and zones) will not be used. + items: + description: VSpherePlatformFailureDomainSpec holds + the region and zone failure domain and the vCenter + topology of that failure domain. + properties: + name: + description: |- + name defines the arbitrary but unique name + of a failure domain. + maxLength: 256 + minLength: 1 + type: string + region: + description: |- + region defines the name of a region tag that will + be attached to a vCenter datacenter. The tag + category in vCenter must be named openshift-region. + maxLength: 80 + minLength: 1 + type: string + regionAffinity: + description: |- + regionAffinity holds the type of region, Datacenter or ComputeCluster. + When set to Datacenter, this means the region is a vCenter Datacenter as defined in topology. + When set to ComputeCluster, this means the region is a vCenter Cluster as defined in topology. + properties: + type: + description: |- + type determines the vSphere object type for a region within this failure domain. + Available types are Datacenter and ComputeCluster. + When set to Datacenter, this means the vCenter Datacenter defined is the region. + When set to ComputeCluster, this means the vCenter cluster defined is the region. + enum: + - ComputeCluster + - Datacenter + type: string + required: + - type + type: object + server: + description: server is the fully-qualified domain + name or the IP address of the vCenter server. + maxLength: 255 + minLength: 1 + type: string + topology: + description: topology describes a given failure + domain using vSphere constructs + properties: + computeCluster: + description: |- + computeCluster the absolute path of the vCenter cluster + in which virtual machine will be located. + The absolute path is of the form //host/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/host/.*? + type: string + datacenter: + description: |- + datacenter is the name of vCenter datacenter in which virtual machines will be located. + The maximum length of the datacenter name is 80 characters. + maxLength: 80 + type: string + datastore: + description: |- + datastore is the absolute path of the datastore in which the + virtual machine is located. + The absolute path is of the form //datastore/ + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/datastore/.*? + type: string + folder: + description: |- + folder is the absolute path of the folder where + virtual machines are located. The absolute path + is of the form //vm/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/vm/.*? + type: string + networks: + description: |- + networks is the list of port group network names within this failure domain. + If feature gate VSphereMultiNetworks is enabled, up to 10 network adapters may be defined. + 10 is the maximum number of virtual network devices which may be attached to a VM as defined by: + https://configmax.esp.vmware.com/guest?vmwareproduct=vSphere&release=vSphere%208.0&categories=1-0 + The available networks (port groups) can be listed using + `govc ls 'network/*'` + Networks should be in the form of an absolute path: + //network/. + items: + type: string + maxItems: 10 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + resourcePool: + description: |- + resourcePool is the absolute path of the resource pool where virtual machines will be + created. The absolute path is of the form //host//Resources/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/host/.*?/Resources.* + type: string + template: + description: |- + template is the full inventory path of the virtual machine or template + that will be cloned when creating new machines in this failure domain. + The maximum length of the path is 2048 characters. + + When omitted, the template will be calculated by the control plane + machineset operator based on the region and zone defined in + VSpherePlatformFailureDomainSpec. + For example, for zone=zonea, region=region1, and infrastructure name=test, + the template path would be calculated as //vm/test-rhcos-region1-zonea. + maxLength: 2048 + minLength: 1 + pattern: ^/.*?/vm/.*? + type: string + required: + - computeCluster + - datacenter + - datastore + - networks + type: object + zone: + description: |- + zone defines the name of a zone tag that will + be attached to a vCenter cluster. The tag + category in vCenter must be named openshift-zone. + maxLength: 80 + minLength: 1 + type: string + zoneAffinity: + description: |- + zoneAffinity holds the type of the zone and the hostGroup which + vmGroup and the hostGroup names in vCenter corresponds to + a vm-host group of type Virtual Machine and Host respectively. Is also + contains the vmHostRule which is an affinity vm-host rule in vCenter. + properties: + hostGroup: + description: |- + hostGroup holds the vmGroup and the hostGroup names in vCenter + corresponds to a vm-host group of type Virtual Machine and Host respectively. Is also + contains the vmHostRule which is an affinity vm-host rule in vCenter. + properties: + hostGroup: + description: |- + hostGroup is the name of the vm-host group of type host within vCenter for this failure domain. + hostGroup is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + vmGroup: + description: |- + vmGroup is the name of the vm-host group of type virtual machine within vCenter for this failure domain. + vmGroup is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + vmHostRule: + description: |- + vmHostRule is the name of the affinity vm-host rule within vCenter for this failure domain. + vmHostRule is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + required: + - hostGroup + - vmGroup + - vmHostRule + type: object + type: + description: |- + type determines the vSphere object type for a zone within this failure domain. + Available types are ComputeCluster and HostGroup. + When set to ComputeCluster, this means the vCenter cluster defined is the zone. + When set to HostGroup, hostGroup must be configured with hostGroup, vmGroup and vmHostRule and + this means the zone is defined by the grouping of those fields. + enum: + - HostGroup + - ComputeCluster + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: hostGroup is required when type is + HostGroup, and forbidden otherwise + rule: 'has(self.type) && self.type == ''HostGroup'' + ? has(self.hostGroup) : !has(self.hostGroup)' + required: + - name + - region + - server + - topology + - zone + type: object + x-kubernetes-validations: + - message: when zoneAffinity type is HostGroup, + regionAffinity type must be ComputeCluster + rule: 'has(self.zoneAffinity) && self.zoneAffinity.type + == ''HostGroup'' ? has(self.regionAffinity) + && self.regionAffinity.type == ''ComputeCluster'' + : true' + - message: when zoneAffinity type is ComputeCluster, + regionAffinity type must be Datacenter + rule: 'has(self.zoneAffinity) && self.zoneAffinity.type + == ''ComputeCluster'' ? has(self.regionAffinity) + && self.regionAffinity.type == ''Datacenter'' + : true' + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeNetworking: + description: |- + nodeNetworking contains the definition of internal and external network constraints for + assigning the node's networking. + If this field is omitted, networking defaults to the legacy + address selection behavior which is to only support a single address and + return the first one found. + properties: + external: + description: external represents the network configuration + of the node that is externally routable. + properties: + excludeNetworkSubnetCidr: + description: |- + excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting + the IP address from the VirtualMachine's VM for use in the status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: atomic + network: + description: |- + network VirtualMachine's VM Network names that will be used to when searching + for status.addresses fields. Note that if internal.networkSubnetCIDR and + external.networkSubnetCIDR are not set, then the vNIC associated to this network must + only have a single IP address assigned to it. + The available networks (port groups) can be listed using + `govc ls 'network/*'` + type: string + networkSubnetCidr: + description: |- + networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs + that will be used in respective status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: set + type: object + internal: + description: internal represents the network configuration + of the node that is routable only within the + cluster. + properties: + excludeNetworkSubnetCidr: + description: |- + excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting + the IP address from the VirtualMachine's VM for use in the status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: atomic + network: + description: |- + network VirtualMachine's VM Network names that will be used to when searching + for status.addresses fields. Note that if internal.networkSubnetCIDR and + external.networkSubnetCIDR are not set, then the vNIC associated to this network must + only have a single IP address assigned to it. + The available networks (port groups) can be listed using + `govc ls 'network/*'` + type: string + networkSubnetCidr: + description: |- + networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs + that will be used in respective status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: set + type: object + type: object + vcenters: + description: |- + vcenters holds the connection details for services to communicate with vCenter. + Currently, only a single vCenter is supported, but in tech preview 3 vCenters are supported. + Once the cluster has been installed, you are unable to change the current number of defined + vCenters except in the case where the cluster has been upgraded from a version of OpenShift + where the vsphere platform spec was not present. You may make modifications to the existing + vCenters that are defined in the vcenters list in order to match with any added or modified + failure domains. + items: + description: |- + VSpherePlatformVCenterSpec stores the vCenter connection fields. + This is used by the vSphere CCM. + properties: + datacenters: + description: |- + The vCenter Datacenters in which the RHCOS + vm guests are located. This field will + be used by the Cloud Controller Manager. + Each datacenter listed here should be used within + a topology. + items: + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + port: + description: |- + port is the TCP port that will be used to communicate to + the vCenter endpoint. + When omitted, this means the user has no opinion and + it is up to the platform to choose a sensible default, + which is subject to change over time. + format: int32 + maximum: 32767 + minimum: 1 + type: integer + server: + description: server is the fully-qualified domain + name or the IP address of the vCenter server. + maxLength: 255 + type: string + required: + - datacenters + - server + type: object + maxItems: 3 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: vcenters cannot be added or removed once + set + rule: 'size(self) != size(oldSelf) ? size(oldSelf) + == 0 && size(self) < 2 : true' + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + - message: vcenters can have at most 1 item when configured + post-install + rule: '!has(oldSelf.vcenters) && has(self.vcenters) + ? size(self.vcenters) < 2 : true' + type: object + x-kubernetes-validations: + - message: vcenters can have at most 1 item when configured + post-install + rule: '!has(oldSelf.vsphere) && has(self.vsphere) ? size(self.vsphere.vcenters) + < 2 : true' + type: object + status: + description: status holds observed values from the cluster. They + may not be overridden. + properties: + apiServerInternalURI: + description: |- + apiServerInternalURL is a valid URI with scheme 'https', + address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components + like kubelets, to contact the Kubernetes API server using the + infrastructure provider rather than Kubernetes networking. + type: string + apiServerURL: + description: |- + apiServerURL is a valid URI with scheme 'https', address and + optionally a port (defaulting to 443). apiServerURL can be used by components like the web console + to tell users where to find the Kubernetes API. + type: string + controlPlaneTopology: + default: HighlyAvailable + description: |- + controlPlaneTopology expresses the expectations for operands that normally run on control nodes. + The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. + The 'SingleReplica' mode will be used in single-node deployments + and the operators should not configure the operand for highly-available operation + The 'External' mode indicates that the control plane is hosted externally to the cluster and that + its components are not visible within the cluster. + enum: + - HighlyAvailable + - HighlyAvailableArbiter + - SingleReplica + - DualReplica + - External + type: string + cpuPartitioning: + default: None + description: |- + cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. + CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. + Valid values are "None" and "AllNodes". When omitted, the default value is "None". + The default value of "None" indicates that no nodes will be setup with CPU partitioning. + The "AllNodes" value indicates that all nodes have been setup with CPU partitioning, + and can then be further configured via the PerformanceProfile API. + enum: + - None + - AllNodes + type: string + etcdDiscoveryDomain: + description: |- + etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering + etcd servers and clients. + For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery + deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release. + type: string + infrastructureName: + description: |- + infrastructureName uniquely identifies a cluster with a human friendly name. + Once set it should not be changed. Must be of max length 27 and must have only + alphanumeric or hyphen characters. + type: string + infrastructureTopology: + default: HighlyAvailable + description: |- + infrastructureTopology expresses the expectations for infrastructure services that do not run on control + plane nodes, usually indicated by a node selector for a `role` value + other than `master`. + The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. + The 'SingleReplica' mode will be used in single-node deployments + and the operators should not configure the operand for highly-available operation + NOTE: External topology mode is not applicable for this field. + enum: + - HighlyAvailable + - SingleReplica + type: string + platform: + description: |- + platform is the underlying infrastructure provider for the cluster. + + Deprecated: Use platformStatus.type instead. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + platformStatus: + description: |- + platformStatus holds status information specific to the underlying + infrastructure provider. + properties: + alibabaCloud: + description: alibabaCloud contains settings specific to + the Alibaba Cloud infrastructure provider. + properties: + region: + description: region specifies the region for Alibaba + Cloud resources created for the cluster. + pattern: ^[0-9A-Za-z-]+$ + type: string + resourceGroupID: + description: resourceGroupID is the ID of the resource + group for the cluster. + pattern: ^(rg-[0-9A-Za-z]+)?$ + type: string + resourceTags: + description: resourceTags is a list of additional + tags to apply to Alibaba Cloud resources created + for the cluster. + items: + description: AlibabaCloudResourceTag is the set + of tags to add to apply to resources. + properties: + key: + description: key is the key of the tag. + maxLength: 128 + minLength: 1 + type: string + value: + description: value is the value of the tag. + maxLength: 128 + minLength: 1 + type: string + required: + - key + - value + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + required: + - region + type: object + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + nullable: true + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + ipFamily: + default: IPv4 + description: |- + ipFamily specifies the IP protocol family that should be used for AWS + network resources. This controls whether AWS resources are created with + IPv4-only, or dual-stack networking with IPv4 or IPv6 as the primary + protocol family. + enum: + - IPv4 + - DualStackIPv6Primary + - DualStackIPv4Primary + type: string + x-kubernetes-validations: + - message: ipFamily is immutable once set + rule: oldSelf == '' || self == oldSelf + region: + description: region holds the default AWS region for + new AWS resources created by the cluster. + type: string + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to AWS resources created for the cluster. + See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html for information on tagging AWS resources. + AWS supports a maximum of 50 tags per resource. OpenShift reserves 25 tags for its use, leaving 25 tags + available for the user. + items: + description: AWSResourceTag is a tag to apply to + AWS resources created for the cluster. + properties: + key: + description: |- + key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag. + Key should consist of between 1 and 128 characters, and may + contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: invalid AWS resource tag key. The + string can contain only the set of alphanumeric + characters, space (' '), '_', '.', '/', + '=', '+', '-', ':', '@' + rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$') + value: + description: |- + value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag. + Value should consist of between 1 and 256 characters, and may + contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'. + Some AWS service do not support empty values. Since tags are added to resources in many services, the + length of the tag value must meet the requirements of all services. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: invalid AWS resource tag value. The + string can contain only the set of alphanumeric + characters, space (' '), '_', '.', '/', + '=', '+', '-', ':', '@' + rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$') + required: + - key + - value + type: object + maxItems: 25 + type: array + x-kubernetes-list-type: atomic + serviceEndpoints: + description: |- + serviceEndpoints list contains custom endpoints which will override default + service endpoint of AWS Services. + There must be only one ServiceEndpoint for a service. + items: + description: |- + AWSServiceEndpoint store the configuration of a custom url to + override existing defaults of AWS Services. + properties: + name: + description: |- + name is the name of the AWS service. + The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html + This must be provided and cannot be empty. + pattern: ^[a-z0-9-]+$ + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + pattern: ^https:// + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + azure: + description: azure contains settings specific to the Azure + infrastructure provider. + properties: + armEndpoint: + description: armEndpoint specifies a URL to use for + resource management in non-soverign clouds such + as Azure Stack. + type: string + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + cloudName: + description: |- + cloudName is the name of the Azure cloud environment which can be used to configure the Azure SDK + with the appropriate Azure API endpoints. + If empty, the value is equal to `AzurePublicCloud`. + enum: + - "" + - AzurePublicCloud + - AzureUSGovernmentCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureStackCloud + type: string + ipFamily: + default: IPv4 + description: |- + ipFamily specifies the IP protocol family that should be used for Azure + network resources. This controls whether Azure resources are created with + IPv4-only, or dual-stack networking with IPv4 or IPv6 as the primary + protocol family. + enum: + - IPv4 + - DualStackIPv6Primary + - DualStackIPv4Primary + type: string + x-kubernetes-validations: + - message: ipFamily is immutable once set + rule: oldSelf == '' || self == oldSelf + networkResourceGroupName: + description: |- + networkResourceGroupName is the Resource Group for network resources like the Virtual Network and Subnets used by the cluster. + If empty, the value is same as ResourceGroupName. + type: string + resourceGroupName: + description: resourceGroupName is the Resource Group + for new Azure resources created for the cluster. + type: string + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to Azure resources created for the cluster. + See https://docs.microsoft.com/en-us/rest/api/resources/tags for information on tagging Azure resources. + Due to limitations on Automation, Content Delivery Network, DNS Azure resources, a maximum of 15 tags + may be applied. OpenShift reserves 5 tags for internal use, allowing 10 tags for user configuration. + items: + description: AzureResourceTag is a tag to apply + to Azure resources created for the cluster. + properties: + key: + description: |- + key is the key part of the tag. A tag key can have a maximum of 128 characters and cannot be empty. Key + must begin with a letter, end with a letter, number or underscore, and must contain only alphanumeric + characters and the following special characters `_ . -`. + maxLength: 128 + minLength: 1 + pattern: ^[a-zA-Z]([0-9A-Za-z_.-]*[0-9A-Za-z_])?$ + type: string + value: + description: |- + value is the value part of the tag. A tag value can have a maximum of 256 characters and cannot be empty. Value + must contain only alphanumeric characters and the following special characters `_ + , - . / : ; < = > ? @`. + maxLength: 256 + minLength: 1 + pattern: ^[0-9A-Za-z_.=+-@]+$ + type: string + required: + - key + - value + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: resourceTags are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + type: object + x-kubernetes-validations: + - message: resourceTags may only be configured during + installation + rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) + || has(oldSelf.resourceTags) && has(self.resourceTags)' + baremetal: + description: baremetal contains settings specific to the + BareMetal platform. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on BareMetal platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + BareMetal deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + equinixMetal: + description: equinixMetal contains settings specific to + the Equinix Metal infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + type: string + type: object + external: + description: external contains settings specific to the + generic External infrastructure provider. + properties: + cloudControllerManager: + description: |- + cloudControllerManager contains settings specific to the external Cloud Controller Manager (a.k.a. CCM or CPI). + When omitted, new nodes will be not tainted + and no extra initialization from the cloud controller manager is expected. + properties: + state: + description: |- + state determines whether or not an external Cloud Controller Manager is expected to + be installed within the cluster. + https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager + + Valid values are "External", "None" and omitted. + When set to "External", new nodes will be tainted as uninitialized when created, + preventing them from running workloads until they are initialized by the cloud controller manager. + When omitted or set to "None", new nodes will be not tainted + and no extra initialization from the cloud controller manager is expected. + enum: + - "" + - External + - None + type: string + x-kubernetes-validations: + - message: state is immutable once set + rule: self == oldSelf + type: object + x-kubernetes-validations: + - message: state may not be added or removed once + set + rule: (has(self.state) == has(oldSelf.state)) || + (!has(oldSelf.state) && self.state != "External") + type: object + x-kubernetes-validations: + - message: cloudControllerManager may not be added or + removed once set + rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager) + gcp: + description: gcp contains settings specific to the Google + Cloud Platform infrastructure provider. + properties: + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + nullable: true + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + projectID: + description: resourceGroupName is the Project ID for + new GCP resources created for the cluster. + type: string + region: + description: region holds the region for new GCP resources + created for the cluster. + type: string + resourceLabels: + description: |- + resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. + See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. + GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, + allowing 32 labels for user configuration. + items: + description: GCPResourceLabel is a label to apply + to GCP resources created for the cluster. + properties: + key: + description: |- + key is the key part of the label. A label key can have a maximum of 63 characters and cannot be empty. + Label key must begin with a lowercase letter, and must contain only lowercase letters, numeric characters, + and the following special characters `_-`. Label key must not have the reserved prefixes `kubernetes-io` + and `openshift-io`. + maxLength: 63 + minLength: 1 + pattern: ^[a-z][0-9a-z_-]{0,62}$ + type: string + x-kubernetes-validations: + - message: label keys must not start with either + `openshift-io` or `kubernetes-io` + rule: '!self.startsWith(''openshift-io'') + && !self.startsWith(''kubernetes-io'')' + value: + description: |- + value is the value part of the label. A label value can have a maximum of 63 characters and cannot be empty. + Value must contain only lowercase letters, numeric characters, and the following special characters `_-`. + maxLength: 63 + minLength: 1 + pattern: ^[0-9a-z_-]{1,63}$ + type: string + required: + - key + - value + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: resourceLabels are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to GCP resources created for the cluster. + See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on + tagging GCP resources. GCP supports a maximum of 50 tags per resource. + items: + description: GCPResourceTag is a tag to apply to + GCP resources created for the cluster. + properties: + key: + description: |- + key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot be empty. + Tag key must begin and end with an alphanumeric character, and must contain only uppercase, lowercase + alphanumeric characters, and the following special characters `._-`. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$ + type: string + parentID: + description: |- + parentID is the ID of the hierarchical resource where the tags are defined, + e.g. at the Organization or the Project level. To find the Organization or Project ID refer to the following pages: + https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id, + https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects. + An OrganizationID must consist of decimal numbers, and cannot have leading zeroes. + A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters, numbers, + and hyphens, and must start with a letter, and cannot end with a hyphen. + maxLength: 32 + minLength: 1 + pattern: (^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$) + type: string + value: + description: |- + value is the value part of the tag. A tag value can have a maximum of 63 characters and cannot be empty. + Tag value must begin and end with an alphanumeric character, and must contain only uppercase, lowercase + alphanumeric characters, and the following special characters `_-.@%=+:,*#&(){}[]` and spaces. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$ + type: string + required: + - key + - parentID + - value + type: object + maxItems: 50 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: resourceTags are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + type: object + x-kubernetes-validations: + - message: resourceLabels may only be configured during + installation + rule: '!has(oldSelf.resourceLabels) && !has(self.resourceLabels) + || has(oldSelf.resourceLabels) && has(self.resourceLabels)' + - message: resourceTags may only be configured during + installation + rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) + || has(oldSelf.resourceTags) && has(self.resourceTags)' + ibmcloud: + description: ibmcloud contains settings specific to the + IBMCloud infrastructure provider. + properties: + cisInstanceCRN: + description: |- + cisInstanceCRN is the CRN of the Cloud Internet Services instance managing + the DNS zone for the cluster's base domain + type: string + dnsInstanceCRN: + description: |- + dnsInstanceCRN is the CRN of the DNS Services instance managing the DNS zone + for the cluster's base domain + type: string + location: + description: location is where the cluster has been + deployed + type: string + providerType: + description: providerType indicates the type of cluster + that was created + type: string + resourceGroupName: + description: resourceGroupName is the Resource Group + for new IBMCloud resources created for the cluster. + type: string + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of an IBM service. These endpoints are used by components + within the cluster when trying to reach the IBM Cloud Services that have been + overridden. The CCCMO reads in the IBMCloudPlatformSpec and validates each + endpoint is resolvable. Once validated, the cloud config and IBMCloudPlatformStatus + are updated to reflect the same custom endpoints. + items: + description: |- + IBMCloudServiceEndpoint stores the configuration of a custom url to + override existing defaults of IBM Cloud Services. + properties: + name: + description: |- + name is the name of the IBM Cloud service. + Possible values are: CIS, COS, COSConfig, DNSServices, GlobalCatalog, GlobalSearch, GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController, ResourceManager, or VPC. + For example, the IBM Cloud Private IAM service could be configured with the + service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` + Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured + with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com` + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. The path must follow the pattern + /v[0,9]+ or /api/v[0,9]+ + maxLength: 300 + type: string + x-kubernetes-validations: + - message: url must be a valid absolute URL + rule: isURL(self) + required: + - name + - url + type: object + maxItems: 13 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + kubevirt: + description: kubevirt contains settings specific to the + kubevirt infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + type: string + type: object + nutanix: + description: nutanix contains settings specific to the + Nutanix infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on Nutanix platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + openstack: + description: openstack contains settings specific to the + OpenStack infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + cloudName: + description: |- + cloudName is the name of the desired OpenStack cloud in the + client configuration file (`clouds.yaml`). + type: string + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on OpenStack platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + OpenStack deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + ovirt: + description: ovirt contains settings specific to the oVirt + infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on Ovirt platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + nodeDNSIP: + description: 'deprecated: as of 4.6, this field is + no longer set or honored. It will be removed in + a future release.' + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + powervs: + description: powervs contains settings specific to the + Power Systems Virtual Servers infrastructure provider. + properties: + cisInstanceCRN: + description: |- + cisInstanceCRN is the CRN of the Cloud Internet Services instance managing + the DNS zone for the cluster's base domain + type: string + dnsInstanceCRN: + description: |- + dnsInstanceCRN is the CRN of the DNS Services instance managing the DNS zone + for the cluster's base domain + type: string + region: + description: region holds the default Power VS region + for new Power VS resources created by the cluster. + type: string + resourceGroup: + description: |- + resourceGroup is the resource group name for new IBMCloud resources created for a cluster. + The resource group specified here will be used by cluster-image-registry-operator to set up a COS Instance in IBMCloud for the cluster registry. + More about resource groups can be found here: https://cloud.ibm.com/docs/account?topic=account-rgs. + When omitted, the image registry operator won't be able to configure storage, + which results in the image registry cluster operator not being in an available state. + maxLength: 40 + pattern: ^[a-zA-Z0-9-_ ]+$ + type: string + x-kubernetes-validations: + - message: resourceGroup is immutable once set + rule: oldSelf == '' || self == oldSelf + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of a Power VS service. + items: + description: |- + PowervsServiceEndpoint stores the configuration of a custom url to + override existing defaults of PowerVS Services. + properties: + name: + description: |- + name is the name of the Power VS service. + Few of the services are + IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api + ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller + Power Cloud - https://cloud.ibm.com/apidocs/power-cloud + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - Power + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + format: uri + pattern: ^https:// + type: string + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + zone: + description: |- + zone holds the default zone for the new Power VS resources created by the cluster. + Note: Currently only single-zone OCP clusters are supported + type: string + type: object + x-kubernetes-validations: + - message: cannot unset resourceGroup once set + rule: '!has(oldSelf.resourceGroup) || has(self.resourceGroup)' + type: + description: |- + type is the underlying infrastructure provider for the cluster. This + value controls whether infrastructure automation such as service load + balancers, dynamic volume provisioning, machine creation and deletion, and + other integrations are enabled. If None, no infrastructure automation is + enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "EquinixMetal", "PowerVS", "AlibabaCloud", "Nutanix" and "None". + Individual components may not support all platforms, and must handle + unrecognized platforms as None if they do not support that platform. + + This value will be synced with to the `status.platform` and `status.platformStatus.type`. + Currently this value cannot be changed once set. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + vsphere: + description: vsphere contains settings specific to the + VSphere infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on VSphere platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + vSphere deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + type: object + type: object + required: + - spec + type: object + x-kubernetes-embedded-resource: true + internalRegistryPullSecret: + description: |- + internalRegistryPullSecret is the pull secret for the internal registry, used by + rpm-ostree to pull images from the internal registry if present + format: byte + nullable: true + type: string + ipFamilies: + description: ipFamilies indicates the IP families in use by the cluster + network + type: string + kubeAPIServerServingCAData: + description: kubeAPIServerServingCAData managed Kubelet to API Server + Cert... Rotated automatically + format: byte + type: string + network: + description: network contains additional network related information + nullable: true + properties: + mtuMigration: + description: mtuMigration contains the MTU migration configuration. + nullable: true + properties: + machine: + description: machine contains MTU migration configuration + for the machine's uplink. + properties: + from: + description: from is the MTU to migrate from. + format: int32 + minimum: 0 + type: integer + to: + description: to is the MTU to migrate to. + format: int32 + minimum: 0 + type: integer + type: object + network: + description: network contains MTU migration configuration + for the default network. + properties: + from: + description: from is the MTU to migrate from. + format: int32 + minimum: 0 + type: integer + to: + description: to is the MTU to migrate to. + format: int32 + minimum: 0 + type: integer + type: object + type: object + required: + - mtuMigration + type: object + networkType: + description: |- + networkType holds the type of network the cluster is using + XXX: this is temporary and will be dropped as soon as possible in favor of a better support + to start network related services the proper way. + Nobody is also changing this once the cluster is up and running the first time, so, disallow + regeneration if this changes. + type: string + osImageURL: + description: osImageURL is the old-format container image that contains + the OS update payload. + type: string + platform: + description: platform is deprecated, use Infra.Status.PlatformStatus.Type + instead + type: string + proxy: + description: proxy holds the current proxy configuration for the nodes + nullable: true + properties: + httpProxy: + description: httpProxy is the URL of the proxy for HTTP requests. + type: string + httpsProxy: + description: httpsProxy is the URL of the proxy for HTTPS requests. + type: string + noProxy: + description: noProxy is a comma-separated list of hostnames and/or + CIDRs for which the proxy should not be used. + type: string + type: object + pullSecret: + description: |- + pullSecret is the default pull secret that needs to be installed + on all machines. + 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. + 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 + releaseImage: + description: releaseImage is the image used when installing the cluster + type: string + rootCAData: + description: rootCAData specifies the root CA data + format: byte + type: string + required: + - additionalTrustBundle + - baseOSContainerImage + - cloudProviderCAData + - cloudProviderConfig + - clusterDNSIP + - dns + - images + - infra + - ipFamilies + - kubeAPIServerServingCAData + - network + - proxy + - releaseImage + - rootCAData + type: object + status: + description: status contains observed information about the controller + config. + properties: + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: ControllerConfigStatusCondition contains condition + information for ControllerConfigStatus + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + nullable: true + type: string + message: + description: |- + message provides additional information about the current condition. + This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are PascalCase + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerCertificates: + description: controllerCertificates represents the latest available + observations of the automatically rotating certificates in the MCO. + items: + description: ControllerCertificate contains info about a specific + cert. + properties: + bundleFile: + description: bundleFile is the larger bundle a cert comes from + type: string + notAfter: + description: notAfter is the upper boundary for validity + format: date-time + type: string + notBefore: + description: notBefore is the lower boundary for validity + format: date-time + type: string + signer: + description: signer is the cert Issuer + type: string + subject: + description: subject is the cert subject + type: string + required: + - bundleFile + - signer + - subject + type: object + type: array + x-kubernetes-list-type: atomic + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_controllerconfigs-Default.crd.yaml b/config/crd/external/0000_80_machine-config_01_controllerconfigs-Default.crd.yaml new file mode 100644 index 0000000..485501e --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_controllerconfigs-Default.crd.yaml @@ -0,0 +1,2871 @@ +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" + release.openshift.io/feature-set: Default + labels: + openshift.io/operator-managed: "" + name: controllerconfigs.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: ControllerConfig + listKind: ControllerConfigList + plural: controllerconfigs + singular: controllerconfig + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + ControllerConfig describes configuration for MachineConfigController. + This is currently only used to drive the MachineConfig objects generated by the TemplateController. + + 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: spec contains the desired controller config configuration. + properties: + additionalTrustBundle: + description: |- + additionalTrustBundle is a certificate bundle that will be added to the nodes + trusted certificate store. + format: byte + nullable: true + type: string + baseOSContainerImage: + description: baseOSContainerImage is the new-format container image + for operating system updates. + type: string + baseOSExtensionsContainerImage: + description: baseOSExtensionsContainerImage is the matching extensions + container for the new-format container + type: string + cloudProviderCAData: + description: cloudProviderCAData specifies the cloud provider CA data + format: byte + nullable: true + type: string + cloudProviderConfig: + description: cloudProviderConfig is the configuration for the given + cloud provider + type: string + clusterDNSIP: + description: clusterDNSIP is the cluster DNS IP address + type: string + dns: + description: dns holds the cluster dns details + nullable: true + 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: + description: |- + metadata is the standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + type: object + spec: + description: spec holds user settable values for configuration + properties: + baseDomain: + description: |- + baseDomain is the base domain of the cluster. All managed DNS records will + be sub-domains of this base. + + For example, given the base domain `openshift.example.com`, an API server + DNS record may be created for `cluster-api.openshift.example.com`. + + Once set, this field cannot be changed. + type: string + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for DNS. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + properties: + aws: + description: aws contains DNS configuration specific to + the Amazon Web Services cloud provider. + properties: + privateZoneIAMRole: + description: |- + privateZoneIAMRole contains the ARN of an IAM role that should be assumed when performing + operations on the cluster's private hosted zone specified in the cluster DNS config. + When left empty, no role should be assumed. + pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$ + type: string + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + Allowed values: "", "AWS". + + Individual components may not support all platforms, + and must handle unrecognized platforms with best-effort defaults. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + x-kubernetes-validations: + - message: allowed values are '' and 'AWS' + rule: self in ['','AWS'] + required: + - type + type: object + x-kubernetes-validations: + - message: aws configuration is required when platform is + AWS, and forbidden otherwise + rule: 'has(self.type) && self.type == ''AWS'' ? has(self.aws) + : !has(self.aws)' + privateZone: + description: |- + privateZone is the location where all the DNS records that are only available internally + to the cluster exist. + + If this field is nil, no private records should be created. + + Once set, this field cannot be changed. + properties: + id: + description: |- + id is the identifier that can be used to find the DNS hosted zone. + + on AWS zone can be fetched using `ID` as id in [1] + on Azure zone can be fetched using `ID` as a pre-determined name in [2], + on GCP zone can be fetched using `ID` as a pre-determined name in [3]. + + [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options + [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show + [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get + type: string + tags: + additionalProperties: + type: string + description: |- + tags can be used to query the DNS hosted zone. + + on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, + + [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options + type: object + type: object + publicZone: + description: |- + publicZone is the location where all the DNS records that are publicly accessible to + the internet exist. + + If this field is nil, no public records should be created. + + Once set, this field cannot be changed. + properties: + id: + description: |- + id is the identifier that can be used to find the DNS hosted zone. + + on AWS zone can be fetched using `ID` as id in [1] + on Azure zone can be fetched using `ID` as a pre-determined name in [2], + on GCP zone can be fetched using `ID` as a pre-determined name in [3]. + + [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options + [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show + [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get + type: string + tags: + additionalProperties: + type: string + description: |- + tags can be used to query the DNS hosted zone. + + on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, + + [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options + type: object + type: object + type: object + status: + description: status holds observed values from the cluster. They + may not be overridden. + type: object + required: + - spec + type: object + x-kubernetes-embedded-resource: true + etcdDiscoveryDomain: + description: etcdDiscoveryDomain is deprecated, use Infra.Status.EtcdDiscoveryDomain + instead + type: string + imageRegistryBundleData: + description: imageRegistryBundleData is the ImageRegistryData + items: + description: ImageRegistryBundle contains information for writing + image registry certificates + properties: + data: + description: data holds the contents of the bundle that will + be written to the file location + format: byte + type: string + file: + description: file holds the name of the file where the bundle + will be written to disk + type: string + required: + - data + - file + type: object + type: array + x-kubernetes-list-type: atomic + imageRegistryBundleUserData: + description: imageRegistryBundleUserData is Image Registry Data provided + by the user + items: + description: ImageRegistryBundle contains information for writing + image registry certificates + properties: + data: + description: data holds the contents of the bundle that will + be written to the file location + format: byte + type: string + file: + description: file holds the name of the file where the bundle + will be written to disk + type: string + required: + - data + - file + type: object + type: array + x-kubernetes-list-type: atomic + images: + additionalProperties: + type: string + description: images is map of images that are used by the controller + to render templates under ./templates/ + type: object + infra: + description: infra holds the infrastructure details + nullable: true + 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: + description: |- + metadata is the standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + type: object + spec: + description: spec holds user settable values for configuration + properties: + cloudConfig: + description: |- + cloudConfig is a reference to a ConfigMap containing the cloud provider configuration file. + This configuration file is used to configure the Kubernetes cloud provider integration + when using the built-in cloud provider integration or the external cloud controller manager. + The namespace for this config map is openshift-config. + + cloudConfig should only be consumed by the kube_cloud_config controller. + The controller is responsible for using the user configuration in the spec + for various platforms and combining that with the user provided ConfigMap in this field + to create a stitched kube cloud config. + The controller generates a ConfigMap `kube-cloud-config` in `openshift-config-managed` namespace + with the kube cloud config is stored in `cloud.conf` key. + All the clients are expected to use the generated ConfigMap only. + properties: + key: + description: key allows pointing to a specific key/value + inside of the configmap. This is useful for logical + file references. + type: string + name: + type: string + type: object + platformSpec: + description: |- + platformSpec holds desired information specific to the underlying + infrastructure provider. + properties: + alibabaCloud: + description: alibabaCloud contains settings specific to + the Alibaba Cloud infrastructure provider. + type: object + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints list contains custom endpoints which will override default + service endpoint of AWS Services. + There must be only one ServiceEndpoint for a service. + items: + description: |- + AWSServiceEndpoint store the configuration of a custom url to + override existing defaults of AWS Services. + properties: + name: + description: |- + name is the name of the AWS service. + The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html + This must be provided and cannot be empty. + pattern: ^[a-z0-9-]+$ + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + pattern: ^https:// + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + azure: + description: azure contains settings specific to the Azure + infrastructure provider. + type: object + baremetal: + description: baremetal contains settings specific to the + BareMetal platform. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + equinixMetal: + description: equinixMetal contains settings specific to + the Equinix Metal infrastructure provider. + type: object + external: + description: |- + ExternalPlatformType represents generic infrastructure provider. + Platform-specific components should be supplemented separately. + properties: + platformName: + default: Unknown + description: |- + platformName holds the arbitrary string representing the infrastructure provider name, expected to be set at the installation time. + This field is solely for informational and reporting purposes and is not expected to be used for decision-making. + type: string + x-kubernetes-validations: + - message: platform name cannot be changed once set + rule: oldSelf == 'Unknown' || self == oldSelf + type: object + gcp: + description: gcp contains settings specific to the Google + Cloud Platform infrastructure provider. + type: object + ibmcloud: + description: ibmcloud contains settings specific to the + IBMCloud infrastructure provider. + type: object + kubevirt: + description: kubevirt contains settings specific to the + kubevirt infrastructure provider. + type: object + nutanix: + description: nutanix contains settings specific to the + Nutanix infrastructure provider. + properties: + failureDomains: + description: |- + failureDomains configures failure domains information for the Nutanix platform. + When set, the failure domains defined here may be used to spread Machines across + prism element clusters to improve fault tolerance of the cluster. + items: + description: NutanixFailureDomain configures failure + domain information for the Nutanix platform. + properties: + cluster: + description: |- + cluster is to identify the cluster (the Prism Element under management of the Prism Central), + in which the Machine's VM will be created. The cluster identifier (uuid or name) can be obtained + from the Prism Central console or using the prism_central API. + properties: + name: + description: name is the resource name in + the PC. It cannot be empty if the type + is Name. + type: string + type: + description: type is the identifier type + to use for this resource. + enum: + - UUID + - Name + type: string + uuid: + description: uuid is the UUID of the resource + in the PC. It cannot be empty if the type + is UUID. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: uuid configuration is required when + type is UUID, and forbidden otherwise + rule: 'has(self.type) && self.type == ''UUID'' + ? has(self.uuid) : !has(self.uuid)' + - message: name configuration is required when + type is Name, and forbidden otherwise + rule: 'has(self.type) && self.type == ''Name'' + ? has(self.name) : !has(self.name)' + name: + description: |- + name defines the unique name of a failure domain. + Name is required and must be at most 64 characters in length. + It must consist of only lower case alphanumeric characters and hyphens (-). + It must start and end with an alphanumeric character. + This value is arbitrary and is used to identify the failure domain within the platform. + maxLength: 64 + minLength: 1 + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?' + type: string + subnets: + description: |- + subnets holds a list of identifiers (one or more) of the cluster's network subnets + If the feature gate NutanixMultiSubnets is enabled, up to 32 subnets may be configured. + for the Machine's VM to connect to. The subnet identifiers (uuid or name) can be + obtained from the Prism Central console or using the prism_central API. + items: + description: NutanixResourceIdentifier holds + the identity of a Nutanix PC resource (cluster, + image, subnet, etc.) + properties: + name: + description: name is the resource name + in the PC. It cannot be empty if the + type is Name. + type: string + type: + description: type is the identifier type + to use for this resource. + enum: + - UUID + - Name + type: string + uuid: + description: uuid is the UUID of the resource + in the PC. It cannot be empty if the + type is UUID. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: uuid configuration is required + when type is UUID, and forbidden otherwise + rule: 'has(self.type) && self.type == ''UUID'' + ? has(self.uuid) : !has(self.uuid)' + - message: name configuration is required + when type is Name, and forbidden otherwise + rule: 'has(self.type) && self.type == ''Name'' + ? has(self.name) : !has(self.name)' + maxItems: 1 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + required: + - cluster + - name + - subnets + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + prismCentral: + description: |- + prismCentral holds the endpoint address and port to access the Nutanix Prism Central. + When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. + Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the + proxy spec.noProxy list. + properties: + address: + description: address is the endpoint address (DNS + name or IP address) of the Nutanix Prism Central + or Element (cluster) + maxLength: 256 + type: string + port: + description: port is the port number to access + the Nutanix Prism Central or Element (cluster) + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + prismElements: + description: |- + prismElements holds one or more endpoint address and port data to access the Nutanix + Prism Elements (clusters) of the Nutanix Prism Central. Currently we only support one + Prism Element (cluster) for an OpenShift cluster, where all the Nutanix resources (VMs, subnets, volumes, etc.) + used in the OpenShift cluster are located. In the future, we may support Nutanix resources (VMs, etc.) + spread over multiple Prism Elements (clusters) of the Prism Central. + items: + description: NutanixPrismElementEndpoint holds the + name and endpoint data for a Prism Element (cluster) + properties: + endpoint: + description: |- + endpoint holds the endpoint address and port data of the Prism Element (cluster). + When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. + Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the + proxy spec.noProxy list. + properties: + address: + description: address is the endpoint address + (DNS name or IP address) of the Nutanix + Prism Central or Element (cluster) + maxLength: 256 + type: string + port: + description: port is the port number to + access the Nutanix Prism Central or Element + (cluster) + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + name: + description: |- + name is the name of the Prism Element (cluster). This value will correspond with + the cluster field configured on other resources (eg Machines, PVCs, etc). + maxLength: 256 + type: string + required: + - endpoint + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - prismCentral + - prismElements + type: object + openstack: + description: openstack contains settings specific to the + OpenStack infrastructure provider. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + ovirt: + description: ovirt contains settings specific to the oVirt + infrastructure provider. + type: object + powervs: + description: powervs contains settings specific to the + IBM Power Systems Virtual Servers infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of a Power VS service. + items: + description: |- + PowervsServiceEndpoint stores the configuration of a custom url to + override existing defaults of PowerVS Services. + properties: + name: + description: |- + name is the name of the Power VS service. + Few of the services are + IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api + ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller + Power Cloud - https://cloud.ibm.com/apidocs/power-cloud + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - Power + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + format: uri + pattern: ^https:// + type: string + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. This + value controls whether infrastructure automation such as service load + balancers, dynamic volume provisioning, machine creation and deletion, and + other integrations are enabled. If None, no infrastructure automation is + enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + and must handle unrecognized platforms as None if they do not support that platform. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + vsphere: + description: vsphere contains settings specific to the + VSphere infrastructure provider. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + failureDomains: + description: |- + failureDomains contains the definition of region, zone and the vCenter topology. + If this is omitted failure domains (regions and zones) will not be used. + items: + description: VSpherePlatformFailureDomainSpec holds + the region and zone failure domain and the vCenter + topology of that failure domain. + properties: + name: + description: |- + name defines the arbitrary but unique name + of a failure domain. + maxLength: 256 + minLength: 1 + type: string + region: + description: |- + region defines the name of a region tag that will + be attached to a vCenter datacenter. The tag + category in vCenter must be named openshift-region. + maxLength: 80 + minLength: 1 + type: string + regionAffinity: + description: |- + regionAffinity holds the type of region, Datacenter or ComputeCluster. + When set to Datacenter, this means the region is a vCenter Datacenter as defined in topology. + When set to ComputeCluster, this means the region is a vCenter Cluster as defined in topology. + properties: + type: + description: |- + type determines the vSphere object type for a region within this failure domain. + Available types are Datacenter and ComputeCluster. + When set to Datacenter, this means the vCenter Datacenter defined is the region. + When set to ComputeCluster, this means the vCenter cluster defined is the region. + enum: + - ComputeCluster + - Datacenter + type: string + required: + - type + type: object + server: + description: server is the fully-qualified domain + name or the IP address of the vCenter server. + maxLength: 255 + minLength: 1 + type: string + topology: + description: topology describes a given failure + domain using vSphere constructs + properties: + computeCluster: + description: |- + computeCluster the absolute path of the vCenter cluster + in which virtual machine will be located. + The absolute path is of the form //host/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/host/.*? + type: string + datacenter: + description: |- + datacenter is the name of vCenter datacenter in which virtual machines will be located. + The maximum length of the datacenter name is 80 characters. + maxLength: 80 + type: string + datastore: + description: |- + datastore is the absolute path of the datastore in which the + virtual machine is located. + The absolute path is of the form //datastore/ + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/datastore/.*? + type: string + folder: + description: |- + folder is the absolute path of the folder where + virtual machines are located. The absolute path + is of the form //vm/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/vm/.*? + type: string + networks: + description: |- + networks is the list of port group network names within this failure domain. + If feature gate VSphereMultiNetworks is enabled, up to 10 network adapters may be defined. + 10 is the maximum number of virtual network devices which may be attached to a VM as defined by: + https://configmax.esp.vmware.com/guest?vmwareproduct=vSphere&release=vSphere%208.0&categories=1-0 + The available networks (port groups) can be listed using + `govc ls 'network/*'` + Networks should be in the form of an absolute path: + //network/. + items: + type: string + maxItems: 10 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + resourcePool: + description: |- + resourcePool is the absolute path of the resource pool where virtual machines will be + created. The absolute path is of the form //host//Resources/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/host/.*?/Resources.* + type: string + template: + description: |- + template is the full inventory path of the virtual machine or template + that will be cloned when creating new machines in this failure domain. + The maximum length of the path is 2048 characters. + + When omitted, the template will be calculated by the control plane + machineset operator based on the region and zone defined in + VSpherePlatformFailureDomainSpec. + For example, for zone=zonea, region=region1, and infrastructure name=test, + the template path would be calculated as //vm/test-rhcos-region1-zonea. + maxLength: 2048 + minLength: 1 + pattern: ^/.*?/vm/.*? + type: string + required: + - computeCluster + - datacenter + - datastore + - networks + type: object + zone: + description: |- + zone defines the name of a zone tag that will + be attached to a vCenter cluster. The tag + category in vCenter must be named openshift-zone. + maxLength: 80 + minLength: 1 + type: string + zoneAffinity: + description: |- + zoneAffinity holds the type of the zone and the hostGroup which + vmGroup and the hostGroup names in vCenter corresponds to + a vm-host group of type Virtual Machine and Host respectively. Is also + contains the vmHostRule which is an affinity vm-host rule in vCenter. + properties: + hostGroup: + description: |- + hostGroup holds the vmGroup and the hostGroup names in vCenter + corresponds to a vm-host group of type Virtual Machine and Host respectively. Is also + contains the vmHostRule which is an affinity vm-host rule in vCenter. + properties: + hostGroup: + description: |- + hostGroup is the name of the vm-host group of type host within vCenter for this failure domain. + hostGroup is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + vmGroup: + description: |- + vmGroup is the name of the vm-host group of type virtual machine within vCenter for this failure domain. + vmGroup is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + vmHostRule: + description: |- + vmHostRule is the name of the affinity vm-host rule within vCenter for this failure domain. + vmHostRule is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + required: + - hostGroup + - vmGroup + - vmHostRule + type: object + type: + description: |- + type determines the vSphere object type for a zone within this failure domain. + Available types are ComputeCluster and HostGroup. + When set to ComputeCluster, this means the vCenter cluster defined is the zone. + When set to HostGroup, hostGroup must be configured with hostGroup, vmGroup and vmHostRule and + this means the zone is defined by the grouping of those fields. + enum: + - HostGroup + - ComputeCluster + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: hostGroup is required when type is + HostGroup, and forbidden otherwise + rule: 'has(self.type) && self.type == ''HostGroup'' + ? has(self.hostGroup) : !has(self.hostGroup)' + required: + - name + - region + - server + - topology + - zone + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeNetworking: + description: |- + nodeNetworking contains the definition of internal and external network constraints for + assigning the node's networking. + If this field is omitted, networking defaults to the legacy + address selection behavior which is to only support a single address and + return the first one found. + properties: + external: + description: external represents the network configuration + of the node that is externally routable. + properties: + excludeNetworkSubnetCidr: + description: |- + excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting + the IP address from the VirtualMachine's VM for use in the status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: atomic + network: + description: |- + network VirtualMachine's VM Network names that will be used to when searching + for status.addresses fields. Note that if internal.networkSubnetCIDR and + external.networkSubnetCIDR are not set, then the vNIC associated to this network must + only have a single IP address assigned to it. + The available networks (port groups) can be listed using + `govc ls 'network/*'` + type: string + networkSubnetCidr: + description: |- + networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs + that will be used in respective status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: set + type: object + internal: + description: internal represents the network configuration + of the node that is routable only within the + cluster. + properties: + excludeNetworkSubnetCidr: + description: |- + excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting + the IP address from the VirtualMachine's VM for use in the status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: atomic + network: + description: |- + network VirtualMachine's VM Network names that will be used to when searching + for status.addresses fields. Note that if internal.networkSubnetCIDR and + external.networkSubnetCIDR are not set, then the vNIC associated to this network must + only have a single IP address assigned to it. + The available networks (port groups) can be listed using + `govc ls 'network/*'` + type: string + networkSubnetCidr: + description: |- + networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs + that will be used in respective status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: set + type: object + type: object + vcenters: + description: |- + vcenters holds the connection details for services to communicate with vCenter. + Currently, only a single vCenter is supported, but in tech preview 3 vCenters are supported. + Once the cluster has been installed, you are unable to change the current number of defined + vCenters except in the case where the cluster has been upgraded from a version of OpenShift + where the vsphere platform spec was not present. You may make modifications to the existing + vCenters that are defined in the vcenters list in order to match with any added or modified + failure domains. + items: + description: |- + VSpherePlatformVCenterSpec stores the vCenter connection fields. + This is used by the vSphere CCM. + properties: + datacenters: + description: |- + The vCenter Datacenters in which the RHCOS + vm guests are located. This field will + be used by the Cloud Controller Manager. + Each datacenter listed here should be used within + a topology. + items: + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + port: + description: |- + port is the TCP port that will be used to communicate to + the vCenter endpoint. + When omitted, this means the user has no opinion and + it is up to the platform to choose a sensible default, + which is subject to change over time. + format: int32 + maximum: 32767 + minimum: 1 + type: integer + server: + description: server is the fully-qualified domain + name or the IP address of the vCenter server. + maxLength: 255 + type: string + required: + - datacenters + - server + type: object + maxItems: 3 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: vcenters cannot be added or removed once + set + rule: 'size(self) != size(oldSelf) ? size(oldSelf) + == 0 && size(self) < 2 : true' + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + - message: vcenters can have at most 1 item when configured + post-install + rule: '!has(oldSelf.vcenters) && has(self.vcenters) + ? size(self.vcenters) < 2 : true' + type: object + x-kubernetes-validations: + - message: vcenters can have at most 1 item when configured + post-install + rule: '!has(oldSelf.vsphere) && has(self.vsphere) ? size(self.vsphere.vcenters) + < 2 : true' + type: object + status: + description: status holds observed values from the cluster. They + may not be overridden. + properties: + apiServerInternalURI: + description: |- + apiServerInternalURL is a valid URI with scheme 'https', + address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components + like kubelets, to contact the Kubernetes API server using the + infrastructure provider rather than Kubernetes networking. + type: string + apiServerURL: + description: |- + apiServerURL is a valid URI with scheme 'https', address and + optionally a port (defaulting to 443). apiServerURL can be used by components like the web console + to tell users where to find the Kubernetes API. + type: string + controlPlaneTopology: + default: HighlyAvailable + description: |- + controlPlaneTopology expresses the expectations for operands that normally run on control nodes. + The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. + The 'SingleReplica' mode will be used in single-node deployments + and the operators should not configure the operand for highly-available operation + The 'External' mode indicates that the control plane is hosted externally to the cluster and that + its components are not visible within the cluster. + enum: + - HighlyAvailable + - HighlyAvailableArbiter + - SingleReplica + - External + type: string + cpuPartitioning: + default: None + description: |- + cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. + CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. + Valid values are "None" and "AllNodes". When omitted, the default value is "None". + The default value of "None" indicates that no nodes will be setup with CPU partitioning. + The "AllNodes" value indicates that all nodes have been setup with CPU partitioning, + and can then be further configured via the PerformanceProfile API. + enum: + - None + - AllNodes + type: string + etcdDiscoveryDomain: + description: |- + etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering + etcd servers and clients. + For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery + deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release. + type: string + infrastructureName: + description: |- + infrastructureName uniquely identifies a cluster with a human friendly name. + Once set it should not be changed. Must be of max length 27 and must have only + alphanumeric or hyphen characters. + type: string + infrastructureTopology: + default: HighlyAvailable + description: |- + infrastructureTopology expresses the expectations for infrastructure services that do not run on control + plane nodes, usually indicated by a node selector for a `role` value + other than `master`. + The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. + The 'SingleReplica' mode will be used in single-node deployments + and the operators should not configure the operand for highly-available operation + NOTE: External topology mode is not applicable for this field. + enum: + - HighlyAvailable + - SingleReplica + type: string + platform: + description: |- + platform is the underlying infrastructure provider for the cluster. + + Deprecated: Use platformStatus.type instead. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + platformStatus: + description: |- + platformStatus holds status information specific to the underlying + infrastructure provider. + properties: + alibabaCloud: + description: alibabaCloud contains settings specific to + the Alibaba Cloud infrastructure provider. + properties: + region: + description: region specifies the region for Alibaba + Cloud resources created for the cluster. + pattern: ^[0-9A-Za-z-]+$ + type: string + resourceGroupID: + description: resourceGroupID is the ID of the resource + group for the cluster. + pattern: ^(rg-[0-9A-Za-z]+)?$ + type: string + resourceTags: + description: resourceTags is a list of additional + tags to apply to Alibaba Cloud resources created + for the cluster. + items: + description: AlibabaCloudResourceTag is the set + of tags to add to apply to resources. + properties: + key: + description: key is the key of the tag. + maxLength: 128 + minLength: 1 + type: string + value: + description: value is the value of the tag. + maxLength: 128 + minLength: 1 + type: string + required: + - key + - value + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + required: + - region + type: object + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + region: + description: region holds the default AWS region for + new AWS resources created by the cluster. + type: string + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to AWS resources created for the cluster. + See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html for information on tagging AWS resources. + AWS supports a maximum of 50 tags per resource. OpenShift reserves 25 tags for its use, leaving 25 tags + available for the user. + items: + description: AWSResourceTag is a tag to apply to + AWS resources created for the cluster. + properties: + key: + description: |- + key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag. + Key should consist of between 1 and 128 characters, and may + contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: invalid AWS resource tag key. The + string can contain only the set of alphanumeric + characters, space (' '), '_', '.', '/', + '=', '+', '-', ':', '@' + rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$') + value: + description: |- + value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag. + Value should consist of between 1 and 256 characters, and may + contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'. + Some AWS service do not support empty values. Since tags are added to resources in many services, the + length of the tag value must meet the requirements of all services. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: invalid AWS resource tag value. The + string can contain only the set of alphanumeric + characters, space (' '), '_', '.', '/', + '=', '+', '-', ':', '@' + rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$') + required: + - key + - value + type: object + maxItems: 25 + type: array + x-kubernetes-list-type: atomic + serviceEndpoints: + description: |- + serviceEndpoints list contains custom endpoints which will override default + service endpoint of AWS Services. + There must be only one ServiceEndpoint for a service. + items: + description: |- + AWSServiceEndpoint store the configuration of a custom url to + override existing defaults of AWS Services. + properties: + name: + description: |- + name is the name of the AWS service. + The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html + This must be provided and cannot be empty. + pattern: ^[a-z0-9-]+$ + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + pattern: ^https:// + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + azure: + description: azure contains settings specific to the Azure + infrastructure provider. + properties: + armEndpoint: + description: armEndpoint specifies a URL to use for + resource management in non-soverign clouds such + as Azure Stack. + type: string + cloudName: + description: |- + cloudName is the name of the Azure cloud environment which can be used to configure the Azure SDK + with the appropriate Azure API endpoints. + If empty, the value is equal to `AzurePublicCloud`. + enum: + - "" + - AzurePublicCloud + - AzureUSGovernmentCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureStackCloud + type: string + networkResourceGroupName: + description: |- + networkResourceGroupName is the Resource Group for network resources like the Virtual Network and Subnets used by the cluster. + If empty, the value is same as ResourceGroupName. + type: string + resourceGroupName: + description: resourceGroupName is the Resource Group + for new Azure resources created for the cluster. + type: string + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to Azure resources created for the cluster. + See https://docs.microsoft.com/en-us/rest/api/resources/tags for information on tagging Azure resources. + Due to limitations on Automation, Content Delivery Network, DNS Azure resources, a maximum of 15 tags + may be applied. OpenShift reserves 5 tags for internal use, allowing 10 tags for user configuration. + items: + description: AzureResourceTag is a tag to apply + to Azure resources created for the cluster. + properties: + key: + description: |- + key is the key part of the tag. A tag key can have a maximum of 128 characters and cannot be empty. Key + must begin with a letter, end with a letter, number or underscore, and must contain only alphanumeric + characters and the following special characters `_ . -`. + maxLength: 128 + minLength: 1 + pattern: ^[a-zA-Z]([0-9A-Za-z_.-]*[0-9A-Za-z_])?$ + type: string + value: + description: |- + value is the value part of the tag. A tag value can have a maximum of 256 characters and cannot be empty. Value + must contain only alphanumeric characters and the following special characters `_ + , - . / : ; < = > ? @`. + maxLength: 256 + minLength: 1 + pattern: ^[0-9A-Za-z_.=+-@]+$ + type: string + required: + - key + - value + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: resourceTags are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + type: object + x-kubernetes-validations: + - message: resourceTags may only be configured during + installation + rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) + || has(oldSelf.resourceTags) && has(self.resourceTags)' + baremetal: + description: baremetal contains settings specific to the + BareMetal platform. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on BareMetal platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + BareMetal deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + equinixMetal: + description: equinixMetal contains settings specific to + the Equinix Metal infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + type: string + type: object + external: + description: external contains settings specific to the + generic External infrastructure provider. + properties: + cloudControllerManager: + description: |- + cloudControllerManager contains settings specific to the external Cloud Controller Manager (a.k.a. CCM or CPI). + When omitted, new nodes will be not tainted + and no extra initialization from the cloud controller manager is expected. + properties: + state: + description: |- + state determines whether or not an external Cloud Controller Manager is expected to + be installed within the cluster. + https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager + + Valid values are "External", "None" and omitted. + When set to "External", new nodes will be tainted as uninitialized when created, + preventing them from running workloads until they are initialized by the cloud controller manager. + When omitted or set to "None", new nodes will be not tainted + and no extra initialization from the cloud controller manager is expected. + enum: + - "" + - External + - None + type: string + x-kubernetes-validations: + - message: state is immutable once set + rule: self == oldSelf + type: object + x-kubernetes-validations: + - message: state may not be added or removed once + set + rule: (has(self.state) == has(oldSelf.state)) || + (!has(oldSelf.state) && self.state != "External") + type: object + x-kubernetes-validations: + - message: cloudControllerManager may not be added or + removed once set + rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager) + gcp: + description: gcp contains settings specific to the Google + Cloud Platform infrastructure provider. + properties: + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + nullable: true + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + projectID: + description: resourceGroupName is the Project ID for + new GCP resources created for the cluster. + type: string + region: + description: region holds the region for new GCP resources + created for the cluster. + type: string + resourceLabels: + description: |- + resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. + See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. + GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, + allowing 32 labels for user configuration. + items: + description: GCPResourceLabel is a label to apply + to GCP resources created for the cluster. + properties: + key: + description: |- + key is the key part of the label. A label key can have a maximum of 63 characters and cannot be empty. + Label key must begin with a lowercase letter, and must contain only lowercase letters, numeric characters, + and the following special characters `_-`. Label key must not have the reserved prefixes `kubernetes-io` + and `openshift-io`. + maxLength: 63 + minLength: 1 + pattern: ^[a-z][0-9a-z_-]{0,62}$ + type: string + x-kubernetes-validations: + - message: label keys must not start with either + `openshift-io` or `kubernetes-io` + rule: '!self.startsWith(''openshift-io'') + && !self.startsWith(''kubernetes-io'')' + value: + description: |- + value is the value part of the label. A label value can have a maximum of 63 characters and cannot be empty. + Value must contain only lowercase letters, numeric characters, and the following special characters `_-`. + maxLength: 63 + minLength: 1 + pattern: ^[0-9a-z_-]{1,63}$ + type: string + required: + - key + - value + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: resourceLabels are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to GCP resources created for the cluster. + See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on + tagging GCP resources. GCP supports a maximum of 50 tags per resource. + items: + description: GCPResourceTag is a tag to apply to + GCP resources created for the cluster. + properties: + key: + description: |- + key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot be empty. + Tag key must begin and end with an alphanumeric character, and must contain only uppercase, lowercase + alphanumeric characters, and the following special characters `._-`. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$ + type: string + parentID: + description: |- + parentID is the ID of the hierarchical resource where the tags are defined, + e.g. at the Organization or the Project level. To find the Organization or Project ID refer to the following pages: + https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id, + https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects. + An OrganizationID must consist of decimal numbers, and cannot have leading zeroes. + A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters, numbers, + and hyphens, and must start with a letter, and cannot end with a hyphen. + maxLength: 32 + minLength: 1 + pattern: (^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$) + type: string + value: + description: |- + value is the value part of the tag. A tag value can have a maximum of 63 characters and cannot be empty. + Tag value must begin and end with an alphanumeric character, and must contain only uppercase, lowercase + alphanumeric characters, and the following special characters `_-.@%=+:,*#&(){}[]` and spaces. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$ + type: string + required: + - key + - parentID + - value + type: object + maxItems: 50 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: resourceTags are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + type: object + x-kubernetes-validations: + - message: resourceLabels may only be configured during + installation + rule: '!has(oldSelf.resourceLabels) && !has(self.resourceLabels) + || has(oldSelf.resourceLabels) && has(self.resourceLabels)' + - message: resourceTags may only be configured during + installation + rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) + || has(oldSelf.resourceTags) && has(self.resourceTags)' + ibmcloud: + description: ibmcloud contains settings specific to the + IBMCloud infrastructure provider. + properties: + cisInstanceCRN: + description: |- + cisInstanceCRN is the CRN of the Cloud Internet Services instance managing + the DNS zone for the cluster's base domain + type: string + dnsInstanceCRN: + description: |- + dnsInstanceCRN is the CRN of the DNS Services instance managing the DNS zone + for the cluster's base domain + type: string + location: + description: location is where the cluster has been + deployed + type: string + providerType: + description: providerType indicates the type of cluster + that was created + type: string + resourceGroupName: + description: resourceGroupName is the Resource Group + for new IBMCloud resources created for the cluster. + type: string + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of an IBM service. These endpoints are used by components + within the cluster when trying to reach the IBM Cloud Services that have been + overridden. The CCCMO reads in the IBMCloudPlatformSpec and validates each + endpoint is resolvable. Once validated, the cloud config and IBMCloudPlatformStatus + are updated to reflect the same custom endpoints. + items: + description: |- + IBMCloudServiceEndpoint stores the configuration of a custom url to + override existing defaults of IBM Cloud Services. + properties: + name: + description: |- + name is the name of the IBM Cloud service. + Possible values are: CIS, COS, COSConfig, DNSServices, GlobalCatalog, GlobalSearch, GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController, ResourceManager, or VPC. + For example, the IBM Cloud Private IAM service could be configured with the + service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` + Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured + with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com` + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. The path must follow the pattern + /v[0,9]+ or /api/v[0,9]+ + maxLength: 300 + type: string + x-kubernetes-validations: + - message: url must be a valid absolute URL + rule: isURL(self) + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + kubevirt: + description: kubevirt contains settings specific to the + kubevirt infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + type: string + type: object + nutanix: + description: nutanix contains settings specific to the + Nutanix infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on Nutanix platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + type: object + openstack: + description: openstack contains settings specific to the + OpenStack infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + cloudName: + description: |- + cloudName is the name of the desired OpenStack cloud in the + client configuration file (`clouds.yaml`). + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on OpenStack platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + OpenStack deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + ovirt: + description: ovirt contains settings specific to the oVirt + infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on Ovirt platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + nodeDNSIP: + description: 'deprecated: as of 4.6, this field is + no longer set or honored. It will be removed in + a future release.' + type: string + type: object + powervs: + description: powervs contains settings specific to the + Power Systems Virtual Servers infrastructure provider. + properties: + cisInstanceCRN: + description: |- + cisInstanceCRN is the CRN of the Cloud Internet Services instance managing + the DNS zone for the cluster's base domain + type: string + dnsInstanceCRN: + description: |- + dnsInstanceCRN is the CRN of the DNS Services instance managing the DNS zone + for the cluster's base domain + type: string + region: + description: region holds the default Power VS region + for new Power VS resources created by the cluster. + type: string + resourceGroup: + description: |- + resourceGroup is the resource group name for new IBMCloud resources created for a cluster. + The resource group specified here will be used by cluster-image-registry-operator to set up a COS Instance in IBMCloud for the cluster registry. + More about resource groups can be found here: https://cloud.ibm.com/docs/account?topic=account-rgs. + When omitted, the image registry operator won't be able to configure storage, + which results in the image registry cluster operator not being in an available state. + maxLength: 40 + pattern: ^[a-zA-Z0-9-_ ]+$ + type: string + x-kubernetes-validations: + - message: resourceGroup is immutable once set + rule: oldSelf == '' || self == oldSelf + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of a Power VS service. + items: + description: |- + PowervsServiceEndpoint stores the configuration of a custom url to + override existing defaults of PowerVS Services. + properties: + name: + description: |- + name is the name of the Power VS service. + Few of the services are + IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api + ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller + Power Cloud - https://cloud.ibm.com/apidocs/power-cloud + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - Power + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + format: uri + pattern: ^https:// + type: string + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + zone: + description: |- + zone holds the default zone for the new Power VS resources created by the cluster. + Note: Currently only single-zone OCP clusters are supported + type: string + type: object + x-kubernetes-validations: + - message: cannot unset resourceGroup once set + rule: '!has(oldSelf.resourceGroup) || has(self.resourceGroup)' + type: + description: |- + type is the underlying infrastructure provider for the cluster. This + value controls whether infrastructure automation such as service load + balancers, dynamic volume provisioning, machine creation and deletion, and + other integrations are enabled. If None, no infrastructure automation is + enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "EquinixMetal", "PowerVS", "AlibabaCloud", "Nutanix" and "None". + Individual components may not support all platforms, and must handle + unrecognized platforms as None if they do not support that platform. + + This value will be synced with to the `status.platform` and `status.platformStatus.type`. + Currently this value cannot be changed once set. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + vsphere: + description: vsphere contains settings specific to the + VSphere infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on VSphere platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + vSphere deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + type: object + type: object + required: + - spec + type: object + x-kubernetes-embedded-resource: true + internalRegistryPullSecret: + description: |- + internalRegistryPullSecret is the pull secret for the internal registry, used by + rpm-ostree to pull images from the internal registry if present + format: byte + nullable: true + type: string + ipFamilies: + description: ipFamilies indicates the IP families in use by the cluster + network + type: string + kubeAPIServerServingCAData: + description: kubeAPIServerServingCAData managed Kubelet to API Server + Cert... Rotated automatically + format: byte + type: string + network: + description: network contains additional network related information + nullable: true + properties: + mtuMigration: + description: mtuMigration contains the MTU migration configuration. + nullable: true + properties: + machine: + description: machine contains MTU migration configuration + for the machine's uplink. + properties: + from: + description: from is the MTU to migrate from. + format: int32 + minimum: 0 + type: integer + to: + description: to is the MTU to migrate to. + format: int32 + minimum: 0 + type: integer + type: object + network: + description: network contains MTU migration configuration + for the default network. + properties: + from: + description: from is the MTU to migrate from. + format: int32 + minimum: 0 + type: integer + to: + description: to is the MTU to migrate to. + format: int32 + minimum: 0 + type: integer + type: object + type: object + required: + - mtuMigration + type: object + networkType: + description: |- + networkType holds the type of network the cluster is using + XXX: this is temporary and will be dropped as soon as possible in favor of a better support + to start network related services the proper way. + Nobody is also changing this once the cluster is up and running the first time, so, disallow + regeneration if this changes. + type: string + osImageURL: + description: osImageURL is the old-format container image that contains + the OS update payload. + type: string + platform: + description: platform is deprecated, use Infra.Status.PlatformStatus.Type + instead + type: string + proxy: + description: proxy holds the current proxy configuration for the nodes + nullable: true + properties: + httpProxy: + description: httpProxy is the URL of the proxy for HTTP requests. + type: string + httpsProxy: + description: httpsProxy is the URL of the proxy for HTTPS requests. + type: string + noProxy: + description: noProxy is a comma-separated list of hostnames and/or + CIDRs for which the proxy should not be used. + type: string + type: object + pullSecret: + description: |- + pullSecret is the default pull secret that needs to be installed + on all machines. + 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. + 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 + releaseImage: + description: releaseImage is the image used when installing the cluster + type: string + rootCAData: + description: rootCAData specifies the root CA data + format: byte + type: string + required: + - additionalTrustBundle + - baseOSContainerImage + - cloudProviderCAData + - cloudProviderConfig + - clusterDNSIP + - dns + - images + - infra + - ipFamilies + - kubeAPIServerServingCAData + - network + - proxy + - releaseImage + - rootCAData + type: object + status: + description: status contains observed information about the controller + config. + properties: + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: ControllerConfigStatusCondition contains condition + information for ControllerConfigStatus + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + nullable: true + type: string + message: + description: |- + message provides additional information about the current condition. + This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are PascalCase + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerCertificates: + description: controllerCertificates represents the latest available + observations of the automatically rotating certificates in the MCO. + items: + description: ControllerCertificate contains info about a specific + cert. + properties: + bundleFile: + description: bundleFile is the larger bundle a cert comes from + type: string + notAfter: + description: notAfter is the upper boundary for validity + format: date-time + type: string + notBefore: + description: notBefore is the lower boundary for validity + format: date-time + type: string + signer: + description: signer is the cert Issuer + type: string + subject: + description: subject is the cert subject + type: string + required: + - bundleFile + - signer + - subject + type: object + type: array + x-kubernetes-list-type: atomic + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_controllerconfigs-DevPreviewNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_controllerconfigs-DevPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000..f6b3281 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_controllerconfigs-DevPreviewNoUpgrade.crd.yaml @@ -0,0 +1,3311 @@ +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" + release.openshift.io/feature-set: DevPreviewNoUpgrade + labels: + openshift.io/operator-managed: "" + name: controllerconfigs.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: ControllerConfig + listKind: ControllerConfigList + plural: controllerconfigs + singular: controllerconfig + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + ControllerConfig describes configuration for MachineConfigController. + This is currently only used to drive the MachineConfig objects generated by the TemplateController. + + 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: spec contains the desired controller config configuration. + properties: + additionalTrustBundle: + description: |- + additionalTrustBundle is a certificate bundle that will be added to the nodes + trusted certificate store. + format: byte + nullable: true + type: string + baseOSContainerImage: + description: baseOSContainerImage is the new-format container image + for operating system updates. + type: string + baseOSExtensionsContainerImage: + description: baseOSExtensionsContainerImage is the matching extensions + container for the new-format container + type: string + cloudProviderCAData: + description: cloudProviderCAData specifies the cloud provider CA data + format: byte + nullable: true + type: string + cloudProviderConfig: + description: cloudProviderConfig is the configuration for the given + cloud provider + type: string + clusterDNSIP: + description: clusterDNSIP is the cluster DNS IP address + type: string + dns: + description: dns holds the cluster dns details + nullable: true + 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: + description: |- + metadata is the standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + type: object + spec: + description: spec holds user settable values for configuration + properties: + baseDomain: + description: |- + baseDomain is the base domain of the cluster. All managed DNS records will + be sub-domains of this base. + + For example, given the base domain `openshift.example.com`, an API server + DNS record may be created for `cluster-api.openshift.example.com`. + + Once set, this field cannot be changed. + type: string + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for DNS. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + properties: + aws: + description: aws contains DNS configuration specific to + the Amazon Web Services cloud provider. + properties: + privateZoneIAMRole: + description: |- + privateZoneIAMRole contains the ARN of an IAM role that should be assumed when performing + operations on the cluster's private hosted zone specified in the cluster DNS config. + When left empty, no role should be assumed. + pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$ + type: string + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + Allowed values: "", "AWS". + + Individual components may not support all platforms, + and must handle unrecognized platforms with best-effort defaults. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + x-kubernetes-validations: + - message: allowed values are '' and 'AWS' + rule: self in ['','AWS'] + required: + - type + type: object + x-kubernetes-validations: + - message: aws configuration is required when platform is + AWS, and forbidden otherwise + rule: 'has(self.type) && self.type == ''AWS'' ? has(self.aws) + : !has(self.aws)' + privateZone: + description: |- + privateZone is the location where all the DNS records that are only available internally + to the cluster exist. + + If this field is nil, no private records should be created. + + Once set, this field cannot be changed. + properties: + id: + description: |- + id is the identifier that can be used to find the DNS hosted zone. + + on AWS zone can be fetched using `ID` as id in [1] + on Azure zone can be fetched using `ID` as a pre-determined name in [2], + on GCP zone can be fetched using `ID` as a pre-determined name in [3]. + + [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options + [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show + [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get + type: string + tags: + additionalProperties: + type: string + description: |- + tags can be used to query the DNS hosted zone. + + on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, + + [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options + type: object + type: object + publicZone: + description: |- + publicZone is the location where all the DNS records that are publicly accessible to + the internet exist. + + If this field is nil, no public records should be created. + + Once set, this field cannot be changed. + properties: + id: + description: |- + id is the identifier that can be used to find the DNS hosted zone. + + on AWS zone can be fetched using `ID` as id in [1] + on Azure zone can be fetched using `ID` as a pre-determined name in [2], + on GCP zone can be fetched using `ID` as a pre-determined name in [3]. + + [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options + [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show + [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get + type: string + tags: + additionalProperties: + type: string + description: |- + tags can be used to query the DNS hosted zone. + + on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, + + [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options + type: object + type: object + type: object + status: + description: status holds observed values from the cluster. They + may not be overridden. + type: object + required: + - spec + type: object + x-kubernetes-embedded-resource: true + etcdDiscoveryDomain: + description: etcdDiscoveryDomain is deprecated, use Infra.Status.EtcdDiscoveryDomain + instead + type: string + imageRegistryBundleData: + description: imageRegistryBundleData is the ImageRegistryData + items: + description: ImageRegistryBundle contains information for writing + image registry certificates + properties: + data: + description: data holds the contents of the bundle that will + be written to the file location + format: byte + type: string + file: + description: file holds the name of the file where the bundle + will be written to disk + type: string + required: + - data + - file + type: object + type: array + x-kubernetes-list-type: atomic + imageRegistryBundleUserData: + description: imageRegistryBundleUserData is Image Registry Data provided + by the user + items: + description: ImageRegistryBundle contains information for writing + image registry certificates + properties: + data: + description: data holds the contents of the bundle that will + be written to the file location + format: byte + type: string + file: + description: file holds the name of the file where the bundle + will be written to disk + type: string + required: + - data + - file + type: object + type: array + x-kubernetes-list-type: atomic + images: + additionalProperties: + type: string + description: images is map of images that are used by the controller + to render templates under ./templates/ + type: object + infra: + description: infra holds the infrastructure details + nullable: true + 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: + description: |- + metadata is the standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + type: object + spec: + description: spec holds user settable values for configuration + properties: + cloudConfig: + description: |- + cloudConfig is a reference to a ConfigMap containing the cloud provider configuration file. + This configuration file is used to configure the Kubernetes cloud provider integration + when using the built-in cloud provider integration or the external cloud controller manager. + The namespace for this config map is openshift-config. + + cloudConfig should only be consumed by the kube_cloud_config controller. + The controller is responsible for using the user configuration in the spec + for various platforms and combining that with the user provided ConfigMap in this field + to create a stitched kube cloud config. + The controller generates a ConfigMap `kube-cloud-config` in `openshift-config-managed` namespace + with the kube cloud config is stored in `cloud.conf` key. + All the clients are expected to use the generated ConfigMap only. + properties: + key: + description: key allows pointing to a specific key/value + inside of the configmap. This is useful for logical + file references. + type: string + name: + type: string + type: object + platformSpec: + description: |- + platformSpec holds desired information specific to the underlying + infrastructure provider. + properties: + alibabaCloud: + description: alibabaCloud contains settings specific to + the Alibaba Cloud infrastructure provider. + type: object + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints list contains custom endpoints which will override default + service endpoint of AWS Services. + There must be only one ServiceEndpoint for a service. + items: + description: |- + AWSServiceEndpoint store the configuration of a custom url to + override existing defaults of AWS Services. + properties: + name: + description: |- + name is the name of the AWS service. + The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html + This must be provided and cannot be empty. + pattern: ^[a-z0-9-]+$ + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + pattern: ^https:// + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + azure: + description: azure contains settings specific to the Azure + infrastructure provider. + type: object + baremetal: + description: baremetal contains settings specific to the + BareMetal platform. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + equinixMetal: + description: equinixMetal contains settings specific to + the Equinix Metal infrastructure provider. + type: object + external: + description: |- + ExternalPlatformType represents generic infrastructure provider. + Platform-specific components should be supplemented separately. + properties: + platformName: + default: Unknown + description: |- + platformName holds the arbitrary string representing the infrastructure provider name, expected to be set at the installation time. + This field is solely for informational and reporting purposes and is not expected to be used for decision-making. + type: string + x-kubernetes-validations: + - message: platform name cannot be changed once set + rule: oldSelf == 'Unknown' || self == oldSelf + type: object + gcp: + description: gcp contains settings specific to the Google + Cloud Platform infrastructure provider. + type: object + ibmcloud: + description: ibmcloud contains settings specific to the + IBMCloud infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of an IBM service. These endpoints are used by components + within the cluster when trying to reach the IBM Cloud Services that have been + overridden. The CCCMO reads in the IBMCloudPlatformSpec and validates each + endpoint is resolvable. Once validated, the cloud config and IBMCloudPlatformStatus + are updated to reflect the same custom endpoints. + A maximum of 13 service endpoints overrides are supported. + items: + description: |- + IBMCloudServiceEndpoint stores the configuration of a custom url to + override existing defaults of IBM Cloud Services. + properties: + name: + description: |- + name is the name of the IBM Cloud service. + Possible values are: CIS, COS, COSConfig, DNSServices, GlobalCatalog, GlobalSearch, GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController, ResourceManager, or VPC. + For example, the IBM Cloud Private IAM service could be configured with the + service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` + Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured + with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com` + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. The path must follow the pattern + /v[0,9]+ or /api/v[0,9]+ + maxLength: 300 + type: string + x-kubernetes-validations: + - message: url must use https scheme + rule: url(self).getScheme() == "https" + - message: url path must match /v[0,9]+ or /api/v[0,9]+ + rule: matches((url(self).getEscapedPath()), + '^/(api/)?v[0-9]+/{0,1}$') + - message: url must be a valid absolute URL + rule: isURL(self) + required: + - name + - url + type: object + maxItems: 13 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + kubevirt: + description: kubevirt contains settings specific to the + kubevirt infrastructure provider. + type: object + nutanix: + description: nutanix contains settings specific to the + Nutanix infrastructure provider. + properties: + failureDomains: + description: |- + failureDomains configures failure domains information for the Nutanix platform. + When set, the failure domains defined here may be used to spread Machines across + prism element clusters to improve fault tolerance of the cluster. + items: + description: NutanixFailureDomain configures failure + domain information for the Nutanix platform. + properties: + cluster: + description: |- + cluster is to identify the cluster (the Prism Element under management of the Prism Central), + in which the Machine's VM will be created. The cluster identifier (uuid or name) can be obtained + from the Prism Central console or using the prism_central API. + properties: + name: + description: name is the resource name in + the PC. It cannot be empty if the type + is Name. + type: string + type: + description: type is the identifier type + to use for this resource. + enum: + - UUID + - Name + type: string + uuid: + description: uuid is the UUID of the resource + in the PC. It cannot be empty if the type + is UUID. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: uuid configuration is required when + type is UUID, and forbidden otherwise + rule: 'has(self.type) && self.type == ''UUID'' + ? has(self.uuid) : !has(self.uuid)' + - message: name configuration is required when + type is Name, and forbidden otherwise + rule: 'has(self.type) && self.type == ''Name'' + ? has(self.name) : !has(self.name)' + name: + description: |- + name defines the unique name of a failure domain. + Name is required and must be at most 64 characters in length. + It must consist of only lower case alphanumeric characters and hyphens (-). + It must start and end with an alphanumeric character. + This value is arbitrary and is used to identify the failure domain within the platform. + maxLength: 64 + minLength: 1 + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?' + type: string + subnets: + description: |- + subnets holds a list of identifiers (one or more) of the cluster's network subnets + If the feature gate NutanixMultiSubnets is enabled, up to 32 subnets may be configured. + for the Machine's VM to connect to. The subnet identifiers (uuid or name) can be + obtained from the Prism Central console or using the prism_central API. + items: + description: NutanixResourceIdentifier holds + the identity of a Nutanix PC resource (cluster, + image, subnet, etc.) + properties: + name: + description: name is the resource name + in the PC. It cannot be empty if the + type is Name. + type: string + type: + description: type is the identifier type + to use for this resource. + enum: + - UUID + - Name + type: string + uuid: + description: uuid is the UUID of the resource + in the PC. It cannot be empty if the + type is UUID. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: uuid configuration is required + when type is UUID, and forbidden otherwise + rule: 'has(self.type) && self.type == ''UUID'' + ? has(self.uuid) : !has(self.uuid)' + - message: name configuration is required + when type is Name, and forbidden otherwise + rule: 'has(self.type) && self.type == ''Name'' + ? has(self.name) : !has(self.name)' + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: each subnet must be unique + rule: self.all(x, self.exists_one(y, x == + y)) + required: + - cluster + - name + - subnets + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + prismCentral: + description: |- + prismCentral holds the endpoint address and port to access the Nutanix Prism Central. + When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. + Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the + proxy spec.noProxy list. + properties: + address: + description: address is the endpoint address (DNS + name or IP address) of the Nutanix Prism Central + or Element (cluster) + maxLength: 256 + type: string + port: + description: port is the port number to access + the Nutanix Prism Central or Element (cluster) + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + prismElements: + description: |- + prismElements holds one or more endpoint address and port data to access the Nutanix + Prism Elements (clusters) of the Nutanix Prism Central. Currently we only support one + Prism Element (cluster) for an OpenShift cluster, where all the Nutanix resources (VMs, subnets, volumes, etc.) + used in the OpenShift cluster are located. In the future, we may support Nutanix resources (VMs, etc.) + spread over multiple Prism Elements (clusters) of the Prism Central. + items: + description: NutanixPrismElementEndpoint holds the + name and endpoint data for a Prism Element (cluster) + properties: + endpoint: + description: |- + endpoint holds the endpoint address and port data of the Prism Element (cluster). + When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. + Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the + proxy spec.noProxy list. + properties: + address: + description: address is the endpoint address + (DNS name or IP address) of the Nutanix + Prism Central or Element (cluster) + maxLength: 256 + type: string + port: + description: port is the port number to + access the Nutanix Prism Central or Element + (cluster) + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + name: + description: |- + name is the name of the Prism Element (cluster). This value will correspond with + the cluster field configured on other resources (eg Machines, PVCs, etc). + maxLength: 256 + type: string + required: + - endpoint + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - prismCentral + - prismElements + type: object + openstack: + description: openstack contains settings specific to the + OpenStack infrastructure provider. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + ovirt: + description: ovirt contains settings specific to the oVirt + infrastructure provider. + type: object + powervs: + description: powervs contains settings specific to the + IBM Power Systems Virtual Servers infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of a Power VS service. + items: + description: |- + PowervsServiceEndpoint stores the configuration of a custom url to + override existing defaults of PowerVS Services. + properties: + name: + description: |- + name is the name of the Power VS service. + Few of the services are + IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api + ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller + Power Cloud - https://cloud.ibm.com/apidocs/power-cloud + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - Power + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + format: uri + pattern: ^https:// + type: string + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. This + value controls whether infrastructure automation such as service load + balancers, dynamic volume provisioning, machine creation and deletion, and + other integrations are enabled. If None, no infrastructure automation is + enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + and must handle unrecognized platforms as None if they do not support that platform. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + vsphere: + description: vsphere contains settings specific to the + VSphere infrastructure provider. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + failureDomains: + description: |- + failureDomains contains the definition of region, zone and the vCenter topology. + If this is omitted failure domains (regions and zones) will not be used. + items: + description: VSpherePlatformFailureDomainSpec holds + the region and zone failure domain and the vCenter + topology of that failure domain. + properties: + name: + description: |- + name defines the arbitrary but unique name + of a failure domain. + maxLength: 256 + minLength: 1 + type: string + region: + description: |- + region defines the name of a region tag that will + be attached to a vCenter datacenter. The tag + category in vCenter must be named openshift-region. + maxLength: 80 + minLength: 1 + type: string + regionAffinity: + description: |- + regionAffinity holds the type of region, Datacenter or ComputeCluster. + When set to Datacenter, this means the region is a vCenter Datacenter as defined in topology. + When set to ComputeCluster, this means the region is a vCenter Cluster as defined in topology. + properties: + type: + description: |- + type determines the vSphere object type for a region within this failure domain. + Available types are Datacenter and ComputeCluster. + When set to Datacenter, this means the vCenter Datacenter defined is the region. + When set to ComputeCluster, this means the vCenter cluster defined is the region. + enum: + - ComputeCluster + - Datacenter + type: string + required: + - type + type: object + server: + description: server is the fully-qualified domain + name or the IP address of the vCenter server. + maxLength: 255 + minLength: 1 + type: string + topology: + description: topology describes a given failure + domain using vSphere constructs + properties: + computeCluster: + description: |- + computeCluster the absolute path of the vCenter cluster + in which virtual machine will be located. + The absolute path is of the form //host/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/host/.*? + type: string + datacenter: + description: |- + datacenter is the name of vCenter datacenter in which virtual machines will be located. + The maximum length of the datacenter name is 80 characters. + maxLength: 80 + type: string + datastore: + description: |- + datastore is the absolute path of the datastore in which the + virtual machine is located. + The absolute path is of the form //datastore/ + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/datastore/.*? + type: string + folder: + description: |- + folder is the absolute path of the folder where + virtual machines are located. The absolute path + is of the form //vm/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/vm/.*? + type: string + networks: + description: |- + networks is the list of port group network names within this failure domain. + If feature gate VSphereMultiNetworks is enabled, up to 10 network adapters may be defined. + 10 is the maximum number of virtual network devices which may be attached to a VM as defined by: + https://configmax.esp.vmware.com/guest?vmwareproduct=vSphere&release=vSphere%208.0&categories=1-0 + The available networks (port groups) can be listed using + `govc ls 'network/*'` + Networks should be in the form of an absolute path: + //network/. + items: + type: string + maxItems: 10 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + resourcePool: + description: |- + resourcePool is the absolute path of the resource pool where virtual machines will be + created. The absolute path is of the form //host//Resources/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/host/.*?/Resources.* + type: string + template: + description: |- + template is the full inventory path of the virtual machine or template + that will be cloned when creating new machines in this failure domain. + The maximum length of the path is 2048 characters. + + When omitted, the template will be calculated by the control plane + machineset operator based on the region and zone defined in + VSpherePlatformFailureDomainSpec. + For example, for zone=zonea, region=region1, and infrastructure name=test, + the template path would be calculated as //vm/test-rhcos-region1-zonea. + maxLength: 2048 + minLength: 1 + pattern: ^/.*?/vm/.*? + type: string + required: + - computeCluster + - datacenter + - datastore + - networks + type: object + zone: + description: |- + zone defines the name of a zone tag that will + be attached to a vCenter cluster. The tag + category in vCenter must be named openshift-zone. + maxLength: 80 + minLength: 1 + type: string + zoneAffinity: + description: |- + zoneAffinity holds the type of the zone and the hostGroup which + vmGroup and the hostGroup names in vCenter corresponds to + a vm-host group of type Virtual Machine and Host respectively. Is also + contains the vmHostRule which is an affinity vm-host rule in vCenter. + properties: + hostGroup: + description: |- + hostGroup holds the vmGroup and the hostGroup names in vCenter + corresponds to a vm-host group of type Virtual Machine and Host respectively. Is also + contains the vmHostRule which is an affinity vm-host rule in vCenter. + properties: + hostGroup: + description: |- + hostGroup is the name of the vm-host group of type host within vCenter for this failure domain. + hostGroup is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + vmGroup: + description: |- + vmGroup is the name of the vm-host group of type virtual machine within vCenter for this failure domain. + vmGroup is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + vmHostRule: + description: |- + vmHostRule is the name of the affinity vm-host rule within vCenter for this failure domain. + vmHostRule is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + required: + - hostGroup + - vmGroup + - vmHostRule + type: object + type: + description: |- + type determines the vSphere object type for a zone within this failure domain. + Available types are ComputeCluster and HostGroup. + When set to ComputeCluster, this means the vCenter cluster defined is the zone. + When set to HostGroup, hostGroup must be configured with hostGroup, vmGroup and vmHostRule and + this means the zone is defined by the grouping of those fields. + enum: + - HostGroup + - ComputeCluster + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: hostGroup is required when type is + HostGroup, and forbidden otherwise + rule: 'has(self.type) && self.type == ''HostGroup'' + ? has(self.hostGroup) : !has(self.hostGroup)' + required: + - name + - region + - server + - topology + - zone + type: object + x-kubernetes-validations: + - message: when zoneAffinity type is HostGroup, + regionAffinity type must be ComputeCluster + rule: 'has(self.zoneAffinity) && self.zoneAffinity.type + == ''HostGroup'' ? has(self.regionAffinity) + && self.regionAffinity.type == ''ComputeCluster'' + : true' + - message: when zoneAffinity type is ComputeCluster, + regionAffinity type must be Datacenter + rule: 'has(self.zoneAffinity) && self.zoneAffinity.type + == ''ComputeCluster'' ? has(self.regionAffinity) + && self.regionAffinity.type == ''Datacenter'' + : true' + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeNetworking: + description: |- + nodeNetworking contains the definition of internal and external network constraints for + assigning the node's networking. + If this field is omitted, networking defaults to the legacy + address selection behavior which is to only support a single address and + return the first one found. + properties: + external: + description: external represents the network configuration + of the node that is externally routable. + properties: + excludeNetworkSubnetCidr: + description: |- + excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting + the IP address from the VirtualMachine's VM for use in the status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: atomic + network: + description: |- + network VirtualMachine's VM Network names that will be used to when searching + for status.addresses fields. Note that if internal.networkSubnetCIDR and + external.networkSubnetCIDR are not set, then the vNIC associated to this network must + only have a single IP address assigned to it. + The available networks (port groups) can be listed using + `govc ls 'network/*'` + type: string + networkSubnetCidr: + description: |- + networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs + that will be used in respective status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: set + type: object + internal: + description: internal represents the network configuration + of the node that is routable only within the + cluster. + properties: + excludeNetworkSubnetCidr: + description: |- + excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting + the IP address from the VirtualMachine's VM for use in the status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: atomic + network: + description: |- + network VirtualMachine's VM Network names that will be used to when searching + for status.addresses fields. Note that if internal.networkSubnetCIDR and + external.networkSubnetCIDR are not set, then the vNIC associated to this network must + only have a single IP address assigned to it. + The available networks (port groups) can be listed using + `govc ls 'network/*'` + type: string + networkSubnetCidr: + description: |- + networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs + that will be used in respective status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: set + type: object + type: object + vcenters: + description: |- + vcenters holds the connection details for services to communicate with vCenter. + Currently, only a single vCenter is supported, but in tech preview 3 vCenters are supported. + Once the cluster has been installed, you are unable to change the current number of defined + vCenters except in the case where the cluster has been upgraded from a version of OpenShift + where the vsphere platform spec was not present. You may make modifications to the existing + vCenters that are defined in the vcenters list in order to match with any added or modified + failure domains. + items: + description: |- + VSpherePlatformVCenterSpec stores the vCenter connection fields. + This is used by the vSphere CCM. + properties: + datacenters: + description: |- + The vCenter Datacenters in which the RHCOS + vm guests are located. This field will + be used by the Cloud Controller Manager. + Each datacenter listed here should be used within + a topology. + items: + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + port: + description: |- + port is the TCP port that will be used to communicate to + the vCenter endpoint. + When omitted, this means the user has no opinion and + it is up to the platform to choose a sensible default, + which is subject to change over time. + format: int32 + maximum: 32767 + minimum: 1 + type: integer + server: + description: server is the fully-qualified domain + name or the IP address of the vCenter server. + maxLength: 255 + type: string + required: + - datacenters + - server + type: object + maxItems: 3 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: vcenters cannot be added or removed once + set + rule: 'size(self) != size(oldSelf) ? size(oldSelf) + == 0 && size(self) < 2 : true' + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + - message: vcenters can have at most 1 item when configured + post-install + rule: '!has(oldSelf.vcenters) && has(self.vcenters) + ? size(self.vcenters) < 2 : true' + type: object + x-kubernetes-validations: + - message: vcenters can have at most 1 item when configured + post-install + rule: '!has(oldSelf.vsphere) && has(self.vsphere) ? size(self.vsphere.vcenters) + < 2 : true' + type: object + status: + description: status holds observed values from the cluster. They + may not be overridden. + properties: + apiServerInternalURI: + description: |- + apiServerInternalURL is a valid URI with scheme 'https', + address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components + like kubelets, to contact the Kubernetes API server using the + infrastructure provider rather than Kubernetes networking. + type: string + apiServerURL: + description: |- + apiServerURL is a valid URI with scheme 'https', address and + optionally a port (defaulting to 443). apiServerURL can be used by components like the web console + to tell users where to find the Kubernetes API. + type: string + controlPlaneTopology: + default: HighlyAvailable + description: |- + controlPlaneTopology expresses the expectations for operands that normally run on control nodes. + The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. + The 'SingleReplica' mode will be used in single-node deployments + and the operators should not configure the operand for highly-available operation + The 'External' mode indicates that the control plane is hosted externally to the cluster and that + its components are not visible within the cluster. + enum: + - HighlyAvailable + - HighlyAvailableArbiter + - SingleReplica + - DualReplica + - External + type: string + cpuPartitioning: + default: None + description: |- + cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. + CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. + Valid values are "None" and "AllNodes". When omitted, the default value is "None". + The default value of "None" indicates that no nodes will be setup with CPU partitioning. + The "AllNodes" value indicates that all nodes have been setup with CPU partitioning, + and can then be further configured via the PerformanceProfile API. + enum: + - None + - AllNodes + type: string + etcdDiscoveryDomain: + description: |- + etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering + etcd servers and clients. + For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery + deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release. + type: string + infrastructureName: + description: |- + infrastructureName uniquely identifies a cluster with a human friendly name. + Once set it should not be changed. Must be of max length 27 and must have only + alphanumeric or hyphen characters. + type: string + infrastructureTopology: + default: HighlyAvailable + description: |- + infrastructureTopology expresses the expectations for infrastructure services that do not run on control + plane nodes, usually indicated by a node selector for a `role` value + other than `master`. + The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. + The 'SingleReplica' mode will be used in single-node deployments + and the operators should not configure the operand for highly-available operation + NOTE: External topology mode is not applicable for this field. + enum: + - HighlyAvailable + - SingleReplica + type: string + platform: + description: |- + platform is the underlying infrastructure provider for the cluster. + + Deprecated: Use platformStatus.type instead. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + platformStatus: + description: |- + platformStatus holds status information specific to the underlying + infrastructure provider. + properties: + alibabaCloud: + description: alibabaCloud contains settings specific to + the Alibaba Cloud infrastructure provider. + properties: + region: + description: region specifies the region for Alibaba + Cloud resources created for the cluster. + pattern: ^[0-9A-Za-z-]+$ + type: string + resourceGroupID: + description: resourceGroupID is the ID of the resource + group for the cluster. + pattern: ^(rg-[0-9A-Za-z]+)?$ + type: string + resourceTags: + description: resourceTags is a list of additional + tags to apply to Alibaba Cloud resources created + for the cluster. + items: + description: AlibabaCloudResourceTag is the set + of tags to add to apply to resources. + properties: + key: + description: key is the key of the tag. + maxLength: 128 + minLength: 1 + type: string + value: + description: value is the value of the tag. + maxLength: 128 + minLength: 1 + type: string + required: + - key + - value + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + required: + - region + type: object + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + nullable: true + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + ipFamily: + default: IPv4 + description: |- + ipFamily specifies the IP protocol family that should be used for AWS + network resources. This controls whether AWS resources are created with + IPv4-only, or dual-stack networking with IPv4 or IPv6 as the primary + protocol family. + enum: + - IPv4 + - DualStackIPv6Primary + - DualStackIPv4Primary + type: string + x-kubernetes-validations: + - message: ipFamily is immutable once set + rule: oldSelf == '' || self == oldSelf + region: + description: region holds the default AWS region for + new AWS resources created by the cluster. + type: string + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to AWS resources created for the cluster. + See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html for information on tagging AWS resources. + AWS supports a maximum of 50 tags per resource. OpenShift reserves 25 tags for its use, leaving 25 tags + available for the user. + items: + description: AWSResourceTag is a tag to apply to + AWS resources created for the cluster. + properties: + key: + description: |- + key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag. + Key should consist of between 1 and 128 characters, and may + contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: invalid AWS resource tag key. The + string can contain only the set of alphanumeric + characters, space (' '), '_', '.', '/', + '=', '+', '-', ':', '@' + rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$') + value: + description: |- + value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag. + Value should consist of between 1 and 256 characters, and may + contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'. + Some AWS service do not support empty values. Since tags are added to resources in many services, the + length of the tag value must meet the requirements of all services. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: invalid AWS resource tag value. The + string can contain only the set of alphanumeric + characters, space (' '), '_', '.', '/', + '=', '+', '-', ':', '@' + rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$') + required: + - key + - value + type: object + maxItems: 25 + type: array + x-kubernetes-list-type: atomic + serviceEndpoints: + description: |- + serviceEndpoints list contains custom endpoints which will override default + service endpoint of AWS Services. + There must be only one ServiceEndpoint for a service. + items: + description: |- + AWSServiceEndpoint store the configuration of a custom url to + override existing defaults of AWS Services. + properties: + name: + description: |- + name is the name of the AWS service. + The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html + This must be provided and cannot be empty. + pattern: ^[a-z0-9-]+$ + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + pattern: ^https:// + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + azure: + description: azure contains settings specific to the Azure + infrastructure provider. + properties: + armEndpoint: + description: armEndpoint specifies a URL to use for + resource management in non-soverign clouds such + as Azure Stack. + type: string + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + cloudName: + description: |- + cloudName is the name of the Azure cloud environment which can be used to configure the Azure SDK + with the appropriate Azure API endpoints. + If empty, the value is equal to `AzurePublicCloud`. + enum: + - "" + - AzurePublicCloud + - AzureUSGovernmentCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureStackCloud + type: string + ipFamily: + default: IPv4 + description: |- + ipFamily specifies the IP protocol family that should be used for Azure + network resources. This controls whether Azure resources are created with + IPv4-only, or dual-stack networking with IPv4 or IPv6 as the primary + protocol family. + enum: + - IPv4 + - DualStackIPv6Primary + - DualStackIPv4Primary + type: string + x-kubernetes-validations: + - message: ipFamily is immutable once set + rule: oldSelf == '' || self == oldSelf + networkResourceGroupName: + description: |- + networkResourceGroupName is the Resource Group for network resources like the Virtual Network and Subnets used by the cluster. + If empty, the value is same as ResourceGroupName. + type: string + resourceGroupName: + description: resourceGroupName is the Resource Group + for new Azure resources created for the cluster. + type: string + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to Azure resources created for the cluster. + See https://docs.microsoft.com/en-us/rest/api/resources/tags for information on tagging Azure resources. + Due to limitations on Automation, Content Delivery Network, DNS Azure resources, a maximum of 15 tags + may be applied. OpenShift reserves 5 tags for internal use, allowing 10 tags for user configuration. + items: + description: AzureResourceTag is a tag to apply + to Azure resources created for the cluster. + properties: + key: + description: |- + key is the key part of the tag. A tag key can have a maximum of 128 characters and cannot be empty. Key + must begin with a letter, end with a letter, number or underscore, and must contain only alphanumeric + characters and the following special characters `_ . -`. + maxLength: 128 + minLength: 1 + pattern: ^[a-zA-Z]([0-9A-Za-z_.-]*[0-9A-Za-z_])?$ + type: string + value: + description: |- + value is the value part of the tag. A tag value can have a maximum of 256 characters and cannot be empty. Value + must contain only alphanumeric characters and the following special characters `_ + , - . / : ; < = > ? @`. + maxLength: 256 + minLength: 1 + pattern: ^[0-9A-Za-z_.=+-@]+$ + type: string + required: + - key + - value + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: resourceTags are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + type: object + x-kubernetes-validations: + - message: resourceTags may only be configured during + installation + rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) + || has(oldSelf.resourceTags) && has(self.resourceTags)' + baremetal: + description: baremetal contains settings specific to the + BareMetal platform. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on BareMetal platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + BareMetal deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + equinixMetal: + description: equinixMetal contains settings specific to + the Equinix Metal infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + type: string + type: object + external: + description: external contains settings specific to the + generic External infrastructure provider. + properties: + cloudControllerManager: + description: |- + cloudControllerManager contains settings specific to the external Cloud Controller Manager (a.k.a. CCM or CPI). + When omitted, new nodes will be not tainted + and no extra initialization from the cloud controller manager is expected. + properties: + state: + description: |- + state determines whether or not an external Cloud Controller Manager is expected to + be installed within the cluster. + https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager + + Valid values are "External", "None" and omitted. + When set to "External", new nodes will be tainted as uninitialized when created, + preventing them from running workloads until they are initialized by the cloud controller manager. + When omitted or set to "None", new nodes will be not tainted + and no extra initialization from the cloud controller manager is expected. + enum: + - "" + - External + - None + type: string + x-kubernetes-validations: + - message: state is immutable once set + rule: self == oldSelf + type: object + x-kubernetes-validations: + - message: state may not be added or removed once + set + rule: (has(self.state) == has(oldSelf.state)) || + (!has(oldSelf.state) && self.state != "External") + type: object + x-kubernetes-validations: + - message: cloudControllerManager may not be added or + removed once set + rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager) + gcp: + description: gcp contains settings specific to the Google + Cloud Platform infrastructure provider. + properties: + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + nullable: true + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + projectID: + description: resourceGroupName is the Project ID for + new GCP resources created for the cluster. + type: string + region: + description: region holds the region for new GCP resources + created for the cluster. + type: string + resourceLabels: + description: |- + resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. + See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. + GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, + allowing 32 labels for user configuration. + items: + description: GCPResourceLabel is a label to apply + to GCP resources created for the cluster. + properties: + key: + description: |- + key is the key part of the label. A label key can have a maximum of 63 characters and cannot be empty. + Label key must begin with a lowercase letter, and must contain only lowercase letters, numeric characters, + and the following special characters `_-`. Label key must not have the reserved prefixes `kubernetes-io` + and `openshift-io`. + maxLength: 63 + minLength: 1 + pattern: ^[a-z][0-9a-z_-]{0,62}$ + type: string + x-kubernetes-validations: + - message: label keys must not start with either + `openshift-io` or `kubernetes-io` + rule: '!self.startsWith(''openshift-io'') + && !self.startsWith(''kubernetes-io'')' + value: + description: |- + value is the value part of the label. A label value can have a maximum of 63 characters and cannot be empty. + Value must contain only lowercase letters, numeric characters, and the following special characters `_-`. + maxLength: 63 + minLength: 1 + pattern: ^[0-9a-z_-]{1,63}$ + type: string + required: + - key + - value + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: resourceLabels are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to GCP resources created for the cluster. + See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on + tagging GCP resources. GCP supports a maximum of 50 tags per resource. + items: + description: GCPResourceTag is a tag to apply to + GCP resources created for the cluster. + properties: + key: + description: |- + key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot be empty. + Tag key must begin and end with an alphanumeric character, and must contain only uppercase, lowercase + alphanumeric characters, and the following special characters `._-`. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$ + type: string + parentID: + description: |- + parentID is the ID of the hierarchical resource where the tags are defined, + e.g. at the Organization or the Project level. To find the Organization or Project ID refer to the following pages: + https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id, + https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects. + An OrganizationID must consist of decimal numbers, and cannot have leading zeroes. + A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters, numbers, + and hyphens, and must start with a letter, and cannot end with a hyphen. + maxLength: 32 + minLength: 1 + pattern: (^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$) + type: string + value: + description: |- + value is the value part of the tag. A tag value can have a maximum of 63 characters and cannot be empty. + Tag value must begin and end with an alphanumeric character, and must contain only uppercase, lowercase + alphanumeric characters, and the following special characters `_-.@%=+:,*#&(){}[]` and spaces. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$ + type: string + required: + - key + - parentID + - value + type: object + maxItems: 50 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: resourceTags are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + type: object + x-kubernetes-validations: + - message: resourceLabels may only be configured during + installation + rule: '!has(oldSelf.resourceLabels) && !has(self.resourceLabels) + || has(oldSelf.resourceLabels) && has(self.resourceLabels)' + - message: resourceTags may only be configured during + installation + rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) + || has(oldSelf.resourceTags) && has(self.resourceTags)' + ibmcloud: + description: ibmcloud contains settings specific to the + IBMCloud infrastructure provider. + properties: + cisInstanceCRN: + description: |- + cisInstanceCRN is the CRN of the Cloud Internet Services instance managing + the DNS zone for the cluster's base domain + type: string + dnsInstanceCRN: + description: |- + dnsInstanceCRN is the CRN of the DNS Services instance managing the DNS zone + for the cluster's base domain + type: string + location: + description: location is where the cluster has been + deployed + type: string + providerType: + description: providerType indicates the type of cluster + that was created + type: string + resourceGroupName: + description: resourceGroupName is the Resource Group + for new IBMCloud resources created for the cluster. + type: string + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of an IBM service. These endpoints are used by components + within the cluster when trying to reach the IBM Cloud Services that have been + overridden. The CCCMO reads in the IBMCloudPlatformSpec and validates each + endpoint is resolvable. Once validated, the cloud config and IBMCloudPlatformStatus + are updated to reflect the same custom endpoints. + items: + description: |- + IBMCloudServiceEndpoint stores the configuration of a custom url to + override existing defaults of IBM Cloud Services. + properties: + name: + description: |- + name is the name of the IBM Cloud service. + Possible values are: CIS, COS, COSConfig, DNSServices, GlobalCatalog, GlobalSearch, GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController, ResourceManager, or VPC. + For example, the IBM Cloud Private IAM service could be configured with the + service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` + Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured + with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com` + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. The path must follow the pattern + /v[0,9]+ or /api/v[0,9]+ + maxLength: 300 + type: string + x-kubernetes-validations: + - message: url must be a valid absolute URL + rule: isURL(self) + required: + - name + - url + type: object + maxItems: 13 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + kubevirt: + description: kubevirt contains settings specific to the + kubevirt infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + type: string + type: object + nutanix: + description: nutanix contains settings specific to the + Nutanix infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on Nutanix platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + openstack: + description: openstack contains settings specific to the + OpenStack infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + cloudName: + description: |- + cloudName is the name of the desired OpenStack cloud in the + client configuration file (`clouds.yaml`). + type: string + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on OpenStack platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + OpenStack deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + ovirt: + description: ovirt contains settings specific to the oVirt + infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on Ovirt platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + nodeDNSIP: + description: 'deprecated: as of 4.6, this field is + no longer set or honored. It will be removed in + a future release.' + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + powervs: + description: powervs contains settings specific to the + Power Systems Virtual Servers infrastructure provider. + properties: + cisInstanceCRN: + description: |- + cisInstanceCRN is the CRN of the Cloud Internet Services instance managing + the DNS zone for the cluster's base domain + type: string + dnsInstanceCRN: + description: |- + dnsInstanceCRN is the CRN of the DNS Services instance managing the DNS zone + for the cluster's base domain + type: string + region: + description: region holds the default Power VS region + for new Power VS resources created by the cluster. + type: string + resourceGroup: + description: |- + resourceGroup is the resource group name for new IBMCloud resources created for a cluster. + The resource group specified here will be used by cluster-image-registry-operator to set up a COS Instance in IBMCloud for the cluster registry. + More about resource groups can be found here: https://cloud.ibm.com/docs/account?topic=account-rgs. + When omitted, the image registry operator won't be able to configure storage, + which results in the image registry cluster operator not being in an available state. + maxLength: 40 + pattern: ^[a-zA-Z0-9-_ ]+$ + type: string + x-kubernetes-validations: + - message: resourceGroup is immutable once set + rule: oldSelf == '' || self == oldSelf + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of a Power VS service. + items: + description: |- + PowervsServiceEndpoint stores the configuration of a custom url to + override existing defaults of PowerVS Services. + properties: + name: + description: |- + name is the name of the Power VS service. + Few of the services are + IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api + ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller + Power Cloud - https://cloud.ibm.com/apidocs/power-cloud + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - Power + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + format: uri + pattern: ^https:// + type: string + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + zone: + description: |- + zone holds the default zone for the new Power VS resources created by the cluster. + Note: Currently only single-zone OCP clusters are supported + type: string + type: object + x-kubernetes-validations: + - message: cannot unset resourceGroup once set + rule: '!has(oldSelf.resourceGroup) || has(self.resourceGroup)' + type: + description: |- + type is the underlying infrastructure provider for the cluster. This + value controls whether infrastructure automation such as service load + balancers, dynamic volume provisioning, machine creation and deletion, and + other integrations are enabled. If None, no infrastructure automation is + enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "EquinixMetal", "PowerVS", "AlibabaCloud", "Nutanix" and "None". + Individual components may not support all platforms, and must handle + unrecognized platforms as None if they do not support that platform. + + This value will be synced with to the `status.platform` and `status.platformStatus.type`. + Currently this value cannot be changed once set. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + vsphere: + description: vsphere contains settings specific to the + VSphere infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on VSphere platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + vSphere deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + type: object + type: object + required: + - spec + type: object + x-kubernetes-embedded-resource: true + internalRegistryPullSecret: + description: |- + internalRegistryPullSecret is the pull secret for the internal registry, used by + rpm-ostree to pull images from the internal registry if present + format: byte + nullable: true + type: string + ipFamilies: + description: ipFamilies indicates the IP families in use by the cluster + network + type: string + kubeAPIServerServingCAData: + description: kubeAPIServerServingCAData managed Kubelet to API Server + Cert... Rotated automatically + format: byte + type: string + network: + description: network contains additional network related information + nullable: true + properties: + mtuMigration: + description: mtuMigration contains the MTU migration configuration. + nullable: true + properties: + machine: + description: machine contains MTU migration configuration + for the machine's uplink. + properties: + from: + description: from is the MTU to migrate from. + format: int32 + minimum: 0 + type: integer + to: + description: to is the MTU to migrate to. + format: int32 + minimum: 0 + type: integer + type: object + network: + description: network contains MTU migration configuration + for the default network. + properties: + from: + description: from is the MTU to migrate from. + format: int32 + minimum: 0 + type: integer + to: + description: to is the MTU to migrate to. + format: int32 + minimum: 0 + type: integer + type: object + type: object + required: + - mtuMigration + type: object + networkType: + description: |- + networkType holds the type of network the cluster is using + XXX: this is temporary and will be dropped as soon as possible in favor of a better support + to start network related services the proper way. + Nobody is also changing this once the cluster is up and running the first time, so, disallow + regeneration if this changes. + type: string + osImageURL: + description: osImageURL is the old-format container image that contains + the OS update payload. + type: string + platform: + description: platform is deprecated, use Infra.Status.PlatformStatus.Type + instead + type: string + proxy: + description: proxy holds the current proxy configuration for the nodes + nullable: true + properties: + httpProxy: + description: httpProxy is the URL of the proxy for HTTP requests. + type: string + httpsProxy: + description: httpsProxy is the URL of the proxy for HTTPS requests. + type: string + noProxy: + description: noProxy is a comma-separated list of hostnames and/or + CIDRs for which the proxy should not be used. + type: string + type: object + pullSecret: + description: |- + pullSecret is the default pull secret that needs to be installed + on all machines. + 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. + 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 + releaseImage: + description: releaseImage is the image used when installing the cluster + type: string + rootCAData: + description: rootCAData specifies the root CA data + format: byte + type: string + required: + - additionalTrustBundle + - baseOSContainerImage + - cloudProviderCAData + - cloudProviderConfig + - clusterDNSIP + - dns + - images + - infra + - ipFamilies + - kubeAPIServerServingCAData + - network + - proxy + - releaseImage + - rootCAData + type: object + status: + description: status contains observed information about the controller + config. + properties: + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: ControllerConfigStatusCondition contains condition + information for ControllerConfigStatus + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + nullable: true + type: string + message: + description: |- + message provides additional information about the current condition. + This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are PascalCase + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerCertificates: + description: controllerCertificates represents the latest available + observations of the automatically rotating certificates in the MCO. + items: + description: ControllerCertificate contains info about a specific + cert. + properties: + bundleFile: + description: bundleFile is the larger bundle a cert comes from + type: string + notAfter: + description: notAfter is the upper boundary for validity + format: date-time + type: string + notBefore: + description: notBefore is the lower boundary for validity + format: date-time + type: string + signer: + description: signer is the cert Issuer + type: string + subject: + description: subject is the cert subject + type: string + required: + - bundleFile + - signer + - subject + type: object + type: array + x-kubernetes-list-type: atomic + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_controllerconfigs-TechPreviewNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_controllerconfigs-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000..0db28df --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_controllerconfigs-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,3311 @@ +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" + release.openshift.io/feature-set: TechPreviewNoUpgrade + labels: + openshift.io/operator-managed: "" + name: controllerconfigs.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: ControllerConfig + listKind: ControllerConfigList + plural: controllerconfigs + singular: controllerconfig + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + ControllerConfig describes configuration for MachineConfigController. + This is currently only used to drive the MachineConfig objects generated by the TemplateController. + + 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: spec contains the desired controller config configuration. + properties: + additionalTrustBundle: + description: |- + additionalTrustBundle is a certificate bundle that will be added to the nodes + trusted certificate store. + format: byte + nullable: true + type: string + baseOSContainerImage: + description: baseOSContainerImage is the new-format container image + for operating system updates. + type: string + baseOSExtensionsContainerImage: + description: baseOSExtensionsContainerImage is the matching extensions + container for the new-format container + type: string + cloudProviderCAData: + description: cloudProviderCAData specifies the cloud provider CA data + format: byte + nullable: true + type: string + cloudProviderConfig: + description: cloudProviderConfig is the configuration for the given + cloud provider + type: string + clusterDNSIP: + description: clusterDNSIP is the cluster DNS IP address + type: string + dns: + description: dns holds the cluster dns details + nullable: true + 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: + description: |- + metadata is the standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + type: object + spec: + description: spec holds user settable values for configuration + properties: + baseDomain: + description: |- + baseDomain is the base domain of the cluster. All managed DNS records will + be sub-domains of this base. + + For example, given the base domain `openshift.example.com`, an API server + DNS record may be created for `cluster-api.openshift.example.com`. + + Once set, this field cannot be changed. + type: string + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for DNS. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + properties: + aws: + description: aws contains DNS configuration specific to + the Amazon Web Services cloud provider. + properties: + privateZoneIAMRole: + description: |- + privateZoneIAMRole contains the ARN of an IAM role that should be assumed when performing + operations on the cluster's private hosted zone specified in the cluster DNS config. + When left empty, no role should be assumed. + pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$ + type: string + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + Allowed values: "", "AWS". + + Individual components may not support all platforms, + and must handle unrecognized platforms with best-effort defaults. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + x-kubernetes-validations: + - message: allowed values are '' and 'AWS' + rule: self in ['','AWS'] + required: + - type + type: object + x-kubernetes-validations: + - message: aws configuration is required when platform is + AWS, and forbidden otherwise + rule: 'has(self.type) && self.type == ''AWS'' ? has(self.aws) + : !has(self.aws)' + privateZone: + description: |- + privateZone is the location where all the DNS records that are only available internally + to the cluster exist. + + If this field is nil, no private records should be created. + + Once set, this field cannot be changed. + properties: + id: + description: |- + id is the identifier that can be used to find the DNS hosted zone. + + on AWS zone can be fetched using `ID` as id in [1] + on Azure zone can be fetched using `ID` as a pre-determined name in [2], + on GCP zone can be fetched using `ID` as a pre-determined name in [3]. + + [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options + [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show + [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get + type: string + tags: + additionalProperties: + type: string + description: |- + tags can be used to query the DNS hosted zone. + + on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, + + [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options + type: object + type: object + publicZone: + description: |- + publicZone is the location where all the DNS records that are publicly accessible to + the internet exist. + + If this field is nil, no public records should be created. + + Once set, this field cannot be changed. + properties: + id: + description: |- + id is the identifier that can be used to find the DNS hosted zone. + + on AWS zone can be fetched using `ID` as id in [1] + on Azure zone can be fetched using `ID` as a pre-determined name in [2], + on GCP zone can be fetched using `ID` as a pre-determined name in [3]. + + [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options + [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show + [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get + type: string + tags: + additionalProperties: + type: string + description: |- + tags can be used to query the DNS hosted zone. + + on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, + + [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options + type: object + type: object + type: object + status: + description: status holds observed values from the cluster. They + may not be overridden. + type: object + required: + - spec + type: object + x-kubernetes-embedded-resource: true + etcdDiscoveryDomain: + description: etcdDiscoveryDomain is deprecated, use Infra.Status.EtcdDiscoveryDomain + instead + type: string + imageRegistryBundleData: + description: imageRegistryBundleData is the ImageRegistryData + items: + description: ImageRegistryBundle contains information for writing + image registry certificates + properties: + data: + description: data holds the contents of the bundle that will + be written to the file location + format: byte + type: string + file: + description: file holds the name of the file where the bundle + will be written to disk + type: string + required: + - data + - file + type: object + type: array + x-kubernetes-list-type: atomic + imageRegistryBundleUserData: + description: imageRegistryBundleUserData is Image Registry Data provided + by the user + items: + description: ImageRegistryBundle contains information for writing + image registry certificates + properties: + data: + description: data holds the contents of the bundle that will + be written to the file location + format: byte + type: string + file: + description: file holds the name of the file where the bundle + will be written to disk + type: string + required: + - data + - file + type: object + type: array + x-kubernetes-list-type: atomic + images: + additionalProperties: + type: string + description: images is map of images that are used by the controller + to render templates under ./templates/ + type: object + infra: + description: infra holds the infrastructure details + nullable: true + 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: + description: |- + metadata is the standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + type: object + spec: + description: spec holds user settable values for configuration + properties: + cloudConfig: + description: |- + cloudConfig is a reference to a ConfigMap containing the cloud provider configuration file. + This configuration file is used to configure the Kubernetes cloud provider integration + when using the built-in cloud provider integration or the external cloud controller manager. + The namespace for this config map is openshift-config. + + cloudConfig should only be consumed by the kube_cloud_config controller. + The controller is responsible for using the user configuration in the spec + for various platforms and combining that with the user provided ConfigMap in this field + to create a stitched kube cloud config. + The controller generates a ConfigMap `kube-cloud-config` in `openshift-config-managed` namespace + with the kube cloud config is stored in `cloud.conf` key. + All the clients are expected to use the generated ConfigMap only. + properties: + key: + description: key allows pointing to a specific key/value + inside of the configmap. This is useful for logical + file references. + type: string + name: + type: string + type: object + platformSpec: + description: |- + platformSpec holds desired information specific to the underlying + infrastructure provider. + properties: + alibabaCloud: + description: alibabaCloud contains settings specific to + the Alibaba Cloud infrastructure provider. + type: object + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints list contains custom endpoints which will override default + service endpoint of AWS Services. + There must be only one ServiceEndpoint for a service. + items: + description: |- + AWSServiceEndpoint store the configuration of a custom url to + override existing defaults of AWS Services. + properties: + name: + description: |- + name is the name of the AWS service. + The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html + This must be provided and cannot be empty. + pattern: ^[a-z0-9-]+$ + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + pattern: ^https:// + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + azure: + description: azure contains settings specific to the Azure + infrastructure provider. + type: object + baremetal: + description: baremetal contains settings specific to the + BareMetal platform. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + equinixMetal: + description: equinixMetal contains settings specific to + the Equinix Metal infrastructure provider. + type: object + external: + description: |- + ExternalPlatformType represents generic infrastructure provider. + Platform-specific components should be supplemented separately. + properties: + platformName: + default: Unknown + description: |- + platformName holds the arbitrary string representing the infrastructure provider name, expected to be set at the installation time. + This field is solely for informational and reporting purposes and is not expected to be used for decision-making. + type: string + x-kubernetes-validations: + - message: platform name cannot be changed once set + rule: oldSelf == 'Unknown' || self == oldSelf + type: object + gcp: + description: gcp contains settings specific to the Google + Cloud Platform infrastructure provider. + type: object + ibmcloud: + description: ibmcloud contains settings specific to the + IBMCloud infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of an IBM service. These endpoints are used by components + within the cluster when trying to reach the IBM Cloud Services that have been + overridden. The CCCMO reads in the IBMCloudPlatformSpec and validates each + endpoint is resolvable. Once validated, the cloud config and IBMCloudPlatformStatus + are updated to reflect the same custom endpoints. + A maximum of 13 service endpoints overrides are supported. + items: + description: |- + IBMCloudServiceEndpoint stores the configuration of a custom url to + override existing defaults of IBM Cloud Services. + properties: + name: + description: |- + name is the name of the IBM Cloud service. + Possible values are: CIS, COS, COSConfig, DNSServices, GlobalCatalog, GlobalSearch, GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController, ResourceManager, or VPC. + For example, the IBM Cloud Private IAM service could be configured with the + service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` + Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured + with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com` + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. The path must follow the pattern + /v[0,9]+ or /api/v[0,9]+ + maxLength: 300 + type: string + x-kubernetes-validations: + - message: url must use https scheme + rule: url(self).getScheme() == "https" + - message: url path must match /v[0,9]+ or /api/v[0,9]+ + rule: matches((url(self).getEscapedPath()), + '^/(api/)?v[0-9]+/{0,1}$') + - message: url must be a valid absolute URL + rule: isURL(self) + required: + - name + - url + type: object + maxItems: 13 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + kubevirt: + description: kubevirt contains settings specific to the + kubevirt infrastructure provider. + type: object + nutanix: + description: nutanix contains settings specific to the + Nutanix infrastructure provider. + properties: + failureDomains: + description: |- + failureDomains configures failure domains information for the Nutanix platform. + When set, the failure domains defined here may be used to spread Machines across + prism element clusters to improve fault tolerance of the cluster. + items: + description: NutanixFailureDomain configures failure + domain information for the Nutanix platform. + properties: + cluster: + description: |- + cluster is to identify the cluster (the Prism Element under management of the Prism Central), + in which the Machine's VM will be created. The cluster identifier (uuid or name) can be obtained + from the Prism Central console or using the prism_central API. + properties: + name: + description: name is the resource name in + the PC. It cannot be empty if the type + is Name. + type: string + type: + description: type is the identifier type + to use for this resource. + enum: + - UUID + - Name + type: string + uuid: + description: uuid is the UUID of the resource + in the PC. It cannot be empty if the type + is UUID. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: uuid configuration is required when + type is UUID, and forbidden otherwise + rule: 'has(self.type) && self.type == ''UUID'' + ? has(self.uuid) : !has(self.uuid)' + - message: name configuration is required when + type is Name, and forbidden otherwise + rule: 'has(self.type) && self.type == ''Name'' + ? has(self.name) : !has(self.name)' + name: + description: |- + name defines the unique name of a failure domain. + Name is required and must be at most 64 characters in length. + It must consist of only lower case alphanumeric characters and hyphens (-). + It must start and end with an alphanumeric character. + This value is arbitrary and is used to identify the failure domain within the platform. + maxLength: 64 + minLength: 1 + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?' + type: string + subnets: + description: |- + subnets holds a list of identifiers (one or more) of the cluster's network subnets + If the feature gate NutanixMultiSubnets is enabled, up to 32 subnets may be configured. + for the Machine's VM to connect to. The subnet identifiers (uuid or name) can be + obtained from the Prism Central console or using the prism_central API. + items: + description: NutanixResourceIdentifier holds + the identity of a Nutanix PC resource (cluster, + image, subnet, etc.) + properties: + name: + description: name is the resource name + in the PC. It cannot be empty if the + type is Name. + type: string + type: + description: type is the identifier type + to use for this resource. + enum: + - UUID + - Name + type: string + uuid: + description: uuid is the UUID of the resource + in the PC. It cannot be empty if the + type is UUID. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: uuid configuration is required + when type is UUID, and forbidden otherwise + rule: 'has(self.type) && self.type == ''UUID'' + ? has(self.uuid) : !has(self.uuid)' + - message: name configuration is required + when type is Name, and forbidden otherwise + rule: 'has(self.type) && self.type == ''Name'' + ? has(self.name) : !has(self.name)' + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: each subnet must be unique + rule: self.all(x, self.exists_one(y, x == + y)) + required: + - cluster + - name + - subnets + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + prismCentral: + description: |- + prismCentral holds the endpoint address and port to access the Nutanix Prism Central. + When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. + Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the + proxy spec.noProxy list. + properties: + address: + description: address is the endpoint address (DNS + name or IP address) of the Nutanix Prism Central + or Element (cluster) + maxLength: 256 + type: string + port: + description: port is the port number to access + the Nutanix Prism Central or Element (cluster) + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + prismElements: + description: |- + prismElements holds one or more endpoint address and port data to access the Nutanix + Prism Elements (clusters) of the Nutanix Prism Central. Currently we only support one + Prism Element (cluster) for an OpenShift cluster, where all the Nutanix resources (VMs, subnets, volumes, etc.) + used in the OpenShift cluster are located. In the future, we may support Nutanix resources (VMs, etc.) + spread over multiple Prism Elements (clusters) of the Prism Central. + items: + description: NutanixPrismElementEndpoint holds the + name and endpoint data for a Prism Element (cluster) + properties: + endpoint: + description: |- + endpoint holds the endpoint address and port data of the Prism Element (cluster). + When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. + Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the + proxy spec.noProxy list. + properties: + address: + description: address is the endpoint address + (DNS name or IP address) of the Nutanix + Prism Central or Element (cluster) + maxLength: 256 + type: string + port: + description: port is the port number to + access the Nutanix Prism Central or Element + (cluster) + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + name: + description: |- + name is the name of the Prism Element (cluster). This value will correspond with + the cluster field configured on other resources (eg Machines, PVCs, etc). + maxLength: 256 + type: string + required: + - endpoint + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - prismCentral + - prismElements + type: object + openstack: + description: openstack contains settings specific to the + OpenStack infrastructure provider. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + ovirt: + description: ovirt contains settings specific to the oVirt + infrastructure provider. + type: object + powervs: + description: powervs contains settings specific to the + IBM Power Systems Virtual Servers infrastructure provider. + properties: + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of a Power VS service. + items: + description: |- + PowervsServiceEndpoint stores the configuration of a custom url to + override existing defaults of PowerVS Services. + properties: + name: + description: |- + name is the name of the Power VS service. + Few of the services are + IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api + ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller + Power Cloud - https://cloud.ibm.com/apidocs/power-cloud + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - Power + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + format: uri + pattern: ^https:// + type: string + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. This + value controls whether infrastructure automation such as service load + balancers, dynamic volume provisioning, machine creation and deletion, and + other integrations are enabled. If None, no infrastructure automation is + enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + and must handle unrecognized platforms as None if they do not support that platform. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + vsphere: + description: vsphere contains settings specific to the + VSphere infrastructure provider. + properties: + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.apiServerInternalIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + failureDomains: + description: |- + failureDomains contains the definition of region, zone and the vCenter topology. + If this is omitted failure domains (regions and zones) will not be used. + items: + description: VSpherePlatformFailureDomainSpec holds + the region and zone failure domain and the vCenter + topology of that failure domain. + properties: + name: + description: |- + name defines the arbitrary but unique name + of a failure domain. + maxLength: 256 + minLength: 1 + type: string + region: + description: |- + region defines the name of a region tag that will + be attached to a vCenter datacenter. The tag + category in vCenter must be named openshift-region. + maxLength: 80 + minLength: 1 + type: string + regionAffinity: + description: |- + regionAffinity holds the type of region, Datacenter or ComputeCluster. + When set to Datacenter, this means the region is a vCenter Datacenter as defined in topology. + When set to ComputeCluster, this means the region is a vCenter Cluster as defined in topology. + properties: + type: + description: |- + type determines the vSphere object type for a region within this failure domain. + Available types are Datacenter and ComputeCluster. + When set to Datacenter, this means the vCenter Datacenter defined is the region. + When set to ComputeCluster, this means the vCenter cluster defined is the region. + enum: + - ComputeCluster + - Datacenter + type: string + required: + - type + type: object + server: + description: server is the fully-qualified domain + name or the IP address of the vCenter server. + maxLength: 255 + minLength: 1 + type: string + topology: + description: topology describes a given failure + domain using vSphere constructs + properties: + computeCluster: + description: |- + computeCluster the absolute path of the vCenter cluster + in which virtual machine will be located. + The absolute path is of the form //host/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/host/.*? + type: string + datacenter: + description: |- + datacenter is the name of vCenter datacenter in which virtual machines will be located. + The maximum length of the datacenter name is 80 characters. + maxLength: 80 + type: string + datastore: + description: |- + datastore is the absolute path of the datastore in which the + virtual machine is located. + The absolute path is of the form //datastore/ + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/datastore/.*? + type: string + folder: + description: |- + folder is the absolute path of the folder where + virtual machines are located. The absolute path + is of the form //vm/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/vm/.*? + type: string + networks: + description: |- + networks is the list of port group network names within this failure domain. + If feature gate VSphereMultiNetworks is enabled, up to 10 network adapters may be defined. + 10 is the maximum number of virtual network devices which may be attached to a VM as defined by: + https://configmax.esp.vmware.com/guest?vmwareproduct=vSphere&release=vSphere%208.0&categories=1-0 + The available networks (port groups) can be listed using + `govc ls 'network/*'` + Networks should be in the form of an absolute path: + //network/. + items: + type: string + maxItems: 10 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + resourcePool: + description: |- + resourcePool is the absolute path of the resource pool where virtual machines will be + created. The absolute path is of the form //host//Resources/. + The maximum length of the path is 2048 characters. + maxLength: 2048 + pattern: ^/.*?/host/.*?/Resources.* + type: string + template: + description: |- + template is the full inventory path of the virtual machine or template + that will be cloned when creating new machines in this failure domain. + The maximum length of the path is 2048 characters. + + When omitted, the template will be calculated by the control plane + machineset operator based on the region and zone defined in + VSpherePlatformFailureDomainSpec. + For example, for zone=zonea, region=region1, and infrastructure name=test, + the template path would be calculated as //vm/test-rhcos-region1-zonea. + maxLength: 2048 + minLength: 1 + pattern: ^/.*?/vm/.*? + type: string + required: + - computeCluster + - datacenter + - datastore + - networks + type: object + zone: + description: |- + zone defines the name of a zone tag that will + be attached to a vCenter cluster. The tag + category in vCenter must be named openshift-zone. + maxLength: 80 + minLength: 1 + type: string + zoneAffinity: + description: |- + zoneAffinity holds the type of the zone and the hostGroup which + vmGroup and the hostGroup names in vCenter corresponds to + a vm-host group of type Virtual Machine and Host respectively. Is also + contains the vmHostRule which is an affinity vm-host rule in vCenter. + properties: + hostGroup: + description: |- + hostGroup holds the vmGroup and the hostGroup names in vCenter + corresponds to a vm-host group of type Virtual Machine and Host respectively. Is also + contains the vmHostRule which is an affinity vm-host rule in vCenter. + properties: + hostGroup: + description: |- + hostGroup is the name of the vm-host group of type host within vCenter for this failure domain. + hostGroup is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + vmGroup: + description: |- + vmGroup is the name of the vm-host group of type virtual machine within vCenter for this failure domain. + vmGroup is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + vmHostRule: + description: |- + vmHostRule is the name of the affinity vm-host rule within vCenter for this failure domain. + vmHostRule is limited to 80 characters. + This field is required when the VSphereFailureDomain ZoneType is HostGroup + maxLength: 80 + minLength: 1 + type: string + required: + - hostGroup + - vmGroup + - vmHostRule + type: object + type: + description: |- + type determines the vSphere object type for a zone within this failure domain. + Available types are ComputeCluster and HostGroup. + When set to ComputeCluster, this means the vCenter cluster defined is the zone. + When set to HostGroup, hostGroup must be configured with hostGroup, vmGroup and vmHostRule and + this means the zone is defined by the grouping of those fields. + enum: + - HostGroup + - ComputeCluster + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: hostGroup is required when type is + HostGroup, and forbidden otherwise + rule: 'has(self.type) && self.type == ''HostGroup'' + ? has(self.hostGroup) : !has(self.hostGroup)' + required: + - name + - region + - server + - topology + - zone + type: object + x-kubernetes-validations: + - message: when zoneAffinity type is HostGroup, + regionAffinity type must be ComputeCluster + rule: 'has(self.zoneAffinity) && self.zoneAffinity.type + == ''HostGroup'' ? has(self.regionAffinity) + && self.regionAffinity.type == ''ComputeCluster'' + : true' + - message: when zoneAffinity type is ComputeCluster, + regionAffinity type must be Datacenter + rule: 'has(self.zoneAffinity) && self.zoneAffinity.type + == ''ComputeCluster'' ? has(self.regionAffinity) + && self.regionAffinity.type == ''Datacenter'' + : true' + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. + In dual stack clusters this list contains two IP addresses, one from IPv4 + family and one from IPv6. + In single stack clusters a single IP address is expected. + When omitted, values from the status.ingressIPs will be used. + Once set, the list cannot be completely removed (but its second entry can). + items: + description: IP is an IP address (for example, "10.0.0.0" + or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'size(self) == 2 && isIP(self[0]) && isIP(self[1]) + ? ip(self[0]).family() != ip(self[1]).family() + : true' + machineNetworks: + description: |- + machineNetworks are IP networks used to connect all the OpenShift cluster + nodes. Each network is provided in the CIDR format and should be IPv4 or IPv6, + for example "10.0.0.0/8" or "fd00::/8". + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeNetworking: + description: |- + nodeNetworking contains the definition of internal and external network constraints for + assigning the node's networking. + If this field is omitted, networking defaults to the legacy + address selection behavior which is to only support a single address and + return the first one found. + properties: + external: + description: external represents the network configuration + of the node that is externally routable. + properties: + excludeNetworkSubnetCidr: + description: |- + excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting + the IP address from the VirtualMachine's VM for use in the status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: atomic + network: + description: |- + network VirtualMachine's VM Network names that will be used to when searching + for status.addresses fields. Note that if internal.networkSubnetCIDR and + external.networkSubnetCIDR are not set, then the vNIC associated to this network must + only have a single IP address assigned to it. + The available networks (port groups) can be listed using + `govc ls 'network/*'` + type: string + networkSubnetCidr: + description: |- + networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs + that will be used in respective status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: set + type: object + internal: + description: internal represents the network configuration + of the node that is routable only within the + cluster. + properties: + excludeNetworkSubnetCidr: + description: |- + excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting + the IP address from the VirtualMachine's VM for use in the status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: atomic + network: + description: |- + network VirtualMachine's VM Network names that will be used to when searching + for status.addresses fields. Note that if internal.networkSubnetCIDR and + external.networkSubnetCIDR are not set, then the vNIC associated to this network must + only have a single IP address assigned to it. + The available networks (port groups) can be listed using + `govc ls 'network/*'` + type: string + networkSubnetCidr: + description: |- + networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs + that will be used in respective status.addresses fields. + items: + type: string + type: array + x-kubernetes-list-type: set + type: object + type: object + vcenters: + description: |- + vcenters holds the connection details for services to communicate with vCenter. + Currently, only a single vCenter is supported, but in tech preview 3 vCenters are supported. + Once the cluster has been installed, you are unable to change the current number of defined + vCenters except in the case where the cluster has been upgraded from a version of OpenShift + where the vsphere platform spec was not present. You may make modifications to the existing + vCenters that are defined in the vcenters list in order to match with any added or modified + failure domains. + items: + description: |- + VSpherePlatformVCenterSpec stores the vCenter connection fields. + This is used by the vSphere CCM. + properties: + datacenters: + description: |- + The vCenter Datacenters in which the RHCOS + vm guests are located. This field will + be used by the Cloud Controller Manager. + Each datacenter listed here should be used within + a topology. + items: + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + port: + description: |- + port is the TCP port that will be used to communicate to + the vCenter endpoint. + When omitted, this means the user has no opinion and + it is up to the platform to choose a sensible default, + which is subject to change over time. + format: int32 + maximum: 32767 + minimum: 1 + type: integer + server: + description: server is the fully-qualified domain + name or the IP address of the vCenter server. + maxLength: 255 + type: string + required: + - datacenters + - server + type: object + maxItems: 3 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: vcenters cannot be added or removed once + set + rule: 'size(self) != size(oldSelf) ? size(oldSelf) + == 0 && size(self) < 2 : true' + type: object + x-kubernetes-validations: + - message: apiServerInternalIPs list is required once + set + rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)' + - message: ingressIPs list is required once set + rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)' + - message: vcenters can have at most 1 item when configured + post-install + rule: '!has(oldSelf.vcenters) && has(self.vcenters) + ? size(self.vcenters) < 2 : true' + type: object + x-kubernetes-validations: + - message: vcenters can have at most 1 item when configured + post-install + rule: '!has(oldSelf.vsphere) && has(self.vsphere) ? size(self.vsphere.vcenters) + < 2 : true' + type: object + status: + description: status holds observed values from the cluster. They + may not be overridden. + properties: + apiServerInternalURI: + description: |- + apiServerInternalURL is a valid URI with scheme 'https', + address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components + like kubelets, to contact the Kubernetes API server using the + infrastructure provider rather than Kubernetes networking. + type: string + apiServerURL: + description: |- + apiServerURL is a valid URI with scheme 'https', address and + optionally a port (defaulting to 443). apiServerURL can be used by components like the web console + to tell users where to find the Kubernetes API. + type: string + controlPlaneTopology: + default: HighlyAvailable + description: |- + controlPlaneTopology expresses the expectations for operands that normally run on control nodes. + The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. + The 'SingleReplica' mode will be used in single-node deployments + and the operators should not configure the operand for highly-available operation + The 'External' mode indicates that the control plane is hosted externally to the cluster and that + its components are not visible within the cluster. + enum: + - HighlyAvailable + - HighlyAvailableArbiter + - SingleReplica + - DualReplica + - External + type: string + cpuPartitioning: + default: None + description: |- + cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. + CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. + Valid values are "None" and "AllNodes". When omitted, the default value is "None". + The default value of "None" indicates that no nodes will be setup with CPU partitioning. + The "AllNodes" value indicates that all nodes have been setup with CPU partitioning, + and can then be further configured via the PerformanceProfile API. + enum: + - None + - AllNodes + type: string + etcdDiscoveryDomain: + description: |- + etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering + etcd servers and clients. + For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery + deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release. + type: string + infrastructureName: + description: |- + infrastructureName uniquely identifies a cluster with a human friendly name. + Once set it should not be changed. Must be of max length 27 and must have only + alphanumeric or hyphen characters. + type: string + infrastructureTopology: + default: HighlyAvailable + description: |- + infrastructureTopology expresses the expectations for infrastructure services that do not run on control + plane nodes, usually indicated by a node selector for a `role` value + other than `master`. + The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. + The 'SingleReplica' mode will be used in single-node deployments + and the operators should not configure the operand for highly-available operation + NOTE: External topology mode is not applicable for this field. + enum: + - HighlyAvailable + - SingleReplica + type: string + platform: + description: |- + platform is the underlying infrastructure provider for the cluster. + + Deprecated: Use platformStatus.type instead. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + platformStatus: + description: |- + platformStatus holds status information specific to the underlying + infrastructure provider. + properties: + alibabaCloud: + description: alibabaCloud contains settings specific to + the Alibaba Cloud infrastructure provider. + properties: + region: + description: region specifies the region for Alibaba + Cloud resources created for the cluster. + pattern: ^[0-9A-Za-z-]+$ + type: string + resourceGroupID: + description: resourceGroupID is the ID of the resource + group for the cluster. + pattern: ^(rg-[0-9A-Za-z]+)?$ + type: string + resourceTags: + description: resourceTags is a list of additional + tags to apply to Alibaba Cloud resources created + for the cluster. + items: + description: AlibabaCloudResourceTag is the set + of tags to add to apply to resources. + properties: + key: + description: key is the key of the tag. + maxLength: 128 + minLength: 1 + type: string + value: + description: value is the value of the tag. + maxLength: 128 + minLength: 1 + type: string + required: + - key + - value + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + required: + - region + type: object + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + nullable: true + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + ipFamily: + default: IPv4 + description: |- + ipFamily specifies the IP protocol family that should be used for AWS + network resources. This controls whether AWS resources are created with + IPv4-only, or dual-stack networking with IPv4 or IPv6 as the primary + protocol family. + enum: + - IPv4 + - DualStackIPv6Primary + - DualStackIPv4Primary + type: string + x-kubernetes-validations: + - message: ipFamily is immutable once set + rule: oldSelf == '' || self == oldSelf + region: + description: region holds the default AWS region for + new AWS resources created by the cluster. + type: string + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to AWS resources created for the cluster. + See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html for information on tagging AWS resources. + AWS supports a maximum of 50 tags per resource. OpenShift reserves 25 tags for its use, leaving 25 tags + available for the user. + items: + description: AWSResourceTag is a tag to apply to + AWS resources created for the cluster. + properties: + key: + description: |- + key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag. + Key should consist of between 1 and 128 characters, and may + contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: invalid AWS resource tag key. The + string can contain only the set of alphanumeric + characters, space (' '), '_', '.', '/', + '=', '+', '-', ':', '@' + rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$') + value: + description: |- + value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag. + Value should consist of between 1 and 256 characters, and may + contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'. + Some AWS service do not support empty values. Since tags are added to resources in many services, the + length of the tag value must meet the requirements of all services. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: invalid AWS resource tag value. The + string can contain only the set of alphanumeric + characters, space (' '), '_', '.', '/', + '=', '+', '-', ':', '@' + rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$') + required: + - key + - value + type: object + maxItems: 25 + type: array + x-kubernetes-list-type: atomic + serviceEndpoints: + description: |- + serviceEndpoints list contains custom endpoints which will override default + service endpoint of AWS Services. + There must be only one ServiceEndpoint for a service. + items: + description: |- + AWSServiceEndpoint store the configuration of a custom url to + override existing defaults of AWS Services. + properties: + name: + description: |- + name is the name of the AWS service. + The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html + This must be provided and cannot be empty. + pattern: ^[a-z0-9-]+$ + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + pattern: ^https:// + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + azure: + description: azure contains settings specific to the Azure + infrastructure provider. + properties: + armEndpoint: + description: armEndpoint specifies a URL to use for + resource management in non-soverign clouds such + as Azure Stack. + type: string + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + cloudName: + description: |- + cloudName is the name of the Azure cloud environment which can be used to configure the Azure SDK + with the appropriate Azure API endpoints. + If empty, the value is equal to `AzurePublicCloud`. + enum: + - "" + - AzurePublicCloud + - AzureUSGovernmentCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureStackCloud + type: string + ipFamily: + default: IPv4 + description: |- + ipFamily specifies the IP protocol family that should be used for Azure + network resources. This controls whether Azure resources are created with + IPv4-only, or dual-stack networking with IPv4 or IPv6 as the primary + protocol family. + enum: + - IPv4 + - DualStackIPv6Primary + - DualStackIPv4Primary + type: string + x-kubernetes-validations: + - message: ipFamily is immutable once set + rule: oldSelf == '' || self == oldSelf + networkResourceGroupName: + description: |- + networkResourceGroupName is the Resource Group for network resources like the Virtual Network and Subnets used by the cluster. + If empty, the value is same as ResourceGroupName. + type: string + resourceGroupName: + description: resourceGroupName is the Resource Group + for new Azure resources created for the cluster. + type: string + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to Azure resources created for the cluster. + See https://docs.microsoft.com/en-us/rest/api/resources/tags for information on tagging Azure resources. + Due to limitations on Automation, Content Delivery Network, DNS Azure resources, a maximum of 15 tags + may be applied. OpenShift reserves 5 tags for internal use, allowing 10 tags for user configuration. + items: + description: AzureResourceTag is a tag to apply + to Azure resources created for the cluster. + properties: + key: + description: |- + key is the key part of the tag. A tag key can have a maximum of 128 characters and cannot be empty. Key + must begin with a letter, end with a letter, number or underscore, and must contain only alphanumeric + characters and the following special characters `_ . -`. + maxLength: 128 + minLength: 1 + pattern: ^[a-zA-Z]([0-9A-Za-z_.-]*[0-9A-Za-z_])?$ + type: string + value: + description: |- + value is the value part of the tag. A tag value can have a maximum of 256 characters and cannot be empty. Value + must contain only alphanumeric characters and the following special characters `_ + , - . / : ; < = > ? @`. + maxLength: 256 + minLength: 1 + pattern: ^[0-9A-Za-z_.=+-@]+$ + type: string + required: + - key + - value + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: resourceTags are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + type: object + x-kubernetes-validations: + - message: resourceTags may only be configured during + installation + rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) + || has(oldSelf.resourceTags) && has(self.resourceTags)' + baremetal: + description: baremetal contains settings specific to the + BareMetal platform. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on BareMetal platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + BareMetal deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + equinixMetal: + description: equinixMetal contains settings specific to + the Equinix Metal infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + type: string + type: object + external: + description: external contains settings specific to the + generic External infrastructure provider. + properties: + cloudControllerManager: + description: |- + cloudControllerManager contains settings specific to the external Cloud Controller Manager (a.k.a. CCM or CPI). + When omitted, new nodes will be not tainted + and no extra initialization from the cloud controller manager is expected. + properties: + state: + description: |- + state determines whether or not an external Cloud Controller Manager is expected to + be installed within the cluster. + https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager + + Valid values are "External", "None" and omitted. + When set to "External", new nodes will be tainted as uninitialized when created, + preventing them from running workloads until they are initialized by the cloud controller manager. + When omitted or set to "None", new nodes will be not tainted + and no extra initialization from the cloud controller manager is expected. + enum: + - "" + - External + - None + type: string + x-kubernetes-validations: + - message: state is immutable once set + rule: self == oldSelf + type: object + x-kubernetes-validations: + - message: state may not be added or removed once + set + rule: (has(self.state) == has(oldSelf.state)) || + (!has(oldSelf.state) && self.state != "External") + type: object + x-kubernetes-validations: + - message: cloudControllerManager may not be added or + removed once set + rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager) + gcp: + description: gcp contains settings specific to the Google + Cloud Platform infrastructure provider. + properties: + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: |- + cloudLoadBalancerConfig holds configuration related to DNS and cloud + load balancers. It allows configuration of in-cluster DNS as an alternative + to the platform default DNS implementation. + When using the ClusterHosted DNS type, Load Balancer IP addresses + must be provided for the API and internal API load balancers as well as the + ingress load balancer. + nullable: true + properties: + clusterHosted: + description: |- + clusterHosted holds the IP addresses of API, API-Int and Ingress Load + Balancers on Cloud Platforms. The DNS solution hosted within the cluster + use these IP addresses to provide resolution for API, API-Int and Ingress + services. + properties: + apiIntLoadBalancerIPs: + description: |- + apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the apiIntLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: |- + apiLoadBalancerIPs holds Load Balancer IPs for the API service. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Could be empty for private clusters. + Entries in the apiLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: |- + ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + Entries in the ingressLoadBalancerIPs must be unique. + A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, + "10.0.0.0" or "fd00::"). + maxLength: 39 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid IP address + rule: isIP(self) + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: |- + dnsType indicates the type of DNS solution in use within the cluster. Its default value of + `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + The cluster's use of the cloud's Load Balancers is unaffected by this setting. + The value is immutable after it has been set at install time. + Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + Enabling this functionality allows the user to start their own DNS solution outside the cluster after + installation is complete. The customer would be responsible for configuring this custom DNS solution, + and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object + x-kubernetes-validations: + - message: clusterHosted is permitted only when dnsType + is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' + ? !has(self.clusterHosted) : true' + projectID: + description: resourceGroupName is the Project ID for + new GCP resources created for the cluster. + type: string + region: + description: region holds the region for new GCP resources + created for the cluster. + type: string + resourceLabels: + description: |- + resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. + See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. + GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, + allowing 32 labels for user configuration. + items: + description: GCPResourceLabel is a label to apply + to GCP resources created for the cluster. + properties: + key: + description: |- + key is the key part of the label. A label key can have a maximum of 63 characters and cannot be empty. + Label key must begin with a lowercase letter, and must contain only lowercase letters, numeric characters, + and the following special characters `_-`. Label key must not have the reserved prefixes `kubernetes-io` + and `openshift-io`. + maxLength: 63 + minLength: 1 + pattern: ^[a-z][0-9a-z_-]{0,62}$ + type: string + x-kubernetes-validations: + - message: label keys must not start with either + `openshift-io` or `kubernetes-io` + rule: '!self.startsWith(''openshift-io'') + && !self.startsWith(''kubernetes-io'')' + value: + description: |- + value is the value part of the label. A label value can have a maximum of 63 characters and cannot be empty. + Value must contain only lowercase letters, numeric characters, and the following special characters `_-`. + maxLength: 63 + minLength: 1 + pattern: ^[0-9a-z_-]{1,63}$ + type: string + required: + - key + - value + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: resourceLabels are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + resourceTags: + description: |- + resourceTags is a list of additional tags to apply to GCP resources created for the cluster. + See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on + tagging GCP resources. GCP supports a maximum of 50 tags per resource. + items: + description: GCPResourceTag is a tag to apply to + GCP resources created for the cluster. + properties: + key: + description: |- + key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot be empty. + Tag key must begin and end with an alphanumeric character, and must contain only uppercase, lowercase + alphanumeric characters, and the following special characters `._-`. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$ + type: string + parentID: + description: |- + parentID is the ID of the hierarchical resource where the tags are defined, + e.g. at the Organization or the Project level. To find the Organization or Project ID refer to the following pages: + https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id, + https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects. + An OrganizationID must consist of decimal numbers, and cannot have leading zeroes. + A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters, numbers, + and hyphens, and must start with a letter, and cannot end with a hyphen. + maxLength: 32 + minLength: 1 + pattern: (^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$) + type: string + value: + description: |- + value is the value part of the tag. A tag value can have a maximum of 63 characters and cannot be empty. + Tag value must begin and end with an alphanumeric character, and must contain only uppercase, lowercase + alphanumeric characters, and the following special characters `_-.@%=+:,*#&(){}[]` and spaces. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$ + type: string + required: + - key + - parentID + - value + type: object + maxItems: 50 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: resourceTags are immutable and may only + be configured during installation + rule: self.all(x, x in oldSelf) && oldSelf.all(x, + x in self) + type: object + x-kubernetes-validations: + - message: resourceLabels may only be configured during + installation + rule: '!has(oldSelf.resourceLabels) && !has(self.resourceLabels) + || has(oldSelf.resourceLabels) && has(self.resourceLabels)' + - message: resourceTags may only be configured during + installation + rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) + || has(oldSelf.resourceTags) && has(self.resourceTags)' + ibmcloud: + description: ibmcloud contains settings specific to the + IBMCloud infrastructure provider. + properties: + cisInstanceCRN: + description: |- + cisInstanceCRN is the CRN of the Cloud Internet Services instance managing + the DNS zone for the cluster's base domain + type: string + dnsInstanceCRN: + description: |- + dnsInstanceCRN is the CRN of the DNS Services instance managing the DNS zone + for the cluster's base domain + type: string + location: + description: location is where the cluster has been + deployed + type: string + providerType: + description: providerType indicates the type of cluster + that was created + type: string + resourceGroupName: + description: resourceGroupName is the Resource Group + for new IBMCloud resources created for the cluster. + type: string + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of an IBM service. These endpoints are used by components + within the cluster when trying to reach the IBM Cloud Services that have been + overridden. The CCCMO reads in the IBMCloudPlatformSpec and validates each + endpoint is resolvable. Once validated, the cloud config and IBMCloudPlatformStatus + are updated to reflect the same custom endpoints. + items: + description: |- + IBMCloudServiceEndpoint stores the configuration of a custom url to + override existing defaults of IBM Cloud Services. + properties: + name: + description: |- + name is the name of the IBM Cloud service. + Possible values are: CIS, COS, COSConfig, DNSServices, GlobalCatalog, GlobalSearch, GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController, ResourceManager, or VPC. + For example, the IBM Cloud Private IAM service could be configured with the + service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` + Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured + with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com` + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. The path must follow the pattern + /v[0,9]+ or /api/v[0,9]+ + maxLength: 300 + type: string + x-kubernetes-validations: + - message: url must be a valid absolute URL + rule: isURL(self) + required: + - name + - url + type: object + maxItems: 13 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + kubevirt: + description: kubevirt contains settings specific to the + kubevirt infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + type: string + type: object + nutanix: + description: nutanix contains settings specific to the + Nutanix infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on Nutanix platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + openstack: + description: openstack contains settings specific to the + OpenStack infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + cloudName: + description: |- + cloudName is the name of the desired OpenStack cloud in the + client configuration file (`clouds.yaml`). + type: string + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on OpenStack platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + OpenStack deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + ovirt: + description: ovirt contains settings specific to the oVirt + infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: set + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on Ovirt platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + nodeDNSIP: + description: 'deprecated: as of 4.6, this field is + no longer set or honored. It will be removed in + a future release.' + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + powervs: + description: powervs contains settings specific to the + Power Systems Virtual Servers infrastructure provider. + properties: + cisInstanceCRN: + description: |- + cisInstanceCRN is the CRN of the Cloud Internet Services instance managing + the DNS zone for the cluster's base domain + type: string + dnsInstanceCRN: + description: |- + dnsInstanceCRN is the CRN of the DNS Services instance managing the DNS zone + for the cluster's base domain + type: string + region: + description: region holds the default Power VS region + for new Power VS resources created by the cluster. + type: string + resourceGroup: + description: |- + resourceGroup is the resource group name for new IBMCloud resources created for a cluster. + The resource group specified here will be used by cluster-image-registry-operator to set up a COS Instance in IBMCloud for the cluster registry. + More about resource groups can be found here: https://cloud.ibm.com/docs/account?topic=account-rgs. + When omitted, the image registry operator won't be able to configure storage, + which results in the image registry cluster operator not being in an available state. + maxLength: 40 + pattern: ^[a-zA-Z0-9-_ ]+$ + type: string + x-kubernetes-validations: + - message: resourceGroup is immutable once set + rule: oldSelf == '' || self == oldSelf + serviceEndpoints: + description: |- + serviceEndpoints is a list of custom endpoints which will override the default + service endpoints of a Power VS service. + items: + description: |- + PowervsServiceEndpoint stores the configuration of a custom url to + override existing defaults of PowerVS Services. + properties: + name: + description: |- + name is the name of the Power VS service. + Few of the services are + IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api + ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller + Power Cloud - https://cloud.ibm.com/apidocs/power-cloud + enum: + - CIS + - COS + - COSConfig + - DNSServices + - GlobalCatalog + - GlobalSearch + - GlobalTagging + - HyperProtect + - IAM + - KeyProtect + - Power + - ResourceController + - ResourceManager + - VPC + type: string + url: + description: |- + url is fully qualified URI with scheme https, that overrides the default generated + endpoint for a client. + This must be provided and cannot be empty. + format: uri + pattern: ^https:// + type: string + required: + - name + - url + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + zone: + description: |- + zone holds the default zone for the new Power VS resources created by the cluster. + Note: Currently only single-zone OCP clusters are supported + type: string + type: object + x-kubernetes-validations: + - message: cannot unset resourceGroup once set + rule: '!has(oldSelf.resourceGroup) || has(self.resourceGroup)' + type: + description: |- + type is the underlying infrastructure provider for the cluster. This + value controls whether infrastructure automation such as service load + balancers, dynamic volume provisioning, machine creation and deletion, and + other integrations are enabled. If None, no infrastructure automation is + enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "EquinixMetal", "PowerVS", "AlibabaCloud", "Nutanix" and "None". + Individual components may not support all platforms, and must handle + unrecognized platforms as None if they do not support that platform. + + This value will be synced with to the `status.platform` and `status.platformStatus.type`. + Currently this value cannot be changed once set. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + vsphere: + description: vsphere contains settings specific to the + VSphere infrastructure provider. + properties: + apiServerInternalIP: + description: |- + apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used + by components inside the cluster, like kubelets using the infrastructure rather + than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI + points to. It is the IP for a self-hosted load balancer in front of the API servers. + + Deprecated: Use APIServerInternalIPs instead. + type: string + apiServerInternalIPs: + description: |- + apiServerInternalIPs are the IP addresses to contact the Kubernetes API + server that can be used by components inside the cluster, like kubelets + using the infrastructure rather than Kubernetes networking. These are the + IPs for a self-hosted load balancer in front of the API servers. In dual + stack clusters this list contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: apiServerInternalIPs must contain at most + one IPv4 address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + dnsRecordsType: + description: |- + dnsRecordsType determines whether records for api, api-int, and ingress + are provided by the internal DNS service or externally. + Allowed values are `Internal`, `External`, and omitted. + When set to `Internal`, records are provided by the internal infrastructure and + no additional user configuration is required for the cluster to function. + When set to `External`, records are not provided by the internal infrastructure + and must be configured by the user on a DNS server outside the cluster. + Cluster nodes must use this external server for their upstream DNS requests. + This value may only be set when loadBalancer.type is set to UserManaged. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + The current default is `Internal`. + enum: + - Internal + - External + type: string + ingressIP: + description: |- + ingressIP is an external IP which routes to the default ingress controller. + The IP is a suitable target of a wildcard DNS record used to resolve default route host names. + + Deprecated: Use IngressIPs instead. + type: string + ingressIPs: + description: |- + ingressIPs are the external IPs which route to the default ingress + controller. The IPs are suitable targets of a wildcard DNS record used to + resolve default route host names. In dual stack clusters this list + contains two IPs otherwise only one. + format: ip + items: + type: string + maxItems: 2 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ingressIPs must contain at most one IPv4 + address and at most one IPv6 address + rule: 'self == oldSelf || (size(self) == 2 && isIP(self[0]) + && isIP(self[1]) ? ip(self[0]).family() != ip(self[1]).family() + : true)' + loadBalancer: + default: + type: OpenShiftManagedDefault + description: loadBalancer defines how the load balancer + used by the cluster is configured. + properties: + type: + default: OpenShiftManagedDefault + description: |- + type defines the type of load balancer used by the cluster on VSphere platform + which can be a user-managed or openshift-managed load balancer + that is to be used for the OpenShift API and Ingress endpoints. + When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing + defined in the machine config operator will be deployed. + When set to UserManaged these static pods will not be deployed and it is expected that + the load balancer is configured out of band by the deployer. + When omitted, this means no opinion and the platform is left to choose a reasonable default. + The default value is OpenShiftManagedDefault. + enum: + - OpenShiftManagedDefault + - UserManaged + type: string + x-kubernetes-validations: + - message: type is immutable once set + rule: oldSelf == '' || self == oldSelf + type: object + machineNetworks: + description: machineNetworks are IP networks used + to connect all the OpenShift cluster nodes. + items: + description: CIDR is an IP address range in CIDR + notation (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + minLength: 1 + type: string + x-kubernetes-validations: + - message: value must be a valid CIDR network address + rule: isCIDR(self) + maxItems: 32 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - rule: self.all(x, self.exists_one(y, x == y)) + nodeDNSIP: + description: |- + nodeDNSIP is the IP address for the internal DNS used by the + nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` + provides name resolution for the nodes themselves. There is no DNS-as-a-service for + vSphere deployments. In order to minimize necessary changes to the + datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames + to the nodes in the cluster. + type: string + type: object + x-kubernetes-validations: + - message: dnsRecordsType may only be set to External + when loadBalancer.type is UserManaged + rule: '!has(self.dnsRecordsType) || self.dnsRecordsType + == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type + == ''UserManaged'')' + type: object + type: object + required: + - spec + type: object + x-kubernetes-embedded-resource: true + internalRegistryPullSecret: + description: |- + internalRegistryPullSecret is the pull secret for the internal registry, used by + rpm-ostree to pull images from the internal registry if present + format: byte + nullable: true + type: string + ipFamilies: + description: ipFamilies indicates the IP families in use by the cluster + network + type: string + kubeAPIServerServingCAData: + description: kubeAPIServerServingCAData managed Kubelet to API Server + Cert... Rotated automatically + format: byte + type: string + network: + description: network contains additional network related information + nullable: true + properties: + mtuMigration: + description: mtuMigration contains the MTU migration configuration. + nullable: true + properties: + machine: + description: machine contains MTU migration configuration + for the machine's uplink. + properties: + from: + description: from is the MTU to migrate from. + format: int32 + minimum: 0 + type: integer + to: + description: to is the MTU to migrate to. + format: int32 + minimum: 0 + type: integer + type: object + network: + description: network contains MTU migration configuration + for the default network. + properties: + from: + description: from is the MTU to migrate from. + format: int32 + minimum: 0 + type: integer + to: + description: to is the MTU to migrate to. + format: int32 + minimum: 0 + type: integer + type: object + type: object + required: + - mtuMigration + type: object + networkType: + description: |- + networkType holds the type of network the cluster is using + XXX: this is temporary and will be dropped as soon as possible in favor of a better support + to start network related services the proper way. + Nobody is also changing this once the cluster is up and running the first time, so, disallow + regeneration if this changes. + type: string + osImageURL: + description: osImageURL is the old-format container image that contains + the OS update payload. + type: string + platform: + description: platform is deprecated, use Infra.Status.PlatformStatus.Type + instead + type: string + proxy: + description: proxy holds the current proxy configuration for the nodes + nullable: true + properties: + httpProxy: + description: httpProxy is the URL of the proxy for HTTP requests. + type: string + httpsProxy: + description: httpsProxy is the URL of the proxy for HTTPS requests. + type: string + noProxy: + description: noProxy is a comma-separated list of hostnames and/or + CIDRs for which the proxy should not be used. + type: string + type: object + pullSecret: + description: |- + pullSecret is the default pull secret that needs to be installed + on all machines. + 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. + 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 + releaseImage: + description: releaseImage is the image used when installing the cluster + type: string + rootCAData: + description: rootCAData specifies the root CA data + format: byte + type: string + required: + - additionalTrustBundle + - baseOSContainerImage + - cloudProviderCAData + - cloudProviderConfig + - clusterDNSIP + - dns + - images + - infra + - ipFamilies + - kubeAPIServerServingCAData + - network + - proxy + - releaseImage + - rootCAData + type: object + status: + description: status contains observed information about the controller + config. + properties: + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: ControllerConfigStatusCondition contains condition + information for ControllerConfigStatus + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + nullable: true + type: string + message: + description: |- + message provides additional information about the current condition. + This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are PascalCase + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerCertificates: + description: controllerCertificates represents the latest available + observations of the automatically rotating certificates in the MCO. + items: + description: ControllerCertificate contains info about a specific + cert. + properties: + bundleFile: + description: bundleFile is the larger bundle a cert comes from + type: string + notAfter: + description: notAfter is the upper boundary for validity + format: date-time + type: string + notBefore: + description: notBefore is the lower boundary for validity + format: date-time + type: string + signer: + description: signer is the cert Issuer + type: string + subject: + description: subject is the cert subject + type: string + required: + - bundleFile + - signer + - subject + type: object + type: array + x-kubernetes-list-type: atomic + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_kubeletconfigs.crd.yaml b/config/crd/external/0000_80_machine-config_01_kubeletconfigs.crd.yaml new file mode 100644 index 0000000..b056dc9 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_kubeletconfigs.crd.yaml @@ -0,0 +1,355 @@ +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" + labels: + openshift.io/operator-managed: "" + name: kubeletconfigs.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: KubeletConfig + listKind: KubeletConfigList + plural: kubeletconfigs + singular: kubeletconfig + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + KubeletConfig describes a customized Kubelet configuration. + + 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: spec contains the desired kubelet configuration. + properties: + autoSizingReserved: + type: boolean + kubeletConfig: + description: |- + kubeletConfig fields are defined in kubernetes upstream. Please refer to the types defined in the version/commit used by + OpenShift of the upstream kubernetes. It's important to note that, since the fields of the kubelet configuration are directly fetched from + upstream the validation of those values is handled directly by the kubelet. Please refer to the upstream version of the relevant kubernetes + for the valid values of these fields. Invalid values of the kubelet configuration fields may render cluster nodes unusable. + type: object + x-kubernetes-preserve-unknown-fields: true + logLevel: + format: int32 + type: integer + machineConfigPoolSelector: + description: |- + machineConfigPoolSelector selects which pools the KubeletConfig shoud apply to. + A nil selector will result in no pools being selected. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + tlsSecurityProfile: + description: |- + If unset, the default is based on the apiservers.config.openshift.io/cluster resource. + Note that only Old and Intermediate profiles are currently supported, and + the maximum available minTLSVersion is VersionTLS12. + properties: + custom: + description: |- + custom is a user-defined TLS security profile. Be extremely careful using a custom + profile as invalid configurations can be catastrophic. An example custom profile + looks like this: + + ciphers: + + - ECDHE-ECDSA-CHACHA20-POLY1305 + + - ECDHE-RSA-CHACHA20-POLY1305 + + - ECDHE-RSA-AES128-GCM-SHA256 + + - ECDHE-ECDSA-AES128-GCM-SHA256 + + minTLSVersion: VersionTLS11 + nullable: true + properties: + ciphers: + description: |- + ciphers is used to specify the cipher algorithms that are negotiated + during the TLS handshake. Operators may remove entries their operands + do not support. For example, to use DES-CBC3-SHA (yaml): + + ciphers: + - DES-CBC3-SHA + items: + type: string + type: array + x-kubernetes-list-type: atomic + minTLSVersion: + description: |- + minTLSVersion is used to specify the minimal version of the TLS protocol + that is negotiated during the TLS handshake. For example, to use TLS + versions 1.1, 1.2 and 1.3 (yaml): + + minTLSVersion: VersionTLS11 + + NOTE: currently the highest minTLSVersion allowed is VersionTLS12 + enum: + - VersionTLS10 + - VersionTLS11 + - VersionTLS12 + - VersionTLS13 + type: string + type: object + intermediate: + description: |- + intermediate is a TLS security profile based on: + + https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29 + + and looks like this (yaml): + + ciphers: + + - TLS_AES_128_GCM_SHA256 + + - TLS_AES_256_GCM_SHA384 + + - TLS_CHACHA20_POLY1305_SHA256 + + - ECDHE-ECDSA-AES128-GCM-SHA256 + + - ECDHE-RSA-AES128-GCM-SHA256 + + - ECDHE-ECDSA-AES256-GCM-SHA384 + + - ECDHE-RSA-AES256-GCM-SHA384 + + - ECDHE-ECDSA-CHACHA20-POLY1305 + + - ECDHE-RSA-CHACHA20-POLY1305 + + - DHE-RSA-AES128-GCM-SHA256 + + - DHE-RSA-AES256-GCM-SHA384 + + minTLSVersion: VersionTLS12 + nullable: true + type: object + modern: + description: |- + modern is a TLS security profile based on: + + https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility + + and looks like this (yaml): + + ciphers: + + - TLS_AES_128_GCM_SHA256 + + - TLS_AES_256_GCM_SHA384 + + - TLS_CHACHA20_POLY1305_SHA256 + + minTLSVersion: VersionTLS13 + nullable: true + type: object + old: + description: |- + old is a TLS security profile based on: + + https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility + + and looks like this (yaml): + + ciphers: + + - TLS_AES_128_GCM_SHA256 + + - TLS_AES_256_GCM_SHA384 + + - TLS_CHACHA20_POLY1305_SHA256 + + - ECDHE-ECDSA-AES128-GCM-SHA256 + + - ECDHE-RSA-AES128-GCM-SHA256 + + - ECDHE-ECDSA-AES256-GCM-SHA384 + + - ECDHE-RSA-AES256-GCM-SHA384 + + - ECDHE-ECDSA-CHACHA20-POLY1305 + + - ECDHE-RSA-CHACHA20-POLY1305 + + - DHE-RSA-AES128-GCM-SHA256 + + - DHE-RSA-AES256-GCM-SHA384 + + - DHE-RSA-CHACHA20-POLY1305 + + - ECDHE-ECDSA-AES128-SHA256 + + - ECDHE-RSA-AES128-SHA256 + + - ECDHE-ECDSA-AES128-SHA + + - ECDHE-RSA-AES128-SHA + + - ECDHE-ECDSA-AES256-SHA384 + + - ECDHE-RSA-AES256-SHA384 + + - ECDHE-ECDSA-AES256-SHA + + - ECDHE-RSA-AES256-SHA + + - DHE-RSA-AES128-SHA256 + + - DHE-RSA-AES256-SHA256 + + - AES128-GCM-SHA256 + + - AES256-GCM-SHA384 + + - AES128-SHA256 + + - AES256-SHA256 + + - AES128-SHA + + - AES256-SHA + + - DES-CBC3-SHA + + minTLSVersion: VersionTLS10 + nullable: true + type: object + type: + description: |- + type is one of Old, Intermediate, Modern or Custom. Custom provides + the ability to specify individual TLS security profile parameters. + Old, Intermediate and Modern are TLS security profiles based on: + + https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations + + The profiles are intent based, so they may change over time as new ciphers are developed and existing ciphers + are found to be insecure. Depending on precisely which ciphers are available to a process, the list may be + reduced. + + Note that the Modern profile is currently not supported because it is not + yet well adopted by common software libraries. + enum: + - Old + - Intermediate + - Modern + - Custom + type: string + type: object + type: object + status: + description: status contains observed information about the kubelet configuration. + properties: + conditions: + description: conditions represents the latest available observations + of current state. + items: + description: KubeletConfigCondition defines the state of the KubeletConfig + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + nullable: true + type: string + message: + description: |- + message provides additional information about the current condition. + This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are PascalCase + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality. + type: string + type: object + type: array + observedGeneration: + description: observedGeneration represents the generation observed + by the controller. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-CustomNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-CustomNoUpgrade.crd.yaml new file mode 100644 index 0000000..9f06d0d --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-CustomNoUpgrade.crd.yaml @@ -0,0 +1,631 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + release.openshift.io/feature-set: CustomNoUpgrade + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + 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: spec describes the configuration of the machine config node. + properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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: + - desiredImage + type: object + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + type: object + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + internalReleaseImage: + description: |- + internalReleaseImage describes the status of the release payloads stored in the node. + When specified, an internalReleaseImage custom resource exists on the cluster, and the specified images will be made available on the control plane nodes. + This field will reflect the actual on-disk state of those release images. + properties: + releases: + description: |- + releases is a list of the release bundles currently owned and managed by the + cluster. + A release bundle content could be safely pulled only when its Conditions field + contains at least an Available entry set to "True" and Degraded to "False". + Entries must be unique, keyed on the name field. + releases must contain at least one entry and must not exceed 32 entries. + items: + description: |- + MachineConfigNodeStatusInternalReleaseImageRef is used to provide a more detailed reference for + a release bundle. + properties: + conditions: + description: |- + conditions represent the observations of an internal release image current state. Valid types are: + Mounted, Installing, Available, Removing and Degraded. + + If Mounted is true, that means that a valid ISO has been mounted on the current node. + If Installing is true, that means that a new release bundle is currently being copied on the current node, and not yet completed. + If Available is true, it means that the release has been previously installed on the current node, and it can be used. + If Removing is true, it means that a release deletion is in progress on the current node, and not yet completed. + If Degraded is true, that means something has gone wrong in the current node. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 5 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + image: + description: |- + image is an OCP release image referenced by digest. + The format of the image pull spec is: host[:port][/namespace]/name@sha256:, + where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. + The length of the whole spec must be between 1 to 447 characters. + The field is optional, and it will be provided after a release will be successfully installed. + 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-_.]*?$')) + name: + description: |- + name indicates the desired release bundle identifier. This field is required and must be between 1 and 64 characters long. + The expected name format is ocp-release-bundle--. + maxLength: 64 + minLength: 1 + type: string + x-kubernetes-validations: + - message: must be ocp-release-bundle-- + and <= 64 chars + rule: self.matches('^ocp-release-bundle-[0-9]+\\.[0-9]+\\.[0-9]+-[A-Za-z0-9._-]+$') + required: + - name + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - releases + type: object + irreconcilableChanges: + description: |- + irreconcilableChanges is an optional field that contains the observed differences between this nodes + configuration and the target rendered MachineConfig. + This field will be set when there are changes to the target rendered MachineConfig that can only be applied to + new nodes joining the cluster. + Entries must be unique, keyed on the fieldPath field. + Must not exceed 32 entries. + items: + description: |- + IrreconcilableChangeDiff holds an individual diff between the initial install-time MachineConfig + and the latest applied one caused by the presence of irreconcilable changes. + properties: + diff: + description: |- + diff is a required field containing the difference between the nodes current configuration and the latest + rendered MachineConfig for the field specified in fieldPath. + Must not be an empty string and must not exceed 4096 characters in length. + maxLength: 4096 + minLength: 1 + type: string + fieldPath: + description: |- + fieldPath is a required reference to the path in the latest rendered MachineConfig that differs from this nodes + configuration. + Must not be empty and must not exceed 70 characters in length. + Must begin with the prefix 'spec.' and only contain alphanumeric characters, square brackets ('[]'), or dots ('.'). + maxLength: 70 + minLength: 1 + type: string + x-kubernetes-validations: + - message: The fieldPath must start with `spec.` + rule: self.startsWith('spec.') + - message: The fieldPath must consist only of alphanumeric characters, + brackets [] and dots ('.'). + rule: self.matches('^[\\da-zA-Z\\.\\[\\]]+$') + required: + - diff + - fieldPath + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - fieldPath + x-kubernetes-list-type: map + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-Default.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-Default.crd.yaml new file mode 100644 index 0000000..b05742e --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-Default.crd.yaml @@ -0,0 +1,383 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + release.openshift.io/feature-set: Default + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + 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: spec describes the configuration of the machine config node. + properties: + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-DevPreviewNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-DevPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000..4e0cddf --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-DevPreviewNoUpgrade.crd.yaml @@ -0,0 +1,499 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + release.openshift.io/feature-set: DevPreviewNoUpgrade + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + 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: spec describes the configuration of the machine config node. + properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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: + - desiredImage + type: object + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + type: object + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + irreconcilableChanges: + description: |- + irreconcilableChanges is an optional field that contains the observed differences between this nodes + configuration and the target rendered MachineConfig. + This field will be set when there are changes to the target rendered MachineConfig that can only be applied to + new nodes joining the cluster. + Entries must be unique, keyed on the fieldPath field. + Must not exceed 32 entries. + items: + description: |- + IrreconcilableChangeDiff holds an individual diff between the initial install-time MachineConfig + and the latest applied one caused by the presence of irreconcilable changes. + properties: + diff: + description: |- + diff is a required field containing the difference between the nodes current configuration and the latest + rendered MachineConfig for the field specified in fieldPath. + Must not be an empty string and must not exceed 4096 characters in length. + maxLength: 4096 + minLength: 1 + type: string + fieldPath: + description: |- + fieldPath is a required reference to the path in the latest rendered MachineConfig that differs from this nodes + configuration. + Must not be empty and must not exceed 70 characters in length. + Must begin with the prefix 'spec.' and only contain alphanumeric characters, square brackets ('[]'), or dots ('.'). + maxLength: 70 + minLength: 1 + type: string + x-kubernetes-validations: + - message: The fieldPath must start with `spec.` + rule: self.startsWith('spec.') + - message: The fieldPath must consist only of alphanumeric characters, + brackets [] and dots ('.'). + rule: self.matches('^[\\da-zA-Z\\.\\[\\]]+$') + required: + - diff + - fieldPath + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - fieldPath + x-kubernetes-list-type: map + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-TechPreviewNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000..1022ae3 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfignodes-Hypershift-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,499 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + release.openshift.io/feature-set: TechPreviewNoUpgrade + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + 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: spec describes the configuration of the machine config node. + properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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: + - desiredImage + type: object + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + type: object + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + irreconcilableChanges: + description: |- + irreconcilableChanges is an optional field that contains the observed differences between this nodes + configuration and the target rendered MachineConfig. + This field will be set when there are changes to the target rendered MachineConfig that can only be applied to + new nodes joining the cluster. + Entries must be unique, keyed on the fieldPath field. + Must not exceed 32 entries. + items: + description: |- + IrreconcilableChangeDiff holds an individual diff between the initial install-time MachineConfig + and the latest applied one caused by the presence of irreconcilable changes. + properties: + diff: + description: |- + diff is a required field containing the difference between the nodes current configuration and the latest + rendered MachineConfig for the field specified in fieldPath. + Must not be an empty string and must not exceed 4096 characters in length. + maxLength: 4096 + minLength: 1 + type: string + fieldPath: + description: |- + fieldPath is a required reference to the path in the latest rendered MachineConfig that differs from this nodes + configuration. + Must not be empty and must not exceed 70 characters in length. + Must begin with the prefix 'spec.' and only contain alphanumeric characters, square brackets ('[]'), or dots ('.'). + maxLength: 70 + minLength: 1 + type: string + x-kubernetes-validations: + - message: The fieldPath must start with `spec.` + rule: self.startsWith('spec.') + - message: The fieldPath must consist only of alphanumeric characters, + brackets [] and dots ('.'). + rule: self.matches('^[\\da-zA-Z\\.\\[\\]]+$') + required: + - diff + - fieldPath + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - fieldPath + x-kubernetes-list-type: map + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-CustomNoUpgrade.crd.yaml new file mode 100644 index 0000000..4d92526 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -0,0 +1,631 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/feature-set: CustomNoUpgrade + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + 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: spec describes the configuration of the machine config node. + properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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: + - desiredImage + type: object + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + type: object + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + internalReleaseImage: + description: |- + internalReleaseImage describes the status of the release payloads stored in the node. + When specified, an internalReleaseImage custom resource exists on the cluster, and the specified images will be made available on the control plane nodes. + This field will reflect the actual on-disk state of those release images. + properties: + releases: + description: |- + releases is a list of the release bundles currently owned and managed by the + cluster. + A release bundle content could be safely pulled only when its Conditions field + contains at least an Available entry set to "True" and Degraded to "False". + Entries must be unique, keyed on the name field. + releases must contain at least one entry and must not exceed 32 entries. + items: + description: |- + MachineConfigNodeStatusInternalReleaseImageRef is used to provide a more detailed reference for + a release bundle. + properties: + conditions: + description: |- + conditions represent the observations of an internal release image current state. Valid types are: + Mounted, Installing, Available, Removing and Degraded. + + If Mounted is true, that means that a valid ISO has been mounted on the current node. + If Installing is true, that means that a new release bundle is currently being copied on the current node, and not yet completed. + If Available is true, it means that the release has been previously installed on the current node, and it can be used. + If Removing is true, it means that a release deletion is in progress on the current node, and not yet completed. + If Degraded is true, that means something has gone wrong in the current node. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 5 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + image: + description: |- + image is an OCP release image referenced by digest. + The format of the image pull spec is: host[:port][/namespace]/name@sha256:, + where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. + The length of the whole spec must be between 1 to 447 characters. + The field is optional, and it will be provided after a release will be successfully installed. + 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-_.]*?$')) + name: + description: |- + name indicates the desired release bundle identifier. This field is required and must be between 1 and 64 characters long. + The expected name format is ocp-release-bundle--. + maxLength: 64 + minLength: 1 + type: string + x-kubernetes-validations: + - message: must be ocp-release-bundle-- + and <= 64 chars + rule: self.matches('^ocp-release-bundle-[0-9]+\\.[0-9]+\\.[0-9]+-[A-Za-z0-9._-]+$') + required: + - name + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - releases + type: object + irreconcilableChanges: + description: |- + irreconcilableChanges is an optional field that contains the observed differences between this nodes + configuration and the target rendered MachineConfig. + This field will be set when there are changes to the target rendered MachineConfig that can only be applied to + new nodes joining the cluster. + Entries must be unique, keyed on the fieldPath field. + Must not exceed 32 entries. + items: + description: |- + IrreconcilableChangeDiff holds an individual diff between the initial install-time MachineConfig + and the latest applied one caused by the presence of irreconcilable changes. + properties: + diff: + description: |- + diff is a required field containing the difference between the nodes current configuration and the latest + rendered MachineConfig for the field specified in fieldPath. + Must not be an empty string and must not exceed 4096 characters in length. + maxLength: 4096 + minLength: 1 + type: string + fieldPath: + description: |- + fieldPath is a required reference to the path in the latest rendered MachineConfig that differs from this nodes + configuration. + Must not be empty and must not exceed 70 characters in length. + Must begin with the prefix 'spec.' and only contain alphanumeric characters, square brackets ('[]'), or dots ('.'). + maxLength: 70 + minLength: 1 + type: string + x-kubernetes-validations: + - message: The fieldPath must start with `spec.` + rule: self.startsWith('spec.') + - message: The fieldPath must consist only of alphanumeric characters, + brackets [] and dots ('.'). + rule: self.matches('^[\\da-zA-Z\\.\\[\\]]+$') + required: + - diff + - fieldPath + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - fieldPath + x-kubernetes-list-type: map + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-Default.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-Default.crd.yaml new file mode 100644 index 0000000..84e5ff7 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-Default.crd.yaml @@ -0,0 +1,383 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/feature-set: Default + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + 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: spec describes the configuration of the machine config node. + properties: + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000..1d9dd0d --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -0,0 +1,631 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/feature-set: DevPreviewNoUpgrade + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + 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: spec describes the configuration of the machine config node. + properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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: + - desiredImage + type: object + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + type: object + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + internalReleaseImage: + description: |- + internalReleaseImage describes the status of the release payloads stored in the node. + When specified, an internalReleaseImage custom resource exists on the cluster, and the specified images will be made available on the control plane nodes. + This field will reflect the actual on-disk state of those release images. + properties: + releases: + description: |- + releases is a list of the release bundles currently owned and managed by the + cluster. + A release bundle content could be safely pulled only when its Conditions field + contains at least an Available entry set to "True" and Degraded to "False". + Entries must be unique, keyed on the name field. + releases must contain at least one entry and must not exceed 32 entries. + items: + description: |- + MachineConfigNodeStatusInternalReleaseImageRef is used to provide a more detailed reference for + a release bundle. + properties: + conditions: + description: |- + conditions represent the observations of an internal release image current state. Valid types are: + Mounted, Installing, Available, Removing and Degraded. + + If Mounted is true, that means that a valid ISO has been mounted on the current node. + If Installing is true, that means that a new release bundle is currently being copied on the current node, and not yet completed. + If Available is true, it means that the release has been previously installed on the current node, and it can be used. + If Removing is true, it means that a release deletion is in progress on the current node, and not yet completed. + If Degraded is true, that means something has gone wrong in the current node. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 5 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + image: + description: |- + image is an OCP release image referenced by digest. + The format of the image pull spec is: host[:port][/namespace]/name@sha256:, + where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. + The length of the whole spec must be between 1 to 447 characters. + The field is optional, and it will be provided after a release will be successfully installed. + 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-_.]*?$')) + name: + description: |- + name indicates the desired release bundle identifier. This field is required and must be between 1 and 64 characters long. + The expected name format is ocp-release-bundle--. + maxLength: 64 + minLength: 1 + type: string + x-kubernetes-validations: + - message: must be ocp-release-bundle-- + and <= 64 chars + rule: self.matches('^ocp-release-bundle-[0-9]+\\.[0-9]+\\.[0-9]+-[A-Za-z0-9._-]+$') + required: + - name + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - releases + type: object + irreconcilableChanges: + description: |- + irreconcilableChanges is an optional field that contains the observed differences between this nodes + configuration and the target rendered MachineConfig. + This field will be set when there are changes to the target rendered MachineConfig that can only be applied to + new nodes joining the cluster. + Entries must be unique, keyed on the fieldPath field. + Must not exceed 32 entries. + items: + description: |- + IrreconcilableChangeDiff holds an individual diff between the initial install-time MachineConfig + and the latest applied one caused by the presence of irreconcilable changes. + properties: + diff: + description: |- + diff is a required field containing the difference between the nodes current configuration and the latest + rendered MachineConfig for the field specified in fieldPath. + Must not be an empty string and must not exceed 4096 characters in length. + maxLength: 4096 + minLength: 1 + type: string + fieldPath: + description: |- + fieldPath is a required reference to the path in the latest rendered MachineConfig that differs from this nodes + configuration. + Must not be empty and must not exceed 70 characters in length. + Must begin with the prefix 'spec.' and only contain alphanumeric characters, square brackets ('[]'), or dots ('.'). + maxLength: 70 + minLength: 1 + type: string + x-kubernetes-validations: + - message: The fieldPath must start with `spec.` + rule: self.startsWith('spec.') + - message: The fieldPath must consist only of alphanumeric characters, + brackets [] and dots ('.'). + rule: self.matches('^[\\da-zA-Z\\.\\[\\]]+$') + required: + - diff + - fieldPath + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - fieldPath + x-kubernetes-list-type: map + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000..620b175 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfignodes-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,631 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/feature-set: TechPreviewNoUpgrade + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + 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: spec describes the configuration of the machine config node. + properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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: + - desiredImage + type: object + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + 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-_.]*?$')) + type: object + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + internalReleaseImage: + description: |- + internalReleaseImage describes the status of the release payloads stored in the node. + When specified, an internalReleaseImage custom resource exists on the cluster, and the specified images will be made available on the control plane nodes. + This field will reflect the actual on-disk state of those release images. + properties: + releases: + description: |- + releases is a list of the release bundles currently owned and managed by the + cluster. + A release bundle content could be safely pulled only when its Conditions field + contains at least an Available entry set to "True" and Degraded to "False". + Entries must be unique, keyed on the name field. + releases must contain at least one entry and must not exceed 32 entries. + items: + description: |- + MachineConfigNodeStatusInternalReleaseImageRef is used to provide a more detailed reference for + a release bundle. + properties: + conditions: + description: |- + conditions represent the observations of an internal release image current state. Valid types are: + Mounted, Installing, Available, Removing and Degraded. + + If Mounted is true, that means that a valid ISO has been mounted on the current node. + If Installing is true, that means that a new release bundle is currently being copied on the current node, and not yet completed. + If Available is true, it means that the release has been previously installed on the current node, and it can be used. + If Removing is true, it means that a release deletion is in progress on the current node, and not yet completed. + If Degraded is true, that means something has gone wrong in the current node. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 5 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + image: + description: |- + image is an OCP release image referenced by digest. + The format of the image pull spec is: host[:port][/namespace]/name@sha256:, + where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. + The length of the whole spec must be between 1 to 447 characters. + The field is optional, and it will be provided after a release will be successfully installed. + 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-_.]*?$')) + name: + description: |- + name indicates the desired release bundle identifier. This field is required and must be between 1 and 64 characters long. + The expected name format is ocp-release-bundle--. + maxLength: 64 + minLength: 1 + type: string + x-kubernetes-validations: + - message: must be ocp-release-bundle-- + and <= 64 chars + rule: self.matches('^ocp-release-bundle-[0-9]+\\.[0-9]+\\.[0-9]+-[A-Za-z0-9._-]+$') + required: + - name + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - releases + type: object + irreconcilableChanges: + description: |- + irreconcilableChanges is an optional field that contains the observed differences between this nodes + configuration and the target rendered MachineConfig. + This field will be set when there are changes to the target rendered MachineConfig that can only be applied to + new nodes joining the cluster. + Entries must be unique, keyed on the fieldPath field. + Must not exceed 32 entries. + items: + description: |- + IrreconcilableChangeDiff holds an individual diff between the initial install-time MachineConfig + and the latest applied one caused by the presence of irreconcilable changes. + properties: + diff: + description: |- + diff is a required field containing the difference between the nodes current configuration and the latest + rendered MachineConfig for the field specified in fieldPath. + Must not be an empty string and must not exceed 4096 characters in length. + maxLength: 4096 + minLength: 1 + type: string + fieldPath: + description: |- + fieldPath is a required reference to the path in the latest rendered MachineConfig that differs from this nodes + configuration. + Must not be empty and must not exceed 70 characters in length. + Must begin with the prefix 'spec.' and only contain alphanumeric characters, square brackets ('[]'), or dots ('.'). + maxLength: 70 + minLength: 1 + type: string + x-kubernetes-validations: + - message: The fieldPath must start with `spec.` + rule: self.startsWith('spec.') + - message: The fieldPath must consist only of alphanumeric characters, + brackets [] and dots ('.'). + rule: self.matches('^[\\da-zA-Z\\.\\[\\]]+$') + required: + - diff + - fieldPath + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - fieldPath + x-kubernetes-list-type: map + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineconfigpools-CustomNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfigpools-CustomNoUpgrade.crd.yaml new file mode 100644 index 0000000..6dc75e2 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfigpools-CustomNoUpgrade.crd.yaml @@ -0,0 +1,670 @@ +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" + 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. + + 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: spec contains the desired machine config pool configuration. + 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. + 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. + 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. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + 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. + + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + osImageStream: + description: |- + osImageStream specifies an OS stream to be used for the pool. + + This field can be optionally set to a known OSImageStream name to change the + OS and Extension images with a well-known, tested, release-provided set of images. + This enables a streamlined way of switching the pool's node OS to a different version + than the cluster default, such as transitioning to a major RHEL version. + + When set, the referenced stream overrides the cluster-wide OS + images for the pool with the OS and Extensions associated to stream. + When omitted, the pool uses the cluster-wide default OS images. + properties: + name: + description: |- + name is a required reference to an OSImageStream to be used for the pool. + + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, + consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a RFC 1123 subdomain must consist of lower case alphanumeric + characters, '-' or '.', and must start and end with an alphanumeric + character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + 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. + + 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 + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: status contains observed information about the machine config + pool. + 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. + 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. + 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. + 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 + osImageStream: + description: |- + osImageStream specifies the last updated OSImageStream for the pool. + + When omitted, the pool is using the cluster-wide default OS images. + properties: + name: + description: |- + name is a required reference to an OSImageStream to be used for the pool. + + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, + consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a RFC 1123 subdomain must consist of lower case alphanumeric + characters, '-' or '.', and must start and end with an alphanumeric + character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + poolSynchronizersStatus: + description: poolSynchronizersStatus is the status of the machines + managed by the pool synchronizers. + items: + properties: + availableMachineCount: + description: availableMachineCount is the number of machines + managed by the node synchronizer which are available. + format: int64 + minimum: 0 + type: integer + machineCount: + description: machineCount is the number of machines that are + managed by the node synchronizer. + format: int64 + minimum: 0 + type: integer + observedGeneration: + description: observedGeneration is the last generation change + that has been applied. + format: int64 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not move backwards except + to zero + rule: self >= oldSelf || (self == 0 && oldSelf > 0) + poolSynchronizerType: + description: poolSynchronizerType describes the type of the + pool synchronizer. + enum: + - PinnedImageSets + maxLength: 256 + type: string + readyMachineCount: + description: readyMachineCount is the number of machines managed + by the node synchronizer that are in a ready state. + format: int64 + minimum: 0 + type: integer + unavailableMachineCount: + description: unavailableMachineCount is the number of machines + managed by the node synchronizer but are unavailable. + format: int64 + minimum: 0 + type: integer + updatedMachineCount: + description: updatedMachineCount is the number of machines that + have been updated by the node synchronizer. + format: int64 + minimum: 0 + type: integer + required: + - availableMachineCount + - machineCount + - poolSynchronizerType + - readyMachineCount + - unavailableMachineCount + - updatedMachineCount + type: object + x-kubernetes-validations: + - message: machineCount must be greater than or equal to updatedMachineCount + rule: self.machineCount >= self.updatedMachineCount + - message: machineCount must be greater than or equal to availableMachineCount + rule: self.machineCount >= self.availableMachineCount + - message: machineCount must be greater than or equal to unavailableMachineCount + rule: self.machineCount >= self.unavailableMachineCount + - message: machineCount must be greater than or equal to readyMachineCount + rule: self.machineCount >= self.readyMachineCount + - message: availableMachineCount must be greater than or equal to + readyMachineCount + rule: self.availableMachineCount >= self.readyMachineCount + type: array + x-kubernetes-list-map-keys: + - poolSynchronizerType + x-kubernetes-list-type: map + 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/config/crd/external/0000_80_machine-config_01_machineconfigpools-Default.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfigpools-Default.crd.yaml new file mode 100644 index 0000000..b551493 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfigpools-Default.crd.yaml @@ -0,0 +1,617 @@ +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" + release.openshift.io/feature-set: Default + 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. + + 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: spec contains the desired machine config pool configuration. + 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. + 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. + 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. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + 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. + + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + 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. + + 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 + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: status contains observed information about the machine config + pool. + 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. + 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. + 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. + 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 + poolSynchronizersStatus: + description: poolSynchronizersStatus is the status of the machines + managed by the pool synchronizers. + items: + properties: + availableMachineCount: + description: availableMachineCount is the number of machines + managed by the node synchronizer which are available. + format: int64 + minimum: 0 + type: integer + machineCount: + description: machineCount is the number of machines that are + managed by the node synchronizer. + format: int64 + minimum: 0 + type: integer + observedGeneration: + description: observedGeneration is the last generation change + that has been applied. + format: int64 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not move backwards except + to zero + rule: self >= oldSelf || (self == 0 && oldSelf > 0) + poolSynchronizerType: + description: poolSynchronizerType describes the type of the + pool synchronizer. + enum: + - PinnedImageSets + maxLength: 256 + type: string + readyMachineCount: + description: readyMachineCount is the number of machines managed + by the node synchronizer that are in a ready state. + format: int64 + minimum: 0 + type: integer + unavailableMachineCount: + description: unavailableMachineCount is the number of machines + managed by the node synchronizer but are unavailable. + format: int64 + minimum: 0 + type: integer + updatedMachineCount: + description: updatedMachineCount is the number of machines that + have been updated by the node synchronizer. + format: int64 + minimum: 0 + type: integer + required: + - availableMachineCount + - machineCount + - poolSynchronizerType + - readyMachineCount + - unavailableMachineCount + - updatedMachineCount + type: object + x-kubernetes-validations: + - message: machineCount must be greater than or equal to updatedMachineCount + rule: self.machineCount >= self.updatedMachineCount + - message: machineCount must be greater than or equal to availableMachineCount + rule: self.machineCount >= self.availableMachineCount + - message: machineCount must be greater than or equal to unavailableMachineCount + rule: self.machineCount >= self.unavailableMachineCount + - message: machineCount must be greater than or equal to readyMachineCount + rule: self.machineCount >= self.readyMachineCount + - message: availableMachineCount must be greater than or equal to + readyMachineCount + rule: self.availableMachineCount >= self.readyMachineCount + type: array + x-kubernetes-list-map-keys: + - poolSynchronizerType + x-kubernetes-list-type: map + 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/config/crd/external/0000_80_machine-config_01_machineconfigpools-DevPreviewNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfigpools-DevPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000..48688e4 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfigpools-DevPreviewNoUpgrade.crd.yaml @@ -0,0 +1,670 @@ +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" + release.openshift.io/feature-set: DevPreviewNoUpgrade + 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. + + 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: spec contains the desired machine config pool configuration. + 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. + 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. + 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. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + 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. + + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + osImageStream: + description: |- + osImageStream specifies an OS stream to be used for the pool. + + This field can be optionally set to a known OSImageStream name to change the + OS and Extension images with a well-known, tested, release-provided set of images. + This enables a streamlined way of switching the pool's node OS to a different version + than the cluster default, such as transitioning to a major RHEL version. + + When set, the referenced stream overrides the cluster-wide OS + images for the pool with the OS and Extensions associated to stream. + When omitted, the pool uses the cluster-wide default OS images. + properties: + name: + description: |- + name is a required reference to an OSImageStream to be used for the pool. + + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, + consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a RFC 1123 subdomain must consist of lower case alphanumeric + characters, '-' or '.', and must start and end with an alphanumeric + character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + 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. + + 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 + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: status contains observed information about the machine config + pool. + 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. + 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. + 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. + 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 + osImageStream: + description: |- + osImageStream specifies the last updated OSImageStream for the pool. + + When omitted, the pool is using the cluster-wide default OS images. + properties: + name: + description: |- + name is a required reference to an OSImageStream to be used for the pool. + + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, + consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a RFC 1123 subdomain must consist of lower case alphanumeric + characters, '-' or '.', and must start and end with an alphanumeric + character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + poolSynchronizersStatus: + description: poolSynchronizersStatus is the status of the machines + managed by the pool synchronizers. + items: + properties: + availableMachineCount: + description: availableMachineCount is the number of machines + managed by the node synchronizer which are available. + format: int64 + minimum: 0 + type: integer + machineCount: + description: machineCount is the number of machines that are + managed by the node synchronizer. + format: int64 + minimum: 0 + type: integer + observedGeneration: + description: observedGeneration is the last generation change + that has been applied. + format: int64 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not move backwards except + to zero + rule: self >= oldSelf || (self == 0 && oldSelf > 0) + poolSynchronizerType: + description: poolSynchronizerType describes the type of the + pool synchronizer. + enum: + - PinnedImageSets + maxLength: 256 + type: string + readyMachineCount: + description: readyMachineCount is the number of machines managed + by the node synchronizer that are in a ready state. + format: int64 + minimum: 0 + type: integer + unavailableMachineCount: + description: unavailableMachineCount is the number of machines + managed by the node synchronizer but are unavailable. + format: int64 + minimum: 0 + type: integer + updatedMachineCount: + description: updatedMachineCount is the number of machines that + have been updated by the node synchronizer. + format: int64 + minimum: 0 + type: integer + required: + - availableMachineCount + - machineCount + - poolSynchronizerType + - readyMachineCount + - unavailableMachineCount + - updatedMachineCount + type: object + x-kubernetes-validations: + - message: machineCount must be greater than or equal to updatedMachineCount + rule: self.machineCount >= self.updatedMachineCount + - message: machineCount must be greater than or equal to availableMachineCount + rule: self.machineCount >= self.availableMachineCount + - message: machineCount must be greater than or equal to unavailableMachineCount + rule: self.machineCount >= self.unavailableMachineCount + - message: machineCount must be greater than or equal to readyMachineCount + rule: self.machineCount >= self.readyMachineCount + - message: availableMachineCount must be greater than or equal to + readyMachineCount + rule: self.availableMachineCount >= self.readyMachineCount + type: array + x-kubernetes-list-map-keys: + - poolSynchronizerType + x-kubernetes-list-type: map + 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/config/crd/external/0000_80_machine-config_01_machineconfigpools-TechPreviewNoUpgrade.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfigpools-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000..12bb88d --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfigpools-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,670 @@ +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" + 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. + + 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: spec contains the desired machine config pool configuration. + 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. + 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. + 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. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + 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. + + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + osImageStream: + description: |- + osImageStream specifies an OS stream to be used for the pool. + + This field can be optionally set to a known OSImageStream name to change the + OS and Extension images with a well-known, tested, release-provided set of images. + This enables a streamlined way of switching the pool's node OS to a different version + than the cluster default, such as transitioning to a major RHEL version. + + When set, the referenced stream overrides the cluster-wide OS + images for the pool with the OS and Extensions associated to stream. + When omitted, the pool uses the cluster-wide default OS images. + properties: + name: + description: |- + name is a required reference to an OSImageStream to be used for the pool. + + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, + consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a RFC 1123 subdomain must consist of lower case alphanumeric + characters, '-' or '.', and must start and end with an alphanumeric + character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + 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. + + 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 + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: status contains observed information about the machine config + pool. + 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. + 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. + 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. + 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 + osImageStream: + description: |- + osImageStream specifies the last updated OSImageStream for the pool. + + When omitted, the pool is using the cluster-wide default OS images. + properties: + name: + description: |- + name is a required reference to an OSImageStream to be used for the pool. + + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, + consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a RFC 1123 subdomain must consist of lower case alphanumeric + characters, '-' or '.', and must start and end with an alphanumeric + character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + poolSynchronizersStatus: + description: poolSynchronizersStatus is the status of the machines + managed by the pool synchronizers. + items: + properties: + availableMachineCount: + description: availableMachineCount is the number of machines + managed by the node synchronizer which are available. + format: int64 + minimum: 0 + type: integer + machineCount: + description: machineCount is the number of machines that are + managed by the node synchronizer. + format: int64 + minimum: 0 + type: integer + observedGeneration: + description: observedGeneration is the last generation change + that has been applied. + format: int64 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not move backwards except + to zero + rule: self >= oldSelf || (self == 0 && oldSelf > 0) + poolSynchronizerType: + description: poolSynchronizerType describes the type of the + pool synchronizer. + enum: + - PinnedImageSets + maxLength: 256 + type: string + readyMachineCount: + description: readyMachineCount is the number of machines managed + by the node synchronizer that are in a ready state. + format: int64 + minimum: 0 + type: integer + unavailableMachineCount: + description: unavailableMachineCount is the number of machines + managed by the node synchronizer but are unavailable. + format: int64 + minimum: 0 + type: integer + updatedMachineCount: + description: updatedMachineCount is the number of machines that + have been updated by the node synchronizer. + format: int64 + minimum: 0 + type: integer + required: + - availableMachineCount + - machineCount + - poolSynchronizerType + - readyMachineCount + - unavailableMachineCount + - updatedMachineCount + type: object + x-kubernetes-validations: + - message: machineCount must be greater than or equal to updatedMachineCount + rule: self.machineCount >= self.updatedMachineCount + - message: machineCount must be greater than or equal to availableMachineCount + rule: self.machineCount >= self.availableMachineCount + - message: machineCount must be greater than or equal to unavailableMachineCount + rule: self.machineCount >= self.unavailableMachineCount + - message: machineCount must be greater than or equal to readyMachineCount + rule: self.machineCount >= self.readyMachineCount + - message: availableMachineCount must be greater than or equal to + readyMachineCount + rule: self.availableMachineCount >= self.readyMachineCount + type: array + x-kubernetes-list-map-keys: + - poolSynchronizerType + x-kubernetes-list-type: map + 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/config/crd/external/0000_80_machine-config_01_machineconfigs.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineconfigs.crd.yaml new file mode 100644 index 0000000..df90d44 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineconfigs.crd.yaml @@ -0,0 +1,104 @@ +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" + labels: + openshift.io/operator-managed: "" + name: machineconfigs.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfig + listKind: MachineConfigList + plural: machineconfigs + shortNames: + - mc + singular: machineconfig + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Version of the controller that generated the machineconfig. This + will be empty if the machineconfig is not managed by a controller. + jsonPath: .metadata.annotations.machineconfiguration\.openshift\.io/generated-by-controller-version + name: GeneratedByController + type: string + - description: Version of the Ignition Config defined in the machineconfig. + jsonPath: .spec.config.ignition.version + name: IgnitionVersion + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfig defines the configuration for a machine + + 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: MachineConfigSpec is the spec for MachineConfig + properties: + baseOSExtensionsContainerImage: + description: |- + baseOSExtensionsContainerImage specifies the remote location that will be used + to fetch the extensions container matching a new-format OS image + type: string + config: + description: config is a Ignition Config object. + type: object + x-kubernetes-preserve-unknown-fields: true + extensions: + description: extensions contains a list of additional features that + can be enabled on host + items: + type: string + type: array + x-kubernetes-list-type: atomic + fips: + description: fips controls FIPS mode + type: boolean + kernelArguments: + description: kernelArguments contains a list of kernel arguments to + be added + items: + type: string + nullable: true + type: array + x-kubernetes-list-type: atomic + kernelType: + description: |- + kernelType contains which kernel we want to be running like default + (traditional), realtime, 64k-pages (aarch64 only). + type: string + osImageURL: + description: |- + osImageURL specifies the remote location that will be used to + fetch the OS. + type: string + type: object + type: object + served: true + storage: true diff --git a/config/crd/external/0000_80_machine-config_01_machineosbuilds.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineosbuilds.crd.yaml new file mode 100644 index 0000000..23880a3 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineosbuilds.crd.yaml @@ -0,0 +1,403 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2090 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + labels: + openshift.io/operator-managed: "" + name: machineosbuilds.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineOSBuild + listKind: MachineOSBuildList + plural: machineosbuilds + singular: machineosbuild + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Prepared")].status + name: Prepared + type: string + - jsonPath: .status.conditions[?(@.type=="Building")].status + name: Building + type: string + - jsonPath: .status.conditions[?(@.type=="Succeeded")].status + name: Succeeded + type: string + - jsonPath: .status.conditions[?(@.type=="Interrupted")].status + name: Interrupted + type: string + - jsonPath: .status.conditions[?(@.type=="Failed")].status + name: Failed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineOSBuild describes a build process managed and deployed by the MCO + 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: |- + spec describes the configuration of the machine os build. + It is immutable once set. + properties: + machineConfig: + description: machineConfig points to the rendered MachineConfig resource + to be included in this image build. + properties: + name: + description: |- + name is the name of the rendered MachineConfig object. + This value should be between 10 and 253 characters, and must contain only lowercase + alphanumeric characters, hyphens and periods, and should start and end with an alphanumeric character. + maxLength: 253 + minLength: 10 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + machineOSConfig: + description: machineOSConfig references the MachineOSConfig resource + that this image build extends. + properties: + name: + description: |- + name of the MachineOSConfig. + The name must contain only lowercase alphanumeric characters, '-' or '.' and start/end with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + renderedImagePushSpec: + description: |- + renderedImagePushSpec is set by the Machine Config Operator from the MachineOSConfig object this build is attached to. + This field describes the location of the final image, which will be pushed by the build once complete. + The format of the image push spec is: host[:port][/namespace]/name: or svc_name.namespace.svc[:port]/repository/name:. + The length of the push spec must be between 1 to 447 characters. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme. Or it must + be a valid .svc followed by a port, repository, image name, and + tag. + rule: self.matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?(/[a-zA-Z0-9-_]{1,61})*/[a-zA-Z0-9-_.]+:[a-zA-Z0-9._-]+$') + || self.matches('^[^.]+\\.[^.]+\\.svc:\\d+\\/[^\\/]+\\/[^\\/]+:[^\\/]+$') + required: + - machineConfig + - machineOSConfig + - renderedImagePushSpec + type: object + x-kubernetes-validations: + - message: machineOSBuildSpec is immutable once set + rule: self == oldSelf + status: + description: status describes the last observed state of this machine + os build. + properties: + buildEnd: + description: |- + buildEnd is the timestamp corresponding to completion of the builder backend. + When omitted the build has either not been started, or is in progress. + It will be populated once the build completes, fails or is interrupted. + format: date-time + type: string + x-kubernetes-validations: + - message: buildEnd is immutable once set + rule: self == oldSelf + buildStart: + description: buildStart is the timestamp corresponding to the build + controller initiating the build backend for this MachineOSBuild. + format: date-time + type: string + x-kubernetes-validations: + - message: buildStart is immutable once set + rule: self == oldSelf + builder: + description: builder describes the image builder backend used for + this build. + properties: + imageBuilderType: + description: |- + imageBuilderType describes the type of image builder used to build this image. + Valid values are Job only. + When set to Job, a pod based builder, using buildah, is launched to build the specified image. + type: string + job: + description: |- + job is a reference to the job object that is managing the image build. + This is required if the imageBuilderType is Job, and forbidden otherwise. + properties: + group: + description: |- + group of the referent. + The name must contain only lowercase alphanumeric characters, '-' or '.' and start/end with an alphanumeric character. + Example: "", "apps", "build.openshift.io", etc. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of + lower case alphanumeric characters, '-' or '.', and must + start and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + name: + description: |- + name of the referent. + The name must contain only lowercase alphanumeric characters, '-' or '.' and start/end with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of + lower case alphanumeric characters, '-' or '.', and must + start and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + namespace: + description: |- + namespace of the referent. + This value should consist of at most 63 characters, and of only lowercase alphanumeric characters and hyphens, + and should start and end with an alphanumeric character. + maxLength: 63 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the value must consist of only lowercase alphanumeric + characters and hyphens + rule: '!format.dns1123Label().validate(self).hasValue()' + resource: + description: |- + resource of the referent. + This value should consist of at most 63 characters, and of only lowercase alphanumeric characters and hyphens, + and should start with an alphabetic character and end with an alphanumeric character. + Example: "deployments", "deploymentconfigs", "pods", etc. + maxLength: 63 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a DNS-1035 label must consist of lower case alphanumeric + characters or '-', start with an alphabetic character, + and end with an alphanumeric character + rule: '!format.dns1035Label().validate(self).hasValue()' + required: + - group + - name + - resource + type: object + required: + - imageBuilderType + type: object + x-kubernetes-validations: + - message: job is required when imageBuilderType is Job, and forbidden + otherwise + rule: 'has(self.imageBuilderType) && self.imageBuilderType == ''Job'' + ? has(self.job) : !has(self.job)' + conditions: + description: |- + conditions are state related conditions for the build. Valid types are: + Prepared, Building, Failed, Interrupted, and Succeeded. + Once a Build is marked as Failed, Interrupted or Succeeded, no future conditions can be set. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: once a Failed condition is set, conditions are immutable + rule: 'oldSelf.exists(x, x.type==''Failed'' && x.status==''True'') + ? self==oldSelf : true' + - message: once an Interrupted condition is set, conditions are immutable + rule: 'oldSelf.exists(x, x.type==''Interrupted'' && x.status==''True'') + ? self==oldSelf : true' + - message: once an Succeeded condition is set, conditions are immutable + rule: 'oldSelf.exists(x, x.type==''Succeeded'' && x.status==''True'') + ? self==oldSelf : true' + digestedImagePushSpec: + description: |- + digestedImagePushSpec describes the fully qualified push spec produced by this build. + The format of the push spec is: host[:port][/namespace]/name@sha256:, + where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. + The length of the whole spec must be between 1 to 447 characters. + 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-_.]*?$')) + relatedObjects: + description: |- + relatedObjects is a list of references to ephemeral objects such as ConfigMaps or Secrets that are meant to be consumed while the build process runs. + After a successful build or when this MachineOSBuild is deleted, these ephemeral objects will be removed. + In the event of a failed build, the objects will remain until the build is removed to allow for inspection. + items: + description: ObjectReference contains enough information to let + you inspect or modify the referred object. + properties: + group: + description: |- + group of the referent. + The name must contain only lowercase alphanumeric characters, '-' or '.' and start/end with an alphanumeric character. + Example: "", "apps", "build.openshift.io", etc. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + name: + description: |- + name of the referent. + The name must contain only lowercase alphanumeric characters, '-' or '.' and start/end with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + namespace: + description: |- + namespace of the referent. + This value should consist of at most 63 characters, and of only lowercase alphanumeric characters and hyphens, + and should start and end with an alphanumeric character. + maxLength: 63 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the value must consist of only lowercase alphanumeric + characters and hyphens + rule: '!format.dns1123Label().validate(self).hasValue()' + resource: + description: |- + resource of the referent. + This value should consist of at most 63 characters, and of only lowercase alphanumeric characters and hyphens, + and should start with an alphabetic character and end with an alphanumeric character. + Example: "deployments", "deploymentconfigs", "pods", etc. + maxLength: 63 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a DNS-1035 label must consist of lower case alphanumeric + characters or '-', start with an alphabetic character, and + end with an alphanumeric character + rule: '!format.dns1035Label().validate(self).hasValue()' + required: + - group + - name + - resource + type: object + maxItems: 10 + type: array + x-kubernetes-list-map-keys: + - name + - resource + x-kubernetes-list-type: map + type: object + x-kubernetes-validations: + - message: buildEnd must be after buildStart + rule: 'has(self.buildEnd) ? has(self.buildStart) && timestamp(self.buildStart) + < timestamp(self.buildEnd) : true' + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_machineosconfigs.crd.yaml b/config/crd/external/0000_80_machine-config_01_machineosconfigs.crd.yaml new file mode 100644 index 0000000..d151571 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_machineosconfigs.crd.yaml @@ -0,0 +1,357 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2090 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + labels: + openshift.io/operator-managed: "" + name: machineosconfigs.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineOSConfig + listKind: MachineOSConfigList + plural: machineosconfigs + singular: machineosconfig + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + MachineOSConfig describes the configuration for a build process managed by the MCO + 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: spec describes the configuration of the machineosconfig + properties: + baseImagePullSecret: + description: |- + baseImagePullSecret is the secret used to pull the base image. + Must live in the openshift-machine-config-operator namespace if provided. + Defaults to using the cluster-wide pull secret if not specified. This is provided during install time of the cluster, and lives in the openshift-config namespace as a secret. + properties: + name: + description: |- + name is the name of the secret used to push or pull this MachineOSConfig object. + Must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character. + This secret must be in the openshift-machine-config-operator namespace. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + containerFile: + description: |- + containerFile describes the custom data the user has specified to build into the image. + This is also commonly called a Dockerfile and you can treat it as such. The content is the content of your Dockerfile. + See https://github.com/containers/common/blob/main/docs/Containerfile.5.md for the spec reference. + This is a list indexed by architecture name (e.g. AMD64), and allows specifying one containerFile per arch, up to 4. + items: + description: MachineOSContainerfile contains all custom content + the user wants built into the image + properties: + containerfileArch: + default: NoArch + description: |- + containerfileArch describes the architecture this containerfile is to be built for. + This arch is optional. If the user does not specify an architecture, it is assumed + that the content can be applied to all architectures, or in a single arch cluster: the only architecture. + enum: + - ARM64 + - AMD64 + - PPC64LE + - S390X + - NoArch + type: string + content: + description: |- + content is an embedded Containerfile/Dockerfile that defines the contents to be built into your image. + See https://github.com/containers/common/blob/main/docs/Containerfile.5.md for the spec reference. + for example, this would add the tree package to your hosts: + FROM configs AS final + RUN rpm-ostree install tree && \ + ostree container commit + This is a required field and can have a maximum length of **4096** characters. + maxLength: 4096 + type: string + required: + - content + type: object + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - containerfileArch + x-kubernetes-list-type: map + imageBuilder: + description: |- + imageBuilder describes which image builder will be used in each build triggered by this MachineOSConfig. + Currently supported type(s): Job + properties: + imageBuilderType: + description: |- + imageBuilderType specifies the backend to be used to build the image. + Valid options are: Job + enum: + - Job + type: string + required: + - imageBuilderType + type: object + machineConfigPool: + description: |- + machineConfigPool is the pool which the build is for. + The Machine Config Operator will perform the build and roll out the built image to the specified pool. + properties: + name: + description: |- + name of the MachineConfigPool object. + This value should be at most 253 characters, and must contain only lowercase + alphanumeric characters, hyphens and periods, and should start and end with an alphanumeric character. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + renderedImagePushSecret: + description: |- + renderedImagePushSecret is the secret used to connect to a user registry. + The final image push and pull secrets should be separate and assume the principal of least privilege. + The push secret with write privilege is only required to be present on the node hosting the MachineConfigController pod. + The pull secret with read only privileges is required on all nodes. + By separating the two secrets, the risk of write credentials becoming compromised is reduced. + properties: + name: + description: |- + name is the name of the secret used to push or pull this MachineOSConfig object. + Must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character. + This secret must be in the openshift-machine-config-operator namespace. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + renderedImagePushSpec: + description: |- + renderedImagePushSpec describes the location of the final image. + The MachineOSConfig object will use the in cluster image registry configuration. + If you wish to use a mirror or any other settings specific to registries.conf, please specify those in the cluster wide registries.conf via the cluster image.config, ImageContentSourcePolicies, ImageDigestMirrorSet, or ImageTagMirrorSet objects. + The format of the image push spec is: host[:port][/namespace]/name: or svc_name.namespace.svc[:port]/repository/name:. + The length of the push spec must be between 1 to 447 characters. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme. Or it must + be a valid .svc followed by a port, repository, image name, and + tag. + rule: self.matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?(/[a-zA-Z0-9-_]{1,61})*/[a-zA-Z0-9-_.]+:[a-zA-Z0-9._-]+$') + || self.matches('^[^.]+\\.[^.]+\\.svc:\\d+\\/[^\\/]+\\/[^\\/]+:[^\\/]+$') + required: + - imageBuilder + - machineConfigPool + - renderedImagePushSecret + - renderedImagePushSpec + type: object + status: + description: status describes the status of the machineosconfig + properties: + conditions: + description: conditions are state related conditions for the object. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentImagePullSpec: + description: |- + currentImagePullSpec is the fully qualified image pull spec used by the MCO to pull down the new OSImage. This includes the sha256 image digest. + This is generated when the Machine Config Operator's build controller successfully completes the build, and is populated from the corresponding + MachineOSBuild object's FinalImagePushSpec. This may change after completion in reaction to spec changes that would cause a new image build, + but will not be removed. + The format of the image pull spec is: host[:port][/namespace]/name@sha256:, + where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. + The length of the whole spec must be between 1 to 447 characters. + 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-_.]*?$')) + machineOSBuild: + description: machineOSBuild is a reference to the MachineOSBuild object + for this MachineOSConfig, which contains the status for the image + build. + properties: + group: + description: |- + group of the referent. + The name must contain only lowercase alphanumeric characters, '-' or '.' and start/end with an alphanumeric character. + Example: "", "apps", "build.openshift.io", etc. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + name: + description: |- + name of the referent. + The name must contain only lowercase alphanumeric characters, '-' or '.' and start/end with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + namespace: + description: |- + namespace of the referent. + This value should consist of at most 63 characters, and of only lowercase alphanumeric characters and hyphens, + and should start and end with an alphanumeric character. + maxLength: 63 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the value must consist of only lowercase alphanumeric + characters and hyphens + rule: '!format.dns1123Label().validate(self).hasValue()' + resource: + description: |- + resource of the referent. + This value should consist of at most 63 characters, and of only lowercase alphanumeric characters and hyphens, + and should start with an alphabetic character and end with an alphanumeric character. + Example: "deployments", "deploymentconfigs", "pods", etc. + maxLength: 63 + minLength: 1 + type: string + x-kubernetes-validations: + - message: a DNS-1035 label must consist of lower case alphanumeric + characters or '-', start with an alphabetic character, and + end with an alphanumeric character + rule: '!format.dns1035Label().validate(self).hasValue()' + required: + - group + - name + - resource + type: object + observedGeneration: + description: observedGeneration represents the generation of the MachineOSConfig + object observed by the Machine Config Operator's build controller. + format: int64 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not move backwards + rule: self >= oldSelf + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: MachineOSConfig name must match the referenced MachineConfigPool + name; can only have one MachineOSConfig per MachineConfigPool + optionalOldSelf: true + rule: self.metadata.name == self.spec.machineConfigPool.name || oldSelf.hasValue() + && oldSelf.spec.machineConfigPool.name.value() == self.spec.machineConfigPool.name + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/external/0000_80_machine-config_01_pinnedimagesets.crd.yaml b/config/crd/external/0000_80_machine-config_01_pinnedimagesets.crd.yaml new file mode 100644 index 0000000..49fd8d5 --- /dev/null +++ b/config/crd/external/0000_80_machine-config_01_pinnedimagesets.crd.yaml @@ -0,0 +1,101 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2198 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "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: v1 + 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. + + 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: 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: + + 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:...", + ... + ] + + Image references must be by digest. + A maximum of 500 images may be specified. + items: + description: PinnedImageRef represents a reference to an OCI image + properties: + name: + description: |- + name is an OCI Image referenced by digest. + The format of the image pull spec is: host[:port][/namespace]/name@sha256:, + where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. + The length of the whole spec must be between 1 to 447 characters. + 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/config/default/kustomization.yaml b/config/default/kustomization.yaml index 23661d5..1a8ea61 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -1,234 +1,16 @@ -# Adds namespace to all resources. -namespace: swap-operator-system - -# Value of this field is prepended to the -# names of all resources, e.g. a deployment named -# "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. +namespace: swap-operator namePrefix: swap-operator- - -# Labels to add to all resources and selectors. -#labels: -#- includeSelectors: true -# pairs: -# someName: someValue - resources: - ../crd - ../rbac - ../manager -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -#- ../webhook -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus -# [METRICS] Expose the controller manager metrics service. - metrics_service.yaml -# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. -# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. -# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will -# be able to communicate with the Webhook Server. -#- ../network-policy -# Uncomment the patches line if you enable Metrics patches: -# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. -# More info: https://book.kubebuilder.io/reference/metrics - path: manager_metrics_patch.yaml target: kind: Deployment - -# Uncomment the patches line if you enable Metrics and CertManager -# [METRICS-WITH-CERTS] To enable metrics protected with certManager, uncomment the following line. -# This patch will protect the metrics with certManager self-signed certs. -#- path: cert_metrics_manager_patch.yaml -# target: -# kind: Deployment - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -#- path: manager_webhook_patch.yaml -# target: -# kind: Deployment - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -# Uncomment the following replacements to add the cert-manager CA injection annotations -#replacements: -# - source: # Uncomment the following block to enable certificates for metrics -# kind: Service -# version: v1 -# name: controller-manager-metrics-service -# fieldPath: metadata.name -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: metrics-certs -# fieldPaths: -# - spec.dnsNames.0 -# - spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 0 -# create: true -# - select: # Uncomment the following to set the Service name for TLS config in Prometheus ServiceMonitor -# kind: ServiceMonitor -# group: monitoring.coreos.com -# version: v1 -# name: controller-manager-metrics-monitor -# fieldPaths: -# - spec.endpoints.0.tlsConfig.serverName -# options: -# delimiter: '.' -# index: 0 -# create: true - -# - source: -# kind: Service -# version: v1 -# name: controller-manager-metrics-service -# fieldPath: metadata.namespace -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: metrics-certs -# fieldPaths: -# - spec.dnsNames.0 -# - spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 1 -# create: true -# - select: # Uncomment the following to set the Service namespace for TLS in Prometheus ServiceMonitor -# kind: ServiceMonitor -# group: monitoring.coreos.com -# version: v1 -# name: controller-manager-metrics-monitor -# fieldPaths: -# - spec.endpoints.0.tlsConfig.serverName -# options: -# delimiter: '.' -# index: 1 -# create: true - -# - source: # Uncomment the following block if you have any webhook -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.name # Name of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 0 -# create: true -# - source: -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.namespace # Namespace of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 1 -# create: true - -# - source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # This name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPath: .metadata.name -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true - -# - source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting ) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPath: .metadata.name -# targets: -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true - -# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. -# +kubebuilder:scaffold:crdkustomizecainjectionns -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPath: .metadata.name -# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. -# +kubebuilder:scaffold:crdkustomizecainjectionname +- path: manager_image_pull_policy_patch.yaml + target: + kind: Deployment + name: controller-manager diff --git a/config/default/manager_image_pull_policy_patch.yaml b/config/default/manager_image_pull_policy_patch.yaml new file mode 100644 index 0000000..f115cf9 --- /dev/null +++ b/config/default/manager_image_pull_policy_patch.yaml @@ -0,0 +1,11 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + imagePullPolicy: Always \ No newline at end of file diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 5c5f0b8..d6168f5 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,2 +1,8 @@ resources: - manager.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: quay.io/openshift-virtualization/swap-operator + newTag: v0.1 diff --git a/config/production/cert_metrics_manager_patch.yaml b/config/production/cert_metrics_manager_patch.yaml new file mode 100644 index 0000000..d975015 --- /dev/null +++ b/config/production/cert_metrics_manager_patch.yaml @@ -0,0 +1,30 @@ +# This patch adds the args, volumes, and ports to allow the manager to use the metrics-server certs. + +# Add the volumeMount for the metrics-server certs +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: + mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + +# Add the --metrics-cert-path argument for the metrics server +- op: add + path: /spec/template/spec/containers/0/args/- + value: --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs + +# Add the metrics-server certs volume configuration +- op: add + path: /spec/template/spec/volumes/- + value: + name: metrics-certs + secret: + secretName: metrics-server-cert + optional: false + items: + - key: ca.crt + path: ca.crt + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key diff --git a/config/production/kustomization.backup b/config/production/kustomization.backup new file mode 100644 index 0000000..4de9460 --- /dev/null +++ b/config/production/kustomization.backup @@ -0,0 +1,234 @@ +# Adds namespace to all resources. +namespace: swap-operator + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: swap-operator- + +# Labels to add to all resources and selectors. +#labels: +#- includeSelectors: true +# pairs: +# someName: someValue + +resources: +- ../crd +- ../rbac +- ../manager +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +#- ../certmanager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus +# [METRICS] Expose the controller manager metrics service. +- metrics_service.yaml +# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. +# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. +# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will +# be able to communicate with the Webhook Server. +#- ../network-policy + +# Uncomment the patches line if you enable Metrics +patches: +# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. +# More info: https://book.kubebuilder.io/reference/metrics +- path: manager_metrics_patch.yaml + target: + kind: Deployment + +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS-WITH-CERTS] To enable metrics protected with certManager, uncomment the following line. +# This patch will protect the metrics with certManager self-signed certs. +#- path: cert_metrics_manager_patch.yaml +# target: +# kind: Deployment + +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- path: manager_webhook_patch.yaml +# target: +# kind: Deployment + +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +# Uncomment the following replacements to add the cert-manager CA injection annotations +#replacements: +# - source: # Uncomment the following block to enable certificates for metrics +# kind: Service +# version: v1 +# name: controller-manager-metrics-service +# fieldPath: metadata.name +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: metrics-certs +# fieldPaths: +# - spec.dnsNames.0 +# - spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 0 +# create: true +# - select: # Uncomment the following to set the Service name for TLS config in Prometheus ServiceMonitor +# kind: ServiceMonitor +# group: monitoring.coreos.com +# version: v1 +# name: controller-manager-metrics-monitor +# fieldPaths: +# - spec.endpoints.0.tlsConfig.serverName +# options: +# delimiter: '.' +# index: 0 +# create: true + +# - source: +# kind: Service +# version: v1 +# name: controller-manager-metrics-service +# fieldPath: metadata.namespace +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: metrics-certs +# fieldPaths: +# - spec.dnsNames.0 +# - spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 1 +# create: true +# - select: # Uncomment the following to set the Service namespace for TLS in Prometheus ServiceMonitor +# kind: ServiceMonitor +# group: monitoring.coreos.com +# version: v1 +# name: controller-manager-metrics-monitor +# fieldPaths: +# - spec.endpoints.0.tlsConfig.serverName +# options: +# delimiter: '.' +# index: 1 +# create: true + +# - source: # Uncomment the following block if you have any webhook +# kind: Service +# version: v1 +# name: webhook-service +# fieldPath: .metadata.name # Name of the service +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPaths: +# - .spec.dnsNames.0 +# - .spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 0 +# create: true +# - source: +# kind: Service +# version: v1 +# name: webhook-service +# fieldPath: .metadata.namespace # Namespace of the service +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPaths: +# - .spec.dnsNames.0 +# - .spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 1 +# create: true + +# - source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: ValidatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.name +# targets: +# - select: +# kind: ValidatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true + +# - source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting ) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: MutatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.name +# targets: +# - select: +# kind: MutatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true + +# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. +# +kubebuilder:scaffold:crdkustomizecainjectionns +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.name +# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. +# +kubebuilder:scaffold:crdkustomizecainjectionname diff --git a/config/production/kustomization.yaml b/config/production/kustomization.yaml new file mode 100644 index 0000000..0482a9c --- /dev/null +++ b/config/production/kustomization.yaml @@ -0,0 +1,12 @@ +namespace: swap-operator +namePrefix: swap-operator- +resources: +- ../crd +- ../rbac +- ../manager +- metrics_service.yaml + +patches: +- path: manager_metrics_patch.yaml + target: + kind: Deployment diff --git a/config/production/manager_metrics_patch.yaml b/config/production/manager_metrics_patch.yaml new file mode 100644 index 0000000..2aaef65 --- /dev/null +++ b/config/production/manager_metrics_patch.yaml @@ -0,0 +1,4 @@ +# This patch adds the args to allow exposing the metrics endpoint using HTTPS +- op: add + path: /spec/template/spec/containers/0/args/0 + value: --metrics-bind-address=:8443 diff --git a/config/production/metrics_service.yaml b/config/production/metrics_service.yaml new file mode 100644 index 0000000..a4b9e98 --- /dev/null +++ b/config/production/metrics_service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: swap-operator + app.kubernetes.io/managed-by: kustomize + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + control-plane: controller-manager + app.kubernetes.io/name: swap-operator diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 99c2cdb..3d26021 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -4,6 +4,27 @@ kind: ClusterRole metadata: name: manager-role rules: +- apiGroups: + - machineconfiguration.openshift.io + resources: + - machineconfigpools + - machineconfigs/status + verbs: + - get + - list + - watch +- apiGroups: + - machineconfiguration.openshift.io + resources: + - machineconfigs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - node-swap.openshift.io resources: diff --git a/examples/diskbased.yaml b/examples/diskbased.yaml new file mode 100644 index 0000000..1fa7c24 --- /dev/null +++ b/examples/diskbased.yaml @@ -0,0 +1,13 @@ +apiVersion: node-swap.openshift.io/v1alpha1 +kind: NodeSwap +metadata: + name: swap + namespace: default +spec: + machineConfigPoolSelector: "node-role.kubernetes.io/role:worker" + swaps: + - priority: 10 + swapType: disk + disk: + partition: + partlabel: swap-partition diff --git a/examples/filebased.yaml b/examples/filebased.yaml new file mode 100644 index 0000000..bcf822a --- /dev/null +++ b/examples/filebased.yaml @@ -0,0 +1,14 @@ +apiVersion: node-swap.openshift.io/v1alpha1 +kind: NodeSwap +metadata: + name: swap + namespace: default +spec: + machineConfigPoolSelector: "node-role.kubernetes.io/role:worker" + swaps: + - priority: 10 + swapType: file + file: + path: /var/swap + size: 4Gi + logLevel: 4 diff --git a/examples/minimal.yaml b/examples/minimal.yaml new file mode 100644 index 0000000..434797d --- /dev/null +++ b/examples/minimal.yaml @@ -0,0 +1,6 @@ +apiVersion: node-swap.openshift.io/v1alpha1 +kind: NodeSwap +metadata: + name: swap +spec: + machineConfigPoolSelector: "node-role.kubernetes.io/role:worker" diff --git a/examples/zram.yaml b/examples/zram.yaml new file mode 100644 index 0000000..5c8a3c3 --- /dev/null +++ b/examples/zram.yaml @@ -0,0 +1,12 @@ +apiVersion: node-swap.openshift.io/v1alpha1 +kind: NodeSwap +metadata: + name: swap + namespace: default +spec: + machineConfigPoolSelector: "node-role.kubernetes.io/role:worker" + swaps: + - priority: 10 + swapType: zram + zram: + size: 2Gi diff --git a/internal/common/helpers.go b/internal/common/helpers.go index dea563d..2930bee 100644 --- a/internal/common/helpers.go +++ b/internal/common/helpers.go @@ -10,12 +10,17 @@ import ( fcctbase "github.com/coreos/fcct/base/v0_1" "github.com/coreos/go-semver/semver" + ign2error "github.com/coreos/ignition/config/shared/errors" + ign2 "github.com/coreos/ignition/config/v2_2" + ign2types "github.com/coreos/ignition/config/v2_2/types" + ign3error "github.com/coreos/ignition/v2/config/shared/errors" ign3 "github.com/coreos/ignition/v2/config/v3_5" ign3types "github.com/coreos/ignition/v2/config/v3_5/types" mcfgv1 "github.com/openshift/api/machineconfiguration/v1" "go.yaml.in/yaml/v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/klog/v2" ) // TranspileCoreOSConfigToIgn transpiles Fedora CoreOS config to ignition @@ -149,3 +154,182 @@ func indent(spaces int, v string) string { pad := strings.Repeat(" ", spaces) return pad + strings.ReplaceAll(v, "\n", "\n"+pad) } + +// Ensures SSH keys are unique for a given Ign 2 PasswdUser +// See: https://bugzilla.redhat.com/show_bug.cgi?id=1934176 +func dedupePasswdUserSSHKeys(passwdUser ign2types.PasswdUser) ign2types.PasswdUser { + // Map for checking for duplicates. + knownSSHKeys := map[ign2types.SSHAuthorizedKey]bool{} + + // Preserve ordering of SSH keys. + dedupedSSHKeys := []ign2types.SSHAuthorizedKey{} + + for _, sshKey := range passwdUser.SSHAuthorizedKeys { + if _, isKnown := knownSSHKeys[sshKey]; isKnown { + // We've seen this key before warn and move on. + klog.Warningf("duplicate SSH public key found: %s", sshKey) + continue + } + + // We haven't seen this key before, add it. + dedupedSSHKeys = append(dedupedSSHKeys, sshKey) + knownSSHKeys[sshKey] = true + } + + // Overwrite the keys with the deduped list. + passwdUser.SSHAuthorizedKeys = dedupedSSHKeys + + return passwdUser +} + +// Function to remove duplicated files/units/users from a V2 MC, since the translator +// (and ignition spec V3) does not allow for duplicated entries in one MC. +// This should really not change the actual final behaviour, since it keeps +// ordering into consideration and has contents from the highest alphanumeric +// MC's final version of a file. +// Note: +// Append is not considered since we do not allow for appending +// Units have one exception: dropins are concat'ed + +func removeIgnDuplicateFilesUnitsUsers(ignConfig ign2types.Config) (ign2types.Config, error) { + + files := ignConfig.Storage.Files + units := ignConfig.Systemd.Units + users := ignConfig.Passwd.Users + + filePathMap := map[string]bool{} + var outFiles []ign2types.File + for i := len(files) - 1; i >= 0; i-- { + // We do not actually support to other filesystems so we make the assumption that there is only 1 here + path := files[i].Path + if _, isDup := filePathMap[path]; isDup { + continue + } + outFiles = append(outFiles, files[i]) + filePathMap[path] = true + } + + unitNameMap := map[string]bool{} + var outUnits []ign2types.Unit + for i := len(units) - 1; i >= 0; i-- { + unitName := units[i].Name + if _, isDup := unitNameMap[unitName]; isDup { + // this is a duplicated unit by name, so let's check for the dropins and append them + if len(units[i].Dropins) > 0 { + for j := range outUnits { + if outUnits[j].Name == unitName { + // outUnits[j] is the highest priority entry with this unit name + // now loop over the new unit's dropins and append it if the name + // isn't duplicated in the existing unit's dropins + for _, newDropin := range units[i].Dropins { + hasExistingDropin := false + for _, existingDropins := range outUnits[j].Dropins { + if existingDropins.Name == newDropin.Name { + hasExistingDropin = true + break + } + } + if !hasExistingDropin { + outUnits[j].Dropins = append(outUnits[j].Dropins, newDropin) + } + } + continue + } + } + klog.V(2).Infof("Found duplicate unit %v, appending dropin section", unitName) + } + continue + } + outUnits = append(outUnits, units[i]) + unitNameMap[unitName] = true + } + + // Concat sshkey sections into the newest passwdUser in the list + // We make the assumption that there is only one user: core + // since that is the only supported user by design. + // It's technically possible, though, to have created another user + // during install time configs, since we only check the validity of + // the passwd section if it was changed. Explicitly error in that case. + if len(users) > 0 { + outUser := users[len(users)-1] + if outUser.Name != "core" { + return ignConfig, fmt.Errorf("unexpected user with name: %v. Only core user is supported", outUser.Name) + } + for i := len(users) - 2; i >= 0; i-- { + if users[i].Name != "core" { + return ignConfig, fmt.Errorf("unexpected user with name: %v. Only core user is supported", users[i].Name) + } + for j := range users[i].SSHAuthorizedKeys { + outUser.SSHAuthorizedKeys = append(outUser.SSHAuthorizedKeys, users[i].SSHAuthorizedKeys[j]) + } + } + // Ensure SSH key uniqueness + ignConfig.Passwd.Users = []ign2types.PasswdUser{dedupePasswdUserSSHKeys(outUser)} + } + + // outFiles and outUnits should now have all duplication removed + ignConfig.Storage.Files = outFiles + ignConfig.Systemd.Units = outUnits + + return ignConfig, nil +} + +// IgnParseWrapper parses rawIgn for both V2 and V3 ignition configs and returns +// a V2 or V3 Config or an error. This wrapper is necessary since V2 and V3 use different parsers. +func IgnParseWrapper(rawIgn []byte) (interface{}, error) { + // ParseCompatibleVersion will parse any config <= N to version N + ignCfgV3, rptV3, errV3 := ign3.ParseCompatibleVersion(rawIgn) + if errV3 == nil && !rptV3.IsFatal() { + return ignCfgV3, nil + } + + // ParseCompatibleVersion differentiates between ErrUnknownVersion ("I know what it is and we don't support it") and + // ErrInvalidVersion ("I can't parse it to find out what it is"), but our old 3.2 logic didn't, so this is here to make sure + // our error message for invalid version is still helpful. + if errV3.Error() == ign3error.ErrInvalidVersion.Error() { + versions := strings.TrimSuffix(strings.Join(IgnitionConverterSingleton().GetSupportedMinorVersions(), ","), ",") + return ign3types.Config{}, fmt.Errorf("parsing Ignition config failed: invalid version. Supported spec versions: %s", versions) + } + + if errV3.Error() == ign3error.ErrUnknownVersion.Error() { + ignCfgV2, rptV2, errV2 := ign2.Parse(rawIgn) + if errV2 == nil && !rptV2.IsFatal() { + return ignCfgV2, nil + } + + // If the error is still UnknownVersion it's not a 3.3/3.2/3.1/3.0 or 2.x config, thus unsupported + if errV2.Error() == ign2error.ErrUnknownVersion.Error() { + versions := strings.TrimSuffix(strings.Join(IgnitionConverterSingleton().GetSupportedMinorVersions(), ","), ",") + return ign3types.Config{}, fmt.Errorf("parsing Ignition config failed: unknown version. Supported spec versions: %s", versions) + } + return ign3types.Config{}, fmt.Errorf("parsing Ignition spec v2 failed with error: %v\nReport: %v", errV2, rptV2) + } + + return ign3types.Config{}, fmt.Errorf("parsing Ignition config spec v3 failed with error: %v\nReport: %v", errV3, rptV3) +} + +// ParseAndConvertConfig parses rawIgn for both V2 and V3 ignition configs and returns +// a V3 or an error. +func ParseAndConvertConfig(rawIgn []byte) (ign3types.Config, error) { + ignconfigi, err := IgnParseWrapper(rawIgn) + if err != nil { + return ign3types.Config{}, fmt.Errorf("failed to parse Ignition config: %w", err) + } + + switch typedConfig := ignconfigi.(type) { + case ign3types.Config: + return ignconfigi.(ign3types.Config), nil + case ign2types.Config: + ignconfv2, err := removeIgnDuplicateFilesUnitsUsers(ignconfigi.(ign2types.Config)) + if err != nil { + return ign3types.Config{}, err + } + convertedIgnV3, err := ignitionConverter.Convert(ignconfv2, *semver.New(ignconfv2.Ignition.Version), ign3types.MaxVersion) + if err != nil { + return ign3types.Config{}, fmt.Errorf("failed to convert Ignition config spec v2 to v3: %w", err) + } + return convertedIgnV3.(ign3types.Config), nil + default: + return ign3types.Config{}, fmt.Errorf("unexpected type for ignition config: %v", typedConfig) + } +} diff --git a/internal/controller/nodeswap_controller.go b/internal/controller/nodeswap_controller.go index 448b7d0..60eb450 100644 --- a/internal/controller/nodeswap_controller.go +++ b/internal/controller/nodeswap_controller.go @@ -18,28 +18,52 @@ package controller import ( "context" + "encoding/base64" + "fmt" + "path/filepath" + "strings" - ign3types "github.com/coreos/ignition/v2/config/v3_2/types" mcfgv1 "github.com/openshift/api/machineconfiguration/v1" + "go.yaml.in/yaml/v2" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" logf "sigs.k8s.io/controller-runtime/pkg/log" - nodeswapv1alpha1 "github.com/openshift-virtualization/swap-operator/api/v1alpha1" + nodeswap "github.com/openshift-virtualization/swap-operator/api/v1alpha1" + "github.com/openshift-virtualization/swap-operator/internal/renderconfig" + "github.com/openshift-virtualization/swap-operator/internal/template" +) + +const ( + typeAvailableNodeSwap = "Availabe" + typeProgressingNodeSwap = "Progressing" + typeDegradedNodeSwap = "Degraded" ) -// NodeSwapReconciler reconciles a NodeSwap object type NodeSwapReconciler struct { client.Client - Scheme *runtime.Scheme + Scheme *runtime.Scheme + TemplateDir string + config []renderconfig.RenderConfig + ctx context.Context + desiredNodeSwap nodeswap.NodeSwap + mcpReady bool } // +kubebuilder:rbac:groups=node-swap.openshift.io,resources=nodeswaps,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=node-swap.openshift.io,resources=nodeswaps/status,verbs=get;update;patch // +kubebuilder:rbac:groups=node-swap.openshift.io,resources=nodeswaps/finalizers,verbs=update +// +kubebuilder:rbac:groups=machineconfiguration.openshift.io,resources=machineconfigs,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=machineconfiguration.openshift.io,resources=machineconfigs/status,verbs=get;list;watch +// +kubebuilder:rbac:groups=machineconfiguration.openshift.io,resources=machineconfigpools,verbs=get;list;watch // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -52,121 +76,253 @@ type NodeSwapReconciler struct { // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.22.1/pkg/reconcile func (r *NodeSwapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { _ = logf.FromContext(ctx) + r.ctx = ctx - // TODO(user): your logic here - //RednerMachineConfigFromAPI - //ReconcileRenderedMachineConfigWithCurrentMachineConfig - //UpdateMachineConfig - //UpdateNodeSwapStatus - //Requeue + if err := r.Get(ctx, req.NamespacedName, &r.desiredNodeSwap); err != nil { + if apierrors.IsNotFound(err) { + logf.FromContext(ctx).Info("NodeSwap resource not found. Ignoring since object must be deleted") + return ctrl.Result{}, nil + } + logf.FromContext(ctx).Error(err, "Failed to get NodeSwap") + return ctrl.Result{}, err + } - return ctrl.Result{}, nil -} + // Reconcile the spec and capture any errors + _, reconcileErr := r.ReconcileSpec() -// GenerateSwapMachineConfig creates a MachineConfig object for enabling swap on worker nodes -func GenerateSwapMachineConfig(name, role string, swapSizeMB int) *mcfgv1.MachineConfig { - // Base64 encoded kubelet configuration for swap - // Content: apiVersion: kubelet.config.k8s.io/v1beta1\nkind: KubeletConfiguration\nmemorySwap:\n swapBehavior: LimitedSwap\n - kubeletConfigSource := "data:text/plain;charset=utf-8;base64,YXBpVmVyc2lvbjoga3ViZWxldC5jb25maWcuazhzLmlvL3YxYmV0YTEKa2luZDogS3ViZWxldENvbmZpZ3VyYXRpb24KbWVtb3J5U3dhcDoKICBzd2FwQmVoYXZpb3I6IExpbWl0ZWRTd2FwCg==" - - // Swap provision service unit content - swapProvisionUnit := `[Unit] -Description=Provision and enable swap -ConditionFirstBoot=no -ConditionPathExists=!/var/tmp/swapfile - -[Service] -Type=oneshot -Environment=SWAP_SIZE_MB=` + string(rune(swapSizeMB)) + ` -ExecStart=/bin/sh -c "sudo fallocate -l ${SWAP_SIZE_MB}M /var/tmp/swapfile && \ -sudo chmod 600 /var/tmp/swapfile && \ -sudo mkswap /var/tmp/swapfile && \ -sudo swapon /var/tmp/swapfile && \ -free -h" - -[Install] -RequiredBy=kubelet-dependencies.target -` - - // System slice cgroup configuration service unit content - cgroupSystemSliceUnit := `[Unit] -Description=Restrict swap for system slice -ConditionFirstBoot=no - -[Service] -Type=oneshot -ExecStart=/bin/sh -c "sudo systemctl set-property --runtime system.slice MemorySwapMax=0 IODeviceLatencyTargetSec=\"/ 50ms\"" - -[Install] -RequiredBy=kubelet-dependencies.target -` - - // Create the file mode (420 in decimal = 0644 in octal) - fileMode := 420 - - // Create the MachineConfig object - mc := &mcfgv1.MachineConfig{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "machineconfiguration.openshift.io/v1", - Kind: "MachineConfig", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - "machineconfiguration.openshift.io/role": role, - }, - }, - Spec: mcfgv1.MachineConfigSpec{ - Config: ign3types.Config{ - Ignition: ign3types.Ignition{ - Version: "3.2.0", - }, - Storage: ign3types.Storage{ - Files: []ign3types.File{ - { - Node: ign3types.Node{ - Path: "/etc/openshift/kubelet.conf.d/90-swap.conf", - Overwrite: boolPtr(true), - }, - FileEmbedded1: ign3types.FileEmbedded1{ - Mode: &fileMode, - Contents: ign3types.Resource{ - Source: &kubeletConfigSource, - }, - }, - }, - }, - }, - Systemd: ign3types.Systemd{ - Units: []ign3types.Unit{ - { - Name: "swap-provision.service", - Enabled: boolPtr(true), - Contents: &swapProvisionUnit, - }, - { - Name: "cgroup-system-slice-config.service", - Enabled: boolPtr(true), - Contents: &cgroupSystemSliceUnit, - }, - }, - }, - }, - }, + // Always update status with the result (success or failure) + if _, statusErr := r.ReconcileStatus(reconcileErr); statusErr != nil { + logf.FromContext(ctx).Error(statusErr, "Failed to update status") + // Return both errors if status update fails + if reconcileErr != nil { + return ctrl.Result{}, fmt.Errorf("reconcile error: %v, status update error: %v", reconcileErr, statusErr) + } + return ctrl.Result{}, statusErr } - return mc + // Return the original reconcile error (status was updated successfully) + return ctrl.Result{}, reconcileErr } -// boolPtr returns a pointer to a bool value -func boolPtr(b bool) *bool { - return &b +func (r *NodeSwapReconciler) ReconcileStatus(reconcileErr error) (ctrl.Result, error) { + if reconcileErr != nil { + meta.SetStatusCondition(&r.desiredNodeSwap.Status.Conditions, metav1.Condition{ + Type: typeDegradedNodeSwap, + Status: metav1.ConditionTrue, + Reason: "ReconciliationFailed", + Message: fmt.Sprintf("Failed to reconcile: %v", reconcileErr), + }) + meta.SetStatusCondition(&r.desiredNodeSwap.Status.Conditions, metav1.Condition{ + Type: typeProgressingNodeSwap, + Status: metav1.ConditionFalse, + Reason: "ReconciliationFailed", + Message: "Reconciliation failed", + }) + meta.SetStatusCondition(&r.desiredNodeSwap.Status.Conditions, metav1.Condition{ + Type: typeAvailableNodeSwap, + Status: metav1.ConditionFalse, + Reason: "ReconciliationFailed", + Message: "", + }) + } else if len(r.desiredNodeSwap.Status.Conditions) == 0 { + meta.SetStatusCondition(&r.desiredNodeSwap.Status.Conditions, metav1.Condition{ + Type: typeProgressingNodeSwap, + Status: metav1.ConditionTrue, + Reason: "Reconciling", + Message: "NodeSwap is reconciling", + }) + } else { + meta.SetStatusCondition(&r.desiredNodeSwap.Status.Conditions, metav1.Condition{ + Type: typeAvailableNodeSwap, + Status: metav1.ConditionTrue, + Reason: "ReconciliationSucceeded", + Message: "NodeSwap successfully reconciled", + }) + meta.SetStatusCondition(&r.desiredNodeSwap.Status.Conditions, metav1.Condition{ + Type: typeDegradedNodeSwap, + Status: metav1.ConditionFalse, + Reason: "ReconciliationSucceeded", + Message: "", + }) + meta.SetStatusCondition(&r.desiredNodeSwap.Status.Conditions, metav1.Condition{ + Type: typeProgressingNodeSwap, + Status: metav1.ConditionFalse, + Reason: "ReconciliationSucceeded", + Message: "", + }) + } + + if err := r.Status().Update(r.ctx, &r.desiredNodeSwap); err != nil { + logf.FromContext(r.ctx).Error(err, "Failed to update NodeSwap status") + return ctrl.Result{}, err + } + + return ctrl.Result{}, nil } // SetupWithManager sets up the controller with the Manager. func (r *NodeSwapReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). - For(&nodeswapv1alpha1.NodeSwap{}). + For(&nodeswap.NodeSwap{}). + Watches(&mcfgv1.MachineConfigPool{}, &handler.EnqueueRequestForObject{}). + Owns(&mcfgv1.MachineConfig{}). Named("nodeswap"). Complete(r) } + +func (r *NodeSwapReconciler) ReconcileKubeletCgroups() (ctrl.Result, error) { + var kubeletMachineConfig mcfgv1.MachineConfig + if err := r.Get(r.ctx, + types.NamespacedName{Name: renderconfig.SwapKubeletCgroupsMCPrefix}, + &kubeletMachineConfig); err != nil { + if apierrors.IsNotFound(err) { + fullTemplatePath := filepath.Join(r.TemplateDir, "worker", "99-swap-kubelet-cgroups") + mc, err := template.GenerateMachineConfigForName( + &renderconfig.RenderConfig{}, + "worker", + "99-swap-kubelet-cgroups", + r.TemplateDir, + fullTemplatePath, + ) + if err != nil { + logf.FromContext(r.ctx).Error(err, "Failed to render kubelet machine config") + return ctrl.Result{}, err + } + + mcBytes, err := yaml.Marshal(mc) + if err != nil { + logf.FromContext(r.ctx).Error(err, "Failed to marshal MachineConfig") + } else { + mcBase64 := base64.StdEncoding.EncodeToString(mcBytes) + logf.FromContext(r.ctx).Info("Generated MachineConfig", "base64", mcBase64) + } + + if mc.ObjectMeta.Labels == nil { + mc.ObjectMeta.Labels = map[string]string{} + } + + key, value, err := parseLabelSelector(r.desiredNodeSwap.Spec.MachineConfigPoolSelector) + if err != nil { + logf.FromContext(r.ctx).Error(err, "Failed to parse label selector") + return ctrl.Result{}, err + } + mc.ObjectMeta.Labels[key] = value + + if err := r.Create(r.ctx, mc); errors.IsAlreadyExists(err) { + logf.FromContext(r.ctx).Info("Kubelet machine config already exists") + return ctrl.Result{}, nil + } else if err != nil { + logf.FromContext(r.ctx).Error(err, "Failed to create kubelet machine config") + return ctrl.Result{}, err + } + + return ctrl.Result{}, nil + } + logf.FromContext(r.ctx).Error(err, "Failed to get kubelet machine config") + return ctrl.Result{}, err + } + + return ctrl.Result{}, nil +} + +func (r *NodeSwapReconciler) ReconcileSpec() (ctrl.Result, error) { + config, err := renderconfig.Create(&r.desiredNodeSwap.Spec) + if err != nil { + logf.FromContext(r.ctx).Error(err, "Failed to create render config") + return ctrl.Result{}, err + } + r.config = config + + // List all MachineConfigPools + mcpList := &mcfgv1.MachineConfigPoolList{} + if err := r.List(r.ctx, mcpList); err != nil { + logf.FromContext(r.ctx).Error(err, "Failed to list MachineConfigPools") + return ctrl.Result{}, err + } + + // Parse the desired label selector + labelKey, labelValue, err := parseLabelSelector(r.desiredNodeSwap.Spec.MachineConfigPoolSelector) + if err != nil { + logf.FromContext(r.ctx).Error(err, "Failed to parse label selector") + return ctrl.Result{}, err + } + + // Filter MachineConfigPools that match the selector + var matchingMCPs []*mcfgv1.MachineConfigPool + var updatedMCPs, notUpdatedMCPs []*mcfgv1.MachineConfigPool + + for i := range mcpList.Items { + mcp := &mcpList.Items[i] + if mcp.Spec.MachineConfigSelector != nil && + mcp.Spec.MachineConfigSelector.MatchLabels != nil { + if value, exists := + mcp.Spec.MachineConfigSelector.MatchLabels[labelKey]; exists && value == labelValue { + matchingMCPs = append(matchingMCPs, mcp) + + if isMachineConfigPoolUpdated(mcp) { + updatedMCPs = append(updatedMCPs, mcp) + logf.FromContext(r.ctx).Info("MachineConfigPool is updated", + "name", mcp.Name) + } else { + notUpdatedMCPs = append(notUpdatedMCPs, mcp) + logf.FromContext(r.ctx).Info("MachineConfigPool is not yet updated", + "name", mcp.Name) + } + } + } + } + + logf.FromContext(r.ctx).Info("MachineConfigPool filtering complete", + "matchingCount", len(matchingMCPs), + "updatedCount", len(updatedMCPs), + "notUpdatedCount", len(notUpdatedMCPs)) + + r.mcpReady = len(notUpdatedMCPs) == 0 + + return r.ReconcileKubeletCgroups() +} + +// parseLabelSelector parses a label selector string in the format "key:" or "key:value" +// and returns the key and value separately. The key is required but the value can be empty. +func parseLabelSelector(selector string) (string, string, error) { + if selector == "" { + return "", "", fmt.Errorf("label selector is empty") + } + + parts := strings.SplitN(selector, ":", 2) + if len(parts) != 2 { + return "", "", fmt.Errorf("invalid label selector format: %s, expected key: or key:value", selector) + } + + key := strings.TrimSpace(parts[0]) + value := strings.TrimSpace(parts[1]) + + if key == "" { + return "", "", fmt.Errorf("label selector has empty key: %s", selector) + } + + return key, value, nil +} + +// isMachineConfigPoolUpdated checks if a MachineConfigPool is fully updated. +// Returns true if the pool's Updated condition is True, and both Updating and Degraded are False. +func isMachineConfigPoolUpdated(mcp *mcfgv1.MachineConfigPool) bool { + var updated, updating, degraded bool + + for _, condition := range mcp.Status.Conditions { + switch condition.Type { + case mcfgv1.MachineConfigPoolUpdated: + updated = condition.Status == corev1.ConditionTrue + case mcfgv1.MachineConfigPoolUpdating: + updating = condition.Status == corev1.ConditionTrue + case mcfgv1.MachineConfigPoolDegraded: + degraded = condition.Status == corev1.ConditionTrue + } + } + + // Pool is considered updated if: + // - Updated condition is True + // - Updating condition is False (or not found) + // - Degraded condition is False (or not found) + return updated && !updating && !degraded +} diff --git a/internal/controller/nodeswap_controller_test.go b/internal/controller/nodeswap_controller_test.go index a8d68c7..257b6d1 100644 --- a/internal/controller/nodeswap_controller_test.go +++ b/internal/controller/nodeswap_controller_test.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/reconcile" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" nodeswapv1alpha1 "github.com/openshift-virtualization/swap-operator/api/v1alpha1" @@ -51,7 +52,9 @@ var _ = Describe("NodeSwap Controller", func() { Name: resourceName, Namespace: "default", }, - // TODO(user): Specify other spec details if needed. + Spec: nodeswapv1alpha1.NodeSwapSpec{ + MachineConfigPoolSelector: "node-role.kubernetes.io/role:worker", + }, } Expect(k8sClient.Create(ctx, resource)).To(Succeed()) } @@ -80,5 +83,63 @@ var _ = Describe("NodeSwap Controller", func() { // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. // Example: If you expect a certain status condition after reconciliation, verify it here. }) + It("should update status conditions when reconciliation fails", func() { + By("Creating a NodeSwap with invalid configuration") + invalidResourceName := "test-invalid-resource" + invalidTypeNamespacedName := types.NamespacedName{ + Name: invalidResourceName, + Namespace: "default", + } + + invalidResource := &nodeswapv1alpha1.NodeSwap{ + ObjectMeta: metav1.ObjectMeta{ + Name: invalidResourceName, + Namespace: "default", + }, + Spec: nodeswapv1alpha1.NodeSwapSpec{ + // Invalid selector format to trigger error + MachineConfigPoolSelector: "invalid-selector-no-colon", + }, + } + Expect(k8sClient.Create(ctx, invalidResource)).To(Succeed()) + + By("Reconciling the resource with invalid configuration") + controllerReconciler := &NodeSwapReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + TemplateDir: "../../templates", // Adjust path as needed + } + + _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: invalidTypeNamespacedName, + }) + + // Reconcile should return an error + Expect(err).To(HaveOccurred()) + + By("Verifying that status conditions reflect the error") + updatedResource := &nodeswapv1alpha1.NodeSwap{} + Expect(k8sClient.Get(ctx, invalidTypeNamespacedName, updatedResource)).To(Succeed()) + + // Check that Degraded condition is True + degradedCondition := meta.FindStatusCondition(updatedResource.Status.Conditions, "Degraded") + Expect(degradedCondition).NotTo(BeNil()) + Expect(degradedCondition.Status).To(Equal(metav1.ConditionTrue)) + Expect(degradedCondition.Reason).To(Equal("ReconciliationFailed")) + Expect(degradedCondition.Message).To(ContainSubstring("Failed to reconcile")) + + // Check that Progressing condition is False + progressingCondition := meta.FindStatusCondition(updatedResource.Status.Conditions, "Progressing") + Expect(progressingCondition).NotTo(BeNil()) + Expect(progressingCondition.Status).To(Equal(metav1.ConditionFalse)) + + // Check that Available condition is False + availableCondition := meta.FindStatusCondition(updatedResource.Status.Conditions, "Availabe") + Expect(availableCondition).NotTo(BeNil()) + Expect(availableCondition.Status).To(Equal(metav1.ConditionFalse)) + + By("Cleaning up the invalid resource") + Expect(k8sClient.Delete(ctx, invalidResource)).To(Succeed()) + }) }) }) diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index 85ad9a9..cdf1e19 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -33,6 +33,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" nodeswapv1alpha1 "github.com/openshift-virtualization/swap-operator/api/v1alpha1" + mcfgv1 "github.com/openshift/api/machineconfiguration/v1" // +kubebuilder:scaffold:imports ) @@ -62,11 +63,17 @@ var _ = BeforeSuite(func() { err = nodeswapv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = mcfgv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + // +kubebuilder:scaffold:scheme By("bootstrapping test environment") testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, + CRDDirectoryPaths: []string{ + filepath.Join("..", "..", "config", "crd", "bases"), + filepath.Join("..", "..", "config", "crd", "external"), + }, ErrorIfCRDPathMissing: true, } diff --git a/internal/renderconfig/config.go b/internal/renderconfig/config.go new file mode 100644 index 0000000..ef74cf5 --- /dev/null +++ b/internal/renderconfig/config.go @@ -0,0 +1,140 @@ +package renderconfig + +import ( + "fmt" + "strconv" + + nodeswap "github.com/openshift-virtualization/swap-operator/api/v1alpha1" + "k8s.io/apimachinery/pkg/api/resource" +) + +const ( + FileBasedSwapMCPrefix = "99-filebased-swap" + DiskBasedSwapMCPrefix = "99-diskbased-swap" + ZramBasedSwapMCPrefix = "99-zrambased-swap" + SwapKubeletCgroupsMCPrefix = "99-swap-kubelet-cgroups" +) + +type RenderConfig struct { + Name string + Index int + EnableFileBasedSwap bool + EnableDiskBasedSwap bool + EnableZramBasedSwap bool + SwapFileSize string + SwapFilePath string + SwapDevicePriotiry uint +} + +func Create(spec *nodeswap.NodeSwapSpec) ([]RenderConfig, error) { + configs := []RenderConfig{} + + for idx, swap := range spec.Swaps { + config, err := render(idx, &swap) + if err != nil { + return nil, err + } + configs = append(configs, config) + } + + return configs, nil +} + +func render(id int, swap *nodeswap.SwapSpec) (RenderConfig, error) { + var err error + config := RenderConfig{Index: id} + name, err := generateName(id, swap) + if err != nil { + return RenderConfig{}, err + } + + switch swap.SwapType { + case nodeswap.FileBasedSwap: + config.EnableFileBasedSwap = true + config, err = generateFileBasedSwapConfig(swap.File) + case nodeswap.SwapOnDisk: + config.EnableDiskBasedSwap = true + config, err = generateDiskBasedSwapConfig(swap.Disk) + case nodeswap.SwapOnZram: + config.EnableZramBasedSwap = true + config, err = generateZramBasedSwapConfig(swap.Zram) + default: + return RenderConfig{}, fmt.Errorf("unknown swap type: %s", swap.SwapType) + } + + if err != nil { + return RenderConfig{}, err + } + + config.Name = name + config.SwapDevicePriotiry = uint(swap.Priority) + return config, nil +} + +func generateName(id int, spec *nodeswap.SwapSpec) (string, error) { + switch spec.SwapType { + case nodeswap.FileBasedSwap: + return fmt.Sprintf("%s-%d", FileBasedSwapMCPrefix, id), nil + case nodeswap.SwapOnDisk: + return fmt.Sprintf("%s-%d", DiskBasedSwapMCPrefix, id), nil + case nodeswap.SwapOnZram: + return fmt.Sprintf("%s-%d", ZramBasedSwapMCPrefix, id), nil + } + + return "", fmt.Errorf("unknown swap type: %s", spec.SwapType) +} + +func generateFileBasedSwapConfig(swapConfig *nodeswap.SwapFile) (RenderConfig, error) { + size, err := MkswapSizeArg(swapConfig.Size) + if err != nil { + return RenderConfig{}, err + } + + return RenderConfig{ + SwapFileSize: size, + SwapFilePath: swapConfig.Path, + }, nil +} + +func generateDiskBasedSwapConfig(swapConfig *nodeswap.SwapDisk) (RenderConfig, error) { + return RenderConfig{}, nil +} + +func generateZramBasedSwapConfig(swapConfig *nodeswap.SwapZram) (RenderConfig, error) { + return RenderConfig{}, nil +} + +// MkswapSizeArg converts a resource.Quantity to a string suitable for fallocate --length. +// It prefers an integer GiB/MiB/KiB suffix (Gi/Mi/Ki). If the size does not divide +// evenly by 1024, it falls back to raw bytes. +func MkswapSizeArg(q resource.Quantity) (string, error) { + if q.Sign() <= 0 { + return "", fmt.Errorf("swap size must be positive, got %s", q.String()) + } + + bytes := q.Value() // memory-like quantities are in bytes + if bytes <= 0 { + return "", fmt.Errorf("swap size must be positive in bytes, got %d", bytes) + } + + type unit struct { + name string + size int64 + } + + units := []unit{ + {"Gi", 1024 * 1024 * 1024}, + {"Mi", 1024 * 1024}, + {"Ki", 1024}, + } + + // Try Gi, then Mi, then Ki + for _, u := range units { + if bytes%u.size == 0 { + return strconv.FormatInt(bytes/u.size, 10) + u.name, nil + } + } + + // Fallback: raw bytes + return "", fmt.Errorf("swap size must be in Ki Mi or Gi formats, got %d", bytes) +} diff --git a/internal/renderconfig/config_test.go b/internal/renderconfig/config_test.go new file mode 100644 index 0000000..74839a2 --- /dev/null +++ b/internal/renderconfig/config_test.go @@ -0,0 +1,136 @@ +package renderconfig + +import ( + "testing" + + nodeswap "github.com/openshift-virtualization/swap-operator/api/v1alpha1" + "k8s.io/apimachinery/pkg/api/resource" +) + +func TestMkswapSizeArg(t *testing.T) { + tests := []struct { + name string + q resource.Quantity + want string + wantError bool + }{ + { + name: "1KiB -> 1Ki", + q: resource.MustParse("1Ki"), + want: "1Ki", + }, + { + name: "4MiB -> 4Mi", + q: resource.MustParse("4Mi"), + want: "4Mi", + }, + { + name: "2GiB -> 2Gi", + q: resource.MustParse("2Gi"), + want: "2Gi", + }, + { + name: "zero size -> error", + q: resource.MustParse("0"), + wantError: true, + }, + { + name: "negative size -> error", + q: resource.MustParse("-1"), + wantError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := MkswapSizeArg(tt.q) + if tt.wantError { + if err == nil { + t.Fatalf("expected error, got nil (result=%q)", got) + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if got != tt.want { + t.Fatalf("MkswapSizeArg(%q) = %q, want %q", tt.q.String(), got, tt.want) + } + }) + } +} + +func TestRender(t *testing.T) { + tests := []struct { + name string + id int + spec *nodeswap.SwapSpec + wantName string + wantErr bool + }{ + { + name: "file-based swap", + id: 0, + spec: &nodeswap.SwapSpec{ + SwapType: nodeswap.FileBasedSwap, + File: &nodeswap.SwapFile{ + Path: "/var/tmp/swapfile", + Size: resource.MustParse("1Gi"), + }, + }, + wantName: "99-filebased-swap-0", + }, + { + name: "disk-based swap", + id: 3, + spec: &nodeswap.SwapSpec{ + SwapType: nodeswap.SwapOnDisk, + Disk: &nodeswap.SwapDisk{ + SwapPartition: nodeswap.Partition{ + PartLabel: "SWAP", + }, + }, + }, + wantName: "99-diskbased-swap-3", + }, + { + name: "zram-based swap", + id: 1, + spec: &nodeswap.SwapSpec{ + SwapType: nodeswap.SwapOnZram, + Zram: &nodeswap.SwapZram{ + Size: resource.MustParse("512Mi"), + }, + }, + wantName: "99-zrambased-swap-1", + }, + { + name: "unknown swap type returns error", + id: 0, + spec: &nodeswap.SwapSpec{ + SwapType: "unknown-type", + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := render(tt.id, tt.spec) + if tt.wantErr { + if err == nil { + t.Fatalf("expected error, got nil (config=%+v)", got) + } + return + } + + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if got.Name != tt.wantName { + t.Fatalf("render() Name = %q, want %q", got.Name, tt.wantName) + } + }) + } +} diff --git a/internal/template/render.go b/internal/template/render.go index 81b98ca..c0f0fa0 100644 --- a/internal/template/render.go +++ b/internal/template/render.go @@ -10,28 +10,20 @@ import ( "sort" "text/template" - "github.com/openshift-virtualization/swap-operator/api/v1alpha1" ctrlcommon "github.com/openshift-virtualization/swap-operator/internal/common" + "github.com/openshift-virtualization/swap-operator/internal/renderconfig" mcfgv1 "github.com/openshift/api/machineconfiguration/v1" "k8s.io/klog/v2" ) -type RenderConfig struct { - *v1alpha1.NodeSwapSpec -} - const ( - filesDir = "files" - unitsDir = "units" - extensionsDir = "extensions" - platformBase = "_base" - platformOnPrem = "on-prem" - sno = "sno" - tnf = "two-node-with-fencing" - masterRole = "master" - workerRole = "worker" - arbiterRole = "arbiter" - cloudPlatformAltDNS = "cloud-platform-alt-dns" + filesDir = "files" + unitsDir = "units" + extensionsDir = "extensions" + platformBase = "_base" + masterRole = "master" + workerRole = "worker" + arbiterRole = "arbiter" ) // generateTemplateMachineConfigs returns MachineConfig objects from the templateDir and a config object @@ -47,7 +39,7 @@ const ( // /01-worker-kubelet/_base/files/random.conf.tmpl // /master/00-master/_base/units/kubelet.tmpl // /files/hostname.tmpl -func generateTemplateMachineConfigs(config *RenderConfig, templateDir string) ([]*mcfgv1.MachineConfig, error) { +func generateTemplateMachineConfigs(config *renderconfig.RenderConfig, templateDir string) ([]*mcfgv1.MachineConfig, error) { infos, err := ctrlcommon.ReadDir(templateDir) if err != nil { return nil, err @@ -73,7 +65,7 @@ func generateTemplateMachineConfigs(config *RenderConfig, templateDir string) ([ } // GenerateMachineConfigsForRole creates MachineConfigs for the role provided -func GenerateMachineConfigsForRole(config *RenderConfig, role, templateDir string) ([]*mcfgv1.MachineConfig, error) { +func GenerateMachineConfigsForRole(config *renderconfig.RenderConfig, role, templateDir string) ([]*mcfgv1.MachineConfig, error) { rolePath := role //nolint:goconst if role != workerRole && role != masterRole && role != arbiterRole { @@ -99,7 +91,7 @@ func GenerateMachineConfigsForRole(config *RenderConfig, role, templateDir strin } name := info.Name() namePath := filepath.Join(path, name) - nameConfig, err := generateMachineConfigForName(config, role, name, templateDir, namePath) + nameConfig, err := GenerateMachineConfigForName(config, role, name, templateDir, namePath) if err != nil { return nil, err } @@ -111,7 +103,7 @@ func GenerateMachineConfigsForRole(config *RenderConfig, role, templateDir strin // renderTemplate renders a template file with values from a RenderConfig // returns the rendered file data -func renderTemplate(config RenderConfig, path string, b []byte) ([]byte, error) { +func renderTemplate(config *renderconfig.RenderConfig, path string, b []byte) ([]byte, error) { funcs := ctrlcommon.GetTemplateFuncMap() tmpl, err := template.New(path).Funcs(funcs).Parse(string(b)) if err != nil { @@ -126,7 +118,7 @@ func renderTemplate(config RenderConfig, path string, b []byte) ([]byte, error) return buf.Bytes(), nil } -func filterTemplates(toFilter map[string]string, path string, config *RenderConfig) error { +func filterTemplates(toFilter map[string]string, path string, config *renderconfig.RenderConfig) error { walkFn := func(path string, info os.FileInfo, err error) error { if err != nil { return err @@ -147,7 +139,7 @@ func filterTemplates(toFilter map[string]string, path string, config *RenderConf } // Render the template file - renderedData, err := renderTemplate(*config, path, filedata) + renderedData, err := renderTemplate(config, path, filedata) if err != nil { return err } @@ -189,7 +181,7 @@ func getPaths() []string { return platformBasedPaths } -func generateMachineConfigForName(config *RenderConfig, role, name, templateDir, path string) (*mcfgv1.MachineConfig, error) { +func GenerateMachineConfigForName(config *renderconfig.RenderConfig, role, name, templateDir, path string) (*mcfgv1.MachineConfig, error) { platformDirs := []string{} platformBasedPaths := getPaths() // Loop over templates/common which applies everywhere diff --git a/internal/template/render_test.go b/internal/template/render_test.go index e69de29..cca7631 100644 --- a/internal/template/render_test.go +++ b/internal/template/render_test.go @@ -0,0 +1,207 @@ +package template + +import ( + "os" + "path/filepath" + "strings" + "testing" + + ctrlcommon "github.com/openshift-virtualization/swap-operator/internal/common" + "github.com/openshift-virtualization/swap-operator/internal/renderconfig" + mcfgv1 "github.com/openshift/api/machineconfiguration/v1" +) + +func TestGenerateMachineConfigForName(t *testing.T) { + tests := []struct { + name string + config *renderconfig.RenderConfig + role string + mcName string + setupFunc func(t *testing.T, templateDir string) + wantErr bool + validateFunc func(t *testing.T, mc *mcfgv1.MachineConfig) + }{ + { + name: "basic worker config with file-based swap", + config: &renderconfig.RenderConfig{ + Name: "99-filebased-swap-0", + Index: 0, + EnableFileBasedSwap: true, + SwapFileSize: "1Gi", + SwapFilePath: "/var/tmp/swapfile", + SwapDevicePriotiry: 10, + }, + role: "worker", + mcName: "99-filebased-swap-0", + setupFunc: func(t *testing.T, templateDir string) { + workerPath := filepath.Join(templateDir, "worker", "99-filebased-swap-0", "_base") + filesPath := filepath.Join(workerPath, "files") + unitsPath := filepath.Join(workerPath, "units") + + os.MkdirAll(filesPath, 0755) + os.MkdirAll(unitsPath, 0755) + + fileTemplate := `path: /etc/swap.conf +mode: 0644 +contents: + inline: | + swap enabled +` + os.WriteFile(filepath.Join(filesPath, "swap.conf"), []byte(fileTemplate), 0644) + + unitTemplate := `{{- if .EnableFileBasedSwap }} +name: filbased-swap-provision-{{ .Index }}.service +enabled: true +contents: | + [Unit] + Description=Provision and enable swap + ConditionFirstBoot=no + ConditionPathExists=!{{ .SwapFilePath }} + + [Service] + Type=oneshot + Environment=SWAP_SIZE={{ .SwapFileSize }} + ExecStart=/bin/sh -c "sudo fallocate -l ${SWAP_SIZE} {{ .SwapFilePath }} && \ + sudo chmod 600 {{ .SwapFilePath }} && \ + sudo mkswap {{ .SwapFilePath }} && \ + sudo swapon {{ .SwapFilePath }}" + + [Install] + RequiredBy=kubelet-dependencies.target +{{- end}} +` + os.WriteFile(filepath.Join(unitsPath, "swap.service"), []byte(unitTemplate), 0644) + }, + wantErr: false, + validateFunc: func(t *testing.T, mc *mcfgv1.MachineConfig) { + if mc == nil { + t.Fatal("expected non-nil MachineConfig") + } + + ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw) + if err != nil { + t.Fatalf("failed to parse ignition config: %v", err) + } + + // Check units with rendered template + if len(ignCfg.Systemd.Units) != 1 { + t.Errorf("expected 1 unit, got %d", len(ignCfg.Systemd.Units)) + } else { + unit := ignCfg.Systemd.Units[0] + if unit.Name != "filbased-swap-provision-0.service" { + t.Errorf("wrong unit name: %s", unit.Name) + } + + if unit.Enabled == nil || *unit.Enabled != true { + t.Error("missing expected enabled for unit") + } + + if unit.Contents != nil && !strings.Contains(*unit.Contents, "/var/tmp/swapfile") { + t.Errorf("template SwapFilePath rendered incorrectly, got %s", *unit.Contents) + } + + if unit.Contents != nil && !strings.Contains(*unit.Contents, "SWAP_SIZE=1Gi") { + t.Errorf("template SwapFileSize rendered incorrectly, got %s", *unit.Contents) + } + } + }, + }, + { + name: "worker mandatory templates", + config: &renderconfig.RenderConfig{}, + role: "worker", + mcName: "99-swap-kubelet-cgroups", + setupFunc: func(t *testing.T, templateDir string) { + commonPath := filepath.Join(templateDir, "worker", "99-swap-kubelet-cgroups", "_base", "files") + os.MkdirAll(commonPath, 0755) + commonTmpl := `mode: 0420 +overwrite: true +path: "/etc/openshift/kubelet.conf.d/90-swap.conf" +contents: + inline: | + apiVersion: kubelet.config.k8s.io/v1beta1 + kind: KubeletConfiguration + failSwapOn: false + memorySwap: + swapBehavior: LimitedSwap +` + os.WriteFile(filepath.Join(commonPath, "kubeletdropin.yaml"), []byte(commonTmpl), 0644) + + workerPath := filepath.Join(templateDir, "worker", "99-swap-kubelet-cgroups", "_base", "units") + os.MkdirAll(workerPath, 0755) + workerTmpl := `name: system-slice-swap-disable.service +enabled: true +contents: | + [Unit] + Description=Restrict swap for system slice + ConditionFirstBoot=no + + [Service] + Type=oneshot + ExecStart=/bin/sh -c "sudo systemctl set-property --runtime system.slice MemorySwapMax=0 IODeviceLatencyTargetSec=\"/ 50ms\"" + + [Install] + RequiredBy=kubelet-dependencies.target +` + os.WriteFile(filepath.Join(workerPath, "system-slice-swap-disable.service"), []byte(workerTmpl), 0644) + }, + validateFunc: func(t *testing.T, mc *mcfgv1.MachineConfig) { + ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw) + if err != nil { + t.Fatalf("parse error: %v", err) + } + + if len(ignCfg.Storage.Files) != 1 { + t.Errorf("expected 1 file, got %d", len(ignCfg.Storage.Files)) + } + + if len(ignCfg.Systemd.Units) != 1 { + t.Errorf("expected 1 unit, got %d", len(ignCfg.Systemd.Units)) + } + + file := ignCfg.Storage.Files[0] + if file.Path != "/etc/openshift/kubelet.conf.d/90-swap.conf" { + t.Error("missing expected file path for kubelet drop-in") + } + if file.Overwrite == nil || *file.Overwrite != true { + t.Error("missing expected overwrite for kubelet drop-in") + } + if file.Mode == nil || *file.Mode != 0420 { + t.Error("missing expected mode for kubelet drop-in") + } + + unit := ignCfg.Systemd.Units[0] + if unit.Name != "system-slice-swap-disable.service" { + t.Error("missing expected unit name") + } + + if unit.Enabled == nil || *unit.Enabled != true { + t.Error("missing expected enabled for unit") + } + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tempDir, _ := os.MkdirTemp("", "template-test-*") + defer os.RemoveAll(tempDir) + + if tt.setupFunc != nil { + tt.setupFunc(t, tempDir) + } + + path := filepath.Join(tempDir, tt.role, tt.mcName) + got, err := GenerateMachineConfigForName(tt.config, tt.role, tt.mcName, tempDir, path) + + if (err != nil) != tt.wantErr { + t.Errorf("error = %v, wantErr %v", err, tt.wantErr) + return + } + + if tt.validateFunc != nil { + tt.validateFunc(t, got) + } + }) + } +} diff --git a/templates/worker/99-filebased-swap-provision/_base/units/filebased-swap-provision.service.yaml b/templates/worker/99-filebased-swap/_base/units/filebased-swap-provision.service.yaml similarity index 61% rename from templates/worker/99-filebased-swap-provision/_base/units/filebased-swap-provision.service.yaml rename to templates/worker/99-filebased-swap/_base/units/filebased-swap-provision.service.yaml index 38d1101..93acd47 100644 --- a/templates/worker/99-filebased-swap-provision/_base/units/filebased-swap-provision.service.yaml +++ b/templates/worker/99-filebased-swap/_base/units/filebased-swap-provision.service.yaml @@ -1,16 +1,16 @@ {{- if .EnableFileBasedSwap }} -name: filbased-swap-provision.service +name: filbased-swap-provision-{{ .Index }}.service enabled: true contents: | [Unit] Description=Provision and enable swap ConditionFirstBoot=no - ConditionPathExists=!/var/tmp/swapfile + ConditionPathExists=!{{ .SwapFilePath }} [Service] Type=oneshot - Environment=SWAP_SIZE_MB={{ .SwapFileSize }} - ExecStart=/bin/sh -c "sudo fallocate -l ${SWAP_SIZE_MB}M /var/tmp/swapfile && \ + Environment=SWAP_SIZE={{ .SwapFileSize }} + ExecStart=/bin/sh -c "sudo fallocate -l ${SWAP_SIZE} {{ .SwapFilePath }} && \ sudo chmod 600 {{ .SwapFilePath }} && \ sudo mkswap {{ .SwapFilePath }} && \ sudo swapon {{ .SwapFilePath }}" diff --git a/templates/worker/99-swap-kubelet-cgroups-config/_base/files/kubeletdropin.yaml b/templates/worker/99-swap-kubelet-cgroups/_base/files/kubeletdropin.yaml similarity index 100% rename from templates/worker/99-swap-kubelet-cgroups-config/_base/files/kubeletdropin.yaml rename to templates/worker/99-swap-kubelet-cgroups/_base/files/kubeletdropin.yaml diff --git a/templates/worker/99-swap-kubelet-cgroups-config/_base/units/system-slice-swap-disable.service.yaml b/templates/worker/99-swap-kubelet-cgroups/_base/units/system-slice-swap-disable.service.yaml similarity index 100% rename from templates/worker/99-swap-kubelet-cgroups-config/_base/units/system-slice-swap-disable.service.yaml rename to templates/worker/99-swap-kubelet-cgroups/_base/units/system-slice-swap-disable.service.yaml