From 9225598fd00e23eb622d8bfed4126fe24fb557de Mon Sep 17 00:00:00 2001 From: Jan Jansen Date: Tue, 21 Nov 2023 16:12:02 +0100 Subject: [PATCH] speedup failoverGroups Signed-off-by: Jan Jansen --- .../ionoscloudmachine_controller.go | 38 +++-------- internal/ionos/apiclient.go | 66 +++++++++++-------- testing/fakeClient.go | 4 +- 3 files changed, 52 insertions(+), 56 deletions(-) diff --git a/internal/controller/ionoscloudmachine_controller.go b/internal/controller/ionoscloudmachine_controller.go index 2ed09c1..cefa68d 100644 --- a/internal/controller/ionoscloudmachine_controller.go +++ b/internal/controller/ionoscloudmachine_controller.go @@ -439,34 +439,16 @@ func (r *IONOSCloudMachineReconciler) reconcileFailoverGroups(ctx *context.Machi if err != nil { return err } - for _, ip := range *block.Properties.Ips { - err = ctx.IONOSClient.EnsureAdditionalIPOnNic(ctx, ctx.IONOSCloudCluster.Spec.DataCenterID, ctx.IONOSCloudMachine.Spec.ProviderID, *serverNic.Id, ip) - if err != nil { - return err - } - lanId := fmt.Sprint(*lanSpec.LanID) - lan, _, err := ctx.IONOSClient.GetLan(ctx, ctx.IONOSCloudCluster.Spec.DataCenterID, lanId) - if err != nil { - return err - } - registered := false - if lan.Properties.IpFailover != nil { - for _, f := range *lan.Properties.IpFailover { - if *f.Ip == ip { - registered = true - continue - } - } - if registered { - continue - } - } - - //todo only once per cluster and change if machine gets delete - err = ctx.IONOSClient.EnsureFailoverIPOnLan(ctx, ctx.IONOSCloudCluster.Spec.DataCenterID, lanId, ip, *serverNic.Id) - if err != nil { - return err - } + ips := *block.Properties.Ips + err = ctx.IONOSClient.EnsureAdditionalIPsOnNic(ctx, ctx.IONOSCloudCluster.Spec.DataCenterID, ctx.IONOSCloudMachine.Spec.ProviderID, *serverNic.Id, ips) + if err != nil { + return err + } + //todo only once per cluster and change if machine gets delete + lanId := fmt.Sprint(*lanSpec.LanID) + err = ctx.IONOSClient.EnsureFailoverIPsOnLan(ctx, ctx.IONOSCloudCluster.Spec.DataCenterID, lanId, *serverNic.Id, ips) + if err != nil { + return err } } } diff --git a/internal/ionos/apiclient.go b/internal/ionos/apiclient.go index 99f1a2d..5facbcd 100644 --- a/internal/ionos/apiclient.go +++ b/internal/ionos/apiclient.go @@ -3,10 +3,11 @@ package ionos import ( "context" "fmt" - "github.com/GDATASoftwareAG/cluster-api-provider-ionoscloud/api/v1alpha1" - ionoscloud "github.com/ionos-cloud/sdk-go/v6" "strings" "sync" + + "github.com/GDATASoftwareAG/cluster-api-provider-ionoscloud/api/v1alpha1" + ionoscloud "github.com/ionos-cloud/sdk-go/v6" ) var _ Client = (*APIClient)(nil) @@ -29,7 +30,7 @@ type IPBlockAPI interface { type LanAPI interface { CreateLan(ctx context.Context, datacenterId string, public bool) (ionoscloud.LanPost, *ionoscloud.APIResponse, error) GetLan(ctx context.Context, datacenterId, lanId string) (ionoscloud.Lan, *ionoscloud.APIResponse, error) - EnsureFailoverIPOnLan(ctx context.Context, datacenterId, lanId, ip, nicUuid string) error + EnsureFailoverIPsOnLan(ctx context.Context, datacenterId, lanId, nicUuid string, ips []string) error } type DefaultAPI interface { @@ -51,7 +52,7 @@ type ServerAPI interface { CreateServer(ctx context.Context, datacenterId string, server ionoscloud.Server) (ionoscloud.Server, *ionoscloud.APIResponse, error) GetServer(ctx context.Context, datacenterId, serverId string) (ionoscloud.Server, *ionoscloud.APIResponse, error) DeleteServer(ctx context.Context, datacenterId, serverId string) (*ionoscloud.APIResponse, error) - EnsureAdditionalIPOnNic(ctx context.Context, datacenterId, serverId, nic, ip string) error + EnsureAdditionalIPsOnNic(ctx context.Context, datacenterId, serverId, nicUuid string, ips []string) error } type Client interface { @@ -85,53 +86,66 @@ type APIClient struct { client *ionoscloud.APIClient } -func (c *APIClient) EnsureAdditionalIPOnNic(ctx context.Context, datacenterId, serverId, nicUuid, ip string) error { +func (c *APIClient) EnsureAdditionalIPsOnNic(ctx context.Context, datacenterId, serverId, nicUuid string, toEnsureIPs []string) error { serverId = strings.TrimPrefix(serverId, "ionos://") nic, _, err := c.client.NetworkInterfacesApi.DatacentersServersNicsFindById(ctx, datacenterId, serverId, nicUuid).Execute() if err != nil { return err } - ips := []string{} + ips := make([]string, 0) if nic.Properties.Ips != nil { - for _, current := range *nic.Properties.Ips { + ips = *nic.Properties.Ips + } + for _, ip := range toEnsureIPs { + toAdd := true + for _, current := range ips { if current == ip { - return nil + toAdd = false + break } } - ips = *nic.Properties.Ips + if toAdd { + ips = append(ips, ip) + } } - ips = append(ips, ip) + _, _, err = c.client.NetworkInterfacesApi.DatacentersServersNicsPatch(ctx, datacenterId, serverId, nicUuid).Nic(ionoscloud.NicProperties{ Ips: &ips, }).Execute() return err } -func (c *APIClient) EnsureFailoverIPOnLan(ctx context.Context, datacenterId, lanId, ip, nicUuid string) error { +func (c *APIClient) EnsureFailoverIPsOnLan(ctx context.Context, datacenterId, lanId, nicUuid string, toEnsureIPs []string) error { lan, _, err := c.client.LANsApi.DatacentersLansFindById(ctx, datacenterId, lanId).Execute() if err != nil { return err } - failovers := []ionoscloud.IPFailover{} - ignore := false + + requireRegister := false + failovers := make([]ionoscloud.IPFailover, 0) if lan.Properties.IpFailover != nil { - for _, failover := range *lan.Properties.IpFailover { - if *failover.Ip == ip { - if *failover.NicUuid == nicUuid { - return nil - } - failover.NicUuid = &nicUuid - ignore = true + failovers = *lan.Properties.IpFailover + } + for _, ip := range toEnsureIPs { + toAdd := true + for _, current := range failovers { + if *current.Ip == ip { + toAdd = false + break } - failovers = append(failovers, failover) + } + if toAdd { + requireRegister = true + failovers = append(failovers, ionoscloud.IPFailover{ + Ip: &ip, + NicUuid: &nicUuid, + }) } } - if !ignore { - failovers = append(failovers, ionoscloud.IPFailover{ - Ip: &ip, - NicUuid: &nicUuid, - }) + if !requireRegister { + return nil } + _, _, err = c.client.LANsApi.DatacentersLansPatch(ctx, datacenterId, lanId).Lan(ionoscloud.LanProperties{ IpFailover: &failovers, }).Execute() diff --git a/testing/fakeClient.go b/testing/fakeClient.go index fd3a8ca..7e92ef4 100644 --- a/testing/fakeClient.go +++ b/testing/fakeClient.go @@ -26,12 +26,12 @@ type FakeClient struct { CredentialsAreValid bool } -func (f FakeClient) EnsureFailoverIPOnLan(ctx context.Context, datacenterId, lanId, ip, nicUuid string) error { +func (f FakeClient) EnsureFailoverIPsOnLan(_ context.Context, _, _ string, _ string, _ []string) error { //TODO implement me panic("implement me") } -func (f FakeClient) EnsureAdditionalIPOnNic(ctx context.Context, datacenterId, serverId, nic, ip string) error { +func (f FakeClient) EnsureAdditionalIPsOnNic(_ context.Context, _, _, _ string, _ []string) error { //TODO implement me panic("implement me") }