Skip to content

Commit

Permalink
Add support for external traffic network policies that are restricted…
Browse files Browse the repository at this point in the history
… to only allow the Ingress controller, rather than all traffic (#452)
  • Loading branch information
orishoshan authored Jul 8, 2024
1 parent 317cdf1 commit 00faac0
Show file tree
Hide file tree
Showing 16 changed files with 1,067 additions and 383 deletions.
1 change: 1 addition & 0 deletions src/operator/api/v1alpha3/clientintents_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const (
OtterizeAccessLabelPrefix = "intents.otterize.com/access"
OtterizeServiceAccessLabelPrefix = "intents.otterize.com/svc-access"
OtterizeAccessLabelKey = "intents.otterize.com/access-%s"
OtterizeExternalAccessLabelKey = "intents.otterize.com/external-access-%s"
OtterizeSvcAccessLabelKey = "intents.otterize.com/svc-access-%s"
OtterizeClientLabelKey = "intents.otterize.com/client"
OtterizeServiceLabelKey = "intents.otterize.com/service"
Expand Down
9 changes: 9 additions & 0 deletions src/operator/api/v1alpha3/otterize_labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ func IsMissingOtterizeAccessLabels(pod *v1.Pod, otterizeAccessLabels map[string]
return false
}

func IsMissingOtterizeExternalAccessLabels(pod *v1.Pod) bool {
if pod.Labels == nil {
return true
}

_, found := pod.Labels[OtterizeExternalAccessLabelKey]
return !found
}

// UpdateOtterizeAccessLabels updates a pod's labels with Otterize labels representing their intents
// The pod is also labeled with "otterize-client=<hashed-client-name>" to mark it as having intents or being the client-side of an egress netpol
func UpdateOtterizeAccessLabels(pod *v1.Pod, serviceIdentity serviceidentity.ServiceIdentity, otterizeAccessLabels map[string]string) *v1.Pod {
Expand Down
37 changes: 29 additions & 8 deletions src/operator/controllers/external_traffic/network_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,23 @@ type NetworkPolicyHandler struct {
client client.Client
scheme *runtime.Scheme
injectablerecorder.InjectableRecorder
allowExternalTraffic allowexternaltraffic.Enum
allowExternalTraffic allowexternaltraffic.Enum
ingressControllerIdentities []serviceidentity.ServiceIdentity
}

func NewNetworkPolicyHandler(
client client.Client,
scheme *runtime.Scheme,
allowExternalTraffic allowexternaltraffic.Enum,
ingressControllerIdentities []serviceidentity.ServiceIdentity,
) *NetworkPolicyHandler {
return &NetworkPolicyHandler{client: client, scheme: scheme, allowExternalTraffic: allowExternalTraffic}
return &NetworkPolicyHandler{client: client, scheme: scheme, allowExternalTraffic: allowExternalTraffic, ingressControllerIdentities: ingressControllerIdentities}
}

func (r *NetworkPolicyHandler) createOrUpdateNetworkPolicy(
ctx context.Context, endpoints *corev1.Endpoints, owner *corev1.Service, otterizeServiceName string, selector metav1.LabelSelector, ingressList *v1.IngressList, successMsg string) error {
policyName := r.formatPolicyName(endpoints.Name)
newPolicy := buildNetworkPolicyObjectForEndpoints(endpoints, otterizeServiceName, selector, ingressList, policyName)
newPolicy := r.buildNetworkPolicyObjectForEndpoints(endpoints, owner, otterizeServiceName, selector, ingressList, policyName)
err := controllerutil.SetOwnerReference(owner, newPolicy, r.scheme)
if err != nil {
return errors.Wrap(err)
Expand Down Expand Up @@ -112,9 +114,8 @@ func (r *NetworkPolicyHandler) arePoliciesEqual(existingPolicy *v1.NetworkPolicy
reflect.DeepEqual(existingPolicy.OwnerReferences, newPolicy.OwnerReferences)
}

func buildNetworkPolicyObjectForEndpoints(
endpoints *corev1.Endpoints, otterizeServiceName string, selector metav1.LabelSelector, ingressList *v1.IngressList, policyName string) *v1.NetworkPolicy {
serviceSpecCopy := endpoints.Subsets
func (r *NetworkPolicyHandler) buildNetworkPolicyObjectForEndpoints(
endpoints *corev1.Endpoints, svc *corev1.Service, otterizeServiceName string, selector metav1.LabelSelector, ingressList *v1.IngressList, policyName string) *v1.NetworkPolicy {

annotations := map[string]string{
v1alpha3.OtterizeCreatedForServiceAnnotation: endpoints.GetName(),
Expand All @@ -126,6 +127,26 @@ func buildNetworkPolicyObjectForEndpoints(
}), ",")
}

rule := v1.NetworkPolicyIngressRule{}
// Only limit netpol if there is an ingress controller restriction configured AND the service is not directly exposed.
if len(r.ingressControllerIdentities) != 0 && svc.Spec.Type == corev1.ServiceTypeClusterIP {
for _, ingressController := range r.ingressControllerIdentities {
rule.From = append(rule.From, v1.NetworkPolicyPeer{
PodSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
v1alpha3.OtterizeServiceLabelKey: ingressController.GetFormattedOtterizeIdentityWithoutKind(),
v1alpha3.OtterizeOwnerKindLabelKey: ingressController.Kind,
},
},
NamespaceSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
v1alpha3.KubernetesStandardNamespaceNameLabelKey: ingressController.Namespace,
},
},
})
}
}

netpol := &v1.NetworkPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: policyName,
Expand All @@ -139,12 +160,12 @@ func buildNetworkPolicyObjectForEndpoints(
PolicyTypes: []v1.PolicyType{v1.PolicyTypeIngress},
PodSelector: selector,
Ingress: []v1.NetworkPolicyIngressRule{
{},
rule,
},
},
}

for _, subsets := range serviceSpecCopy {
for _, subsets := range endpoints.Subsets {
for _, port := range subsets.Ports {
netpolPort := v1.NetworkPolicyPort{
Port: lo.ToPtr(intstr.FromInt(int(port.Port))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
otterizev1alpha3 "github.com/otterize/intents-operator/src/operator/api/v1alpha3"
"github.com/otterize/intents-operator/src/shared/operatorconfig/allowexternaltraffic"
"github.com/otterize/intents-operator/src/shared/serviceidresolver/serviceidentity"
"github.com/otterize/intents-operator/src/shared/testbase"
"github.com/stretchr/testify/suite"
"go.uber.org/mock/gomock"
Expand All @@ -21,7 +22,7 @@ type NetworkPolicyHandlerTestSuite struct {

func (s *NetworkPolicyHandlerTestSuite) SetupTest() {
s.MocksSuiteBase.SetupTest()
s.handler = NewNetworkPolicyHandler(s.Client, &runtime.Scheme{}, allowexternaltraffic.IfBlockedByOtterize)
s.handler = NewNetworkPolicyHandler(s.Client, &runtime.Scheme{}, allowexternaltraffic.IfBlockedByOtterize, make([]serviceidentity.ServiceIdentity, 0))
}

func (s *NetworkPolicyHandlerTestSuite) TestNetworkPolicyHandler_HandleBeforeAccessPolicyRemoval_createWhenNoIntentsEnabled_doNothing() {
Expand Down
155 changes: 0 additions & 155 deletions src/operator/controllers/external_traffic/network_policy_uploader.go

This file was deleted.

Loading

0 comments on commit 00faac0

Please sign in to comment.