Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/omris/use-effective-policy-for-e…
Browse files Browse the repository at this point in the history
…gress-to-svc-netpol' into omris/create-only-one-netpol-per-pod
  • Loading branch information
omris94 committed Jan 31, 2024
2 parents 1451470 + d043673 commit fa39035
Show file tree
Hide file tree
Showing 19 changed files with 244 additions and 33 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/allowDNS.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-access
spec:
egress:
- ports:
- port: 53
protocol: UDP
to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
podSelector:
matchExpressions:
- key: intents.otterize.com/server
operator: Exists
policyTypes:
- Egress
149 changes: 146 additions & 3 deletions .github/workflows/netpol-e2e-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ jobs:
- name: Wait for Otterize
run: |-
kubectl wait pods -n otterize-system -l app=intents-operator --for condition=Ready --timeout=360s
# wait for webhook to be ready
POD_IP=`kubectl get pod -l app=intents-operator -n otterize-system -o=jsonpath='{.items[0].status.podIP}'`
kubectl wait -n otterize-system --for=jsonpath='{.subsets[0].addresses[0].ip}'=$POD_IP endpoints/intents-operator-webhook-service
# wait for CRD update
kubectl wait --for=jsonpath='{.spec.conversion.webhook.clientConfig.service.namespace}'=otterize-system customresourcedefinitions/clientintents.k8s.otterize.com
- name: Wait for Tutorial services
Expand Down Expand Up @@ -118,8 +123,10 @@ jobs:
echo Client: $CLI1_POD client_other: $CLI2_POD
source .github/workflows/test-bashrc.sh
kubectl apply -f https://docs.otterize.com/code-examples/automate-network-policies/intents.yaml
echo "Apply intents"
apply_intents_and_wait_for_webhook https://docs.otterize.com/code-examples/automate-network-policies/intents.yaml
echo "Intents applied"
# should work because there is an applied intent
echo check client log
wait_for_log $CLI1_POD 10 "Hi, I am the server, you called, may I help you?"
Expand Down Expand Up @@ -193,12 +200,22 @@ jobs:
- name: Wait for Otterize
run: |-
kubectl wait pods -n otterize-system -l app=intents-operator --for condition=Ready --timeout=360s
# wait for webhook to be ready
POD_IP=`kubectl get pod -l app=intents-operator -n otterize-system -o=jsonpath='{.items[0].status.podIP}'`
kubectl wait -n otterize-system --for=jsonpath='{.subsets[0].addresses[0].ip}'=$POD_IP endpoints/intents-operator-webhook-service
# wait for CRD update
kubectl wait --for=jsonpath='{.spec.conversion.webhook.clientConfig.service.namespace}'=otterize-system customresourcedefinitions/clientintents.k8s.otterize.com
- name: Apply intents
run: |-
source .github/workflows/test-bashrc.sh
kubectl create namespace otterize-tutorial-npol
kubectl apply -f https://docs.otterize.com/code-examples/automate-network-policies/intents.yaml
echo "Apply intents"
apply_intents_and_wait_for_webhook https://docs.otterize.com/code-examples/automate-network-policies/intents.yaml
echo "Intents applied"
- name: Deploy Tutorial services
run: |-
Expand Down Expand Up @@ -230,10 +247,136 @@ jobs:


e2e-test-intents-after-pods-with-egress:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive

- name: Start minikube
uses: medyagh/setup-minikube@master
with:
start-args: "--network-plugin=cni --cni=calico"

- name: Load images from GitHub Artifacts
if: github.repository != 'otterize/intents-operator' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'otterize/intents-operator')
uses: actions/download-artifact@v3
with:
name: ${{ env.REGISTRY }}_${{ github.actor }}_intents-operator_${{ github.sha }}.tar

- name: Load Docker image
if: github.repository != 'otterize/intents-operator' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'otterize/intents-operator')
run: |-
docker image load -i intents-operator.tar
minikube image load ${{ env.REGISTRY }}/${{ github.actor }}/intents-operator:${{ github.sha }}
- name: Login to GCR
if: (github.event_name == 'push' && github.repository == 'otterize/intents-operator') || github.event.pull_request.head.repo.full_name == 'otterize/intents-operator'
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: _json_key_base64
password: ${{ secrets.B64_GCLOUD_SERVICE_ACCOUNT_JSON}}

