Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement webhook server. #166

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
FROM scratch
COPY bin/firewall-controller /firewall-controller
FROM alpine:3.18
COPY bin/firewall-controller-webhook .
USER 65534
ENTRYPOINT ["/firewall-controller-webhook"]
18 changes: 16 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LOCALBIN ?= $(shell pwd)/bin
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
ENVTEST ?= $(LOCALBIN)/setup-envtest

all: firewall-controller
all: firewall-controller firewall-controller-webhook

# Build firewall-controller binary
firewall-controller: generate fmt vet
Expand All @@ -24,6 +24,19 @@ firewall-controller: generate fmt vet
strip bin/firewall-controller
sha256sum bin/firewall-controller > bin/firewall-controller.sha256

firewall-controller-webhook: generate fmt vet
CGO_ENABLED=0 go build \
-tags netgo \
-trimpath \
-ldflags \
"-X 'github.com/metal-stack/v.Version=$(VERSION)' \
-X 'github.com/metal-stack/v.Revision=$(GITVERSION)' \
-X 'github.com/metal-stack/v.GitSHA1=$(SHA)' \
-X 'github.com/metal-stack/v.BuildDate=$(BUILDDATE)'" \
-o bin/firewall-controller-webhook cmd/webhook/cmd.go
strip bin/firewall-controller-webhook
sha256sum bin/firewall-controller-webhook > bin/firewall-controller-webhook.sha256

$(LOCALBIN):
mkdir -p $(LOCALBIN)

Expand Down Expand Up @@ -52,7 +65,8 @@ deploy: manifests

# Generate manifests e.g. CRD, RBAC etc.
manifests: controller-gen
$(CONTROLLER_GEN) crd rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
$(CONTROLLER_GEN) crd rbac:roleName=manager-role paths="./..." output:crd:artifacts:config=config/crd/bases
$(CONTROLLER_GEN) +webhook paths="./..." +output:dir=config/webhooks

# Run go fmt against code
fmt:
Expand Down
74 changes: 0 additions & 74 deletions api/v1/clusterwidenetworkpolicy_types.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package v1

import (
"errors"
"fmt"
"net"
"strings"

dnsgo "github.com/miekg/dns"
corev1 "k8s.io/api/core/v1"
networking "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

type IPVersion string
Expand Down Expand Up @@ -186,72 +181,3 @@ func (s FQDNSelector) GetRegex() string {
// Anchor the match to require the whole string to match this expression
return "^" + pattern + "$"
}

// Validate validates the spec of a ClusterwideNetworkPolicy
func (p *PolicySpec) Validate() error {
var errs []error
for _, e := range p.Egress {
errs = append(errs, validatePorts(e.Ports), validateIPBlocks(e.To))
}
for _, i := range p.Ingress {
errs = append(errs, validatePorts(i.Ports), validateIPBlocks(i.From))
}

return errors.Join(errs...)
}

func validatePorts(ports []networking.NetworkPolicyPort) error {
var errs []error
for _, p := range ports {
if p.Port != nil && p.Port.Type != intstr.Int {
errs = append(errs, fmt.Errorf("only int ports are supported, but %v given", p.Port))
}

if p.Port != nil && (p.Port.IntValue() > 65535 || p.Port.IntValue() <= 0) {
errs = append(errs, fmt.Errorf("only ports between 0 and 65535 are allowed, but %v given", p.Port))
}

if p.Protocol != nil {
proto := *p.Protocol
if proto != corev1.ProtocolUDP && proto != corev1.ProtocolTCP {
errs = append(errs, fmt.Errorf("only TCP and UDP are supported as protocol, but %v given", proto))
}
}
}
return errors.Join(errs...)
}

func validateIPBlocks(blocks []networking.IPBlock) error {
var errs []error
for _, b := range blocks {
_, blockNet, err := net.ParseCIDR(b.CIDR)
if err != nil {
errs = append(errs, fmt.Errorf("%v is not a valid IP CIDR", b.CIDR))
continue
}

for _, e := range b.Except {
exceptIP, exceptNet, err := net.ParseCIDR(b.CIDR)
if err != nil {
errs = append(errs, fmt.Errorf("%v is not a valid IP CIDR", e))
continue
}

if !blockNet.Contains(exceptIP) {
errs = append(errs, fmt.Errorf("%v is not contained in the IP CIDR %v", exceptIP, blockNet))
continue
}

blockSize, _ := blockNet.Mask.Size()
exceptSize, _ := exceptNet.Mask.Size()
if exceptSize > blockSize {
errs = append(errs, fmt.Errorf("netmask size of network to be excluded must be smaller than netmask of the block CIDR"))
}
}
}
return errors.Join(errs...)
}

func init() {
SchemeBuilder.Register(&ClusterwideNetworkPolicy{}, &ClusterwideNetworkPolicyList{})
}
156 changes: 0 additions & 156 deletions api/v1/clusterwidenetworkpolicy_types_test.go

This file was deleted.

34 changes: 34 additions & 0 deletions api/v1/defaults/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package defaults

import (
"context"
"fmt"

"github.com/go-logr/logr"
v1 "github.com/metal-stack/firewall-controller/api/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

type defaulter struct {
log logr.Logger
}

func NewDefaulter(log logr.Logger) admission.CustomDefaulter {
return &defaulter{
log: log,
}
}

func (d *defaulter) Default(ctx context.Context, obj runtime.Object) error {
f, ok := obj.(*v1.ClusterwideNetworkPolicy)
if !ok {
return fmt.Errorf("mutator received unexpected type: %T", obj)
}

d.log.Info("defaulting resource", "name", f.GetName(), "namespace", f.GetNamespace())

// TODO: Implement

return nil
}
4 changes: 4 additions & 0 deletions api/v1/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Package v1 contains API Schema definitions for the firewall v1 API group
// +kubebuilder:object:generate=true
// +groupName=metal-stack.io
//
// +kubebuilder:webhook:path=/validate-metal-stack-io-v1-clusterwide-network-policy,mutating=false,failurePolicy=fail,groups=metal-stack.io,resources=clusterwidenetworkpolicy,verbs=create;update,versions=v1,name=metal-stack.io,sideEffects=None,admissionReviewVersions=v1
//
// +kubebuilder:webhook:path=/mutate-metal-stack-io-v1-clusterwide-network-policy,mutating=true,failurePolicy=fail,groups=metal-stack.io,resources=clusterwidenetworkpolicy,verbs=create,versions=v1,name=metal-stack.io,sideEffects=None,admissionReviewVersions=v1
package v1

import (
Expand Down
Loading