From e745cfb0fe3d6ca772e343baa9aae8729e0a2113 Mon Sep 17 00:00:00 2001 From: Per Goncalves da Silva Date: Mon, 19 May 2025 20:54:03 +0200 Subject: [PATCH] Adds kube-apiserver egress to config map catalog source network policy Signed-off-by: Per Goncalves da Silva --- .../operators/catalog/operator_test.go | 123 ++++++++++++++---- pkg/controller/registry/reconciler/helpers.go | 19 ++- 2 files changed, 116 insertions(+), 26 deletions(-) diff --git a/pkg/controller/operators/catalog/operator_test.go b/pkg/controller/operators/catalog/operator_test.go index 2a688dfb9c..00a6e48d9a 100644 --- a/pkg/controller/operators/catalog/operator_test.go +++ b/pkg/controller/operators/catalog/operator_test.go @@ -889,7 +889,6 @@ func TestSyncCatalogSourcesSecurityPolicy(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), }, Spec: v1alpha1.CatalogSourceSpec{ Image: "catalog-image", @@ -908,7 +907,6 @@ func TestSyncCatalogSourcesSecurityPolicy(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), }, Spec: v1alpha1.CatalogSourceSpec{ Image: "catalog-image", @@ -934,7 +932,6 @@ func TestSyncCatalogSourcesSecurityPolicy(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), }, Spec: v1alpha1.CatalogSourceSpec{ Image: "catalog-image", @@ -953,7 +950,6 @@ func TestSyncCatalogSourcesSecurityPolicy(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), }, Spec: v1alpha1.CatalogSourceSpec{ Image: "catalog-image", @@ -1006,23 +1002,32 @@ func TestSyncCatalogSources(t *testing.T) { clockFake := utilclocktesting.NewFakeClock(time.Date(2018, time.January, 26, 20, 40, 0, 0, time.UTC)) now := metav1.NewTime(clockFake.Now()) - configmapCatalog := &v1alpha1.CatalogSource{ + internalCatalog := &v1alpha1.CatalogSource{ ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), }, Spec: v1alpha1.CatalogSourceSpec{ ConfigMap: "cool-configmap", SourceType: v1alpha1.SourceTypeInternal, }, } + configMapCatalog := &v1alpha1.CatalogSource{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cool-catalog", + Namespace: "cool-namespace", + }, + Spec: v1alpha1.CatalogSourceSpec{ + ConfigMap: "cool-configmap", + SourceType: v1alpha1.SourceTypeConfigmap, + }, + } grpcCatalog := &v1alpha1.CatalogSource{ ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), - Labels: map[string]string{"olm.catalogSource": "cool-catalog"}, + + Labels: map[string]string{"olm.catalogSource": "cool-catalog"}, }, Spec: v1alpha1.CatalogSourceSpec{ Image: "catalog-image", @@ -1047,7 +1052,6 @@ func TestSyncCatalogSources(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), }, Spec: v1alpha1.CatalogSourceSpec{ SourceType: "nope", @@ -1061,13 +1065,12 @@ func TestSyncCatalogSources(t *testing.T) { { testName: "CatalogSourceWithBackingConfigMap", namespace: "cool-namespace", - catalogSource: configmapCatalog, + catalogSource: internalCatalog, k8sObjs: []runtime.Object{ &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "cool-configmap", Namespace: "cool-namespace", - UID: types.UID("configmap-uid"), ResourceVersion: "resource-version", }, Data: fakeConfigMapData(), @@ -1077,7 +1080,6 @@ func TestSyncCatalogSources(t *testing.T) { ConfigMapResource: &v1alpha1.ConfigMapResourceReference{ Name: "cool-configmap", Namespace: "cool-namespace", - UID: types.UID("configmap-uid"), ResourceVersion: "resource-version", LastUpdateTime: now, }, @@ -1092,7 +1094,6 @@ func TestSyncCatalogSources(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), }, Spec: v1alpha1.CatalogSourceSpec{ ConfigMap: "cool-configmap", @@ -1102,7 +1103,6 @@ func TestSyncCatalogSources(t *testing.T) { ConfigMapResource: &v1alpha1.ConfigMapResourceReference{ Name: "cool-configmap", Namespace: "cool-namespace", - UID: types.UID("configmap-uid"), ResourceVersion: "resource-version", LastUpdateTime: now, }, @@ -1114,7 +1114,6 @@ func TestSyncCatalogSources(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cool-configmap", Namespace: "cool-namespace", - UID: types.UID("configmap-uid"), ResourceVersion: "resource-version", }, Data: fakeConfigMapData(), @@ -1124,7 +1123,6 @@ func TestSyncCatalogSources(t *testing.T) { ConfigMapResource: &v1alpha1.ConfigMapResourceReference{ Name: "cool-configmap", Namespace: "cool-namespace", - UID: types.UID("configmap-uid"), ResourceVersion: "resource-version", LastUpdateTime: now, }, @@ -1141,7 +1139,7 @@ func TestSyncCatalogSources(t *testing.T) { { testName: "CatalogSourceWithMissingConfigMap", namespace: "cool-namespace", - catalogSource: configmapCatalog, + catalogSource: internalCatalog, k8sObjs: []runtime.Object{ &corev1.ConfigMap{}, }, @@ -1175,8 +1173,8 @@ func TestSyncCatalogSources(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "cool-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), - Labels: map[string]string{"olm.catalogSource": "cool-catalog"}, + + Labels: map[string]string{"olm.catalogSource": "cool-catalog"}, }, Spec: v1alpha1.CatalogSourceSpec{ Image: "old-image", @@ -1198,6 +1196,19 @@ func TestSyncCatalogSources(t *testing.T) { pod(t, *grpcCatalog), }, }, + { + testName: "CatalogSourceWithGrpcType/CreatesNetworkPolicyResources", + namespace: "cool-namespace", + catalogSource: grpcCatalog, + expectedObjs: []runtime.Object{ + grpcServerNetworkPolicy(grpcCatalog, map[string]string{ + reconciler.CatalogSourceLabelKey: grpcCatalog.GetName(), + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }), + unpackBundlesNetworkPolicy(grpcCatalog), + }, + expectedError: nil, + }, { testName: "CatalogSourceWithGrpcType/EnsuresImageOrAddressIsSet", namespace: "cool-namespace", @@ -1205,8 +1216,8 @@ func TestSyncCatalogSources(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "invalid-spec-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), - Labels: map[string]string{"olm.catalogSource": "invalid-spec-catalog"}, + + Labels: map[string]string{"olm.catalogSource": "invalid-spec-catalog"}, }, Spec: v1alpha1.CatalogSourceSpec{ SourceType: v1alpha1.SourceTypeGrpc, @@ -1225,8 +1236,8 @@ func TestSyncCatalogSources(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "invalid-spec-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), - Labels: map[string]string{"olm.catalogSource": "invalid-spec-catalog"}, + + Labels: map[string]string{"olm.catalogSource": "invalid-spec-catalog"}, }, Spec: v1alpha1.CatalogSourceSpec{ SourceType: v1alpha1.SourceTypeInternal, @@ -1238,6 +1249,37 @@ func TestSyncCatalogSources(t *testing.T) { }, expectedError: nil, }, + { + testName: "CatalogSourceWithInternalType/CreatesNetworkPolicyResources", + namespace: "cool-namespace", + catalogSource: withStatus(*internalCatalog, v1alpha1.CatalogSourceStatus{ + ConfigMapResource: &v1alpha1.ConfigMapResourceReference{ + Name: "cool-configmap", + Namespace: "cool-namespace", + ResourceVersion: "resource-version", + LastUpdateTime: now, + }, + RegistryServiceStatus: nil, + }), + k8sObjs: []runtime.Object{ + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cool-configmap", + Namespace: "cool-namespace", + ResourceVersion: "resource-version", + }, + Data: fakeConfigMapData(), + }, + }, + expectedObjs: []runtime.Object{ + grpcServerNetworkPolicy(internalCatalog, map[string]string{ + reconciler.CatalogSourceLabelKey: internalCatalog.GetName(), + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }), + unpackBundlesNetworkPolicy(internalCatalog), + }, + expectedError: nil, + }, { testName: "CatalogSourceWithConfigMapType/EnsuresConfigMapIsSet", namespace: "cool-namespace", @@ -1245,8 +1287,8 @@ func TestSyncCatalogSources(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "invalid-spec-catalog", Namespace: "cool-namespace", - UID: types.UID("catalog-uid"), - Labels: map[string]string{"olm.catalogSource": "invalid-spec-catalog"}, + + Labels: map[string]string{"olm.catalogSource": "invalid-spec-catalog"}, }, Spec: v1alpha1.CatalogSourceSpec{ SourceType: v1alpha1.SourceTypeConfigmap, @@ -1258,6 +1300,37 @@ func TestSyncCatalogSources(t *testing.T) { }, expectedError: nil, }, + { + testName: "CatalogSourceWithConfigMapType/CreatesNetworkPolicyResources", + namespace: "cool-namespace", + catalogSource: withStatus(*configMapCatalog, v1alpha1.CatalogSourceStatus{ + ConfigMapResource: &v1alpha1.ConfigMapResourceReference{ + Name: "cool-configmap", + Namespace: "cool-namespace", + ResourceVersion: "resource-version", + LastUpdateTime: now, + }, + RegistryServiceStatus: nil, + }), + k8sObjs: []runtime.Object{ + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cool-configmap", + Namespace: "cool-namespace", + ResourceVersion: "resource-version", + }, + Data: fakeConfigMapData(), + }, + }, + expectedObjs: []runtime.Object{ + grpcServerNetworkPolicy(configMapCatalog, map[string]string{ + reconciler.CatalogSourceLabelKey: configMapCatalog.GetName(), + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }), + unpackBundlesNetworkPolicy(configMapCatalog), + }, + expectedError: nil, + }, { testName: "GRPCConnectionStateAddressIsUpdated", namespace: "cool-namespace", diff --git a/pkg/controller/registry/reconciler/helpers.go b/pkg/controller/registry/reconciler/helpers.go index 15f263e7bf..8302cd5df6 100644 --- a/pkg/controller/registry/reconciler/helpers.go +++ b/pkg/controller/registry/reconciler/helpers.go @@ -3,6 +3,8 @@ package reconciler import ( "fmt" + "github.com/operator-framework/api/pkg/operators/v1alpha1" + corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/api/equality" @@ -16,7 +18,7 @@ import ( "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" ) -func DesiredGRPCServerNetworkPolicy(catalogSource client.Object, matchLabels map[string]string) *networkingv1.NetworkPolicy { +func DesiredGRPCServerNetworkPolicy(catalogSource *v1alpha1.CatalogSource, matchLabels map[string]string) *networkingv1.NetworkPolicy { np := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%s-grpc-server", catalogSource.GetName()), @@ -43,6 +45,21 @@ func DesiredGRPCServerNetworkPolicy(catalogSource client.Object, matchLabels map }, }, } + + // Allow egress to kube-apiserver from configmap backed catalog sources + if catalogSource.Spec.SourceType == v1alpha1.SourceTypeConfigmap || catalogSource.Spec.SourceType == v1alpha1.SourceTypeInternal { + np.Spec.Egress = []networkingv1.NetworkPolicyEgressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Protocol: ptr.To(corev1.ProtocolTCP), + Port: ptr.To(intstr.FromInt32(6443)), + }, + }, + }, + } + } + ownerutil.AddOwner(np, catalogSource, false, false) return np }