ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
155
services/oci-l4-relay-guest/cmd/admission/main_test.go
Normal file
155
services/oci-l4-relay-guest/cmd/admission/main_test.go
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestWriteJSONFileCreatesParentDirectory(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "workflow", "validation-summary.json")
|
||||
if err := writeJSONFile(path, map[string]bool{"valid": true}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
contents, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(contents) != "{\"valid\":true}\n" {
|
||||
t.Fatalf("unexpected contents %q", contents)
|
||||
}
|
||||
}
|
||||
|
||||
func validBundle(now time.Time) bundle {
|
||||
return bundle{
|
||||
SchemaVersion: 1,
|
||||
GeneratedAt: now.Add(-time.Minute),
|
||||
ExpiresAt: now.Add(24 * time.Hour),
|
||||
AdmittedIPv4: []addressRange{{Start: "192.0.2.0", End: "192.0.2.255"}, {Start: "198.51.100.1", End: "198.51.100.1"}},
|
||||
ExceptionIPv4: []addressRange{{Start: "203.0.113.0", End: "203.0.113.15"}},
|
||||
AdmittedIntervalCount: 2,
|
||||
AdmittedAddressCount: 257,
|
||||
ExceptionIntervalCount: 1,
|
||||
ExceptionAddressCount: 16,
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAndRender(t *testing.T) {
|
||||
now := time.Date(2026, 7, 12, 0, 0, 0, 0, time.UTC)
|
||||
validated, err := validateBundle(now, validBundle(now))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var output bytes.Buffer
|
||||
if err := render(&output, validated, "ens3"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, expected := range []string{
|
||||
"delete table inet oci_l4_relay_web_allow",
|
||||
"192.0.2.0-192.0.2.255",
|
||||
"198.51.100.1",
|
||||
"203.0.113.0-203.0.113.15",
|
||||
"iifname \"ens3\" tcp dport { 80, 443, 465, 993 }",
|
||||
"counter name web_allow_denied drop",
|
||||
} {
|
||||
if !strings.Contains(output.String(), expected) {
|
||||
t.Errorf("rendered output does not contain %q", expected)
|
||||
}
|
||||
}
|
||||
if strings.Contains(output.String(), "587") {
|
||||
t.Fatal("rendered output admits cluster-local submission")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidationFailures(t *testing.T) {
|
||||
now := time.Date(2026, 7, 12, 0, 0, 0, 0, time.UTC)
|
||||
tests := map[string]func(*bundle){
|
||||
"schema": func(value *bundle) { value.SchemaVersion = 2 },
|
||||
"future": func(value *bundle) { value.GeneratedAt = now.Add(10 * time.Minute) },
|
||||
"expiry": func(value *bundle) { value.ExpiresAt = now.Add(30 * time.Minute) },
|
||||
"lifetime": func(value *bundle) { value.ExpiresAt = now.Add(8 * 24 * time.Hour) },
|
||||
"overlap": func(value *bundle) { value.AdmittedIPv4[1] = addressRange{Start: "192.0.2.128", End: "192.0.2.200"} },
|
||||
"reversed": func(value *bundle) { value.AdmittedIPv4[0] = addressRange{Start: "192.0.2.10", End: "192.0.2.1"} },
|
||||
"ipv6": func(value *bundle) { value.AdmittedIPv4[0] = addressRange{Start: "2001:db8::1", End: "2001:db8::2"} },
|
||||
"noncanonical": func(value *bundle) { value.AdmittedIPv4[0].Start = "192.000.002.000" },
|
||||
"address count": func(value *bundle) { value.AdmittedAddressCount++ },
|
||||
}
|
||||
for name, mutate := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
value := validBundle(now)
|
||||
mutate(&value)
|
||||
if _, err := validateBundle(now, value); err == nil {
|
||||
t.Fatal("expected validation failure")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRejectsUnsafeInterface(t *testing.T) {
|
||||
now := time.Date(2026, 7, 12, 0, 0, 0, 0, time.UTC)
|
||||
validated, err := validateBundle(now, validBundle(now))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := render(&bytes.Buffer{}, validated, "ens3\nflush ruleset"); err == nil {
|
||||
t.Fatal("expected unsafe interface rejection")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderFailClosed(t *testing.T) {
|
||||
var output bytes.Buffer
|
||||
if err := renderFailClosed(&output, "ens3"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(output.String(), "iifname \"ens3\" tcp dport { 80, 443, 465, 993 } counter name web_allow_denied drop") {
|
||||
t.Fatal("fail-closed ruleset does not drop every positive-policy surface")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPolicyBounds(t *testing.T) {
|
||||
now := time.Date(2026, 7, 12, 0, 0, 0, 0, time.UTC)
|
||||
validated, err := validateBundle(now, validBundle(now))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := validatePolicy(updateConfig{minimumAddresses: 257, maximumAddresses: 257, minimumIntervals: 2, maximumExceptionAddresses: 16, maximumExceptionIntervals: 1}, validated); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for name, configuration := range map[string]updateConfig{
|
||||
"minimum addresses": {minimumAddresses: 258, maximumAddresses: 1 << 32, minimumIntervals: 1, maximumExceptionAddresses: 1 << 32, maximumExceptionIntervals: maxExceptions},
|
||||
"maximum addresses": {minimumAddresses: 1, maximumAddresses: 256, minimumIntervals: 1, maximumExceptionAddresses: 1 << 32, maximumExceptionIntervals: maxExceptions},
|
||||
"minimum intervals": {minimumAddresses: 1, maximumAddresses: 1 << 32, minimumIntervals: 3, maximumExceptionAddresses: 1 << 32, maximumExceptionIntervals: maxExceptions},
|
||||
"maximum exception addresses": {minimumAddresses: 1, maximumAddresses: 1 << 32, minimumIntervals: 1, maximumExceptionAddresses: 15, maximumExceptionIntervals: maxExceptions},
|
||||
"maximum exception intervals": {minimumAddresses: 1, maximumAddresses: 1 << 32, minimumIntervals: 1, maximumExceptionAddresses: 1 << 32, maximumExceptionIntervals: 0},
|
||||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if err := validatePolicy(configuration, validated); err == nil {
|
||||
t.Fatal("expected policy-bound failure")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddStaticExceptions(t *testing.T) {
|
||||
now := time.Date(2026, 7, 12, 0, 0, 0, 0, time.UTC)
|
||||
validated, err := validateBundle(now, validBundle(now))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
validated, err = addStaticExceptions(validated, []string{"203.0.113.16", "198.51.100.50"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var output bytes.Buffer
|
||||
if err := render(&output, validated, "ens3"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, expected := range []string{"198.51.100.50", "203.0.113.0-203.0.113.16"} {
|
||||
if !strings.Contains(output.String(), expected) {
|
||||
t.Errorf("rendered output does not contain %q", expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue