Skip to content

Commit 437b8cb

Browse files
committed
include network policy for all configmap and grpc catalogsources
Signed-off-by: Joe Lanford <[email protected]>
1 parent c6ef935 commit 437b8cb

File tree

14 files changed

+852
-96
lines changed

14 files changed

+852
-96
lines changed

pkg/controller/operators/catalog/operator.go

+19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"google.golang.org/grpc/connectivity"
1919
batchv1 "k8s.io/api/batch/v1"
2020
corev1 "k8s.io/api/core/v1"
21+
networkingv1 "k8s.io/api/networking/v1"
2122
rbacv1 "k8s.io/api/rbac/v1"
2223
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
2324
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@@ -38,6 +39,7 @@ import (
3839
"k8s.io/apimachinery/pkg/util/yaml"
3940
batchv1applyconfigurations "k8s.io/client-go/applyconfigurations/batch/v1"
4041
corev1applyconfigurations "k8s.io/client-go/applyconfigurations/core/v1"
42+
networkingv1applyconfigurations "k8s.io/client-go/applyconfigurations/networking/v1"
4143
rbacv1applyconfigurations "k8s.io/client-go/applyconfigurations/rbac/v1"
4244
"k8s.io/client-go/dynamic"
4345
"k8s.io/client-go/informers"
@@ -600,6 +602,23 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo
600602
}
601603
}
602604

