Skip to content

Commit 144cb8d

Browse files
committed
Implement BaseComponentNetworkPolicy
1 parent e81ad99 commit 144cb8d

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
@@ -414,13 +414,37 @@ type WebSphereLibertyApplicationNetworkPolicy struct {
414414
// +operator-sdk:csv:customresourcedefinitions:order=52,type=spec,displayName="Disable",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
415415
Disable *bool `json:"disable,omitempty"`
416416

417-
// Specify the labels of namespaces that incoming traffic is allowed from.
418-
// +operator-sdk:csv:customresourcedefinitions:order=53,type=spec,displayName="Namespace Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
417+
// Disable the creation of the network policy ingress. Defaults to false.
418+
// +operator-sdk:csv:customresourcedefinitions:order=53,type=spec,displayName="Disable Ingress",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
419+
DisableIngress *bool `json:"disableIngress,omitempty"`
420+
421+
// Disable the creation of the network policy egress. Defaults to false.
422+
// +operator-sdk:csv:customresourcedefinitions:order=54,type=spec,displayName="Disable Egress",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
423+
DisableEgress *bool `json:"disableEgress,omitempty"`
424+
425+
// Bypasses deny all egress rules to allow API server and DNS access. Defaults to false.
426+
// +operator-sdk:csv:customresourcedefinitions:order=55,type=spec,displayName="Bypass Deny All Egress",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
427+
BypassDenyAllEgress *bool `json:"bypassDenyAllEgress,omitempty"`
428+
429+
// Deprecated. .spec.networkPolicy.fromNamespaceLabels should be used instead. If both are specified, .spec.networkPolicy.fromNamespaceLabels will override this.
430+
// +operator-sdk:csv:customresourcedefinitions:order=56,type=spec,displayName="Namespace Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
419431
NamespaceLabels *map[string]string `json:"namespaceLabels,omitempty"`
420432

433+
// Specify the labels of namespaces that incoming traffic is allowed from.
434+
// +operator-sdk:csv:customresourcedefinitions:order=57,type=spec,displayName="From Namespace Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
435+
FromNamespaceLabels *map[string]string `json:"fromNamespaceLabels,omitempty"`
436+
421437
// Specify the labels of pod(s) that incoming traffic is allowed from.
422-
// +operator-sdk:csv:customresourcedefinitions:order=54,type=spec,displayName="From Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
438+
// +operator-sdk:csv:customresourcedefinitions:order=58,type=spec,displayName="From Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
423439
FromLabels *map[string]string `json:"fromLabels,omitempty"`
440+
441+
// Specify the labels of namespaces that outgoing traffic is allowed to.
442+
// +operator-sdk:csv:customresourcedefinitions:order=59,type=spec,displayName="To Namespace Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
443+
ToNamespaceLabels *map[string]string `json:"toNamespaceLabels,omitempty"`
444+
445+
// Specify the labels of pod(s) that outgoing traffic is allowed to.
446+
// +operator-sdk:csv:customresourcedefinitions:order=60,type=spec,displayName="To Labels",xDescriptors="urn:alm:descriptor:com.tectonic.ui:text"
447+
ToLabels *map[string]string `json:"toLabels,omitempty"`
424448
}
425449

426450
// Defines the desired state and cycle of applications.
@@ -1211,8 +1235,28 @@ func (ssa *WebSphereLibertyApplicationServiceSessionAffinity) GetConfig() *corev
12111235
return ssa.Config
12121236
}
12131237

1214-
// GetNamespaceLabels returns the namespace selector labels that should be used for the ingress rule
1215-
func (np *WebSphereLibertyApplicationNetworkPolicy) GetNamespaceLabels() map[string]string {
1238+
// GetToNamespaceLabels returns the namespace selector labels that should be used for the egress rule
1239+
func (np *WebSphereLibertyApplicationNetworkPolicy) GetToNamespaceLabels() map[string]string {
1240+
if np.ToNamespaceLabels != nil {
1241+
return *np.ToNamespaceLabels
1242+
}
1243+
return nil
1244+
}
1245+
1246+
// GetToLabels returns the pod selector labels that should be used for the egress rule
1247+
func (np *WebSphereLibertyApplicationNetworkPolicy) GetToLabels() map[string]string {
1248+
if np.ToLabels != nil {
1249+
return *np.ToLabels
1250+
}
1251+
return nil
1252+
}
1253+
1254+
// GetFromNamespaceLabels returns the namespace selector labels that should be used for the ingress rule
1255+
func (np *WebSphereLibertyApplicationNetworkPolicy) GetFromNamespaceLabels() map[string]string {
1256+
if np.FromNamespaceLabels != nil {
1257+
return *np.FromNamespaceLabels
1258+
}
1259+
// fallback to deprecated flag np.NamespaceLabels for when we only supported one type of network policy (ingress)
12161260
if np.NamespaceLabels != nil {
12171261
return *np.NamespaceLabels
12181262
}
@@ -1232,6 +1276,20 @@ func (np *WebSphereLibertyApplicationNetworkPolicy) IsDisabled() bool {
12321276
return np.Disable != nil && *np.Disable
12331277
}
12341278

1279+
// IsIngressDisabled returns whether the network policy ingress should be created or not
1280+
func (np *WebSphereLibertyApplicationNetworkPolicy) IsIngressDisabled() bool {
1281+
return np.DisableIngress != nil && *np.DisableIngress
1282+
}
1283+
1284+
// IsEgressDisabled returns whether the network policy egress should be created or not
1285+
func (np *WebSphereLibertyApplicationNetworkPolicy) IsEgressDisabled() bool {
1286+
return np.DisableEgress != nil && *np.DisableEgress
1287+
}
1288+
1289+
func (np *WebSphereLibertyApplicationNetworkPolicy) IsBypassingDenyAllEgress() bool {
1290+
return np.BypassDenyAllEgress != nil && *np.BypassDenyAllEgress
1291+
}
1292+
12351293
// GetLabels returns labels to be added on ServiceMonitor
12361294
func (m *WebSphereLibertyApplicationMonitoring) GetLabels() map[string]string {
12371295
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)