diff --git a/cmd/machine-config-operator/bootstrap.go b/cmd/machine-config-operator/bootstrap.go index 5a37c1883a..d1ae50d15a 100644 --- a/cmd/machine-config-operator/bootstrap.go +++ b/cmd/machine-config-operator/bootstrap.go @@ -31,6 +31,8 @@ var ( infraImage string releaseImage string keepalivedImage string + frrK8sImage string + kubeVipImage string mcoImage string oauthProxyImage string kubeRbacProxyImage string @@ -68,6 +70,8 @@ func init() { bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.dependencyFiles.DNS, "dns-config-file", "/assets/manifests/cluster-dns-02-config.yml", "File containing dns.config.openshift.io manifest.") bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.dependencyFiles.AdditionalTrustBundle, "additional-trust-bundle-config-file", "/assets/manifests/user-ca-bundle-config.yaml", "File containing the additional user provided CA bundle manifest.") bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.keepalivedImage, "keepalived-image", "", "Image for Keepalived.") + bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.frrK8sImage, "frr-k8s-image", "", "Image for frr-k8s.") + bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.kubeVipImage, "kube-vip-image", "", "Image for kube-vip.") bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.corednsImage, "coredns-image", "", "Image for CoreDNS.") bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.haproxyImage, "haproxy-image", "", "Image for haproxy.") bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.baremetalRuntimeCfgImage, "baremetal-runtimecfg-image", "", "Image for baremetal-runtimecfg.") @@ -78,6 +82,7 @@ func init() { bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.dockerRegistryImage, "docker-registry-image", "", "Image for docker-registry.") bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.imageReferences, "image-references", "", "File containing imagestreams (from cluster-version-operator)") bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.dependencyFiles.CloudProviderCA, "cloud-provider-ca-file", "", "path to cloud provider CA certificate") + bootstrapCmd.PersistentFlags().StringVar(&bootstrapOpts.dependencyFiles.BGPVIPConfig, "bgp-vip-config-file", "/assets/manifests/bgp-vip-config.yaml", "File containing the bgp-vip-config ConfigMap manifest (optional).") } @@ -142,6 +147,18 @@ func runBootstrapCmd(_ *cobra.Command, _ []string) { if err != nil { klog.Warningf("Base OS extensions container not found: %s", err) } + // The frr-k8s and kube-vip images are only present in payloads that + // support BGP-based VIP management, so their absence is not fatal. + if img, err := findImage(imgstream, "metallb-frr"); err == nil { + bootstrapOpts.frrK8sImage = img + } else { + klog.Warningf("metallb-frr image not found in image references: %v", err) + } + if img, err := findImage(imgstream, "kube-vip"); err == nil { + bootstrapOpts.kubeVipImage = img + } else { + klog.Warningf("kube-vip image not found in image references: %v", err) + } } imgs := ctrlcommon.Images{ @@ -155,6 +172,8 @@ func runBootstrapCmd(_ *cobra.Command, _ []string) { BaseOSContainerImage: bootstrapOpts.baseOSContainerImage, BaseOSExtensionsContainerImage: bootstrapOpts.baseOSExtensionsContainerImage, DockerRegistryBootstrap: bootstrapOpts.dockerRegistryImage, + FRRK8sBootstrap: bootstrapOpts.frrK8sImage, + KubeVIPBootstrap: bootstrapOpts.kubeVipImage, }, ControllerConfigImages: ctrlcommon.ControllerConfigImages{ InfraImage: bootstrapOpts.infraImage, @@ -163,6 +182,8 @@ func runBootstrapCmd(_ *cobra.Command, _ []string) { Haproxy: bootstrapOpts.haproxyImage, BaremetalRuntimeCfg: bootstrapOpts.baremetalRuntimeCfgImage, DockerRegistry: bootstrapOpts.dockerRegistryImage, + FRRK8s: bootstrapOpts.frrK8sImage, + KubeVip: bootstrapOpts.kubeVipImage, }, } diff --git a/go.mod b/go.mod index 9a4fa87f9d..74b4ac9f4d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/openshift/machine-config-operator -go 1.25.5 +go 1.26.0 require ( github.com/Azure/ARO-RP v0.0.0-20250602035759-0693f32d5ccc @@ -58,9 +58,9 @@ require ( golang.org/x/net v0.56.0 golang.org/x/time v0.14.0 google.golang.org/grpc v1.79.3 - k8s.io/api v0.35.1 + k8s.io/api v0.36.2 k8s.io/apiextensions-apiserver v0.35.1 - k8s.io/apimachinery v0.35.1 + k8s.io/apimachinery v0.36.2 k8s.io/client-go v0.35.1 k8s.io/code-generator v0.35.1 k8s.io/component-base v0.35.1 @@ -420,7 +420,7 @@ require ( golang.org/x/term v0.45.0 // indirect golang.org/x/text v0.40.0 // indirect golang.org/x/tools v0.47.0 // indirect - google.golang.org/protobuf v1.36.11 // indirect + google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 @@ -471,3 +471,8 @@ replace ( k8s.io/sample-cli-plugin => github.com/openshift/kubernetes/staging/src/k8s.io/sample-cli-plugin v0.0.0-20260305123649-d18f3f005eaa k8s.io/sample-controller => github.com/openshift/kubernetes/staging/src/k8s.io/sample-controller v0.0.0-20260305123649-d18f3f005eaa ) + +// TEMPORARY (OPNET-780): pin to the openshift/api#2923 content until that PR +// merges; this replace is then dropped in a one-commit swap to the upstream +// module (see the vendor commit message and PR description). +replace github.com/openshift/api => github.com/mkowalski/openshift-api v0.0.0-20260720204730-3b96df04543d diff --git a/go.sum b/go.sum index 97833e104c..1458fd1543 100644 --- a/go.sum +++ b/go.sum @@ -588,6 +588,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mkowalski/openshift-api v0.0.0-20260720204730-3b96df04543d h1:rTJXtBn6UMoJgX2FO80cUQzn2IP8rGISPMtBMTSyctM= +github.com/mkowalski/openshift-api v0.0.0-20260720204730-3b96df04543d/go.mod h1:k6qH5QOVa5GDln2VVm8Jz4NV3Z7R2SATHFLwGS6Wh3M= github.com/moby/buildkit v0.29.0 h1:wxLEFbCOJntEDjSNNN2YWd8zxltZxT5muDQ0LzpbtpU= github.com/moby/buildkit v0.29.0/go.mod h1:Dmv2FeDe34t75QuzeU87rBoZpAAkcpT5zeu4hXzmASc= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= @@ -656,8 +658,6 @@ github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22 github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg= github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 h1:jJLE/aCAqDf8U4wc3bE1IEKgIxbb0ICjCNVFA49x/8s= github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M= -github.com/openshift/api v0.0.0-20260702202555-ef71f942ef6c h1:X1B6zMjD7kmKcuv9Cxs4Zhq/ruJLt7BsywSWKOA9Jn4= -github.com/openshift/api v0.0.0-20260702202555-ef71f942ef6c/go.mod h1:7WJ3IPaK6nmWT8bDcaNooHqd0H5WepjVqV/10VlkMEM= github.com/openshift/client-go v0.0.0-20260703082747-24d059aea27a h1:RfmstmmWz5/23/Tt8gBipICzC1VHQLgGBeQUQ1aWoUA= github.com/openshift/client-go v0.0.0-20260703082747-24d059aea27a/go.mod h1:fNuXvm6bMJff2AxiRb9CR5L3a9CLzVgcoSmHZ3l7FgU= github.com/openshift/imagebuilder v1.2.21 h1:XX0tZVznWTxzYevvNVZ/0eeTzmgY6cfcT4/xjs5ToyU= @@ -1203,8 +1203,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/install/0000_80_machine-config_00_rbac.yaml b/install/0000_80_machine-config_00_rbac.yaml index 50f2fbaff7..16cd883dbf 100644 --- a/install/0000_80_machine-config_00_rbac.yaml +++ b/install/0000_80_machine-config_00_rbac.yaml @@ -224,3 +224,34 @@ subjects: roleRef: kind: Role name: host-networking-services +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: machine-config-operator-bgp-vip + namespace: openshift-network-operator + annotations: + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" +rules: + - apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["bgp-vip-config"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: machine-config-operator-bgp-vip + namespace: openshift-network-operator + annotations: + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: machine-config-operator-bgp-vip +subjects: + - kind: ServiceAccount + name: machine-config-operator + namespace: openshift-machine-config-operator diff --git a/manifests/on-prem/0000-frr-k8s.yaml b/manifests/on-prem/0000-frr-k8s.yaml new file mode 100644 index 0000000000..05b0c5e49b --- /dev/null +++ b/manifests/on-prem/0000-frr-k8s.yaml @@ -0,0 +1,165 @@ +--- +kind: Pod +apiVersion: v1 +metadata: + name: frr-k8s + namespace: openshift-frr-k8s + labels: + app: frr-k8s +spec: + # hostNetwork: the BGP session must originate from the node IP and the + # advertised VIP routes live in the host routing table (keepalived parity). + hostNetwork: true + shareProcessNamespace: true + priorityClassName: system-node-critical + # 10s (not the upstream DaemonSet's 0): a SIGTERM'd bgpd sends a Cease + # NOTIFICATION, which hard-resets the session; after a SIGKILL a peer in + # graceful-restart helper mode may retain stale VIP routes on bare TCP + # loss until the restart timer expires. + terminationGracePeriodSeconds: 10 + tolerations: + - operator: Exists + initContainers: + - name: render-config-frr + image: {{ .Images.BaremetalRuntimeCfgBootstrap }} + command: + - /usr/bin/runtimecfg + - render + - /etc/kubernetes/kubeconfig + - --api-vips + - {{ onPremPlatformAPIServerInternalIP .ControllerConfig }} + - --ingress-vips + - {{ onPremPlatformIngressIP .ControllerConfig }} + - "--cluster-config" + - "/opt/openshift/manifests/cluster-config.yaml" + - /config/frr.conf.tmpl + - --out-dir + - /etc/frr + - --peer-file + - /config/frr-peers.json + env: + - name: IS_BOOTSTRAP + value: "yes" + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 100m + memory: 128Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: resource-dir + mountPath: /config + readOnly: true + - name: frr-conf + mountPath: /etc/frr + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + - name: manifests + mountPath: "/opt/openshift/manifests" + mountPropagation: HostToContainer + readOnly: true + - name: cp-frr-files + image: {{ .Images.FRRK8sBootstrap }} + command: + - /bin/sh + - -c + - | + set -eu + cp -f /tmp/frr/daemons /etc/frr/daemons + cp -f /tmp/frr/vtysh.conf /etc/frr/vtysh.conf + securityContext: + runAsUser: 100 + runAsGroup: 101 + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: 10m + memory: 20Mi + limits: + cpu: 100m + memory: 128Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: frr-startup + mountPath: /tmp/frr + readOnly: true + - name: frr-conf + mountPath: /etc/frr + containers: + - name: frr + image: {{ .Images.FRRK8sBootstrap }} + command: + - /bin/sh + - -c + - /sbin/tini -- /usr/lib/frr/docker-start + env: + - name: TINI_SUBREAPER + value: "true" + resources: + requests: + cpu: 100m + memory: 200Mi + limits: + cpu: 500m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + # Mirrors the frr container of the frr-k8s DaemonSet shipped by CNO + # (upstream metallb/frr-k8s parity). No drop ALL: FRR's + # privilege-separated startup (watchfrr as root spawning daemons as + # the frr user) additionally relies on root's implicit capabilities + # (SETUID/SETGID/DAC_OVERRIDE/CHOWN); dropping ALL and re-adding + # only the network capabilities was tested and prevents the FRR + # daemons from starting. SYS_ADMIN is required by docker-start/ + # watchfrr process supervision. + add: + - NET_ADMIN + - NET_RAW + - SYS_ADMIN + - NET_BIND_SERVICE + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: frr-sockets + mountPath: /var/run/frr + - name: frr-conf + mountPath: /etc/frr + - name: frr-lib + mountPath: /var/lib/frr + - name: frr-tmp + mountPath: /var/tmp/frr + volumes: + - name: resource-dir + hostPath: + path: /etc/kubernetes/static-pod-resources/frr-k8s + - name: frr-conf + emptyDir: {} + - name: frr-sockets + emptyDir: {} + - name: frr-lib + emptyDir: {} + - name: frr-tmp + emptyDir: {} + - name: frr-startup + hostPath: + path: /etc/kubernetes/static-pod-resources/frr-k8s/startup + - name: kubeconfig + hostPath: + path: /etc/kubernetes + - name: manifests + hostPath: + path: "/opt/openshift/manifests" diff --git a/manifests/on-prem/0010-kube-vip-api.yaml b/manifests/on-prem/0010-kube-vip-api.yaml new file mode 100644 index 0000000000..55f6eda4fc --- /dev/null +++ b/manifests/on-prem/0010-kube-vip-api.yaml @@ -0,0 +1,66 @@ +--- +kind: Pod +apiVersion: v1 +metadata: + name: kube-vip-api + namespace: openshift-kube-vip + labels: + app: kube-vip + component: api +spec: + hostNetwork: true + priorityClassName: system-node-critical + tolerations: + - operator: Exists + containers: + - name: kube-vip + image: {{ .Images.KubeVIPBootstrap }} + args: + - manager + env: + - name: address + value: "{{ onPremPlatformAPIServerInternalIP .ControllerConfig }}" + - name: k8s_config_file + value: "/etc/kubernetes/kubeconfig" + - name: kubernetes_addr + value: "https://localhost:6443" + - name: port + value: "6443" + - name: cp_enable + value: "true" + - name: vip_leaderelection + value: "true" + - name: vip_routingtable + value: "true" + - name: vip_cleanroutingtable + value: "true" + - name: vip_routingtableid + value: "198" + - name: vip_routingtableprotocol + value: "248" + - name: backend_health_check_interval + value: "5" + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + add: + - NET_ADMIN + - NET_RAW + volumeMounts: + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + volumes: + - name: kubeconfig + hostPath: + path: /etc/kubernetes diff --git a/manifests/on-prem/frr-peers.json.tmpl b/manifests/on-prem/frr-peers.json.tmpl new file mode 100644 index 0000000000..b91e5f25b4 --- /dev/null +++ b/manifests/on-prem/frr-peers.json.tmpl @@ -0,0 +1 @@ +{{- .ControllerConfig.BGPVIPPeersJSON -}} diff --git a/manifests/on-prem/frr-startup-daemons b/manifests/on-prem/frr-startup-daemons new file mode 100644 index 0000000000..f5696cb62d --- /dev/null +++ b/manifests/on-prem/frr-startup-daemons @@ -0,0 +1,23 @@ +zebra=yes +bgpd=yes +ospfd=no +ospf6d=no +ripd=no +ripngd=no +isisd=no +pimd=no +ldpd=no +nhrpd=no +eigrpd=no +babeld=no +sharpd=no +pbrd=no +bfdd=yes +fabricd=no +vrrpd=no +pathd=no + +vtysh_enable=yes +zebra_options=" -A 127.0.0.1 -s 90000000" +bgpd_options=" -A 127.0.0.1" +bfdd_options=" -A 127.0.0.1" diff --git a/manifests/on-prem/frr-startup-vtysh.conf b/manifests/on-prem/frr-startup-vtysh.conf new file mode 100644 index 0000000000..e0ab9cb6f3 --- /dev/null +++ b/manifests/on-prem/frr-startup-vtysh.conf @@ -0,0 +1 @@ +service integrated-vtysh-config diff --git a/manifests/on-prem/frr.conf.tmpl b/manifests/on-prem/frr.conf.tmpl new file mode 100644 index 0000000000..687ec9c50b --- /dev/null +++ b/manifests/on-prem/frr.conf.tmpl @@ -0,0 +1,58 @@ +frr version 9.1 +frr defaults traditional +hostname {{`{{.Hostname}}`}} +! +router bgp {{`{{.LocalASN}}`}} + bgp router-id {{`{{.RouterID}}`}} + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + ! +{{`{{- range .Peers}}`}} + neighbor {{`{{.PeerAddress}}`}} remote-as {{`{{.PeerASN}}`}} +{{`{{- if .Password}}`}} + neighbor {{`{{.PeerAddress}}`}} password {{`{{.Password}}`}} +{{`{{- end}}`}} +{{`{{- if eq .BFDEnabled "true"}}`}} + neighbor {{`{{.PeerAddress}}`}} bfd +{{`{{- end}}`}} +{{`{{- if eq .EBGPMultiHop "true"}}`}} + neighbor {{`{{.PeerAddress}}`}} ebgp-multihop +{{`{{- end}}`}} +{{`{{- if .HoldTime}}`}} + neighbor {{`{{.PeerAddress}}`}} timers {{`{{.KeepaliveTime}}`}} {{`{{.HoldTime}}`}} +{{`{{- end}}`}} +{{`{{- end}}`}} + ! + address-family ipv4 unicast + redistribute table-direct 198 +{{`{{- range .Peers}}`}} +{{`{{- if isIPv4 .PeerAddress}}`}} + neighbor {{`{{.PeerAddress}}`}} activate +{{`{{- if $.Communities}}`}} + neighbor {{`{{.PeerAddress}}`}} route-map VIP-COMMUNITY out +{{`{{- end}}`}} +{{`{{- end}}`}} +{{`{{- end}}`}} + exit-address-family + ! + address-family ipv6 unicast + redistribute table-direct 198 +{{`{{- range .Peers}}`}} +{{`{{- if isIPv6 .PeerAddress}}`}} + neighbor {{`{{.PeerAddress}}`}} activate +{{`{{- if $.Communities}}`}} + neighbor {{`{{.PeerAddress}}`}} route-map VIP-COMMUNITY out +{{`{{- end}}`}} +{{`{{- end}}`}} +{{`{{- end}}`}} + exit-address-family +! +{{`{{- if .Communities}}`}} +route-map VIP-COMMUNITY permit 10 +{{`{{- range .Communities}}`}} + set community {{`{{.}}`}} additive +{{`{{- end}}`}} +! +{{`{{- end}}`}} +line vty +! diff --git a/pkg/controller/common/helpers.go b/pkg/controller/common/helpers.go index a0fe7b1bce..5d543c7f1c 100644 --- a/pkg/controller/common/helpers.go +++ b/pkg/controller/common/helpers.go @@ -1605,3 +1605,23 @@ func DetectRuncInMachineConfig(mc *mcfgv1.MachineConfig) (string, error) { } return "", nil } + +// IsBGPVIPManagement reports whether BGP-based VIP management is active: +// BareMetal platform, vipManagement "BGP", and VIPs present. Without VIPs +// (user-managed load balancer) there is nothing to advertise and the +// VIP-consuming templates would render empty values, so the keepalived +// default applies. Shared by the template renderer, the bootstrap manifest +// selection, and the operator's peers ingestion so they cannot disagree. +func IsBGPVIPManagement(infra *configv1.Infrastructure) bool { + if infra == nil || infra.Status.PlatformStatus == nil { + return false + } + ps := infra.Status.PlatformStatus + if ps.Type != configv1.BareMetalPlatformType || ps.BareMetal == nil { + return false + } + if len(ps.BareMetal.APIServerInternalIPs) == 0 || len(ps.BareMetal.IngressIPs) == 0 { + return false + } + return ps.BareMetal.VIPManagement == configv1.VIPManagementTypeBGP +} diff --git a/pkg/controller/common/images.go b/pkg/controller/common/images.go index edb7fb0399..9762254066 100644 --- a/pkg/controller/common/images.go +++ b/pkg/controller/common/images.go @@ -41,6 +41,8 @@ type RenderConfigImages struct { OauthProxy string `json:"oauthProxy"` KubeRbacProxy string `json:"kubeRbacProxy"` DockerRegistryBootstrap string `json:"dockerRegistry"` + FRRK8sBootstrap string `json:"frrK8s"` + KubeVIPBootstrap string `json:"kubeVip"` } // ControllerConfigImages are image names used to render templates under ./templates/ @@ -51,6 +53,8 @@ type ControllerConfigImages struct { Haproxy string `json:"haproxyImage"` BaremetalRuntimeCfg string `json:"baremetalRuntimeCfgImage"` DockerRegistry string `json:"dockerRegistryImage"` + FRRK8s string `json:"frrK8sImage"` + KubeVip string `json:"kubeVipImage"` } // Parses the JSON blob containing the images information into an Images struct. diff --git a/pkg/controller/container-runtime-config/actual.json b/pkg/controller/container-runtime-config/actual.json new file mode 100755 index 0000000000..9c84584104 --- /dev/null +++ b/pkg/controller/container-runtime-config/actual.json @@ -0,0 +1,80 @@ +{ + "default": [ + { + "type": "insecureAcceptAnything" + } + ], + "transports": { + "atomic": { + "test0.com": [ + { + "type": "sigstoreSigned", + "fulcio": { + "caData": "dGVzdC1jYS1kYXRhLWRhdGE=", + "oidcIssuer": "https://OIDC.example.com", + "subjectEmail": "test-user@example.com" + }, + "rekorPublicKeyData": "dGVzdC1yZWtvci1rZXktZGF0YQ==", + "signedIdentity": { + "type": "remapIdentity", + "prefix": "test-remap-prefix", + "signedPrefix": "test-remap-signed-prefix" + } + } + ], + "test3.com/ns/repo": [ + { + "type": "sigstoreSigned", + "pki": { + "caRootsData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJBVEE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", + "caIntermediatesData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJBVEE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", + "subjectEmail": "test-user@example.com", + "subjectHostname": "my-host.example.com" + }, + "signedIdentity": { + "type": "matchRepoDigestOrExact" + } + } + ] + }, + "docker": { + "test0.com": [ + { + "type": "sigstoreSigned", + "fulcio": { + "caData": "dGVzdC1jYS1kYXRhLWRhdGE=", + "oidcIssuer": "https://OIDC.example.com", + "subjectEmail": "test-user@example.com" + }, + "rekorPublicKeyData": "dGVzdC1yZWtvci1rZXktZGF0YQ==", + "signedIdentity": { + "type": "remapIdentity", + "prefix": "test-remap-prefix", + "signedPrefix": "test-remap-signed-prefix" + } + } + ], + "test3.com/ns/repo": [ + { + "type": "sigstoreSigned", + "pki": { + "caRootsData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJBVEE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", + "caIntermediatesData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJBVEE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", + "subjectEmail": "test-user@example.com", + "subjectHostname": "my-host.example.com" + }, + "signedIdentity": { + "type": "matchRepoDigestOrExact" + } + } + ] + }, + "docker-daemon": { + "": [ + { + "type": "insecureAcceptAnything" + } + ] + } + } +} \ No newline at end of file diff --git a/pkg/controller/container-runtime-config/expected.json b/pkg/controller/container-runtime-config/expected.json new file mode 100755 index 0000000000..8c8c67d92b --- /dev/null +++ b/pkg/controller/container-runtime-config/expected.json @@ -0,0 +1,82 @@ + + { + "default": [ + { + "type": "insecureAcceptAnything" + } + ], + "transports": { + "atomic": { + "test0.com": [ + { + "type": "sigstoreSigned", + "fulcio": { + "caData": "dGVzdC1jYS1kYXRhLWRhdGE=", + "oidcIssuer": "https://OIDC.example.com", + "subjectEmail": "test-user@example.com" + }, + "rekorPublicKeyData": "dGVzdC1yZWtvci1rZXktZGF0YQ==", + "signedIdentity": { + "type": "remapIdentity", + "prefix": "test-remap-prefix", + "signedPrefix": "test-remap-signed-prefix" + } + } + ], + "test3.com/ns/repo": [ + { + "type": "sigstoreSigned", + "pki": { + "caRootsData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJBVEE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", + "caIntermediatesData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJBVEE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", + "subjectEmail": "test-user@example.com", + "subjectHostname": "my-host.example.com" + }, + "signedIdentity": { + "type": "matchRepoDigestOrExact" + } + } + ] + }, + "docker": { + "test0.com": [ + { + "type": "sigstoreSigned", + "fulcio": { + "caData": "dGVzdC1jYS1kYXRhLWRhdGE=", + "oidcIssuer": "https://OIDC.example.com", + "subjectEmail": "test-user@example.com" + }, + "rekorPublicKeyData": "dGVzdC1yZWtvci1rZXktZGF0YQ==", + "signedIdentity": { + "type": "remapIdentity", + "prefix": "test-remap-prefix", + "signedPrefix": "test-remap-signed-prefix" + } + } + ], + "test3.com/ns/repo": [ + { + "type": "sigstoreSigned", + "pki": { + "caRootsData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJBVEE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", + "caIntermediatesData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJBVEE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", + "subjectEmail": "test-user@example.com", + "subjectHostname": "my-host.example.com" + }, + "signedIdentity": { + "type": "matchRepoDigestOrExact" + } + } + ] + }, + "docker-daemon": { + "": [ + { + "type": "insecureAcceptAnything" + } + ] + } + } + } + \ No newline at end of file diff --git a/pkg/controller/template/constants.go b/pkg/controller/template/constants.go index 91baec288e..d033553bff 100644 --- a/pkg/controller/template/constants.go +++ b/pkg/controller/template/constants.go @@ -22,6 +22,16 @@ const ( // BaremetalRuntimeCfgKey is the key that references the baremetal-runtimecfg image in the controller BaremetalRuntimeCfgKey string = "baremetalRuntimeCfgImage" + // FRRK8sKey is the key for the frr-k8s image used by the frr-k8s static pod. + // A single image is used for all frr-k8s containers (controller, FRR daemon, + // reloader, metrics, status) in OpenShift. + FRRK8sKey string = "frrK8sImage" + + // KubeVIPKey is the key for the kube-vip image used by the kube-vip static pods. + // kube-vip manages API and Ingress VIPs in Routing Table Mode for BGP-based + // VIP management. + KubeVIPKey string = "kubeVipImage" + // KubeRbacProxyKey the key that references the kubeRbacProxy image KubeRbacProxyKey string = "kubeRbacProxyImage" diff --git a/pkg/controller/template/render.go b/pkg/controller/template/render.go index 39492770f9..ead241f145 100644 --- a/pkg/controller/template/render.go +++ b/pkg/controller/template/render.go @@ -386,6 +386,7 @@ func renderTemplate(config RenderConfig, path string, b []byte) ([]byte, error) funcs["urlHost"] = urlHost funcs["urlPort"] = urlPort funcs["isOpenShiftManagedDefaultLB"] = isOpenShiftManagedDefaultLB + funcs["isBGPVIPManagement"] = isBGPVIPManagement funcs["dnsRecordsType"] = dnsRecordsType funcs["cloudPlatformAPIIntLoadBalancerIPs"] = cloudPlatformAPIIntLoadBalancerIPs funcs["cloudPlatformAPILoadBalancerIPs"] = cloudPlatformAPILoadBalancerIPs @@ -497,10 +498,19 @@ func onPremPlatformIngressIP(cfg RenderConfig) (interface{}, error) { if cfg.Infra.Status.PlatformStatus != nil { switch cfg.Infra.Status.PlatformStatus.Type { case configv1.BareMetalPlatformType: + if len(cfg.Infra.Status.PlatformStatus.BareMetal.IngressIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.BareMetal.IngressIPs[0], nil case configv1.OvirtPlatformType: + if len(cfg.Infra.Status.PlatformStatus.Ovirt.IngressIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.Ovirt.IngressIPs[0], nil case configv1.OpenStackPlatformType: + if len(cfg.Infra.Status.PlatformStatus.OpenStack.IngressIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.OpenStack.IngressIPs[0], nil case configv1.VSpherePlatformType: if cfg.Infra.Status.PlatformStatus.VSphere != nil { @@ -513,6 +523,9 @@ func onPremPlatformIngressIP(cfg RenderConfig) (interface{}, error) { // and there is also no data return nil, nil case configv1.NutanixPlatformType: + if len(cfg.Infra.Status.PlatformStatus.Nutanix.IngressIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.Nutanix.IngressIPs[0], nil default: return nil, fmt.Errorf("invalid platform for Ingress IP") @@ -557,10 +570,19 @@ func onPremPlatformAPIServerInternalIP(cfg RenderConfig) (interface{}, error) { if cfg.Infra.Status.PlatformStatus != nil { switch cfg.Infra.Status.PlatformStatus.Type { case configv1.BareMetalPlatformType: + if len(cfg.Infra.Status.PlatformStatus.BareMetal.APIServerInternalIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.BareMetal.APIServerInternalIPs[0], nil case configv1.OvirtPlatformType: + if len(cfg.Infra.Status.PlatformStatus.Ovirt.APIServerInternalIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.Ovirt.APIServerInternalIPs[0], nil case configv1.OpenStackPlatformType: + if len(cfg.Infra.Status.PlatformStatus.OpenStack.APIServerInternalIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.OpenStack.APIServerInternalIPs[0], nil case configv1.VSpherePlatformType: if cfg.Infra.Status.PlatformStatus.VSphere != nil { @@ -573,6 +595,9 @@ func onPremPlatformAPIServerInternalIP(cfg RenderConfig) (interface{}, error) { // and there is also no data return nil, nil case configv1.NutanixPlatformType: + if len(cfg.Infra.Status.PlatformStatus.Nutanix.APIServerInternalIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.Nutanix.APIServerInternalIPs[0], nil default: return nil, fmt.Errorf("invalid platform for API Server Internal IP") @@ -723,6 +748,14 @@ func isOpenShiftManagedDefaultLB(cfg RenderConfig) bool { return false } +// isBGPVIPManagement returns true when the cluster is configured to use +// BGP-based VIP management instead of keepalived/VRRP. This controls +// whether MCO renders frr-k8s static pod manifests (BGP) or keepalived +// static pod manifests (default). +func isBGPVIPManagement(cfg RenderConfig) bool { + return ctrlcommon.IsBGPVIPManagement(cfg.Infra) +} + func dnsRecordsType(cfg RenderConfig) configv1.DNSRecordsType { if cfg.Infra.Status.PlatformStatus != nil { switch cfg.Infra.Status.PlatformStatus.Type { diff --git a/pkg/controller/template/render_test.go b/pkg/controller/template/render_test.go index 10e6ab739b..af89d9dcc3 100644 --- a/pkg/controller/template/render_test.go +++ b/pkg/controller/template/render_test.go @@ -596,3 +596,148 @@ func verifyIgn(actual [][]byte, dir string, t *testing.T) { t.Errorf("can't find expected file:\n%v", key) } } + +func TestIsBGPVIPManagement(t *testing.T) { + dummyTemplate := []byte(`{{isBGPVIPManagement .}}`) + + cases := []struct { + name string + infra *configv1.Infrastructure + result string + }{ + { + name: "nil infra", + infra: nil, + result: "false", + }, + { + name: "nil platform status", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{}, + }, + result: "false", + }, + { + name: "baremetal without VIPManagement", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.BareMetalPlatformType, + BareMetal: &configv1.BareMetalPlatformStatus{}, + }, + }, + }, + result: "false", + }, + { + name: "baremetal with VIPManagement BGP", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.BareMetalPlatformType, + BareMetal: &configv1.BareMetalPlatformStatus{ + VIPManagement: "BGP", + APIServerInternalIPs: []string{"192.168.111.5"}, + IngressIPs: []string{"192.168.111.4"}, + }, + }, + }, + }, + result: "true", + }, + { + name: "baremetal with VIPManagement BGP but no VIPs (user-managed LB)", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.BareMetalPlatformType, + BareMetal: &configv1.BareMetalPlatformStatus{ + VIPManagement: "BGP", + }, + }, + }, + }, + result: "false", + }, + { + name: "baremetal with VIPManagement BGP but no ingress VIPs", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.BareMetalPlatformType, + BareMetal: &configv1.BareMetalPlatformStatus{ + VIPManagement: "BGP", + APIServerInternalIPs: []string{"192.168.111.5"}, + }, + }, + }, + }, + result: "false", + }, + { + name: "baremetal with VIPManagement Keepalived", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.BareMetalPlatformType, + BareMetal: &configv1.BareMetalPlatformStatus{ + VIPManagement: "Keepalived", + }, + }, + }, + }, + result: "false", + }, + { + name: "nil baremetal status", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.BareMetalPlatformType, + }, + }, + }, + result: "false", + }, + { + name: "vsphere platform", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.VSpherePlatformType, + }, + }, + }, + result: "false", + }, + { + name: "aws platform", + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.AWSPlatformType, + }, + }, + }, + result: "false", + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + config := &mcfgv1.ControllerConfig{ + Spec: mcfgv1.ControllerConfigSpec{ + Infra: c.infra, + }, + } + + got, err := renderTemplate(RenderConfig{&config.Spec, `{"dummy":"dummy"}`, "dummy", nil, nil}, c.name, dummyTemplate) + if err != nil { + t.Fatalf("expected nil error, got: %v", err) + } + if string(got) != c.result { + t.Fatalf("mismatch: got %q, want %q", string(got), c.result) + } + }) + } +} diff --git a/pkg/operator/bootstrap.go b/pkg/operator/bootstrap.go index 459143e431..b0c968ca42 100644 --- a/pkg/operator/bootstrap.go +++ b/pkg/operator/bootstrap.go @@ -112,6 +112,15 @@ func buildSpec(dependencies *BootstrapDependencies, imgs *ctrlcommon.Images, rel return nil, err } + // BGP-based VIP management renders frr-k8s and kube-vip static pods at + // bootstrap; without their images the manifests would carry empty image + // fields and the install dies much later with no useful signal. + if ctrlcommon.IsBGPVIPManagement(dependencies.Infrastructure) { + if imgs.FRRK8s == "" || imgs.KubeVip == "" { + return nil, fmt.Errorf("BGP-based VIP management is enabled but the frr-k8s (%q) or kube-vip (%q) image is missing from the release payload", imgs.FRRK8s, imgs.KubeVip) + } + } + if dependencies.AdditionalTrustBundle != "" { spec.AdditionalTrustBundle = []byte(dependencies.AdditionalTrustBundle) } @@ -130,6 +139,7 @@ func buildSpec(dependencies *BootstrapDependencies, imgs *ctrlcommon.Images, rel } spec.RootCAData = []byte(dependencies.MCSCA) + spec.BGPVIPPeersJSON = dependencies.BGPVIPPeersJSON spec.PullSecret = nil spec.BaseOSContainerImage = imgs.BaseOSContainerImage spec.BaseOSExtensionsContainerImage = imgs.BaseOSExtensionsContainerImage @@ -145,6 +155,8 @@ func buildSpec(dependencies *BootstrapDependencies, imgs *ctrlcommon.Images, rel templatectrl.BaremetalRuntimeCfgKey: imgs.BaremetalRuntimeCfg, templatectrl.KubeRbacProxyKey: imgs.KubeRbacProxy, templatectrl.DockerRegistryKey: imgs.DockerRegistry, + templatectrl.FRRK8sKey: imgs.FRRK8s, + templatectrl.KubeVIPKey: imgs.KubeVip, } config := getRenderConfig("", dependencies.KubeAPIServerServingCA, spec, @@ -154,25 +166,29 @@ func buildSpec(dependencies *BootstrapDependencies, imgs *ctrlcommon.Images, rel func appendManifestsByPlatform(manifests []manifest, infra *configv1.Infrastructure) []manifest { lbType := configv1.LoadBalancerTypeOpenShiftManagedDefault + var vipManagement configv1.VIPManagementType if infra.Status.PlatformStatus.BareMetal != nil { if infra.Status.PlatformStatus.BareMetal.LoadBalancer != nil { lbType = infra.Status.PlatformStatus.BareMetal.LoadBalancer.Type } - manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.BareMetalPlatformType)), lbType) + if ctrlcommon.IsBGPVIPManagement(infra) { + vipManagement = configv1.VIPManagementTypeBGP + } + manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.BareMetalPlatformType)), lbType, vipManagement) } if infra.Status.PlatformStatus.OpenStack != nil { if infra.Status.PlatformStatus.OpenStack.LoadBalancer != nil { lbType = infra.Status.PlatformStatus.OpenStack.LoadBalancer.Type } - manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.OpenStackPlatformType)), lbType) + manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.OpenStackPlatformType)), lbType, "") } if infra.Status.PlatformStatus.Ovirt != nil { if infra.Status.PlatformStatus.Ovirt.LoadBalancer != nil { lbType = infra.Status.PlatformStatus.Ovirt.LoadBalancer.Type } - manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.OvirtPlatformType)), lbType) + manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.OvirtPlatformType)), lbType, "") } if infra.Status.PlatformStatus.VSphere != nil { @@ -189,14 +205,14 @@ func appendManifestsByPlatform(manifests []manifest, infra *configv1.Infrastruct return manifests } } - manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.VSpherePlatformType)), lbType) + manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.VSpherePlatformType)), lbType, "") } if infra.Status.PlatformStatus.Nutanix != nil { if infra.Status.PlatformStatus.Nutanix.LoadBalancer != nil { lbType = infra.Status.PlatformStatus.Nutanix.LoadBalancer.Type } - manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.NutanixPlatformType)), lbType) + manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.NutanixPlatformType)), lbType, "") } if infra.Status.PlatformStatus.GCP != nil { @@ -205,7 +221,7 @@ func appendManifestsByPlatform(manifests []manifest, infra *configv1.Infrastruct // We do not need the keepalived manifests to be generated because the cloud default Load Balancers are in use. // So, setting the lbType to `UserManaged` although the default cloud LBs are not user managed. lbType = configv1.LoadBalancerTypeUserManaged - manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.GCPPlatformType)), lbType) + manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.GCPPlatformType)), lbType, "") } } if infra.Status.PlatformStatus.AWS != nil { @@ -214,7 +230,7 @@ func appendManifestsByPlatform(manifests []manifest, infra *configv1.Infrastruct // We do not need the keepalived manifests to be generated because the cloud default Load Balancers are in use. // So, setting the lbType to `UserManaged` although the default cloud LBs are not user managed. lbType = configv1.LoadBalancerTypeUserManaged - manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.AWSPlatformType)), lbType) + manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.AWSPlatformType)), lbType, "") } } if infra.Status.PlatformStatus.Azure != nil { @@ -223,14 +239,14 @@ func appendManifestsByPlatform(manifests []manifest, infra *configv1.Infrastruct // We do not need the keepalived manifests to be generated because the cloud default Load Balancers are in use. // So, setting the lbType to `UserManaged` although the default cloud LBs are not user managed. lbType = configv1.LoadBalancerTypeUserManaged - manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.AzurePlatformType)), lbType) + manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.AzurePlatformType)), lbType, "") } } return manifests } -func getPlatformManifests(manifests []manifest, platformName string, lbType configv1.PlatformLoadBalancerType) []manifest { +func getPlatformManifests(manifests []manifest, platformName string, lbType configv1.PlatformLoadBalancerType, vipManagement configv1.VIPManagementType) []manifest { var corednsName string var corefileName string switch platformName { @@ -254,16 +270,27 @@ func getPlatformManifests(manifests []manifest, platformName string, lbType conf ) if lbType == configv1.LoadBalancerTypeOpenShiftManagedDefault || lbType == "" { - platformManifests = append(platformManifests, - manifest{ - name: "manifests/on-prem/keepalived.yaml", - filename: platformName + "/manifests/keepalived.yaml", - }, - manifest{ - name: "manifests/on-prem/keepalived.conf.tmpl", - filename: platformName + "/static-pod-resources/keepalived/keepalived.conf.tmpl", - }, - ) + if vipManagement == "BGP" { + platformManifests = append(platformManifests, + manifest{name: "manifests/on-prem/0000-frr-k8s.yaml", filename: platformName + "/manifests/0000-frr-k8s.yaml"}, + manifest{name: "manifests/on-prem/frr.conf.tmpl", filename: platformName + "/static-pod-resources/frr-k8s/frr.conf.tmpl"}, + manifest{name: "manifests/on-prem/frr-peers.json.tmpl", filename: platformName + "/static-pod-resources/frr-k8s/frr-peers.json"}, + manifest{name: "manifests/on-prem/frr-startup-daemons", filename: platformName + "/static-pod-resources/frr-k8s/startup/daemons"}, + manifest{name: "manifests/on-prem/frr-startup-vtysh.conf", filename: platformName + "/static-pod-resources/frr-k8s/startup/vtysh.conf"}, + manifest{name: "manifests/on-prem/0010-kube-vip-api.yaml", filename: platformName + "/manifests/0010-kube-vip-api.yaml"}, + ) + } else { + platformManifests = append(platformManifests, + manifest{ + name: "manifests/on-prem/keepalived.yaml", + filename: platformName + "/manifests/keepalived.yaml", + }, + manifest{ + name: "manifests/on-prem/keepalived.conf.tmpl", + filename: platformName + "/static-pod-resources/keepalived/keepalived.conf.tmpl", + }, + ) + } } return append(manifests, platformManifests...) diff --git a/pkg/operator/bootstrap_dependencies.go b/pkg/operator/bootstrap_dependencies.go index a9ae876214..e6a86de13c 100644 --- a/pkg/operator/bootstrap_dependencies.go +++ b/pkg/operator/bootstrap_dependencies.go @@ -25,6 +25,7 @@ type BootstrapDependenciesFiles struct { MCSCAFile string KubeAPIServerServingCA string PullSecret string + BGPVIPConfig string } // Validate ensures all required files are set and all provided file paths exist. @@ -45,6 +46,7 @@ func (b BootstrapDependenciesFiles) Validate() error { {"CloudProviderCA", b.CloudProviderCA, false}, {"AdditionalTrustBundle", b.AdditionalTrustBundle, false}, {"CloudConfig", b.CloudConfig, false}, + {"BGPVIPConfig", b.BGPVIPConfig, false}, } for _, file := range files { if err := b.validateFile(file.name, file.path, file.required); err != nil { @@ -87,6 +89,7 @@ type BootstrapDependencies struct { KubeAPIServerServingCA string MCSCA string AdditionalTrustBundle string + BGPVIPPeersJSON string } // NewBootstrapDependencies creates a new BootstrapDependencies instance by validating and loading @@ -131,6 +134,9 @@ func (b *BootstrapDependencies) fillDependencies() error { if err := b.fillClusterConfig(); err != nil { return err } + if err := b.fillBGPVIPConfig(b.Files.BGPVIPConfig); err != nil { + return err + } if err := b.fillCloudConfigData(); err != nil { return err } @@ -276,3 +282,30 @@ func (b *BootstrapDependencies) fillClusterConfig() error { } return nil } + +// fillBGPVIPConfig loads the optional bgp-vip-config ConfigMap manifest and +// extracts its config.json payload for frr-peers.json rendering. +func (b *BootstrapDependencies) fillBGPVIPConfig(path string) error { + if path == "" { + return nil + } + if _, err := os.Stat(path); os.IsNotExist(err) { + return nil // optional: only present when BGP VIP management is enabled + } + cm, err := readCoreCR[*corev1.ConfigMap](path) + if err != nil { + return fmt.Errorf("failed to read bgp-vip-config ConfigMap: %w", err) + } + // Mirror the day-2 sync: a present ConfigMap without a config.json + // payload is a hard error, not an empty peers file. + raw := cm.Data["config.json"] + if raw == "" { + return fmt.Errorf("bgp-vip-config ConfigMap has no config.json payload") + } + peersJSON, err := compactBGPVIPPeersJSON(raw) + if err != nil { + return err + } + b.BGPVIPPeersJSON = peersJSON + return nil +} diff --git a/pkg/operator/bootstrap_test.go b/pkg/operator/bootstrap_test.go new file mode 100644 index 0000000000..5f00bc9831 --- /dev/null +++ b/pkg/operator/bootstrap_test.go @@ -0,0 +1,238 @@ +package operator + +import ( + "os" + "path/filepath" + "testing" + + configv1 "github.com/openshift/api/config/v1" + ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetPlatformManifests(t *testing.T) { + cases := []struct { + name string + platformName string + lbType configv1.PlatformLoadBalancerType + vipManagement configv1.VIPManagementType + expectKeepalived bool + expectFRRK8s bool + expectCoredns bool + expectKubeVIPAPI bool + }{ + { + name: "baremetal default LB, no BGP", + platformName: "baremetal", + lbType: configv1.LoadBalancerTypeOpenShiftManagedDefault, + vipManagement: "", + expectKeepalived: true, + expectFRRK8s: false, + expectCoredns: true, + expectKubeVIPAPI: false, + }, + { + name: "baremetal default LB, BGP enabled", + platformName: "baremetal", + lbType: configv1.LoadBalancerTypeOpenShiftManagedDefault, + vipManagement: "BGP", + expectKeepalived: false, + expectFRRK8s: true, + expectCoredns: true, + expectKubeVIPAPI: true, + }, + { + name: "baremetal user-managed LB, no BGP", + platformName: "baremetal", + lbType: configv1.LoadBalancerTypeUserManaged, + vipManagement: "", + expectKeepalived: false, + expectFRRK8s: false, + expectCoredns: true, + expectKubeVIPAPI: false, + }, + { + name: "baremetal user-managed LB, BGP enabled", + platformName: "baremetal", + lbType: configv1.LoadBalancerTypeUserManaged, + vipManagement: "BGP", + expectKeepalived: false, + expectFRRK8s: false, + expectCoredns: true, + expectKubeVIPAPI: false, + }, + { + name: "baremetal empty LB type, no BGP", + platformName: "baremetal", + lbType: "", + vipManagement: "", + expectKeepalived: true, + expectFRRK8s: false, + expectCoredns: true, + expectKubeVIPAPI: false, + }, + { + name: "baremetal empty LB type, BGP enabled", + platformName: "baremetal", + lbType: "", + vipManagement: "BGP", + expectKeepalived: false, + expectFRRK8s: true, + expectCoredns: true, + expectKubeVIPAPI: true, + }, + { + name: "openstack default LB, no BGP", + platformName: "openstack", + lbType: configv1.LoadBalancerTypeOpenShiftManagedDefault, + vipManagement: "", + expectKeepalived: true, + expectFRRK8s: false, + expectCoredns: true, + expectKubeVIPAPI: false, + }, + { + name: "gcp cloud platform", + platformName: "gcp", + lbType: configv1.LoadBalancerTypeUserManaged, + vipManagement: "", + expectKeepalived: false, + expectFRRK8s: false, + expectCoredns: true, + expectKubeVIPAPI: false, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + result := getPlatformManifests(nil, c.platformName, c.lbType, c.vipManagement) + + hasKeepalived := false + hasFRRK8s := false + hasCoredns := false + hasKubeVIPAPI := false + for _, m := range result { + if m.name == "manifests/on-prem/keepalived.yaml" { + hasKeepalived = true + } + if m.name == "manifests/on-prem/0000-frr-k8s.yaml" { + hasFRRK8s = true + } + if m.name == "manifests/on-prem/coredns.yaml" || m.name == "manifests/cloud-platform-alt-dns/coredns.yaml" { + hasCoredns = true + } + if m.name == "manifests/on-prem/0010-kube-vip-api.yaml" { + hasKubeVIPAPI = true + } + } + + assert.Equal(t, c.expectKeepalived, hasKeepalived, "keepalived manifest presence") + assert.Equal(t, c.expectFRRK8s, hasFRRK8s, "frr-k8s manifest presence") + assert.Equal(t, c.expectCoredns, hasCoredns, "coredns manifest presence") + assert.Equal(t, c.expectKubeVIPAPI, hasKubeVIPAPI, "kube-vip-api manifest presence") + }) + } +} + +func TestFillBGPVIPConfig(t *testing.T) { + dir := t.TempDir() + peersJSON := `{"localASN":64512,"defaultPeers":[{"peerAddress":"192.168.111.1","peerASN":64513}],"apiVIPs":["192.168.111.5"],"ingressVIPs":["192.168.111.4"]}` + cmYAML := `apiVersion: v1 +kind: ConfigMap +metadata: + name: bgp-vip-config + namespace: openshift-network-operator +data: + config.json: '` + peersJSON + `' +` + path := filepath.Join(dir, "bgp-vip-config.yaml") + require.NoError(t, os.WriteFile(path, []byte(cmYAML), 0o644)) + + deps := &BootstrapDependencies{} + require.NoError(t, deps.fillBGPVIPConfig(path), "fillBGPVIPConfig") + assert.Equal(t, peersJSON, deps.BGPVIPPeersJSON, "BGPVIPPeersJSON must be the compacted config.json payload") + + // Missing file is tolerated (optional dependency). + deps2 := &BootstrapDependencies{} + require.NoError(t, deps2.fillBGPVIPConfig(filepath.Join(dir, "nonexistent.yaml")), "missing file must not error") + assert.Empty(t, deps2.BGPVIPPeersJSON, "expected empty for missing file") + + // Malformed config.json payload must be rejected. + badCMYAML := `apiVersion: v1 +kind: ConfigMap +metadata: + name: bgp-vip-config + namespace: openshift-network-operator +data: + config.json: '{not json' +` + badPath := filepath.Join(dir, "bgp-vip-config-bad.yaml") + require.NoError(t, os.WriteFile(badPath, []byte(badCMYAML), 0o644)) + + deps3 := &BootstrapDependencies{} + assert.Error(t, deps3.fillBGPVIPConfig(badPath), "malformed config.json must error") + assert.Empty(t, deps3.BGPVIPPeersJSON, "expected empty for malformed config.json") + + // A present ConfigMap without a config.json payload must be rejected + // (mirrors the day-2 sync behavior). + emptyCMYAML := `apiVersion: v1 +kind: ConfigMap +metadata: + name: bgp-vip-config + namespace: openshift-network-operator +data: {} +` + emptyPath := filepath.Join(dir, "bgp-vip-config-empty.yaml") + require.NoError(t, os.WriteFile(emptyPath, []byte(emptyCMYAML), 0o644)) + + deps4 := &BootstrapDependencies{} + assert.Error(t, deps4.fillBGPVIPConfig(emptyPath), "empty config.json payload must error") + assert.Empty(t, deps4.BGPVIPPeersJSON, "expected empty for empty config.json") +} + +// TestBuildSpecBGPImageValidation locks the bootstrap hard-fail: rendering a +// BGP VIP management cluster without the frr-k8s/kube-vip images must error +// at render time rather than emit static pod manifests with empty images. +func TestBuildSpecBGPImageValidation(t *testing.T) { + bgpInfra := &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.BareMetalPlatformType, + BareMetal: &configv1.BareMetalPlatformStatus{ + VIPManagement: configv1.VIPManagementTypeBGP, + APIServerInternalIPs: []string{"192.168.111.5"}, + IngressIPs: []string{"192.168.111.4"}, + }, + }, + EtcdDiscoveryDomain: "tt.testing", + }, + } + deps := func(infra *configv1.Infrastructure) *BootstrapDependencies { + return &BootstrapDependencies{ + Infrastructure: infra, + Network: &configv1.Network{ + Spec: configv1.NetworkSpec{ServiceNetwork: []string{"192.168.1.0/24"}}}, + DNS: &configv1.DNS{ + Spec: configv1.DNSSpec{BaseDomain: "tt.testing"}}, + } + } + imgs := &ctrlcommon.Images{} + + if _, err := buildSpec(deps(bgpInfra), imgs, ""); err == nil { + t.Fatal("expected an error for BGP VIP management without frr-k8s/kube-vip images") + } + + imgs.FRRK8s = "frr-k8s-image" + imgs.KubeVip = "kube-vip-image" + if _, err := buildSpec(deps(bgpInfra), imgs, ""); err != nil { + t.Fatalf("unexpected error with images present: %v", err) + } + + // VIP-less BGP falls back to keepalived; missing images must not fail. + noVIPs := bgpInfra.DeepCopy() + noVIPs.Status.PlatformStatus.BareMetal.APIServerInternalIPs = nil + if _, err := buildSpec(deps(noVIPs), &ctrlcommon.Images{}, ""); err != nil { + t.Fatalf("unexpected error for VIP-less BGP without images: %v", err) + } +} diff --git a/pkg/operator/render.go b/pkg/operator/render.go index 5fb2c3aa85..43b72ed13c 100644 --- a/pkg/operator/render.go +++ b/pkg/operator/render.go @@ -281,10 +281,19 @@ func onPremPlatformIngressIP(cfg mcfgv1.ControllerConfigSpec) (interface{}, erro if cfg.Infra.Status.PlatformStatus != nil { switch cfg.Infra.Status.PlatformStatus.Type { case configv1.BareMetalPlatformType: + if len(cfg.Infra.Status.PlatformStatus.BareMetal.IngressIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.BareMetal.IngressIPs[0], nil case configv1.OvirtPlatformType: + if len(cfg.Infra.Status.PlatformStatus.Ovirt.IngressIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.Ovirt.IngressIPs[0], nil case configv1.OpenStackPlatformType: + if len(cfg.Infra.Status.PlatformStatus.OpenStack.IngressIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.OpenStack.IngressIPs[0], nil case configv1.VSpherePlatformType: if len(cfg.Infra.Status.PlatformStatus.VSphere.IngressIPs) > 0 { @@ -292,6 +301,9 @@ func onPremPlatformIngressIP(cfg mcfgv1.ControllerConfigSpec) (interface{}, erro } return nil, nil case configv1.NutanixPlatformType: + if len(cfg.Infra.Status.PlatformStatus.Nutanix.IngressIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.Nutanix.IngressIPs[0], nil default: return nil, fmt.Errorf("invalid platform for Ingress IP") @@ -332,10 +344,19 @@ func onPremPlatformAPIServerInternalIP(cfg mcfgv1.ControllerConfigSpec) (interfa if cfg.Infra.Status.PlatformStatus != nil { switch cfg.Infra.Status.PlatformStatus.Type { case configv1.BareMetalPlatformType: + if len(cfg.Infra.Status.PlatformStatus.BareMetal.APIServerInternalIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.BareMetal.APIServerInternalIPs[0], nil case configv1.OvirtPlatformType: + if len(cfg.Infra.Status.PlatformStatus.Ovirt.APIServerInternalIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.Ovirt.APIServerInternalIPs[0], nil case configv1.OpenStackPlatformType: + if len(cfg.Infra.Status.PlatformStatus.OpenStack.APIServerInternalIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.OpenStack.APIServerInternalIPs[0], nil case configv1.VSpherePlatformType: if len(cfg.Infra.Status.PlatformStatus.VSphere.APIServerInternalIPs) > 0 { @@ -343,6 +364,9 @@ func onPremPlatformAPIServerInternalIP(cfg mcfgv1.ControllerConfigSpec) (interfa } return nil, nil case configv1.NutanixPlatformType: + if len(cfg.Infra.Status.PlatformStatus.Nutanix.APIServerInternalIPs) == 0 { + return nil, nil + } return cfg.Infra.Status.PlatformStatus.Nutanix.APIServerInternalIPs[0], nil default: return nil, fmt.Errorf("invalid platform for API Server Internal IP") diff --git a/pkg/operator/render_test.go b/pkg/operator/render_test.go index 4602089634..b5244a3b7c 100644 --- a/pkg/operator/render_test.go +++ b/pkg/operator/render_test.go @@ -120,6 +120,7 @@ func TestRenderAllManifests(t *testing.T) { HTTPSProxy: "https://i.am.a.proxy.server", NoProxy: "*", }, + BGPVIPPeersJSON: `{"localASN":64512,"defaultPeers":[{"peerAddress":"192.168.111.1","peerASN":64513}]}`, Infra: &configv1.Infrastructure{ Status: configv1.InfrastructureStatus{ PlatformStatus: &configv1.PlatformStatus{ diff --git a/pkg/operator/sync.go b/pkg/operator/sync.go index dd8cbe5b18..90898a8a1e 100644 --- a/pkg/operator/sync.go +++ b/pkg/operator/sync.go @@ -374,6 +374,48 @@ func (optr *Operator) syncCloudConfig(spec *mcfgv1.ControllerConfigSpec, infra * return nil } +// compactBGPVIPPeersJSON validates and compacts the bgp-vip-config payload so +// it is safe to embed in single-line template contexts. +func compactBGPVIPPeersJSON(raw string) (string, error) { + if raw == "" { + return "", nil + } + var buf bytes.Buffer + if err := json.Compact(&buf, []byte(raw)); err != nil { + return "", fmt.Errorf("bgp-vip-config config.json is not valid JSON: %w", err) + } + return buf.String(), nil +} + +// syncBGPVIPPeersJSON populates spec.BGPVIPPeersJSON from the +// openshift-network-operator/bgp-vip-config ConfigMap when BGP-based VIP +// management is enabled on a BareMetal platform. +func (optr *Operator) syncBGPVIPPeersJSON(spec *mcfgv1.ControllerConfigSpec, infra *configv1.Infrastructure) error { + if !ctrlcommon.IsBGPVIPManagement(infra) { + return nil + } + cm, err := optr.clusterCmLister.ConfigMaps("openshift-network-operator").Get("bgp-vip-config") + if err != nil { + if apierrors.IsNotFound(err) { + // The spec is rebuilt from scratch on every sync, so silently + // tolerating absence would blank the peers file fleet-wide. + // Degrade instead, holding the last good ControllerConfig. + return fmt.Errorf("BGP VIP management is enabled but the openshift-network-operator/bgp-vip-config ConfigMap is missing") + } + return fmt.Errorf("failed to read bgp-vip-config ConfigMap: %w", err) + } + raw := cm.Data["config.json"] + if raw == "" { + return fmt.Errorf("BGP VIP management is enabled but the bgp-vip-config ConfigMap has no config.json payload") + } + peersJSON, err := compactBGPVIPPeersJSON(raw) + if err != nil { + return err + } + spec.BGPVIPPeersJSON = peersJSON + return nil +} + //nolint:gocyclo func (optr *Operator) syncRenderConfig(_ *renderConfig, _ *configv1.ClusterOperator) error { if optr.inClusterBringup { @@ -598,6 +640,10 @@ func (optr *Operator) syncRenderConfig(_ *renderConfig, _ *configv1.ClusterOpera return err } + if err := optr.syncBGPVIPPeersJSON(spec, infra); err != nil { + return err + } + if !osimagestream.IsFeatureEnabled(optr.fgHandler) { oscontainer, osextensionscontainer, err := optr.getOSImageURLsFromConfigMap() if err != nil { @@ -625,6 +671,8 @@ func (optr *Operator) syncRenderConfig(_ *renderConfig, _ *configv1.ClusterOpera templatectrl.BaremetalRuntimeCfgKey: imgs.BaremetalRuntimeCfg, templatectrl.KubeRbacProxyKey: imgs.KubeRbacProxy, templatectrl.DockerRegistryKey: imgs.DockerRegistry, + templatectrl.FRRK8sKey: imgs.FRRK8s, + templatectrl.KubeVIPKey: imgs.KubeVip, } ignitionHost, err := getIgnitionHost(&infra.Status) diff --git a/pkg/operator/sync_test.go b/pkg/operator/sync_test.go index 7c5ca80260..5dfeaed461 100644 --- a/pkg/operator/sync_test.go +++ b/pkg/operator/sync_test.go @@ -10,6 +10,7 @@ import ( ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common" "github.com/openshift/machine-config-operator/test/helpers" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/informers" @@ -179,6 +180,121 @@ func withCABundle(caBundle string) kubeCloudConfigOption { } } +func withBareMetalVIPManagement(vipManagement configv1.VIPManagementType) infraOption { + return func(infra *configv1.Infrastructure) { + if infra.Status.PlatformStatus == nil { + infra.Status.PlatformStatus = &configv1.PlatformStatus{} + } + infra.Status.PlatformStatus.Type = configv1.BareMetalPlatformType + infra.Status.PlatformStatus.BareMetal = &configv1.BareMetalPlatformStatus{ + VIPManagement: vipManagement, + APIServerInternalIPs: []string{"192.168.111.5"}, + IngressIPs: []string{"192.168.111.4"}, + } + } +} + +func buildBGPVIPConfigMap(configJSON string) *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "openshift-network-operator", + Name: "bgp-vip-config", + }, + Data: map[string]string{ + "config.json": configJSON, + }, + } +} + +func TestSyncBGPVIPPeersJSON(t *testing.T) { + compactJSON := `{"localASN":64512,"defaultPeers":[{"peerAddress":"192.168.111.1","peerASN":64513}]}` + prettyJSON := `{ + "localASN": 64512, + "defaultPeers": [ + { + "peerAddress": "192.168.111.1", + "peerASN": 64513 + } + ] +}` + cases := []struct { + name string + infra *configv1.Infrastructure + configMap *corev1.ConfigMap + expectError bool + expectedBGPVIPPeersJSON string + }{ + { + name: "non-BareMetal platform is a no-op", + infra: buildInfra(withPlatformType(configv1.AWSPlatformType)), + }, + { + name: "BareMetal without BGP VIP management is a no-op", + infra: buildInfra(withPlatformType(configv1.BareMetalPlatformType), withBareMetalVIPManagement("")), + }, + { + // User-managed load balancer: BGP mode without VIPs renders + // keepalived-neither-BGP, and the peers ingestion must not + // degrade the operator over the (rightfully) absent ConfigMap. + name: "BGP without VIPs is a no-op", + infra: buildInfra(withPlatformType(configv1.BareMetalPlatformType), withBareMetalVIPManagement("BGP"), + func(infra *configv1.Infrastructure) { + infra.Status.PlatformStatus.BareMetal.APIServerInternalIPs = nil + }), + }, + { + name: "BGP enabled with ConfigMap present", + infra: buildInfra(withPlatformType(configv1.BareMetalPlatformType), withBareMetalVIPManagement("BGP")), + configMap: buildBGPVIPConfigMap(compactJSON), + expectedBGPVIPPeersJSON: compactJSON, + }, + { + name: "BGP enabled with pretty-printed ConfigMap payload is compacted", + infra: buildInfra(withPlatformType(configv1.BareMetalPlatformType), withBareMetalVIPManagement("BGP")), + configMap: buildBGPVIPConfigMap(prettyJSON), + expectedBGPVIPPeersJSON: compactJSON, + }, + { + name: "BGP enabled with missing ConfigMap degrades", + infra: buildInfra(withPlatformType(configv1.BareMetalPlatformType), withBareMetalVIPManagement("BGP")), + expectError: true, + }, + { + name: "BGP enabled with malformed payload degrades", + infra: buildInfra(withPlatformType(configv1.BareMetalPlatformType), withBareMetalVIPManagement("BGP")), + configMap: buildBGPVIPConfigMap("{not json"), + expectError: true, + }, + { + name: "BGP enabled with empty config.json payload degrades", + infra: buildInfra(withPlatformType(configv1.BareMetalPlatformType), withBareMetalVIPManagement("BGP")), + configMap: buildBGPVIPConfigMap(""), + expectError: true, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + sharedInformer := informers.NewSharedInformerFactory(fake.NewSimpleClientset(), 0) + cmInformer := sharedInformer.Core().V1().ConfigMaps() + if tc.configMap != nil { + require.NoError(t, cmInformer.Informer().GetIndexer().Add(tc.configMap)) + } + optr := &Operator{ + clusterCmLister: cmInformer.Lister(), + } + spec := &mcfgv1.ControllerConfigSpec{} + err := optr.syncBGPVIPPeersJSON(spec, tc.infra) + if tc.expectError { + assert.Error(t, err) + assert.Empty(t, spec.BGPVIPPeersJSON) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.expectedBGPVIPPeersJSON, spec.BGPVIPPeersJSON) + }) + } +} + func TestMachineOSBuilderSecretReconciliation(t *testing.T) { masterPool := helpers.NewMachineConfigPool("master", nil, helpers.MasterSelector, "v0") workerPool := helpers.NewMachineConfigPool("worker", nil, helpers.MasterSelector, "v0") diff --git a/templates/common/on-prem/files/0020-kube-vip-ingress.yaml b/templates/common/on-prem/files/0020-kube-vip-ingress.yaml new file mode 100644 index 0000000000..99abe8a755 --- /dev/null +++ b/templates/common/on-prem/files/0020-kube-vip-ingress.yaml @@ -0,0 +1,74 @@ +mode: 0644 +path: {{ if isBGPVIPManagement . }}"/etc/kubernetes/manifests/0020-kube-vip-ingress.yaml"{{ else }}"/etc/kubernetes/disabled-manifests/0020-kube-vip-ingress.yaml"{{ end }} +contents: + inline: | + --- + kind: Pod + apiVersion: v1 + metadata: + name: kube-vip-ingress + namespace: openshift-kube-vip + labels: + app: kube-vip + component: ingress + spec: + hostNetwork: true + priorityClassName: system-node-critical + tolerations: + - operator: Exists + containers: + - name: kube-vip + image: {{.Images.kubeVipImage}} + args: + - manager + env: + - name: address + value: "{{ onPremPlatformIngressIP . }}" + - name: k8s_config_file + value: "/etc/kubernetes/kubeconfig" + - name: kubernetes_addr + value: "https://localhost:6443" + - name: port + value: "443" + - name: cp_enable + value: "true" + - name: vip_leaderelection + value: "true" + - name: vip_routingtable + value: "true" + - name: vip_cleanroutingtable + value: "true" + - name: vip_routingtableid + value: "198" + - name: vip_routingtableprotocol + value: "248" + - name: backend_health_check_interval + value: "5" + - name: control_plane_health_check_address + value: "http://localhost:1936/healthz" + - name: control_plane_health_check_timeout_seconds + value: "3" + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + add: + - NET_ADMIN + - NET_RAW + volumeMounts: + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + volumes: + - name: kubeconfig + hostPath: + path: /etc/kubernetes diff --git a/templates/common/on-prem/files/keepalived.yaml b/templates/common/on-prem/files/keepalived.yaml index 0605b2eb30..94981e1d82 100644 --- a/templates/common/on-prem/files/keepalived.yaml +++ b/templates/common/on-prem/files/keepalived.yaml @@ -1,5 +1,5 @@ mode: 0644 -path: {{ if isOpenShiftManagedDefaultLB . }} "/etc/kubernetes/manifests/keepalived.yaml" {{ else }} "/etc/kubernetes/disabled-manifests/keepalived.yaml" {{ end }} +path: {{ if and (isOpenShiftManagedDefaultLB .) (not (isBGPVIPManagement .)) }} "/etc/kubernetes/manifests/keepalived.yaml" {{ else }} "/etc/kubernetes/disabled-manifests/keepalived.yaml" {{ end }} contents: inline: | kind: Pod diff --git a/templates/master/00-master/on-prem/files/0000-frr-k8s.yaml b/templates/master/00-master/on-prem/files/0000-frr-k8s.yaml new file mode 100644 index 0000000000..1204af78b6 --- /dev/null +++ b/templates/master/00-master/on-prem/files/0000-frr-k8s.yaml @@ -0,0 +1,340 @@ +mode: 0644 +path: {{ if isBGPVIPManagement . }}"/etc/kubernetes/manifests/0000-frr-k8s.yaml"{{ else }}"/etc/kubernetes/disabled-manifests/0000-frr-k8s.yaml"{{ end }} +contents: + inline: | + --- + kind: Pod + apiVersion: v1 + metadata: + name: frr-k8s + namespace: openshift-frr-k8s + labels: + app: frr-k8s + spec: + # hostNetwork: the BGP session must originate from the node IP and the + # advertised VIP routes live in the host routing table (keepalived parity). + hostNetwork: true + shareProcessNamespace: true + priorityClassName: system-node-critical + # 10s (not the upstream DaemonSet's 0): a SIGTERM'd bgpd sends a Cease + # NOTIFICATION, which hard-resets the session; after a SIGKILL a peer + # in graceful-restart helper mode may retain stale VIP routes on bare + # TCP loss until the restart timer expires. + terminationGracePeriodSeconds: 10 + tolerations: + - operator: Exists + initContainers: + - name: render-config-frr + image: {{.Images.baremetalRuntimeCfgImage}} + command: + - /usr/bin/runtimecfg + - render + - /etc/kubernetes/kubeconfig + - --api-vips + - {{ onPremPlatformAPIServerInternalIP . }} + - --ingress-vips + - {{ onPremPlatformIngressIP . }} + - /config/frr.conf.tmpl + - --out-dir + - /etc/frr + - --peer-file + - /config/frr-peers.json + env: + - name: IS_BOOTSTRAP + value: "no" + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 100m + memory: 128Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: resource-dir + mountPath: /config + readOnly: true + - name: frr-conf + mountPath: /etc/frr + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + - name: cp-frr-files + image: {{.Images.frrK8sImage}} + command: + - /bin/sh + - -c + - | + set -eu + cp -f /tmp/frr/daemons /etc/frr/daemons + cp -f /tmp/frr/vtysh.conf /etc/frr/vtysh.conf + securityContext: + runAsUser: 100 + runAsGroup: 101 + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: 10m + memory: 20Mi + limits: + cpu: 100m + memory: 128Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: frr-startup + mountPath: /tmp/frr + readOnly: true + - name: frr-conf + mountPath: /etc/frr + - name: cp-reloader + image: {{.Images.frrK8sImage}} + command: + - /bin/sh + - -c + - cp -f /frr-reloader.sh /etc/frr_reloader/ + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: 10m + memory: 20Mi + limits: + cpu: 100m + memory: 128Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: reloader + mountPath: /etc/frr_reloader + - name: cp-frr-status + image: {{.Images.frrK8sImage}} + command: + - /bin/sh + - -c + - cp -f /frr-status /etc/frr_status/ + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: 10m + memory: 20Mi + limits: + cpu: 100m + memory: 128Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: frr-status + mountPath: /etc/frr_status + containers: + - name: controller + image: {{.Images.frrK8sImage}} + command: + - /frr-k8s + args: + - --node-name=$(NODE_NAME) + - --namespace=openshift-frr-k8s + env: + - name: FRR_CONFIG_FILE + value: /etc/frr_reloader/frr.conf + - name: FRR_RELOADER_PID_FILE + value: /etc/frr_reloader/reloader.pid + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: KUBECONFIG + value: /etc/kubernetes/kubeconfig + resources: + requests: + cpu: 100m + memory: 200Mi + limits: + cpu: 500m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + add: + - NET_RAW + livenessProbe: + httpGet: + path: /healthz + port: 7572 + host: 127.0.0.1 + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /readyz + port: 7572 + host: 127.0.0.1 + initialDelaySeconds: 10 + periodSeconds: 10 + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: reloader + mountPath: /etc/frr_reloader + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + - name: frr + image: {{.Images.frrK8sImage}} + command: + - /bin/sh + - -c + - /sbin/tini -- /usr/lib/frr/docker-start + env: + - name: TINI_SUBREAPER + value: "true" + resources: + requests: + cpu: 100m + memory: 200Mi + limits: + cpu: 500m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + # Mirrors the frr container of the frr-k8s DaemonSet shipped by + # CNO (upstream metallb/frr-k8s parity). No drop ALL: FRR's + # privilege-separated startup (watchfrr as root spawning daemons + # as the frr user) additionally relies on root's implicit + # capabilities (SETUID/SETGID/DAC_OVERRIDE/CHOWN); dropping ALL + # and re-adding only the network capabilities was tested and + # prevents the FRR daemons from starting. SYS_ADMIN is required + # by docker-start/watchfrr process supervision. + add: + - NET_ADMIN + - NET_RAW + - SYS_ADMIN + - NET_BIND_SERVICE + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: frr-sockets + mountPath: /var/run/frr + - name: frr-conf + mountPath: /etc/frr + - name: frr-lib + mountPath: /var/lib/frr + - name: frr-tmp + mountPath: /var/tmp/frr + - name: reloader + image: {{.Images.frrK8sImage}} + command: + - /etc/frr_reloader/frr-reloader.sh + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + # vtysh as root against the frr-user-owned vty sockets. + add: + - DAC_OVERRIDE + resources: + requests: + cpu: 10m + memory: 20Mi + limits: + cpu: 500m + memory: 128Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: frr-sockets + mountPath: /var/run/frr + - name: frr-conf + mountPath: /etc/frr + - name: reloader + mountPath: /etc/frr_reloader + - name: frr-status + image: {{.Images.frrK8sImage}} + command: + - /etc/frr_status/frr-status + args: + - --node-name=$(NODE_NAME) + - --namespace=openshift-frr-k8s + - --pod-name=frr-k8s-$(NODE_NAME) + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: KUBECONFIG + value: /etc/kubernetes/kubeconfig + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + # vtysh as root against the frr-user-owned vty sockets. + add: + - DAC_OVERRIDE + resources: + requests: + cpu: 10m + memory: 20Mi + limits: + cpu: 500m + memory: 128Mi + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: frr-sockets + mountPath: /var/run/frr + - name: frr-conf + mountPath: /etc/frr + - name: frr-status + mountPath: /etc/frr_status + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + volumes: + - name: resource-dir + hostPath: + path: /etc/kubernetes/static-pod-resources/frr-k8s + # hostPath (not emptyDir) so the CNO-managed metrics companion + # DaemonSet can reach the FRR sockets; perms via tmpfiles.d. + - name: frr-conf + hostPath: + path: /run/frr-k8s/conf + type: DirectoryOrCreate + - name: frr-sockets + hostPath: + path: /run/frr-k8s/sockets + type: DirectoryOrCreate + - name: reloader + emptyDir: {} + - name: frr-status + emptyDir: {} + - name: frr-lib + emptyDir: {} + - name: frr-tmp + emptyDir: {} + - name: frr-startup + hostPath: + path: /etc/kubernetes/static-pod-resources/frr-k8s/startup + - name: kubeconfig + hostPath: + path: /etc/kubernetes diff --git a/templates/master/00-master/on-prem/files/0010-kube-vip-api.yaml b/templates/master/00-master/on-prem/files/0010-kube-vip-api.yaml new file mode 100644 index 0000000000..a1bbf9454a --- /dev/null +++ b/templates/master/00-master/on-prem/files/0010-kube-vip-api.yaml @@ -0,0 +1,70 @@ +mode: 0644 +path: {{ if isBGPVIPManagement . }}"/etc/kubernetes/manifests/0010-kube-vip-api.yaml"{{ else }}"/etc/kubernetes/disabled-manifests/0010-kube-vip-api.yaml"{{ end }} +contents: + inline: | + --- + kind: Pod + apiVersion: v1 + metadata: + name: kube-vip-api + namespace: openshift-kube-vip + labels: + app: kube-vip + component: api + spec: + hostNetwork: true + priorityClassName: system-node-critical + tolerations: + - operator: Exists + containers: + - name: kube-vip + image: {{.Images.kubeVipImage}} + args: + - manager + env: + - name: address + value: "{{ onPremPlatformAPIServerInternalIP . }}" + - name: k8s_config_file + value: "/etc/kubernetes/kubeconfig" + - name: kubernetes_addr + value: "https://localhost:6443" + - name: port + value: "6443" + - name: cp_enable + value: "true" + - name: vip_leaderelection + value: "true" + - name: vip_routingtable + value: "true" + - name: vip_cleanroutingtable + value: "true" + - name: vip_routingtableid + value: "198" + - name: vip_routingtableprotocol + value: "248" + - name: backend_health_check_interval + value: "5" + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + add: + - NET_ADMIN + - NET_RAW + volumeMounts: + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + volumes: + - name: kubeconfig + hostPath: + path: /etc/kubernetes diff --git a/templates/master/00-master/on-prem/files/frr-k8s-conf.yaml b/templates/master/00-master/on-prem/files/frr-k8s-conf.yaml new file mode 100644 index 0000000000..e6181426dd --- /dev/null +++ b/templates/master/00-master/on-prem/files/frr-k8s-conf.yaml @@ -0,0 +1,62 @@ +mode: 0644 +path: "/etc/kubernetes/static-pod-resources/frr-k8s/frr.conf.tmpl" +contents: + inline: | + frr version 9.1 + frr defaults traditional + hostname {{`{{.Hostname}}`}} + ! + router bgp {{`{{.LocalASN}}`}} + bgp router-id {{`{{.RouterID}}`}} + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + ! + {{`{{- range .Peers}}`}} + neighbor {{`{{.PeerAddress}}`}} remote-as {{`{{.PeerASN}}`}} + {{`{{- if .Password}}`}} + neighbor {{`{{.PeerAddress}}`}} password {{`{{.Password}}`}} + {{`{{- end}}`}} + {{`{{- if eq .BFDEnabled "true"}}`}} + neighbor {{`{{.PeerAddress}}`}} bfd + {{`{{- end}}`}} + {{`{{- if eq .EBGPMultiHop "true"}}`}} + neighbor {{`{{.PeerAddress}}`}} ebgp-multihop + {{`{{- end}}`}} + {{`{{- if .HoldTime}}`}} + neighbor {{`{{.PeerAddress}}`}} timers {{`{{.KeepaliveTime}}`}} {{`{{.HoldTime}}`}} + {{`{{- end}}`}} + {{`{{- end}}`}} + ! + address-family ipv4 unicast + redistribute table-direct 198 + {{`{{- range .Peers}}`}} + {{`{{- if isIPv4 .PeerAddress}}`}} + neighbor {{`{{.PeerAddress}}`}} activate + {{`{{- if $.Communities}}`}} + neighbor {{`{{.PeerAddress}}`}} route-map VIP-COMMUNITY out + {{`{{- end}}`}} + {{`{{- end}}`}} + {{`{{- end}}`}} + exit-address-family + ! + address-family ipv6 unicast + redistribute table-direct 198 + {{`{{- range .Peers}}`}} + {{`{{- if isIPv6 .PeerAddress}}`}} + neighbor {{`{{.PeerAddress}}`}} activate + {{`{{- if $.Communities}}`}} + neighbor {{`{{.PeerAddress}}`}} route-map VIP-COMMUNITY out + {{`{{- end}}`}} + {{`{{- end}}`}} + {{`{{- end}}`}} + exit-address-family + ! + {{`{{- if .Communities}}`}} + route-map VIP-COMMUNITY permit 10 + {{`{{- range .Communities}}`}} + set community {{`{{.}}`}} additive + {{`{{- end}}`}} + ! + {{`{{- end}}`}} + line vty + ! diff --git a/templates/master/00-master/on-prem/files/frr-k8s-peers.yaml b/templates/master/00-master/on-prem/files/frr-k8s-peers.yaml new file mode 100644 index 0000000000..e4284d9f57 --- /dev/null +++ b/templates/master/00-master/on-prem/files/frr-k8s-peers.yaml @@ -0,0 +1,5 @@ +mode: 0600 +path: "/etc/kubernetes/static-pod-resources/frr-k8s/frr-peers.json" +contents: + inline: |- + {{.BGPVIPPeersJSON}} diff --git a/templates/master/00-master/on-prem/files/frr-k8s-startup-daemons.yaml b/templates/master/00-master/on-prem/files/frr-k8s-startup-daemons.yaml new file mode 100644 index 0000000000..633516007d --- /dev/null +++ b/templates/master/00-master/on-prem/files/frr-k8s-startup-daemons.yaml @@ -0,0 +1,27 @@ +mode: 0644 +path: "/etc/kubernetes/static-pod-resources/frr-k8s/startup/daemons" +contents: + inline: | + zebra=yes + bgpd=yes + ospfd=no + ospf6d=no + ripd=no + ripngd=no + isisd=no + pimd=no + ldpd=no + nhrpd=no + eigrpd=no + babeld=no + sharpd=no + pbrd=no + bfdd=yes + fabricd=no + vrrpd=no + pathd=no + + vtysh_enable=yes + zebra_options=" -A 127.0.0.1 -s 90000000" + bgpd_options=" -A 127.0.0.1" + bfdd_options=" -A 127.0.0.1" diff --git a/templates/master/00-master/on-prem/files/frr-k8s-startup-vtysh.yaml b/templates/master/00-master/on-prem/files/frr-k8s-startup-vtysh.yaml new file mode 100644 index 0000000000..7cc769bd2b --- /dev/null +++ b/templates/master/00-master/on-prem/files/frr-k8s-startup-vtysh.yaml @@ -0,0 +1,5 @@ +mode: 0644 +path: "/etc/kubernetes/static-pod-resources/frr-k8s/startup/vtysh.conf" +contents: + inline: | + service integrated-vtysh-config diff --git a/templates/master/00-master/on-prem/units/frr-k8s-hostpath.service.yaml b/templates/master/00-master/on-prem/units/frr-k8s-hostpath.service.yaml new file mode 100644 index 0000000000..3ee97217ae --- /dev/null +++ b/templates/master/00-master/on-prem/units/frr-k8s-hostpath.service.yaml @@ -0,0 +1,21 @@ +name: frr-k8s-hostpath.service +enabled: {{if isBGPVIPManagement .}}true{{else}}false{{end}} +contents: | + [Unit] + Description=Prepare the frr-k8s static pod hostPath directories + # /run/frr-k8s is shared between the frr-k8s static pod and the + # CNO-managed metrics companion DaemonSet. 0777 mirrors emptyDir + # semantics: FRR daemons run as uid 100 while watchfrr runs as root + # without CAP_DAC_OVERRIDE. container_file_t because the companion runs + # as plain container_t (MCS-confined): the static pod itself is spc_t + # (host network) and unconstrained, but its files inherit the directory + # type and must stay accessible to the companion. + Before=kubelet-dependencies.target + + [Service] + Type=oneshot + RemainAfterExit=yes + ExecStart=/bin/bash -c 'mkdir -p /run/frr-k8s/sockets /run/frr-k8s/conf && chmod 0777 /run/frr-k8s/sockets /run/frr-k8s/conf && chcon -R -t container_file_t /run/frr-k8s' + + [Install] + WantedBy=kubelet-dependencies.target diff --git a/vendor/github.com/openshift/api/.golangci.yaml b/vendor/github.com/openshift/api/.golangci.yaml index 53c9b4009e..e4e5b97612 100644 --- a/vendor/github.com/openshift/api/.golangci.yaml +++ b/vendor/github.com/openshift/api/.golangci.yaml @@ -106,6 +106,10 @@ linters: # This regex must always be updated in tandem with the regex in .golangci.go-validated.yaml that prevents `optionalfields` from being applied to the files in the path. path: machine/v1beta1/(types_awsprovider.go|types_azureprovider.go|types_gcpprovider.go|types_vsphereprovider.go)|machine/v1alpha1/types_openstack.go text: "optionalfields" + - linters: + - kubeapilinter + # osin/v1 types are config file APIs, not CRDs — validation is handled in Go code at config load time. + path: osin/v1/types.go - linters: - kubeapilinter # Silence norefs lint for `Ref` field in ClusterAPI as it refers to an OCI image reference, not a kube object reference. diff --git a/vendor/github.com/openshift/api/Makefile b/vendor/github.com/openshift/api/Makefile index 8b85144eaf..b6c0de378c 100644 --- a/vendor/github.com/openshift/api/Makefile +++ b/vendor/github.com/openshift/api/Makefile @@ -4,7 +4,7 @@ all: build update: update-non-codegen update-codegen RUNTIME ?= podman -RUNTIME_IMAGE_NAME ?= registry.ci.openshift.org/openshift/release:rhel-9-release-golang-1.25-openshift-4.22 +RUNTIME_IMAGE_NAME ?= registry.ci.openshift.org/openshift/release:rhel-9-release-golang-1.26-openshift-5.0 EXCLUDE_DIRS := _output/ dependencymagnet/ hack/ third_party/ tls/ tools/ vendor/ tests/ GO_PACKAGES :=$(addsuffix ...,$(addprefix ./,$(filter-out $(EXCLUDE_DIRS), $(wildcard */)))) @@ -220,7 +220,7 @@ write-available-featuresets: .PHONY: clean clean: - rm -f render write-available-featuresets models-schema + rm -f render write-available-featuresets rm -rf tools/_output VERSION ?= $(shell git describe --always --abbrev=7) diff --git a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go index e8aaa810f5..9e11ecddcc 100644 --- a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go +++ b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go @@ -210,6 +210,21 @@ const ( DNSRecordsTypeInternal DNSRecordsType = "Internal" ) +// VIPManagementType defines which mechanism manages the API and Ingress +// VIPs on an on-premise cluster. +// +kubebuilder:validation:Enum=Keepalived;BGP +// +enum +type VIPManagementType string + +const ( + // VIPManagementTypeKeepalived means the VIPs are managed by the default + // keepalived/VRRP mechanism. + VIPManagementTypeKeepalived VIPManagementType = "Keepalived" + // VIPManagementTypeBGP means the VIPs are advertised via BGP by kube-vip + // (Routing Table Mode) and frr-k8s running as static pods. + VIPManagementTypeBGP VIPManagementType = "BGP" +) + // PlatformType is a specific supported infrastructure provider. // +kubebuilder:validation:Enum="";AWS;Azure;BareMetal;GCP;Libvirt;OpenStack;None;VSphere;oVirt;IBMCloud;KubeVirt;EquinixMetal;PowerVS;AlibabaCloud;Nutanix;External type PlatformType string @@ -660,7 +675,6 @@ type AzurePlatformStatus struct { // // +default={"dnsType": "PlatformDefault"} // +kubebuilder:default={"dnsType": "PlatformDefault"} - // +openshift:enable:FeatureGate=AzureClusterHostedDNSInstall // +optional CloudLoadBalancerConfig *CloudLoadBalancerConfig `json:"cloudLoadBalancerConfig,omitempty"` @@ -1075,6 +1089,20 @@ type BareMetalPlatformStatus struct { // +optional LoadBalancer *BareMetalPlatformLoadBalancer `json:"loadBalancer,omitempty"` + // vipManagement indicates which VIP management mechanism is active + // on this cluster. + // Allowed values are `Keepalived`, `BGP`, and omitted. + // When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + // deployed as static pods to advertise VIPs via BGP, replacing the + // default keepalived/VRRP mechanism. + // When set to `Keepalived`, the default keepalived-based VIP + // management is used. + // When omitted, the default keepalived-based VIP management is used. + // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="vipManagement is immutable once set" + // +openshift:enable:FeatureGate=BGPBasedVIPManagement + // +optional + VIPManagement VIPManagementType `json:"vipManagement,omitempty"` + // 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. diff --git a/vendor/github.com/openshift/api/config/v1/types_ingress.go b/vendor/github.com/openshift/api/config/v1/types_ingress.go index 26e0ebf218..bb461e2f3e 100644 --- a/vendor/github.com/openshift/api/config/v1/types_ingress.go +++ b/vendor/github.com/openshift/api/config/v1/types_ingress.go @@ -64,10 +64,12 @@ type IngressSpec struct { // To determine the set of configurable Routes, look at namespace and name of entries in the // .status.componentRoutes list, where participating operators write the status of // configurable routes. + // A maximum of 250 component routes may be configured. // +optional // +listType=map // +listMapKey=namespace // +listMapKey=name + // +kubebuilder:validation:MaxItems=250 ComponentRoutes []ComponentRouteSpec `json:"componentRoutes,omitempty"` // requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes @@ -164,6 +166,14 @@ const ( Classic AWSLBType = "Classic" ) +// LabelValue is the value part of a Kubernetes label. +// A label value must be either empty or 1-63 characters, consisting of +// alphanumeric characters, '-', '_', or '.', starting and ending with +// an alphanumeric character. +// +kubebuilder:validation:MaxLength=63 +// +kubebuilder:validation:XValidation:rule="!format.labelValue().validate(self).hasValue()",message="label values must be valid Kubernetes label values (at most 63 characters, alphanumeric, '-', '_', or '.', must start and end with alphanumeric)" +type LabelValue string + // ConsumingUser is an alias for string which we add validation to. Currently only service accounts are supported. // +kubebuilder:validation:Pattern="^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" // +kubebuilder:validation:MinLength=1 @@ -245,6 +255,32 @@ type ComponentRouteSpec struct { // the Secret specification for a serving certificate will not be needed. // +optional ServingCertKeyPairSecret SecretNameReference `json:"servingCertKeyPairSecret"` + + // labels defines additional labels to be applied to the route created + // for the component. These labels are used by the IngressController to + // determine which routes it should manage. Changing labels may cause the + // route to be reassigned to a different IngressController. + // When omitted, no additional labels are applied to the component route. + // When specified, labels must contain at least one entry, up to a maximum of 8. + // Label keys must be valid qualified names, consisting of a name segment and + // an optional prefix separated by a slash (/). The name segment must be at most + // 63 characters in length and must consist only of alphanumeric characters, + // dashes (-), underscores (_), and dots (.), and must start and end with + // alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + // at most 253 characters in length, consisting of dot-separated segments where + // each segment starts and ends with an alphanumeric character. + // Label values must be either empty or 1-63 characters, consisting of + // alphanumeric characters, dashes (-), underscores (_), or dots (.), + // starting and ending with an alphanumeric character. + // Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + // +openshift:enable:FeatureGate=IngressComponentRouteLabels + // +optional + // +mapType=granular + // +kubebuilder:validation:MinProperties=1 + // +kubebuilder:validation:MaxProperties=8 + // +kubebuilder:validation:XValidation:rule="self.all(key, !format.qualifiedName().validate(key).hasValue())",message="label keys must be valid qualified names, consisting of an optional DNS subdomain prefix of up to 253 characters followed by a slash and a name segment of 1-63 characters, that consists only of alphanumeric characters, dashes, underscores, and dots, and must start and end with an alphanumeric character" + // +kubebuilder:validation:XValidation:rule="self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/') && !key.startsWith('openshift.io/'))",message="kubernetes.io/, k8s.io/, and openshift.io/ prefixed label keys are reserved and may not be used" + Labels map[string]LabelValue `json:"labels,omitempty"` } // ComponentRouteStatus contains information allowing configuration of a route's hostname and serving certificate. diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml index de0dd293a8..d883307d84 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml @@ -446,6 +446,434 @@ spec: ? has(self.requiredClaim) : !has(self.requiredClaim)' type: array x-kubernetes-list-type: atomic + externalClaimsSources: + description: |- + externalClaimsSources is an optional field that can be used to configure + sources, external to the token provided in a request, in which claims + should be fetched from and made available to the claim mapping process + that is used to build the identity of a token holder. + + For example, fetching additional user metadata from an OIDC provider's UserInfo endpoint. + + When not specified, only claims present in the token itself will be available + in the claim mapping process. + + When specified, at least one external claim source must be specified and no more than 5 + sources may be specified. + All external claim sources must have unique claim mappings. + When an external source responds and resolves additional claims successfully, they will + be made available as claims during the claim mapping process. + Externally sourced claims with the same name as a claim existing within the token will + overwrite the claim data from the token with the externally sourced information. + If an external source does not respond, responds with an error, or the additional + claim data cannot be resolved from the response successfully it will not be + included in the claim data passed to the claim mapping process. + items: + description: ExternalClaimsSource provides the configuration + for a single external claim source. + properties: + authentication: + description: |- + authentication is an optional field that configures how the apiserver authenticates with an external claims source. + When not specified, anonymous authentication is used which means no 'Authorization' header + is sent in the HTTP request to fetch the external claims. + properties: + clientCredential: + description: |- + clientCredential configures the client credentials + and token endpoint to use to get an access token. + clientCredential is required when type is 'ClientCredential', and forbidden otherwise. + properties: + clientID: + description: |- + clientID is a required client identifier to use during the OAuth2 client credentials flow. + clientID must be at least 1 character in length, must not exceed 256 characters in length, + and must only contain printable ASCII characters. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: clientID must only contain printable + ASCII characters + rule: self.matches('^[[:print:]]+$') + clientSecret: + description: |- + clientSecret is a required reference to a Secret in the openshift-config namespace to be used + as the client secret during the OAuth2 client credentials flow. + + The key 'client-secret' is used to locate the client secret data in the Secret. + properties: + name: + description: |- + name is the required name of the Secret that exists in the openshift-config namespace. + + It must be at least 1 character in length, must not exceed 253 characters in length, + must start and end with a lowercase alphanumeric character, and must only contain + lowercase alphanumeric characters, '-' or '.'. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: name must start and end with a + lowercase alphanumeric character, and + must only contain lowercase alphanumeric + characters, '-' or '.' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + scopes: + description: |- + scopes is an optional list of OAuth2 scopes to request when obtaining + an access token. + + If not specified, the token endpoint's default scopes + will be used. + + When specified, there must be at least 1 entry and must not exceed 16 entries. + Each entry must be at least 1 character in length and must not exceed 256 characters in length. + Each entry must only contain printable ASCII characters, excluding spaces, double quotes and backslashes. + Entries must be unique. + items: + description: |- + OAuth2Scope is a string alias that represents an OAuth2 Scope as defined by https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.4 + Must be at least 1 character in length, must not exceed 256 characters in length and must only contain printable ASCII characters, excluding spaces, double quotes and backslashes. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: scopes must only contain printable + ASCII characters excluding spaces, double + quotes and backslashes + rule: self.matches('^[!#-[\\]-~]+$') + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-type: set + tls: + description: |- + tls is an optional field that allows configuring the TLS + settings used to interact with the identity provider + as an OAuth2 client. + + When omitted, system default TLS settings will be used + for the OAuth2 client. + properties: + certificateAuthority: + description: |- + certificateAuthority is a required reference to a ConfigMap in the openshift-config + namespace that contains the CA certificate to use to validate TLS connections with the external claims source. + The key "ca-bundle.crt" must be present in the referenced ConfigMap and must contain the CA certificate to be used + to verify the external source's TLS certificate. + properties: + name: + description: |- + name is the required name of the ConfigMap that exists in the openshift-config namespace. + The key "ca-bundle.crt" must be present and must contain the CA certificate to be used + to verify the external source's TLS certificate. + + It must be at least 1 character in length, must not exceed 253 characters in length, + must start and end with a lowercase alphanumeric character, and must only contain + lowercase alphanumeric characters, '-' or '.'. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: name must start and end with + a lowercase alphanumeric character, + and must only contain lowercase alphanumeric + characters, '-' or '.' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - certificateAuthority + type: object + tokenEndpoint: + description: |- + tokenEndpoint is a required URL to query for an access token using + the client credential OAuth2 flow. + tokenEndpoint must be at least 1 character in length and must not exceed 2048 characters in length. + tokenEndpoint must be a valid HTTPS URL. + tokenEndpoint must have a host and a path. + tokenEndpoint must not contain query parameters, fragments, + or user information (e.g., "user:password@host"). + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: tokenEndpoint must be a valid HTTPS + url + rule: isURL(self) + - message: tokenEndpoint must be a valid HTTPS + url + rule: isURL(self) && url(self).getScheme() == + 'https' + - message: tokenEndpoint must have a hostname + rule: isURL(self) && url(self).getHost() != + '' + - message: tokenEndpoint must have a path + rule: isURL(self) && url(self).getEscapedPath() + != '' + - message: tokenEndpoint must not have query parameters + rule: isURL(self) && url(self).getQuery() == + {} + - message: tokenEndpoint must not have a fragment + rule: isURL(self) && self.find('#(.+)$') == + '' + - message: tokenEndpoint must not have user info + rule: isURL(self) && !self.matches('^https://[^/]+@.+$') + required: + - clientID + - clientSecret + - tokenEndpoint + type: object + type: + description: |- + type is a required field that sets the type of + authentication method used by the authenticator + when fetching external claims. + + Allowed values are 'RequestProvidedToken' and 'ClientCredential'. + + When set to 'RequestProvidedToken', the authenticator will + use the token provided to the kube-apiserver as part of the + request to authenticate with the external claims source. + + When set to 'ClientCredential', the authenticator will + use the configured client-id, client-secret, and token endpoint + to fetch an access token using the OAuth2 client credentials grant + flow. The fetched access token will then be used to authenticate + with the external claims source. + enum: + - RequestProvidedToken + - ClientCredential + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: clientCredential is required when type is ClientCredential, + and forbidden otherwise + rule: 'self.type == ''ClientCredential'' ? has(self.clientCredential) + : !has(self.clientCredential)' + mappings: + description: |- + mappings is a required list of the claim + and response handling expression pairs + that produces the claims from the external source. + mappings must have at least 1 entry and must not exceed 16 entries. + Entries must have a unique name across all external claim sources. + items: + description: |- + SourcedClaimMapping configures the mapping behavior for a single external claim + from the response the apiserver received from the external claim source. + properties: + expression: + description: |- + expression is a required CEL expression that + will produce a value to be assigned to the claim. + The full response body from the request to the + external claim source is provided via the + `response.body` variable. + + The contents of the `response.body` variable varies based on the response received + from the external source. It is the responsibility of those configuring + this expression to understand what is returned from the external source. + + expression must be at least 1 character and must not exceed 1024 characters in length. + maxLength: 1024 + minLength: 1 + type: string + name: + description: |- + name is a required name of the claim that + will be produced and made available during + the claim-to-identity mapping process. + name must consist of only lowercase alpha characters and underscores ('_'). + name must be at least 1 character and must not exceed 256 characters in length. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: name must consist of only lowercase alpha + characters and underscores + rule: self.matches('^[a-z_]+$') + required: + - expression + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + predicates: + description: |- + predicates is an optional list of constraints in + which claims should attempt to be fetched from this + external source. + + When omitted, claims are always fetched + from this external source. + + When specified, all predicates must evaluate to 'true' + before claims are attempted to be fetched from this external source. + predicates must have at least 1 entry and must not exceed 16 entries. + Entries must have unique expressions. + items: + description: |- + ExternalSourcePredicate configures a singular condition + that must return true before the external source is queried + to retrieve external claims. + properties: + expression: + description: |- + expression is a required CEL expression that + is used to determine whether or not an external + source should be used to fetch external claims. + + The expression must return a boolean value, + where true means that the source should be consulted + and false means that it should not. + + Claims from the token used for the request to the kube-apiserver + are made available via the `claims` variable. + + The contents of the `claims` variable varies based on the claims that are + present in the token being validated. It is the responsibility of those configuring this + field to understand what claims the identity provider includes when issuing tokens. + + expression must be at least 1 character and must not exceed 1024 characters in length. + maxLength: 1024 + minLength: 1 + type: string + required: + - expression + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - expression + x-kubernetes-list-type: map + tls: + description: |- + tls is an optional field that configures the http client TLS + settings when fetching external claims from this source. + + When omitted, system default TLS settings will be used + for fetching claims from the external source. + properties: + certificateAuthority: + description: |- + certificateAuthority is a required reference to a ConfigMap in the openshift-config + namespace that contains the CA certificate to use to validate TLS connections with the external claims source. + The key "ca-bundle.crt" must be present in the referenced ConfigMap and must contain the CA certificate to be used + to verify the external source's TLS certificate. + properties: + name: + description: |- + name is the required name of the ConfigMap that exists in the openshift-config namespace. + The key "ca-bundle.crt" must be present and must contain the CA certificate to be used + to verify the external source's TLS certificate. + + It must be at least 1 character in length, must not exceed 253 characters in length, + must start and end with a lowercase alphanumeric character, and must only contain + lowercase alphanumeric characters, '-' or '.'. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: name must start and end with a lowercase + alphanumeric character, and must only contain + lowercase alphanumeric characters, '-' or + '.' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - certificateAuthority + type: object + url: + description: |- + url is a required configuration of the URL + for which the external claims are located. + properties: + hostname: + description: |- + hostname is a required hostname for which the external claims are located. + + It must be a valid DNS subdomain name as per RFC1123. + + This means that it must start and end with a lowercase alphanumeric character, + must only consist of lowercase alphanumeric characters, '-', and '.'. + hostname may optionally specify a port in the format ':{port}'. + If a port is specified it must not exceed 65535. + + hostname must be at least 1 character in length. + When specifying a port, hostname must not exceed 259 characters in length. + When not specifying a port, hostname must not exceed 253 characters in length. + maxLength: 259 + minLength: 1 + type: string + x-kubernetes-validations: + - message: hostname must be a valid hostname + rule: isURL('https://'+self) + - message: hostname before port must start and end + with a lowercase alphanumeric character, and must + only contain lowercase alphanumeric characters, + '-' or '.' + rule: '!format.dns1123Subdomain().validate(self.split('':'')[0]).hasValue()' + - message: port must not exceed 65535 + rule: 'self.split('':'').size() > 1 ? int(self.split('':'')[1]) + <= 65535 : true' + pathExpression: + description: |- + pathExpression is a required CEL expression that returns a list + of string values used to construct the URL path. + Claims from the token used for the request to the kube-apiserver + are made available via the `claims` variable. + expression must be at least 1 character in length and must not exceed 1024 characters in length. + + Values in the returned list will be joined with the hostname using a forward slash + (`/`) as a separator. Values in the returned list do not need to include the forward slash. + If a forward slash is included in a returned value, it will be encoded as `%2F`. + + Example of a static path configuration: + + pathExpression: ['realms', 'k8s', 'protocol', 'openid-connect', 'userinfo'] + + The above example would resolve to the path: '/realms/k8s/protocol/openid-connect/userinfo' + + Example of a dynamic path configuration: + + pathExpression: "['admin', 'realms', 'k8s', 'users'] + [claims.sub] + ['groups']" + + Assuming 'claims.sub' is set to '12345', the above example would resolve to the path: '/admin/realms/k8s/users/12345/groups' + maxLength: 1024 + minLength: 1 + type: string + required: + - hostname + - pathExpression + type: object + required: + - mappings + - url + type: object + maxItems: 5 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: mapping names must be unique across all external + claim sources. + rule: self.all(s, s.mappings.all(m, self.filter(s2, s2.mappings.exists(m2, + m2.name == m.name)).size() == 1)) issuer: description: issuer is a required field that configures how the platform interacts with the identity provider and how diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_criocredentialproviderconfigs.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_criocredentialproviderconfigs.crd.yaml index 9aa182639b..7a720440ac 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_criocredentialproviderconfigs.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_criocredentialproviderconfigs.crd.yaml @@ -209,7 +209,7 @@ spec: be 'cluster' rule: self.metadata.name == 'cluster' served: true - storage: true + storage: false subresources: status: {} - name: v1alpha1 @@ -404,6 +404,6 @@ spec: be 'cluster' rule: self.metadata.name == 'cluster' served: true - storage: false + storage: true subresources: status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index 2829b41dce..d5372d9616 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1785,6 +1785,24 @@ spec: datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string + vipManagement: + description: |- + vipManagement indicates which VIP management mechanism is active + on this cluster. + Allowed values are `Keepalived`, `BGP`, and omitted. + When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + deployed as static pods to advertise VIPs via BGP, replacing the + default keepalived/VRRP mechanism. + When set to `Keepalived`, the default keepalived-based VIP + management is used. + When omitted, the default keepalived-based VIP management is used. + enum: + - Keepalived + - BGP + type: string + x-kubernetes-validations: + - message: vipManagement is immutable once set + rule: oldSelf == '' || self == oldSelf type: object x-kubernetes-validations: - message: dnsRecordsType may only be set to External when loadBalancer.type diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-DevPreviewNoUpgrade.crd.yaml index a3064161f2..4ccf8c6858 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-DevPreviewNoUpgrade.crd.yaml @@ -1770,6 +1770,24 @@ spec: datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string + vipManagement: + description: |- + vipManagement indicates which VIP management mechanism is active + on this cluster. + Allowed values are `Keepalived`, `BGP`, and omitted. + When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + deployed as static pods to advertise VIPs via BGP, replacing the + default keepalived/VRRP mechanism. + When set to `Keepalived`, the default keepalived-based VIP + management is used. + When omitted, the default keepalived-based VIP management is used. + enum: + - Keepalived + - BGP + type: string + x-kubernetes-validations: + - message: vipManagement is immutable once set + rule: oldSelf == '' || self == oldSelf type: object x-kubernetes-validations: - message: dnsRecordsType may only be set to External when loadBalancer.type diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-TechPreviewNoUpgrade.crd.yaml deleted file mode 100644 index cafc698a8a..0000000000 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-TechPreviewNoUpgrade.crd.yaml +++ /dev/null @@ -1,2774 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.openshift.io: https://github.com/openshift/api/pull/470 - api.openshift.io/merged-by-featuregates: "true" - include.release.openshift.io/ibm-cloud-managed: "true" - release.openshift.io/bootstrap-required: "true" - release.openshift.io/feature-set: TechPreviewNoUpgrade - name: infrastructures.config.openshift.io -spec: - group: config.openshift.io - names: - kind: Infrastructure - listKind: InfrastructureList - plural: infrastructures - singular: infrastructure - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - description: |- - Infrastructure holds cluster-wide information about Infrastructure. The canonical name is `cluster` - - 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 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", "IBMCloud", "KubeVirt", "EquinixMetal", - "PowerVS", "AlibabaCloud", "Nutanix", "External", 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: - anyOf: - - format: ipv4 - - format: ipv6 - - format: hostname - 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: - format: cidr - 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: - format: cidr - 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: - format: cidr - 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: - format: cidr - 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. - Up to 3 vCenters are supported. - Once the cluster has been installed, you are unable to change the current number of defined - vCenters except when 1.) the cluster has been upgraded from a version of OpenShift - where the vsphere platform spec was not present or 2.) in TechPreview you are able to add and - remove vCenters but may not remove all vCenters. 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: - anyOf: - - format: ipv4 - - format: ipv6 - - format: hostname - 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: 1 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: Cannot add and remove vCenters at the same time - rule: 'size(self) >= size(oldSelf) ? oldSelf.all(x, self.exists(y, - y.server == x.server)) : true' - - message: Cannot add and remove vCenters at the same time - rule: 'size(self) < size(oldSelf) ? self.all(x, oldSelf.exists(y, - y.server == x.server)) : true' - - message: vcenters must have unique server values - rule: self.all(x, self.exists_one(y, y.server == x.server)) - 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)' - type: object - x-kubernetes-validations: - - message: vcenters is required once set and cannot be removed - rule: 'oldSelf.?vsphere.vcenters.hasValue() ? self.?vsphere.vcenters.hasValue() - : 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. - The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes - that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum. - 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 - served: true - storage: true - subresources: - status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 310ba4ad38..1e547336c8 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1785,6 +1785,24 @@ spec: datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string + vipManagement: + description: |- + vipManagement indicates which VIP management mechanism is active + on this cluster. + Allowed values are `Keepalived`, `BGP`, and omitted. + When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + deployed as static pods to advertise VIPs via BGP, replacing the + default keepalived/VRRP mechanism. + When set to `Keepalived`, the default keepalived-based VIP + management is used. + When omitted, the default keepalived-based VIP management is used. + enum: + - Keepalived + - BGP + type: string + x-kubernetes-validations: + - message: vipManagement is immutable once set + rule: oldSelf == '' || self == oldSelf type: object x-kubernetes-validations: - message: dnsRecordsType may only be set to External when loadBalancer.type diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index f3b307973b..3c14ccd691 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1785,6 +1785,24 @@ spec: datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string + vipManagement: + description: |- + vipManagement indicates which VIP management mechanism is active + on this cluster. + Allowed values are `Keepalived`, `BGP`, and omitted. + When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + deployed as static pods to advertise VIPs via BGP, replacing the + default keepalived/VRRP mechanism. + When set to `Keepalived`, the default keepalived-based VIP + management is used. + When omitted, the default keepalived-based VIP management is used. + enum: + - Keepalived + - BGP + type: string + x-kubernetes-validations: + - message: vipManagement is immutable once set + rule: oldSelf == '' || self == oldSelf type: object x-kubernetes-validations: - message: dnsRecordsType may only be set to External when loadBalancer.type diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml similarity index 99% rename from vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml rename to vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml index 998b9be396..197bf2706f 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml @@ -4,6 +4,7 @@ metadata: annotations: api-approved.openshift.io: https://github.com/openshift/api/pull/470 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/bootstrap-required: "true" release.openshift.io/feature-set: TechPreviewNoUpgrade diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml new file mode 100644 index 0000000000..92f2913150 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml @@ -0,0 +1,593 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + 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/bootstrap-required: "true" + release.openshift.io/feature-set: CustomNoUpgrade + name: ingresses.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Ingress + listKind: IngressList + plural: ingresses + singular: ingress + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Ingress holds cluster-wide information about ingress, including the default ingress domain + used for routes. The canonical name is `cluster`. + + 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 holds user settable values for configuration + properties: + appsDomain: + description: |- + appsDomain is an optional domain to use instead of the one specified + in the domain field when a Route is created without specifying an explicit + host. If appsDomain is nonempty, this value is used to generate default + host values for Route. Unlike domain, appsDomain may be modified after + installation. + This assumes a new ingresscontroller has been setup with a wildcard + certificate. + type: string + componentRoutes: + description: |- + componentRoutes is an optional list of routes that are managed by OpenShift components + that a cluster-admin is able to configure the hostname and serving certificate for. + The namespace and name of each route in this list should match an existing entry in the + status.componentRoutes list. + + To determine the set of configurable Routes, look at namespace and name of entries in the + .status.componentRoutes list, where participating operators write the status of + configurable routes. + A maximum of 250 component routes may be configured. + items: + description: ComponentRouteSpec allows for configuration of a route's + hostname and serving certificate. + properties: + hostname: + description: hostname is the hostname that should be used by + the route. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + labels: + additionalProperties: + description: |- + LabelValue is the value part of a Kubernetes label. + A label value must be either empty or 1-63 characters, consisting of + alphanumeric characters, '-', '_', or '.', starting and ending with + an alphanumeric character. + maxLength: 63 + type: string + x-kubernetes-validations: + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: '!format.labelValue().validate(self).hasValue()' + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. Changing labels may cause the + route to be reassigned to a different IngressController. + When omitted, no additional labels are applied to the component route. + When specified, labels must contain at least one entry, up to a maximum of 8. + Label keys must be valid qualified names, consisting of a name segment and + an optional prefix separated by a slash (/). The name segment must be at most + 63 characters in length and must consist only of alphanumeric characters, + dashes (-), underscores (_), and dots (.), and must start and end with + alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + at most 253 characters in length, consisting of dot-separated segments where + each segment starts and ends with an alphanumeric character. + Label values must be either empty or 1-63 characters, consisting of + alphanumeric characters, dashes (-), underscores (_), or dots (.), + starting and ending with an alphanumeric character. + Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + maxProperties: 8 + minProperties: 1 + type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid qualified names, consisting + of an optional DNS subdomain prefix of up to 253 characters + followed by a slash and a name segment of 1-63 characters, + that consists only of alphanumeric characters, dashes, underscores, + and dots, and must start and end with an alphanumeric character + rule: self.all(key, !format.qualifiedName().validate(key).hasValue()) + - message: kubernetes.io/, k8s.io/, and openshift.io/ prefixed + label keys are reserved and may not be used + rule: self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/') + && !key.startsWith('openshift.io/')) + name: + description: |- + name is the logical name of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + servingCertKeyPairSecret: + description: |- + servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. + The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. + If the custom hostname uses the default routing suffix of the cluster, + the Secret specification for a serving certificate will not be needed. + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + required: + - name + type: object + required: + - hostname + - name + - namespace + type: object + maxItems: 250 + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + domain: + description: |- + domain is used to generate a default host name for a route when the + route's host name is empty. The generated host name will follow this + pattern: "..". + + It is also used as the default wildcard domain suffix for ingress. The + default ingresscontroller domain will follow this pattern: "*.". + + Once set, changing domain is not currently supported. + type: string + x-kubernetes-validations: + - message: domain is immutable once set + rule: self == oldSelf + loadBalancer: + description: |- + loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure + provider of the current cluster and are required for Ingress Controller to work on OpenShift. + properties: + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for the ingress load balancers. + 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 settings specific to the Amazon + Web Services infrastructure provider. + properties: + type: + description: |- + type allows user to set a load balancer type. + When this field is set the default ingresscontroller will get created using the specified LBType. + If this field is not set then the default ingress controller of LBType Classic will be created. + Valid values are: + + * "Classic": A Classic Load Balancer that makes routing decisions at either + the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See + the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + + * "NLB": A Network Load Balancer that makes routing decisions at the + transport layer (TCP/SSL). See the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb + enum: + - NLB + - Classic + type: string + required: + - type + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + 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 + type: object + type: object + requiredHSTSPolicies: + description: |- + requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes + matching the domainPattern/s and namespaceSelector/s that are specified in the policy. + Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route + annotation, and affect route admission. + + A candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: + "haproxy.router.openshift.io/hsts_header" + E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains + + - For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, + then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route + is rejected. + - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies + determines the route's admission status. + - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, + then it may use any HSTS Policy annotation. + + The HSTS policy configuration may be changed after routes have already been created. An update to a previously + admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. + However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working. + + Note that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid. + items: + properties: + domainPatterns: + description: |- + domainPatterns is a list of domains for which the desired HSTS annotations are required. + If domainPatterns is specified and a route is created with a spec.host matching one of the domains, + the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. + + The use of wildcards is allowed like this: *.foo.com matches everything under foo.com. + foo.com only matches foo.com, so to cover foo.com and everything under it, you must specify *both*. + items: + type: string + minItems: 1 + type: array + includeSubDomainsPolicy: + description: |- + includeSubDomainsPolicy means the HSTS Policy should apply to any subdomains of the host's + domain name. Thus, for the host bar.foo.com, if includeSubDomainsPolicy was set to RequireIncludeSubDomains: + - the host app.bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host foo.com would NOT inherit the HSTS Policy of bar.foo.com + - the host def.foo.com would NOT inherit the HSTS Policy of bar.foo.com + enum: + - RequireIncludeSubDomains + - RequireNoIncludeSubDomains + - NoOpinion + type: string + maxAge: + description: |- + maxAge is the delta time range in seconds during which hosts are regarded as HSTS hosts. + If set to 0, it negates the effect, and hosts are removed as HSTS hosts. + If set to 0 and includeSubdomains is specified, all subdomains of the host are also removed as HSTS hosts. + maxAge is a time-to-live value, and if this policy is not refreshed on a client, the HSTS + policy will eventually expire on that client. + properties: + largestMaxAge: + description: |- + The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age + This value can be left unspecified, in which case no upper limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + smallestMaxAge: + description: |- + The smallest allowed value (in seconds) of the RequiredHSTSPolicy max-age + Setting max-age=0 allows the deletion of an existing HSTS header from a host. This is a necessary + tool for administrators to quickly correct mistakes. + This value can be left unspecified, in which case no lower limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + type: object + namespaceSelector: + description: |- + namespaceSelector specifies a label selector such that the policy applies only to those routes that + are in namespaces with labels that match the selector, and are in one of the DomainPatterns. + Defaults to the empty LabelSelector, which matches everything. + 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 + preloadPolicy: + description: |- + preloadPolicy directs the client to include hosts in its host preload list so that + it never needs to do an initial load to get the HSTS header (note that this is not defined + in RFC 6797 and is therefore client implementation-dependent). + enum: + - RequirePreload + - RequireNoPreload + - NoOpinion + type: string + required: + - domainPatterns + type: object + type: array + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + componentRoutes: + description: |- + componentRoutes is where participating operators place the current route status for routes whose + hostnames and serving certificates can be customized by the cluster-admin. + items: + description: ComponentRouteStatus contains information allowing + configuration of a route's hostname and serving certificate. + properties: + conditions: + description: |- + conditions are used to communicate the state of the componentRoutes entry. + + Supported conditions include Available, Degraded and Progressing. + + If available is true, the content served by the route can be accessed by users. This includes cases + where a default may continue to serve content while the customized route specified by the cluster-admin + is being configured. + + If Degraded is true, that means something has gone wrong trying to handle the componentRoutes entry. + The currentHostnames field may or may not be in effect. + + If Progressing is true, that means the component is taking some action related to the componentRoutes entry. + 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 + consumingUsers: + description: consumingUsers is a slice of ServiceAccounts that + need to have read permission on the servingCertKeyPairSecret + secret. + items: + description: ConsumingUser is an alias for string which we + add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + currentHostnames: + description: |- + currentHostnames is the list of current names used by the route. Typically, this list should consist of a single + hostname, but if multiple hostnames are supported by the route the operator may write multiple entries to this list. + items: + description: Hostname is a host name as defined by RFC-1123. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + minItems: 1 + type: array + defaultHostname: + description: defaultHostname is the hostname of this route prior + to customization. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. It does not have to be the actual name of a route resource + but it cannot be renamed. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. It must be a real namespace. Using an actual namespace + ensures that no two components will conflict and the same component can be installed multiple times. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + relatedObjects: + description: relatedObjects is a list of resources which are + useful when debugging or inspecting how spec.componentRoutes + is applied. + items: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + minItems: 1 + type: array + required: + - defaultHostname + - name + - namespace + - relatedObjects + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + defaultPlacement: + description: |- + defaultPlacement is set at installation time to control which + nodes will host the ingress router pods by default. The options are + control-plane nodes or worker nodes. + + This field works by dictating how the Cluster Ingress Operator will + consider unset replicas and nodePlacement fields in IngressController + resources when creating the corresponding Deployments. + + See the documentation for the IngressController replicas and nodePlacement + fields for more information. + + When omitted, the default value is Workers + enum: + - ControlPlane + - Workers + - "" + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-Default.crd.yaml new file mode 100644 index 0000000000..70c87e6e48 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-Default.crd.yaml @@ -0,0 +1,546 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + 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/bootstrap-required: "true" + release.openshift.io/feature-set: Default + name: ingresses.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Ingress + listKind: IngressList + plural: ingresses + singular: ingress + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Ingress holds cluster-wide information about ingress, including the default ingress domain + used for routes. The canonical name is `cluster`. + + 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 holds user settable values for configuration + properties: + appsDomain: + description: |- + appsDomain is an optional domain to use instead of the one specified + in the domain field when a Route is created without specifying an explicit + host. If appsDomain is nonempty, this value is used to generate default + host values for Route. Unlike domain, appsDomain may be modified after + installation. + This assumes a new ingresscontroller has been setup with a wildcard + certificate. + type: string + componentRoutes: + description: |- + componentRoutes is an optional list of routes that are managed by OpenShift components + that a cluster-admin is able to configure the hostname and serving certificate for. + The namespace and name of each route in this list should match an existing entry in the + status.componentRoutes list. + + To determine the set of configurable Routes, look at namespace and name of entries in the + .status.componentRoutes list, where participating operators write the status of + configurable routes. + A maximum of 250 component routes may be configured. + items: + description: ComponentRouteSpec allows for configuration of a route's + hostname and serving certificate. + properties: + hostname: + description: hostname is the hostname that should be used by + the route. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + servingCertKeyPairSecret: + description: |- + servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. + The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. + If the custom hostname uses the default routing suffix of the cluster, + the Secret specification for a serving certificate will not be needed. + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + required: + - name + type: object + required: + - hostname + - name + - namespace + type: object + maxItems: 250 + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + domain: + description: |- + domain is used to generate a default host name for a route when the + route's host name is empty. The generated host name will follow this + pattern: "..". + + It is also used as the default wildcard domain suffix for ingress. The + default ingresscontroller domain will follow this pattern: "*.". + + Once set, changing domain is not currently supported. + type: string + x-kubernetes-validations: + - message: domain is immutable once set + rule: self == oldSelf + loadBalancer: + description: |- + loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure + provider of the current cluster and are required for Ingress Controller to work on OpenShift. + properties: + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for the ingress load balancers. + 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 settings specific to the Amazon + Web Services infrastructure provider. + properties: + type: + description: |- + type allows user to set a load balancer type. + When this field is set the default ingresscontroller will get created using the specified LBType. + If this field is not set then the default ingress controller of LBType Classic will be created. + Valid values are: + + * "Classic": A Classic Load Balancer that makes routing decisions at either + the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See + the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + + * "NLB": A Network Load Balancer that makes routing decisions at the + transport layer (TCP/SSL). See the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb + enum: + - NLB + - Classic + type: string + required: + - type + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + 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 + type: object + type: object + requiredHSTSPolicies: + description: |- + requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes + matching the domainPattern/s and namespaceSelector/s that are specified in the policy. + Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route + annotation, and affect route admission. + + A candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: + "haproxy.router.openshift.io/hsts_header" + E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains + + - For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, + then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route + is rejected. + - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies + determines the route's admission status. + - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, + then it may use any HSTS Policy annotation. + + The HSTS policy configuration may be changed after routes have already been created. An update to a previously + admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. + However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working. + + Note that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid. + items: + properties: + domainPatterns: + description: |- + domainPatterns is a list of domains for which the desired HSTS annotations are required. + If domainPatterns is specified and a route is created with a spec.host matching one of the domains, + the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. + + The use of wildcards is allowed like this: *.foo.com matches everything under foo.com. + foo.com only matches foo.com, so to cover foo.com and everything under it, you must specify *both*. + items: + type: string + minItems: 1 + type: array + includeSubDomainsPolicy: + description: |- + includeSubDomainsPolicy means the HSTS Policy should apply to any subdomains of the host's + domain name. Thus, for the host bar.foo.com, if includeSubDomainsPolicy was set to RequireIncludeSubDomains: + - the host app.bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host foo.com would NOT inherit the HSTS Policy of bar.foo.com + - the host def.foo.com would NOT inherit the HSTS Policy of bar.foo.com + enum: + - RequireIncludeSubDomains + - RequireNoIncludeSubDomains + - NoOpinion + type: string + maxAge: + description: |- + maxAge is the delta time range in seconds during which hosts are regarded as HSTS hosts. + If set to 0, it negates the effect, and hosts are removed as HSTS hosts. + If set to 0 and includeSubdomains is specified, all subdomains of the host are also removed as HSTS hosts. + maxAge is a time-to-live value, and if this policy is not refreshed on a client, the HSTS + policy will eventually expire on that client. + properties: + largestMaxAge: + description: |- + The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age + This value can be left unspecified, in which case no upper limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + smallestMaxAge: + description: |- + The smallest allowed value (in seconds) of the RequiredHSTSPolicy max-age + Setting max-age=0 allows the deletion of an existing HSTS header from a host. This is a necessary + tool for administrators to quickly correct mistakes. + This value can be left unspecified, in which case no lower limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + type: object + namespaceSelector: + description: |- + namespaceSelector specifies a label selector such that the policy applies only to those routes that + are in namespaces with labels that match the selector, and are in one of the DomainPatterns. + Defaults to the empty LabelSelector, which matches everything. + 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 + preloadPolicy: + description: |- + preloadPolicy directs the client to include hosts in its host preload list so that + it never needs to do an initial load to get the HSTS header (note that this is not defined + in RFC 6797 and is therefore client implementation-dependent). + enum: + - RequirePreload + - RequireNoPreload + - NoOpinion + type: string + required: + - domainPatterns + type: object + type: array + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + componentRoutes: + description: |- + componentRoutes is where participating operators place the current route status for routes whose + hostnames and serving certificates can be customized by the cluster-admin. + items: + description: ComponentRouteStatus contains information allowing + configuration of a route's hostname and serving certificate. + properties: + conditions: + description: |- + conditions are used to communicate the state of the componentRoutes entry. + + Supported conditions include Available, Degraded and Progressing. + + If available is true, the content served by the route can be accessed by users. This includes cases + where a default may continue to serve content while the customized route specified by the cluster-admin + is being configured. + + If Degraded is true, that means something has gone wrong trying to handle the componentRoutes entry. + The currentHostnames field may or may not be in effect. + + If Progressing is true, that means the component is taking some action related to the componentRoutes entry. + 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 + consumingUsers: + description: consumingUsers is a slice of ServiceAccounts that + need to have read permission on the servingCertKeyPairSecret + secret. + items: + description: ConsumingUser is an alias for string which we + add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + currentHostnames: + description: |- + currentHostnames is the list of current names used by the route. Typically, this list should consist of a single + hostname, but if multiple hostnames are supported by the route the operator may write multiple entries to this list. + items: + description: Hostname is a host name as defined by RFC-1123. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + minItems: 1 + type: array + defaultHostname: + description: defaultHostname is the hostname of this route prior + to customization. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. It does not have to be the actual name of a route resource + but it cannot be renamed. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. It must be a real namespace. Using an actual namespace + ensures that no two components will conflict and the same component can be installed multiple times. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + relatedObjects: + description: relatedObjects is a list of resources which are + useful when debugging or inspecting how spec.componentRoutes + is applied. + items: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + minItems: 1 + type: array + required: + - defaultHostname + - name + - namespace + - relatedObjects + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + defaultPlacement: + description: |- + defaultPlacement is set at installation time to control which + nodes will host the ingress router pods by default. The options are + control-plane nodes or worker nodes. + + This field works by dictating how the Cluster Ingress Operator will + consider unset replicas and nodePlacement fields in IngressController + resources when creating the corresponding Deployments. + + See the documentation for the IngressController replicas and nodePlacement + fields for more information. + + When omitted, the default value is Workers + enum: + - ControlPlane + - Workers + - "" + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000000..42e4209c6b --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml @@ -0,0 +1,593 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + 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/bootstrap-required: "true" + release.openshift.io/feature-set: DevPreviewNoUpgrade + name: ingresses.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Ingress + listKind: IngressList + plural: ingresses + singular: ingress + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Ingress holds cluster-wide information about ingress, including the default ingress domain + used for routes. The canonical name is `cluster`. + + 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 holds user settable values for configuration + properties: + appsDomain: + description: |- + appsDomain is an optional domain to use instead of the one specified + in the domain field when a Route is created without specifying an explicit + host. If appsDomain is nonempty, this value is used to generate default + host values for Route. Unlike domain, appsDomain may be modified after + installation. + This assumes a new ingresscontroller has been setup with a wildcard + certificate. + type: string + componentRoutes: + description: |- + componentRoutes is an optional list of routes that are managed by OpenShift components + that a cluster-admin is able to configure the hostname and serving certificate for. + The namespace and name of each route in this list should match an existing entry in the + status.componentRoutes list. + + To determine the set of configurable Routes, look at namespace and name of entries in the + .status.componentRoutes list, where participating operators write the status of + configurable routes. + A maximum of 250 component routes may be configured. + items: + description: ComponentRouteSpec allows for configuration of a route's + hostname and serving certificate. + properties: + hostname: + description: hostname is the hostname that should be used by + the route. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + labels: + additionalProperties: + description: |- + LabelValue is the value part of a Kubernetes label. + A label value must be either empty or 1-63 characters, consisting of + alphanumeric characters, '-', '_', or '.', starting and ending with + an alphanumeric character. + maxLength: 63 + type: string + x-kubernetes-validations: + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: '!format.labelValue().validate(self).hasValue()' + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. Changing labels may cause the + route to be reassigned to a different IngressController. + When omitted, no additional labels are applied to the component route. + When specified, labels must contain at least one entry, up to a maximum of 8. + Label keys must be valid qualified names, consisting of a name segment and + an optional prefix separated by a slash (/). The name segment must be at most + 63 characters in length and must consist only of alphanumeric characters, + dashes (-), underscores (_), and dots (.), and must start and end with + alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + at most 253 characters in length, consisting of dot-separated segments where + each segment starts and ends with an alphanumeric character. + Label values must be either empty or 1-63 characters, consisting of + alphanumeric characters, dashes (-), underscores (_), or dots (.), + starting and ending with an alphanumeric character. + Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + maxProperties: 8 + minProperties: 1 + type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid qualified names, consisting + of an optional DNS subdomain prefix of up to 253 characters + followed by a slash and a name segment of 1-63 characters, + that consists only of alphanumeric characters, dashes, underscores, + and dots, and must start and end with an alphanumeric character + rule: self.all(key, !format.qualifiedName().validate(key).hasValue()) + - message: kubernetes.io/, k8s.io/, and openshift.io/ prefixed + label keys are reserved and may not be used + rule: self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/') + && !key.startsWith('openshift.io/')) + name: + description: |- + name is the logical name of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + servingCertKeyPairSecret: + description: |- + servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. + The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. + If the custom hostname uses the default routing suffix of the cluster, + the Secret specification for a serving certificate will not be needed. + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + required: + - name + type: object + required: + - hostname + - name + - namespace + type: object + maxItems: 250 + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + domain: + description: |- + domain is used to generate a default host name for a route when the + route's host name is empty. The generated host name will follow this + pattern: "..". + + It is also used as the default wildcard domain suffix for ingress. The + default ingresscontroller domain will follow this pattern: "*.". + + Once set, changing domain is not currently supported. + type: string + x-kubernetes-validations: + - message: domain is immutable once set + rule: self == oldSelf + loadBalancer: + description: |- + loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure + provider of the current cluster and are required for Ingress Controller to work on OpenShift. + properties: + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for the ingress load balancers. + 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 settings specific to the Amazon + Web Services infrastructure provider. + properties: + type: + description: |- + type allows user to set a load balancer type. + When this field is set the default ingresscontroller will get created using the specified LBType. + If this field is not set then the default ingress controller of LBType Classic will be created. + Valid values are: + + * "Classic": A Classic Load Balancer that makes routing decisions at either + the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See + the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + + * "NLB": A Network Load Balancer that makes routing decisions at the + transport layer (TCP/SSL). See the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb + enum: + - NLB + - Classic + type: string + required: + - type + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + 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 + type: object + type: object + requiredHSTSPolicies: + description: |- + requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes + matching the domainPattern/s and namespaceSelector/s that are specified in the policy. + Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route + annotation, and affect route admission. + + A candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: + "haproxy.router.openshift.io/hsts_header" + E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains + + - For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, + then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route + is rejected. + - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies + determines the route's admission status. + - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, + then it may use any HSTS Policy annotation. + + The HSTS policy configuration may be changed after routes have already been created. An update to a previously + admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. + However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working. + + Note that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid. + items: + properties: + domainPatterns: + description: |- + domainPatterns is a list of domains for which the desired HSTS annotations are required. + If domainPatterns is specified and a route is created with a spec.host matching one of the domains, + the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. + + The use of wildcards is allowed like this: *.foo.com matches everything under foo.com. + foo.com only matches foo.com, so to cover foo.com and everything under it, you must specify *both*. + items: + type: string + minItems: 1 + type: array + includeSubDomainsPolicy: + description: |- + includeSubDomainsPolicy means the HSTS Policy should apply to any subdomains of the host's + domain name. Thus, for the host bar.foo.com, if includeSubDomainsPolicy was set to RequireIncludeSubDomains: + - the host app.bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host foo.com would NOT inherit the HSTS Policy of bar.foo.com + - the host def.foo.com would NOT inherit the HSTS Policy of bar.foo.com + enum: + - RequireIncludeSubDomains + - RequireNoIncludeSubDomains + - NoOpinion + type: string + maxAge: + description: |- + maxAge is the delta time range in seconds during which hosts are regarded as HSTS hosts. + If set to 0, it negates the effect, and hosts are removed as HSTS hosts. + If set to 0 and includeSubdomains is specified, all subdomains of the host are also removed as HSTS hosts. + maxAge is a time-to-live value, and if this policy is not refreshed on a client, the HSTS + policy will eventually expire on that client. + properties: + largestMaxAge: + description: |- + The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age + This value can be left unspecified, in which case no upper limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + smallestMaxAge: + description: |- + The smallest allowed value (in seconds) of the RequiredHSTSPolicy max-age + Setting max-age=0 allows the deletion of an existing HSTS header from a host. This is a necessary + tool for administrators to quickly correct mistakes. + This value can be left unspecified, in which case no lower limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + type: object + namespaceSelector: + description: |- + namespaceSelector specifies a label selector such that the policy applies only to those routes that + are in namespaces with labels that match the selector, and are in one of the DomainPatterns. + Defaults to the empty LabelSelector, which matches everything. + 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 + preloadPolicy: + description: |- + preloadPolicy directs the client to include hosts in its host preload list so that + it never needs to do an initial load to get the HSTS header (note that this is not defined + in RFC 6797 and is therefore client implementation-dependent). + enum: + - RequirePreload + - RequireNoPreload + - NoOpinion + type: string + required: + - domainPatterns + type: object + type: array + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + componentRoutes: + description: |- + componentRoutes is where participating operators place the current route status for routes whose + hostnames and serving certificates can be customized by the cluster-admin. + items: + description: ComponentRouteStatus contains information allowing + configuration of a route's hostname and serving certificate. + properties: + conditions: + description: |- + conditions are used to communicate the state of the componentRoutes entry. + + Supported conditions include Available, Degraded and Progressing. + + If available is true, the content served by the route can be accessed by users. This includes cases + where a default may continue to serve content while the customized route specified by the cluster-admin + is being configured. + + If Degraded is true, that means something has gone wrong trying to handle the componentRoutes entry. + The currentHostnames field may or may not be in effect. + + If Progressing is true, that means the component is taking some action related to the componentRoutes entry. + 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 + consumingUsers: + description: consumingUsers is a slice of ServiceAccounts that + need to have read permission on the servingCertKeyPairSecret + secret. + items: + description: ConsumingUser is an alias for string which we + add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + currentHostnames: + description: |- + currentHostnames is the list of current names used by the route. Typically, this list should consist of a single + hostname, but if multiple hostnames are supported by the route the operator may write multiple entries to this list. + items: + description: Hostname is a host name as defined by RFC-1123. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + minItems: 1 + type: array + defaultHostname: + description: defaultHostname is the hostname of this route prior + to customization. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. It does not have to be the actual name of a route resource + but it cannot be renamed. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. It must be a real namespace. Using an actual namespace + ensures that no two components will conflict and the same component can be installed multiple times. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + relatedObjects: + description: relatedObjects is a list of resources which are + useful when debugging or inspecting how spec.componentRoutes + is applied. + items: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + minItems: 1 + type: array + required: + - defaultHostname + - name + - namespace + - relatedObjects + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + defaultPlacement: + description: |- + defaultPlacement is set at installation time to control which + nodes will host the ingress router pods by default. The options are + control-plane nodes or worker nodes. + + This field works by dictating how the Cluster Ingress Operator will + consider unset replicas and nodePlacement fields in IngressController + resources when creating the corresponding Deployments. + + See the documentation for the IngressController replicas and nodePlacement + fields for more information. + + When omitted, the default value is Workers + enum: + - ControlPlane + - Workers + - "" + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-OKD.crd.yaml similarity index 99% rename from vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml rename to vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-OKD.crd.yaml index 603d58d6d8..2c5b410efc 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-OKD.crd.yaml @@ -7,6 +7,7 @@ metadata: include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" release.openshift.io/bootstrap-required: "true" + release.openshift.io/feature-set: OKD name: ingresses.config.openshift.io spec: group: config.openshift.io @@ -66,6 +67,7 @@ spec: To determine the set of configurable Routes, look at namespace and name of entries in the .status.componentRoutes list, where participating operators write the status of configurable routes. + A maximum of 250 component routes may be configured. items: description: ComponentRouteSpec allows for configuration of a route's hostname and serving certificate. @@ -113,6 +115,7 @@ spec: - name - namespace type: object + maxItems: 250 type: array x-kubernetes-list-map-keys: - namespace diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000000..d7fc151b11 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,593 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + 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/bootstrap-required: "true" + release.openshift.io/feature-set: TechPreviewNoUpgrade + name: ingresses.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Ingress + listKind: IngressList + plural: ingresses + singular: ingress + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Ingress holds cluster-wide information about ingress, including the default ingress domain + used for routes. The canonical name is `cluster`. + + 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 holds user settable values for configuration + properties: + appsDomain: + description: |- + appsDomain is an optional domain to use instead of the one specified + in the domain field when a Route is created without specifying an explicit + host. If appsDomain is nonempty, this value is used to generate default + host values for Route. Unlike domain, appsDomain may be modified after + installation. + This assumes a new ingresscontroller has been setup with a wildcard + certificate. + type: string + componentRoutes: + description: |- + componentRoutes is an optional list of routes that are managed by OpenShift components + that a cluster-admin is able to configure the hostname and serving certificate for. + The namespace and name of each route in this list should match an existing entry in the + status.componentRoutes list. + + To determine the set of configurable Routes, look at namespace and name of entries in the + .status.componentRoutes list, where participating operators write the status of + configurable routes. + A maximum of 250 component routes may be configured. + items: + description: ComponentRouteSpec allows for configuration of a route's + hostname and serving certificate. + properties: + hostname: + description: hostname is the hostname that should be used by + the route. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + labels: + additionalProperties: + description: |- + LabelValue is the value part of a Kubernetes label. + A label value must be either empty or 1-63 characters, consisting of + alphanumeric characters, '-', '_', or '.', starting and ending with + an alphanumeric character. + maxLength: 63 + type: string + x-kubernetes-validations: + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: '!format.labelValue().validate(self).hasValue()' + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. Changing labels may cause the + route to be reassigned to a different IngressController. + When omitted, no additional labels are applied to the component route. + When specified, labels must contain at least one entry, up to a maximum of 8. + Label keys must be valid qualified names, consisting of a name segment and + an optional prefix separated by a slash (/). The name segment must be at most + 63 characters in length and must consist only of alphanumeric characters, + dashes (-), underscores (_), and dots (.), and must start and end with + alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + at most 253 characters in length, consisting of dot-separated segments where + each segment starts and ends with an alphanumeric character. + Label values must be either empty or 1-63 characters, consisting of + alphanumeric characters, dashes (-), underscores (_), or dots (.), + starting and ending with an alphanumeric character. + Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + maxProperties: 8 + minProperties: 1 + type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid qualified names, consisting + of an optional DNS subdomain prefix of up to 253 characters + followed by a slash and a name segment of 1-63 characters, + that consists only of alphanumeric characters, dashes, underscores, + and dots, and must start and end with an alphanumeric character + rule: self.all(key, !format.qualifiedName().validate(key).hasValue()) + - message: kubernetes.io/, k8s.io/, and openshift.io/ prefixed + label keys are reserved and may not be used + rule: self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/') + && !key.startsWith('openshift.io/')) + name: + description: |- + name is the logical name of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + servingCertKeyPairSecret: + description: |- + servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. + The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. + If the custom hostname uses the default routing suffix of the cluster, + the Secret specification for a serving certificate will not be needed. + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + required: + - name + type: object + required: + - hostname + - name + - namespace + type: object + maxItems: 250 + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + domain: + description: |- + domain is used to generate a default host name for a route when the + route's host name is empty. The generated host name will follow this + pattern: "..". + + It is also used as the default wildcard domain suffix for ingress. The + default ingresscontroller domain will follow this pattern: "*.". + + Once set, changing domain is not currently supported. + type: string + x-kubernetes-validations: + - message: domain is immutable once set + rule: self == oldSelf + loadBalancer: + description: |- + loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure + provider of the current cluster and are required for Ingress Controller to work on OpenShift. + properties: + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for the ingress load balancers. + 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 settings specific to the Amazon + Web Services infrastructure provider. + properties: + type: + description: |- + type allows user to set a load balancer type. + When this field is set the default ingresscontroller will get created using the specified LBType. + If this field is not set then the default ingress controller of LBType Classic will be created. + Valid values are: + + * "Classic": A Classic Load Balancer that makes routing decisions at either + the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See + the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + + * "NLB": A Network Load Balancer that makes routing decisions at the + transport layer (TCP/SSL). See the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb + enum: + - NLB + - Classic + type: string + required: + - type + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + 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 + type: object + type: object + requiredHSTSPolicies: + description: |- + requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes + matching the domainPattern/s and namespaceSelector/s that are specified in the policy. + Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route + annotation, and affect route admission. + + A candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: + "haproxy.router.openshift.io/hsts_header" + E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains + + - For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, + then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route + is rejected. + - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies + determines the route's admission status. + - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, + then it may use any HSTS Policy annotation. + + The HSTS policy configuration may be changed after routes have already been created. An update to a previously + admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. + However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working. + + Note that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid. + items: + properties: + domainPatterns: + description: |- + domainPatterns is a list of domains for which the desired HSTS annotations are required. + If domainPatterns is specified and a route is created with a spec.host matching one of the domains, + the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. + + The use of wildcards is allowed like this: *.foo.com matches everything under foo.com. + foo.com only matches foo.com, so to cover foo.com and everything under it, you must specify *both*. + items: + type: string + minItems: 1 + type: array + includeSubDomainsPolicy: + description: |- + includeSubDomainsPolicy means the HSTS Policy should apply to any subdomains of the host's + domain name. Thus, for the host bar.foo.com, if includeSubDomainsPolicy was set to RequireIncludeSubDomains: + - the host app.bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host foo.com would NOT inherit the HSTS Policy of bar.foo.com + - the host def.foo.com would NOT inherit the HSTS Policy of bar.foo.com + enum: + - RequireIncludeSubDomains + - RequireNoIncludeSubDomains + - NoOpinion + type: string + maxAge: + description: |- + maxAge is the delta time range in seconds during which hosts are regarded as HSTS hosts. + If set to 0, it negates the effect, and hosts are removed as HSTS hosts. + If set to 0 and includeSubdomains is specified, all subdomains of the host are also removed as HSTS hosts. + maxAge is a time-to-live value, and if this policy is not refreshed on a client, the HSTS + policy will eventually expire on that client. + properties: + largestMaxAge: + description: |- + The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age + This value can be left unspecified, in which case no upper limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + smallestMaxAge: + description: |- + The smallest allowed value (in seconds) of the RequiredHSTSPolicy max-age + Setting max-age=0 allows the deletion of an existing HSTS header from a host. This is a necessary + tool for administrators to quickly correct mistakes. + This value can be left unspecified, in which case no lower limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + type: object + namespaceSelector: + description: |- + namespaceSelector specifies a label selector such that the policy applies only to those routes that + are in namespaces with labels that match the selector, and are in one of the DomainPatterns. + Defaults to the empty LabelSelector, which matches everything. + 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 + preloadPolicy: + description: |- + preloadPolicy directs the client to include hosts in its host preload list so that + it never needs to do an initial load to get the HSTS header (note that this is not defined + in RFC 6797 and is therefore client implementation-dependent). + enum: + - RequirePreload + - RequireNoPreload + - NoOpinion + type: string + required: + - domainPatterns + type: object + type: array + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + componentRoutes: + description: |- + componentRoutes is where participating operators place the current route status for routes whose + hostnames and serving certificates can be customized by the cluster-admin. + items: + description: ComponentRouteStatus contains information allowing + configuration of a route's hostname and serving certificate. + properties: + conditions: + description: |- + conditions are used to communicate the state of the componentRoutes entry. + + Supported conditions include Available, Degraded and Progressing. + + If available is true, the content served by the route can be accessed by users. This includes cases + where a default may continue to serve content while the customized route specified by the cluster-admin + is being configured. + + If Degraded is true, that means something has gone wrong trying to handle the componentRoutes entry. + The currentHostnames field may or may not be in effect. + + If Progressing is true, that means the component is taking some action related to the componentRoutes entry. + 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 + consumingUsers: + description: consumingUsers is a slice of ServiceAccounts that + need to have read permission on the servingCertKeyPairSecret + secret. + items: + description: ConsumingUser is an alias for string which we + add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + currentHostnames: + description: |- + currentHostnames is the list of current names used by the route. Typically, this list should consist of a single + hostname, but if multiple hostnames are supported by the route the operator may write multiple entries to this list. + items: + description: Hostname is a host name as defined by RFC-1123. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + minItems: 1 + type: array + defaultHostname: + description: defaultHostname is the hostname of this route prior + to customization. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. It does not have to be the actual name of a route resource + but it cannot be renamed. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. It must be a real namespace. Using an actual namespace + ensures that no two components will conflict and the same component can be installed multiple times. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + relatedObjects: + description: relatedObjects is a list of resources which are + useful when debugging or inspecting how spec.componentRoutes + is applied. + items: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + minItems: 1 + type: array + required: + - defaultHostname + - name + - namespace + - relatedObjects + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + defaultPlacement: + description: |- + defaultPlacement is set at installation time to control which + nodes will host the ingress router pods by default. The options are + control-plane nodes or worker nodes. + + This field works by dictating how the Cluster Ingress Operator will + consider unset replicas and nodePlacement fields in IngressController + resources when creating the corresponding Deployments. + + See the documentation for the IngressController replicas and nodePlacement + fields for more information. + + When omitted, the default value is Workers + enum: + - ControlPlane + - Workers + - "" + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go index 3c75062bb7..4b194b226a 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go @@ -1640,6 +1640,13 @@ func (in *ComponentOverride) DeepCopy() *ComponentOverride { func (in *ComponentRouteSpec) DeepCopyInto(out *ComponentRouteSpec) { *out = *in out.ServingCertKeyPairSecret = in.ServingCertKeyPairSecret + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]LabelValue, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } @@ -3914,7 +3921,9 @@ func (in *IngressSpec) DeepCopyInto(out *IngressSpec) { if in.ComponentRoutes != nil { in, out := &in.ComponentRoutes, &out.ComponentRoutes *out = make([]ComponentRouteSpec, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.RequiredHSTSPolicies != nil { in, out := &in.RequiredHSTSPolicies, &out.RequiredHSTSPolicies diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml index 5426057a88..7707626383 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml @@ -396,8 +396,8 @@ infrastructures.config.openshift.io: FeatureGates: - AWSClusterHostedDNSInstall - AWSDualStackInstall - - AzureClusterHostedDNSInstall - AzureDualStackInstall + - BGPBasedVIPManagement - DualReplica - DyanmicServiceEndpointIBMCloud - MutableTopology @@ -427,7 +427,8 @@ ingresses.config.openshift.io: CRDName: ingresses.config.openshift.io Capability: "" Category: "" - FeatureGates: [] + FeatureGates: + - IngressComponentRouteLabels FilenameOperatorName: config-operator FilenameOperatorOrdering: "01" FilenameRunLevel: "0000_10" diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go index e853db9793..92cc2acb6c 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go @@ -1698,6 +1698,7 @@ var map_BareMetalPlatformStatus = map[string]string{ "ingressIPs": "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.", "nodeDNSIP": "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.", "loadBalancer": "loadBalancer defines how the load balancer used by the cluster is configured.", + "vipManagement": "vipManagement indicates which VIP management mechanism is active on this cluster. Allowed values are `Keepalived`, `BGP`, and omitted. When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are deployed as static pods to advertise VIPs via BGP, replacing the default keepalived/VRRP mechanism. When set to `Keepalived`, the default keepalived-based VIP management is used. When omitted, the default keepalived-based VIP management is used.", "dnsRecordsType": "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`.", "machineNetworks": "machineNetworks are IP networks used to connect all the OpenShift cluster nodes.", } @@ -2283,6 +2284,7 @@ var map_ComponentRouteSpec = map[string]string{ "name": "name is the logical name of the route to customize.\n\nThe namespace and name of this componentRoute must match a corresponding entry in the list of status.componentRoutes if the route is to be customized.", "hostname": "hostname is the hostname that should be used by the route.", "servingCertKeyPairSecret": "servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. If the custom hostname uses the default routing suffix of the cluster, the Secret specification for a serving certificate will not be needed.", + "labels": "labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage. Changing labels may cause the route to be reassigned to a different IngressController. When omitted, no additional labels are applied to the component route. When specified, labels must contain at least one entry, up to a maximum of 8. Label keys must be valid qualified names, consisting of a name segment and an optional prefix separated by a slash (/). The name segment must be at most 63 characters in length and must consist only of alphanumeric characters, dashes (-), underscores (_), and dots (.), and must start and end with alphanumeric characters. The prefix, if specified, must be a DNS subdomain: at most 253 characters in length, consisting of dot-separated segments where each segment starts and ends with an alphanumeric character. Label values must be either empty or 1-63 characters, consisting of alphanumeric characters, dashes (-), underscores (_), or dots (.), starting and ending with an alphanumeric character. Keys with the \"kubernetes.io/\", \"k8s.io/\", and \"openshift.io/\" prefixes are reserved and may not be used.", } func (ComponentRouteSpec) SwaggerDoc() map[string]string { @@ -2337,7 +2339,7 @@ func (IngressPlatformSpec) SwaggerDoc() map[string]string { var map_IngressSpec = map[string]string{ "domain": "domain is used to generate a default host name for a route when the route's host name is empty. The generated host name will follow this pattern: \"..\".\n\nIt is also used as the default wildcard domain suffix for ingress. The default ingresscontroller domain will follow this pattern: \"*.\".\n\nOnce set, changing domain is not currently supported.", "appsDomain": "appsDomain is an optional domain to use instead of the one specified in the domain field when a Route is created without specifying an explicit host. If appsDomain is nonempty, this value is used to generate default host values for Route. Unlike domain, appsDomain may be modified after installation. This assumes a new ingresscontroller has been setup with a wildcard certificate.", - "componentRoutes": "componentRoutes is an optional list of routes that are managed by OpenShift components that a cluster-admin is able to configure the hostname and serving certificate for. The namespace and name of each route in this list should match an existing entry in the status.componentRoutes list.\n\nTo determine the set of configurable Routes, look at namespace and name of entries in the .status.componentRoutes list, where participating operators write the status of configurable routes.", + "componentRoutes": "componentRoutes is an optional list of routes that are managed by OpenShift components that a cluster-admin is able to configure the hostname and serving certificate for. The namespace and name of each route in this list should match an existing entry in the status.componentRoutes list.\n\nTo determine the set of configurable Routes, look at namespace and name of entries in the .status.componentRoutes list, where participating operators write the status of configurable routes. A maximum of 250 component routes may be configured.", "requiredHSTSPolicies": "requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes matching the domainPattern/s and namespaceSelector/s that are specified in the policy. Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route annotation, and affect route admission.\n\nA candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: \"haproxy.router.openshift.io/hsts_header\" E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains\n\n- For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route is rejected. - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies determines the route's admission status. - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, then it may use any HSTS Policy annotation.\n\nThe HSTS policy configuration may be changed after routes have already been created. An update to a previously admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working.\n\nNote that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid.", "loadBalancer": "loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure provider of the current cluster and are required for Ingress Controller to work on OpenShift.", } diff --git a/vendor/github.com/openshift/api/features.md b/vendor/github.com/openshift/api/features.md index 43c2d694b0..98d11f79eb 100644 --- a/vendor/github.com/openshift/api/features.md +++ b/vendor/github.com/openshift/api/features.md @@ -12,12 +12,13 @@ | ShortCertRotation| | | | | | | | | | KarpenterOperator| | | | Enabled | | | | | | MutableTopology| | | | Enabled | | | | | +| AuthenticationComponentProxy| | | | Enabled | | | | Enabled | +| BGPBasedVIPManagement| | | Enabled | Enabled | | | | | | ClusterAPIComputeInstall| | | Enabled | Enabled | | | | | | ClusterAPIControlPlaneInstall| | | Enabled | Enabled | | | | | | ClusterUpdatePreflight| | | Enabled | Enabled | | | | | | ConfidentialCluster| | | Enabled | Enabled | | | | | | Example2| | | Enabled | Enabled | | | | | -| ExternalOIDCExternalClaimsSourcing| | | Enabled | Enabled | | | | | | MachineAPIMigrationVSphere| | | Enabled | Enabled | | | | | | NetworkConnect| | | Enabled | Enabled | | | | | | NewOLMBoxCutterRuntime| | | | Enabled | | | | Enabled | @@ -59,6 +60,7 @@ | DyanmicServiceEndpointIBMCloud| | | Enabled | Enabled | | | Enabled | Enabled | | EtcdBackendQuota| | | Enabled | Enabled | | | Enabled | Enabled | | Example| | | Enabled | Enabled | | | Enabled | Enabled | +| ExternalOIDCExternalClaimsSourcing| | | Enabled | Enabled | | | Enabled | Enabled | | ExternalOIDCWithUpstreamParity| | | Enabled | Enabled | | | Enabled | Enabled | | ExternalSnapshotMetadata| | | Enabled | Enabled | | | Enabled | Enabled | | GCPCustomAPIEndpoints| | | Enabled | Enabled | | | Enabled | Enabled | @@ -66,6 +68,7 @@ | GCPDualStackInstall| | | Enabled | Enabled | | | Enabled | Enabled | | HyperShiftOnlyDynamicResourceAllocation| Enabled | | Enabled | | Enabled | | Enabled | | | ImageModeStatusReporting| | | Enabled | Enabled | | | Enabled | Enabled | +| IngressComponentRouteLabels| | | Enabled | Enabled | | | Enabled | Enabled | | IngressControllerDynamicConfigurationManager| | | Enabled | Enabled | | | Enabled | Enabled | | IngressControllerMultipleHAProxyVersions| | | Enabled | Enabled | | | Enabled | Enabled | | IrreconcilableMachineConfig| | | Enabled | Enabled | | | Enabled | Enabled | @@ -95,7 +98,6 @@ | OSStreams| | Enabled | Enabled | Enabled | | Enabled | Enabled | Enabled | | AWSClusterHostedDNSInstall| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | AWSServiceLBNetworkSecurityGroup| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | -| AzureClusterHostedDNSInstall| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | AzureWorkloadIdentity| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | BootImageSkewEnforcement| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | BuildCSIVolumes| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | diff --git a/vendor/github.com/openshift/api/features/features.go b/vendor/github.com/openshift/api/features/features.go index 393bf7e6f1..16538d919e 100644 --- a/vendor/github.com/openshift/api/features/features.go +++ b/vendor/github.com/openshift/api/features/features.go @@ -272,14 +272,6 @@ var ( enable(inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() - FeatureGateAzureClusterHostedDNSInstall = newFeatureGate("AzureClusterHostedDNSInstall"). - reportProblemsToJiraComponent("Installer"). - contactPerson("sadasu"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1468"). - enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). - mustRegister() - FeatureGateMixedCPUsAllocation = newFeatureGate("MixedCPUsAllocation"). reportProblemsToJiraComponent("NodeTuningOperator"). contactPerson("titzhak"). @@ -368,6 +360,14 @@ var ( enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() + FeatureGateAuthenticationComponentProxy = newFeatureGate("AuthenticationComponentProxy"). + reportProblemsToJiraComponent("authentication"). + contactPerson("liouk"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/2015"). + enable(inClusterProfile(SelfManaged), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). + mustRegister() + FeatureGateExternalOIDCWithAdditionalClaimMappings = newFeatureGate("ExternalOIDCWithUIDAndExtraClaimMappings"). reportProblemsToJiraComponent("authentication"). contactPerson("bpalmer"). @@ -389,7 +389,7 @@ var ( contactPerson("bpalmer"). productScope(ocpSpecific). enhancementPR("https://github.com/openshift/enhancements/pull/1907"). - enable(inDevPreviewNoUpgrade()). + enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). mustRegister() FeatureGateExample = newFeatureGate("Example"). @@ -666,6 +666,14 @@ var ( enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). mustRegister() + FeatureGateIngressComponentRouteLabels = newFeatureGate("IngressComponentRouteLabels"). + reportProblemsToJiraComponent("Management Console"). + contactPerson("leoli"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/2033"). + enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). + mustRegister() + FeatureGateIngressControllerMultipleHAProxyVersions = newFeatureGate("IngressControllerMultipleHAProxyVersions"). reportProblemsToJiraComponent("Networking/router"). contactPerson("miciah"). @@ -942,6 +950,14 @@ var ( enable(inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() + FeatureGateBGPBasedVIPManagement = newFeatureGate("BGPBasedVIPManagement"). + reportProblemsToJiraComponent("Networking / On-Prem Networking"). + contactPerson("mkowalski"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/1982"). + enable(inDevPreviewNoUpgrade()). + mustRegister() + FeatureGateProvisioningRequestAvailable = newFeatureGate("ProvisioningRequestAvailable"). reportProblemsToJiraComponent("Cluster Autoscaler"). contactPerson("elmiko"). diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/types.go b/vendor/github.com/openshift/api/machineconfiguration/v1/types.go index 33c12be923..5c4f6804ee 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/types.go +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/types.go @@ -113,6 +113,19 @@ type ControllerConfigSpec struct { // +required Images map[string]string `json:"images"` + // bgpVIPPeersJSON carries the BGP VIP peer configuration (the config.json + // payload of the bgp-vip-config ConfigMap) for rendering the frr-k8s + // static pod peer file on control plane nodes. Only set when BGP-based + // VIP management is enabled. + // When omitted, BGP-based VIP management is not configured and no + // frr-k8s peer file is rendered. + // When set, the value must be between 1 and 65536 characters long. + // +openshift:enable:FeatureGate=BGPBasedVIPManagement + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=65536 + // +optional + BGPVIPPeersJSON string `json:"bgpVIPPeersJSON,omitempty"` + // baseOSContainerImage is the new-format container image for operating system updates. // +required BaseOSContainerImage string `json:"baseOSContainerImage"` diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 9fd305414c..c749da98fc 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -62,6 +62,18 @@ spec: description: baseOSExtensionsContainerImage is the matching extensions container for the new-format container type: string + bgpVIPPeersJSON: + description: |- + bgpVIPPeersJSON carries the BGP VIP peer configuration (the config.json + payload of the bgp-vip-config ConfigMap) for rendering the frr-k8s + static pod peer file on control plane nodes. Only set when BGP-based + VIP management is enabled. + When omitted, BGP-based VIP management is not configured and no + frr-k8s peer file is rendered. + When set, the value must be between 1 and 65536 characters long. + maxLength: 65536 + minLength: 1 + type: string cloudProviderCAData: description: cloudProviderCAData specifies the cloud provider CA data format: byte @@ -2082,6 +2094,24 @@ spec: datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string + vipManagement: + description: |- + vipManagement indicates which VIP management mechanism is active + on this cluster. + Allowed values are `Keepalived`, `BGP`, and omitted. + When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + deployed as static pods to advertise VIPs via BGP, replacing the + default keepalived/VRRP mechanism. + When set to `Keepalived`, the default keepalived-based VIP + management is used. + When omitted, the default keepalived-based VIP management is used. + enum: + - Keepalived + - BGP + type: string + x-kubernetes-validations: + - message: vipManagement is immutable once set + rule: oldSelf == '' || self == oldSelf type: object x-kubernetes-validations: - message: dnsRecordsType may only be set to External diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-DevPreviewNoUpgrade.crd.yaml index 4717d10021..65c717d377 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-DevPreviewNoUpgrade.crd.yaml @@ -62,6 +62,18 @@ spec: description: baseOSExtensionsContainerImage is the matching extensions container for the new-format container type: string + bgpVIPPeersJSON: + description: |- + bgpVIPPeersJSON carries the BGP VIP peer configuration (the config.json + payload of the bgp-vip-config ConfigMap) for rendering the frr-k8s + static pod peer file on control plane nodes. Only set when BGP-based + VIP management is enabled. + When omitted, BGP-based VIP management is not configured and no + frr-k8s peer file is rendered. + When set, the value must be between 1 and 65536 characters long. + maxLength: 65536 + minLength: 1 + type: string cloudProviderCAData: description: cloudProviderCAData specifies the cloud provider CA data format: byte @@ -2067,6 +2079,24 @@ spec: datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string + vipManagement: + description: |- + vipManagement indicates which VIP management mechanism is active + on this cluster. + Allowed values are `Keepalived`, `BGP`, and omitted. + When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + deployed as static pods to advertise VIPs via BGP, replacing the + default keepalived/VRRP mechanism. + When set to `Keepalived`, the default keepalived-based VIP + management is used. + When omitted, the default keepalived-based VIP management is used. + enum: + - Keepalived + - BGP + type: string + x-kubernetes-validations: + - message: vipManagement is immutable once set + rule: oldSelf == '' || self == oldSelf type: object x-kubernetes-validations: - message: dnsRecordsType may only be set to External diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-TechPreviewNoUpgrade.crd.yaml deleted file mode 100644 index f176deea6e..0000000000 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-TechPreviewNoUpgrade.crd.yaml +++ /dev/null @@ -1,3324 +0,0 @@ -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" - 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. - - The ARN must follow the format: arn::iam:::role/, where: - is the AWS partition (aws, aws-cn, aws-us-gov, or aws-eusc), - is a 12-digit numeric identifier for the AWS account, - is the IAM role name. - type: string - x-kubernetes-validations: - - message: 'privateZoneIAMRole must be a valid AWS - IAM role ARN in the format: arn::iam:::role/' - rule: matches(self, '^arn:(aws|aws-cn|aws-us-gov|aws-eusc):iam::[0-9]{12}:role/.*$') - 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", "IBMCloud", "KubeVirt", "EquinixMetal", - "PowerVS", "AlibabaCloud", "Nutanix", "External", 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. - Up to 3 vCenters are supported. - Once the cluster has been installed, you are unable to change the current number of defined - vCenters except when 1.) the cluster has been upgraded from a version of OpenShift - where the vsphere platform spec was not present or 2.) in TechPreview you are able to add and - remove vCenters but may not remove all vCenters. 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: 1 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: Cannot add and remove vCenters at the same - time - rule: 'size(self) >= size(oldSelf) ? oldSelf.all(x, - self.exists(y, y.server == x.server)) : true' - - message: Cannot add and remove vCenters at the same - time - rule: 'size(self) < size(oldSelf) ? self.all(x, - oldSelf.exists(y, y.server == x.server)) : true' - - message: vcenters must have unique server values - rule: self.all(x, self.exists_one(y, y.server == - x.server)) - 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)' - type: object - x-kubernetes-validations: - - message: vcenters is required once set and cannot be removed - rule: 'oldSelf.?vsphere.vcenters.hasValue() ? self.?vsphere.vcenters.hasValue() - : 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. - The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes - that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum. - 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/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index de2a65dfa3..9f73ad1275 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -62,6 +62,18 @@ spec: description: baseOSExtensionsContainerImage is the matching extensions container for the new-format container type: string + bgpVIPPeersJSON: + description: |- + bgpVIPPeersJSON carries the BGP VIP peer configuration (the config.json + payload of the bgp-vip-config ConfigMap) for rendering the frr-k8s + static pod peer file on control plane nodes. Only set when BGP-based + VIP management is enabled. + When omitted, BGP-based VIP management is not configured and no + frr-k8s peer file is rendered. + When set, the value must be between 1 and 65536 characters long. + maxLength: 65536 + minLength: 1 + type: string cloudProviderCAData: description: cloudProviderCAData specifies the cloud provider CA data format: byte @@ -2082,6 +2094,24 @@ spec: datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string + vipManagement: + description: |- + vipManagement indicates which VIP management mechanism is active + on this cluster. + Allowed values are `Keepalived`, `BGP`, and omitted. + When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + deployed as static pods to advertise VIPs via BGP, replacing the + default keepalived/VRRP mechanism. + When set to `Keepalived`, the default keepalived-based VIP + management is used. + When omitted, the default keepalived-based VIP management is used. + enum: + - Keepalived + - BGP + type: string + x-kubernetes-validations: + - message: vipManagement is immutable once set + rule: oldSelf == '' || self == oldSelf type: object x-kubernetes-validations: - message: dnsRecordsType may only be set to External diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 7bf1e60dfa..ff10a45a5b 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -62,6 +62,18 @@ spec: description: baseOSExtensionsContainerImage is the matching extensions container for the new-format container type: string + bgpVIPPeersJSON: + description: |- + bgpVIPPeersJSON carries the BGP VIP peer configuration (the config.json + payload of the bgp-vip-config ConfigMap) for rendering the frr-k8s + static pod peer file on control plane nodes. Only set when BGP-based + VIP management is enabled. + When omitted, BGP-based VIP management is not configured and no + frr-k8s peer file is rendered. + When set, the value must be between 1 and 65536 characters long. + maxLength: 65536 + minLength: 1 + type: string cloudProviderCAData: description: cloudProviderCAData specifies the cloud provider CA data format: byte @@ -2082,6 +2094,24 @@ spec: datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string + vipManagement: + description: |- + vipManagement indicates which VIP management mechanism is active + on this cluster. + Allowed values are `Keepalived`, `BGP`, and omitted. + When set to `BGP`, kube-vip (Routing Table Mode) and frr-k8s are + deployed as static pods to advertise VIPs via BGP, replacing the + default keepalived/VRRP mechanism. + When set to `Keepalived`, the default keepalived-based VIP + management is used. + When omitted, the default keepalived-based VIP management is used. + enum: + - Keepalived + - BGP + type: string + x-kubernetes-validations: + - message: vipManagement is immutable once set + rule: oldSelf == '' || self == oldSelf type: object x-kubernetes-validations: - message: dnsRecordsType may only be set to External diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-TechPreviewNoUpgrade.crd.yaml similarity index 99% rename from vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml rename to vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-TechPreviewNoUpgrade.crd.yaml index 51b3d3ceca..0d318c38c1 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-TechPreviewNoUpgrade.crd.yaml @@ -4,6 +4,7 @@ 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: diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml index 4baab07508..a7866043ce 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml @@ -32,8 +32,8 @@ controllerconfigs.machineconfiguration.openshift.io: - AWSClusterHostedDNSInstall - AWSDualStackInstall - AWSEuropeanSovereignCloudInstall - - AzureClusterHostedDNSInstall - AzureDualStackInstall + - BGPBasedVIPManagement - DualReplica - DyanmicServiceEndpointIBMCloud - MutableTopology diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.swagger_doc_generated.go index aac65c9acb..198c2b9a6d 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.swagger_doc_generated.go @@ -162,6 +162,7 @@ var map_ControllerConfigSpec = map[string]string{ "pullSecret": "pullSecret is the default pull secret that needs to be installed on all machines.", "internalRegistryPullSecret": "internalRegistryPullSecret is the pull secret for the internal registry, used by rpm-ostree to pull images from the internal registry if present", "images": "images is map of images that are used by the controller to render templates under ./templates/", + "bgpVIPPeersJSON": "bgpVIPPeersJSON carries the BGP VIP peer configuration (the config.json payload of the bgp-vip-config ConfigMap) for rendering the frr-k8s static pod peer file on control plane nodes. Only set when BGP-based VIP management is enabled. When omitted, BGP-based VIP management is not configured and no frr-k8s peer file is rendered. When set, the value must be between 1 and 65536 characters long.", "baseOSContainerImage": "baseOSContainerImage is the new-format container image for operating system updates.", "baseOSExtensionsContainerImage": "baseOSExtensionsContainerImage is the matching extensions container for the new-format container", "osImageURL": "osImageURL is the old-format container image that contains the OS update payload.", diff --git a/vendor/github.com/openshift/api/operator/v1/types_authentication.go b/vendor/github.com/openshift/api/operator/v1/types_authentication.go index 4d0e9f6d68..55fc62a791 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_authentication.go +++ b/vendor/github.com/openshift/api/operator/v1/types_authentication.go @@ -33,6 +33,94 @@ type Authentication struct { type AuthenticationSpec struct { OperatorSpec `json:",inline"` + + // proxy configures proxy settings for outbound connections made + // by the authentication stack. When set, it replaces the + // cluster-wide proxy (proxy.config.openshift.io/cluster) + // entirely for authentication — individual fields are not + // inherited from the cluster-wide configuration. When omitted, + // the cluster-wide proxy is used if configured; otherwise no + // proxy is used. + // +openshift:enable:FeatureGate=AuthenticationComponentProxy + // +optional + Proxy AuthenticationProxyConfig `json:"proxy,omitzero"` +} + +// AuthenticationProxyConfig holds proxy configuration scoped to +// authentication components (the OAuth server and the cluster +// authentication operator). +// +kubebuilder:validation:MinProperties=1 +// +kubebuilder:validation:XValidation:rule="has(self.httpProxy) || has(self.httpsProxy)",message="at least one of httpProxy or httpsProxy must be specified" +type AuthenticationProxyConfig struct { + // httpProxy is the URL of the proxy for HTTP requests. + // Must be a valid URL with http or https scheme, a non-empty + // hostname, and no path, query parameters, or fragment. + // Userinfo (e.g. user:password@host) is allowed for proxy + // authentication. Maximum length is 2048 characters. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +kubebuilder:validation:XValidation:rule="isURL(self)",message="httpProxy must be a valid URL" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getScheme() in ['http', 'https']",message="httpProxy must use http or https scheme" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || size(url(self).getHostname()) > 0",message="httpProxy must contain a hostname" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getEscapedPath() == '' || url(self).getEscapedPath() == '/'",message="httpProxy must not contain a path" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getQuery().size() == 0",message="httpProxy must not contain query parameters" + // +kubebuilder:validation:XValidation:rule="!self.matches('.*#.*')",message="httpProxy must not contain a fragment" + // +optional + HTTPProxy string `json:"httpProxy,omitempty"` + + // httpsProxy is the URL of the proxy for HTTPS requests. + // Must be a valid URL with http or https scheme, a non-empty + // hostname, and no path, query parameters, or fragment. + // Userinfo (e.g. user:password@host) is allowed for proxy + // authentication. Maximum length is 2048 characters. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +kubebuilder:validation:XValidation:rule="isURL(self)",message="httpsProxy must be a valid URL" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getScheme() in ['http', 'https']",message="httpsProxy must use http or https scheme" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || size(url(self).getHostname()) > 0",message="httpsProxy must contain a hostname" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getEscapedPath() == '' || url(self).getEscapedPath() == '/'",message="httpsProxy must not contain a path" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getQuery().size() == 0",message="httpsProxy must not contain query parameters" + // +kubebuilder:validation:XValidation:rule="!self.matches('.*#.*')",message="httpsProxy must not contain a fragment" + // +optional + HTTPSProxy string `json:"httpsProxy,omitempty"` + + // noProxy is a list of hostnames and/or CIDRs and/or IPs for which + // the proxy should not be used. Must contain at least one entry + // when set. Each entry must be between 1 and 253 characters long + // and at most 64 entries are allowed. Duplicate + // entries are not permitted. Entries that are not valid hostnames, + // CIDRs, or IPs are silently ignored. Cluster-internal defaults + // (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + // automatically and do not need to be included. + // +listType=set + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=64 + // +kubebuilder:validation:items:MinLength=1 + // +kubebuilder:validation:items:MaxLength=253 + // +optional + NoProxy []string `json:"noProxy,omitempty"` + + // trustedCA is a reference to a ConfigMap in the openshift-config + // namespace containing a CA certificate bundle under the key + // "ca-bundle.crt". This bundle is appended to the system trust store + // used by authentication components for proxy TLS connections. + // When omitted, only the system trust store is used. + // +optional + TrustedCA AuthenticationConfigMapReference `json:"trustedCA,omitzero"` +} + +// AuthenticationConfigMapReference references a ConfigMap in the +// openshift-config namespace. +type AuthenticationConfigMapReference struct { + // name is the metadata.name of the referenced ConfigMap. + // Must be a valid DNS subdomain name (RFC 1123): at most 253 + // characters, only lowercase alphanumeric characters, '-' or + // '.', starting and ending with an alphanumeric character. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="name must be a valid DNS subdomain name: contain no more than 253 characters, contain only lowercase alphanumeric characters, '-' or '.', and start and end with an alphanumeric character" + // +required + Name string `json:"name,omitempty"` } type AuthenticationStatus struct { diff --git a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go index 51ecab70c8..fca2c808d3 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go +++ b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go @@ -506,16 +506,28 @@ type SecretsStoreSecretRotation struct { // CustomSecretRotation holds configuration for custom secret rotation behavior. // +kubebuilder:validation:MinProperties=1 type CustomSecretRotation struct { - // rotationPollIntervalSeconds is the minimum time in seconds between secret - // rotation attempts. The driver skips provider calls if less than this interval - // has elapsed since the last successful rotation. + // minimumRefreshAge is the minimum time in seconds between secret + // rotation attempts. Each time kubelet calls NodePublishVolume, the driver + // checks whether this interval has elapsed since the last successful provider + // call. If it has, the driver contacts the secret provider to fetch the latest + // secret values and updates the mounted volume. + // Setting this value below the kubelet syncFrequency (default: 1 minute) + // has no additional effect on the actual rotation cadence. // Must be at least 1 second and no more than 31560000 seconds (~1 year). // When omitted, this means no opinion and the platform is left to choose a // reasonable default, which is subject to change over time. // +kubebuilder:validation:Minimum=1 // +kubebuilder:validation:Maximum=31560000 // +optional - RotationPollIntervalSeconds int32 `json:"rotationPollIntervalSeconds,omitempty"` + MinimumRefreshAge int32 `json:"minimumRefreshAge,omitempty"` + + // --- TOMBSTONE --- + // rotationPollIntervalSeconds was the previous name for minimumRefreshAge. + // The field has been renamed to better reflect its semantics. + // The JSON key is reserved to prevent reuse. + // + // +optional + // RotationPollIntervalSeconds int32 `json:"rotationPollIntervalSeconds,omitempty"` } // SecretsStoreTokenRequest specifies a service account token audience configuration diff --git a/vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go b/vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go index 52bfdede3e..2d442d4b41 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go +++ b/vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go @@ -385,6 +385,31 @@ type IngressControllerSpec struct { // +kubebuilder:default:="Continue" // +default="Continue" ClosedClientConnectionPolicy IngressControllerClosedClientConnectionPolicy `json:"closedClientConnectionPolicy,omitempty"` + + // haproxyVersion specifies the HAProxy version to use for this + // IngressController. + // + // OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + // HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + // release introduces a new default HAProxy version, that HAProxy version + // becomes available as a pinnable value in subsequent OpenShift releases, + // providing a smooth migration path for administrators who want to defer + // HAProxy upgrades. + // + // Valid values for OpenShift 5.0: + // - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + // - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + // upgrades to future OpenShift releases + // - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + // be dropped in the next OpenShift release) + // + // If a specific HAProxy version is set and would become unsupported in a + // target cluster upgrade, a preflight check will block the cluster upgrade + // until this field is updated to unset or a supported version. + // + // +optional + // +openshift:enable:FeatureGate=IngressControllerMultipleHAProxyVersions + HAProxyVersion HAProxyVersion `json:"haproxyVersion,omitempty"` } // httpCompressionPolicy turns on compression for the specified MIME types. @@ -2263,6 +2288,19 @@ type IngressControllerStatus struct { // routeSelector is the actual routeSelector in use. // +optional RouteSelector *metav1.LabelSelector `json:"routeSelector,omitempty"` + + // effectiveHAProxyVersion reports the HAProxy version currently in use by + // this IngressController. This reflects the resolved value of the + // spec.haproxyVersion field. When omitted, the effective value has not yet + // been resolved by the operator or the feature is not enabled for this cluster. + // + // Examples for OpenShift 5.0: + // - "3.2": Using HAProxy 3.2 + // - "2.8": Using HAProxy 2.8 + // + // +optional + // +openshift:enable:FeatureGate=IngressControllerMultipleHAProxyVersions + EffectiveHAProxyVersion HAProxyVersion `json:"effectiveHAProxyVersion,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -2331,3 +2369,18 @@ const ( // server's response regardless of the client having closed the connection. IngressControllerClosedClientConnectionPolicyContinue IngressControllerClosedClientConnectionPolicy = "Continue" ) + +// HAProxyVersion is a string representing a HAProxy minor version in "X.Y" +// format. The allowed values are constrained by enum validation and vary by +// OpenShift release. +// +// +kubebuilder:validation:Enum="2.8";"3.2" +type HAProxyVersion string + +const ( + // HAProxyVersion28 represents HAProxy 2.8, shipped with OpenShift 4.22. + HAProxyVersion28 HAProxyVersion = "2.8" + + // HAProxyVersion32 represents HAProxy 3.2, introduced in OpenShift 5.0. + HAProxyVersion32 HAProxyVersion = "3.2" +) diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml index 3d5beb8c3c..a1d80bd5d9 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml index 9c6a6de7db..9e8ba13fd5 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml index 196a05d604..03b3daf02a 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_console_01_consoles.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_console_01_consoles.crd.yaml index f6f31fb401..ee5f83e6c5 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_console_01_consoles.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_console_01_consoles.crd.yaml @@ -531,7 +531,7 @@ spec: x-kubernetes-list-type: atomic type: object group: - description: Group is the API Group of the + description: group is the API Group of the Resource. "*" means all. type: string labelSelector: @@ -584,32 +584,32 @@ spec: x-kubernetes-list-type: atomic type: object name: - description: Name is the name of the resource + description: name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. type: string namespace: description: |- - Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces "" (empty) is defaulted for LocalSubjectAccessReviews "" (empty) is empty for cluster-scoped resources "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview type: string resource: - description: Resource is one of the existing + description: resource is one of the existing resource types. "*" means all. type: string subresource: - description: Subresource is one of the existing + description: subresource is one of the existing resource types. "" means none. type: string verb: - description: 'Verb is a kubernetes resource + description: 'verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all.' type: string version: - description: Version is the API Version of + description: version is the API Version of the Resource. "*" means all. type: string type: object @@ -678,7 +678,7 @@ spec: x-kubernetes-list-type: atomic type: object group: - description: Group is the API Group of the + description: group is the API Group of the Resource. "*" means all. type: string labelSelector: @@ -731,32 +731,32 @@ spec: x-kubernetes-list-type: atomic type: object name: - description: Name is the name of the resource + description: name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. type: string namespace: description: |- - Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces "" (empty) is defaulted for LocalSubjectAccessReviews "" (empty) is empty for cluster-scoped resources "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview type: string resource: - description: Resource is one of the existing + description: resource is one of the existing resource types. "*" means all. type: string subresource: - description: Subresource is one of the existing + description: subresource is one of the existing resource types. "" means none. type: string verb: - description: 'Verb is a kubernetes resource + description: 'verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all.' type: string version: - description: Version is the API Version of + description: version is the API Version of the Resource. "*" means all. type: string type: object diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml index 02b95f82fe..6c5120e1a6 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml index 56859fc15a..2ea91955ba 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml index f2be3b2eeb..d30ab1abe9 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml index de5190a522..118bcd135d 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml index 51ffcfd974..bd6f1a14d8 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml index 66b935c916..3a55f7bdf0 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml @@ -924,6 +924,32 @@ spec: required: - type type: object + haproxyVersion: + description: |- + haproxyVersion specifies the HAProxy version to use for this + IngressController. + + OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + release introduces a new default HAProxy version, that HAProxy version + becomes available as a pinnable value in subsequent OpenShift releases, + providing a smooth migration path for administrators who want to defer + HAProxy upgrades. + + Valid values for OpenShift 5.0: + - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + upgrades to future OpenShift releases + - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + be dropped in the next OpenShift release) + + If a specific HAProxy version is set and would become unsupported in a + target cluster upgrade, a preflight check will block the cluster upgrade + until this field is updated to unset or a supported version. + enum: + - "2.8" + - "3.2" + type: string httpCompression: description: |- httpCompression defines a policy for HTTP traffic compression. @@ -2601,6 +2627,20 @@ spec: domain: description: domain is the actual domain in use. type: string + effectiveHAProxyVersion: + description: |- + effectiveHAProxyVersion reports the HAProxy version currently in use by + this IngressController. This reflects the resolved value of the + spec.haproxyVersion field. When omitted, the effective value has not yet + been resolved by the operator or the feature is not enabled for this cluster. + + Examples for OpenShift 5.0: + - "3.2": Using HAProxy 3.2 + - "2.8": Using HAProxy 2.8 + enum: + - "2.8" + - "3.2" + type: string endpointPublishingStrategy: description: endpointPublishingStrategy is the actual strategy in use. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml index a9600ab839..0a638843f5 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml @@ -924,6 +924,32 @@ spec: required: - type type: object + haproxyVersion: + description: |- + haproxyVersion specifies the HAProxy version to use for this + IngressController. + + OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + release introduces a new default HAProxy version, that HAProxy version + becomes available as a pinnable value in subsequent OpenShift releases, + providing a smooth migration path for administrators who want to defer + HAProxy upgrades. + + Valid values for OpenShift 5.0: + - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + upgrades to future OpenShift releases + - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + be dropped in the next OpenShift release) + + If a specific HAProxy version is set and would become unsupported in a + target cluster upgrade, a preflight check will block the cluster upgrade + until this field is updated to unset or a supported version. + enum: + - "2.8" + - "3.2" + type: string httpCompression: description: |- httpCompression defines a policy for HTTP traffic compression. @@ -2601,6 +2627,20 @@ spec: domain: description: domain is the actual domain in use. type: string + effectiveHAProxyVersion: + description: |- + effectiveHAProxyVersion reports the HAProxy version currently in use by + this IngressController. This reflects the resolved value of the + spec.haproxyVersion field. When omitted, the effective value has not yet + been resolved by the operator or the feature is not enabled for this cluster. + + Examples for OpenShift 5.0: + - "3.2": Using HAProxy 3.2 + - "2.8": Using HAProxy 2.8 + enum: + - "2.8" + - "3.2" + type: string endpointPublishingStrategy: description: endpointPublishingStrategy is the actual strategy in use. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml index ea37a2261d..27dcb3bab6 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml @@ -924,6 +924,32 @@ spec: required: - type type: object + haproxyVersion: + description: |- + haproxyVersion specifies the HAProxy version to use for this + IngressController. + + OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + release introduces a new default HAProxy version, that HAProxy version + becomes available as a pinnable value in subsequent OpenShift releases, + providing a smooth migration path for administrators who want to defer + HAProxy upgrades. + + Valid values for OpenShift 5.0: + - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + upgrades to future OpenShift releases + - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + be dropped in the next OpenShift release) + + If a specific HAProxy version is set and would become unsupported in a + target cluster upgrade, a preflight check will block the cluster upgrade + until this field is updated to unset or a supported version. + enum: + - "2.8" + - "3.2" + type: string httpCompression: description: |- httpCompression defines a policy for HTTP traffic compression. @@ -2601,6 +2627,20 @@ spec: domain: description: domain is the actual domain in use. type: string + effectiveHAProxyVersion: + description: |- + effectiveHAProxyVersion reports the HAProxy version currently in use by + this IngressController. This reflects the resolved value of the + spec.haproxyVersion field. When omitted, the effective value has not yet + been resolved by the operator or the feature is not enabled for this cluster. + + Examples for OpenShift 5.0: + - "3.2": Using HAProxy 3.2 + - "2.8": Using HAProxy 2.8 + enum: + - "2.8" + - "3.2" + type: string endpointPublishingStrategy: description: endpointPublishingStrategy is the actual strategy in use. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go index 0a6726b199..3c244a9867 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go @@ -285,6 +285,22 @@ func (in *Authentication) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationConfigMapReference) DeepCopyInto(out *AuthenticationConfigMapReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationConfigMapReference. +func (in *AuthenticationConfigMapReference) DeepCopy() *AuthenticationConfigMapReference { + if in == nil { + return nil + } + out := new(AuthenticationConfigMapReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationList) DeepCopyInto(out *AuthenticationList) { *out = *in @@ -318,10 +334,33 @@ func (in *AuthenticationList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationProxyConfig) DeepCopyInto(out *AuthenticationProxyConfig) { + *out = *in + if in.NoProxy != nil { + in, out := &in.NoProxy, &out.NoProxy + *out = make([]string, len(*in)) + copy(*out, *in) + } + out.TrustedCA = in.TrustedCA + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationProxyConfig. +func (in *AuthenticationProxyConfig) DeepCopy() *AuthenticationProxyConfig { + if in == nil { + return nil + } + out := new(AuthenticationProxyConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationSpec) DeepCopyInto(out *AuthenticationSpec) { *out = *in in.OperatorSpec.DeepCopyInto(&out.OperatorSpec) + in.Proxy.DeepCopyInto(&out.Proxy) return } diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml index 9edb02ec6e..aab9e3564f 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml @@ -6,6 +6,7 @@ authentications.operator.openshift.io: Capability: "" Category: "" FeatureGates: + - AuthenticationComponentProxy - KMSEncryption FilenameOperatorName: authentication FilenameOperatorOrdering: "01" @@ -179,6 +180,7 @@ ingresscontrollers.operator.openshift.io: Category: "" FeatureGates: - IngressControllerDynamicConfigurationManager + - IngressControllerMultipleHAProxyVersions - TLSGroupPreferences FilenameOperatorName: ingress FilenameOperatorOrdering: "00" diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go index c6a047d2ce..271665a7ec 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go @@ -65,11 +65,21 @@ func (in Authentication) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.Authentication" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in AuthenticationConfigMapReference) OpenAPIModelName() string { + return "com.github.openshift.api.operator.v1.AuthenticationConfigMapReference" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in AuthenticationList) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.AuthenticationList" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in AuthenticationProxyConfig) OpenAPIModelName() string { + return "com.github.openshift.api.operator.v1.AuthenticationProxyConfig" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in AuthenticationSpec) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.AuthenticationSpec" diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go index a79189ffc2..114b5c7a68 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go @@ -118,6 +118,15 @@ func (Authentication) SwaggerDoc() map[string]string { return map_Authentication } +var map_AuthenticationConfigMapReference = map[string]string{ + "": "AuthenticationConfigMapReference references a ConfigMap in the openshift-config namespace.", + "name": "name is the metadata.name of the referenced ConfigMap. Must be a valid DNS subdomain name (RFC 1123): at most 253 characters, only lowercase alphanumeric characters, '-' or '.', starting and ending with an alphanumeric character.", +} + +func (AuthenticationConfigMapReference) SwaggerDoc() map[string]string { + return map_AuthenticationConfigMapReference +} + var map_AuthenticationList = map[string]string{ "": "AuthenticationList is a collection of items\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", "metadata": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", @@ -127,6 +136,26 @@ func (AuthenticationList) SwaggerDoc() map[string]string { return map_AuthenticationList } +var map_AuthenticationProxyConfig = map[string]string{ + "": "AuthenticationProxyConfig holds proxy configuration scoped to authentication components (the OAuth server and the cluster authentication operator).", + "httpProxy": "httpProxy is the URL of the proxy for HTTP requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + "httpsProxy": "httpsProxy is the URL of the proxy for HTTPS requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + "noProxy": "noProxy is a list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. Must contain at least one entry when set. Each entry must be between 1 and 253 characters long and at most 64 entries are allowed. Duplicate entries are not permitted. Entries that are not valid hostnames, CIDRs, or IPs are silently ignored. Cluster-internal defaults (.cluster.local, .svc, 127.0.0.1, localhost) are always appended automatically and do not need to be included.", + "trustedCA": "trustedCA is a reference to a ConfigMap in the openshift-config namespace containing a CA certificate bundle under the key \"ca-bundle.crt\". This bundle is appended to the system trust store used by authentication components for proxy TLS connections. When omitted, only the system trust store is used.", +} + +func (AuthenticationProxyConfig) SwaggerDoc() map[string]string { + return map_AuthenticationProxyConfig +} + +var map_AuthenticationSpec = map[string]string{ + "proxy": "proxy configures proxy settings for outbound connections made by the authentication stack. When set, it replaces the cluster-wide proxy (proxy.config.openshift.io/cluster) entirely for authentication — individual fields are not inherited from the cluster-wide configuration. When omitted, the cluster-wide proxy is used if configured; otherwise no proxy is used.", +} + +func (AuthenticationSpec) SwaggerDoc() map[string]string { + return map_AuthenticationSpec +} + var map_AuthenticationStatus = map[string]string{ "oauthAPIServer": "oauthAPIServer holds status specific only to oauth-apiserver", } @@ -569,8 +598,8 @@ func (ClusterCSIDriverStatus) SwaggerDoc() map[string]string { } var map_CustomSecretRotation = map[string]string{ - "": "CustomSecretRotation holds configuration for custom secret rotation behavior.", - "rotationPollIntervalSeconds": "rotationPollIntervalSeconds is the minimum time in seconds between secret rotation attempts. The driver skips provider calls if less than this interval has elapsed since the last successful rotation. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time.", + "": "CustomSecretRotation holds configuration for custom secret rotation behavior.", + "minimumRefreshAge": "minimumRefreshAge is the minimum time in seconds between secret rotation attempts. Each time kubelet calls NodePublishVolume, the driver checks whether this interval has elapsed since the last successful provider call. If it has, the driver contacts the secret provider to fetch the latest secret values and updates the mounted volume. Setting this value below the kubelet syncFrequency (default: 1 minute) has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time.", } func (CustomSecretRotation) SwaggerDoc() map[string]string { @@ -1143,6 +1172,7 @@ var map_IngressControllerSpec = map[string]string{ "httpCompression": "httpCompression defines a policy for HTTP traffic compression. By default, there is no HTTP compression.", "idleConnectionTerminationPolicy": "idleConnectionTerminationPolicy maps directly to HAProxy's idle-close-on-response option and controls whether HAProxy keeps idle frontend connections open during a soft stop (router reload).\n\nAllowed values for this field are \"Immediate\" and \"Deferred\". The default value is \"Immediate\".\n\nWhen set to \"Immediate\", idle connections are closed immediately during router reloads. This ensures immediate propagation of route changes but may impact clients sensitive to connection resets.\n\nWhen set to \"Deferred\", HAProxy will maintain idle connections during a soft reload instead of closing them immediately. These connections remain open until any of the following occurs:\n\n - A new request is received on the connection, in which\n case HAProxy handles it in the old process and closes\n the connection after sending the response.\n\n - HAProxy's `timeout http-keep-alive` duration expires.\n By default this is 300 seconds, but it can be changed\n using httpKeepAliveTimeout tuning option.\n\n - The client's keep-alive timeout expires, causing the\n client to close the connection.\n\nSetting Deferred can help prevent errors in clients or load balancers that do not properly handle connection resets. Additionally, this option allows you to retain the pre-2.4 HAProxy behaviour: in HAProxy version 2.2 (OpenShift versions < 4.14), maintaining idle connections during a soft reload was the default behaviour, but starting with HAProxy 2.4, the default changed to closing idle connections immediately.\n\nImportant Consideration:\n\n - Using Deferred will result in temporary inconsistencies\n for the first request on each persistent connection\n after a route update and router reload. This request\n will be processed by the old HAProxy process using its\n old configuration. Subsequent requests will use the\n updated configuration.\n\nOperational Considerations:\n\n - Keeping idle connections open during reloads may lead\n to an accumulation of old HAProxy processes if\n connections remain idle for extended periods,\n especially in environments where frequent reloads\n occur.\n\n - Consider monitoring the number of HAProxy processes in\n the router pods when Deferred is set.\n\n - You may need to enable or adjust the\n `ingress.operator.openshift.io/hard-stop-after`\n duration (configured via an annotation on the\n IngressController resource) in environments with\n frequent reloads to prevent resource exhaustion.", "closedClientConnectionPolicy": "closedClientConnectionPolicy controls how the IngressController behaves when the client closes the TCP connection while the TLS handshake or HTTP request is in progress. This option maps directly to HAProxy’s \"abortonclose\" option.\n\nValid values are: \"Abort\" and \"Continue\". The default value is \"Continue\".\n\nWhen set to \"Abort\", the router will stop processing the TLS handshake if it is in progress, and it will not send an HTTP request to the backend server if the request has not yet been sent when the client closes the connection.\n\nWhen set to \"Continue\", the router will complete the TLS handshake if it is in progress, or send an HTTP request to the backend server and wait for the backend server's response, regardless of whether the client has closed the connection.\n\nSetting \"Abort\" can help free CPU resources otherwise spent on TLS computation for connections the client has already closed, and can reduce request queue size, thereby reducing the load on saturated backend servers.\n\nImportant Considerations:\n\n - The default policy (\"Continue\") is HTTP-compliant, and requests\n for aborted client connections will still be served.\n Use the \"Continue\" policy to allow a client to send a request\n and then immediately close its side of the connection while\n still receiving a response on the half-closed connection.\n\n - When clients use keep-alive connections, the most common case for premature\n closure is when the user wants to cancel the transfer or when a timeout\n occurs. In that case, the \"Abort\" policy may be used to reduce resource consumption.\n\n - Using RSA keys larger than 2048 bits can significantly slow down\n TLS computations. Consider using the \"Abort\" policy to reduce CPU usage.", + "haproxyVersion": "haproxyVersion specifies the HAProxy version to use for this IngressController.\n\nOpenShift 5.0 introduces HAProxy 3.2 as its default version and supports HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift release introduces a new default HAProxy version, that HAProxy version becomes available as a pinnable value in subsequent OpenShift releases, providing a smooth migration path for administrators who want to defer HAProxy upgrades.\n\nValid values for OpenShift 5.0: - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) - \"3.2\": Explicitly pins HAProxy 3.2 for preservation during cluster\n upgrades to future OpenShift releases\n- \"2.8\": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will\n be dropped in the next OpenShift release)\n\nIf a specific HAProxy version is set and would become unsupported in a target cluster upgrade, a preflight check will block the cluster upgrade until this field is updated to unset or a supported version.", } func (IngressControllerSpec) SwaggerDoc() map[string]string { @@ -1160,6 +1190,7 @@ var map_IngressControllerStatus = map[string]string{ "observedGeneration": "observedGeneration is the most recent generation observed.", "namespaceSelector": "namespaceSelector is the actual namespaceSelector in use.", "routeSelector": "routeSelector is the actual routeSelector in use.", + "effectiveHAProxyVersion": "effectiveHAProxyVersion reports the HAProxy version currently in use by this IngressController. This reflects the resolved value of the spec.haproxyVersion field. When omitted, the effective value has not yet been resolved by the operator or the feature is not enabled for this cluster.\n\nExamples for OpenShift 5.0: - \"3.2\": Using HAProxy 3.2 - \"2.8\": Using HAProxy 2.8", } func (IngressControllerStatus) SwaggerDoc() map[string]string { diff --git a/vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go b/vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go index 719893f8a5..291cedc145 100644 --- a/vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go +++ b/vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go @@ -244,13 +244,24 @@ type ClusterAPIInstallerComponentSource struct { Image ClusterAPIInstallerComponentImage `json:"image,omitzero"` } -// ImageDigestFormat is a type that conforms to the format host[:port][/namespace]/name@sha256:. +// The image name validation regex is derived from the OCI distribution reference: +// https://github.com/distribution/reference/blob/main/regexp.go +// It matches: domainAndPort "/" remoteName +// +// domainAndPort = (domainName | "[" ipv6 "]") [ ":" port ] +// domainName = label ("." label)* +// label = alphanumeric, may contain hyphens but must start/end with [a-zA-Z0-9] +// remoteName = pathComponent ("/" pathComponent)* +// pathComponent = [a-z0-9]+ separated by ".", "_", "__", or "-"+ + +// ImageDigestFormat is a type that conforms to the format host[:port][/namespace[/namespace...]]/name@sha256:. +// The host may be a dotted domain name (including IPv4 addresses like 192.168.1.1), or an IPv6 address in brackets (e.g. [fd00::1]). // The digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. // The length of the field must be between 1 to 447 characters. // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=447 // +kubebuilder:validation:XValidation:rule=`(self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$'))`,message="the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" -// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$'))`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme" +// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))*|\\[(?:[a-fA-F0-9:]+)\\])(?::[0-9]+)?/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*)*$'))`,message="the OCI Image name should follow the host[:port][/namespace[/namespace...]]/name format, where host is a domain name, IPv4, or IPv6 address in brackets" type ImageDigestFormat string // ClusterAPIInstallerComponentImage defines an image source for a component. diff --git a/vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml b/vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml index 67d384d3eb..501ad52418 100644 --- a/vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml @@ -172,9 +172,10 @@ spec: 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-_.]*?$')) + - message: the OCI Image name should follow the host[:port][/namespace[/namespace...]]/name + format, where host is a domain name, IPv4, or + IPv6 address in brackets + rule: (self.split('@')[0].matches('^(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))*|\\[(?:[a-fA-F0-9:]+)\\])(?::[0-9]+)?/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*)*$')) required: - profile - ref diff --git a/vendor/github.com/openshift/api/osin/v1/types.go b/vendor/github.com/openshift/api/osin/v1/types.go index 35eb3ee8b0..3f3af3cfa5 100644 --- a/vendor/github.com/openshift/api/osin/v1/types.go +++ b/vendor/github.com/openshift/api/osin/v1/types.go @@ -80,6 +80,11 @@ type OAuthConfig struct { // templates allow you to customize pages like the login page. Templates *OAuthTemplates `json:"templates"` + + // proxyTrustedCA is an optional path to a PEM-encoded CA bundle used to + // verify connections to an HTTPS proxy during outbound IdP requests. + // When omitted, proxy connections use the system trust roots only. + ProxyTrustedCA string `json:"proxyTrustedCA,omitempty"` } // OAuthTemplates allow for customization of pages like the login page diff --git a/vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go index 890928a7a4..6594af9451 100644 --- a/vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go @@ -154,6 +154,7 @@ var map_OAuthConfig = map[string]string{ "sessionConfig": "sessionConfig hold information about configuring sessions.", "tokenConfig": "tokenConfig contains options for authorization and access tokens", "templates": "templates allow you to customize pages like the login page.", + "proxyTrustedCA": "proxyTrustedCA is an optional path to a PEM-encoded CA bundle used to verify connections to an HTTPS proxy during outbound IdP requests. When omitted, proxy connections use the system trust roots only.", } func (OAuthConfig) SwaggerDoc() map[string]string { diff --git a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go index 2ef36bbcf9..ec63689e72 100644 --- a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go +++ b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go @@ -10,6 +10,7 @@ import ( "encoding/binary" "fmt" "io" + "math" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/errors" @@ -117,7 +118,13 @@ func (o UnmarshalOptions) UnmarshalFrom(r Reader, m proto.Message) error { if maxSize == 0 { maxSize = defaultMaxSize } - if maxSize != -1 && size > uint64(maxSize) { + if maxSize == -1 { + // No limit specified: Just check that size fits into an integer, + // otherwise the make([]byte, size) call below will panic. + if size > math.MaxInt { + return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: math.MaxInt}, "") + } + } else if size > uint64(maxSize) { return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: uint64(maxSize)}, "") } diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/decode.go b/vendor/google.golang.org/protobuf/encoding/protojson/decode.go index 737d6876d5..1d6608dc7d 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/decode.go @@ -365,6 +365,10 @@ func unmarshalInt(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getInt(tok, bitSize) } return protoreflect.Value{}, false @@ -397,6 +401,10 @@ func unmarshalUint(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getUint(tok, bitSize) } return protoreflect.Value{}, false @@ -447,6 +455,10 @@ func unmarshalFloat(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getFloat(tok, bitSize) } return protoreflect.Value{}, false diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go index e9fe103943..d2eab46947 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go @@ -52,7 +52,10 @@ func wellKnownTypeMarshaler(name protoreflect.FullName) marshalFunc { case genid.FieldMask_message_name: return encoder.marshalFieldMask case genid.Empty_message_name: - return encoder.marshalEmpty + // The spec explicitly specifies that the Empty message + // is not considered to have any special JSON mapping: + // https://protobuf.dev/programming-guides/json/#any + return nil } } return nil diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go index b53805056a..20ec09e194 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go @@ -8,6 +8,7 @@ import ( "fmt" "unicode/utf8" + "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/text" "google.golang.org/protobuf/internal/errors" @@ -49,12 +50,19 @@ type UnmarshalOptions struct { protoregistry.MessageTypeResolver protoregistry.ExtensionTypeResolver } + + // RecursionLimit limits how deeply messages may be nested. + // If zero, a default limit is applied. + RecursionLimit int } // Unmarshal reads the given []byte and populates the given [proto.Message] // using options in the UnmarshalOptions object. // The provided message must be mutable (e.g., a non-nil pointer to a message). func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error { + if o.RecursionLimit == 0 { + o.RecursionLimit = protowire.DefaultRecursionLimit + } return o.unmarshal(b, m) } @@ -102,8 +110,14 @@ func (d decoder) syntaxError(pos int, f string, x ...any) error { return errors.New(head+f, x...) } +var errRecursionDepth = errors.New("exceeded maximum recursion depth") + // unmarshalMessage unmarshals into the given protoreflect.Message. func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) error { + if d.opts.RecursionLimit--; d.opts.RecursionLimit < 0 { + return errRecursionDepth + } + messageDesc := m.Descriptor() if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { return errors.New("no support for proto1 MessageSets") @@ -437,6 +451,10 @@ func (d decoder) unmarshalList(fd protoreflect.FieldDescriptor, list protoreflec // unmarshalMap unmarshals into given protoreflect.Map. A map value is a // textproto message containing {key: , value: }. func (d decoder) unmarshalMap(fd protoreflect.FieldDescriptor, mmap protoreflect.Map) error { + if d.opts.RecursionLimit--; d.opts.RecursionLimit < 0 { + return errRecursionDepth + } + // Determine ahead whether map entry is a scalar type or a message type in // order to call the appropriate unmarshalMapValue func inside // unmarshalMapEntry. diff --git a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go index 87e46bd4df..0b0dfacbe5 100644 --- a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go +++ b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go @@ -83,12 +83,13 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { case protoreflect.FileImports: for i := 0; i < vs.Len(); i++ { var rs records - rv := reflect.ValueOf(vs.Get(i)) - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("IsPublic"), "IsPublic"}, - {rv.MethodByName("IsWeak"), "IsWeak"}, + fi := vs.Get(i) + rv := reflect.ValueOf(fi) + rs.Append(rv, []attrAndName{ + {fi.Path(), "Path"}, + {fi.Package(), "Package"}, + {fi.IsPublic, "IsPublic"}, + {fi.IsWeak, "IsWeak"}, }...) ss = append(ss, "{"+rs.Join()+"}") } @@ -104,9 +105,9 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { } } -type methodAndName struct { - method reflect.Value - name string +type attrAndName struct { + attr any + name string } func FormatDesc(s fmt.State, r rune, t protoreflect.Descriptor) { @@ -126,58 +127,58 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu start = rt.Name() + "{" } - _, isFile := t.(protoreflect.FileDescriptor) + fd, isFile := t.(protoreflect.FileDescriptor) rs := records{ allowMulti: allowMulti, record: record, } if t.IsPlaceholder() { if isFile { - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("IsPlaceholder"), "IsPlaceholder"}, + rs.Append(rv, []attrAndName{ + {fd.Path(), "Path"}, + {fd.Package(), "Package"}, + {fd.IsPlaceholder(), "IsPlaceholder"}, }...) } else { - rs.Append(rv, []methodAndName{ - {rv.MethodByName("FullName"), "FullName"}, - {rv.MethodByName("IsPlaceholder"), "IsPlaceholder"}, + rs.Append(rv, []attrAndName{ + {t.FullName(), "FullName"}, + {t.IsPlaceholder(), "IsPlaceholder"}, }...) } } else { switch { case isFile: - rs.Append(rv, methodAndName{rv.MethodByName("Syntax"), "Syntax"}) + rs.Append(rv, attrAndName{fd.Syntax(), "Syntax"}) case isRoot: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Syntax"), "Syntax"}, - {rv.MethodByName("FullName"), "FullName"}, + rs.Append(rv, []attrAndName{ + {t.Syntax(), "Syntax"}, + {t.FullName(), "FullName"}, }...) default: - rs.Append(rv, methodAndName{rv.MethodByName("Name"), "Name"}) + rs.Append(rv, attrAndName{t.Name(), "Name"}) } switch t := t.(type) { case protoreflect.FieldDescriptor: - accessors := []methodAndName{ - {rv.MethodByName("Number"), "Number"}, - {rv.MethodByName("Cardinality"), "Cardinality"}, - {rv.MethodByName("Kind"), "Kind"}, - {rv.MethodByName("HasJSONName"), "HasJSONName"}, - {rv.MethodByName("JSONName"), "JSONName"}, - {rv.MethodByName("HasPresence"), "HasPresence"}, - {rv.MethodByName("IsExtension"), "IsExtension"}, - {rv.MethodByName("IsPacked"), "IsPacked"}, - {rv.MethodByName("IsWeak"), "IsWeak"}, - {rv.MethodByName("IsList"), "IsList"}, - {rv.MethodByName("IsMap"), "IsMap"}, - {rv.MethodByName("MapKey"), "MapKey"}, - {rv.MethodByName("MapValue"), "MapValue"}, - {rv.MethodByName("HasDefault"), "HasDefault"}, - {rv.MethodByName("Default"), "Default"}, - {rv.MethodByName("ContainingOneof"), "ContainingOneof"}, - {rv.MethodByName("ContainingMessage"), "ContainingMessage"}, - {rv.MethodByName("Message"), "Message"}, - {rv.MethodByName("Enum"), "Enum"}, + accessors := []attrAndName{ + {t.Number(), "Number"}, + {t.Cardinality(), "Cardinality"}, + {t.Kind(), "Kind"}, + {t.HasJSONName(), "HasJSONName"}, + {t.JSONName(), "JSONName"}, + {t.HasPresence(), "HasPresence"}, + {t.IsExtension(), "IsExtension"}, + {t.IsPacked(), "IsPacked"}, + {t.IsWeak(), "IsWeak"}, + {t.IsList(), "IsList"}, + {t.IsMap(), "IsMap"}, + {t.MapKey(), "MapKey"}, + {t.MapValue(), "MapValue"}, + {t.HasDefault(), "HasDefault"}, + {t.Default(), "Default"}, + {t.ContainingOneof(), "ContainingOneof"}, + {t.ContainingMessage(), "ContainingMessage"}, + {t.Message(), "Message"}, + {t.Enum(), "Enum"}, } for _, s := range accessors { switch s.name { @@ -223,58 +224,54 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu } case protoreflect.FileDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("Imports"), "Imports"}, - {rv.MethodByName("Messages"), "Messages"}, - {rv.MethodByName("Enums"), "Enums"}, - {rv.MethodByName("Extensions"), "Extensions"}, - {rv.MethodByName("Services"), "Services"}, + rs.Append(rv, []attrAndName{ + {t.Path(), "Path"}, + {t.Package(), "Package"}, + {t.Imports(), "Imports"}, + {t.Messages(), "Messages"}, + {t.Enums(), "Enums"}, + {t.Extensions(), "Extensions"}, + {t.Services(), "Services"}, }...) case protoreflect.MessageDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("IsMapEntry"), "IsMapEntry"}, - {rv.MethodByName("Fields"), "Fields"}, - {rv.MethodByName("Oneofs"), "Oneofs"}, - {rv.MethodByName("ReservedNames"), "ReservedNames"}, - {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, - {rv.MethodByName("RequiredNumbers"), "RequiredNumbers"}, - {rv.MethodByName("ExtensionRanges"), "ExtensionRanges"}, - {rv.MethodByName("Messages"), "Messages"}, - {rv.MethodByName("Enums"), "Enums"}, - {rv.MethodByName("Extensions"), "Extensions"}, + rs.Append(rv, []attrAndName{ + {t.IsMapEntry(), "IsMapEntry"}, + {t.Fields(), "Fields"}, + {t.Oneofs(), "Oneofs"}, + {t.ReservedNames(), "ReservedNames"}, + {t.ReservedRanges(), "ReservedRanges"}, + {t.RequiredNumbers(), "RequiredNumbers"}, + {t.ExtensionRanges(), "ExtensionRanges"}, + {t.Messages(), "Messages"}, + {t.Enums(), "Enums"}, + {t.Extensions(), "Extensions"}, }...) case protoreflect.EnumDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Values"), "Values"}, - {rv.MethodByName("ReservedNames"), "ReservedNames"}, - {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, - {rv.MethodByName("IsClosed"), "IsClosed"}, + rs.Append(rv, []attrAndName{ + {t.Values(), "Values"}, + {t.ReservedNames(), "ReservedNames"}, + {t.ReservedRanges(), "ReservedRanges"}, + {t.IsClosed(), "IsClosed"}, }...) case protoreflect.EnumValueDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Number"), "Number"}, - }...) + rs.Append(rv, attrAndName{t.Number(), "Number"}) case protoreflect.ServiceDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Methods"), "Methods"}, - }...) + rs.Append(rv, attrAndName{t.Methods(), "Methods"}) case protoreflect.MethodDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Input"), "Input"}, - {rv.MethodByName("Output"), "Output"}, - {rv.MethodByName("IsStreamingClient"), "IsStreamingClient"}, - {rv.MethodByName("IsStreamingServer"), "IsStreamingServer"}, + rs.Append(rv, []attrAndName{ + {t.Input(), "Input"}, + {t.Output(), "Output"}, + {t.IsStreamingClient(), "IsStreamingClient"}, + {t.IsStreamingServer(), "IsStreamingServer"}, }...) } - if m := rv.MethodByName("GoType"); m.IsValid() { - rs.Append(rv, methodAndName{m, "GoType"}) + if m, ok := t.(interface{ GoType() reflect.Type }); ok { + rs.Append(rv, attrAndName{m.GoType(), "GoType"}) } } return start + rs.Join() + end @@ -297,68 +294,66 @@ func (rs *records) AppendRecs(fieldName string, newRecs [2]string) { rs.recs = append(rs.recs, newRecs) } -func (rs *records) Append(v reflect.Value, accessors ...methodAndName) { - for _, a := range accessors { - if rs.record != nil { - rs.record(a.name) - } - var rv reflect.Value - if a.method.IsValid() { - rv = a.method.Call(nil)[0] - } - if v.Kind() == reflect.Struct && !rv.IsValid() { - rv = v.FieldByName(a.name) - } - if !rv.IsValid() { - panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a.name)) - } - if _, ok := rv.Interface().(protoreflect.Value); ok { - rv = rv.MethodByName("Interface").Call(nil)[0] - if !rv.IsNil() { - rv = rv.Elem() - } - } +func (rs *records) Append(v reflect.Value, results ...attrAndName) { + for _, r := range results { + rs.appendAttribute(v, r.name, r.attr) + } +} - // Ignore zero values. - var isZero bool - switch rv.Kind() { - case reflect.Interface, reflect.Slice: - isZero = rv.IsNil() - case reflect.Bool: - isZero = rv.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - isZero = rv.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - isZero = rv.Uint() == 0 - case reflect.String: - isZero = rv.String() == "" - } - if n, ok := rv.Interface().(list); ok { - isZero = n.Len() == 0 - } - if isZero { - continue +func (rs *records) appendAttribute(val reflect.Value, name string, attrVal any) { + if rs.record != nil { + rs.record(name) + } + if attrVal == nil { + return + } + rv := reflect.ValueOf(attrVal) + if _, ok := rv.Interface().(protoreflect.Value); ok { + rv = rv.MethodByName("Interface").Call(nil)[0] + if !rv.IsNil() { + rv = rv.Elem() } + } - // Format the value. - var s string - v := rv.Interface() - switch v := v.(type) { - case list: - s = formatListOpt(v, false, rs.allowMulti) - case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: - s = string(v.(protoreflect.Descriptor).Name()) - case protoreflect.Descriptor: - s = string(v.FullName()) - case string: - s = strconv.Quote(v) - case []byte: - s = fmt.Sprintf("%q", v) - default: - s = fmt.Sprint(v) - } - rs.recs = append(rs.recs, [2]string{a.name, s}) + // Ignore zero values. + var isZero bool + switch rv.Kind() { + case reflect.Interface, reflect.Slice: + isZero = rv.IsNil() + case reflect.Bool: + isZero = rv.Bool() == false + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + isZero = rv.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + isZero = rv.Uint() == 0 + case reflect.String: + isZero = rv.String() == "" + } + if n, ok := rv.Interface().(list); ok { + isZero = n.Len() == 0 + } + if isZero { + return + } + + // Format the value. + var s string + v := rv.Interface() + switch v := v.(type) { + case list: + s = formatListOpt(v, false, rs.allowMulti) + case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: + s = string(v.(protoreflect.Descriptor).Name()) + case protoreflect.Descriptor: + s = string(v.FullName()) + case string: + s = strconv.Quote(v) + case []byte: + s = fmt.Sprintf("%q", v) + default: + s = fmt.Sprint(v) } + rs.recs = append(rs.recs, [2]string{name, s}) } func (rs *records) Join() string { diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index 763fd82841..bfb2cfdea5 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -53,7 +53,7 @@ const ( Major = 1 Minor = 36 Patch = 11 - PreRelease = "" + PreRelease = "devel" ) // String formats the version string for this module in semver format. diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go index c826ad0430..84a3228edb 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go @@ -201,6 +201,7 @@ func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescript return nil, err } x.L1.EditionFeatures = mergeEditionFeatures(parent, xd.GetOptions().GetFeatures()) + x.L2.IsProto3Optional = xd.GetProto3Optional() if opts := xd.GetOptions(); opts != nil { opts = proto.Clone(opts).(*descriptorpb.FieldOptions) x.L2.Options = func() protoreflect.ProtoMessage { return opts } diff --git a/vendor/modules.txt b/vendor/modules.txt index 9f30a15bf8..70858adf08 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1367,8 +1367,8 @@ github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo github.com/openshift-eng/openshift-tests-extension/pkg/junit github.com/openshift-eng/openshift-tests-extension/pkg/util/sets github.com/openshift-eng/openshift-tests-extension/pkg/version -# github.com/openshift/api v0.0.0-20260702202555-ef71f942ef6c -## explicit; go 1.25.0 +# github.com/openshift/api v0.0.0-20260702202555-ef71f942ef6c => github.com/mkowalski/openshift-api v0.0.0-20260720204730-3b96df04543d +## explicit; go 1.26.0 github.com/openshift/api github.com/openshift/api/annotations github.com/openshift/api/apiextensions @@ -2397,7 +2397,7 @@ google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats google.golang.org/grpc/status google.golang.org/grpc/tap -# google.golang.org/protobuf v1.36.11 +# google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af ## explicit; go 1.23 google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/protojson @@ -2638,7 +2638,7 @@ honnef.co/go/tools/stylecheck/st1021 honnef.co/go/tools/stylecheck/st1022 honnef.co/go/tools/stylecheck/st1023 honnef.co/go/tools/unused -# k8s.io/api v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260305123649-d18f3f005eaa +# k8s.io/api v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260305123649-d18f3f005eaa ## explicit; go 1.25.0 k8s.io/api/admission/v1 k8s.io/api/admission/v1beta1 @@ -2719,7 +2719,7 @@ k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalint k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1 k8s.io/apiextensions-apiserver/pkg/features -# k8s.io/apimachinery v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260305123649-d18f3f005eaa +# k8s.io/apimachinery v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260305123649-d18f3f005eaa ## explicit; go 1.25.0 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -4113,3 +4113,4 @@ sigs.k8s.io/yaml/kyaml # k8s.io/sample-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260305123649-d18f3f005eaa # k8s.io/sample-cli-plugin => github.com/openshift/kubernetes/staging/src/k8s.io/sample-cli-plugin v0.0.0-20260305123649-d18f3f005eaa # k8s.io/sample-controller => github.com/openshift/kubernetes/staging/src/k8s.io/sample-controller v0.0.0-20260305123649-d18f3f005eaa +# github.com/openshift/api => github.com/mkowalski/openshift-api v0.0.0-20260720204730-3b96df04543d