diff --git a/go.mod b/go.mod
index c73164f157..9ee165560b 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,10 @@ module github.com/openshift/library-go
go 1.25.0
+replace github.com/openshift/api => github.com/bhperry/openshift-api v0.0.0-20260430171308-07f1fbedc28f
+
+replace github.com/openshift/client-go => github.com/bhperry/openshift-client-go v0.0.0-20260430171600-439d308fac91
+
require (
github.com/RangelReale/osincli v0.0.0-20160924135400-fababb0555f2
github.com/blang/semver/v4 v4.0.0
diff --git a/go.sum b/go.sum
index 3f7146a5cf..507e5f424c 100644
--- a/go.sum
+++ b/go.sum
@@ -20,6 +20,10 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bhperry/openshift-api v0.0.0-20260430171308-07f1fbedc28f h1:R930pInp3YsxDUcvx8nXgQyga1z2f/xcnDEbtM44rRo=
+github.com/bhperry/openshift-api v0.0.0-20260430171308-07f1fbedc28f/go.mod h1:pyVjK0nZ4sRs4fuQVQ4rubsJdahI1PB94LnQ8sGdvxo=
+github.com/bhperry/openshift-client-go v0.0.0-20260430171600-439d308fac91 h1:UeTG9/NiL9hTpcnLvucw0wkgCdG9evZJ/fIhwVjQemQ=
+github.com/bhperry/openshift-client-go v0.0.0-20260430171600-439d308fac91/go.mod h1:fcdSl1rcCdZOKgn3zH8C7UbIykq6PeXVRB1EFL6xJKI=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
@@ -225,12 +229,8 @@ github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrB
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/selinux v1.13.0 h1:Zza88GWezyT7RLql12URvoxsbLfjFx988+LGaWfbL84=
github.com/opencontainers/selinux v1.13.0/go.mod h1:XxWTed+A/s5NNq4GmYScVy+9jzXhGBVEOAyucdRUY8s=
-github.com/openshift/api v0.0.0-20260429122012-1180c0f5c3e9 h1:lZw6pYY7El1giNk1lYvkp6hLungiqwIOqLlH+Hm7w9g=
-github.com/openshift/api v0.0.0-20260429122012-1180c0f5c3e9/go.mod h1:pyVjK0nZ4sRs4fuQVQ4rubsJdahI1PB94LnQ8sGdvxo=
github.com/openshift/build-machinery-go v0.0.0-20250530140348-dc5b2804eeee h1:+Sp5GGnjHDhT/a/nQ1xdp43UscBMr7G5wxsYotyhzJ4=
github.com/openshift/build-machinery-go v0.0.0-20250530140348-dc5b2804eeee/go.mod h1:8jcm8UPtg2mCAsxfqKil1xrmRMI3a+XU2TZ9fF8A7TE=
-github.com/openshift/client-go v0.0.0-20260429123927-c81f86abfa6a h1:4GR6seHvlfv0rADe+LCQx63FqSExx6gaSo8uNiyWq+c=
-github.com/openshift/client-go v0.0.0-20260429123927-c81f86abfa6a/go.mod h1:Lm7X7aYbAaKhGsNhgYaowP7hiLKwfN/w0r+Q6VlQoI8=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
diff --git a/pkg/operator/staticpod/controller/node/node_controller.go b/pkg/operator/staticpod/controller/node/node_controller.go
index 0f2cbec4f5..e5b09d988a 100644
--- a/pkg/operator/staticpod/controller/node/node_controller.go
+++ b/pkg/operator/staticpod/controller/node/node_controller.go
@@ -7,6 +7,7 @@ import (
coreapiv1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/informers"
corelisterv1 "k8s.io/client-go/listers/core/v1"
@@ -84,22 +85,31 @@ func (c *NodeController) sync(ctx context.Context, syncCtx factory.SyncContext)
nodes = append(nodes, extraNodes...)
}
+ nodeUIDs := map[string]types.UID{}
+ for _, node := range nodes {
+ nodeUIDs[node.Name] = node.UID
+ }
+
jsonPatch := jsonpatch.New()
var removedNodeStatusesCounter int
newTargetNodeStates := []*applyoperatorv1.NodeStatusApplyConfiguration{}
// remove entries for missing nodes
for i, nodeState := range originalOperatorStatus.NodeStatuses {
- found := false
- for _, node := range nodes {
- if nodeState.NodeName == node.Name {
- found = true
+ currentUID, found := nodeUIDs[nodeState.NodeName]
+ if found && (nodeState.NodeUID == currentUID || nodeState.NodeUID == "") {
+ if nodeState.NodeUID == "" {
+ syncCtx.Recorder().Warningf("MasterNodeUnknownUID", "Node %s has no recorded UID. If this node was replaced its status may need to be manually removed from operator objects.")
}
- }
- if found {
- newTargetNodeState := applyoperatorv1.NodeStatus().WithNodeName(originalOperatorStatus.NodeStatuses[i].NodeName)
+ newTargetNodeState := applyoperatorv1.NodeStatus().
+ WithNodeName(nodeState.NodeName).
+ WithNodeUID(currentUID)
newTargetNodeStates = append(newTargetNodeStates, newTargetNodeState)
} else {
- syncCtx.Recorder().Warningf("MasterNodeRemoved", "Observed removal of master node %s", nodeState.NodeName)
+ if found {
+ syncCtx.Recorder().Warningf("MasterNodeReplaced", "Observed replacement of master node %s (old UID: %s, new UID: %s)", nodeState.NodeName, nodeState.NodeUID, currentUID)
+ } else {
+ syncCtx.Recorder().Warningf("MasterNodeRemoved", "Observed removal of master node %s", nodeState.NodeName)
+ }
// each delete operation is applied to the object,
// which modifies the array. Thus, we need to
// adjust the indices to find the correct node to remove.
@@ -116,16 +126,17 @@ func (c *NodeController) sync(ctx context.Context, syncCtx factory.SyncContext)
for _, node := range nodes {
found := false
for _, nodeState := range originalOperatorStatus.NodeStatuses {
- if nodeState.NodeName == node.Name {
+ if nodeState.NodeName == node.Name && (nodeState.NodeUID == node.UID || nodeState.NodeUID == "") {
found = true
+ break
}
}
if found {
continue
}
- syncCtx.Recorder().Eventf("MasterNodeObserved", "Observed new master node %s", node.Name)
- newTargetNodeState := applyoperatorv1.NodeStatus().WithNodeName(node.Name)
+ syncCtx.Recorder().Eventf("MasterNodeObserved", "Observed new master node %s (UID: %s)", node.Name, node.UID)
+ newTargetNodeState := applyoperatorv1.NodeStatus().WithNodeName(node.Name).WithNodeUID(node.UID)
newTargetNodeStates = append(newTargetNodeStates, newTargetNodeState)
}
diff --git a/pkg/operator/staticpod/controller/node/node_controller_test.go b/pkg/operator/staticpod/controller/node/node_controller_test.go
index 20784fbca9..80a9435c55 100644
--- a/pkg/operator/staticpod/controller/node/node_controller_test.go
+++ b/pkg/operator/staticpod/controller/node/node_controller_test.go
@@ -13,6 +13,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/selection"
+ "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/fake"
clientgotesting "k8s.io/client-go/testing"
clocktesting "k8s.io/utils/clock/testing"
@@ -28,6 +29,7 @@ import (
func fakeMasterNode(name string) *corev1.Node {
n := &corev1.Node{}
n.Name = name
+ n.UID = types.UID(name + "-uid")
n.Labels = map[string]string{
"node-role.kubernetes.io/master": "",
}
@@ -729,3 +731,143 @@ func TestNewNodeController(t *testing.T) {
}
}
+
+func TestNodeControllerTrackNodeUIDs(t *testing.T) {
+ tests := []struct {
+ name string
+ startNodes []runtime.Object
+ startNodeStatus []operatorv1.NodeStatus
+ expectedNodes [][2]string
+ evaluateNodeStatus func([]operatorv1.NodeStatus) error
+ }{
+ {
+ name: "node exists missing uid in status",
+ startNodes: []runtime.Object{fakeMasterNode("test-node-1")},
+ startNodeStatus: []operatorv1.NodeStatus{
+ {
+ NodeName: "test-node-1",
+ },
+ },
+ evaluateNodeStatus: func(s []operatorv1.NodeStatus) error {
+ if len(s) != 1 {
+ return fmt.Errorf("expected 1 node status, got %d", len(s))
+ }
+ if s[0].NodeName != "test-node-1" {
+ return fmt.Errorf("expected 'test-node-1' as node name, got %q", s[0].NodeName)
+ }
+ if s[0].NodeUID != "test-node-1-uid" {
+ return fmt.Errorf("expected 'test-node-1-uid' as node UID, got %q", s[0].NodeUID)
+ }
+ return nil
+ },
+ },
+ {
+ name: "node exists matching uid in status",
+ startNodes: []runtime.Object{fakeMasterNode("test-node-1")},
+ startNodeStatus: []operatorv1.NodeStatus{
+ {
+ NodeName: "test-node-1",
+ NodeUID: "test-node-1-uid",
+ },
+ },
+ evaluateNodeStatus: func(s []operatorv1.NodeStatus) error {
+ if len(s) != 1 {
+ return fmt.Errorf("expected 1 node status, got %d", len(s))
+ }
+ if s[0].NodeName != "test-node-1" {
+ return fmt.Errorf("expected 'test-node-1' as node name, got %q", s[0].NodeName)
+ }
+ if s[0].NodeUID != "test-node-1-uid" {
+ return fmt.Errorf("expected 'test-node-1-uid' as node UID, got %q", s[0].NodeUID)
+ }
+ return nil
+ },
+ },
+ {
+ name: "node replaced mismatched uid in status",
+ startNodes: []runtime.Object{fakeMasterNode("test-node-1")},
+ startNodeStatus: []operatorv1.NodeStatus{
+ {
+ NodeName: "test-node-1",
+ NodeUID: "test-node-1-uid-init",
+ },
+ },
+ evaluateNodeStatus: func(s []operatorv1.NodeStatus) error {
+ if len(s) != 1 {
+ return fmt.Errorf("expected 1 node status, got %d", len(s))
+ }
+ if s[0].NodeName != "test-node-1" {
+ return fmt.Errorf("expected 'test-node-1' as node name, got %q", s[0].NodeName)
+ }
+ if s[0].NodeUID != "test-node-1-uid" {
+ return fmt.Errorf("expected 'test-node-1-uid' as node UID, got %q", s[0].NodeUID)
+ }
+ return nil
+ },
+ },
+ {
+ name: "node removed",
+ startNodes: []runtime.Object{fakeMasterNode("test-node-2")},
+ startNodeStatus: []operatorv1.NodeStatus{
+ {
+ NodeName: "test-node-1",
+ NodeUID: "test-node-1-uid",
+ },
+ },
+ evaluateNodeStatus: func(s []operatorv1.NodeStatus) error {
+ if len(s) != 1 {
+ return fmt.Errorf("expected 1 node status, got %d", len(s))
+ }
+ if s[0].NodeName != "test-node-2" {
+ return fmt.Errorf("expected 'test-node-2' as node name, got %q", s[0].NodeName)
+ }
+ if s[0].NodeUID != "test-node-2-uid" {
+ return fmt.Errorf("expected 'test-node-2-uid' as node UID, got %q", s[0].NodeUID)
+ }
+ return nil
+ },
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ kubeClient := fake.NewSimpleClientset(test.startNodes...)
+ fakeLister := v1helpers.NewFakeNodeLister(kubeClient)
+ fakeStaticPodOperatorClient := v1helpers.NewFakeStaticPodOperatorClient(
+ &operatorv1.StaticPodOperatorSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: operatorv1.Managed,
+ },
+ },
+ &operatorv1.StaticPodOperatorStatus{
+ OperatorStatus: operatorv1.OperatorStatus{
+ LatestAvailableRevision: 1,
+ },
+ NodeStatuses: test.startNodeStatus,
+ },
+ nil,
+ nil,
+ )
+
+ eventRecorder := events.NewRecorder(kubeClient.CoreV1().Events("test"), "test-operator", &corev1.ObjectReference{}, clocktesting.NewFakePassiveClock(time.Now()))
+
+ c := &NodeController{
+ operatorClient: fakeStaticPodOperatorClient,
+ nodeLister: fakeLister,
+ masterNodesSelector: masterNodesSelector(t),
+ }
+
+ // override the lister so we don't have to run the informer to list nodes
+ c.nodeLister = fakeLister
+ if err := c.sync(context.TODO(), factory.NewSyncContext("NodeController", eventRecorder)); err != nil {
+ t.Fatal(err)
+ }
+
+ _, status, _, _ := fakeStaticPodOperatorClient.GetStaticPodOperatorState()
+ if err := test.evaluateNodeStatus(status.NodeStatuses); err != nil {
+ t.Errorf("%s: failed to evaluate node status: %v", test.name, err)
+ }
+ })
+
+ }
+}
diff --git a/pkg/operator/v1helpers/test_helpers.go b/pkg/operator/v1helpers/test_helpers.go
index ec67f6dd97..fcd32527c7 100644
--- a/pkg/operator/v1helpers/test_helpers.go
+++ b/pkg/operator/v1helpers/test_helpers.go
@@ -470,6 +470,7 @@ func mergeStaticPodOperatorStatusApplyConfiguration(currentOperatorStatus *v1.Op
for _, nodeStatus := range applyConfiguration.NodeStatuses {
newNodeStatus := operatorv1.NodeStatus{
NodeName: ptr.Deref(nodeStatus.NodeName, ""),
+ NodeUID: ptr.Deref(nodeStatus.NodeUID, ""),
CurrentRevision: ptr.Deref(nodeStatus.CurrentRevision, 0),
TargetRevision: ptr.Deref(nodeStatus.TargetRevision, 0),
LastFailedRevision: ptr.Deref(nodeStatus.LastFailedRevision, 0),
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 c579be3a11..e7680899d4 100644
--- a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go
+++ b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go
@@ -295,7 +295,8 @@ type ExternalPlatformSpec struct {
// PlatformSpec holds the desired state specific to the underlying infrastructure provider
// of the current cluster. Since these are used at spec-level for the underlying cluster, it
// is supposed that only one of the spec structs is set.
-// +kubebuilder:validation:XValidation:rule="!has(oldSelf.vsphere) && has(self.vsphere) ? size(self.vsphere.vcenters) < 2 : true",message="vcenters can have at most 1 item when configured post-install"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="!has(oldSelf.vsphere) && has(self.vsphere) ? (has(self.vsphere.vcenters) && size(self.vsphere.vcenters) < 2) : true",message="vcenters can have at most 1 item when configured post-install"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=VSphereMultiVCenterDay2,rule="oldSelf.?vsphere.vcenters.hasValue() ? self.?vsphere.vcenters.hasValue() : true",message="vcenters is required once set and cannot be removed"
type PlatformSpec struct {
// type is the underlying infrastructure provider for the cluster. This
// value controls whether infrastructure automation such as service load
@@ -1641,21 +1642,24 @@ type VSpherePlatformNodeNetworking struct {
// use these fields for configuration.
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)",message="apiServerInternalIPs list is required once set"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ingressIPs) || has(self.ingressIPs)",message="ingressIPs list is required once set"
-// +kubebuilder:validation:XValidation:rule="!has(oldSelf.vcenters) && has(self.vcenters) ? size(self.vcenters) < 2 : true",message="vcenters can have at most 1 item when configured post-install"
type VSpherePlatformSpec struct {
// vcenters holds the connection details for services to communicate with vCenter.
- // Currently, only a single vCenter is supported, but in tech preview 3 vCenters are supported.
+ // Up to 3 vCenters are supported.
// Once the cluster has been installed, you are unable to change the current number of defined
- // vCenters except in the case where the cluster has been upgraded from a version of OpenShift
- // where the vsphere platform spec was not present. You may make modifications to the existing
+ // vCenters 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.
// ---
// + If VCenters is not defined use the existing cloud-config configmap defined
// + in openshift-config.
- // +kubebuilder:validation:MinItems=0
+ // +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=3
- // +kubebuilder:validation:XValidation:rule="size(self) != size(oldSelf) ? size(oldSelf) == 0 && size(self) < 2 : true",message="vcenters cannot be added or removed once set"
+ // +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="size(self) != size(oldSelf) ? size(oldSelf) == 0 && size(self) < 2 : true",message="vcenters cannot be added or removed once set"
+ // +openshift:validation:FeatureGateAwareXValidation:featureGate=VSphereMultiVCenterDay2,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"
+ // +openshift:validation:FeatureGateAwareXValidation:featureGate=VSphereMultiVCenterDay2,rule="size(self) < size(oldSelf) ? self.all(x, oldSelf.exists(y, y.server == x.server)) : true",message="Cannot add and remove vCenters at the same time"
+ // +kubebuilder:validation:XValidation:rule="self.all(x, self.exists_one(y, y.server == x.server))",message="vcenters must have unique server values"
// +listType=atomic
// +optional
VCenters []VSpherePlatformVCenterSpec `json:"vcenters,omitempty"`
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 75233bff73..ff232e723e 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
@@ -376,6 +376,7 @@ infrastructures.config.openshift.io:
- OnPremDNSRecords
- VSphereHostVMGroupZonal
- VSphereMultiNetworks
+ - VSphereMultiVCenterDay2
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 f386a81125..b35922c587 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
@@ -2082,7 +2082,7 @@ func (VSpherePlatformNodeNetworkingSpec) SwaggerDoc() map[string]string {
var map_VSpherePlatformSpec = map[string]string{
"": "VSpherePlatformSpec holds the desired state of the vSphere infrastructure provider. In the future the cloud provider operator, storage operator and machine operator will use these fields for configuration.",
- "vcenters": "vcenters holds the connection details for services to communicate with vCenter. Currently, only a single vCenter is supported, but in tech preview 3 vCenters are supported. Once the cluster has been installed, you are unable to change the current number of defined vCenters except in the case where the cluster has been upgraded from a version of OpenShift where the vsphere platform spec was not present. You may make modifications to the existing vCenters that are defined in the vcenters list in order to match with any added or modified failure domains.",
+ "vcenters": "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.",
"failureDomains": "failureDomains contains the definition of region, zone and the vCenter topology. If this is omitted failure domains (regions and zones) will not be used.",
"nodeNetworking": "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.",
"apiServerInternalIPs": "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).",
diff --git a/vendor/github.com/openshift/api/console/v1/types_console_plugin.go b/vendor/github.com/openshift/api/console/v1/types_console_plugin.go
index 0160a4a242..c63db50d52 100644
--- a/vendor/github.com/openshift/api/console/v1/types_console_plugin.go
+++ b/vendor/github.com/openshift/api/console/v1/types_console_plugin.go
@@ -90,7 +90,6 @@ type ConsolePluginSpec struct {
// OpenShift web console server CSP response header:
// Content-Security-Policy: default-src 'self'; base-uri 'self'; script-src 'self' https://script1.com/ https://script2.com/ https://script3.com/; font-src 'self' https://font1.com/ https://font2.com/; img-src 'self' https://img1.com/; style-src 'self'; frame-src 'none'; object-src 'none'
//
- // +openshift:enable:FeatureGate=ConsolePluginContentSecurityPolicy
// +kubebuilder:validation:MaxItems=5
// +kubebuilder:validation:XValidation:rule="self.map(x, x.values.map(y, y.size()).sum()).sum() < 8192",message="the total combined size of values of all directives must not exceed 8192 (8kb)"
// +listType=map
diff --git a/vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml
index caa676e691..26524d0a17 100644
--- a/vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml
+++ b/vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml
@@ -137,8 +137,7 @@ consoleplugins.console.openshift.io:
CRDName: consoleplugins.console.openshift.io
Capability: Console
Category: ""
- FeatureGates:
- - ConsolePluginContentSecurityPolicy
+ FeatureGates: []
FilenameOperatorName: ""
FilenameOperatorOrdering: "90"
FilenameRunLevel: ""
diff --git a/vendor/github.com/openshift/api/features.md b/vendor/github.com/openshift/api/features.md
index 24149f56e9..eb3235e2bb 100644
--- a/vendor/github.com/openshift/api/features.md
+++ b/vendor/github.com/openshift/api/features.md
@@ -92,7 +92,6 @@
| 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 |
-| ConsolePluginContentSecurityPolicy| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled |
| DualReplica| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled |
| EventTTL| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled |
| ExternalOIDC| 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 6fdc233195..0fc8583dfe 100644
--- a/vendor/github.com/openshift/api/features/features.go
+++ b/vendor/github.com/openshift/api/features/features.go
@@ -75,14 +75,6 @@ func AllFeatureSets() map[uint64]map[ClusterProfileName]map[configv1.FeatureSet]
var (
allFeatureGates = map[configv1.FeatureGateName][]featureGateStatus{}
- FeatureGateConsolePluginCSP = newFeatureGate("ConsolePluginContentSecurityPolicy").
- reportProblemsToJiraComponent("Management Console").
- contactPerson("jhadvig").
- productScope(ocpSpecific).
- enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()).
- enhancementPR("https://github.com/openshift/enhancements/pull/1706").
- mustRegister()
-
FeatureGateServiceAccountTokenNodeBinding = newFeatureGate("ServiceAccountTokenNodeBinding").
reportProblemsToJiraComponent("apiserver-auth").
contactPerson("ibihim").
@@ -979,11 +971,11 @@ var (
enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()).
mustRegister()
- FeatureGateConfidentialCluster = newFeatureGate("ConfidentialCluster").
- reportProblemsToJiraComponent("ConfidentialClusters").
- contactPerson("fjin").
- productScope(ocpSpecific).
- enhancementPR("https://github.com/openshift/enhancements/pull/1962").
- enable(inDevPreviewNoUpgrade()).
- mustRegister()
+ FeatureGateConfidentialCluster = newFeatureGate("ConfidentialCluster").
+ reportProblemsToJiraComponent("ConfidentialClusters").
+ contactPerson("fjin").
+ productScope(ocpSpecific).
+ enhancementPR("https://github.com/openshift/enhancements/pull/1962").
+ enable(inDevPreviewNoUpgrade()).
+ mustRegister()
)
diff --git a/vendor/github.com/openshift/api/operator/v1/types.go b/vendor/github.com/openshift/api/operator/v1/types.go
index 3a2141abb9..5e4e49dafc 100644
--- a/vendor/github.com/openshift/api/operator/v1/types.go
+++ b/vendor/github.com/openshift/api/operator/v1/types.go
@@ -3,6 +3,7 @@ package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
)
// MyOperatorResource is an example operator configuration type
@@ -266,6 +267,12 @@ type NodeStatus struct {
// +required
NodeName string `json:"nodeName"`
+ // nodeUID is the UID of the node.
+ // This field is used to detect that a node has been deleted and recreated with the same name.
+ // When the UID changes, it indicates the node is a new instance and the status should be reset.
+ // +optional
+ NodeUID types.UID `json:"nodeUID,omitempty"`
+
// currentRevision is the generation of the most recently successful deployment.
// Can not be set on creation of a nodeStatus. Updates must only increase the value.
// +kubebuilder:validation:XValidation:rule="self >= oldSelf",message="must only increase"
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 c3ed726028..262d2dd881 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
@@ -37,6 +37,7 @@ func (MyOperatorResource) SwaggerDoc() map[string]string {
var map_NodeStatus = map[string]string{
"": "NodeStatus provides information about the current state of a particular node managed by this operator.",
"nodeName": "nodeName is the name of the node",
+ "nodeUID": "nodeUID is the UID of the node. This field is used to detect that a node has been deleted and recreated with the same name. When the UID changes, it indicates the node is a new instance and the status should be reset.",
"currentRevision": "currentRevision is the generation of the most recently successful deployment. Can not be set on creation of a nodeStatus. Updates must only increase the value.",
"targetRevision": "targetRevision is the generation of the deployment we're trying to apply. Can not be set on creation of a nodeStatus.",
"lastFailedRevision": "lastFailedRevision is the generation of the deployment we tried and failed to deploy.",
diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go
index 7603b05954..e5359c1d38 100644
--- a/vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go
+++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go
@@ -3366,6 +3366,9 @@ var schemaYAML = typed.YAMLObject(`types:
type:
scalar: string
default: ""
+ - name: nodeUID
+ type:
+ scalar: string
- name: targetRevision
type:
scalar: numeric
diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/nodestatus.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/nodestatus.go
index f107c370d2..9a796d563f 100644
--- a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/nodestatus.go
+++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/nodestatus.go
@@ -4,6 +4,7 @@ package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ types "k8s.io/apimachinery/pkg/types"
)
// NodeStatusApplyConfiguration represents a declarative configuration of the NodeStatus type for use
@@ -13,6 +14,10 @@ import (
type NodeStatusApplyConfiguration struct {
// nodeName is the name of the node
NodeName *string `json:"nodeName,omitempty"`
+ // nodeUID is the UID of the node.
+ // This field is used to detect that a node has been deleted and recreated with the same name.
+ // When the UID changes, it indicates the node is a new instance and the status should be reset.
+ NodeUID *types.UID `json:"nodeUID,omitempty"`
// currentRevision is the generation of the most recently successful deployment.
// Can not be set on creation of a nodeStatus. Updates must only increase the value.
CurrentRevision *int32 `json:"currentRevision,omitempty"`
@@ -47,6 +52,14 @@ func (b *NodeStatusApplyConfiguration) WithNodeName(value string) *NodeStatusApp
return b
}
+// WithNodeUID sets the NodeUID field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the NodeUID field is set to the value of the last call.
+func (b *NodeStatusApplyConfiguration) WithNodeUID(value types.UID) *NodeStatusApplyConfiguration {
+ b.NodeUID = &value
+ return b
+}
+
// WithCurrentRevision sets the CurrentRevision field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the CurrentRevision field is set to the value of the last call.
diff --git a/vendor/modules.txt b/vendor/modules.txt
index f92ced237e..a94c4d2857 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -286,7 +286,7 @@ github.com/opencontainers/image-spec/specs-go/v1
## explicit; go 1.19
github.com/opencontainers/selinux/go-selinux
github.com/opencontainers/selinux/pkg/pwalkdir
-# github.com/openshift/api v0.0.0-20260429122012-1180c0f5c3e9
+# github.com/openshift/api v0.0.0-20260429122012-1180c0f5c3e9 => github.com/bhperry/openshift-api v0.0.0-20260430171308-07f1fbedc28f
## explicit; go 1.25.0
github.com/openshift/api
github.com/openshift/api/annotations
@@ -376,7 +376,7 @@ github.com/openshift/build-machinery-go/make/targets/golang
github.com/openshift/build-machinery-go/make/targets/openshift
github.com/openshift/build-machinery-go/make/targets/openshift/operator
github.com/openshift/build-machinery-go/scripts
-# github.com/openshift/client-go v0.0.0-20260429123927-c81f86abfa6a
+# github.com/openshift/client-go v0.0.0-20260429123927-c81f86abfa6a => github.com/bhperry/openshift-client-go v0.0.0-20260430171600-439d308fac91
## explicit; go 1.25.0
github.com/openshift/client-go/apps/applyconfigurations/apps/v1
github.com/openshift/client-go/apps/applyconfigurations/internal
@@ -1675,3 +1675,5 @@ sigs.k8s.io/structured-merge-diff/v6/value
# sigs.k8s.io/yaml v1.6.0
## explicit; go 1.22
sigs.k8s.io/yaml
+# github.com/openshift/api => github.com/bhperry/openshift-api v0.0.0-20260430171308-07f1fbedc28f
+# github.com/openshift/client-go => github.com/bhperry/openshift-client-go v0.0.0-20260430171600-439d308fac91