- name: Load Docker images from GCR
if: (github.event_name == 'push' && github.repository == 'otterize/intents-operator') || github.event.pull_request.head.repo.full_name == 'otterize/intents-operator'
run: |-
docker pull ${{ env.REGISTRY }}/intents-operator:${{ inputs.operator-tag }}
minikube image load ${{ env.REGISTRY }}/intents-operator:${{ inputs.operator-tag }}
- name: Set up Helm
uses: azure/setup-helm@v3

- name: Wait for Calico startup
run: |-
kubectl wait pods -n kube-system -l k8s-app=calico-kube-controllers --for condition=Ready --timeout=90s
kubectl wait pods -n kube-system -l k8s-app=calico-node --for condition=Ready --timeout=90s
kubectl wait pods -n kube-system -l k8s-app=calico-kube-controllers --for condition=Ready --timeout=90s
- name: Install Otterize
run: |-
OPERATOR_FLAGS="--set-string intentsOperator.operator.repository=${{ env.REGISTRY }} --set-string intentsOperator.operator.image=${{ inputs.operator-image }} --set-string intentsOperator.operator.tag=${{ inputs.operator-tag }} --set-string intentsOperator.operator.pullPolicy=Never"
TELEMETRY_FLAG="--set global.telemetry.enabled=false"
EGRESS_FLAG="--set intentsOperator.operator.enableEgressNetworkPolicyCreation=true"
helm dep up ./helm-charts/otterize-kubernetes
helm install otterize ./helm-charts/otterize-kubernetes -n otterize-system --create-namespace $OPERATOR_FLAGS $TELEMETRY_FLAG $EGRESS_FLAG
- name: Deploy Tutorial services
run: |-
kubectl apply -f https://docs.otterize.com/code-examples/automate-network-policies/all.yaml
- name: Wait for Otterize
run: |-
kubectl wait pods -n otterize-system -l app=intents-operator --for condition=Ready --timeout=360s
# wait for webhook to be ready
POD_IP=`kubectl get pod -l app=intents-operator -n otterize-system -o=jsonpath='{.items[0].status.podIP}'`
kubectl wait -n otterize-system --for=jsonpath='{.subsets[0].addresses[0].ip}'=$POD_IP endpoints/intents-operator-webhook-service
# wait for CRD update
kubectl wait --for=jsonpath='{.spec.conversion.webhook.clientConfig.service.namespace}'=otterize-system customresourcedefinitions/clientintents.k8s.otterize.com
- name: Wait for Tutorial services
run: |-
kubectl wait pods -n otterize-tutorial-npol -l app=client --for condition=Ready --timeout=180s
kubectl wait pods -n otterize-tutorial-npol -l app=client-other --for condition=Ready --timeout=180s
kubectl wait pods -n otterize-tutorial-npol -l app=server --for condition=Ready --timeout=180s
- name: Before apply intents
run: |-
CLI1_POD=`kubectl get pod --selector app=client -n otterize-tutorial-npol -o json | jq -r ".items[0].metadata.name"`
CLI2_POD=`kubectl get pod --selector app=client-other -n otterize-tutorial-npol -o json | jq -r ".items[0].metadata.name"`
echo Client: $CLI1_POD client_other: $CLI2_POD
source .github/workflows/test-bashrc.sh
# using 14 because the log repeat itself every 14 lines
echo check client log
wait_for_log $CLI1_POD 10 "Hi, I am the server, you called, may I help you?"
echo check client other log
wait_for_log $CLI2_POD 10 "Hi, I am the server, you called, may I help you?"
- name: Apply intents and test connectivity
run: |-
CLI1_POD=`kubectl get pod --selector app=client -n otterize-tutorial-npol -o json | jq -r ".items[0].metadata.name"`
CLI2_POD=`kubectl get pod --selector app=client-other -n otterize-tutorial-npol -o json | jq -r ".items[0].metadata.name"`
echo Client: $CLI1_POD client_other: $CLI2_POD
source .github/workflows/test-bashrc.sh
echo "Apply intents"
apply_intents_and_wait_for_webhook https://docs.otterize.com/code-examples/automate-network-policies/intents.yaml
echo "Intents applied"
# should not work at first because there is no allow DNS netpol
echo "check client log - should get timed out because it is missing DNS allow netpol"
wait_for_log $CLI1_POD 10 "curl timed out"
# should be blocked (using 3 because the log should repeat itself every 3 lines)
echo "check client other log - should get timed out because it does not have an applied intent"
wait_for_log $CLI2_POD 10 "curl timed out"
echo "apply allow DNS netpol"
kubectl apply -f .github/workflows/allowDNS.yaml -n otterize-tutorial-npol
# should work because there is an applied intent and allowDNS netpol
echo "check client log - should work because there is an applied intent and allowDNS netpol"
wait_for_log $CLI1_POD 10 "Hi, I am the server, you called, may I help you?"
# should be blocked (using 3 because the log should repeat itself every 3 lines)
echo "check client other log - should get timed out because it does not have an applied intent"
wait_for_log $CLI2_POD 10 "curl timed out"



