Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
k8s.io/klog/v2 v2.130.1
k8s.io/kube-proxy v0.35.2
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2
sigs.k8s.io/controller-runtime v0.23.1
sigs.k8s.io/controller-runtime v0.23.3
)

require (
Expand Down Expand Up @@ -102,7 +102,8 @@ require (
require (
github.com/openshift/api v0.0.0-20260320151444-324a1bcb9f55
github.com/openshift/client-go v0.0.0-20260320040014-4b5fc2cdad98
github.com/openshift/library-go v0.0.0-20260303171201-5d9eb6295ff6
github.com/openshift/controller-runtime-common v0.0.0-20260428152732-64ee174f5e2e
github.com/openshift/library-go v0.0.0-20260318140748-04979c746b4d
github.com/openshift/machine-config-operator v0.0.1-0.20250724162154-ab14c8e2843b
k8s.io/apiextensions-apiserver v0.35.2
k8s.io/client-go v0.35.2
Expand Down Expand Up @@ -140,7 +141,6 @@ require (
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/onsi/ginkgo/v2 v2.28.1 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/stretchr/objx v0.5.3 // indirect
Expand Down
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,10 @@ github.com/openshift/build-machinery-go v0.0.0-20251023084048-5d77c1a5e5af h1:Ui
github.com/openshift/build-machinery-go v0.0.0-20251023084048-5d77c1a5e5af/go.mod h1:8jcm8UPtg2mCAsxfqKil1xrmRMI3a+XU2TZ9fF8A7TE=
github.com/openshift/client-go v0.0.0-20260320040014-4b5fc2cdad98 h1:Ssuo/zELWqb7pFCwzB3QGEA4QeLW948hL2AhWq2SWjs=
github.com/openshift/client-go v0.0.0-20260320040014-4b5fc2cdad98/go.mod h1:8O4jIKdcr5YR9FFQEeokYoCplCUN+j9hZj4u/2yg0As=
github.com/openshift/library-go v0.0.0-20260303171201-5d9eb6295ff6 h1:xjqy0OolrFdJ+ofI/aD0+2k9+MSk5anP5dXifFt539Q=
github.com/openshift/library-go v0.0.0-20260303171201-5d9eb6295ff6/go.mod h1:D797O/ssKTNglbrGchjIguFq+DbyRYdeds5w4/VTrKM=
github.com/openshift/controller-runtime-common v0.0.0-20260428152732-64ee174f5e2e h1:k89oIo2EjX0PRSdi1kesktCyWp50SC9WwKurvupvRGs=
github.com/openshift/controller-runtime-common v0.0.0-20260428152732-64ee174f5e2e/go.mod h1:XGabTMnNbz0M5Oa7IbscZp/jmcc7aHobvOCUWwkzKvM=
github.com/openshift/library-go v0.0.0-20260318140748-04979c746b4d h1:i3STSVfFi+39gOAramKPySB6WrvuD0rAIssSNOnTwyg=
github.com/openshift/library-go v0.0.0-20260318140748-04979c746b4d/go.mod h1:3bi4pLpYRdVd1aEhsHfRTJkwxwPLfRZ+ZePn3RmJd2k=
github.com/openshift/machine-config-operator v0.0.1-0.20250724162154-ab14c8e2843b h1:LvoFr/2IEj0BWy7mKBdR7ueAHpMJGju1EkEIZrXa+DM=
github.com/openshift/machine-config-operator v0.0.1-0.20250724162154-ab14c8e2843b/go.mod h1:UL1OVkRAUkB4aaFZrLlSvuY0jayfdF+o+ZxKiKaaArc=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
Expand Down Expand Up @@ -482,8 +484,8 @@ k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0x
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE=
sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
sigs.k8s.io/controller-tools v0.20.1 h1:gkfMt9YodI0K85oT8rVi80NTXO/kDmabKR5Ajn5GYxs=
sigs.k8s.io/controller-tools v0.20.1/go.mod h1:b4qPmjGU3iZwqn34alUU5tILhNa9+VXK+J3QV0fT/uU=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
Expand Down
6 changes: 6 additions & 0 deletions pkg/bootstrap/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ type BootstrapResult struct {

OVN OVNBootstrapResult
IPTablesAlerter IPTablesAlerterBootstrapResult
TLSProfile TLSProfile
}

type InfraStatus struct {
Expand Down Expand Up @@ -176,3 +177,8 @@ type FlowsConfig struct {
// Sampling is the sampling rate on the reporter. 100 means one flow on 100 is sent. 0 means disabled.
Sampling *uint
}

type TLSProfile struct {
Spec configv1.TLSProfileSpec
Adherence configv1.TLSAdherencePolicy
}
14 changes: 13 additions & 1 deletion pkg/client/fake/fake_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,27 @@ func NewFakeClient(objs ...crclient.Object) cnoclient.Client {
}
}
co := &configv1.ClusterOperator{ObjectMeta: metav1.ObjectMeta{Name: ""}}

fc := FakeClusterClient{
kClient: faketyped.NewClientset(ooTyped...),
dynclient: fakedynamic.NewSimpleDynamicClient(scheme.Scheme, oo...),
crclient: crfake.NewClientBuilder().WithStatusSubresource(co).WithObjects(objs...).Build(),
osOperClient: osoperfakeclient.NewClientset(),
}

// Create a management cluster client for HyperShift scenarios
// This represents a separate cluster, so it starts empty
managementClient := FakeClusterClient{
kClient: faketyped.NewClientset(),
dynclient: fakedynamic.NewSimpleDynamicClient(scheme.Scheme),
crclient: crfake.NewClientBuilder().WithStatusSubresource(co).Build(),
osOperClient: osoperfakeclient.NewClientset(),
}

return &FakeClient{
clusterClients: map[string]*FakeClusterClient{
names.DefaultClusterName: &fc,
names.DefaultClusterName: &fc,
names.ManagementClusterName: &managementClient,
},
}
}
Expand Down
92 changes: 92 additions & 0 deletions pkg/controller/operconfig/operconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/openshift/cluster-network-operator/pkg/hypershift"
openshifttls "github.com/openshift/controller-runtime-common/pkg/tls"
"github.com/pkg/errors"

configv1 "github.com/openshift/api/config/v1"
Expand All @@ -32,6 +33,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/watch"
v1coreinformers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -177,6 +179,96 @@ func add(mgr manager.Manager, r *ReconcileOperConfig) error {
return err
}

// Watch for changes to the APIServer TLS profile
err = c.Watch(source.Kind[crclient.Object](mgr.GetCache(), &configv1.APIServer{},
handler.EnqueueRequestsFromMapFunc(reconcileOperConfig),
predicate.Funcs{
CreateFunc: func(evt event.CreateEvent) bool {
// Don't reconcile on initial creation/add events
return false
},
UpdateFunc: func(evt event.UpdateEvent) bool {
newAPI, ok := evt.ObjectNew.(*configv1.APIServer)
if !ok || newAPI.GetName() != openshifttls.APIServerName {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems weird that we're getting the name of the APIServer config object from openshifttls... is this not available from library-go or openshift/api or somethign?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's not defined in library-go or openshift/api.

return false
}

oldAPI := evt.ObjectOld.(*configv1.APIServer)

// Only reconcile if TLS profile or adherence changed
tlsProfileChanged := !reflect.DeepEqual(oldAPI.Spec.TLSSecurityProfile, newAPI.Spec.TLSSecurityProfile)
adherenceChanged := oldAPI.Spec.TLSAdherence != newAPI.Spec.TLSAdherence

return tlsProfileChanged || adherenceChanged
},
},
))
if err != nil {
return err
}

// In HyperShift mode, watch for changes to the HostedCluster TLS profile in the management cluster.
hc := hypershift.NewHyperShiftConfig()
if hc.Enabled {
// Create a dynamic informer for HostedCluster in the management cluster
dynClient := r.client.ClientFor(names.ManagementClusterName).Dynamic()
hostedClusterInformer := cache.NewSharedIndexInformer(
cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{
ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) {
return dynClient.Resource(hypershift.HostedClusterGVR).Namespace(hc.Namespace).List(ctx, options)
},
WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) {
return dynClient.Resource(hypershift.HostedClusterGVR).Namespace(hc.Namespace).Watch(ctx, options)
},
}, dynClient),
&uns.Unstructured{},
0, // don't resync
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)

r.client.ClientFor(names.ManagementClusterName).AddCustomInformer(hostedClusterInformer)

err = c.Watch(&source.Informer{
Informer: hostedClusterInformer,
Handler: handler.EnqueueRequestsFromMapFunc(reconcileOperConfig),
Predicates: []predicate.TypedPredicate[crclient.Object]{
predicate.NewPredicateFuncs(func(obj crclient.Object) bool {
// Only watch our specific HostedCluster
return obj.GetName() == hc.Name && obj.GetNamespace() == hc.Namespace
}),
predicate.Funcs{
CreateFunc: func(evt event.CreateEvent) bool {
// Don't reconcile on initial creation/add events
return false
},
UpdateFunc: func(evt event.UpdateEvent) bool {
newObj, ok := evt.ObjectNew.(*uns.Unstructured)
if !ok {
return false
}

oldObj, ok := evt.ObjectOld.(*uns.Unstructured)
if !ok {
return false
}

oldTLSProfile, _, _ := uns.NestedFieldCopy(oldObj.Object, "spec", "configuration", "apiServer", "tlsSecurityProfile")
newTLSProfile, _, _ := uns.NestedFieldCopy(newObj.Object, "spec", "configuration", "apiServer", "tlsSecurityProfile")

oldAdherence, _, _ := uns.NestedString(oldObj.Object, "spec", "configuration", "apiServer", "tlsAdherence")
newAdherence, _, _ := uns.NestedString(newObj.Object, "spec", "configuration", "apiServer", "tlsAdherence")

// Only reconcile if TLS profile or adherence changed
return !reflect.DeepEqual(oldTLSProfile, newTLSProfile) || oldAdherence != newAdherence
},
},
},
})
if err != nil {
return err
}
}

