Skip to content

Commit 9f34f6a

Browse files
committed
Implement BaseComponentNetworkPolicy
1 parent fee5a93 commit 9f34f6a

File tree

3 files changed

+122
-6
lines changed

3 files changed

+122
-6
lines changed

api/v1/webspherelibertyapplication_types.go

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,13 +398,37 @@ type WebSphereLibertyApplicationNetworkPolicy struct {
398398
// +operator-sdk:csv:customresourcedefinitions:order=52,type=spec,displayName="Disable",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
399399
Disable *bool `json:"disable,omitempty"`
400400

401-
// Specify the labels of namespaces that incoming traffic is allowed from.
402-
// +operator-sdk:csv:customresourcedefinitions:order=53,type=spec,displayName="Namespace Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
401+
// Disable the creation of the network policy ingress. Defaults to false.
402+
// +operator-sdk:csv:customresourcedefinitions:order=53,type=spec,displayName="Disable Ingress",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
403+
DisableIngress *bool `json:"disableIngress,omitempty"`
404+
405+
// Disable the creation of the network policy egress. Defaults to false.
406+
// +operator-sdk:csv:customresourcedefinitions:order=54,type=spec,displayName="Disable Egress",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
407+
DisableEgress *bool `json:"disableEgress,omitempty"`
408+
409+
// Bypasses deny all egress rules to allow API server and DNS access. Defaults to false.
410+
// +operator-sdk:csv:customresourcedefinitions:order=55,type=spec,displayName="Bypass Deny All Egress",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
411+
BypassDenyAllEgress *bool `json:"bypassDenyAllEgress,omitempty"`
412+
413+
// Deprecated. .spec.networkPolicy.fromNamespaceLabels should be used instead. If both are specified, .spec.networkPolicy.fromNamespaceLabels will override this.
414+
// +operator-sdk:csv:customresourcedefinitions:order=56,type=spec,displayName="Namespace Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
403415
NamespaceLabels *map[string]string `json:"namespaceLabels,omitempty"`
404416

417+
// Specify the labels of namespaces that incoming traffic is allowed from.
418+
// +operator-sdk:csv:customresourcedefinitions:order=57,type=spec,displayName="From Namespace Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
419+
FromNamespaceLabels *map[string]string `json:"fromNamespaceLabels,omitempty"`
420+
405421
// Specify the labels of pod(s) that incoming traffic is allowed from.
406-
// +operator-sdk:csv:customresourcedefinitions:order=54,type=spec,displayName="From Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
422+
// +operator-sdk:csv:customresourcedefinitions:order=58,type=spec,displayName="From Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
407423
FromLabels *map[string]string `json:"fromLabels,omitempty"`
424+
425+
// Specify the labels of namespaces that outgoing traffic is allowed to.
426+
// +operator-sdk:csv:customresourcedefinitions:order=59,type=spec,displayName="To Namespace Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
427+
ToNamespaceLabels *map[string]string `json:"toNamespaceLabels,omitempty"`
428+
429+
// Specify the labels of pod(s) that outgoing traffic is allowed to.
430+
// +operator-sdk:csv:customresourcedefinitions:order=60,type=spec,displayName="To Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
431+
ToLabels *map[string]string `json:"toLabels,omitempty"`
408432
}
409433

410434
// Defines the desired state and cycle of applications.
@@ -1177,8 +1201,28 @@ func (s *WebSphereLibertyApplicationService) GetBindable() *bool {
11771201
return s.Bindable
11781202
}
11791203