605+
// Wire NetworkPolicies
606+
networkPolicyInformer := k8sInformerFactory.Networking().V1().NetworkPolicies()
607+
op.lister.NetworkingV1().RegisterNetworkPolicyLister(metav1.NamespaceAll, networkPolicyInformer.Lister())
608+
sharedIndexInformers = append(sharedIndexInformers, networkPolicyInformer.Informer())
609+
610+
networkPoliciesGVR := networkingv1.SchemeGroupVersion.WithResource("networkpolicies")
611+
if err := labelObjects(networkPoliciesGVR, networkPolicyInformer.Informer(), labeller.ObjectLabeler[*networkingv1.NetworkPolicy, *networkingv1applyconfigurations.NetworkPolicyApplyConfiguration](
612+
ctx, op.logger, labeller.Filter(networkPoliciesGVR),
613+
networkPolicyInformer.Lister().List,
614+
networkingv1applyconfigurations.NetworkPolicy,
615+
func(namespace string, ctx context.Context, cfg *networkingv1applyconfigurations.NetworkPolicyApplyConfiguration, opts metav1.ApplyOptions) (*networkingv1.NetworkPolicy, error) {
616+
return op.opClient.KubernetesInterface().NetworkingV1().NetworkPolicies(namespace).Apply(ctx, cfg, opts)
617+
},
618+
)); err != nil {
619+
return nil, err
620+
}
621+
603622
// Wire Pods for CatalogSource
604623
catsrcReq, err := labels.NewRequirement(reconciler.CatalogSourceLabelKey, selection.Exists, nil)
605624
if err != nil {

pkg/controller/operators/catalog/operator_test.go

+21-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"gopkg.in/yaml.v2"
2626
appsv1 "k8s.io/api/apps/v1"
2727
corev1 "k8s.io/api/core/v1"
28+
networkingv1 "k8s.io/api/networking/v1"
2829
rbacv1 "k8s.io/api/rbac/v1"
2930
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3031
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
@@ -1276,6 +1277,10 @@ func TestSyncCatalogSources(t *testing.T) {
12761277
pod(t, *grpcCatalog),
12771278
service(grpcCatalog.GetName(), grpcCatalog.GetNamespace()),
12781279
serviceAccount(grpcCatalog.GetName(), grpcCatalog.GetNamespace(), "", objectReference("init secret")),
1280+
networkPolicy(grpcCatalog, map[string]string{
1281+
reconciler.CatalogSourceLabelKey: grpcCatalog.GetName(),
1282+
install.OLMManagedLabelKey: install.OLMManagedLabelValue,
1283+
}),
12791284
},
12801285
existingSources: []sourceAddress{
12811286
{
@@ -2128,14 +2133,25 @@ func NewFakeOperator(ctx context.Context, namespace string, namespaces []string,
21282133
serviceInformer := factory.Core().V1().Services()
21292134
podInformer := factory.Core().V1().Pods()
21302135
configMapInformer := factory.Core().V1().ConfigMaps()
2131-
sharedInformers = append(sharedInformers, roleInformer.Informer(), roleBindingInformer.Informer(), serviceAccountInformer.Informer(), serviceInformer.Informer(), podInformer.Informer(), configMapInformer.Informer())
2136+
networkPolicyInformer := factory.Networking().V1().NetworkPolicies()
2137+
2138+
sharedInformers = append(sharedInformers,
2139+
roleInformer.Informer(),
2140+
roleBindingInformer.Informer(),
2141+
serviceAccountInformer.Informer(),
2142+
serviceInformer.Informer(),
2143+
podInformer.Informer(),
2144+
configMapInformer.Informer(),
2145+
networkPolicyInformer.Informer(),
2146+
)
21322147

21332148
lister.RbacV1().RegisterRoleLister(metav1.NamespaceAll, roleInformer.Lister())
21342149
lister.RbacV1().RegisterRoleBindingLister(metav1.NamespaceAll, roleBindingInformer.Lister())
21352150
lister.CoreV1().RegisterServiceAccountLister(metav1.NamespaceAll, serviceAccountInformer.Lister())
21362151
lister.CoreV1().RegisterServiceLister(metav1.NamespaceAll, serviceInformer.Lister())
21372152
lister.CoreV1().RegisterPodLister(metav1.NamespaceAll, podInformer.Lister())
21382153
lister.CoreV1().RegisterConfigMapLister(metav1.NamespaceAll, configMapInformer.Lister())
2154+
lister.NetworkingV1().RegisterNetworkPolicyLister(metav1.NamespaceAll, networkPolicyInformer.Lister())
21392155
logger := logrus.New()
21402156

21412157
// Create the new operator
@@ -2319,6 +2335,10 @@ func configMap(name, namespace string) *corev1.ConfigMap {
23192335
}
23202336
}
23212337

2338+
func networkPolicy(catSrc *v1alpha1.CatalogSource, matchLabels map[string]string) *networkingv1.NetworkPolicy {
2339+
return reconciler.DesiredRegistryNetworkPolicy(catSrc, matchLabels)
2340+
}
2341+
23222342
func objectReference(name string) *corev1.ObjectReference {
23232343
if name == "" {
23242344
return &corev1.ObjectReference{}

pkg/controller/registry/reconciler/configmap.go

+43
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
pkgerrors "github.com/pkg/errors"
1212
"github.com/sirupsen/logrus"
1313
corev1 "k8s.io/api/core/v1"
14+
networkingv1 "k8s.io/api/networking/v1"
1415
rbacv1 "k8s.io/api/rbac/v1"
1516
apierrors "k8s.io/apimachinery/pkg/api/errors"
1617
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -121,6 +122,9 @@ func (s *configMapCatalogSourceDecorator) Pod(image string, defaultPodSecurityCo
121122
ownerutil.AddOwner(pod, s.CatalogSource, false, true)
122123
return pod, nil
123124
}
125+
func (s *configMapCatalogSourceDecorator) NetworkPolicy() *networkingv1.NetworkPolicy {
126+
return DesiredRegistryNetworkPolicy(s.CatalogSource, s.Labels())
127+
}
124128

125129
func (s *configMapCatalogSourceDecorator) ServiceAccount() *corev1.ServiceAccount {
126130
sa := &corev1.ServiceAccount{
@@ -210,6 +214,16 @@ func (c *ConfigMapRegistryReconciler) currentService(source configMapCatalogSour
210214
return service, nil
211215
}
212216

217+
func (c *ConfigMapRegistryReconciler) currentNetworkPolicy(source configMapCatalogSourceDecorator) *networkingv1.NetworkPolicy {
218+
npName := source.NetworkPolicy().GetName()
219+
np, err := c.Lister.NetworkingV1().NetworkPolicyLister().NetworkPolicies(source.GetNamespace()).Get(npName)
220+
if err != nil {
221+
logrus.WithField("networkPolicy", npName).WithError(err).Debug("couldn't find network policy in cache")
222+
return nil
223+
}
224+
return np
225+
}
226+
213227
func (c *ConfigMapRegistryReconciler) currentServiceAccount(source configMapCatalogSourceDecorator) *corev1.ServiceAccount {
214228
serviceAccountName := source.ServiceAccount().GetName()
215229
serviceAccount, err := c.Lister.CoreV1().ServiceAccountLister().ServiceAccounts(source.GetNamespace()).Get(serviceAccountName)
@@ -328,6 +342,9 @@ func (c *ConfigMapRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry,
328342
}
329343

330344
//TODO: if any of these error out, we should write a status back (possibly set RegistryServiceStatus to nil so they get recreated)
345+
if err := c.ensureNetworkPolicy(source); err != nil {
346+
return pkgerrors.Wrapf(err, "error ensuring network policy: %s", source.GetName())
347+
}
331348
if err := c.ensureServiceAccount(source, overwrite); err != nil {
332349
return pkgerrors.Wrapf(err, "error ensuring service account: %s", source.serviceAccountName())
333350
}
@@ -365,6 +382,20 @@ func (c *ConfigMapRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry,
365382
return nil
366383
}
367384

385+
func (c *ConfigMapRegistryReconciler) ensureNetworkPolicy(source configMapCatalogSourceDecorator) error {
386+
networkPolicy := source.NetworkPolicy()
387+
if currentNetworkPolicy := c.currentNetworkPolicy(source); currentNetworkPolicy != nil {
388+
if sanitizedDeepEqual(networkPolicy, currentNetworkPolicy) {
389+
return nil
390+
}
391+
if err := c.OpClient.DeleteNetworkPolicy(networkPolicy.GetNamespace(), networkPolicy.GetName(), metav1.NewDeleteOptions(0)); err != nil && !apierrors.IsNotFound(err) {
392+
return err
393+
}
394+
}
395+
_, err := c.OpClient.CreateNetworkPolicy(networkPolicy)
396+
return err
397+
}
398+
368399
func (c *ConfigMapRegistryReconciler) ensureServiceAccount(source configMapCatalogSourceDecorator, overwrite bool) error {
369400
serviceAccount := source.ServiceAccount()
370401
if c.currentServiceAccount(source) != nil {
@@ -497,6 +528,18 @@ func (c *ConfigMapRegistryReconciler) CheckRegistryServer(logger *logrus.Entry,
497528
// Check on registry resources
498529
// TODO: more complex checks for resources
499530
// TODO: add gRPC health check
531+
np := c.currentNetworkPolicy(source)
532+
if np == nil {
533+
logger.Error("registry service not healthy: could not get network policy")
534+
healthy = false
535+
return
536+
}
537+
if !sanitizedDeepEqual(source.NetworkPolicy(), np) {
538+
logger.Error("registry service not healthy: unexpected network policy")
539+
healthy = false
540+
return
541+
}
542+
500543
service, err := c.currentService(source)
501544
if err != nil {
502545
return false, err

pkg/controller/registry/reconciler/configmap_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/sirupsen/logrus"
1313
"github.com/stretchr/testify/require"
1414
corev1 "k8s.io/api/core/v1"
15+
networkingv1 "k8s.io/api/networking/v1"
1516
rbacv1 "k8s.io/api/rbac/v1"
1617
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
1718
"k8s.io/apimachinery/pkg/api/meta"
@@ -83,6 +84,7 @@ func fakeReconcilerFactory(t *testing.T, stopc <-chan struct{}, options ...fakeR
8384
serviceInformer := informerFactory.Core().V1().Services()
8485
podInformer := informerFactory.Core().V1().Pods()
8586
configMapInformer := informerFactory.Core().V1().ConfigMaps()
87+
networkPolicyInformer := informerFactory.Networking().V1().NetworkPolicies()
8688

8789
registryInformers := []cache.SharedIndexInformer{
8890
roleInformer.Informer(),
@@ -91,6 +93,7 @@ func fakeReconcilerFactory(t *testing.T, stopc <-chan struct{}, options ...fakeR
9193
serviceInformer.Informer(),
9294
podInformer.Informer(),
9395
configMapInformer.Informer(),
96+
networkPolicyInformer.Informer(),
9497
}
9598

9699
lister := operatorlister.NewLister()
@@ -100,6 +103,7 @@ func fakeReconcilerFactory(t *testing.T, stopc <-chan struct{}, options ...fakeR
100103
lister.CoreV1().RegisterServiceLister(testNamespace, serviceInformer.Lister())
101104
lister.CoreV1().RegisterPodLister(testNamespace, podInformer.Lister())
102105
lister.CoreV1().RegisterConfigMapLister(testNamespace, configMapInformer.Lister())
106+
lister.NetworkingV1().RegisterNetworkPolicyLister(testNamespace, networkPolicyInformer.Lister())
103107

104108
rec := &registryReconcilerFactory{
105109
now: config.now,
@@ -195,6 +199,7 @@ func objectsForCatalogSource(t *testing.T, catsrc *v1alpha1.CatalogSource) []run
195199
switch catsrc.Spec.SourceType {
196200
case v1alpha1.SourceTypeInternal, v1alpha1.SourceTypeConfigmap:
197201
decorated := configMapCatalogSourceDecorator{catsrc, runAsUser}
202+
np := decorated.NetworkPolicy()
198203
service, err := decorated.Service()
199204
if err != nil {
200205
t.Fatal(err)
@@ -205,13 +210,15 @@ func objectsForCatalogSource(t *testing.T, catsrc *v1alpha1.CatalogSource) []run
205210
t.Fatal(err)
206211
}
207212
objs = append(objs,
213+
np,
208214
pod,
209215
service,
210216
serviceAccount,
211217
)
212218
case v1alpha1.SourceTypeGrpc:
213219
if catsrc.Spec.Image != "" {
214220
decorated := grpcCatalogSourceDecorator{CatalogSource: catsrc, createPodAsUser: runAsUser, opmImage: ""}
221+
np := decorated.NetworkPolicy()
215222
serviceAccount := decorated.ServiceAccount()
216223
service, err := decorated.Service()
217224
if err != nil {
@@ -222,6 +229,7 @@ func objectsForCatalogSource(t *testing.T, catsrc *v1alpha1.CatalogSource) []run
222229
t.Fatal(err)
223230
}
224231
objs = append(objs,
232+
np,
225233
pod,
226234
service,
227235
serviceAccount,
@@ -342,6 +350,24 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
342350
},
343351
},
344352
},
353+
{
354+
testName: "ExistingRegistry/BadNetworkPolicy",
355+
in: in{
356+
cluster: cluster{
357+
k8sObjs: append(setLabel(objectsForCatalogSource(t, validCatalogSource), &networkingv1.NetworkPolicy{}, CatalogSourceLabelKey, "wrongValue"), validConfigMap),
358+
},
359+
catsrc: validCatalogSource,
360+
},
361+
out: out{
362+
status: &v1alpha1.RegistryServiceStatus{
363+
CreatedAt: now(),
364+
Protocol: "grpc",
365+
ServiceName: "cool-catalog",
366+
ServiceNamespace: testNamespace,
367+
Port: "50051",
368+
},
369+
},
370+
},
345371
{
346372
testName: "ExistingRegistry/BadServiceAccount",
347373
in: in{
@@ -504,6 +530,11 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
504530
require.Equal(t, pod.GetLabels(), outPod.GetLabels())
505531
require.Equal(t, pod.Spec, outPod.Spec)
506532

533+
np := decorated.NetworkPolicy()
534+
outNp, err := client.KubernetesInterface().NetworkingV1().NetworkPolicies(np.GetNamespace()).Get(context.TODO(), np.GetName(), metav1.GetOptions{})
535+
require.NoError(t, err)
536+
require.Equal(t, np, outNp)
537+
507538
service, err := decorated.Service()
508539
require.NoError(t, err)
509540
outService, err := client.KubernetesInterface().CoreV1().Services(service.GetNamespace()).Get(context.TODO(), service.GetName(), metav1.GetOptions{})

pkg/controller/registry/reconciler/grpc.go

+45
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
pkgerrors "github.com/pkg/errors"
2020
"github.com/sirupsen/logrus"
2121
corev1 "k8s.io/api/core/v1"
22+
networkingv1 "k8s.io/api/networking/v1"
2223
apierrors "k8s.io/apimachinery/pkg/api/errors"
2324
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2425
"k8s.io/apimachinery/pkg/labels"
@@ -102,6 +103,10 @@ func (s *grpcCatalogSourceDecorator) Service() (*corev1.Service, error) {
102103
return svc, nil
103104
}
104105

106+
func (s *grpcCatalogSourceDecorator) NetworkPolicy() *networkingv1.NetworkPolicy {
107+
return DesiredRegistryNetworkPolicy(s.CatalogSource, s.Labels())
108+
}
109+
105110
func (s *grpcCatalogSourceDecorator) ServiceAccount() *corev1.ServiceAccount {
106111
var secrets []corev1.LocalObjectReference
107112
blockOwnerDeletion := true
@@ -153,6 +158,16 @@ type GrpcRegistryReconciler struct {
153158

154159
var _ RegistryReconciler = &GrpcRegistryReconciler{}
155160

161+
func (c *GrpcRegistryReconciler) currentNetworkPolicy(source grpcCatalogSourceDecorator) *networkingv1.NetworkPolicy {
162+
npName := source.NetworkPolicy().GetName()
163+
np, err := c.Lister.NetworkingV1().NetworkPolicyLister().NetworkPolicies(source.GetNamespace()).Get(npName)
164+
if err != nil {
165+
logrus.WithField("networkPolicy", npName).WithError(err).Debug("couldn't find network policy in cache")
166+
return nil
167+
}
168+
return np
169+
}
170+
156171
func (c *GrpcRegistryReconciler) currentService(source grpcCatalogSourceDecorator) (*corev1.Service, error) {
157172
protoService, err := source.Service()
158173
if err != nil {
@@ -261,6 +276,11 @@ func (c *GrpcRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry, cata
261276
}
262277

263278
//TODO: if any of these error out, we should write a status back (possibly set RegistryServiceStatus to nil so they get recreated)
279+
if err := c.ensureNetworkPolicy(source); err != nil {
280+
logger.WithError(err).Error("error ensuring registry server: could not ensure registry network policy")
281+
return pkgerrors.Wrapf(err, "error ensuring network policy: %s", source.GetName())
282+
}
283+
264284
sa, err := c.ensureSA(source)
265285
if err != nil && !apierrors.IsAlreadyExists(err) {
266286
logger.WithError(err).Error("error ensuring registry server: could not ensure registry service account")
@@ -467,6 +487,20 @@ func (c *GrpcRegistryReconciler) ensureService(source grpcCatalogSourceDecorator
467487
return err
468488
}
469489

490+
func (c *GrpcRegistryReconciler) ensureNetworkPolicy(source grpcCatalogSourceDecorator) error {
491+
networkPolicy := source.NetworkPolicy()
492+
if currentNetworkPolicy := c.currentNetworkPolicy(source); currentNetworkPolicy != nil {
493+
if sanitizedDeepEqual(networkPolicy, currentNetworkPolicy) {
494+
return nil
495+
}
496+
if err := c.OpClient.DeleteNetworkPolicy(networkPolicy.GetNamespace(), networkPolicy.GetName(), metav1.NewDeleteOptions(0)); err != nil && !apierrors.IsNotFound(err) {
497+
return err
498+
}
499+
}
500+
_, err := c.OpClient.CreateNetworkPolicy(networkPolicy)
501+
return err
502+
}
503+
470504
func (c *GrpcRegistryReconciler) ensureSA(source grpcCatalogSourceDecorator) (*corev1.ServiceAccount, error) {
471505
sa := source.ServiceAccount()
472506
if _, err := c.OpClient.CreateServiceAccount(sa); err != nil {
@@ -606,6 +640,17 @@ func (c *GrpcRegistryReconciler) CheckRegistryServer(logger *logrus.Entry, catal
606640

607641
// Check on registry resources
608642
// TODO: add gRPC health check
643+
currentNetworkPolicy := c.currentNetworkPolicy(source)
644+
if currentNetworkPolicy == nil {
645+
logger.Error("registry service not healthy: could not get network policy")
646+
return false, nil
647+
}
648+
expectedNetworkPolicy := source.NetworkPolicy()
649+
if !sanitizedDeepEqual(expectedNetworkPolicy, currentNetworkPolicy) {
650+
logger.Error("registry service not healthy: unexpected network policy")
651+
return false, nil
652+
}
653+
609654
service, err := c.currentService(source)
610655
if err != nil {
611656
logger.WithError(err).Error("registry service not healthy: could not get current service")

0 commit comments

Comments
 (0)