return nil
}

Expand Down
49 changes: 23 additions & 26 deletions pkg/hypershift/hypershift.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@ const HostedClusterDefaultAdvertiseAddressIPV6 = "fd00::1"

const HostedClusterDefaultAdvertisePort = int64(6443)

var (
enabled = os.Getenv("HYPERSHIFT")
name = os.Getenv("HOSTED_CLUSTER_NAME")
namespace = os.Getenv("HOSTED_CLUSTER_NAMESPACE")
runAsUser = os.Getenv("RUN_AS_USER")
releaseImage = os.Getenv("OPENSHIFT_RELEASE_IMAGE")
controlPlaneImage = os.Getenv("OVN_CONTROL_PLANE_IMAGE")
caConfigMap = os.Getenv("CA_CONFIG_MAP")
caConfigMapKey = os.Getenv("CA_CONFIG_MAP_KEY")
)

const (
// ClusterIDLabel (_id) is the common label used to identify clusters in telemeter.
// For hypershift, it will identify metrics produced by the both the control plane
Expand Down Expand Up @@ -84,11 +73,21 @@ const (

// HostedControlPlaneGVK GroupVersionKind for HostedControlPlane
// Based on https://github.com/openshift/hypershift/blob/27316d734d806a29d63f65ddf746cafd4409a1de/api/hypershift/v1beta1/hosted_controlplane.go#L19
var HostedControlPlaneGVK = schema.GroupVersionKind{
Group: "hypershift.openshift.io",
Version: "v1beta1",
Kind: "HostedControlPlane",
}
var (
HostedControlPlaneGVK = schema.GroupVersionKind{
Group: "hypershift.openshift.io",
Version: "v1beta1",
Kind: "HostedControlPlane",
}

HostedClusterGVK = schema.GroupVersionKind{
Group: "hypershift.openshift.io",
Version: "v1beta1",
Kind: "HostedCluster",
}

HostedClusterGVR = HostedClusterGVK.GroupVersion().WithResource("hostedclusters")
)

type HyperShiftConfig struct {
sync.Mutex
Expand All @@ -104,30 +103,28 @@ type HyperShiftConfig struct {
}

func NewHyperShiftConfig() *HyperShiftConfig {
caConfigMap := os.Getenv("CA_CONFIG_MAP")
if caConfigMap == "" {
caConfigMap = "openshift-service-ca.crt"
}

caConfigMapKey := os.Getenv("CA_CONFIG_MAP_KEY")
if caConfigMapKey == "" {
caConfigMapKey = "service-ca.crt"
}

return &HyperShiftConfig{
Enabled: hyperShiftEnabled(),
Name: name,
Namespace: namespace,
RunAsUser: runAsUser,
ReleaseImage: releaseImage,
ControlPlaneImage: controlPlaneImage,
Enabled: os.Getenv("HYPERSHIFT") == "true",
Name: os.Getenv("HOSTED_CLUSTER_NAME"),
Namespace: os.Getenv("HOSTED_CLUSTER_NAMESPACE"),
RunAsUser: os.Getenv("RUN_AS_USER"),
ReleaseImage: os.Getenv("OPENSHIFT_RELEASE_IMAGE"),
ControlPlaneImage: os.Getenv("OVN_CONTROL_PLANE_IMAGE"),
CAConfigMap: caConfigMap,
CAConfigMapKey: caConfigMapKey,
}
}

func hyperShiftEnabled() bool {
return enabled == "true"
}

func (hc *HyperShiftConfig) SetRelatedObjects(relatedObjects []RelatedObject) {
hc.Lock()
defer hc.Unlock()
Expand Down
9 changes: 6 additions & 3 deletions pkg/network/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ package network
import (
"context"

operv1 "github.com/openshift/api/operator/v1"
"github.com/openshift/cluster-network-operator/pkg/bootstrap"
cnoclient "github.com/openshift/cluster-network-operator/pkg/client"
"github.com/openshift/cluster-network-operator/pkg/platform"

operv1 "github.com/openshift/api/operator/v1"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -36,6 +34,11 @@ func Bootstrap(conf *operv1.Network, client cnoclient.Client) (*bootstrap.Bootst

out.IPTablesAlerter = iptablesAlerterBootstrap(client.ClientFor("").CRClient())

out.TLSProfile, err = getTLSProfile(client)
if err != nil {
return nil, err
}

return out, nil
}

Expand Down
Loading