diff --git a/charts/internal/crds-firewall/templates/firewall-controller/metal-stack.io_firewalls.yaml b/charts/internal/crds-firewall/templates/firewall-controller/metal-stack.io_firewalls.yaml deleted file mode 100644 index 225692de6..000000000 --- a/charts/internal/crds-firewall/templates/firewall-controller/metal-stack.io_firewalls.yaml +++ /dev/null @@ -1,257 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null - name: firewalls.metal-stack.io -spec: - group: metal-stack.io - names: - kind: Firewall - listKind: FirewallList - plural: firewalls - shortNames: - - fw - singular: firewall - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.interval - name: Interval - type: string - - jsonPath: .spec.internalprefixes - name: InternalPrefixes - type: string - name: v1 - schema: - openAPIV3Schema: - description: Firewall is the Schema for the firewalls API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: FirewallSpec defines the desired state of Firewall - properties: - controllerURL: - description: ControllerURL points to the downloadable binary artifact - of the firewall controller - type: string - controllerVersion: - description: ControllerVersion holds the firewall-controller version - to reconcile. - type: string - dnsPort: - description: DNSPort specifies port to which DNS proxy should be bound - type: integer - dnsServerAddress: - description: DNSServerAddress specifies DNS server address used by - DNS proxy - type: string - dryrun: - description: DryRun if set to true, firewall rules are not applied - type: boolean - egressRules: - description: EgressRules - items: - description: EgressRuleSNAT holds a Source-NAT rule - properties: - ips: - items: - type: string - type: array - networkid: - type: string - required: - - ips - - networkid - type: object - type: array - firewallNetworks: - description: FirewallNetworks holds the networks known at the metal-api - for this firewall machine - items: - properties: - asn: - format: int64 - type: integer - destinationprefixes: - items: - type: string - type: array - ips: - items: - type: string - type: array - nat: - type: boolean - networkid: - type: string - networktype: - type: string - prefixes: - items: - type: string - type: array - vrf: - format: int64 - type: integer - required: - - asn - - destinationprefixes - - ips - - nat - - networkid - - networktype - - prefixes - - vrf - type: object - type: array - internalprefixes: - description: 'InternalPrefixes specify prefixes which are considered - local to the partition or all regions. Traffic to/from these prefixes - is accounted as internal traffic TODO: align to camel-case - rename - to internalPrefixes' - items: - type: string - type: array - interval: - description: Interval on which rule reconciliation should happen - type: string - ipv4rulefile: - description: TrafficControl defines where to store the generated ipv4 - firewall rules on disk - type: string - logAcceptedConnections: - description: LogAcceptedConnections if set to true, also log accepted - connections in the droptailer log - type: boolean - rateLimits: - description: RateLimits allows configuration of rate limit rules for - interfaces. - items: - description: RateLimit contains the rate limit rule for a network. - properties: - networkid: - description: NetworkID specifies the network which should be - rate limited - type: string - rate: - description: Rate is the input rate in MiB/s - format: int32 - type: integer - required: - - networkid - - rate - type: object - type: array - signature: - description: Signature of firewall attributes generated by GEPM. - type: string - required: - - signature - type: object - status: - description: FirewallStatus defines the observed state of Firewall - properties: - controllerVersion: - type: string - lastRun: - format: date-time - type: string - message: - type: string - stats: - description: FirewallStats contains firewall statistics - properties: - devices: - additionalProperties: - description: DeviceStat contains statistics of a device - properties: - in: - format: int64 - type: integer - out: - format: int64 - type: integer - total: - description: 'Deprecated: TotalBytes is kept for backwards - compatibility' - format: int64 - type: integer - required: - - in - - out - - total - type: object - description: DeviceStatsByDevice contains DeviceStatistics grouped - by device name - type: object - idsstats: - additionalProperties: - properties: - drop: - type: integer - invalidchecksums: - type: integer - packets: - type: integer - required: - - drop - - invalidchecksums - - packets - type: object - type: object - rules: - additionalProperties: - additionalProperties: - description: RuleStat contains the statistics for a single - nftables rule - properties: - counter: - description: Counter holds values of a nftables counter - object - properties: - bytes: - format: int64 - type: integer - packets: - format: int64 - type: integer - required: - - bytes - - packets - type: object - required: - - counter - type: object - description: RuleStats contains firewall rule statistics of - all rules of an action - type: object - description: 'RuleStatsByAction contains firewall rule statistics - groups by action: e.g. accept, drop, policy, masquerade' - type: object - required: - - devices - - idsstats - - rules - type: object - required: - - stats - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/charts/internal/shoot-control-plane/templates/firewall/firewall.yaml b/charts/internal/shoot-control-plane/templates/firewall/firewall.yaml index 80cbd92d1..e05fbfe33 100644 --- a/charts/internal/shoot-control-plane/templates/firewall/firewall.yaml +++ b/charts/internal/shoot-control-plane/templates/firewall/firewall.yaml @@ -1,15 +1,4 @@ ---- apiVersion: v1 kind: Namespace metadata: - name: firewall ---- -apiVersion: metal-stack.io/v1 -kind: Firewall -metadata: - namespace: firewall - name: firewall -spec: -{{ toYaml .Values.firewallSpec | indent 2 }} -status: - stats: {} + name: firewall \ No newline at end of file diff --git a/charts/internal/shoot-control-plane/templates/firewall/rbac-firewall-controller.yaml b/charts/internal/shoot-control-plane/templates/firewall/rbac-firewall-controller.yaml deleted file mode 100644 index 3b985e368..000000000 --- a/charts/internal/shoot-control-plane/templates/firewall/rbac-firewall-controller.yaml +++ /dev/null @@ -1,89 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: system:firewall-controller -rules: -- apiGroups: - - "" - resources: - - pods - - secrets - - services - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - events - verbs: ["*"] -- apiGroups: - - apiextensions.k8s.io - - "" - resources: - - customresourcedefinitions - - services - - endpoints - verbs: - - get - - create - - update - - list - - watch -- apiGroups: - - networking.k8s.io - resources: - - networkpolicies - verbs: - - get - - list - - watch -- apiGroups: - - metal-stack.io - resources: - - firewalls - - firewalls/status - - clusterwidenetworkpolicies - - clusterwidenetworkpolicies/status - verbs: - - list - - get - - update - - patch - - create - - delete - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: system:firewall-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: system:firewall-controller -subjects: -- kind: User - name: system:firewall-controller - apiGroup: "" - ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: firewall-controller-view - labels: - # With this label, all view roles will automatically get view access to this resources. - rbac.authorization.k8s.io/aggregate-to-view: "true" -rules: -- apiGroups: - - "metal-stack.io" - resources: - - clusterwidenetworkpolicies - - firewalls - verbs: - - get - - list - - watch diff --git a/charts/internal/shoot-control-plane/values.yaml b/charts/internal/shoot-control-plane/values.yaml index c9b2f7ffa..70925ee63 100644 --- a/charts/internal/shoot-control-plane/values.yaml +++ b/charts/internal/shoot-control-plane/values.yaml @@ -15,15 +15,6 @@ images: imagePullPolicy: IfNotPresent -firewallSpec: - interval: 10s - dryrun: false - logAcceptedConnections: false - rateLimits: [] - internalprefixes: [] - egressRules: [] - firewallNetworks: [] - duros: enabled: false endpoints: [] diff --git a/go.mod b/go.mod index 49e9a4d67..88c03c0c4 100644 --- a/go.mod +++ b/go.mod @@ -17,8 +17,8 @@ require ( github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.5.9 github.com/metal-stack/duros-controller v0.6.2 - github.com/metal-stack/firewall-controller v1.3.0 github.com/metal-stack/firewall-controller-manager v0.2.3 + github.com/metal-stack/firewall-controller/v2 v2.1.0 github.com/metal-stack/machine-controller-manager-provider-metal v0.1.14 github.com/metal-stack/metal-go v0.24.1 github.com/metal-stack/metal-lib v0.13.3 @@ -50,7 +50,7 @@ require ( github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/emicklei/go-restful/v3 v3.10.2 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fatih/color v1.15.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect @@ -136,7 +136,7 @@ require ( golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect diff --git a/go.sum b/go.sum index c11106699..99f8d0166 100644 --- a/go.sum +++ b/go.sum @@ -433,10 +433,10 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/metal-stack/duros-controller v0.6.2 h1:P/KpOvNlSsqXf0Qucbar/wFR7wMmqZTwoaN3F8YhD7M= github.com/metal-stack/duros-controller v0.6.2/go.mod h1:4sN2SQfzMp1x3ylL+ATxb8nmrxMh2JZThDZYPy4k5WU= -github.com/metal-stack/firewall-controller v1.3.0 h1:K6QSP74BrKW0tmTCwT0xS5oByE2CqtyL6roTsvSbuDg= -github.com/metal-stack/firewall-controller v1.3.0/go.mod h1:Ltmu4CWekOqd1m4GD/XlYtPl9p0q7U/an1WGqR1w+vc= github.com/metal-stack/firewall-controller-manager v0.2.3 h1:FZSg+y/RyHYQ053GpHTpIP/E+8z7JtJ5Wb5049Op3iA= github.com/metal-stack/firewall-controller-manager v0.2.3/go.mod h1:ppoOJE3sLiwROVhB4Yui5tuWylctT+lEa0S70PGCb0k= +github.com/metal-stack/firewall-controller/v2 v2.1.0 h1:ekVEnUBRDl3YYHV4a13mktjSy47WQvkKsPccz5iIB28= +github.com/metal-stack/firewall-controller/v2 v2.1.0/go.mod h1:IQASxGZld7wxaW1TaFiQQCrjt/vOFK/uIV2ALQjlxyg= github.com/metal-stack/machine-controller-manager-provider-metal v0.1.14 h1:qbbdnGXSDP5Fagliheh73rGm+NaYCEBd/oRsydrqHbI= github.com/metal-stack/machine-controller-manager-provider-metal v0.1.14/go.mod h1:d36VmegtqJd7AKv8FVFvuimRPK+M93odICUUbTXg8CU= github.com/metal-stack/metal-go v0.24.1 h1:S4g3LXeWBELCKIyyCsRMa9B1pC5EClqcX35oV/8xv2U= @@ -936,8 +936,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc= -gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= diff --git a/pkg/apis/metal/install/install.go b/pkg/apis/metal/install/install.go index 55e1908b6..c2ff4e467 100644 --- a/pkg/apis/metal/install/install.go +++ b/pkg/apis/metal/install/install.go @@ -3,7 +3,7 @@ package install import ( durosv1 "github.com/metal-stack/duros-controller/api/v1" fcmv2 "github.com/metal-stack/firewall-controller-manager/api/v2" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" "github.com/metal-stack/gardener-extension-provider-metal/pkg/apis/metal" "github.com/metal-stack/gardener-extension-provider-metal/pkg/apis/metal/v1alpha1" diff --git a/pkg/controller/controlplane/valuesprovider.go b/pkg/controller/controlplane/valuesprovider.go index d44c76071..eb4748b00 100644 --- a/pkg/controller/controlplane/valuesprovider.go +++ b/pkg/controller/controlplane/valuesprovider.go @@ -8,7 +8,6 @@ import ( "net/url" "os" "path/filepath" - "slices" "strings" "time" @@ -19,7 +18,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" durosv1 "github.com/metal-stack/duros-controller/api/v1" - firewallv1 "github.com/metal-stack/firewall-controller/api/v1" + firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" extensionsconfig "github.com/gardener/gardener/extensions/pkg/apis/config" extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller" @@ -27,7 +26,6 @@ import ( gardencorev1beta1helper "github.com/gardener/gardener/pkg/apis/core/v1beta1/helper" "github.com/gardener/gardener/extensions/pkg/controller/controlplane/genericactuator" - "github.com/gardener/gardener/pkg/utils" "github.com/metal-stack/gardener-extension-provider-metal/pkg/apis/config" apismetal "github.com/metal-stack/gardener-extension-provider-metal/pkg/apis/metal" @@ -248,7 +246,6 @@ var cpShootChart = &chart.Chart{ // firewall controller {Type: &rbacv1.ClusterRole{}, Name: "system:firewall-controller"}, {Type: &rbacv1.ClusterRoleBinding{}, Name: "system:firewall-controller"}, - {Type: &firewallv1.Firewall{}, Name: "firewall"}, // firewall controller manager {Type: &corev1.ServiceAccount{}, Name: "firewall-controller-manager"}, @@ -660,16 +657,6 @@ func (vp *valuesProvider) getControlPlaneShootChartValues(ctx context.Context, m return nil, err } - fwSpec, err := vp.getFirewallSpec(ctx, metalControlPlane, infrastructureConfig, cluster, nws, mclient) - if err != nil { - return nil, fmt.Errorf("could not assemble firewall values %w", err) - } - - err = vp.signFirewallValues(ctx, namespace, fwSpec) - if err != nil { - return nil, fmt.Errorf("could not sign firewall values %w", err) - } - durosValues := map[string]interface{}{ "enabled": vp.controllerConfig.Storage.Duros.Enabled, } @@ -734,7 +721,6 @@ func (vp *valuesProvider) getControlPlaneShootChartValues(ctx context.Context, m "pspDisabled": gardencorev1beta1helper.IsPSPDisabled(cluster.Shoot), "apiserverIPs": apiserverIPs, "nodeCIDR": nodeCIDR, - "firewallSpec": fwSpec, "duros": durosValues, "clusterAudit": clusterAuditValues, "nodeInit": nodeInitValues, @@ -805,132 +791,6 @@ func (vp *valuesProvider) getControlPlaneShootChartValues(ctx context.Context, m return values, nil } -// getFirewallSpec returns the firewall v1 specification to be deployed to the shoot cluster. -// this is kept for backwards-compatibility to support firewall-controller v1.x, can be removed as soon as all firewall-controllers are migrated to v2.x -func (vp *valuesProvider) getFirewallSpec(ctx context.Context, metalControlPlane *apismetal.MetalControlPlane, infrastructureConfig *apismetal.InfrastructureConfig, cluster *extensionscontroller.Cluster, nws networkMap, mclient metalgo.Client) (*firewallv1.FirewallSpec, error) { - rateLimits := []firewallv1.RateLimit{} - for _, rateLimit := range infrastructureConfig.Firewall.RateLimits { - rateLimits = append(rateLimits, firewallv1.RateLimit{ - NetworkID: rateLimit.NetworkID, - Rate: rateLimit.RateLimit, - }) - } - - egressRules := []firewallv1.EgressRuleSNAT{} - for _, egressRule := range infrastructureConfig.Firewall.EgressRules { - egressRules = append(egressRules, firewallv1.EgressRuleSNAT{ - NetworkID: egressRule.NetworkID, - IPs: egressRule.IPs, - }) - } - - spec := firewallv1.FirewallSpec{ - Data: firewallv1.Data{ - Interval: "10s", - InternalPrefixes: vp.controllerConfig.FirewallInternalPrefixes, - RateLimits: rateLimits, - EgressRules: egressRules, - }, - LogAcceptedConnections: infrastructureConfig.Firewall.LogAcceptedConnections, - } - - fwcv, err := validation.ValidateFirewallControllerVersion(metalControlPlane.FirewallControllerVersions, infrastructureConfig.Firewall.ControllerVersion) - if err != nil { - return nil, err - } - - spec.ControllerVersion = fwcv.Version - spec.ControllerURL = fwcv.URL - - var ( - clusterID = string(cluster.Shoot.GetUID()) - projectID = infrastructureConfig.ProjectID - ) - - firewalls, err := metalclient.FindClusterFirewalls(ctx, mclient, clusterTag(clusterID), projectID) - if err != nil { - return nil, fmt.Errorf("could not find firewall for cluster %w", err) - } - - if len(firewalls) == 0 { - // cluster has no firewall yet, firewall-controller-manager will create a new one - return &spec, nil - } - if len(firewalls) > 1 { - // firewall-controller-manager supports rolling updates such that there can be more than 1 firewall - // during the update process. - // - // we have to use the networks of the latest firewall to write the firewall v1 spec as otherwise - // the firewall-controller that reads the firewall v1 spec will remove it's ip addresses from the - // network interfaces. - // - // older firewalls that still run firewall-controller 1.x will break. therefore, before doing a rolling upgrade - // we should update the firewall-controller to > 2.x. - vp.logger.Info("firewall currently has more than one firewall, rolling update in progress?", "amount", len(firewalls)) - } - - slices.SortFunc(firewalls, firewallCompareFunc) - - latestFirewall := firewalls[0] - - firewallNetworks := []firewallv1.FirewallNetwork{} - for _, n := range latestFirewall.Allocation.Networks { - if n.Networkid == nil { - continue - } - n := n - - // prefixes in the firewall machine allocation are just a snapshot when the firewall was created. - // -> when changing prefixes in the referenced network the firewall does not know about any prefix changes. - // - // we replace the prefixes from the snapshot with the actual prefixes that are currently attached to the network. - // this allows dynamic prefix reconfiguration of the firewall. - prefixes := n.Prefixes - networkRef, ok := nws[*n.Networkid] - if !ok { - vp.logger.Info("network in firewall allocation does not exist anymore") - } else { - prefixes = networkRef.Prefixes - } - - firewallNetworks = append(firewallNetworks, firewallv1.FirewallNetwork{ - Asn: n.Asn, - Destinationprefixes: n.Destinationprefixes, - Ips: n.Ips, - Nat: n.Nat, - Networkid: n.Networkid, - Networktype: n.Networktype, - Prefixes: prefixes, - Vrf: n.Vrf, - }) - } - - spec.FirewallNetworks = firewallNetworks - - return &spec, nil -} - -func (vp *valuesProvider) signFirewallValues(ctx context.Context, namespace string, spec *firewallv1.FirewallSpec) error { - secret, err := vp.getSecret(ctx, namespace, v1beta1constants.SecretNameCACluster) - if err != nil { - return fmt.Errorf("could not find ca secret for signing firewall values %w", err) - } - - privateKey, err := utils.DecodePrivateKey(secret.Data[secrets.DataKeyPrivateKeyCA]) - if err != nil { - return fmt.Errorf("could not decode private key from ca secret for signing firewall values %w", err) - } - - vp.logger.Info("signing firewall", "data", spec.Data) - signature, err := spec.Data.Sign(privateKey) - if err != nil { - return fmt.Errorf("could not sign firewall values %w", err) - } - - spec.Signature = signature - return nil -} - // getSecret returns the secret with the given namespace/secretName func (vp *valuesProvider) getSecret(ctx context.Context, namespace string, secretName string) (*corev1.Secret, error) { key := kutil.Key(namespace, secretName)