Skip to content

Commit 711a76d

Browse files
committed
Add API server NetworkPolicy to support a potential deny all egress
1 parent e7e2fb3 commit 711a76d

File tree

13 files changed

+235
-482
lines changed

13 files changed

+235
-482
lines changed

bundle/manifests/ibm-websphere-liberty.clusterserviceversion.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ metadata:
6262
capabilities: Auto Pilot
6363
categories: Application Runtime
6464
containerImage: icr.io/cpopen/websphere-liberty-operator:daily
65-
createdAt: "2024-01-30T02:09:24Z"
65+
createdAt: "2024-02-22T16:01:09Z"
6666
description: Deploy and manage containerized Liberty applications
6767
olm.skipRange: '>=1.0.0 <1.3.1'
6868
operators.openshift.io/infrastructure-features: '["disconnected"]'
@@ -1034,6 +1034,13 @@ spec:
10341034
- list
10351035
- update
10361036
- watch
1037+
- apiGroups:
1038+
- ""
1039+
resources:
1040+
- endpoints
1041+
verbs:
1042+
- get
1043+
- list
10371044
- apiGroups:
10381045
- ""
10391046
resources:

config/rbac/role.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ rules:
7474
- list
7575
- update
7676
- watch
77+
- apiGroups:
78+
- ""
79+
resources:
80+
- endpoints
81+
verbs:
82+
- get
83+
- list
7784
- apiGroups:
7885
- ""
7986
resources:

