diff --git a/pkg/apis/metal/types_infrastructure.go b/pkg/apis/metal/types_infrastructure.go index 3f86a341c..2c3f75b9a 100644 --- a/pkg/apis/metal/types_infrastructure.go +++ b/pkg/apis/metal/types_infrastructure.go @@ -43,5 +43,6 @@ type InfrastructureStatus struct { } type FirewallStatus struct { - MachineID string + MachineID string + ExternalEgressIPs []string } diff --git a/pkg/apis/metal/v1alpha1/types_infrastructure.go b/pkg/apis/metal/v1alpha1/types_infrastructure.go index a42ba22dc..f2a0ed7ca 100644 --- a/pkg/apis/metal/v1alpha1/types_infrastructure.go +++ b/pkg/apis/metal/v1alpha1/types_infrastructure.go @@ -43,5 +43,6 @@ type InfrastructureStatus struct { } type FirewallStatus struct { - MachineID string `json:"machineID"` + MachineID string `json:"machineID"` + ExternalEgressIPs []string `json:"externalEgressIPs"` } diff --git a/pkg/apis/metal/v1alpha1/zz_generated.conversion.go b/pkg/apis/metal/v1alpha1/zz_generated.conversion.go index 47193daff..d6bb94e1d 100644 --- a/pkg/apis/metal/v1alpha1/zz_generated.conversion.go +++ b/pkg/apis/metal/v1alpha1/zz_generated.conversion.go @@ -395,6 +395,7 @@ func Convert_metal_FirewallControllerVersion_To_v1alpha1_FirewallControllerVersi func autoConvert_v1alpha1_FirewallStatus_To_metal_FirewallStatus(in *FirewallStatus, out *metal.FirewallStatus, s conversion.Scope) error { out.MachineID = in.MachineID + out.ExternalEgressIPs = *(*[]string)(unsafe.Pointer(&in.ExternalEgressIPs)) return nil } @@ -405,6 +406,7 @@ func Convert_v1alpha1_FirewallStatus_To_metal_FirewallStatus(in *FirewallStatus, func autoConvert_metal_FirewallStatus_To_v1alpha1_FirewallStatus(in *metal.FirewallStatus, out *FirewallStatus, s conversion.Scope) error { out.MachineID = in.MachineID + out.ExternalEgressIPs = *(*[]string)(unsafe.Pointer(&in.ExternalEgressIPs)) return nil } diff --git a/pkg/apis/metal/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/metal/v1alpha1/zz_generated.deepcopy.go index 98d9a1194..9e8e27dbf 100644 --- a/pkg/apis/metal/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/metal/v1alpha1/zz_generated.deepcopy.go @@ -244,6 +244,11 @@ func (in *FirewallControllerVersion) DeepCopy() *FirewallControllerVersion { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FirewallStatus) DeepCopyInto(out *FirewallStatus) { *out = *in + if in.ExternalEgressIPs != nil { + in, out := &in.ExternalEgressIPs, &out.ExternalEgressIPs + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -287,7 +292,7 @@ func (in *InfrastructureConfig) DeepCopyObject() runtime.Object { func (in *InfrastructureStatus) DeepCopyInto(out *InfrastructureStatus) { *out = *in out.TypeMeta = in.TypeMeta - out.Firewall = in.Firewall + in.Firewall.DeepCopyInto(&out.Firewall) return } diff --git a/pkg/apis/metal/zz_generated.deepcopy.go b/pkg/apis/metal/zz_generated.deepcopy.go index e6ce0ce2e..cec52a765 100644 --- a/pkg/apis/metal/zz_generated.deepcopy.go +++ b/pkg/apis/metal/zz_generated.deepcopy.go @@ -244,6 +244,11 @@ func (in *FirewallControllerVersion) DeepCopy() *FirewallControllerVersion { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FirewallStatus) DeepCopyInto(out *FirewallStatus) { *out = *in + if in.ExternalEgressIPs != nil { + in, out := &in.ExternalEgressIPs, &out.ExternalEgressIPs + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -287,7 +292,7 @@ func (in *InfrastructureConfig) DeepCopyObject() runtime.Object { func (in *InfrastructureStatus) DeepCopyInto(out *InfrastructureStatus) { *out = *in out.TypeMeta = in.TypeMeta - out.Firewall = in.Firewall + in.Firewall.DeepCopyInto(&out.Firewall) return } diff --git a/pkg/controller/infrastructure/actuator.go b/pkg/controller/infrastructure/actuator.go index eb073909a..39ded778a 100644 --- a/pkg/controller/infrastructure/actuator.go +++ b/pkg/controller/infrastructure/actuator.go @@ -80,7 +80,7 @@ func decodeInfrastructure(infrastructure *extensionsv1alpha1.Infrastructure, dec return infrastructureConfig, infrastructureStatus, nil } -func updateProviderStatus(ctx context.Context, c client.Client, infrastructure *extensionsv1alpha1.Infrastructure, providerStatus *metalapi.InfrastructureStatus, nodeCIDR *string) error { +func updateProviderStatus(ctx context.Context, c client.Client, infrastructure *extensionsv1alpha1.Infrastructure, providerStatus *metalapi.InfrastructureStatus, nodeCIDR *string, externalEgressIPs *[]string) error { patch := client.MergeFrom(infrastructure.DeepCopy()) infrastructure.Status.ProviderStatus = &runtime.RawExtension{Object: &metalv1alpha1.InfrastructureStatus{ TypeMeta: metav1.TypeMeta{ @@ -88,7 +88,8 @@ func updateProviderStatus(ctx context.Context, c client.Client, infrastructure * Kind: "InfrastructureStatus", }, Firewall: metalv1alpha1.FirewallStatus{ - MachineID: providerStatus.Firewall.MachineID, + MachineID: providerStatus.Firewall.MachineID, + ExternalEgressIPs: *externalEgressIPs, }, }} infrastructure.Status.NodesCIDR = nodeCIDR diff --git a/pkg/controller/infrastructure/actuator_reconcile.go b/pkg/controller/infrastructure/actuator_reconcile.go index bf8b5cbac..5e9ccec76 100644 --- a/pkg/controller/infrastructure/actuator_reconcile.go +++ b/pkg/controller/infrastructure/actuator_reconcile.go @@ -6,15 +6,16 @@ import ( "time" "github.com/go-logr/logr" + mn "github.com/metal-stack/metal-lib/pkg/net" "github.com/metal-stack/metal-lib/pkg/tag" "k8s.io/apimachinery/pkg/util/sets" + "sigs.k8s.io/controller-runtime/pkg/client" metalclient "github.com/metal-stack/gardener-extension-provider-metal/pkg/metal/client" metalapi "github.com/metal-stack/gardener-extension-provider-metal/pkg/apis/metal" "github.com/metal-stack/gardener-extension-provider-metal/pkg/apis/metal/helper" metalgo "github.com/metal-stack/metal-go" - "github.com/metal-stack/metal-go/api/client/ip" metalip "github.com/metal-stack/metal-go/api/client/ip" "github.com/metal-stack/metal-go/api/client/network" "github.com/metal-stack/metal-go/api/models" @@ -23,6 +24,7 @@ import ( "github.com/gardener/gardener/pkg/controllerutils/reconciler" extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" + fcmv2 "github.com/metal-stack/firewall-controller-manager/api/v2" ) type networkReconciler struct { @@ -79,7 +81,16 @@ func (a *actuator) Reconcile(ctx context.Context, logger logr.Logger, infrastruc } } - err = updateProviderStatus(ctx, a.client, infrastructure, internalInfrastructureStatus, &nodeCIDR) + // get all egress ips from the firewall CRs and the infrastructure config and save them in the infrastructure status + externalEgressIPs, err := getFirewallEgressIPs(ctx, networkReconciler, a.client, cluster.Shoot.Status.TechnicalID, logger) + if err != nil { + return &reconciler.RequeueAfterError{ + Cause: err, + RequeueAfter: 30 * time.Second, + } + } + + err = updateProviderStatus(ctx, a.client, infrastructure, internalInfrastructureStatus, &nodeCIDR, &externalEgressIPs) if err != nil { return err } @@ -105,7 +116,7 @@ func (a *actuator) Reconcile(ctx context.Context, logger logr.Logger, infrastruc func reconcileEgressIPs(ctx context.Context, r *egressIPReconciler) error { currentEgressIPs := sets.NewString() - resp, err := r.mclient.IP().FindIPs(ip.NewFindIPsParams().WithBody(&models.V1IPFindRequest{ + resp, err := r.mclient.IP().FindIPs(metalip.NewFindIPsParams().WithBody(&models.V1IPFindRequest{ Projectid: r.infrastructureConfig.ProjectID, Tags: []string{r.egressTag}, Type: models.V1IPBaseTypeStatic, @@ -227,3 +238,30 @@ func ensureNodeNetwork(ctx context.Context, r *networkReconciler) (string, error return nodeCIDR, nil } + +// getFirewallEgressIPs returns all egress ips from the firewall CRs and the infrastructure config +func getFirewallEgressIPs(ctx context.Context, r *networkReconciler, c client.Client, namespace string, logger logr.Logger) ([]string, error) { + firewalls := &fcmv2.FirewallList{} + egressIPs := sets.NewString() + + err := c.List(ctx, firewalls, client.InNamespace(namespace)) + if err != nil { + return nil, fmt.Errorf("unable to list firewalls: %w", err) + } + + for _, fw := range firewalls.Items { + fw := fw + + for _, n := range fw.Status.FirewallNetworks { + if n.NetworkType != nil && *n.NetworkType == mn.External { + egressIPs.Insert(n.IPs...) + } + } + } + + for _, egressRule := range r.infrastructureConfig.Firewall.EgressRules { + egressIPs.Insert(egressRule.IPs...) + } + + return egressIPs.List(), nil +}