diff --git a/README.md b/README.md index f49af46b2743a15d34a0a8c88b2e8b6a063a7821..653e1373286abf14ddf7e1edb06fdd8d9f6df55b 100644 --- a/README.md +++ b/README.md @@ -59,3 +59,5 @@ | podDisruptionBudget.maxUnavailable | | `1` | | podDisruptionBudget.minAvailable | If present, this variable will configure minAvailable in the PodDisruptionBudget. :warning: if you have `replicaCount: 1` and `podDisruptionBudget.minAvailable: 1` `kubectl drain` will be blocked. | `nil` | | prometheus.metrics | Annotates the service for prometheus auto-discovery. Also denies access to the `/metrics` endpoint from external addresses with Ingress. | `false` | +| networkPolicy.enabled | Enable container network policy | `false` | +| networkPolicy.spec | [Network policy](https://kubernetes.io/docs/concepts/services-networking/network-policies/) definition | `{ podSelector: { matchLabels: {} }, ingress: [{ from: [{ podSelector: { matchLabels: {} } }, { namespaceSelector: { matchLabels: { name: gitlab-managed-apps } } }] }] }` | diff --git a/templates/network-policy.yaml b/templates/network-policy.yaml new file mode 100644 index 0000000000000000000000000000000000000000..79c0ed662514d8deb99bb19382105f8f445ce288 --- /dev/null +++ b/templates/network-policy.yaml @@ -0,0 +1,13 @@ +{{- if .Values.networkPolicy.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "fullname" . }} + labels: + app: {{ template "appname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: +{{ toYaml .Values.networkPolicy.spec | indent 2 }} +{{- end -}} diff --git a/test/template_test.go b/test/template_test.go index d725d724036201ef9017aead95d44369ad5734e5..bc93ea9a36ad466e5c4e6581a79edde08221384a 100644 --- a/test/template_test.go +++ b/test/template_test.go @@ -9,6 +9,7 @@ import ( "github.com/gruntwork-io/terratest/modules/random" "github.com/stretchr/testify/require" extensions "k8s.io/api/extensions/v1beta1" + netV1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -198,6 +199,107 @@ func TestWorkerDeploymentTemplate(t *testing.T) { } } +func TestNetworkPolicyDeployment(t *testing.T) { + releaseName := "network-policy-test" + templates := []string{"templates/network-policy.yaml"} + expectedLabels := map[string]string{ + "app": releaseName, + "chart": chartName, + "release": releaseName, + "heritage": "Tiller", + } + + tcs := []struct { + name string + valueFiles []string + values map[string]string + + meta metav1.ObjectMeta + podSelector metav1.LabelSelector + policyTypes []netV1.PolicyType + ingress []netV1.NetworkPolicyIngressRule + egress []netV1.NetworkPolicyEgressRule + }{ + { + name: "defaults", + }, + { + name: "with default policy", + values: map[string]string{"networkPolicy.enabled": "true"}, + meta: metav1.ObjectMeta{Name: releaseName + "-auto-deploy", Labels: expectedLabels}, + podSelector: metav1.LabelSelector{MatchLabels: map[string]string{}}, + ingress: []netV1.NetworkPolicyIngressRule{ + { + From: []netV1.NetworkPolicyPeer{ + {PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{}}}, + {NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"name": "gitlab-managed-apps"}, + }}, + }, + }, + }, + }, + { + name: "with custom policy", + valueFiles: []string{"./testdata/custom-policy.yaml"}, + meta: metav1.ObjectMeta{Name: releaseName + "-auto-deploy", Labels: expectedLabels}, + podSelector: metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, + ingress: []netV1.NetworkPolicyIngressRule{ + { + From: []netV1.NetworkPolicyPeer{ + {PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{}}}, + {NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"name": "foo"}, + }}, + }, + }, + }, + }, + { + name: "with full spec policy", + valueFiles: []string{"./testdata/full-spec-policy.yaml"}, + meta: metav1.ObjectMeta{Name: releaseName + "-auto-deploy", Labels: expectedLabels}, + podSelector: metav1.LabelSelector{MatchLabels: map[string]string{}}, + policyTypes: []netV1.PolicyType{"Ingress", "Egress"}, + ingress: []netV1.NetworkPolicyIngressRule{ + { + From: []netV1.NetworkPolicyPeer{ + {PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{}}}, + }, + }, + }, + egress: []netV1.NetworkPolicyEgressRule{ + { + To: []netV1.NetworkPolicyPeer{ + {NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"name": "gitlab-managed-apps"}, + }}, + }, + }, + }, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + opts := &helm.Options{ + ValuesFiles: tc.valueFiles, + SetValues: tc.values, + } + output := helm.RenderTemplate(t, opts, helmChartPath, releaseName, templates) + + policy := new(netV1.NetworkPolicy) + helm.UnmarshalK8SYaml(t, output, policy) + + require.Equal(t, tc.meta, policy.ObjectMeta) + require.Equal(t, tc.podSelector, policy.Spec.PodSelector) + require.Equal(t, tc.policyTypes, policy.Spec.PolicyTypes) + require.Equal(t, tc.ingress, policy.Spec.Ingress) + require.Equal(t, tc.egress, policy.Spec.Egress) + }) + } +} + type workerDeploymentTestCase struct { ExpectedName string ExpectedCmd []string diff --git a/test/testdata/custom-policy.yaml b/test/testdata/custom-policy.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8cc487aa725b2bb91a704caf5e39c3a3882be055 --- /dev/null +++ b/test/testdata/custom-policy.yaml @@ -0,0 +1,13 @@ +networkPolicy: + enabled: true + spec: + podSelector: + matchLabels: + foo: bar + ingress: + - from: + - podSelector: + matchLabels: {} + - namespaceSelector: + matchLabels: + name: foo diff --git a/test/testdata/full-spec-policy.yaml b/test/testdata/full-spec-policy.yaml new file mode 100644 index 0000000000000000000000000000000000000000..25254b5d2c51802230fd383f206e1848a9517879 --- /dev/null +++ b/test/testdata/full-spec-policy.yaml @@ -0,0 +1,17 @@ +networkPolicy: + enabled: true + spec: + podSelector: + matchLabels: {} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: {} + egress: + - to: + - namespaceSelector: + matchLabels: + name: gitlab-managed-apps diff --git a/values.yaml b/values.yaml index 9c6a8345f7ab4a6a100b6c45a7ccfc46d4d7d7d2..7c21c34800bb7c5008d17fa10ddf7e877d4acabc 100644 --- a/values.yaml +++ b/values.yaml @@ -83,6 +83,22 @@ podDisruptionBudget: # minAvailable: 1 maxUnavailable: 1 +## Configure NetworkPolicy +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +# +networkPolicy: + enabled: false + spec: + podSelector: + matchLabels: {} + ingress: + - from: + - podSelector: + matchLabels: {} + - namespaceSelector: + matchLabels: + name: gitlab-managed-apps + workers: {} # worker: # replicaCount: 1