e2e-test:
needs:
- e2e-test-intents-after-pods
- e2e-test-intents-before-pods
- e2e-test-intents-after-pods-with-egress
runs-on: ubuntu-latest
steps:
- run: |-
Expand Down
21 changes: 20 additions & 1 deletion .github/workflows/test-bashrc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,23 @@ wait_for_log() {
echo "Operator manager logs:"
kubectl logs -n otterize-system -l app=intents-operator --tail 400
exit 1
}
}

apply_intents_and_wait_for_webhook() {
INTENTS_FILE=$1
for i in {1..5}; do
kubectl apply -f "$INTENTS_FILE" 2> error.txt && break;
if grep -q "connection refused" error.txt; then
if [ "$i" -eq 5 ]; then
echo "Failed to apply intents, webhook server is not ready";
cat error.txt;
exit 1;
fi;
echo "Waiting for webhook to be ready, try $i/5";
sleep 5;
else
cat error.txt;
exit 1;
fi;
done
}
6 changes: 3 additions & 3 deletions src/operator/api/v1alpha3/clientintents_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ type Service struct {

type Intent struct {
//+optional
Name string `json:"name" yaml:"name"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`

//+optional
Type IntentType `json:"type,omitempty" yaml:"type,omitempty"`
Expand All @@ -168,7 +168,7 @@ type Intent struct {
AWSActions []string `json:"awsActions,omitempty" yaml:"awsActions,omitempty"`

//+optional
Internet Internet `json:"internet,omitempty" yaml:"internet,omitempty"`
Internet *Internet `json:"internet,omitempty" yaml:"internet,omitempty"`
}

type Internet struct {
Expand Down Expand Up @@ -543,7 +543,7 @@ func (in *Intent) ConvertToCloudFormat(resourceNamespace string, clientName stri
})
}

if in.Internet.Ips != nil {
if in.Internet != nil && len(in.Internet.Ips) != 0 {
intentInput.Internet = &graphqlclient.InternetConfigInput{
Ips: lo.ToSlicePtr(in.Internet.Ips),
}
Expand Down
6 changes: 5 additions & 1 deletion src/operator/api/v1alpha3/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/operator/controllers/intents_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ func (r *IntentsReconciler) getIntentsToProtectedService(protectedService *otter
)
if err != nil {
logrus.Errorf("Failed to list client intents for client %s: %v", fullServerName, err)
// Intentionally no return - we are not able to return errors in this flow currently
}

intentsToReconcile = append(intentsToReconcile, intentsToServer.Items...)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,13 @@ func (s *CloudReconcilerTestSuite) TestInternetUpload() {
Calls: []otterizev1alpha3.Intent{
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: []string{"1.1.1.1", "2.2.2.0/24"},
},
},
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: []string{"3.3.3.3"},
Ports: []int{443},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (s *InternetNetworkPolicyReconcilerTestSuite) TestCreateNetworkPolicySingle
Calls: []otterizev1alpha3.Intent{
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: ips,
},
},
Expand Down Expand Up @@ -218,14 +218,14 @@ func (s *InternetNetworkPolicyReconcilerTestSuite) TestCreateNetworkPolicyMultip
Calls: []otterizev1alpha3.Intent{
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: []string{endpointAIp1, endpointAip2},
Ports: []int{endpointAPort},
},
},
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: []string{endpointBIp},
Ports: []int{endpointBPort},
},
Expand Down Expand Up @@ -338,7 +338,7 @@ func (s *InternetNetworkPolicyReconcilerTestSuite) TestNetworkPolicyDeletedClean
Calls: []otterizev1alpha3.Intent{
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: ips,
}},
},
Expand Down Expand Up @@ -428,7 +428,7 @@ func (s *InternetNetworkPolicyReconcilerTestSuite) TestUpdateNetworkPolicy() {
Calls: []otterizev1alpha3.Intent{
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: ips,
},
},
Expand Down Expand Up @@ -543,7 +543,7 @@ func (s *InternetNetworkPolicyReconcilerTestSuite) TestRemoveOrphanNetworkPolicy
Calls: []otterizev1alpha3.Intent{
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: ips,
},
},
Expand Down Expand Up @@ -730,7 +730,7 @@ func (s *InternetNetworkPolicyReconcilerTestSuite) testEnforcementDisabled() {
Calls: []otterizev1alpha3.Intent{
{
Type: otterizev1alpha3.IntentTypeInternet,
Internet: otterizev1alpha3.Internet{
Internet: &otterizev1alpha3.Internet{
Ips: []string{"1.1.1.1/32"},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (r *PortEgressNetworkPolicyReconciler) ReconcileEffectivePolicies(ctx conte

// remove policies that doesn't exist in the policy list
err := r.removeNetworkPoliciesThatShouldNotExist(ctx, currentPolicies)
return currentPolicies.Len(), err
return currentPolicies.Len(), errors.Wrap(err)
}

func (r *PortEgressNetworkPolicyReconciler) applyServiceEffectivePolicy(ctx context.Context, ep effectivepolicy.ServiceEffectivePolicy) ([]types.NamespacedName, error) {
Expand Down
1 change: 1 addition & 0 deletions src/operator/controllers/kafkaserverconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ func (r *KafkaServerConfigReconciler) getKSCsForProtectedService(ctx context.Con
)
if err != nil {
logrus.Errorf("Failed to list KSCs for server %s: %v", protectedService.Spec.Name, err)
// Intentionally no return - we are not able to return errors in this flow currently
}

kscsToReconcile = append(kscsToReconcile, kafkaServerConfigs.Items...)
Expand Down
7 changes: 3 additions & 4 deletions src/operator/controllers/pod_reconcilers/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ func (p *PodWatcher) updateServerSideCar(ctx context.Context, pod v1.Pod, servic
}

func (p *PodWatcher) addOtterizePodLabels(ctx context.Context, req ctrl.Request, serviceID serviceidentity.ServiceIdentity, pod v1.Pod) error {
if !viper.GetBool(operatorconfig.EnableNetworkPolicyKey) {
logrus.Debug("Not labeling new pod since network policy creation is disabled")
if !viper.GetBool(operatorconfig.EnableNetworkPolicyKey) && !viper.GetBool(operatorconfig.EnableIstioPolicyKey) {
logrus.Debug("Not labeling new pod since network policy creation and Istio policy creation is disabled")
return nil
}

Expand Down Expand Up @@ -223,8 +223,7 @@ func (p *PodWatcher) addOtterizePodLabels(ctx context.Context, req ctrl.Request,
if hasUpdates {
err = p.Patch(ctx, updatedPod, client.MergeFrom(&pod))
if err != nil {
logrus.Errorf("Failed updating Otterize labels for pod %s in namespace %s", pod.Name, pod.Namespace)
return errors.Wrap(err)
return errors.Errorf("failed updating Otterize labels for pod %s in namespace %s: %w", pod.Name, pod.Namespace, err)
}
}
return nil
Expand Down
Loading

0 comments on commit fa39035

Please sign in to comment.