Skip to content

Commit

Permalink
tests: add ValidatingAdmissionPolicy tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pmalek committed Jan 16, 2025
1 parent 47450e0 commit e112d0a
Show file tree
Hide file tree
Showing 3 changed files with 438 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ spec:
resources:
- "dataplanes"
variables:
- name: network
expression: object.spec.network
- name: services
expression: variables.network.services
- name: ingressPorts
expression: object.spec.network.services.ingress.ports
expression: variables.services.ingress.ports
- name: podTemplateSpec
expression: object.spec.deployment.podTemplateSpec
- name: proxyContainer
Expand All @@ -33,33 +37,37 @@ spec:
variables.proxyContainer.env.filter(e, e.name == "KONG_PROXY_LISTEN")
- name: envPortMaps
expression: |
variables.envFilteredPortMaps.size() > 0 ? variables.envFilteredPortMaps[0] : null
variables.envFilteredPortMaps.size() > 0 ? variables.envFilteredPortMaps[0].value : null
- name: envProxyListen
expression: |
variables.envFilteredProxyListen.size() > 0 ? variables.envFilteredProxyListen[0] : null
variables.envFilteredProxyListen.size() > 0 ? variables.envFilteredProxyListen[0].value : null
# Using string functions from: https://pkg.go.dev/github.com/google/cel-go/ext
validations:
- messageExpression: "'Each port from spec.network.services.ingress.ports has to have an accompanying port in KONG_PORT_MAPS env'"
expression: |
variables.ingressPorts == null ||
variables.envPortMaps == null ||
variables.ingressPorts.all(p, variables.envPortMaps.value.
split(",").
exists(pm,
pm.split(":")[1].trim() == string(p.targetPort)
)
)
!has(object.spec.network) ||
!has(object.spec.network.services) ||
variables.ingressPorts == null ||
variables.envPortMaps == null ||
variables.ingressPorts.all(p, variables.envPortMaps.
split(",").
exists(pm,
pm.split(":")[1].trim() == string(p.targetPort)
)
)
reason: Invalid
- messageExpression: "'Each port from spec.network.services.ingress.ports has to have an accompanying port in KONG_PROXY_LISTEN env'"
expression: |
variables.ingressPorts == null ||
variables.envProxyListen == null ||
variables.ingressPorts.all(p, variables.envProxyListen.value.
split(",").
exists(pm,
pm.trim().split(" ")[0].split(":")[1].trim() == string(p.targetPort)
)
!has(object.spec.network) ||
!has(object.spec.network.services) ||
variables.ingressPorts == null ||
variables.envProxyListen == null ||
variables.ingressPorts.all(p, variables.envProxyListen.
split(",").
exists(pm,
pm.trim().split(" ")[0].split(":")[1].trim() == string(p.targetPort)
)
)
reason: Invalid
---
apiVersion: admissionregistration.k8s.io/v1
Expand Down
263 changes: 263 additions & 0 deletions test/crdsvalidation/dataplane_validatingadmissionpolicy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
package crdsvalidation

import (
"context"
"testing"

"github.com/samber/lo"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"

operatorv1beta1 "github.com/kong/gateway-operator/api/v1beta1"
"github.com/kong/gateway-operator/modules/manager/scheme"
"github.com/kong/gateway-operator/test/envtest"
"github.com/kong/gateway-operator/test/helpers/kustomize"

kcfgcrdsvalidation "github.com/kong/kubernetes-configuration/test/crdsvalidation"
)

const (
// KustomizePathValidationPolicies is the path to the Kustomize directory containing the validation policies.
KustomizePathValidationPolicies = "config/default/validation_policies/"
)

func TestDataPlaneValidatingAdmissionPolicy(t *testing.T) {
t.Parallel()
ctx := context.Background()
scheme := scheme.Get()
cfg, ns := envtest.Setup(t, ctx, scheme)

require.NoError(t, kustomize.Apply(ctx, cfg, KustomizePathValidationPolicies))

t.Run("ports", func(t *testing.T) {
kcfgcrdsvalidation.TestCasesGroup[*operatorv1beta1.DataPlane]{
{
Name: "not providing spec fails",
TestObject: &operatorv1beta1.DataPlane{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "dp-",
Namespace: ns.Name,
},
Spec: operatorv1beta1.DataPlaneSpec{},
},
ExpectedErrorMessage: lo.ToPtr("DataPlane requires an image to be set on proxy container"),
},
{
Name: "providing correct ingress service ports and KONG_PORT_MAPS env succeeds",
TestObject: &operatorv1beta1.DataPlane{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "dp-",
Namespace: ns.Name,
},
Spec: operatorv1beta1.DataPlaneSpec{
DataPlaneOptions: operatorv1beta1.DataPlaneOptions{
Deployment: operatorv1beta1.DataPlaneDeploymentOptions{
DeploymentOptions: operatorv1beta1.DeploymentOptions{
PodTemplateSpec: &corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "proxy",
Image: "kong:3.9",
Env: []corev1.EnvVar{
{
Name: "KONG_PROXY_LISTEN",
Value: "0.0.0.0:8000 reuseport backlog=16384, 0.0.0.0:8443 http2 ssl reuseport backlog=16384",
},
{
Name: "KONG_PORT_MAPS",
Value: "80:8000,443:8443",
},
},
},
},
},
},
},
},
Network: operatorv1beta1.DataPlaneNetworkOptions{
Services: &operatorv1beta1.DataPlaneServices{
Ingress: &operatorv1beta1.DataPlaneServiceOptions{
Ports: []operatorv1beta1.DataPlaneServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.FromInt(8000),
},
{
Name: "http",
Port: 443,
TargetPort: intstr.FromInt(8443),
},
},
},
},
},
},
},
},
},
{
Name: "providing incorrect ingress service ports and KONG_PORT_MAPS env fails",
TestObject: &operatorv1beta1.DataPlane{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "dp-",
Namespace: ns.Name,
},
Spec: operatorv1beta1.DataPlaneSpec{
DataPlaneOptions: operatorv1beta1.DataPlaneOptions{
Deployment: operatorv1beta1.DataPlaneDeploymentOptions{
DeploymentOptions: operatorv1beta1.DeploymentOptions{
PodTemplateSpec: &corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "proxy",
Image: "kong:3.9",
Env: []corev1.EnvVar{
{
Name: "KONG_PROXY_LISTEN",
Value: "0.0.0.0:8000 reuseport backlog=16384, 0.0.0.0:8443 http2 ssl reuseport backlog=16384",
},
{
Name: "KONG_PORT_MAPS",
Value: "80:8000,443:8443",
},
},
},
},
},
},
},
},
Network: operatorv1beta1.DataPlaneNetworkOptions{
Services: &operatorv1beta1.DataPlaneServices{
Ingress: &operatorv1beta1.DataPlaneServiceOptions{
Ports: []operatorv1beta1.DataPlaneServicePort{
{
Name: "http",
Port: 80,
// No matching port in KONG_PORT_MAPS
TargetPort: intstr.FromInt(8001),
},
{
Name: "http",
Port: 443,
TargetPort: intstr.FromInt(8443),
},
},
},
},
},
},
},
},
ExpectedErrorMessage: lo.ToPtr("is forbidden: ValidatingAdmissionPolicy 'ports.dataplane.gateway-operator.konghq.com' with binding 'binding-ports.dataplane.gateway-operator.konghq.com' denied request: Each port from spec.network.services.ingress.ports has to have an accompanying port in KONG_PORT_MAPS env"),
},
{
Name: "providing correct ingress service ports and KONG_PROXY_LISTEN env succeeds",
TestObject: &operatorv1beta1.DataPlane{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "dp-",
Namespace: ns.Name,
},
Spec: operatorv1beta1.DataPlaneSpec{
DataPlaneOptions: operatorv1beta1.DataPlaneOptions{
Deployment: operatorv1beta1.DataPlaneDeploymentOptions{
DeploymentOptions: operatorv1beta1.DeploymentOptions{
PodTemplateSpec: &corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "proxy",
Image: "kong:3.9",
Env: []corev1.EnvVar{
{
Name: "KONG_PROXY_LISTEN",
Value: "0.0.0.0:8000 reuseport backlog=16384, 0.0.0.0:8443 http2 ssl reuseport backlog=16384",
},
{
Name: "KONG_PORT_MAPS",
Value: "80:8000,443:8443",
},
},
},
},
},
},
},
},
Network: operatorv1beta1.DataPlaneNetworkOptions{
Services: &operatorv1beta1.DataPlaneServices{
Ingress: &operatorv1beta1.DataPlaneServiceOptions{
Ports: []operatorv1beta1.DataPlaneServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.FromInt(8000),
},
},
},
},
},
},
},
},
},
{
Name: "providing incorrect ingress service ports and KONG_PROXY_LISTEN env fails",
TestObject: &operatorv1beta1.DataPlane{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "dp-",
Namespace: ns.Name,
},
Spec: operatorv1beta1.DataPlaneSpec{
DataPlaneOptions: operatorv1beta1.DataPlaneOptions{
Deployment: operatorv1beta1.DataPlaneDeploymentOptions{
DeploymentOptions: operatorv1beta1.DeploymentOptions{
PodTemplateSpec: &corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "proxy",
Image: "kong:3.9",
Env: []corev1.EnvVar{
{
Name: "KONG_PROXY_LISTEN",
Value: "0.0.0.0:8000 reuseport backlog=16384, 0.0.0.0:8443 http2 ssl reuseport backlog=16384",
},
{
Name: "KONG_PORT_MAPS",
Value: "80:8000,443:8443",
},
},
},
},
},
},
},
},
Network: operatorv1beta1.DataPlaneNetworkOptions{
Services: &operatorv1beta1.DataPlaneServices{
Ingress: &operatorv1beta1.DataPlaneServiceOptions{
Ports: []operatorv1beta1.DataPlaneServicePort{
{
Name: "http",
Port: 80,
// No matching port in KONG_PROXY_LISTEN
TargetPort: intstr.FromInt(8001),
},
},
},
},
},
},
},
},
ExpectedErrorMessage: lo.ToPtr("is forbidden: ValidatingAdmissionPolicy 'ports.dataplane.gateway-operator.konghq.com' with binding 'binding-ports.dataplane.gateway-operator.konghq.com' denied request: Each port from spec.network.services.ingress.ports has to have an accompanying port in KONG_PORT_MAPS env"),
},
}.RunWithConfig(t, cfg, scheme)
})
}
Loading

0 comments on commit e112d0a

Please sign in to comment.