From 33ca86b39e6fe8357d31055b647ac9e1a3f680ab Mon Sep 17 00:00:00 2001 From: Nikola Date: Sun, 14 Apr 2024 19:04:22 +0300 Subject: [PATCH 1/3] analyze: start parsing anps and banp from kube server or path --- cmd/policy-assistant/anps/anp-list.yaml | 39 +++ cmd/policy-assistant/anps/anp.yaml | 72 ++++++ cmd/policy-assistant/banp/banp.yaml | 53 ++++ cmd/policy-assistant/pkg/cli/analyze.go | 29 ++- .../pkg/connectivity/testcasestate.go | 5 +- cmd/policy-assistant/pkg/kube/ikubernetes.go | 59 ++++- cmd/policy-assistant/pkg/kube/kubernetes.go | 41 +++- cmd/policy-assistant/pkg/kube/read.go | 153 ++++++++++-- cmd/policy-assistant/pkg/kube/read_test.go | 230 ++++++++++++++++++ cmd/policy-assistant/pkg/kube/read_tests.go | 20 +- cmd/policy-assistant/pkg/utils/utils.go | 1 - 11 files changed, 650 insertions(+), 52 deletions(-) create mode 100644 cmd/policy-assistant/anps/anp-list.yaml create mode 100644 cmd/policy-assistant/anps/anp.yaml create mode 100644 cmd/policy-assistant/banp/banp.yaml create mode 100644 cmd/policy-assistant/pkg/kube/read_test.go diff --git a/cmd/policy-assistant/anps/anp-list.yaml b/cmd/policy-assistant/anps/anp-list.yaml new file mode 100644 index 00000000..0e7271d3 --- /dev/null +++ b/cmd/policy-assistant/anps/anp-list.yaml @@ -0,0 +1,39 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: AdminNetworkPolicyList +Items: + - apiVersion: policy.networking.k8s.io/v1alpha1 + kind: AdminNetworkPolicy + metadata: + name: egress-sctp + spec: + priority: 3 + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + egress: + - name: "allow-to-gryffindor-everything" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - apiVersion: policy.networking.k8s.io/v1alpha1 + kind: AdminNetworkPolicy + metadata: + name: gress-rules + spec: + priority: 15 + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + egress: + - name: "allow-to-ravenclaw-everything" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw \ No newline at end of file diff --git a/cmd/policy-assistant/anps/anp.yaml b/cmd/policy-assistant/anps/anp.yaml new file mode 100644 index 00000000..2ada0fd5 --- /dev/null +++ b/cmd/policy-assistant/anps/anp.yaml @@ -0,0 +1,72 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: AdminNetworkPolicy +metadata: + name: egress-sctp +spec: + priority: 8 + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + egress: + - name: "allow-to-gryffindor-everything" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "deny-to-gryffindor-everything" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "pass-to-gryffindor-everything" + action: "Pass" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "deny-to-slytherin-at-port-9003" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "pass-to-slytherin-at-port-9003" + action: "Pass" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "allow-to-hufflepuff-at-port-9003" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "deny-to-hufflepuff-everything-else" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff diff --git a/cmd/policy-assistant/banp/banp.yaml b/cmd/policy-assistant/banp/banp.yaml new file mode 100644 index 00000000..2fd7b6d6 --- /dev/null +++ b/cmd/policy-assistant/banp/banp.yaml @@ -0,0 +1,53 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: BaselineAdminNetworkPolicy +metadata: + name: default +spec: + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + egress: + - name: "allow-to-gryffindor-everything" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "deny-to-gryffindor-everything" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "deny-to-slytherin-at-port-9003" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "allow-to-hufflepuff-at-port-9003" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "deny-to-hufflepuff-everything-else" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff diff --git a/cmd/policy-assistant/pkg/cli/analyze.go b/cmd/policy-assistant/pkg/cli/analyze.go index 1ec59156..8db87b84 100644 --- a/cmd/policy-assistant/pkg/cli/analyze.go +++ b/cmd/policy-assistant/pkg/cli/analyze.go @@ -4,8 +4,10 @@ import ( "fmt" "github.com/mattfenwick/cyclonus/examples" "github.com/mattfenwick/cyclonus/pkg/kube/netpol" + "golang.org/x/net/context" "sigs.k8s.io/network-policy-api/apis/v1alpha1" "strings" + "time" "github.com/mattfenwick/collections/pkg/json" "github.com/mattfenwick/cyclonus/pkg/connectivity/probe" @@ -93,6 +95,7 @@ func RunAnalyzeCommand(args *AnalyzeArgs) { var kubeBANPs *v1alpha1.BaselineAdminNetworkPolicy var kubePods []v1.Pod var kubeNamespaces []v1.Namespace + var netErr, anpErr, banpErr error if args.AllNamespaces || len(args.Namespaces) > 0 { kubeClient, err := kube.NewKubernetesForContext(args.Context) utils.DoOrDie(err) @@ -104,27 +107,37 @@ func RunAnalyzeCommand(args *AnalyzeArgs) { kubeNamespaces = nsList.Items namespaces = []string{v1.NamespaceAll} } - kubePolicies, err = kube.ReadNetworkPoliciesFromKube(kubeClient, namespaces) - if err != nil { + + //TODO: add a flag for the timeout + ctx, cancel := context.WithTimeout(context.TODO(), 15*time.Second) + defer cancel() + + kubePolicies, kubeANPs, kubeBANPs, netErr, anpErr, banpErr = kube.ReadNetworkPoliciesFromKube(ctx, kubeClient, namespaces) + + if netErr != nil { logrus.Errorf("unable to read network policies from kube, ns '%s': %+v", namespaces, err) } - kubePods, err = kube.GetPodsInNamespaces(kubeClient, namespaces) - if err != nil { - logrus.Errorf("unable to read pods from kube, ns '%s': %+v", namespaces, err) + if anpErr != nil { + fmt.Printf("Unable to fetch admin network policies: %s \n", anpErr) + } + if banpErr != nil { + fmt.Printf("Unable to fetch base admin network policies: %s \n", banpErr) } } // 2. read policies from file if args.PolicyPath != "" { - policiesFromPath, err := kube.ReadNetworkPoliciesFromPath(args.PolicyPath) + policiesFromPath, anpsFromPath, banpFromPath, err := kube.ReadNetworkPoliciesFromPath(args.PolicyPath) utils.DoOrDie(err) kubePolicies = append(kubePolicies, policiesFromPath...) + kubeANPs = append(kubeANPs, anpsFromPath...) + kubeBANPs = banpFromPath } // 3. read example policies if args.UseExamplePolicies { kubePolicies = append(kubePolicies, netpol.AllExamples...) - kubeANPs = examples.CoreGressRulesCombinedANB - kubeBANPs = examples.CoreGressRulesCombinedBANB + kubeANPs = append(kubeANPs, examples.CoreGressRulesCombinedANB...) + kubeBANPs = kubeBANPs } logrus.Debugf("parsed policies:\n%s", json.MustMarshalToString(kubePolicies)) diff --git a/cmd/policy-assistant/pkg/connectivity/testcasestate.go b/cmd/policy-assistant/pkg/connectivity/testcasestate.go index 9696a050..391f07e1 100644 --- a/cmd/policy-assistant/pkg/connectivity/testcasestate.go +++ b/cmd/policy-assistant/pkg/connectivity/testcasestate.go @@ -1,6 +1,7 @@ package connectivity import ( + "context" "time" "github.com/mattfenwick/cyclonus/pkg/connectivity/probe" @@ -140,7 +141,7 @@ func (t *TestCaseState) DeletePod(ns string, pod string) error { } func (t *TestCaseState) ReadPolicies(namespaces []string) error { - policies, err := kube.GetNetworkPoliciesInNamespaces(t.Kubernetes, namespaces) + policies, err := kube.GetNetworkPoliciesInNamespaces(context.TODO(), t.Kubernetes, namespaces) if err != nil { return err } @@ -322,7 +323,7 @@ func (t *TestCaseState) VerifyClusterState() error { return err } - policies, err := kube.GetNetworkPoliciesInNamespaces(t.Kubernetes, t.Resources.NamespacesSlice()) + policies, err := kube.GetNetworkPoliciesInNamespaces(context.TODO(), t.Kubernetes, t.Resources.NamespacesSlice()) if err != nil { return err } diff --git a/cmd/policy-assistant/pkg/kube/ikubernetes.go b/cmd/policy-assistant/pkg/kube/ikubernetes.go index 497277ab..ccf5ecf0 100644 --- a/cmd/policy-assistant/pkg/kube/ikubernetes.go +++ b/cmd/policy-assistant/pkg/kube/ikubernetes.go @@ -1,6 +1,7 @@ package kube import ( + "context" "fmt" "github.com/mattfenwick/cyclonus/pkg/utils" "github.com/pkg/errors" @@ -8,6 +9,7 @@ import ( networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "math/rand" + v1alpha12 "sigs.k8s.io/network-policy-api/apis/v1alpha1" ) type IKubernetes interface { @@ -18,7 +20,7 @@ type IKubernetes interface { GetAllNamespaces() (*v1.NamespaceList, error) CreateNetworkPolicy(kubePolicy *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) - GetNetworkPoliciesInNamespace(namespace string) ([]networkingv1.NetworkPolicy, error) + GetNetworkPoliciesInNamespace(ctx context.Context, namespace string) ([]networkingv1.NetworkPolicy, error) UpdateNetworkPolicy(kubePolicy *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) DeleteNetworkPolicy(namespace string, name string) error DeleteAllNetworkPoliciesInNamespace(namespace string) error @@ -28,6 +30,9 @@ type IKubernetes interface { DeleteService(namespace string, name string) error GetServicesInNamespace(namespace string) ([]v1.Service, error) + GetAdminNetworkPoliciesInNamespace(ctx context.Context) ([]v1alpha12.AdminNetworkPolicy, error) + GetBaseAdminNetworkPoliciesInNamespace(ctx context.Context) (v1alpha12.BaselineAdminNetworkPolicy, error) + CreatePod(kubePod *v1.Pod) (*v1.Pod, error) GetPod(namespace string, pod string) (*v1.Pod, error) DeletePod(namespace string, pod string) error @@ -37,10 +42,10 @@ type IKubernetes interface { ExecuteRemoteCommand(namespace string, pod string, container string, command []string) (string, string, error, error) } -func GetNetworkPoliciesInNamespaces(kubernetes IKubernetes, namespaces []string) ([]networkingv1.NetworkPolicy, error) { +func GetNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes, namespaces []string) ([]networkingv1.NetworkPolicy, error) { var allNetpols []networkingv1.NetworkPolicy for _, ns := range namespaces { - netpols, err := kubernetes.GetNetworkPoliciesInNamespace(ns) + netpols, err := kubernetes.GetNetworkPoliciesInNamespace(ctx, ns) if err != nil { return nil, err } @@ -83,6 +88,14 @@ func GetServicesInNamespaces(kubernetes IKubernetes, namespaces []string) ([]v1. return allServices, nil } +func GetAdminNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes) ([]v1alpha12.AdminNetworkPolicy, error) { + return kubernetes.GetAdminNetworkPoliciesInNamespace(ctx) +} + +func GetBaseAdminNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes) (v1alpha12.BaselineAdminNetworkPolicy, error) { + return kubernetes.GetBaseAdminNetworkPoliciesInNamespace(ctx) +} + type MockNamespace struct { NamespaceObject *v1.Namespace Netpols map[string]*networkingv1.NetworkPolicy @@ -91,9 +104,12 @@ type MockNamespace struct { } type MockKubernetes struct { - Namespaces map[string]*MockNamespace - passRate float64 - podID int + AdminNetworkPolicies func() ([]v1alpha12.AdminNetworkPolicy, error) + BaseNetworkPolicies func() (v1alpha12.BaselineAdminNetworkPolicy, error) + NetworkPolicies func() ([]networkingv1.NetworkPolicy, error) + Namespaces map[string]*MockNamespace + passRate float64 + podID int } func NewMockKubernetes(passRate float64) *MockKubernetes { @@ -191,7 +207,17 @@ func (m *MockKubernetes) DeleteNetworkPolicy(ns string, name string) error { return nil } -func (m *MockKubernetes) GetNetworkPoliciesInNamespace(namespace string) ([]networkingv1.NetworkPolicy, error) { +func (m *MockKubernetes) GetNetworkPoliciesInNamespace(ctx context.Context, namespace string) ([]networkingv1.NetworkPolicy, error) { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + res, err := m.NetworkPolicies() + if res != nil || err != nil { + return res, err + } + } + nsObject, err := m.getNamespaceObject(namespace) if err != nil { return nil, err @@ -363,3 +389,22 @@ func (m *MockKubernetes) ExecuteRemoteCommand(namespace string, pod string, cont } return "", "", nil, nil } + +func (m *MockKubernetes) GetAdminNetworkPoliciesInNamespace(ctx context.Context) ([]v1alpha12.AdminNetworkPolicy, error) { + select { + default: + return m.AdminNetworkPolicies() + case <-ctx.Done(): + return []v1alpha12.AdminNetworkPolicy{}, ctx.Err() + } + +} + +func (m *MockKubernetes) GetBaseAdminNetworkPoliciesInNamespace(ctx context.Context) (v1alpha12.BaselineAdminNetworkPolicy, error) { + select { + default: + return m.BaseNetworkPolicies() + case <-ctx.Done(): + return v1alpha12.BaselineAdminNetworkPolicy{}, ctx.Err() + } +} diff --git a/cmd/policy-assistant/pkg/kube/kubernetes.go b/cmd/policy-assistant/pkg/kube/kubernetes.go index a28f7dfa..b0e1a637 100644 --- a/cmd/policy-assistant/pkg/kube/kubernetes.go +++ b/cmd/policy-assistant/pkg/kube/kubernetes.go @@ -3,6 +3,8 @@ package kube import ( "bytes" "context" + v1alpha12 "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/pkg/client/clientset/versioned/typed/apis/v1alpha1" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -19,8 +21,9 @@ import ( ) type Kubernetes struct { - ClientSet *kubernetes.Clientset - RestConfig *rest.Config + ClientSet *kubernetes.Clientset + alphaClientSet *v1alpha1.PolicyV1alpha1Client + RestConfig *rest.Config } func NewKubernetesForContext(context string) (*Kubernetes, error) { @@ -35,9 +38,15 @@ func NewKubernetesForContext(context string) (*Kubernetes, error) { if err != nil { return nil, errors.Wrapf(err, "unable to instantiate Clientset") } + alphacClientset, err := v1alpha1.NewForConfig(kubeConfig) + if err != nil { + return nil, errors.Wrapf(err, "unable to instantiate alpha network client set") + } + return &Kubernetes{ - ClientSet: clientset, - RestConfig: kubeConfig, + ClientSet: clientset, + alphaClientSet: alphacClientset, + RestConfig: kubeConfig, }, nil } @@ -92,14 +101,34 @@ func (k *Kubernetes) DeleteNetworkPolicy(ns string, name string) error { return errors.Wrapf(err, "unable to delete network policy %s/%s", ns, name) } -func (k *Kubernetes) GetNetworkPoliciesInNamespace(namespace string) ([]networkingv1.NetworkPolicy, error) { - netpolList, err := k.ClientSet.NetworkingV1().NetworkPolicies(namespace).List(context.TODO(), metav1.ListOptions{}) +func (k *Kubernetes) GetNetworkPoliciesInNamespace(ctx context.Context, namespace string) ([]networkingv1.NetworkPolicy, error) { + netpolList, err := k.ClientSet.NetworkingV1().NetworkPolicies(namespace).List(ctx, metav1.ListOptions{}) if err != nil { return nil, errors.Wrapf(err, "unable to get netpols in namespace %s", namespace) } return netpolList.Items, nil } +func (k *Kubernetes) GetAdminNetworkPoliciesInNamespace(ctx context.Context) ([]v1alpha12.AdminNetworkPolicy, error) { + anps, err := k.alphaClientSet.AdminNetworkPolicies().List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, err + } + return anps.Items, nil +} + +func (k *Kubernetes) GetBaseAdminNetworkPoliciesInNamespace(ctx context.Context) (v1alpha12.BaselineAdminNetworkPolicy, error) { + banp, err := k.alphaClientSet.BaselineAdminNetworkPolicies().List(ctx, metav1.ListOptions{}) + if err != nil { + return v1alpha12.BaselineAdminNetworkPolicy{}, err + } + if len(banp.Items) > 0 { + return banp.Items[0], nil + } + return v1alpha12.BaselineAdminNetworkPolicy{}, errors.New("BANP not found") + +} + func (k *Kubernetes) UpdateNetworkPolicy(policy *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { logrus.Debugf("updating network policy %s/%s", policy.Namespace, policy.Name) np, err := k.ClientSet.NetworkingV1().NetworkPolicies(policy.Namespace).Update(context.TODO(), policy, metav1.UpdateOptions{}) diff --git a/cmd/policy-assistant/pkg/kube/read.go b/cmd/policy-assistant/pkg/kube/read.go index 5cdf2167..a186df49 100644 --- a/cmd/policy-assistant/pkg/kube/read.go +++ b/cmd/policy-assistant/pkg/kube/read.go @@ -1,9 +1,7 @@ package kube import ( - "os" - "path/filepath" - + "context" "github.com/mattfenwick/collections/pkg/builtin" "github.com/mattfenwick/collections/pkg/file" "github.com/mattfenwick/collections/pkg/slice" @@ -11,10 +9,23 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" networkingv1 "k8s.io/api/networking/v1" + "os" + "path/filepath" + v1alpha12 "sigs.k8s.io/network-policy-api/apis/v1alpha1" ) -func ReadNetworkPoliciesFromPath(policyPath string) ([]*networkingv1.NetworkPolicy, error) { - var allPolicies []*networkingv1.NetworkPolicy +// ReadNetworkPoliciesFromPath walks the folder and try to parse each file in +// one of the supported types in the following manner: +// 1. NetworkPolicyList +// 2. NetworkPolicy +// 3. BaselineAdminNetworkPolicy +// 4. AdminNetworkPolicyList +// 5. AdminNetworkPolicy +func ReadNetworkPoliciesFromPath(policyPath string) ([]*networkingv1.NetworkPolicy, []*v1alpha12.AdminNetworkPolicy, *v1alpha12.BaselineAdminNetworkPolicy, error) { + var netPolicies []*networkingv1.NetworkPolicy + var adminNetPolicies []*v1alpha12.AdminNetworkPolicy + var baseAdminNetPolicies *v1alpha12.BaselineAdminNetworkPolicy + err := filepath.Walk(policyPath, func(path string, info os.FileInfo, err error) error { if err != nil { return errors.Wrapf(err, "unable to walk path %s", path) @@ -36,7 +47,7 @@ func ReadNetworkPoliciesFromPath(policyPath string) ([]*networkingv1.NetworkPoli // policies, err := yaml.ParseMany[networkingv1.NetworkPolicy](bytes) // if err == nil { // logrus.Debugf("parsed %d policies from %s", len(policies), path) - // allPolicies = append(allPolicies, refNetpolList(policies)...) + // netPolicies = append(netPolicies, refNetpolList(policies)...) // return nil // } // logrus.Errorf("unable to parse multiple policies separated by '---' lines: %+v", err) @@ -44,41 +55,135 @@ func ReadNetworkPoliciesFromPath(policyPath string) ([]*networkingv1.NetworkPoli // try parsing a NetworkPolicyList policyList, err := utils.ParseYamlStrict[networkingv1.NetworkPolicyList](bytes) if err == nil { - allPolicies = append(allPolicies, refNetpolList(policyList.Items)...) + netPolicies = append(netPolicies, refList(policyList.Items)...) return nil } - - logrus.Debugf("unable to parse list of policies: %+v", err) + logrus.Debugf("unable to parse list of network policies: %+v", err) policy, err := utils.ParseYamlStrict[networkingv1.NetworkPolicy](bytes) - if err != nil { - return errors.WithMessagef(err, "unable to parse single policy from yaml at %s", path) + if err == nil { + netPolicies = append(netPolicies, policy) + return nil + } + logrus.Debugf("unable to parse network policy: %+v", err) + + banp, err := utils.ParseYamlStrict[v1alpha12.BaselineAdminNetworkPolicy](bytes) + if err == nil { + baseAdminNetPolicies = banp + return nil + } + logrus.Debugf("unable to base admin network policies: %+v", err) + + anpList, err := utils.ParseYamlStrict[v1alpha12.AdminNetworkPolicyList](bytes) + if err == nil { + adminNetPolicies = append(adminNetPolicies, refList(anpList.Items)...) + return nil + } + logrus.Debugf("unable to parse list of admin network policies: %+v", err) + + anp, err := utils.ParseYamlStrict[v1alpha12.AdminNetworkPolicy](bytes) + if err == nil { + adminNetPolicies = append(adminNetPolicies, anp) + return nil + } + logrus.Debugf("unable to single admin network policies: %+v", err) + + if len(netPolicies) == 0 && len(adminNetPolicies) == 0 && baseAdminNetPolicies == nil { + return errors.WithMessagef(err, "unable to parse any policies from yaml at %s", path) } - logrus.Debugf("parsed single policy from %s: %+v", path, policy) - allPolicies = append(allPolicies, policy) return nil }) if err != nil { - return nil, err + return nil, nil, nil, err //return nil, errors.Wrapf(err, "unable to walk filesystem from %s", policyPath) } - for _, p := range allPolicies { - if len(p.Spec.PolicyTypes) == 0 { - return nil, errors.Errorf("missing spec.policyTypes from network policy %s/%s", p.Namespace, p.Name) + if len(netPolicies) > 0 { + for _, p := range netPolicies { + if len(p.Spec.PolicyTypes) == 0 { + return nil, nil, nil, errors.Errorf("missing spec.policyTypes from network policy %s/%s", p.Namespace, p.Name) + } } } - return allPolicies, nil + return netPolicies, adminNetPolicies, baseAdminNetPolicies, nil +} + +func ReadNetworkPoliciesFromKube(ctx context.Context, kubeClient IKubernetes, namespaces []string) ([]*networkingv1.NetworkPolicy, []*v1alpha12.AdminNetworkPolicy, *v1alpha12.BaselineAdminNetworkPolicy, error, error, error) { + var netpols []*networkingv1.NetworkPolicy + var anps []*v1alpha12.AdminNetworkPolicy + var banp *v1alpha12.BaselineAdminNetworkPolicy + var neterr, anperr, banperr error + + var netPolsCn = make(chan apiResponse[[]networkingv1.NetworkPolicy], 1) + go func(ch chan apiResponse[[]networkingv1.NetworkPolicy]) { + ch <- readNetworkPolicies(ctx, kubeClient, namespaces) + }(netPolsCn) + + var anpsCh = make(chan apiResponse[[]v1alpha12.AdminNetworkPolicy], 1) + go func(ch chan apiResponse[[]v1alpha12.AdminNetworkPolicy]) { + ch <- readAdminNetworkPolicies(ctx, kubeClient) + }(anpsCh) + + var banpsCh = make(chan apiResponse[v1alpha12.BaselineAdminNetworkPolicy], 1) + go func(ch chan apiResponse[v1alpha12.BaselineAdminNetworkPolicy]) { + ch <- readBaseAdminNetworkPolicies(ctx, kubeClient) + }(banpsCh) + + for i := 0; i <= 2; i++ { + select { + case result := <-netPolsCn: + r, err := result.response() + netpols = refList(r) + neterr = err + case result := <-anpsCh: + r, err := result.response() + anps = refList(r) + anperr = err + case result := <-banpsCh: + r, err := result.response() + if err == nil { + banp = &r + } + banperr = err + } + } + + return netpols, anps, banp, neterr, anperr, banperr +} + +func refList[T any](refs []T) []*T { + return slice.Map(builtin.Reference[T], refs) +} + +type apiResponse[T []networkingv1.NetworkPolicy | []v1alpha12.AdminNetworkPolicy | v1alpha12.BaselineAdminNetworkPolicy] struct { + data T + error error +} + +func (t apiResponse[T]) response() (T, error) { + return t.data, t.error +} + +func readNetworkPolicies(ctx context.Context, kubeClient IKubernetes, namespaces []string) apiResponse[[]networkingv1.NetworkPolicy] { + result, err := GetNetworkPoliciesInNamespaces(ctx, kubeClient, namespaces) + if err != nil { + return apiResponse[[]networkingv1.NetworkPolicy]{nil, err} + } + return apiResponse[[]networkingv1.NetworkPolicy]{result, err} } -func ReadNetworkPoliciesFromKube(kubeClient *Kubernetes, namespaces []string) ([]*networkingv1.NetworkPolicy, error) { - netpols, err := GetNetworkPoliciesInNamespaces(kubeClient, namespaces) +func readAdminNetworkPolicies(ctx context.Context, kubeClient IKubernetes) apiResponse[[]v1alpha12.AdminNetworkPolicy] { + result, err := GetAdminNetworkPoliciesInNamespaces(ctx, kubeClient) if err != nil { - return nil, err + return apiResponse[[]v1alpha12.AdminNetworkPolicy]{nil, err} } - return refNetpolList(netpols), nil + return apiResponse[[]v1alpha12.AdminNetworkPolicy]{result, err} } -func refNetpolList(refs []networkingv1.NetworkPolicy) []*networkingv1.NetworkPolicy { - return slice.Map(builtin.Reference[networkingv1.NetworkPolicy], refs) +func readBaseAdminNetworkPolicies(ctx context.Context, kubeClient IKubernetes) apiResponse[v1alpha12.BaselineAdminNetworkPolicy] { + result, err := GetBaseAdminNetworkPoliciesInNamespaces(ctx, kubeClient) + if err != nil { + return apiResponse[v1alpha12.BaselineAdminNetworkPolicy]{result, err} + } + return apiResponse[v1alpha12.BaselineAdminNetworkPolicy]{result, err} } diff --git a/cmd/policy-assistant/pkg/kube/read_test.go b/cmd/policy-assistant/pkg/kube/read_test.go new file mode 100644 index 00000000..d8918f9f --- /dev/null +++ b/cmd/policy-assistant/pkg/kube/read_test.go @@ -0,0 +1,230 @@ +package kube + +import ( + "context" + "errors" + "fmt" + v1 "k8s.io/api/networking/v1" + errors2 "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + v1alpha12 "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "testing" + "time" +) + +func TestReadNetworkPoliciesFromKube(t *testing.T) { + anpNotFound := errors2.NewNotFound(schema.GroupResource{v1alpha12.GroupName, "AdminNetworkPolicy"}, "AdminNetworkPolicy") + banpNotFound := errors2.NewNotFound(schema.GroupResource{v1alpha12.GroupName, "BaselineAdminNetworkPolicy"}, "BaselineAdminNetworkPolicy") + netpolNotFound := errors2.NewNotFound(schema.GroupResource{v1.GroupName, "NetworkPolicies"}, "NetworkPolicies") + + scenarios := map[string]struct { + ctxCreator func() (context.Context, context.CancelFunc) + anpResponse func() ([]v1alpha12.AdminNetworkPolicy, error) + banpResponse func() (v1alpha12.BaselineAdminNetworkPolicy, error) + netPolResponse func() ([]v1.NetworkPolicy, error) + + expectedNetErr error + expectedAnpErr error + expectedBanpErr error + }{ + "timeout error on admin network policies retrieval": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.WithTimeout(context.TODO(), 1*time.Nanosecond) + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + time.Sleep(1 * time.Millisecond) + return []v1alpha12.AdminNetworkPolicy{}, nil + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + return v1alpha12.BaselineAdminNetworkPolicy{}, nil + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + return nil, nil + }, + expectedAnpErr: context.DeadlineExceeded, + }, + "resource not found on admin network policies retrieval": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.TODO(), func() {} + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + return []v1alpha12.AdminNetworkPolicy{}, anpNotFound + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + return v1alpha12.BaselineAdminNetworkPolicy{}, nil + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + return nil, nil + }, + expectedAnpErr: anpNotFound, + }, + "return admin network policies": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.TODO(), func() {} + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + return []v1alpha12.AdminNetworkPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "admin-network-policy", + }, + }, + }, nil + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + return v1alpha12.BaselineAdminNetworkPolicy{}, nil + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + return nil, nil + }, + }, + "timeout error on base admin network policies retrieval": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.WithTimeout(context.TODO(), 1*time.Nanosecond) + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + return []v1alpha12.AdminNetworkPolicy{}, nil + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + time.Sleep(1 * time.Millisecond) + return v1alpha12.BaselineAdminNetworkPolicy{}, nil + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + return nil, nil + }, + expectedAnpErr: context.DeadlineExceeded, + }, + "resource not found on base admin network policies retrieval": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.TODO(), func() {} + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + return []v1alpha12.AdminNetworkPolicy{}, nil + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + return v1alpha12.BaselineAdminNetworkPolicy{}, banpNotFound + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + return nil, nil + }, + expectedBanpErr: banpNotFound, + }, + "return base admin network policies": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.TODO(), func() {} + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + return []v1alpha12.AdminNetworkPolicy{}, nil + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + return v1alpha12.BaselineAdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: "base-admin-network-policy"}, + }, nil + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + return nil, nil + }, + }, + "timeout error on network policies retrieval": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.WithTimeout(context.TODO(), 1*time.Nanosecond) + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + return []v1alpha12.AdminNetworkPolicy{}, nil + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + return v1alpha12.BaselineAdminNetworkPolicy{}, nil + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + time.Sleep(10 * time.Millisecond) + return nil, nil + }, + expectedNetErr: context.DeadlineExceeded, + }, + "resource not found on network policies retrieval": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.TODO(), func() {} + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + return []v1alpha12.AdminNetworkPolicy{}, nil + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + return v1alpha12.BaselineAdminNetworkPolicy{}, nil + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + return nil, netpolNotFound + }, + expectedNetErr: netpolNotFound, + }, + "return network policies": { + ctxCreator: func() (context.Context, context.CancelFunc) { + return context.TODO(), func() {} + }, + anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { + return []v1alpha12.AdminNetworkPolicy{}, nil + }, + banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { + return v1alpha12.BaselineAdminNetworkPolicy{}, nil + }, + netPolResponse: func() ([]v1.NetworkPolicy, error) { + return []v1.NetworkPolicy{ + { + ObjectMeta: metav1.ObjectMeta{Name: "network_policy"}, + }, + }, nil + }, + }, + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + ctx, cancel := scenario.ctxCreator() + defer cancel() + + k := &MockKubernetes{ + AdminNetworkPolicies: scenario.anpResponse, + BaseNetworkPolicies: scenario.banpResponse, + NetworkPolicies: scenario.netPolResponse, + } + netpol, anps, banp, netErr, anpErr, banpErr := ReadNetworkPoliciesFromKube(ctx, k, []string{"test"}) + if scenario.expectedNetErr != nil { + if !errors.Is(netErr, scenario.expectedNetErr) { + t.Fatalf("Unexpected error1: %v, expected %v", netErr, scenario.expectedNetErr) + } + } + if scenario.expectedAnpErr != nil { + if !errors.Is(anpErr, scenario.expectedAnpErr) { + t.Fatalf("Unexpected error1: %v, expected %v", anpErr, scenario.expectedAnpErr) + } + } + if scenario.expectedBanpErr != nil { + if !errors.Is(banpErr, scenario.expectedBanpErr) { + t.Fatalf("Unexpected error1: %v, expected %v", banpErr, scenario.expectedBanpErr) + } + } + + if len(anps) > 0 { + expected, _ := scenario.anpResponse() + if anps[0].Name != expected[0].Name { + t.Fatalf("Unexpected ANP: %v, expected %v", anps[0].Name, expected[0].Name) + } + } + + if banp != nil { + expected, _ := scenario.banpResponse() + if banp.Name != expected.Name { + t.Fatalf("Unexpected BANP: %v, expected %v", banp.Name, banp.Name) + } + } + if len(netpol) > 0 { + expected, _ := scenario.netPolResponse() + fmt.Println(netpol[0].Name, expected[0].Name+"1") + if netpol[0].Name != expected[0].Name { + t.Fatalf("Unexpected NetworkPolicy: %v, expected %v", netpol[0].Name, expected[0].Name) + } + } + }) + } + +} diff --git a/cmd/policy-assistant/pkg/kube/read_tests.go b/cmd/policy-assistant/pkg/kube/read_tests.go index f5b5946b..fea1bd12 100644 --- a/cmd/policy-assistant/pkg/kube/read_tests.go +++ b/cmd/policy-assistant/pkg/kube/read_tests.go @@ -8,12 +8,12 @@ import ( func RunReadNetworkPolicyTests() { Describe("ReadNetworkPolicies", func() { It("Should read a single policy from a single file", func() { - policies, err := ReadNetworkPoliciesFromPath("../../networkpolicies/features/portrange1.yaml") + policies, _, _, err := ReadNetworkPoliciesFromPath("../../networkpolicies/features/portrange1.yaml") Expect(err).To(BeNil()) Expect(len(policies)).To(Equal(1)) }) It("Should read a list of policies from a single file", func() { - policies, err := ReadNetworkPoliciesFromPath("../../networkpolicies/yaml-syntax/yaml-list.yaml") + policies, _, _, err := ReadNetworkPoliciesFromPath("../../networkpolicies/yaml-syntax/yaml-list.yaml") Expect(err).To(BeNil()) Expect(len(policies)).To(Equal(3)) }) @@ -28,15 +28,27 @@ func RunReadNetworkPolicyTests() { // }) It("Should read multiple policies from all files in a directory", func() { - policies, err := ReadNetworkPoliciesFromPath("../../networkpolicies/simple-example") + policies, _, _, err := ReadNetworkPoliciesFromPath("../../networkpolicies/simple-example") Expect(err).To(BeNil()) Expect(len(policies)).To(Equal(7)) - policies, err = ReadNetworkPoliciesFromPath("../../networkpolicies/") + policies, _, _, err = ReadNetworkPoliciesFromPath("../../networkpolicies/") Expect(err).To(BeNil()) Expect(len(policies)).To(Equal(14)) }) + It("Should read multiple admin network policies", func() { + _, anps, _, err := ReadNetworkPoliciesFromPath("../../anps/") + Expect(err).To(BeNil()) + Expect(len(anps)).To(Equal(3)) + }) + + It("Should read a base admin network policy", func() { + _, _, banp, err := ReadNetworkPoliciesFromPath("../../banp/") + Expect(err).To(BeNil()) + Expect(banp).ToNot(BeNil()) + }) + // TODO test to show what happens for duplicate names }) } diff --git a/cmd/policy-assistant/pkg/utils/utils.go b/cmd/policy-assistant/pkg/utils/utils.go index 8ef86606..70434077 100644 --- a/cmd/policy-assistant/pkg/utils/utils.go +++ b/cmd/policy-assistant/pkg/utils/utils.go @@ -2,7 +2,6 @@ package utils import ( "encoding/json" - "github.com/mattfenwick/collections/pkg/file" "github.com/pkg/errors" "github.com/sirupsen/logrus" From 33629dbce7930a1a9e3696a330378135fb74d014 Mon Sep 17 00:00:00 2001 From: Nikola Date: Sun, 21 Jul 2024 17:24:17 +0300 Subject: [PATCH 2/3] feedback --- cmd/policy-assistant/pkg/cli/analyze.go | 62 +++++- cmd/policy-assistant/pkg/kube/ikubernetes.go | 88 +++++--- cmd/policy-assistant/pkg/kube/kubernetes.go | 38 +++- cmd/policy-assistant/pkg/kube/read.go | 127 +++++------ cmd/policy-assistant/pkg/kube/read_test.go | 210 ++++-------------- cmd/policy-assistant/pkg/kube/read_tests.go | 20 +- .../example-policies}/anps/anp-list.yaml | 0 .../{ => test/example-policies}/anps/anp.yaml | 0 .../example-policies}/banp/banp.yaml | 0 .../networkpolicies/allow-all-internal.yaml | 0 .../networkpolicies/allow-all.yaml | 0 .../networkpolicies/features/portrange1.yaml | 0 .../allow-all-egress-by-label.yaml | 0 .../simple-example/allow-all-for-label.yaml | 0 .../simple-example/allow-by-ip.yaml | 0 .../simple-example/allow-label-to-label.yaml | 0 .../simple-example/deny-all-egress.yaml | 0 .../simple-example/deny-all-for-label.yaml | 0 .../simple-example/deny-all.yaml | 0 .../allow-to-ns-y-pod-a.yaml | 0 .../yaml-syntax/yaml-list.yaml | 0 21 files changed, 246 insertions(+), 299 deletions(-) rename cmd/policy-assistant/{ => test/example-policies}/anps/anp-list.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/anps/anp.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/banp/banp.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/allow-all-internal.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/allow-all.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/features/portrange1.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/simple-example/allow-all-egress-by-label.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/simple-example/allow-all-for-label.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/simple-example/allow-by-ip.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/simple-example/allow-label-to-label.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/simple-example/deny-all-egress.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/simple-example/deny-all-for-label.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/simple-example/deny-all.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/upstream_test_cases/allow-to-ns-y-pod-a.yaml (100%) rename cmd/policy-assistant/{ => test/example-policies}/networkpolicies/yaml-syntax/yaml-list.yaml (100%) diff --git a/cmd/policy-assistant/pkg/cli/analyze.go b/cmd/policy-assistant/pkg/cli/analyze.go index 8db87b84..9b62886a 100644 --- a/cmd/policy-assistant/pkg/cli/analyze.go +++ b/cmd/policy-assistant/pkg/cli/analyze.go @@ -5,6 +5,8 @@ import ( "github.com/mattfenwick/cyclonus/examples" "github.com/mattfenwick/cyclonus/pkg/kube/netpol" "golang.org/x/net/context" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" "sigs.k8s.io/network-policy-api/apis/v1alpha1" "strings" "time" @@ -40,6 +42,8 @@ var AllModes = []string{ ProbeMode, } +const DefaultTimeout = 180 + type AnalyzeArgs struct { AllNamespaces bool Namespaces []string @@ -58,6 +62,8 @@ type AnalyzeArgs struct { // synthetic probe ProbePath string + + Timeout int } func SetupAnalyzeCommand() *cobra.Command { @@ -85,6 +91,8 @@ func SetupAnalyzeCommand() *cobra.Command { command.Flags().StringVar(&args.TrafficPath, "traffic-path", "", "path to json traffic file, containing of a list of traffic objects") command.Flags().StringVar(&args.ProbePath, "probe-path", "", "path to json model file for synthetic probe") + command.Flags().IntVar(&args.Timeout, "timeout", DefaultTimeout, "timeout time in seconds") + return command } @@ -92,10 +100,10 @@ func RunAnalyzeCommand(args *AnalyzeArgs) { // 1. read policies from kube var kubePolicies []*networkingv1.NetworkPolicy var kubeANPs []*v1alpha1.AdminNetworkPolicy - var kubeBANPs *v1alpha1.BaselineAdminNetworkPolicy + var kubeBANP *v1alpha1.BaselineAdminNetworkPolicy var kubePods []v1.Pod var kubeNamespaces []v1.Namespace - var netErr, anpErr, banpErr error + var netpolErr, anpErr, banpErr error if args.AllNamespaces || len(args.Namespaces) > 0 { kubeClient, err := kube.NewKubernetesForContext(args.Context) utils.DoOrDie(err) @@ -108,20 +116,21 @@ func RunAnalyzeCommand(args *AnalyzeArgs) { namespaces = []string{v1.NamespaceAll} } - //TODO: add a flag for the timeout - ctx, cancel := context.WithTimeout(context.TODO(), 15*time.Second) + includeANPS, includeBANPSs := shouldIncludeANPandBANP(kubeClient.ClientSet) + + ctx, cancel := context.WithTimeout(context.TODO(), time.Duration(args.Timeout)*time.Second) defer cancel() - kubePolicies, kubeANPs, kubeBANPs, netErr, anpErr, banpErr = kube.ReadNetworkPoliciesFromKube(ctx, kubeClient, namespaces) + kubePolicies, kubeANPs, kubeBANP, netpolErr, anpErr, banpErr = kube.ReadNetworkPoliciesFromKube(ctx, kubeClient, namespaces, includeANPS, includeBANPSs) - if netErr != nil { + if netpolErr != nil { logrus.Errorf("unable to read network policies from kube, ns '%s': %+v", namespaces, err) } if anpErr != nil { - fmt.Printf("Unable to fetch admin network policies: %s \n", anpErr) + logrus.Errorf("Unable to fetch admin network policies: %s \n", anpErr) } if banpErr != nil { - fmt.Printf("Unable to fetch base admin network policies: %s \n", banpErr) + logrus.Errorf("Unable to fetch base admin network policies: %s \n", banpErr) } } // 2. read policies from file @@ -130,18 +139,24 @@ func RunAnalyzeCommand(args *AnalyzeArgs) { utils.DoOrDie(err) kubePolicies = append(kubePolicies, policiesFromPath...) kubeANPs = append(kubeANPs, anpsFromPath...) - kubeBANPs = banpFromPath + if banpFromPath != nil && kubeBANP != nil { + logrus.Debugf("More that one banp parsed - setting banp from file") + } + kubeBANP = banpFromPath } // 3. read example policies if args.UseExamplePolicies { kubePolicies = append(kubePolicies, netpol.AllExamples...) kubeANPs = append(kubeANPs, examples.CoreGressRulesCombinedANB...) - kubeBANPs = kubeBANPs + if kubeBANP != nil { + logrus.Debugf("More that onew banp parsed - setting banp from the examples") + } + kubeBANP = examples.CoreGressRulesCombinedBANB } logrus.Debugf("parsed policies:\n%s", json.MustMarshalToString(kubePolicies)) - policies := matcher.BuildV1AndV2NetPols(args.SimplifyPolicies, kubePolicies, kubeANPs, kubeBANPs) + policies := matcher.BuildV1AndV2NetPols(args.SimplifyPolicies, kubePolicies, kubeANPs, kubeBANP) for _, mode := range args.Modes { switch mode { @@ -316,3 +331,28 @@ func ProbeSyntheticConnectivity(explainedPolicies *matcher.Policy, modelPath str fmt.Printf("Egress:\n%s\n", simulatedProbe.RenderEgress()) fmt.Printf("Combined:\n%s\n\n\n", simulatedProbe.RenderTable()) } + +func shouldIncludeANPandBANP(client *kubernetes.Clientset) (bool, bool) { + var includeANP, includeBANP bool + _, resources, _, err := client.DiscoveryClient.GroupsAndMaybeResources() + if err != nil { + logrus.Errorf("Unable to fetch all registered resources: %s", err) + return includeANP, includeBANP + } + gv := schema.GroupVersion{Group: "policy.networking.k8s.io", Version: "v1alpha1"} + + if groupResources, ok := resources[gv]; ok { + for _, res := range groupResources.APIResources { + switch res.Kind { + case "AdminNetworkPolicy": + includeANP = true + case "BaselineAdminNetworkPolicy": + includeBANP = true + default: + panic(fmt.Sprintf("unexpected resource kind %s", res.Kind)) + } + } + } + + return includeANP, includeBANP +} diff --git a/cmd/policy-assistant/pkg/kube/ikubernetes.go b/cmd/policy-assistant/pkg/kube/ikubernetes.go index ccf5ecf0..bbf69184 100644 --- a/cmd/policy-assistant/pkg/kube/ikubernetes.go +++ b/cmd/policy-assistant/pkg/kube/ikubernetes.go @@ -9,7 +9,7 @@ import ( networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "math/rand" - v1alpha12 "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/apis/v1alpha1" ) type IKubernetes interface { @@ -30,8 +30,15 @@ type IKubernetes interface { DeleteService(namespace string, name string) error GetServicesInNamespace(namespace string) ([]v1.Service, error) - GetAdminNetworkPoliciesInNamespace(ctx context.Context) ([]v1alpha12.AdminNetworkPolicy, error) - GetBaseAdminNetworkPoliciesInNamespace(ctx context.Context) (v1alpha12.BaselineAdminNetworkPolicy, error) + GetAdminNetworkPolicies(ctx context.Context) ([]v1alpha1.AdminNetworkPolicy, error) + CreateAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.AdminNetworkPolicy) (*v1alpha1.AdminNetworkPolicy, error) + UpdateAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.AdminNetworkPolicy) (*v1alpha1.AdminNetworkPolicy, error) + DeleteAdminNetworkPolicy(ctx context.Context, name string) error + + GetBaseAdminNetworkPolicies(ctx context.Context) ([]v1alpha1.BaselineAdminNetworkPolicy, error) + CreateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.BaselineAdminNetworkPolicy) (*v1alpha1.BaselineAdminNetworkPolicy, error) + UpdateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.BaselineAdminNetworkPolicy) (*v1alpha1.BaselineAdminNetworkPolicy, error) + DeleteBaselineAdminNetworkPolicy(ctx context.Context, name string) error CreatePod(kubePod *v1.Pod) (*v1.Pod, error) GetPod(namespace string, pod string) (*v1.Pod, error) @@ -88,12 +95,12 @@ func GetServicesInNamespaces(kubernetes IKubernetes, namespaces []string) ([]v1. return allServices, nil } -func GetAdminNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes) ([]v1alpha12.AdminNetworkPolicy, error) { - return kubernetes.GetAdminNetworkPoliciesInNamespace(ctx) +func GetAdminNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes) ([]v1alpha1.AdminNetworkPolicy, error) { + return kubernetes.GetAdminNetworkPolicies(ctx) } -func GetBaseAdminNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes) (v1alpha12.BaselineAdminNetworkPolicy, error) { - return kubernetes.GetBaseAdminNetworkPoliciesInNamespace(ctx) +func GetBaseAdminNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes) ([]v1alpha1.BaselineAdminNetworkPolicy, error) { + return kubernetes.GetBaseAdminNetworkPolicies(ctx) } type MockNamespace struct { @@ -104,12 +111,14 @@ type MockNamespace struct { } type MockKubernetes struct { - AdminNetworkPolicies func() ([]v1alpha12.AdminNetworkPolicy, error) - BaseNetworkPolicies func() (v1alpha12.BaselineAdminNetworkPolicy, error) - NetworkPolicies func() ([]networkingv1.NetworkPolicy, error) - Namespaces map[string]*MockNamespace - passRate float64 - podID int + AdminNetworkPolicies []v1alpha1.AdminNetworkPolicy + AdminNetworkPolicyError error + BaseNetworkPolicies []v1alpha1.BaselineAdminNetworkPolicy + BaseAdminNetworkPolicyError error + Namespaces map[string]*MockNamespace + NetworkPolicyError error + passRate float64 + podID int } func NewMockKubernetes(passRate float64) *MockKubernetes { @@ -208,14 +217,8 @@ func (m *MockKubernetes) DeleteNetworkPolicy(ns string, name string) error { } func (m *MockKubernetes) GetNetworkPoliciesInNamespace(ctx context.Context, namespace string) ([]networkingv1.NetworkPolicy, error) { - select { - case <-ctx.Done(): - return nil, ctx.Err() - default: - res, err := m.NetworkPolicies() - if res != nil || err != nil { - return res, err - } + if m.NetworkPolicyError != nil { + return nil, m.NetworkPolicyError } nsObject, err := m.getNamespaceObject(namespace) @@ -390,21 +393,36 @@ func (m *MockKubernetes) ExecuteRemoteCommand(namespace string, pod string, cont return "", "", nil, nil } -func (m *MockKubernetes) GetAdminNetworkPoliciesInNamespace(ctx context.Context) ([]v1alpha12.AdminNetworkPolicy, error) { - select { - default: - return m.AdminNetworkPolicies() - case <-ctx.Done(): - return []v1alpha12.AdminNetworkPolicy{}, ctx.Err() - } +func (m *MockKubernetes) GetAdminNetworkPolicies(ctx context.Context) ([]v1alpha1.AdminNetworkPolicy, error) { + return m.AdminNetworkPolicies, m.AdminNetworkPolicyError +} +func (k *MockKubernetes) CreateAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.AdminNetworkPolicy) (*v1alpha1.AdminNetworkPolicy, error) { + return nil, ErrNotImplemented } -func (m *MockKubernetes) GetBaseAdminNetworkPoliciesInNamespace(ctx context.Context) (v1alpha12.BaselineAdminNetworkPolicy, error) { - select { - default: - return m.BaseNetworkPolicies() - case <-ctx.Done(): - return v1alpha12.BaselineAdminNetworkPolicy{}, ctx.Err() - } +func (k *MockKubernetes) UpdateAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.AdminNetworkPolicy) (*v1alpha1.AdminNetworkPolicy, error) { + return nil, ErrNotImplemented +} + +func (k *MockKubernetes) DeleteAdminNetworkPolicy(ctx context.Context, name string) error { + //TODO: implement + return ErrNotImplemented +} + +func (m *MockKubernetes) GetBaseAdminNetworkPolicies(ctx context.Context) ([]v1alpha1.BaselineAdminNetworkPolicy, error) { + return m.BaseNetworkPolicies, m.BaseAdminNetworkPolicyError +} + +func (k *MockKubernetes) CreateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.BaselineAdminNetworkPolicy) (*v1alpha1.BaselineAdminNetworkPolicy, error) { + return nil, ErrNotImplemented +} + +func (k *MockKubernetes) UpdateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.BaselineAdminNetworkPolicy) (*v1alpha1.BaselineAdminNetworkPolicy, error) { + return nil, ErrNotImplemented +} + +func (k *MockKubernetes) DeleteBaselineAdminNetworkPolicy(ctx context.Context, name string) error { + //TODO: implement + return ErrNotImplemented } diff --git a/cmd/policy-assistant/pkg/kube/kubernetes.go b/cmd/policy-assistant/pkg/kube/kubernetes.go index b0e1a637..479e5a0e 100644 --- a/cmd/policy-assistant/pkg/kube/kubernetes.go +++ b/cmd/policy-assistant/pkg/kube/kubernetes.go @@ -20,6 +20,8 @@ import ( "k8s.io/client-go/tools/remotecommand" ) +var ErrNotImplemented = errors.New("Not implemented") + type Kubernetes struct { ClientSet *kubernetes.Clientset alphaClientSet *v1alpha1.PolicyV1alpha1Client @@ -109,7 +111,7 @@ func (k *Kubernetes) GetNetworkPoliciesInNamespace(ctx context.Context, namespac return netpolList.Items, nil } -func (k *Kubernetes) GetAdminNetworkPoliciesInNamespace(ctx context.Context) ([]v1alpha12.AdminNetworkPolicy, error) { +func (k *Kubernetes) GetAdminNetworkPolicies(ctx context.Context) ([]v1alpha12.AdminNetworkPolicy, error) { anps, err := k.alphaClientSet.AdminNetworkPolicies().List(ctx, metav1.ListOptions{}) if err != nil { return nil, err @@ -117,16 +119,38 @@ func (k *Kubernetes) GetAdminNetworkPoliciesInNamespace(ctx context.Context) ([] return anps.Items, nil } -func (k *Kubernetes) GetBaseAdminNetworkPoliciesInNamespace(ctx context.Context) (v1alpha12.BaselineAdminNetworkPolicy, error) { +func (k *Kubernetes) CreateAdminNetworkPolicy(ctx context.Context, policy *v1alpha12.AdminNetworkPolicy) (*v1alpha12.AdminNetworkPolicy, error) { + return nil, ErrNotImplemented +} + +func (k *Kubernetes) UpdateAdminNetworkPolicy(ctx context.Context, policy *v1alpha12.AdminNetworkPolicy) (*v1alpha12.AdminNetworkPolicy, error) { + return nil, ErrNotImplemented +} + +func (k *Kubernetes) DeleteAdminNetworkPolicy(ctx context.Context, name string) error { + //TODO: implement + return ErrNotImplemented +} + +func (k *Kubernetes) GetBaseAdminNetworkPolicies(ctx context.Context) ([]v1alpha12.BaselineAdminNetworkPolicy, error) { banp, err := k.alphaClientSet.BaselineAdminNetworkPolicies().List(ctx, metav1.ListOptions{}) if err != nil { - return v1alpha12.BaselineAdminNetworkPolicy{}, err - } - if len(banp.Items) > 0 { - return banp.Items[0], nil + return nil, err } - return v1alpha12.BaselineAdminNetworkPolicy{}, errors.New("BANP not found") + return banp.Items, nil +} + +func (k *Kubernetes) CreateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha12.BaselineAdminNetworkPolicy) (*v1alpha12.BaselineAdminNetworkPolicy, error) { + return nil, ErrNotImplemented +} + +func (k *Kubernetes) UpdateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha12.BaselineAdminNetworkPolicy) (*v1alpha12.BaselineAdminNetworkPolicy, error) { + return nil, ErrNotImplemented +} +func (k *Kubernetes) DeleteBaselineAdminNetworkPolicy(ctx context.Context, name string) error { + //TODO: implement + return ErrNotImplemented } func (k *Kubernetes) UpdateNetworkPolicy(policy *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { diff --git a/cmd/policy-assistant/pkg/kube/read.go b/cmd/policy-assistant/pkg/kube/read.go index a186df49..e1b557bd 100644 --- a/cmd/policy-assistant/pkg/kube/read.go +++ b/cmd/policy-assistant/pkg/kube/read.go @@ -12,6 +12,7 @@ import ( "os" "path/filepath" v1alpha12 "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sync" ) // ReadNetworkPoliciesFromPath walks the folder and try to parse each file in @@ -23,8 +24,8 @@ import ( // 5. AdminNetworkPolicy func ReadNetworkPoliciesFromPath(policyPath string) ([]*networkingv1.NetworkPolicy, []*v1alpha12.AdminNetworkPolicy, *v1alpha12.BaselineAdminNetworkPolicy, error) { var netPolicies []*networkingv1.NetworkPolicy - var adminNetPolicies []*v1alpha12.AdminNetworkPolicy - var baseAdminNetPolicies *v1alpha12.BaselineAdminNetworkPolicy + var adminNetworkPolicies []*v1alpha12.AdminNetworkPolicy + var baselineAdminNetworkPolicy *v1alpha12.BaselineAdminNetworkPolicy err := filepath.Walk(policyPath, func(path string, info os.FileInfo, err error) error { if err != nil { @@ -69,26 +70,29 @@ func ReadNetworkPoliciesFromPath(policyPath string) ([]*networkingv1.NetworkPoli banp, err := utils.ParseYamlStrict[v1alpha12.BaselineAdminNetworkPolicy](bytes) if err == nil { - baseAdminNetPolicies = banp + if baselineAdminNetworkPolicy != nil { + return errors.New("baseline admin network policy already exists") + } + baselineAdminNetworkPolicy = banp return nil } logrus.Debugf("unable to base admin network policies: %+v", err) anpList, err := utils.ParseYamlStrict[v1alpha12.AdminNetworkPolicyList](bytes) if err == nil { - adminNetPolicies = append(adminNetPolicies, refList(anpList.Items)...) + adminNetworkPolicies = append(adminNetworkPolicies, refList(anpList.Items)...) return nil } logrus.Debugf("unable to parse list of admin network policies: %+v", err) anp, err := utils.ParseYamlStrict[v1alpha12.AdminNetworkPolicy](bytes) if err == nil { - adminNetPolicies = append(adminNetPolicies, anp) + adminNetworkPolicies = append(adminNetworkPolicies, anp) return nil } logrus.Debugf("unable to single admin network policies: %+v", err) - if len(netPolicies) == 0 && len(adminNetPolicies) == 0 && baseAdminNetPolicies == nil { + if len(netPolicies) == 0 && len(adminNetworkPolicies) == 0 && baselineAdminNetworkPolicy == nil { return errors.WithMessagef(err, "unable to parse any policies from yaml at %s", path) } @@ -105,85 +109,54 @@ func ReadNetworkPoliciesFromPath(policyPath string) ([]*networkingv1.NetworkPoli } } } - return netPolicies, adminNetPolicies, baseAdminNetPolicies, nil -} - -func ReadNetworkPoliciesFromKube(ctx context.Context, kubeClient IKubernetes, namespaces []string) ([]*networkingv1.NetworkPolicy, []*v1alpha12.AdminNetworkPolicy, *v1alpha12.BaselineAdminNetworkPolicy, error, error, error) { - var netpols []*networkingv1.NetworkPolicy - var anps []*v1alpha12.AdminNetworkPolicy - var banp *v1alpha12.BaselineAdminNetworkPolicy - var neterr, anperr, banperr error - - var netPolsCn = make(chan apiResponse[[]networkingv1.NetworkPolicy], 1) - go func(ch chan apiResponse[[]networkingv1.NetworkPolicy]) { - ch <- readNetworkPolicies(ctx, kubeClient, namespaces) - }(netPolsCn) - - var anpsCh = make(chan apiResponse[[]v1alpha12.AdminNetworkPolicy], 1) - go func(ch chan apiResponse[[]v1alpha12.AdminNetworkPolicy]) { - ch <- readAdminNetworkPolicies(ctx, kubeClient) - }(anpsCh) - - var banpsCh = make(chan apiResponse[v1alpha12.BaselineAdminNetworkPolicy], 1) - go func(ch chan apiResponse[v1alpha12.BaselineAdminNetworkPolicy]) { - ch <- readBaseAdminNetworkPolicies(ctx, kubeClient) - }(banpsCh) - - for i := 0; i <= 2; i++ { - select { - case result := <-netPolsCn: - r, err := result.response() - netpols = refList(r) - neterr = err - case result := <-anpsCh: - r, err := result.response() - anps = refList(r) - anperr = err - case result := <-banpsCh: - r, err := result.response() - if err == nil { - banp = &r - } - banperr = err - } - } - - return netpols, anps, banp, neterr, anperr, banperr + return netPolicies, adminNetworkPolicies, baselineAdminNetworkPolicy, nil } func refList[T any](refs []T) []*T { return slice.Map(builtin.Reference[T], refs) } -type apiResponse[T []networkingv1.NetworkPolicy | []v1alpha12.AdminNetworkPolicy | v1alpha12.BaselineAdminNetworkPolicy] struct { - data T - error error -} +func ReadNetworkPoliciesFromKube(ctx context.Context, kubeClient IKubernetes, namespaces []string, includeANPs, includeBANPs bool) ([]*networkingv1.NetworkPolicy, []*v1alpha12.AdminNetworkPolicy, *v1alpha12.BaselineAdminNetworkPolicy, error, error, error) { + var netpols []networkingv1.NetworkPolicy + var anps []v1alpha12.AdminNetworkPolicy + var banp *v1alpha12.BaselineAdminNetworkPolicy + var netErr, anpErr, banpErr error -func (t apiResponse[T]) response() (T, error) { - return t.data, t.error -} + var wg sync.WaitGroup + wg.Add(3) -func readNetworkPolicies(ctx context.Context, kubeClient IKubernetes, namespaces []string) apiResponse[[]networkingv1.NetworkPolicy] { - result, err := GetNetworkPoliciesInNamespaces(ctx, kubeClient, namespaces) - if err != nil { - return apiResponse[[]networkingv1.NetworkPolicy]{nil, err} - } - return apiResponse[[]networkingv1.NetworkPolicy]{result, err} -} + go func(w *sync.WaitGroup) { + defer w.Done() + netpols, netErr = GetNetworkPoliciesInNamespaces(ctx, kubeClient, namespaces) + return + }(&wg) -func readAdminNetworkPolicies(ctx context.Context, kubeClient IKubernetes) apiResponse[[]v1alpha12.AdminNetworkPolicy] { - result, err := GetAdminNetworkPoliciesInNamespaces(ctx, kubeClient) - if err != nil { - return apiResponse[[]v1alpha12.AdminNetworkPolicy]{nil, err} - } - return apiResponse[[]v1alpha12.AdminNetworkPolicy]{result, err} -} + go func(w *sync.WaitGroup) { + defer w.Done() + if !includeANPs { + return + } + anps, anpErr = GetAdminNetworkPoliciesInNamespaces(ctx, kubeClient) + return + }(&wg) + + go func(w *sync.WaitGroup) { + defer w.Done() + if !includeBANPs { + return + } + result, err := GetBaseAdminNetworkPoliciesInNamespaces(ctx, kubeClient) + if err != nil { + banpErr = err + } + if len(result) > 0 { + banp = &result[0] + } -func readBaseAdminNetworkPolicies(ctx context.Context, kubeClient IKubernetes) apiResponse[v1alpha12.BaselineAdminNetworkPolicy] { - result, err := GetBaseAdminNetworkPoliciesInNamespaces(ctx, kubeClient) - if err != nil { - return apiResponse[v1alpha12.BaselineAdminNetworkPolicy]{result, err} - } - return apiResponse[v1alpha12.BaselineAdminNetworkPolicy]{result, err} + return + }(&wg) + + wg.Wait() + + return refList(netpols), refList(anps), banp, netErr, anpErr, banpErr } diff --git a/cmd/policy-assistant/pkg/kube/read_test.go b/cmd/policy-assistant/pkg/kube/read_test.go index d8918f9f..2fa8af1e 100644 --- a/cmd/policy-assistant/pkg/kube/read_test.go +++ b/cmd/policy-assistant/pkg/kube/read_test.go @@ -3,225 +3,109 @@ package kube import ( "context" "errors" - "fmt" v1 "k8s.io/api/networking/v1" - errors2 "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" v1alpha12 "sigs.k8s.io/network-policy-api/apis/v1alpha1" "testing" - "time" ) func TestReadNetworkPoliciesFromKube(t *testing.T) { - anpNotFound := errors2.NewNotFound(schema.GroupResource{v1alpha12.GroupName, "AdminNetworkPolicy"}, "AdminNetworkPolicy") - banpNotFound := errors2.NewNotFound(schema.GroupResource{v1alpha12.GroupName, "BaselineAdminNetworkPolicy"}, "BaselineAdminNetworkPolicy") - netpolNotFound := errors2.NewNotFound(schema.GroupResource{v1.GroupName, "NetworkPolicies"}, "NetworkPolicies") - scenarios := map[string]struct { - ctxCreator func() (context.Context, context.CancelFunc) - anpResponse func() ([]v1alpha12.AdminNetworkPolicy, error) - banpResponse func() (v1alpha12.BaselineAdminNetworkPolicy, error) - netPolResponse func() ([]v1.NetworkPolicy, error) + AdminNetworkPolicies []v1alpha12.AdminNetworkPolicy + BaselineAdminNetworkPolicies []v1alpha12.BaselineAdminNetworkPolicy + NetworkPolicies []v1.NetworkPolicy expectedNetErr error expectedAnpErr error expectedBanpErr error }{ - "timeout error on admin network policies retrieval": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.WithTimeout(context.TODO(), 1*time.Nanosecond) - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - time.Sleep(1 * time.Millisecond) - return []v1alpha12.AdminNetworkPolicy{}, nil - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - return v1alpha12.BaselineAdminNetworkPolicy{}, nil - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - return nil, nil - }, + "parse error on admin network policies retrieval": { expectedAnpErr: context.DeadlineExceeded, }, - "resource not found on admin network policies retrieval": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.TODO(), func() {} - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - return []v1alpha12.AdminNetworkPolicy{}, anpNotFound - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - return v1alpha12.BaselineAdminNetworkPolicy{}, nil - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - return nil, nil - }, - expectedAnpErr: anpNotFound, - }, "return admin network policies": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.TODO(), func() {} - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - return []v1alpha12.AdminNetworkPolicy{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "admin-network-policy", - }, + AdminNetworkPolicies: []v1alpha12.AdminNetworkPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "admin-network-policy", }, - }, nil - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - return v1alpha12.BaselineAdminNetworkPolicy{}, nil - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - return nil, nil + }, }, }, - "timeout error on base admin network policies retrieval": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.WithTimeout(context.TODO(), 1*time.Nanosecond) - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - return []v1alpha12.AdminNetworkPolicy{}, nil - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - time.Sleep(1 * time.Millisecond) - return v1alpha12.BaselineAdminNetworkPolicy{}, nil - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - return nil, nil - }, + "parse error on base admin network policies retrieval": { expectedAnpErr: context.DeadlineExceeded, }, - "resource not found on base admin network policies retrieval": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.TODO(), func() {} - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - return []v1alpha12.AdminNetworkPolicy{}, nil - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - return v1alpha12.BaselineAdminNetworkPolicy{}, banpNotFound - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - return nil, nil - }, - expectedBanpErr: banpNotFound, - }, "return base admin network policies": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.TODO(), func() {} - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - return []v1alpha12.AdminNetworkPolicy{}, nil - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - return v1alpha12.BaselineAdminNetworkPolicy{ + BaselineAdminNetworkPolicies: []v1alpha12.BaselineAdminNetworkPolicy{ + { ObjectMeta: metav1.ObjectMeta{Name: "base-admin-network-policy"}, - }, nil - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - return nil, nil + }, }, }, - "timeout error on network policies retrieval": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.WithTimeout(context.TODO(), 1*time.Nanosecond) - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - return []v1alpha12.AdminNetworkPolicy{}, nil - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - return v1alpha12.BaselineAdminNetworkPolicy{}, nil - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - time.Sleep(10 * time.Millisecond) - return nil, nil - }, + "parse error on network policies retrieval": { expectedNetErr: context.DeadlineExceeded, }, - "resource not found on network policies retrieval": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.TODO(), func() {} - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - return []v1alpha12.AdminNetworkPolicy{}, nil - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - return v1alpha12.BaselineAdminNetworkPolicy{}, nil - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - return nil, netpolNotFound - }, - expectedNetErr: netpolNotFound, - }, "return network policies": { - ctxCreator: func() (context.Context, context.CancelFunc) { - return context.TODO(), func() {} - }, - anpResponse: func() ([]v1alpha12.AdminNetworkPolicy, error) { - return []v1alpha12.AdminNetworkPolicy{}, nil - }, - banpResponse: func() (v1alpha12.BaselineAdminNetworkPolicy, error) { - return v1alpha12.BaselineAdminNetworkPolicy{}, nil - }, - netPolResponse: func() ([]v1.NetworkPolicy, error) { - return []v1.NetworkPolicy{ - { - ObjectMeta: metav1.ObjectMeta{Name: "network_policy"}, + NetworkPolicies: []v1.NetworkPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "network_policy", + Namespace: "default", }, - }, nil + }, }, }, } for name, scenario := range scenarios { t.Run(name, func(t *testing.T) { - ctx, cancel := scenario.ctxCreator() - defer cancel() - k := &MockKubernetes{ - AdminNetworkPolicies: scenario.anpResponse, - BaseNetworkPolicies: scenario.banpResponse, - NetworkPolicies: scenario.netPolResponse, + AdminNetworkPolicies: scenario.AdminNetworkPolicies, + AdminNetworkPolicyError: scenario.expectedAnpErr, + BaseNetworkPolicies: scenario.BaselineAdminNetworkPolicies, + BaseAdminNetworkPolicyError: scenario.expectedBanpErr, + Namespaces: map[string]*MockNamespace{}, + NetworkPolicyError: scenario.expectedNetErr, } - netpol, anps, banp, netErr, anpErr, banpErr := ReadNetworkPoliciesFromKube(ctx, k, []string{"test"}) + + for _, np := range scenario.NetworkPolicies { + k.Namespaces[np.Namespace] = &MockNamespace{ + Netpols: map[string]*v1.NetworkPolicy{ + np.Name: &np, + }, + } + } + + netpol, anps, banp, netErr, anpErr, banpErr := ReadNetworkPoliciesFromKube(context.TODO(), k, []string{"default"}, true, true) if scenario.expectedNetErr != nil { if !errors.Is(netErr, scenario.expectedNetErr) { - t.Fatalf("Unexpected error1: %v, expected %v", netErr, scenario.expectedNetErr) + t.Fatalf("Unexpected error: %v, expected %v", netErr, scenario.expectedNetErr) } } if scenario.expectedAnpErr != nil { if !errors.Is(anpErr, scenario.expectedAnpErr) { - t.Fatalf("Unexpected error1: %v, expected %v", anpErr, scenario.expectedAnpErr) + t.Fatalf("Unexpected error: %v, expected %v", anpErr, scenario.expectedAnpErr) } } if scenario.expectedBanpErr != nil { if !errors.Is(banpErr, scenario.expectedBanpErr) { - t.Fatalf("Unexpected error1: %v, expected %v", banpErr, scenario.expectedBanpErr) + t.Fatalf("Unexpected error: %v, expected %v", banpErr, scenario.expectedBanpErr) } } - if len(anps) > 0 { - expected, _ := scenario.anpResponse() - if anps[0].Name != expected[0].Name { - t.Fatalf("Unexpected ANP: %v, expected %v", anps[0].Name, expected[0].Name) + if len(scenario.AdminNetworkPolicies) > 0 { + if anps[0].Name != scenario.AdminNetworkPolicies[0].Name { + t.Fatalf("Unexpected ANP: %v, expected %v", anps[0].Name, scenario.AdminNetworkPolicies[0].Name) } } - if banp != nil { - expected, _ := scenario.banpResponse() - if banp.Name != expected.Name { + if scenario.BaselineAdminNetworkPolicies != nil { + if banp.Name != scenario.BaselineAdminNetworkPolicies[0].Name { t.Fatalf("Unexpected BANP: %v, expected %v", banp.Name, banp.Name) } } - if len(netpol) > 0 { - expected, _ := scenario.netPolResponse() - fmt.Println(netpol[0].Name, expected[0].Name+"1") - if netpol[0].Name != expected[0].Name { - t.Fatalf("Unexpected NetworkPolicy: %v, expected %v", netpol[0].Name, expected[0].Name) + if len(scenario.NetworkPolicies) > 0 { + if netpol[0].Name != scenario.NetworkPolicies[0].Name { + t.Fatalf("Unexpected NetworkPolicy: %v, expected %v", netpol[0].Name, scenario.NetworkPolicies[0].Name) } } }) diff --git a/cmd/policy-assistant/pkg/kube/read_tests.go b/cmd/policy-assistant/pkg/kube/read_tests.go index fea1bd12..44922bad 100644 --- a/cmd/policy-assistant/pkg/kube/read_tests.go +++ b/cmd/policy-assistant/pkg/kube/read_tests.go @@ -8,12 +8,12 @@ import ( func RunReadNetworkPolicyTests() { Describe("ReadNetworkPolicies", func() { It("Should read a single policy from a single file", func() { - policies, _, _, err := ReadNetworkPoliciesFromPath("../../networkpolicies/features/portrange1.yaml") + policies, _, _, err := ReadNetworkPoliciesFromPath("../../test/example-policies/networkpolicies/features/portrange1.yaml") Expect(err).To(BeNil()) Expect(len(policies)).To(Equal(1)) }) It("Should read a list of policies from a single file", func() { - policies, _, _, err := ReadNetworkPoliciesFromPath("../../networkpolicies/yaml-syntax/yaml-list.yaml") + policies, _, _, err := ReadNetworkPoliciesFromPath("../../test/example-policies/networkpolicies/yaml-syntax/yaml-list.yaml") Expect(err).To(BeNil()) Expect(len(policies)).To(Equal(3)) }) @@ -28,27 +28,35 @@ func RunReadNetworkPolicyTests() { // }) It("Should read multiple policies from all files in a directory", func() { - policies, _, _, err := ReadNetworkPoliciesFromPath("../../networkpolicies/simple-example") + policies, _, _, err := ReadNetworkPoliciesFromPath("../../test/example-policies/networkpolicies/simple-example") Expect(err).To(BeNil()) Expect(len(policies)).To(Equal(7)) - policies, _, _, err = ReadNetworkPoliciesFromPath("../../networkpolicies/") + policies, _, _, err = ReadNetworkPoliciesFromPath("../../test/example-policies/networkpolicies/") Expect(err).To(BeNil()) Expect(len(policies)).To(Equal(14)) }) It("Should read multiple admin network policies", func() { - _, anps, _, err := ReadNetworkPoliciesFromPath("../../anps/") + _, anps, _, err := ReadNetworkPoliciesFromPath("../../test/example-policies/anps/") Expect(err).To(BeNil()) Expect(len(anps)).To(Equal(3)) }) It("Should read a base admin network policy", func() { - _, _, banp, err := ReadNetworkPoliciesFromPath("../../banp/") + _, _, banp, err := ReadNetworkPoliciesFromPath("../../test/example-policies/banp/") Expect(err).To(BeNil()) Expect(banp).ToNot(BeNil()) }) + It("Should parse multiple types from folder", func() { + policiies, anps, bapn, err := ReadNetworkPoliciesFromPath("../../test/example-policies/") + Expect(err).To(BeNil()) + Expect(len(policiies)).To(Equal(14)) + Expect(len(anps)).To(Equal(3)) + Expect(bapn).ToNot(BeNil()) + }) + // TODO test to show what happens for duplicate names }) } diff --git a/cmd/policy-assistant/anps/anp-list.yaml b/cmd/policy-assistant/test/example-policies/anps/anp-list.yaml similarity index 100% rename from cmd/policy-assistant/anps/anp-list.yaml rename to cmd/policy-assistant/test/example-policies/anps/anp-list.yaml diff --git a/cmd/policy-assistant/anps/anp.yaml b/cmd/policy-assistant/test/example-policies/anps/anp.yaml similarity index 100% rename from cmd/policy-assistant/anps/anp.yaml rename to cmd/policy-assistant/test/example-policies/anps/anp.yaml diff --git a/cmd/policy-assistant/banp/banp.yaml b/cmd/policy-assistant/test/example-policies/banp/banp.yaml similarity index 100% rename from cmd/policy-assistant/banp/banp.yaml rename to cmd/policy-assistant/test/example-policies/banp/banp.yaml diff --git a/cmd/policy-assistant/networkpolicies/allow-all-internal.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/allow-all-internal.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/allow-all-internal.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/allow-all-internal.yaml diff --git a/cmd/policy-assistant/networkpolicies/allow-all.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/allow-all.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/allow-all.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/allow-all.yaml diff --git a/cmd/policy-assistant/networkpolicies/features/portrange1.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/features/portrange1.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/features/portrange1.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/features/portrange1.yaml diff --git a/cmd/policy-assistant/networkpolicies/simple-example/allow-all-egress-by-label.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/allow-all-egress-by-label.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/simple-example/allow-all-egress-by-label.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/allow-all-egress-by-label.yaml diff --git a/cmd/policy-assistant/networkpolicies/simple-example/allow-all-for-label.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/allow-all-for-label.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/simple-example/allow-all-for-label.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/allow-all-for-label.yaml diff --git a/cmd/policy-assistant/networkpolicies/simple-example/allow-by-ip.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/allow-by-ip.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/simple-example/allow-by-ip.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/allow-by-ip.yaml diff --git a/cmd/policy-assistant/networkpolicies/simple-example/allow-label-to-label.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/allow-label-to-label.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/simple-example/allow-label-to-label.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/allow-label-to-label.yaml diff --git a/cmd/policy-assistant/networkpolicies/simple-example/deny-all-egress.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/deny-all-egress.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/simple-example/deny-all-egress.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/deny-all-egress.yaml diff --git a/cmd/policy-assistant/networkpolicies/simple-example/deny-all-for-label.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/deny-all-for-label.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/simple-example/deny-all-for-label.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/deny-all-for-label.yaml diff --git a/cmd/policy-assistant/networkpolicies/simple-example/deny-all.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/deny-all.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/simple-example/deny-all.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/simple-example/deny-all.yaml diff --git a/cmd/policy-assistant/networkpolicies/upstream_test_cases/allow-to-ns-y-pod-a.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/upstream_test_cases/allow-to-ns-y-pod-a.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/upstream_test_cases/allow-to-ns-y-pod-a.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/upstream_test_cases/allow-to-ns-y-pod-a.yaml diff --git a/cmd/policy-assistant/networkpolicies/yaml-syntax/yaml-list.yaml b/cmd/policy-assistant/test/example-policies/networkpolicies/yaml-syntax/yaml-list.yaml similarity index 100% rename from cmd/policy-assistant/networkpolicies/yaml-syntax/yaml-list.yaml rename to cmd/policy-assistant/test/example-policies/networkpolicies/yaml-syntax/yaml-list.yaml From 2663369d9f85c84d2efd62cda18c4e6bee631aa0 Mon Sep 17 00:00:00 2001 From: Nikola Date: Wed, 21 Aug 2024 08:25:50 +0300 Subject: [PATCH 3/3] final touches --- cmd/policy-assistant/pkg/cli/analyze.go | 11 +++++------ cmd/policy-assistant/pkg/kube/ikubernetes.go | 14 +++++++------- cmd/policy-assistant/pkg/kube/kubernetes.go | 10 +++++++--- cmd/policy-assistant/pkg/kube/read.go | 11 ++--------- cmd/policy-assistant/pkg/kube/read_test.go | 12 +++++------- 5 files changed, 26 insertions(+), 32 deletions(-) diff --git a/cmd/policy-assistant/pkg/cli/analyze.go b/cmd/policy-assistant/pkg/cli/analyze.go index 9b62886a..b26a6801 100644 --- a/cmd/policy-assistant/pkg/cli/analyze.go +++ b/cmd/policy-assistant/pkg/cli/analyze.go @@ -42,7 +42,7 @@ var AllModes = []string{ ProbeMode, } -const DefaultTimeout = 180 +const DefaultTimeout = 3 * time.Minute type AnalyzeArgs struct { AllNamespaces bool @@ -63,7 +63,7 @@ type AnalyzeArgs struct { // synthetic probe ProbePath string - Timeout int + Timeout time.Duration } func SetupAnalyzeCommand() *cobra.Command { @@ -90,8 +90,7 @@ func SetupAnalyzeCommand() *cobra.Command { command.Flags().StringVar(&args.TargetPodPath, "target-pod-path", "", "path to json target pod file -- json array of dicts") command.Flags().StringVar(&args.TrafficPath, "traffic-path", "", "path to json traffic file, containing of a list of traffic objects") command.Flags().StringVar(&args.ProbePath, "probe-path", "", "path to json model file for synthetic probe") - - command.Flags().IntVar(&args.Timeout, "timeout", DefaultTimeout, "timeout time in seconds") + command.Flags().DurationVar(&args.Timeout, "kube-client-timeout", DefaultTimeout, "kube client timeout") return command } @@ -118,7 +117,7 @@ func RunAnalyzeCommand(args *AnalyzeArgs) { includeANPS, includeBANPSs := shouldIncludeANPandBANP(kubeClient.ClientSet) - ctx, cancel := context.WithTimeout(context.TODO(), time.Duration(args.Timeout)*time.Second) + ctx, cancel := context.WithTimeout(context.TODO(), args.Timeout) defer cancel() kubePolicies, kubeANPs, kubeBANP, netpolErr, anpErr, banpErr = kube.ReadNetworkPoliciesFromKube(ctx, kubeClient, namespaces, includeANPS, includeBANPSs) @@ -349,7 +348,7 @@ func shouldIncludeANPandBANP(client *kubernetes.Clientset) (bool, bool) { case "BaselineAdminNetworkPolicy": includeBANP = true default: - panic(fmt.Sprintf("unexpected resource kind %s", res.Kind)) + continue } } } diff --git a/cmd/policy-assistant/pkg/kube/ikubernetes.go b/cmd/policy-assistant/pkg/kube/ikubernetes.go index bbf69184..393227fd 100644 --- a/cmd/policy-assistant/pkg/kube/ikubernetes.go +++ b/cmd/policy-assistant/pkg/kube/ikubernetes.go @@ -35,7 +35,7 @@ type IKubernetes interface { UpdateAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.AdminNetworkPolicy) (*v1alpha1.AdminNetworkPolicy, error) DeleteAdminNetworkPolicy(ctx context.Context, name string) error - GetBaseAdminNetworkPolicies(ctx context.Context) ([]v1alpha1.BaselineAdminNetworkPolicy, error) + GetBaselineAdminNetworkPolicy(ctx context.Context) (*v1alpha1.BaselineAdminNetworkPolicy, error) CreateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.BaselineAdminNetworkPolicy) (*v1alpha1.BaselineAdminNetworkPolicy, error) UpdateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.BaselineAdminNetworkPolicy) (*v1alpha1.BaselineAdminNetworkPolicy, error) DeleteBaselineAdminNetworkPolicy(ctx context.Context, name string) error @@ -95,12 +95,12 @@ func GetServicesInNamespaces(kubernetes IKubernetes, namespaces []string) ([]v1. return allServices, nil } -func GetAdminNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes) ([]v1alpha1.AdminNetworkPolicy, error) { +func GetAdminNetworkPolicies(ctx context.Context, kubernetes IKubernetes) ([]v1alpha1.AdminNetworkPolicy, error) { return kubernetes.GetAdminNetworkPolicies(ctx) } -func GetBaseAdminNetworkPoliciesInNamespaces(ctx context.Context, kubernetes IKubernetes) ([]v1alpha1.BaselineAdminNetworkPolicy, error) { - return kubernetes.GetBaseAdminNetworkPolicies(ctx) +func GetBaselineAdminNetworkPolicy(ctx context.Context, kubernetes IKubernetes) (*v1alpha1.BaselineAdminNetworkPolicy, error) { + return kubernetes.GetBaselineAdminNetworkPolicy(ctx) } type MockNamespace struct { @@ -113,7 +113,7 @@ type MockNamespace struct { type MockKubernetes struct { AdminNetworkPolicies []v1alpha1.AdminNetworkPolicy AdminNetworkPolicyError error - BaseNetworkPolicies []v1alpha1.BaselineAdminNetworkPolicy + BaselineNetworkPolicy *v1alpha1.BaselineAdminNetworkPolicy BaseAdminNetworkPolicyError error Namespaces map[string]*MockNamespace NetworkPolicyError error @@ -410,8 +410,8 @@ func (k *MockKubernetes) DeleteAdminNetworkPolicy(ctx context.Context, name stri return ErrNotImplemented } -func (m *MockKubernetes) GetBaseAdminNetworkPolicies(ctx context.Context) ([]v1alpha1.BaselineAdminNetworkPolicy, error) { - return m.BaseNetworkPolicies, m.BaseAdminNetworkPolicyError +func (m *MockKubernetes) GetBaselineAdminNetworkPolicy(ctx context.Context) (*v1alpha1.BaselineAdminNetworkPolicy, error) { + return m.BaselineNetworkPolicy, m.BaseAdminNetworkPolicyError } func (k *MockKubernetes) CreateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha1.BaselineAdminNetworkPolicy) (*v1alpha1.BaselineAdminNetworkPolicy, error) { diff --git a/cmd/policy-assistant/pkg/kube/kubernetes.go b/cmd/policy-assistant/pkg/kube/kubernetes.go index 479e5a0e..d6db587e 100644 --- a/cmd/policy-assistant/pkg/kube/kubernetes.go +++ b/cmd/policy-assistant/pkg/kube/kubernetes.go @@ -132,12 +132,16 @@ func (k *Kubernetes) DeleteAdminNetworkPolicy(ctx context.Context, name string) return ErrNotImplemented } -func (k *Kubernetes) GetBaseAdminNetworkPolicies(ctx context.Context) ([]v1alpha12.BaselineAdminNetworkPolicy, error) { - banp, err := k.alphaClientSet.BaselineAdminNetworkPolicies().List(ctx, metav1.ListOptions{}) +func (k *Kubernetes) GetBaselineAdminNetworkPolicy(ctx context.Context) (*v1alpha12.BaselineAdminNetworkPolicy, error) { + banps, err := k.alphaClientSet.BaselineAdminNetworkPolicies().List(ctx, metav1.ListOptions{}) + if err != nil { return nil, err } - return banp.Items, nil + if len(banps.Items) == 1 { + return &banps.Items[0], nil + } + return nil, nil } func (k *Kubernetes) CreateBaselineAdminNetworkPolicy(ctx context.Context, policy *v1alpha12.BaselineAdminNetworkPolicy) (*v1alpha12.BaselineAdminNetworkPolicy, error) { diff --git a/cmd/policy-assistant/pkg/kube/read.go b/cmd/policy-assistant/pkg/kube/read.go index e1b557bd..d3f8ff51 100644 --- a/cmd/policy-assistant/pkg/kube/read.go +++ b/cmd/policy-assistant/pkg/kube/read.go @@ -136,7 +136,7 @@ func ReadNetworkPoliciesFromKube(ctx context.Context, kubeClient IKubernetes, na if !includeANPs { return } - anps, anpErr = GetAdminNetworkPoliciesInNamespaces(ctx, kubeClient) + anps, anpErr = GetAdminNetworkPolicies(ctx, kubeClient) return }(&wg) @@ -145,14 +145,7 @@ func ReadNetworkPoliciesFromKube(ctx context.Context, kubeClient IKubernetes, na if !includeBANPs { return } - result, err := GetBaseAdminNetworkPoliciesInNamespaces(ctx, kubeClient) - if err != nil { - banpErr = err - } - if len(result) > 0 { - banp = &result[0] - } - + banp, banpErr = GetBaselineAdminNetworkPolicy(ctx, kubeClient) return }(&wg) diff --git a/cmd/policy-assistant/pkg/kube/read_test.go b/cmd/policy-assistant/pkg/kube/read_test.go index 2fa8af1e..2bcfd3ba 100644 --- a/cmd/policy-assistant/pkg/kube/read_test.go +++ b/cmd/policy-assistant/pkg/kube/read_test.go @@ -12,7 +12,7 @@ import ( func TestReadNetworkPoliciesFromKube(t *testing.T) { scenarios := map[string]struct { AdminNetworkPolicies []v1alpha12.AdminNetworkPolicy - BaselineAdminNetworkPolicies []v1alpha12.BaselineAdminNetworkPolicy + BaselineAdminNetworkPolicies *v1alpha12.BaselineAdminNetworkPolicy NetworkPolicies []v1.NetworkPolicy expectedNetErr error @@ -35,10 +35,8 @@ func TestReadNetworkPoliciesFromKube(t *testing.T) { expectedAnpErr: context.DeadlineExceeded, }, "return base admin network policies": { - BaselineAdminNetworkPolicies: []v1alpha12.BaselineAdminNetworkPolicy{ - { - ObjectMeta: metav1.ObjectMeta{Name: "base-admin-network-policy"}, - }, + BaselineAdminNetworkPolicies: &v1alpha12.BaselineAdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: "base-admin-network-policy"}, }, }, "parse error on network policies retrieval": { @@ -61,7 +59,7 @@ func TestReadNetworkPoliciesFromKube(t *testing.T) { k := &MockKubernetes{ AdminNetworkPolicies: scenario.AdminNetworkPolicies, AdminNetworkPolicyError: scenario.expectedAnpErr, - BaseNetworkPolicies: scenario.BaselineAdminNetworkPolicies, + BaselineNetworkPolicy: scenario.BaselineAdminNetworkPolicies, BaseAdminNetworkPolicyError: scenario.expectedBanpErr, Namespaces: map[string]*MockNamespace{}, NetworkPolicyError: scenario.expectedNetErr, @@ -99,7 +97,7 @@ func TestReadNetworkPoliciesFromKube(t *testing.T) { } if scenario.BaselineAdminNetworkPolicies != nil { - if banp.Name != scenario.BaselineAdminNetworkPolicies[0].Name { + if banp.Name != scenario.BaselineAdminNetworkPolicies.Name { t.Fatalf("Unexpected BANP: %v, expected %v", banp.Name, banp.Name) } }