1180-
// GetNamespaceLabels returns the namespace selector labels that should be used for the ingress rule
1181-
func (np *WebSphereLibertyApplicationNetworkPolicy) GetNamespaceLabels() map[string]string {
1204+
// GetToNamespaceLabels returns the namespace selector labels that should be used for the egress rule
1205+
func (np *WebSphereLibertyApplicationNetworkPolicy) GetToNamespaceLabels() map[string]string {
1206+
if np.ToNamespaceLabels != nil {
1207+
return *np.ToNamespaceLabels
1208+
}
1209+
return nil
1210+
}
1211+
1212+
// GetToLabels returns the pod selector labels that should be used for the egress rule
1213+
func (np *WebSphereLibertyApplicationNetworkPolicy) GetToLabels() map[string]string {
1214+
if np.ToLabels != nil {
1215+
return *np.ToLabels
1216+
}
1217+
return nil
1218+
}
1219+
1220+
// GetFromNamespaceLabels returns the namespace selector labels that should be used for the ingress rule
1221+
func (np *WebSphereLibertyApplicationNetworkPolicy) GetFromNamespaceLabels() map[string]string {
1222+
if np.FromNamespaceLabels != nil {
1223+
return *np.FromNamespaceLabels
1224+
}
1225+
// fallback to deprecated flag np.NamespaceLabels for when we only supported one type of network policy (ingress)
11821226
if np.NamespaceLabels != nil {
11831227
return *np.NamespaceLabels
11841228
}
@@ -1198,6 +1242,20 @@ func (np *WebSphereLibertyApplicationNetworkPolicy) IsDisabled() bool {
11981242
return np.Disable != nil && *np.Disable
11991243
}
12001244

1245+
// IsIngressDisabled returns whether the network policy ingress should be created or not
1246+
func (np *WebSphereLibertyApplicationNetworkPolicy) IsIngressDisabled() bool {
1247+
return np.DisableIngress != nil && *np.DisableIngress
1248+
}
1249+
1250+
// IsEgressDisabled returns whether the network policy egress should be created or not
1251+
func (np *WebSphereLibertyApplicationNetworkPolicy) IsEgressDisabled() bool {
1252+
return np.DisableEgress != nil && *np.DisableEgress
1253+
}
1254+
1255+
func (np *WebSphereLibertyApplicationNetworkPolicy) IsBypassingDenyAllEgress() bool {
1256+
return np.BypassDenyAllEgress != nil && *np.BypassDenyAllEgress
1257+
}
1258+
12011259
// GetLabels returns labels to be added on ServiceMonitor
12021260
func (m *WebSphereLibertyApplicationMonitoring) GetLabels() map[string]string {
12031261
return m.Labels

internal/controller/webspherelibertyapplication_controller.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ const applicationFinalizer = "finalizer.webspherelibertyapps.liberty.websphere.i
7373
// +kubebuilder:rbac:groups=apps,resources=deployments;statefulsets,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
7474
// +kubebuilder:rbac:groups=apps,resources=deployments/finalizers;statefulsets,verbs=update,namespace=websphere-liberty-operator
7575
// +kubebuilder:rbac:groups=core,resources=services;secrets;serviceaccounts;configmaps;persistentvolumeclaims,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
76+
// +kubebuilder:rbac:groups=core,resources=endpoints,verbs=get;list;watch,namespace=websphere-liberty-operator
7677
// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
7778
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
7879
// +kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator
@@ -456,7 +457,7 @@ func (r *ReconcileWebSphereLiberty) Reconcile(ctx context.Context, request ctrl.
456457
networkPolicy := &networkingv1.NetworkPolicy{ObjectMeta: defaultMeta}
457458
if np := instance.Spec.NetworkPolicy; np == nil || np != nil && !np.IsDisabled() {
458459
err = r.CreateOrUpdate(networkPolicy, instance, func() error {
459-
oputils.CustomizeNetworkPolicy(networkPolicy, r.IsOpenShift(), instance)
460+
oputils.CustomizeNetworkPolicy(networkPolicy, r.IsOpenShift(), r.getDNSEgressRule, r.getEndpoints, instance)
460461
return nil
461462
})
462463
if err != nil {
@@ -1022,3 +1023,38 @@ func (r *ReconcileWebSphereLiberty) deletePVC(reqLogger logr.Logger, pvcName str
10221023
}
10231024
}
10241025
}
1026+
1027+
func (r *ReconcileWebSphereLiberty) getEndpoints(serviceName string, namespace string) (*corev1.Endpoints, error) {
1028+
endpoints := &corev1.Endpoints{}
1029+
if err := r.GetClient().Get(context.TODO(), types.NamespacedName{Name: serviceName, Namespace: namespace}, endpoints); err != nil {
1030+
return nil, err
1031+
} else {
1032+
return endpoints, nil
1033+
}
1034+
}
1035+
1036+
func (r *ReconcileWebSphereLiberty) getDNSEgressRule(endpointsName string, endpointsNamespace string) (bool, networkingv1.NetworkPolicyEgressRule) {
1037+
dnsRule := networkingv1.NetworkPolicyEgressRule{}
1038+
if dnsEndpoints, err := r.getEndpoints(endpointsName, endpointsNamespace); err == nil {
1039+
if len(dnsEndpoints.Subsets) > 0 {
1040+
if endpointPort := lutils.GetEndpointPortByName(&dnsEndpoints.Subsets[0].Ports, "dns"); endpointPort != nil {
1041+
dnsRule.Ports = append(dnsRule.Ports, lutils.CreateNetworkPolicyPortFromEndpointPort(endpointPort))
1042+
}
1043+
if endpointPort := lutils.GetEndpointPortByName(&dnsEndpoints.Subsets[0].Ports, "dns-tcp"); endpointPort != nil {
1044+
dnsRule.Ports = append(dnsRule.Ports, lutils.CreateNetworkPolicyPortFromEndpointPort(endpointPort))
1045+
}
1046+
}
1047+
peer := networkingv1.NetworkPolicyPeer{}
1048+
peer.NamespaceSelector = &metav1.LabelSelector{
1049+
MatchLabels: map[string]string{
1050+
"kubernetes.io/metadata.name": endpointsNamespace,
1051+
},
1052+
}
1053+
dnsRule.To = append(dnsRule.To, peer)
1054+
return false, dnsRule
1055+
}
1056+
// use permissive rule
1057+
// egress:
1058+
// - {}
1059+
return true, dnsRule
1060+
}

utils/utils.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828

2929
"math/rand/v2"
3030

31+
networkingv1 "k8s.io/api/networking/v1"
32+
3133
wlv1 "github.com/WASdev/websphere-liberty-operator/api/v1"
3234
rcoutils "github.com/application-stacks/runtime-component-operator/utils"
3335
routev1 "github.com/openshift/api/route/v1"
@@ -37,6 +39,7 @@ import (
3739
"k8s.io/apimachinery/pkg/api/resource"
3840
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3941
"k8s.io/apimachinery/pkg/types"
42+
"k8s.io/apimachinery/pkg/util/intstr"
4043
"k8s.io/client-go/kubernetes"
4144
"k8s.io/client-go/kubernetes/scheme"
4245
"k8s.io/client-go/rest"
@@ -1001,6 +1004,25 @@ func GetRequiredLabels(name string, instance string) map[string]string {
10011004
return requiredLabels
10021005
}
10031006

1007+
func GetEndpointPortByName(endpointPorts *[]corev1.EndpointPort, name string) *corev1.EndpointPort {
1008+
if endpointPorts != nil {
1009+
for _, endpointPort := range *endpointPorts {
1010+
if endpointPort.Name == name {
1011+
return &endpointPort
1012+
}
1013+
}
1014+
}
1015+
return nil
1016+
}
1017+
1018+
func CreateNetworkPolicyPortFromEndpointPort(endpointPort *corev1.EndpointPort) networkingv1.NetworkPolicyPort {
1019+
port := networkingv1.NetworkPolicyPort{}
1020+
port.Protocol = &endpointPort.Protocol
1021+
var portNumber intstr.IntOrString = intstr.FromInt((int)(endpointPort.Port))
1022+
port.Port = &portNumber
1023+
return port
1024+
}
1025+
10041026
func IsOperandVersionString(version string) bool {
10051027
if !strings.Contains(version, "_") {
10061028
return false

0 commit comments

Comments
 (0)