migrated LB regionalized API to zoned API

This commit is contained in:
Leïla MARABESE 2023-01-17 17:43:53 +01:00
parent ea2f7123e1
commit 3dece51a3a
5 changed files with 91 additions and 123 deletions

View File

@ -52,6 +52,10 @@ func (b *APILoadBalancerModelBuilder) Build(c *fi.CloudupModelBuilderContext) er
return fmt.Errorf("unhandled load-balancer type %q", lbSpec.Type)
}
zone, err := scaleway.ParseZoneFromClusterSpec(b.Cluster.Spec)
if err != nil {
return fmt.Errorf("building load-balancer task: %w", err)
}
lbTags := []string(nil)
for k, v := range b.CloudTags(b.ClusterName(), false) {
lbTags = append(lbTags, fmt.Sprintf("%s=%s", k, v))
@ -61,9 +65,11 @@ func (b *APILoadBalancerModelBuilder) Build(c *fi.CloudupModelBuilderContext) er
loadBalancerName := "api." + b.ClusterName()
loadBalancer := &scalewaytasks.LoadBalancer{
Name: fi.PtrTo(loadBalancerName),
Region: fi.PtrTo(b.Region),
Zone: fi.PtrTo(string(zone)),
Lifecycle: b.Lifecycle,
Tags: lbTags,
Description: "Load-balancer for kops cluster " + b.ClusterName(),
SslCompatibilityLevel: string(lb.SSLCompatibilityLevelSslCompatibilityLevelUnknown),
}
c.AddTask(loadBalancer)

View File

@ -688,7 +688,7 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
KopsModelContext: modelContext,
}
l.Builders = append(l.Builders,
&scalewaymodel.APILoadBalancerModelBuilder{ScwModelContext: scwModelContext, Lifecycle: clusterLifecycle},
&scalewaymodel.APILoadBalancerModelBuilder{ScwModelContext: scwModelContext, Lifecycle: networkLifecycle},
&scalewaymodel.InstanceModelBuilder{ScwModelContext: scwModelContext, BootstrapScriptBuilder: bootstrapScriptBuilder, Lifecycle: clusterLifecycle},
&scalewaymodel.SSHKeyModelBuilder{ScwModelContext: scwModelContext, Lifecycle: securityLifecycle},
)

View File

