Skip to content

Commit f199fca

Browse files
committed
Set up harvester-restricted-vlan
1 parent 116cad1 commit f199fca

File tree

19 files changed

+785
-6
lines changed

19 files changed

+785
-6
lines changed

Makefile.tinygo

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
ROOT_DIR ?= $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
22
BIN_DIR := $(abspath $(ROOT_DIR)/bin)
3-
POLICY_DIR := $(dir $(patsubst %/,%,$(CURDIR)))
3+
POLICY_DIR := $(notdir $(patsubst %/,%,$(CURDIR)))
44

55
GOLANGCI_LINT_VER := v2.5.0
66
GOLANGCI_LINT_BIN := golangci-lint
@@ -14,8 +14,9 @@ ifeq ($(CI),true)
1414
else
1515
podman run \
1616
--rm \
17+
--user $(id -u):$(id -g) \
1718
-e GOFLAGS="-buildvcs=false" \
18-
-v ${POLICY_DIR}:/src:rw,Z \
19+
-v ${CURDIR}:/src:rw,Z \
1920
-w /src tinygo/tinygo:0.39.0 \
2021
tinygo build -o policy.wasm -target=wasi -no-debug ./cmd
2122
endif

policies/harvester-pci-devices/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This policy guards against VMs attaching PCI Devices (e.g., GPUs) without permis
88
apiVersion: policies.kubewarden.io/v1
99
kind: ClusterAdmissionPolicy
1010
metadata:
11-
name: cc-policy-1
11+
name: harvester-pci-policy-1
1212
spec:
1313
module: harbor.op-prg2-0-dev-ingress.op.suse.org/op-portal/kubewarden-policy:20
1414
rules:

