Skip to content
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
bin/
.vscode
cover.out
.codegraph
3 changes: 0 additions & 3 deletions CONTRIBUTING.md

This file was deleted.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ GITVERSION := $(shell git describe --long --all)
BUILDDATE := $(shell date -Iseconds)
VERSION := $(or ${VERSION},$(shell git describe --tags --exact-match 2> /dev/null || git symbolic-ref -q --short HEAD || git rev-parse --short HEAD))

CONTROLLER_TOOLS_VERSION ?= v0.20.0
CONTROLLER_TOOLS_VERSION ?= v0.21.0
LOCALBIN ?= $(shell pwd)/bin
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
ENVTEST ?= $(LOCALBIN)/setup-envtest
Expand Down
17 changes: 12 additions & 5 deletions api/v2/config/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"fmt"
"time"

apiv2client "github.com/metal-stack/api/go/client"

v2 "github.com/metal-stack/firewall-controller-manager/api/v2"
"github.com/metal-stack/firewall-controller-manager/api/v2/helper"
metalgo "github.com/metal-stack/metal-go"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
)
Expand Down Expand Up @@ -47,9 +48,11 @@ type NewControllerConfig struct {
SSHKeySecretName string

// Metal is the metal client for accessing the metal-api.
Metal metalgo.Client
Metal apiv2client.Client
// ClusterTag is the tag used in the metal-api for new firewalls to associate them with the cluster.
ClusterTag string
// Project of this cluster
Project string

// SafetyBackoff is used for guarding the metal-api when it comes to creating new firewalls.
SafetyBackoff time.Duration
Expand Down Expand Up @@ -83,8 +86,9 @@ type ControllerConfig struct {
sshKeySecretNamespace string
sshKeySecretName string

metal metalgo.Client
metal apiv2client.Client
clusterTag string
project string

safetyBackoff time.Duration
progressDeadline time.Duration
Expand Down Expand Up @@ -117,6 +121,7 @@ func New(c *NewControllerConfig) (*ControllerConfig, error) {
shootAccessHelper: helper,
metal: c.Metal,
clusterTag: c.ClusterTag,
project: c.Project,
safetyBackoff: c.SafetyBackoff,
progressDeadline: c.ProgressDeadline,
firewallHealthTimeout: c.FirewallHealthTimeout,
Expand Down Expand Up @@ -248,14 +253,16 @@ func (c *ControllerConfig) GetSSHKeySecretNamespace() string {
return c.sshKeySecretNamespace
}

func (c *ControllerConfig) GetMetal() metalgo.Client {
func (c *ControllerConfig) GetMetal() apiv2client.Client {
return c.metal
}

func (c *ControllerConfig) GetClusterTag() string {
return c.clusterTag
}

func (c *ControllerConfig) GetProject() string {
return c.project
}
func (c *ControllerConfig) GetSafetyBackoff() time.Duration {
return c.safetyBackoff
}
Expand Down
2 changes: 2 additions & 0 deletions api/v2/types_firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ type FirewallNetwork struct {
Prefixes []string `json:"prefixes,omitempty"`
// Vrf is vrf id of this network.
Vrf *int64 `json:"vrf"`
// Project of this network
Project *string `json:"project,omitempty"`
}

// FirewallList contains a list of firewalls
Expand Down
5 changes: 2 additions & 3 deletions api/v2/types_firewall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/metal-stack/metal-lib/pkg/pointer"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"testing/synctest"
Expand Down Expand Up @@ -190,7 +189,7 @@ func Test_EvaluateFirewallStatus(t *testing.T) {
want: &FirewallStatusEvalResult{
Result: FirewallStatusUnhealthy,
Reason: "not all health conditions are true: [SeedConnected]",
TimeoutIn: pointer.Pointer(5 * time.Minute),
TimeoutIn: new(5 * time.Minute),
},
},
{
Expand Down Expand Up @@ -219,7 +218,7 @@ func Test_EvaluateFirewallStatus(t *testing.T) {
want: &FirewallStatusEvalResult{
Result: FirewallStatusProgressing,
Reason: "not all health conditions are true: [Provisioned]",
TimeoutIn: pointer.Pointer(5 * time.Minute),
TimeoutIn: new(5 * time.Minute),
},
},
}
Expand Down
5 changes: 5 additions & 0 deletions api/v2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.0
controller-gen.kubebuilder.io/version: v0.21.0
name: firewalldeployments.firewall.metal-stack.io
spec:
group: firewall.metal-stack.io
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.0
controller-gen.kubebuilder.io/version: v0.21.0
name: firewallmonitors.firewall.metal-stack.io
spec:
group: firewall.metal-stack.io
Expand Down
5 changes: 4 additions & 1 deletion config/crds/firewall.metal-stack.io_firewalls.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.0
controller-gen.kubebuilder.io/version: v0.21.0
name: firewalls.firewall.metal-stack.io
spec:
group: firewall.metal-stack.io
Expand Down Expand Up @@ -325,6 +325,9 @@ spec:
items:
type: string
type: array
project:
description: Project of this network
type: string
vrf:
description: Vrf is vrf id of this network.
format: int64
Expand Down
2 changes: 1 addition & 1 deletion config/crds/firewall.metal-stack.io_firewallsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.0
controller-gen.kubebuilder.io/version: v0.21.0
name: firewallsets.firewall.metal-stack.io
spec:
group: firewall.metal-stack.io
Expand Down
53 changes: 28 additions & 25 deletions controllers/firewall/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package firewall

import (
"context"
"errors"
"fmt"
"net/http"
"time"

"github.com/go-logr/logr"
Expand All @@ -13,50 +11,55 @@ import (
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/predicate"

"github.com/metal-stack/api/go/errorutil"
apiv2 "github.com/metal-stack/api/go/metalstack/api/v2"
v2 "github.com/metal-stack/firewall-controller-manager/api/v2"
"github.com/metal-stack/firewall-controller-manager/api/v2/config"
"github.com/metal-stack/firewall-controller-manager/api/v2/defaults"
"github.com/metal-stack/firewall-controller-manager/api/v2/validation"
"github.com/metal-stack/firewall-controller-manager/controllers"
"github.com/metal-stack/metal-go/api/client/firewall"
"github.com/metal-stack/metal-go/api/client/network"
"github.com/metal-stack/metal-go/api/models"
"github.com/metal-stack/metal-lib/pkg/cache"
)

type controller struct {
c *config.ControllerConfig
log logr.Logger
recorder events.EventRecorder
networkCache *cache.Cache[string, *models.V1NetworkResponse]
firewallCache *cache.Cache[*v2.Firewall, []*models.V1FirewallResponse]
networkCache *cache.Cache[string, *apiv2.Network]
firewallCache *cache.Cache[*v2.Firewall, []*apiv2.Machine]
}

func SetupWithManager(log logr.Logger, recorder events.EventRecorder, mgr ctrl.Manager, c *config.ControllerConfig) error {
g := controllers.NewGenericController(log, c.GetSeedClient(), c.GetSeedNamespace(), &controller{
log: log,
recorder: recorder,
c: c,
networkCache: cache.New(5*time.Minute, func(ctx context.Context, id string) (*models.V1NetworkResponse, error) {
resp, err := c.GetMetal().Network().FindNetwork(network.NewFindNetworkParams().WithID(id).WithContext(ctx), nil)
networkCache: cache.New(5*time.Minute, func(ctx context.Context, id string) (*apiv2.Network, error) {
resp, err := c.GetMetal().Apiv2().Network().Get(ctx, &apiv2.NetworkServiceGetRequest{Project: c.GetProject(), Id: id})
if err != nil {
return nil, fmt.Errorf("network find error: %w", err)
}
return resp.Payload, nil
return resp.Network, nil
}),
// the cache is only very short but on quickly repeated status updates, this should prevent the metal-api from being flooded
firewallCache: cache.New(5*time.Second, func(ctx context.Context, fw *v2.Firewall) ([]*models.V1FirewallResponse, error) {
searchFirewalls := func() ([]*models.V1FirewallResponse, error) {
resp, err := c.GetMetal().Firewall().FindFirewalls(firewall.NewFindFirewallsParams().WithBody(&models.V1FirewallFindRequest{
AllocationName: fw.Name,
AllocationProject: fw.Spec.Project,
Tags: []string{c.GetClusterTag()},
}).WithContext(ctx), nil)
firewallCache: cache.New(5*time.Second, func(ctx context.Context, fw *v2.Firewall) ([]*apiv2.Machine, error) {
searchFirewalls := func() ([]*apiv2.Machine, error) {
resp, err := c.GetMetal().Apiv2().Machine().List(ctx, &apiv2.MachineServiceListRequest{
Project: c.GetProject(),
Query: &apiv2.MachineQuery{
Allocation: &apiv2.MachineAllocationQuery{
Name: &fw.Name,
Labels: &apiv2.Labels{
Labels: controllers.ToLabels([]string{c.GetClusterTag()}),
},
},
},
})
if err != nil {
return nil, fmt.Errorf("firewall search error: %w", err)
}

return resp.Payload, nil
return resp.Machines, nil
}

// First try to find the firewall by machineID but check that allocation, project and hostname still matches
Expand All @@ -66,20 +69,20 @@ func SetupWithManager(log logr.Logger, recorder events.EventRecorder, mgr ctrl.M
// big enough that we agreed to do it. We still need to run the expensive lookup in the metal-api in case deriving
// the machine from the status field does not work.
if fw.Status.MachineStatus != nil && fw.Status.MachineStatus.MachineID != "" {
resp, err := c.GetMetal().Firewall().FindFirewall(firewall.NewFindFirewallParams().WithContext(ctx).WithID(fw.Status.MachineStatus.MachineID), nil)
resp, err := c.GetMetal().Apiv2().Machine().Get(ctx, &apiv2.MachineServiceGetRequest{Project: c.GetProject(), Uuid: fw.Status.MachineStatus.MachineID})
if err != nil {
var defaultErr *firewall.FindFirewallDefault
if errors.As(err, &defaultErr) && defaultErr.Code() == http.StatusNotFound {

if errorutil.IsNotFound(err) {
return searchFirewalls()
}

return nil, fmt.Errorf("firewall find error: %w", err)
}

if resp.Payload.Allocation != nil &&
*resp.Payload.Allocation.Project == fw.Spec.Project &&
*resp.Payload.Allocation.Hostname == fw.Name {
return []*models.V1FirewallResponse{resp.Payload}, nil
if resp.Machine.Allocation != nil &&
resp.Machine.Allocation.Project == fw.Spec.Project &&
resp.Machine.Allocation.Hostname == fw.Name {
return []*apiv2.Machine{resp.Machine}, nil
}
}

Expand Down
15 changes: 7 additions & 8 deletions controllers/firewall/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"fmt"
"time"

apiv2 "github.com/metal-stack/api/go/metalstack/api/v2"
v2 "github.com/metal-stack/firewall-controller-manager/api/v2"
"github.com/metal-stack/firewall-controller-manager/controllers"
"github.com/metal-stack/metal-go/api/client/machine"
apierrors "k8s.io/apimachinery/pkg/api/errors"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -35,20 +35,19 @@ func (c *controller) Delete(r *controllers.Ctx[*v2.Firewall]) error {
}

for _, f := range fws {
if f.ID == nil {
continue
}

resp, err := c.c.GetMetal().Machine().FreeMachine(machine.NewFreeMachineParams().WithID(*f.ID).WithContext(r.Ctx), nil)
resp, err := c.c.GetMetal().Apiv2().Machine().Delete(r.Ctx, &apiv2.MachineServiceDeleteRequest{
Uuid: f.Uuid,
Project: c.c.GetProject(),
})
if err != nil {
r.Log.Error(err, "firewall deletion failed")

return controllers.RequeueAfter(5*time.Second, "firewall deletion failed, retrying")
}

r.Log.Info("deleted firewall", "firewall-name", f.Name, "id", *resp.Payload.ID)
r.Log.Info("deleted firewall", "firewall-name", f.Allocation.Name, "id", resp.Machine.Uuid)

c.recorder.Eventf(r.Target, nil, corev1.EventTypeNormal, "Delete", "deleting firewall", "deleted firewall %s id %s", r.Target.Name, *resp.Payload.ID)
c.recorder.Eventf(r.Target, nil, corev1.EventTypeNormal, "Delete", "deleting firewall", "deleted firewall %s id %s", r.Target.Name, resp.Machine.Uuid)
}

return nil
Expand Down
Loading
Loading