@ -57,7 +57,7 @@ type ScwCloud interface {
IamService() *iam.API
InstanceService() *instance.API
LBService() *lb.API
LBService() *lb.ZonedAPI
DeleteGroup(group *cloudinstances.CloudInstanceGroup) error
DeleteInstance(i *cloudinstances.CloudInstance) error
@ -91,7 +91,7 @@ type scwCloudImplementation struct {
iamAPI *iam.API
instanceAPI *instance.API
lbAPI *lb.API
lbAPI *lb.ZonedAPI
}
// NewScwCloud returns a Cloud with a Scaleway Client using the env vars SCW_ACCESS_KEY, SCW_SECRET_KEY and SCW_DEFAULT_PROJECT_ID
@ -140,7 +140,7 @@ func NewScwCloud(tags map[string]string) (ScwCloud, error) {
tags: tags,
iamAPI: iam.NewAPI(scwClient),
instanceAPI: instance.NewAPI(scwClient),
lbAPI: lb.NewAPI(scwClient),
lbAPI: lb.NewZonedAPI(scwClient),
}, nil
}
@ -178,7 +178,7 @@ func (s *scwCloudImplementation) InstanceService() *instance.API {
return s.instanceAPI
}
func (s *scwCloudImplementation) LBService() *lb.API {
func (s *scwCloudImplementation) LBService() *lb.ZonedAPI {
return s.lbAPI
}
@ -229,8 +229,8 @@ func (s *scwCloudImplementation) DeregisterInstance(i *cloudinstances.CloudInsta
return fmt.Errorf("deregistering cloud instance %s of group %q: %w", i.ID, i.CloudInstanceGroup.HumanName, err)
}
for _, loadBalancer := range lbs {
backEnds, err := s.lbAPI.ListBackends(&lb.ListBackendsRequest{
Region: s.region,
backEnds, err := s.lbAPI.ListBackends(&lb.ZonedAPIListBackendsRequest{
Zone: s.zone,
LBID: loadBalancer.ID,
}, scw.WithAllPages())
if err != nil {
@ -239,8 +239,8 @@ func (s *scwCloudImplementation) DeregisterInstance(i *cloudinstances.CloudInsta
for _, backEnd := range backEnds.Backends {
for _, serverIP := range backEnd.Pool {
if serverIP == fi.ValueOf(server.Server.PrivateIP) {
_, err := s.lbAPI.RemoveBackendServers(&lb.RemoveBackendServersRequest{
Region: s.region,
_, err := s.lbAPI.RemoveBackendServers(&lb.ZonedAPIRemoveBackendServersRequest{
Zone: s.zone,
BackendID: backEnd.ID,
ServerIP: []string{serverIP},
})
@ -276,8 +276,8 @@ func (s *scwCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]f
var ingresses []fi.ApiIngressStatus
name := "api." + cluster.Name
responseLoadBalancers, err := s.lbAPI.ListLBs(&lb.ListLBsRequest{
Region: scw.Region(s.Region()),
responseLoadBalancers, err := s.lbAPI.ListLBs(&lb.ZonedAPIListLBsRequest{
Zone: s.zone,
Name: &name,
}, scw.WithAllPages())
if err != nil {
@ -382,8 +382,8 @@ func buildCloudGroup(ig *kops.InstanceGroup, sg []*instance.Server, nodeMap map[
func (s *scwCloudImplementation) GetClusterLoadBalancers(clusterName string) ([]*lb.LB, error) {
loadBalancerName := "api." + clusterName
lbs, err := s.lbAPI.ListLBs(&lb.ListLBsRequest{
Region: s.region,
lbs, err := s.lbAPI.ListLBs(&lb.ZonedAPIListLBsRequest{
Zone: s.zone,
Name: &loadBalancerName,
}, scw.WithAllPages())
if err != nil {
@ -437,15 +437,15 @@ func (s *scwCloudImplementation) DeleteLoadBalancer(loadBalancer *lb.LB) error {
ipsToRelease := loadBalancer.IP
// We delete the load-balancer once it's in a stable state
_, err := s.lbAPI.WaitForLb(&lb.WaitForLBRequest{
_, err := s.lbAPI.WaitForLb(&lb.ZonedAPIWaitForLBRequest{
LBID: loadBalancer.ID,
Region: s.region,
Zone: s.zone,
})
if err != nil {
return fmt.Errorf("waiting for load-balancer: %w", err)
}
err = s.lbAPI.DeleteLB(&lb.DeleteLBRequest{
Region: s.region,
err = s.lbAPI.DeleteLB(&lb.ZonedAPIDeleteLBRequest{
Zone: s.zone,
LBID: loadBalancer.ID,
})
if err != nil {
@ -453,16 +453,16 @@ func (s *scwCloudImplementation) DeleteLoadBalancer(loadBalancer *lb.LB) error {
}
// We wait for the load-balancer to be deleted, then we detach its IPs
_, err = s.lbAPI.WaitForLb(&lb.WaitForLBRequest{
_, err = s.lbAPI.WaitForLb(&lb.ZonedAPIWaitForLBRequest{
LBID: loadBalancer.ID,
Region: s.region,
Zone: s.zone,
})
if !is404Error(err) {
return fmt.Errorf("waiting for load-balancer %s after deletion: %w", loadBalancer.ID, err)
}
for _, ip := range ipsToRelease {
err := s.lbAPI.ReleaseIP(&lb.ReleaseIPRequest{
Region: s.region,
err := s.lbAPI.ReleaseIP(&lb.ZonedAPIReleaseIPRequest{
Zone: s.zone,
IPID: ip.ID,
})
if err != nil {

View File

@ -208,7 +208,7 @@ func (_ *Instance) RenderScw(c *fi.CloudupContext, actual, expected, changes *In
// If IG is control-plane, we add the new servers' IPs to the load-balancer's back-end
if len(controlPlanePrivateIPs) > 0 {
lbService := cloud.LBService()
region := scw.Region(cloud.Region())
zone := scw.Zone(cloud.Zone())
lbs, err := cloud.GetClusterLoadBalancers(cloud.ClusterName(expected.Tags))
if err != nil {
@ -216,8 +216,8 @@ func (_ *Instance) RenderScw(c *fi.CloudupContext, actual, expected, changes *In
}
for _, loadBalancer := range lbs {
backEnds, err := lbService.ListBackends(&lb.ListBackendsRequest{
Region: region,
backEnds, err := lbService.ListBackends(&lb.ZonedAPIListBackendsRequest{
Zone: zone,
LBID: loadBalancer.ID,
})
if err != nil {
@ -228,8 +228,8 @@ func (_ *Instance) RenderScw(c *fi.CloudupContext, actual, expected, changes *In
}
backEnd := backEnds.Backends[0]
_, err = lbService.AddBackendServers(&lb.AddBackendServersRequest{
Region: region,
_, err = lbService.AddBackendServers(&lb.ZonedAPIAddBackendServersRequest{
Zone: zone,
BackendID: backEnd.ID,
ServerIP: controlPlanePrivateIPs,
})
@ -237,9 +237,9 @@ func (_ *Instance) RenderScw(c *fi.CloudupContext, actual, expected, changes *In
return fmt.Errorf("adding servers' IPs to load-balancer's back-end: %w", err)
}
_, err = lbService.WaitForLb(&lb.WaitForLBRequest{
_, err = lbService.WaitForLb(&lb.ZonedAPIWaitForLBRequest{
LBID: loadBalancer.ID,
Region: region,
Zone: zone,
})
if err != nil {
return fmt.Errorf("waiting for load-balancer %s: %w", loadBalancer.ID, err)

View File

@ -32,10 +32,12 @@ type LoadBalancer struct {
Name *string
Lifecycle fi.Lifecycle
Region *string
Zone *string
LBID *string
LBAddresses []string
Tags []string
Description string
SslCompatibilityLevel string
ForAPIServer bool
}
@ -51,20 +53,20 @@ func (l *LoadBalancer) IsForAPIServer() bool {
}
func (l *LoadBalancer) Find(context *fi.CloudupContext) (*LoadBalancer, error) {
if fi.ValueOf(l.LBID) == "" {
return nil, nil
}
cloud := context.T.Cloud.(scaleway.ScwCloud)
lbService := cloud.LBService()
loadBalancer, err := lbService.GetLB(&lb.GetLBRequest{
Region: scw.Region(cloud.Region()),
LBID: fi.ValueOf(l.LBID),
})
lbResponse, err := lbService.ListLBs(&lb.ZonedAPIListLBsRequest{
Zone: scw.Zone(cloud.Zone()),
Name: l.Name,
}, scw.WithAllPages())
if err != nil {
return nil, fmt.Errorf("getting load-balancer %s: %s", fi.ValueOf(l.LBID), err)
return nil, fmt.Errorf("getting load-balancer %s: %w", fi.ValueOf(l.LBID), err)
}
if lbResponse.TotalCount != 1 {
return nil, nil
}
loadBalancer := lbResponse.LBs[0]
lbIPs := []string(nil)
for _, IP := range loadBalancer.IP {
@ -72,8 +74,9 @@ func (l *LoadBalancer) Find(context *fi.CloudupContext) (*LoadBalancer, error) {
}
return &LoadBalancer{
Name: &loadBalancer.Name,
LBID: &loadBalancer.ID,
Name: fi.PtrTo(loadBalancer.Name),
LBID: fi.PtrTo(loadBalancer.ID),
Zone: fi.PtrTo(string(loadBalancer.Zone)),
LBAddresses: lbIPs,
Tags: loadBalancer.Tags,
Lifecycle: l.Lifecycle,
@ -89,8 +92,8 @@ func (l *LoadBalancer) FindAddresses(context *fi.CloudupContext) ([]string, erro
return nil, nil
}
loadBalancer, err := lbService.GetLB(&lb.GetLBRequest{
Region: scw.Region(cloud.Region()),
loadBalancer, err := lbService.GetLB(&lb.ZonedAPIGetLBRequest{
Zone: scw.Zone(cloud.Zone()),
LBID: fi.ValueOf(l.LBID),
})
if err != nil {
@ -117,15 +120,15 @@ func (_ *LoadBalancer) CheckChanges(actual, expected, changes *LoadBalancer) err
if changes.LBID != nil {
return fi.CannotChangeField("ID")
}
if changes.Region != nil {
return fi.CannotChangeField("Region")
if changes.Zone != nil {
return fi.CannotChangeField("Zone")
}
} else {
if expected.Name == nil {
return fi.RequiredField("Name")
}
if expected.Region == nil {
return fi.RequiredField("Region")
if expected.Zone == nil {
return fi.RequiredField("Zone")
}
}
return nil
@ -133,30 +136,20 @@ func (_ *LoadBalancer) CheckChanges(actual, expected, changes *LoadBalancer) err
func (l *LoadBalancer) RenderScw(t *scaleway.ScwAPITarget, actual, expected, changes *LoadBalancer) error {
lbService := t.Cloud.LBService()
region := scw.Region(fi.ValueOf(expected.Region))
var loadBalancer *lb.LB
backEndToCreate := true
frontEndToCreate := true
zone := scw.Zone(fi.ValueOf(expected.Zone))
if actual != nil {
klog.Infof("Updating existing load-balancer with name %q", expected.Name)
lbToUpdate, err := lbService.GetLB(&lb.GetLBRequest{
Region: region,
LBID: fi.ValueOf(actual.LBID),
})
if err != nil {
return fmt.Errorf("getting load-balancer %q (%s): %w", fi.ValueOf(actual.Name), fi.ValueOf(actual.LBID), err)
}
klog.Infof("Updating existing load-balancer with name %q", expected.Name)
// We update the tags
if changes != nil || len(actual.Tags) != len(expected.Tags) {
_, err = lbService.UpdateLB(&lb.UpdateLBRequest{
Region: region,
LBID: lbToUpdate.ID,
Name: lbToUpdate.Name,
Description: lbToUpdate.Description,
SslCompatibilityLevel: lbToUpdate.SslCompatibilityLevel,
_, err := lbService.UpdateLB(&lb.ZonedAPIUpdateLBRequest{
Zone: zone,
LBID: fi.ValueOf(expected.LBID),
Name: fi.ValueOf(expected.Name),
Description: expected.Description,
SslCompatibilityLevel: lb.SSLCompatibilityLevel(expected.SslCompatibilityLevel),
Tags: expected.Tags,
})
if err != nil {
@ -164,46 +157,15 @@ func (l *LoadBalancer) RenderScw(t *scaleway.ScwAPITarget, actual, expected, cha
}
}
// We check that the back-end exists
backEnds, err := lbService.ListBackends(&lb.ListBackendsRequest{
Region: region,
LBID: lbToUpdate.ID,
Name: scw.StringPtr("lb-backend"),
})
if err != nil {
return fmt.Errorf("listing back-ends for load-balancer %q: %w", fi.ValueOf(expected.Name), err)
}
if backEnds.TotalCount > 0 {
backEndToCreate = false
}
// We check that the front-end exists
frontEnds, err := lbService.ListFrontends(&lb.ListFrontendsRequest{
Region: region,
LBID: lbToUpdate.ID,
Name: scw.StringPtr("lb-frontend"),
})
if err != nil {
return fmt.Errorf("listing front-ends for load-balancer %q: %w", fi.ValueOf(expected.Name), err)
}
if frontEnds.TotalCount > 0 {
frontEndToCreate = false
}
lbIPs := []string(nil)
for _, ip := range lbToUpdate.IP {
lbIPs = append(lbIPs, ip.IPAddress)
}
expected.LBID = &lbToUpdate.ID
expected.LBAddresses = lbIPs
loadBalancer = lbToUpdate
expected.LBID = actual.LBID
expected.LBAddresses = actual.LBAddresses
} else {
klog.Infof("Creating new load-balancer with name %q", expected.Name)
lbCreated, err := lbService.CreateLB(&lb.CreateLBRequest{
Region: region,
lbCreated, err := lbService.CreateLB(&lb.ZonedAPICreateLBRequest{
Zone: zone,
Name: fi.ValueOf(expected.Name),
Tags: expected.Tags,
})
@ -211,9 +173,9 @@ func (l *LoadBalancer) RenderScw(t *scaleway.ScwAPITarget, actual, expected, cha
return fmt.Errorf("creating load-balancer: %w", err)
}
_, err = lbService.WaitForLb(&lb.WaitForLBRequest{
_, err = lbService.WaitForLb(&lb.ZonedAPIWaitForLBRequest{
LBID: lbCreated.ID,
Region: region,
Zone: zone,
})
if err != nil {
return fmt.Errorf("waiting for load-balancer %s: %w", lbCreated.ID, err)