policies/harvester-pci-devices/internal/domain/settings_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ func TestNewSettingsFromValidationReq(t *testing.T) {
141141
settingsJSON := []byte(`{
142142
"namespaceDeviceBindings": [
143143
{
144-
"namespace": "test-cc-namespace-1",
145-
"device": "test-cc-device-1"
144+
"namespace": "test-restricted-namespace-1",
145+
"device": "test-restricted-device-1"
146146
}
147147
]
148148
}`)
@@ -153,5 +153,5 @@ func TestNewSettingsFromValidationReq(t *testing.T) {
153153

154154
newSettings, err := domain.NewSettingsFromValidationReq(validationRequest)
155155
require.NoError(t, err)
156-
assert.Equal(t, "test-cc-namespace-1", newSettings.NamespaceDeviceBindings[0].Namespace)
156+
assert.Equal(t, "test-restricted-namespace-1", newSettings.NamespaceDeviceBindings[0].Namespace)
157157
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Binaries for programs and plugins
2+
*.exe
3+
*.exe~
4+
*.dll
5+
*.so
6+
*.dylib
7+
*.wasm
8+
9+
# Test binary, built with `go test -c`
10+
*.test
11+
12+
# Output of the go coverage tool, specifically when used with LiteIDE
13+
*.out
14+
coverage.xml
15+
16+
# Dependency directories (remove the comment below to include it)
17+
# vendor/
18+
19+
bin/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../Makefile.tinygo
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# harvester-restricted-vlan-namespace
2+
3+
This policy guards against harvester creating a network for a restricted VLAN in unauthorized namespaces.
4+
5+
**Example policy:**
6+
7+
```
8+
apiVersion: policies.kubewarden.io/v1
9+
kind: ClusterAdmissionPolicy
10+
metadata:
11+
name: restricted-vlan-policy-1
12+
spec:
13+
module: harvester-restricted-vlan:0.1.0
14+
rules:
15+
- apiGroups: ["k8s.cni.cncf.io"]
16+
apiVersions: ["v1"]
17+
resources: ["network-attachment-definitions"]
18+
operations: ["CREATE", "UPDATE"]
19+
settings:
20+
namespaceVLANBindings:
21+
- namespace: test-restricted-1-network-1
22+
vlan: 42
23+
- namespace: test-restricted-2-network-1
24+
vlan: 1337
25+
mutating: false # or true if your policy mutates resources
26+
policyServer: default
27+
```
28+
29+
**Specifications:**
30+
31+
1. All bound namespaces must use their respective bound VLANs.
32+
2. All bound VLANs must use their respective bound namespaces.
33+
3. Any namespace or VLAN that isn't bound, is unrestricted.
34+
35+
**Examples:**
36+
37+
The following examples are with the example policy above, with a random non-cc VLAN being 100.
38+
39+
| namespace | network | Result |
40+
|-----------------------------|---------|--------|
41+
| test-restricted-1-network-1 | 42 | ALLOW |
42+
| test-restricted-2-network-1 | 1337 | ALLOW |
43+
| random-namespace | 100 | ALLOW |
44+
| test-restricted-1-network-1 | 1337 | REJECT |
45+
| test-restricted-2-network-2 | 42 | REJECT |
46+
| random-namespace | 42 | REJECT |
47+
| random-namespace | 1337 | REJECT |
48+
| test-restricted-1-network-1 | 100 | REJECT |
49+
| test-restricted-2-network-2 | 100 | REJECT |
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
7+
"github.com/SUSE/openplatform-kubewarden-policies/policies/harvester-restricted-vlan-namespace/internal"
8+
"github.com/SUSE/openplatform-kubewarden-policies/policies/harvester-restricted-vlan-namespace/internal/logger"
9+
"github.com/wapc/wapc-guest-tinygo"
10+
)
11+
12+
const httpBadRequestStatusCode = 400
13+
14+
func main() {
15+
ctx := logger.ContextWithLogger(context.Background())
16+
17+
wapc.RegisterFunctions(wapc.Functions{
18+
"validate": func(payload []byte) ([]byte, error) {
19+
return validateRequest(ctx, payload)
20+
},
21+
"validate_settings": func(payload []byte) ([]byte, error) {
22+
return validateSettings(ctx, payload)
23+
},
24+
})
25+
}
26+
27+
func parseSettings(payload []byte) (internal.Settings, error) {
28+
settings := internal.Settings{}
29+
err := json.Unmarshal(payload, &settings)
30+
if err != nil {
31+
return internal.Settings{}, err
32+
}
33+
34+
return settings, nil
35+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
7+
"github.com/SUSE/openplatform-kubewarden-policies/policies/harvester-restricted-vlan-namespace/internal"
8+
"github.com/SUSE/openplatform-kubewarden-policies/policies/harvester-restricted-vlan-namespace/internal/logger"
9+
"github.com/francoispqt/onelog"
10+
kubewarden "github.com/kubewarden/policy-sdk-go"
11+
kubewardenProtocol "github.com/kubewarden/policy-sdk-go/protocol"
12+
)
13+
14+
func validateRequest(ctx context.Context, payload []byte) ([]byte, error) {
15+
validationRequest := kubewardenProtocol.ValidationRequest{}
16+
err := json.Unmarshal(payload, &validationRequest)
17+
if err != nil {
18+
return kubewarden.RejectRequest(
19+
kubewarden.Message(err.Error()),
20+
kubewarden.Code(httpBadRequestStatusCode))
21+
}
22+
23+
settings, err := parseSettings(validationRequest.Settings)
24+
if err != nil {
25+
return kubewarden.RejectRequest(
26+
kubewarden.Message(err.Error()),
27+
kubewarden.Code(httpBadRequestStatusCode))
28+
}
29+
30+
networkAttachmentDefinition := internal.NetworkAttachmentDefinition{}
31+
err = json.Unmarshal(validationRequest.Request.Object, &networkAttachmentDefinition)
32+
if err != nil {
33+
return kubewarden.RejectRequest(
34+
kubewarden.Message(err.Error()),
35+
kubewarden.Code(httpBadRequestStatusCode))
36+
}
37+
38+
namespace := networkAttachmentDefinition.Metadata.Namespace
39+
vlan := networkAttachmentDefinition.Spec.Config.VLAN
40+
l := logger.FromContext(ctx).With(func(entry onelog.Entry) {
41+
entry.String("namespace", namespace)
42+
entry.Int("vlan", vlan)
43+
})
44+
45+
l.Info("NETWORK_CHECK namespace")
46+
if !settings.IsVLANAllowed(ctx, namespace, vlan) {
47+
l.Info("NETWORK_REJECTED namespace")
48+
return kubewarden.RejectRequest("Invalid request", kubewarden.Code(httpBadRequestStatusCode))
49+
}
50+
l.Info("NETWORK_ALLOWED namespace")
51+
52+
return kubewarden.AcceptRequest()
53+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
kubewarden "github.com/kubewarden/policy-sdk-go"
8+
)
9+
10+
func validateSettings(ctx context.Context, payload []byte) ([]byte, error) {
11+
settings, err := parseSettings(payload)
12+
if err != nil {
13+
return kubewarden.RejectSettings(kubewarden.Message(fmt.Sprintf("Invalid settings JSON: %v", err)))
14+
}
15+
16+
valid := settings.IsValid(ctx)
17+
if !valid {
18+
return kubewarden.RejectSettings("Invalid settings")
19+
}
20+
21+
return kubewarden.AcceptSettings()
22+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module github.com/SUSE/openplatform-kubewarden-policies/policies/harvester-restricted-vlan-namespace
2+
3+
go 1.22
4+
5+
toolchain go1.23.1
6+
7+
require (
8+
github.com/francoispqt/onelog v0.0.0-20190306043706-8c2bb31b10a4
9+
github.com/kubewarden/policy-sdk-go v0.11.0
10+
github.com/stretchr/testify v1.10.0
11+
github.com/wapc/wapc-guest-tinygo v0.3.3
12+
)
13+
14+
require (
15+
github.com/davecgh/go-spew v1.1.1 // indirect
16+
github.com/francoispqt/gojay v1.2.13 // indirect
17+
github.com/go-openapi/strfmt v0.23.0 // indirect
18+
github.com/kr/pretty v0.3.1 // indirect
19+
github.com/kubewarden/k8s-objects v1.32.0-kw1 // indirect
20+
github.com/pmezard/go-difflib v1.0.0 // indirect
21+
github.com/rogpeppe/go-internal v1.10.0 // indirect
22+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
23+
gopkg.in/yaml.v3 v3.0.1 // indirect
24+
)
25+
26+
replace github.com/go-openapi/strfmt => github.com/kubewarden/strfmt v0.1.3

0 commit comments

Comments
 (0)