controllers/ltpa_keys_sharing.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ func (r *ReconcileWebSphereLiberty) generateLTPAKeys(instance *wlv1.WebSphereLib
231231
err = r.GetClient().Get(context.TODO(), types.NamespacedName{Name: generateLTPAKeysJob.Name, Namespace: generateLTPAKeysJob.Namespace}, generateLTPAKeysJob)
232232
if err != nil && kerrors.IsNotFound(err) {
233233
err = r.CreateOrUpdate(generateLTPAKeysJob, instance, func() error {
234-
lutils.CustomizeLTPAJob(generateLTPAKeysJob, instance, ltpaSecret.Name, ltpaServiceAccountName, ltpaKeysCreationScriptConfigMap.Name)
234+
lutils.CustomizeLTPAJob(generateLTPAKeysJob, instance, ltpaSecret.Name, ltpaServiceAccountName, ltpaKeysCreationScriptConfigMap.Name, OperatorAllowAPIServerAccessLabel)
235235
return nil
236236
})
237237
if err != nil {

controllers/webspherelibertyapplication_controller.go

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343
kerrors "k8s.io/apimachinery/pkg/api/errors"
4444
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4545
"k8s.io/apimachinery/pkg/types"
46+
"k8s.io/apimachinery/pkg/util/intstr"
4647
servingv1 "knative.dev/serving/pkg/apis/serving/v1"
4748
ctrl "sigs.k8s.io/controller-runtime"
4849
"sigs.k8s.io/controller-runtime/pkg/builder"
@@ -54,8 +55,9 @@ import (
5455
)
5556

5657
const (
57-
OperatorName = "websphere-liberty-operator"
58-
OperatorShortName = "wlo"
58+
OperatorName = "websphere-liberty-operator"
59+
OperatorShortName = "wlo"
60+
OperatorAllowAPIServerAccessLabel = "webspherelibertyapps.liberty.websphere.ibm.com/allow-apiserver-access"
5961
)
6062

6163
// ReconcileWebSphereLiberty reconciles a WebSphereLibertyApplication object
@@ -74,6 +76,7 @@ const applicationFinalizer = "finalizer.webspherelibertyapps.liberty.websphere.i
7476
// +kubebuilder:rbac:groups=apps,resources=deployments;statefulsets,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
7577
// +kubebuilder:rbac:groups=apps,resources=deployments/finalizers;statefulsets,verbs=update,namespace=websphere-liberty-operator
7678
// +kubebuilder:rbac:groups=core,resources=services;secrets;serviceaccounts;configmaps;persistentvolumeclaims,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
79+
// +kubebuilder:rbac:groups=core,resources=endpoints,verbs=get;list,namespace=websphere-liberty-operator
7780
// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
7881
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
7982
// +kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
@@ -395,6 +398,53 @@ func (r *ReconcileWebSphereLiberty) Reconcile(ctx context.Context, request ctrl.
395398
common.StatusConditionTypeReconciled, instance)
396399
}
397400

401+
// Kube API Server NetworkPolicy (credit to Martin Smithson)
402+
apiServerNetworkPolicy := &networkingv1.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{
403+
Name: instance.Name + "-egress-apiserver-access",
404+
Namespace: instance.Namespace,
405+
}}
406+
apiServerEndpoints, err := r.getKubeAPIServerEndpoints()
407+
apiServerNetworkPolicy.Spec.PodSelector = metav1.LabelSelector{
408+
MatchLabels: map[string]string{
409+
OperatorAllowAPIServerAccessLabel: "true",
410+
},
411+
}
412+
rule := networkingv1.NetworkPolicyEgressRule{}
413+
if err == nil {
414+
// Define the port
415+
port := networkingv1.NetworkPolicyPort{}
416+
port.Protocol = &apiServerEndpoints.Subsets[0].Ports[0].Protocol
417+
var portNumber intstr.IntOrString = intstr.FromInt((int)(apiServerEndpoints.Subsets[0].Ports[0].Port))
418+
port.Port = &portNumber
419+
rule.Ports = append(rule.Ports, port)
420+
421+
// Add the endpoint address as ipBlock entries
422+
for _, endpoint := range apiServerEndpoints.Subsets {
423+
for _, address := range endpoint.Addresses {
424+
peer := networkingv1.NetworkPolicyPeer{}
425+
ipBlock := networkingv1.IPBlock{}
426+
ipBlock.CIDR = address.IP + "/32"
427+
428+
peer.IPBlock = &ipBlock
429+
rule.To = append(rule.To, peer)
430+
}
431+
}
432+
} else {
433+
peer := networkingv1.NetworkPolicyPeer{}
434+
peer.NamespaceSelector = &metav1.LabelSelector{
435+
MatchLabels: map[string]string{},
436+
}
437+
rule.To = append(rule.To, peer)
438+
reqLogger.Info("Failed to retrieve endpoints for kubernetes service in the default namespace. Using more permissive rule.")
439+
}
440+
apiServerNetworkPolicy.Spec.Egress = append(apiServerNetworkPolicy.Spec.Egress, rule)
441+
err = r.CreateOrUpdate(apiServerNetworkPolicy, instance, func() error {
442+
apiServerNetworkPolicy.Labels = ba.GetLabels()
443+
apiServerNetworkPolicy.Annotations = oputils.MergeMaps(apiServerNetworkPolicy.Annotations, ba.GetAnnotations())
444+
apiServerNetworkPolicy.Spec.PolicyTypes = []networkingv1.PolicyType{networkingv1.PolicyTypeEgress}
445+
return nil
446+
})
447+
398448
networkPolicy := &networkingv1.NetworkPolicy{ObjectMeta: defaultMeta}
399449
if np := instance.Spec.NetworkPolicy; np == nil || np != nil && !np.IsDisabled() {
400450
err = r.CreateOrUpdate(networkPolicy, instance, func() error {
@@ -885,3 +935,14 @@ func shouldDeleteRoute(ba common.BaseComponent) bool {
885935
}
886936
return false
887937
}
938+
939+
func (r *ReconcileWebSphereLiberty) getKubeAPIServerEndpoints() (*corev1.Endpoints, error) {
940+
serviceName := "kubernetes"
941+
namespace := "default"
942+
endpoints := &corev1.Endpoints{}
943+
if err := r.GetClient().Get(context.TODO(), types.NamespacedName{Name: serviceName, Namespace: namespace}, endpoints); err != nil {
944+
return nil, err
945+
} else {
946+
return endpoints, nil
947+
}
948+
}

go.mod

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.21
55
require (
66
github.com/application-stacks/runtime-component-operator v1.0.0-20220602-0850.0.20240314154848-960659e893e0
77
github.com/cert-manager/cert-manager v1.10.2
8-
github.com/go-logr/logr v1.2.4
8+
github.com/go-logr/logr v1.3.0
99
github.com/openshift/api v0.0.0-20230928134114-673ed0cfc7f1
1010
github.com/openshift/library-go v0.0.0-20231002074440-3f69f773d102
1111
github.com/pkg/errors v0.9.1
@@ -18,7 +18,8 @@ require (
1818
)
1919

2020
require (
21-
cloud.google.com/go v0.99.0 // indirect
21+
cloud.google.com/go/compute v1.20.1 // indirect
22+
cloud.google.com/go/compute/metadata v0.2.3 // indirect
2223
github.com/beorn7/perks v1.0.1 // indirect
2324
github.com/blang/semver v3.5.1+incompatible // indirect
2425
github.com/blendle/zapdriver v1.3.1 // indirect
@@ -27,16 +28,16 @@ require (
2728
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
2829
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
2930
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
30-
github.com/fsnotify/fsnotify v1.5.4 // indirect
31+
github.com/fsnotify/fsnotify v1.7.0 // indirect
3132
github.com/go-logr/zapr v1.2.3 // indirect
32-
github.com/go-openapi/jsonpointer v0.19.5 // indirect
33-
github.com/go-openapi/jsonreference v0.20.0 // indirect
33+
github.com/go-openapi/jsonpointer v0.19.6 // indirect
34+
github.com/go-openapi/jsonreference v0.20.2 // indirect
3435
github.com/go-openapi/swag v0.22.3 // indirect
3536
github.com/gogo/protobuf v1.3.2 // indirect
3637
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
3738
github.com/golang/protobuf v1.5.3 // indirect
3839
github.com/google/gnostic v0.6.9 // indirect
39-
github.com/google/go-cmp v0.5.9 // indirect
40+
github.com/google/go-cmp v0.6.0 // indirect
4041
github.com/google/go-containerregistry v0.13.0 // indirect
4142
github.com/google/gofuzz v1.2.0 // indirect
4243
github.com/google/uuid v1.3.0 // indirect
@@ -49,37 +50,42 @@ require (
4950
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
5051
github.com/modern-go/reflect2 v1.0.2 // indirect
5152
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
53+
github.com/onsi/ginkgo/v2 v2.9.4 // indirect
54+
github.com/onsi/gomega v1.27.6 // indirect
5255
github.com/opencontainers/go-digest v1.0.0 // indirect
53-
github.com/prometheus/client_golang v1.13.0 // indirect
54-
github.com/prometheus/client_model v0.2.0 // indirect
55-
github.com/prometheus/common v0.37.0 // indirect
56-
github.com/prometheus/procfs v0.8.0 // indirect
56+
github.com/prometheus/client_golang v1.16.0 // indirect
57+
github.com/prometheus/client_model v0.4.0 // indirect
58+
github.com/prometheus/common v0.44.0 // indirect
59+
github.com/prometheus/procfs v0.10.1 // indirect
5760
github.com/spf13/pflag v1.0.5 // indirect
58-
go.uber.org/atomic v1.9.0 // indirect
59-
go.uber.org/multierr v1.6.0 // indirect
61+
github.com/stretchr/testify v1.8.2 // indirect
62+
go.uber.org/atomic v1.10.0 // indirect
63+
go.uber.org/goleak v1.2.1 // indirect
64+
go.uber.org/multierr v1.11.0 // indirect
6065
go.uber.org/zap v1.21.0 // indirect
61-
golang.org/x/net v0.17.0 // indirect
62-
golang.org/x/oauth2 v0.7.0 // indirect
63-
golang.org/x/sys v0.13.0 // indirect
64-
golang.org/x/term v0.13.0 // indirect
65-
golang.org/x/text v0.13.0 // indirect
66-
golang.org/x/time v0.1.0 // indirect
66+
golang.org/x/mod v0.10.0 // indirect
67+
golang.org/x/net v0.19.0 // indirect
68+
golang.org/x/oauth2 v0.10.0 // indirect
69+
golang.org/x/sys v0.15.0 // indirect
70+
golang.org/x/term v0.15.0 // indirect
71+
golang.org/x/text v0.14.0 // indirect
72+
golang.org/x/time v0.3.0 // indirect
6773
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
6874
google.golang.org/appengine v1.6.7 // indirect
69-
google.golang.org/protobuf v1.30.0 // indirect
75+
google.golang.org/protobuf v1.31.0 // indirect
7076
gopkg.in/inf.v0 v0.9.1 // indirect
7177
gopkg.in/yaml.v2 v2.4.0 // indirect
7278
gopkg.in/yaml.v3 v3.0.1 // indirect
7379
k8s.io/apiextensions-apiserver v0.25.4 // indirect
7480
k8s.io/component-base v0.25.4 // indirect
75-
k8s.io/klog/v2 v2.80.2-0.20221028030830-9ae4992afb54 // indirect
76-
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
77-
k8s.io/utils v0.0.0-20221108210102-8e77b1f39fe2 // indirect
81+
k8s.io/klog/v2 v2.110.1 // indirect
82+
k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 // indirect
83+
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
7884
knative.dev/networking v0.0.0-20231012063223-0b0f2107abef // indirect
7985
knative.dev/pkg v0.0.0-20231023160942-0c39ce4b3a7f // indirect
8086
sigs.k8s.io/gateway-api v0.5.0 // indirect
81-
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
82-
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
87+
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
88+
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
8389
sigs.k8s.io/yaml v1.3.0 // indirect
8490
)
8591

0 commit comments

Comments
 (0)