Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/update hostname faster #286

Merged
merged 12 commits into from
Jan 22, 2025
6 changes: 3 additions & 3 deletions internal/controller/compute/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ func (c *externalServer) Update(ctx context.Context, mg resource.Managed) (manag
}
// Attach or Detach Volume
if cr.Spec.ForProvider.VolumeCfg.VolumeID != "" && cr.Spec.ForProvider.VolumeCfg.VolumeID != cr.Status.AtProvider.VolumeID {
c.log.Debug("Update, attaching ", "volume", cr.Spec.ForProvider.VolumeCfg.VolumeID)
c.log.Debug("Update, attaching ", "volume id", cr.Spec.ForProvider.VolumeCfg.VolumeID, "volume name", cr.Spec.ForProvider.Name, "for server name", cr.Spec.ForProvider.Name)
_, apiResponse, err := c.service.AttachVolume(ctx, cr.Spec.ForProvider.DatacenterCfg.DatacenterID, cr.Status.AtProvider.ServerID,
sdkgo.Volume{Id: &cr.Spec.ForProvider.VolumeCfg.VolumeID})
if err != nil {
Expand All @@ -226,10 +226,10 @@ func (c *externalServer) Update(ctx context.Context, mg resource.Managed) (manag
if err = compute.WaitForRequest(ctx, c.service.GetAPIClient(), apiResponse); err != nil {
return managed.ExternalUpdate{}, err
}
c.log.Debug("Update, finished attaching Volume", "volume", cr.Spec.ForProvider.VolumeCfg.VolumeID)
c.log.Debug("Update, finished attaching Volume", "volume", cr.Spec.ForProvider.VolumeCfg.VolumeID, "volume name", cr.Spec.ForProvider.Name, "for server name", cr.Spec.ForProvider.Name)

} else if cr.Spec.ForProvider.VolumeCfg.VolumeID == "" && cr.Status.AtProvider.VolumeID != "" {
c.log.Debug("Update, detaching ", "volume", cr.Status.AtProvider.VolumeID)
c.log.Debug("Update, detaching ", "volume", cr.Status.AtProvider.VolumeID, "for server name", cr.Spec.ForProvider.Name)
apiResponse, err := c.service.DetachVolume(ctx, cr.Spec.ForProvider.DatacenterCfg.DatacenterID,
cr.Status.AtProvider.ServerID, cr.Status.AtProvider.VolumeID)
if err != nil {
Expand Down
21 changes: 10 additions & 11 deletions internal/controller/compute/statefulserverset/lan_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,21 @@ type kubeLANController struct {
// Create creates a lan CR and waits until in reaches AVAILABLE state
func (k *kubeLANController) Create(ctx context.Context, cr *v1alpha1.StatefulServerSet, lanIndex int) (v1alpha1.Lan, error) {
name := cr.Spec.ForProvider.Lans[lanIndex].Metadata.Name
k.log.Info("Creating LAN", "name", name)
k.log.Info("Creating LAN", "name", name, "ssset", cr.Name)

createLAN := fromStatefulServerSetToLAN(cr, name, lanIndex)
if err := k.kube.Create(ctx, &createLAN); err != nil {
return v1alpha1.Lan{}, err
return v1alpha1.Lan{}, fmt.Errorf("while creating lan %s %w", createLAN.Name, err)
}
if err := kube.WaitForResource(ctx, kube.ResourceReadyTimeout, k.isAvailable, name, cr.Namespace); err != nil {
_ = k.Delete(ctx, name, cr.Namespace)
return v1alpha1.Lan{}, fmt.Errorf("while waiting for LAN to be populated %w ", err)
return v1alpha1.Lan{}, fmt.Errorf("while waiting for LAN to be populated %s %w", name, err)
}
kubeLAN, err := k.Get(ctx, name, cr.Namespace)
if err != nil {
return v1alpha1.Lan{}, err
}
k.log.Info("Finished creating LAN", "name", name)
k.log.Info("Finished creating LAN", "name", name, "ssset", cr.Name)

return *kubeLAN, nil
}
Expand Down Expand Up @@ -84,19 +84,19 @@ func (k *kubeLANController) Update(ctx context.Context, cr *v1alpha1.StatefulSer
return v1alpha1.Lan{}, nil
}

k.log.Info("Updating LAN", "name", name)
k.log.Info("Updating LAN", "name", name, "ssset", cr.Name)

if err := k.kube.Update(ctx, updateKubeLAN); err != nil {
return v1alpha1.Lan{}, err
}
if err := kube.WaitForResource(ctx, kube.ResourceReadyTimeout, k.isAvailable, name, cr.Namespace); err != nil {
return v1alpha1.Lan{}, err
return v1alpha1.Lan{}, fmt.Errorf("while waiting for resource %s to be populated %w ", name, err)
}
updateKubeLAN, err = k.Get(ctx, name, cr.Namespace)
if err != nil {
return v1alpha1.Lan{}, err
}
k.log.Info("Finished updating LAN", "name", name)
k.log.Info("Finished updating LAN", "name", name, "ssset", cr.Name)
return *updateKubeLAN, nil
}

Expand Down Expand Up @@ -128,7 +128,7 @@ func (k *kubeLANController) Delete(ctx context.Context, name, namespace string)
return err
}
if err := k.kube.Delete(ctx, condemnedLAN); err != nil {
return fmt.Errorf("while deleting lan %w", err)
return fmt.Errorf("while deleting lan %s %w", name, err)
}
return kube.WaitForResource(ctx, kube.ResourceReadyTimeout, k.isLANDeleted, condemnedLAN.Name, namespace)
}
Expand Down Expand Up @@ -200,7 +200,7 @@ func fromStatefulServerSetToLAN(cr *v1alpha1.StatefulServerSet, name string, lan

// Ensure - creates a lan if it does not exist
func (k *kubeLANController) Ensure(ctx context.Context, cr *v1alpha1.StatefulServerSet, lanIndex int) error {
k.log.Info("Ensuring LAN", "lanIndex", lanIndex)
k.log.Info("Ensuring LAN", "lanIndex", lanIndex, "ssset", cr.Name)
res := &v1alpha1.LanList{}
if err := k.kube.List(ctx, res, client.MatchingLabels{
fmt.Sprintf(volumeselector.IndexLabel, getSSetName(cr), resourceLAN): strconv.Itoa(lanIndex),
Expand All @@ -212,7 +212,6 @@ func (k *kubeLANController) Ensure(ctx context.Context, cr *v1alpha1.StatefulSer
_, err := k.Create(ctx, cr, lanIndex)
return err
}
k.log.Info("Finished ensuring LAN", "lanIndex", lanIndex)

k.log.Info("Finished ensuring LAN", "lanIndex", lanIndex, "ssset", cr.Name)
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func (e *external) observeResourcesUpdateStatus(ctx context.Context, cr *v1alpha
if err != nil {
return false, false, false, err
}
e.log.Info("Observing the StatefulServerSet", "creationLansUpToDate", creationLansUpToDate, "lansUpToDate", lansUpToDate, "creationVolumesUpToDate", creationVolumesUpToDate,
e.log.Info("Observing the StatefulServerSet", "name", cr.Name, "creationLansUpToDate", creationLansUpToDate, "lansUpToDate", lansUpToDate, "creationVolumesUpToDate", creationVolumesUpToDate,
"areVolumesUpToDate", areVolumesUpToDate, "creationSSetUpToDate", creationSSetUpToDate, "isSSetUpToDate", isSSetUpToDate, "creationVSUpToDate", creationVSUpToDate, "areVolumesAvailable", areVolumesAvailable)
areResourcesCreated = creationLansUpToDate && creationVolumesUpToDate && creationSSetUpToDate && creationVSUpToDate
areResourcesUpdated = lansUpToDate && areVolumesUpToDate && isSSetUpToDate
Expand Down Expand Up @@ -296,22 +296,22 @@ func (e *external) Delete(ctx context.Context, mg resource.Managed) (managed.Ext
for replicaIndex := 0; replicaIndex < cr.Spec.ForProvider.Replicas; replicaIndex++ {
for volumeIndex := range cr.Spec.ForProvider.Volumes {
name := generateNameFrom(cr.Spec.ForProvider.Volumes[volumeIndex].Metadata.Name, replicaIndex, volumeIndex)
e.log.Info("Deleting the DataVolume with name", "name", name)
e.log.Info("Deleting the DataVolume with", "name", name, "ssset", cr.Name)
err := e.dataVolumeController.Delete(ctx, name, cr.Namespace)
if err != nil {
return managed.ExternalDelete{}, err
}
}
}

e.log.Info("Deleting the ServerSet with name", "name", cr.Spec.ForProvider.Template.Metadata.Name)
e.log.Info("Deleting the ServerSet with name", "name", cr.Spec.ForProvider.Template.Metadata.Name, "ssset", cr.Name)
if err := e.SSetController.Delete(ctx, cr.Spec.ForProvider.Template.Metadata.Name, cr.Namespace); err != nil {
return managed.ExternalDelete{}, err
}

for lanIndex := range cr.Spec.ForProvider.Lans {
name := cr.Spec.ForProvider.Lans[lanIndex].Metadata.Name
e.log.Info("Deleting the LANs with name", "name", name)
e.log.Info("Deleting the LANs with name", "name", name, "ssset", cr.Name)
err := e.LANController.Delete(ctx, name, cr.Namespace)
if err != nil {
return managed.ExternalDelete{}, err
Expand All @@ -328,7 +328,7 @@ func (e *external) Delete(ctx context.Context, mg resource.Managed) (managed.Ext
}

func (e *external) ensureDataVolumes(ctx context.Context, cr *v1alpha1.StatefulServerSet, replicaIndex int) error {
e.log.Info("Ensuring the DataVolumes")
e.log.Info("Ensuring the DataVolumes for ", "name", cr.Name)
for volumeIndex := range cr.Spec.ForProvider.Volumes {
err := e.dataVolumeController.Ensure(ctx, cr, replicaIndex, volumeIndex)
if err != nil {
Expand All @@ -339,7 +339,7 @@ func (e *external) ensureDataVolumes(ctx context.Context, cr *v1alpha1.StatefulS
}

func (e *external) ensureLans(ctx context.Context, cr *v1alpha1.StatefulServerSet) error {
e.log.Info("Ensuring the LANs")
e.log.Info("Ensuring the LANs for", "name", cr.Name)
for lanIndex := range cr.Spec.ForProvider.Lans {
err := e.LANController.Ensure(ctx, cr, lanIndex)
if err != nil {
Expand Down
39 changes: 22 additions & 17 deletions internal/controller/serverset/bootvolume_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type kubeBootVolumeController struct {
func (k *kubeBootVolumeController) Create(ctx context.Context, cr *v1alpha1.ServerSet, replicaIndex, version int) (v1alpha1.Volume, error) {
name := getNameFrom(cr.Spec.ForProvider.BootVolumeTemplate.Metadata.Name, replicaIndex, version)
hostname := getNameFrom(cr.Spec.ForProvider.Template.Metadata.Name, replicaIndex, version)
k.log.Info("Creating BootVolume", "name", name)
k.log.Info("Creating BootVolume", "name", name, "serverset", cr.Name)
var userDataPatcher *ccpatch.CloudInitPatcher
var err error
userDataPatcher, err = k.setPatcher(ctx, cr, replicaIndex, version, name, k.kube)
Expand All @@ -53,14 +53,14 @@ func (k *kubeBootVolumeController) Create(ctx context.Context, cr *v1alpha1.Serv
}
if err := kube.WaitForResource(ctx, kube.ResourceReadyTimeout, k.isAvailable, name, cr.Namespace); err != nil {
_ = k.Delete(ctx, createVolume.Name, cr.Namespace)
return v1alpha1.Volume{}, fmt.Errorf("while waiting for BootVolume to be populated %w ", err)
return v1alpha1.Volume{}, fmt.Errorf("while waiting for BootVolume %s to be populated %w ", createVolume.Name, err)
}
// get the volume again before returning to have the id populated
kubeVolume, err := k.Get(ctx, name, cr.Namespace)
if err != nil {
return v1alpha1.Volume{}, err
}
k.log.Info("Finished creating BootVolume", "name", name)
k.log.Info("Finished creating BootVolume", "name", name, "serverset", cr.Name)

return *kubeVolume, nil
}
Expand All @@ -80,7 +80,7 @@ func (k *kubeBootVolumeController) setPatcher(ctx context.Context, cr *v1alpha1.
substitutions := extractSubstitutions(cr.Spec.ForProvider.BootVolumeTemplate.Spec.Substitutions)
userDataPatcher, err = ccpatch.NewCloudInitPatcherWithSubstitutions(userData, identifier, substitutions, ionoscloud.ToPtr(globalStateMap[cr.Name]))
if err != nil {
return userDataPatcher, fmt.Errorf("while creating cloud init patcher with substitutions for BootVolume %s %w", name, err)
return userDataPatcher, fmt.Errorf("while creating cloud init patcher with substitutions for BootVolume %s on serverset %s %w", name, cr.Name, err)
}
namespace := "default"
if cr.Spec.ForProvider.IdentityConfigMap.Namespace != "" {
Expand All @@ -98,12 +98,12 @@ func (k *kubeBootVolumeController) setPatcher(ctx context.Context, cr *v1alpha1.
}
err := k.mapController.CreateOrUpdate(ctx, cr.Name)
if err != nil {
k.log.Info("while writing to substConfig map", "error", err)
k.log.Info("while writing to substConfig map", "error", err, "serverset", cr.Name)
}
} else {
userDataPatcher, err = ccpatch.NewCloudInitPatcher(userData)
if err != nil {
return userDataPatcher, fmt.Errorf("while creating cloud init patcher for BootVolume %s %w", name, err)
return userDataPatcher, fmt.Errorf("while creating cloud init patcher for BootVolume %s serverset %s %w", name, cr.Name, err)
}
}
err = setPCINICSlotEnv(ctx, cr.Spec.ForProvider.Template.Spec.NICs, cr.Name, replicaIndex, kube, *userDataPatcher)
Expand Down Expand Up @@ -157,7 +157,7 @@ func (k *kubeBootVolumeController) Delete(ctx context.Context, name, namespace s
return err
}
if err := k.kube.Delete(ctx, condemnedVolume); err != nil {
return fmt.Errorf("error deleting BootVolume %w", err)
return fmt.Errorf("error deleting BootVolume %s %w", name, err)
}
return kube.WaitForResource(ctx, kube.ResourceReadyTimeout, k.isBootVolumeDeleted, condemnedVolume.Name, namespace)
}
Expand Down Expand Up @@ -216,13 +216,19 @@ func fromServerSetToVolume(cr *v1alpha1.ServerSet, name string, replicaIndex, ve
DeletionPolicy: cr.GetDeletionPolicy(),
},
ForProvider: v1alpha1.VolumeParameters{
DatacenterCfg: cr.Spec.ForProvider.DatacenterCfg,
Name: name,
AvailabilityZone: GetZoneFromIndex(replicaIndex),
Size: cr.Spec.ForProvider.BootVolumeTemplate.Spec.Size,
Type: cr.Spec.ForProvider.BootVolumeTemplate.Spec.Type,
Image: cr.Spec.ForProvider.BootVolumeTemplate.Spec.Image,
UserData: cr.Spec.ForProvider.BootVolumeTemplate.Spec.UserData,
DatacenterCfg: cr.Spec.ForProvider.DatacenterCfg,
Name: name,
AvailabilityZone: GetZoneFromIndex(replicaIndex),
Size: cr.Spec.ForProvider.BootVolumeTemplate.Spec.Size,
Type: cr.Spec.ForProvider.BootVolumeTemplate.Spec.Type,
Image: cr.Spec.ForProvider.BootVolumeTemplate.Spec.Image,
UserData: cr.Spec.ForProvider.BootVolumeTemplate.Spec.UserData,
CPUHotPlug: true,
RAMHotPlug: true,
NicHotPlug: true,
NicHotUnplug: true,
DiscVirtioHotPlug: true,
DiscVirtioHotUnplug: true,
},
}}
if cr.Spec.ForProvider.BootVolumeTemplate.Spec.ImagePassword != "" {
Expand All @@ -236,7 +242,7 @@ func fromServerSetToVolume(cr *v1alpha1.ServerSet, name string, replicaIndex, ve

// Ensure - creates a boot volume if it does not exist
func (k *kubeBootVolumeController) Ensure(ctx context.Context, cr *v1alpha1.ServerSet, replicaIndex, version int) error {
k.log.Info("Ensuring BootVolume", "replicaIndex", replicaIndex, "version", version)
k.log.Info("Ensuring BootVolume from serverset", "name", cr.Name, "replicaIndex", replicaIndex, "version", version)
res := &v1alpha1.VolumeList{}
if err := listResFromSSetWithIndexAndVersion(ctx, k.kube, cr.GetName(), resourceBootVolume, replicaIndex, version, res); err != nil {
return err
Expand All @@ -246,8 +252,7 @@ func (k *kubeBootVolumeController) Ensure(ctx context.Context, cr *v1alpha1.Serv
_, err := k.Create(ctx, cr, replicaIndex, version)
return err
}
k.log.Info("Finished ensuring BootVolume", "replicaIndex", replicaIndex, "version", version)

k.log.Info("Finished ensuring BootVolume", "replicaIndex", replicaIndex, "version", version, "serverset", cr.Name)
return nil
}

Expand Down
20 changes: 10 additions & 10 deletions internal/controller/serverset/nic_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func getNicName(resourceName string, replicaIndex, nicIndex, version int) string
// Create creates a NIC CR and waits until in reaches AVAILABLE state
func (k *kubeNicController) Create(ctx context.Context, cr *v1alpha1.ServerSet, serverID, lanName string, replicaIndex, nicIndex, version int) (v1alpha1.Nic, error) {
name := getNicName(cr.Spec.ForProvider.Template.Spec.NICs[nicIndex].Name, replicaIndex, nicIndex, version)
k.log.Info("Creating NIC", "name", name)
k.log.Info("Creating NIC", "name", name, "serverset", cr.Name)
lan := v1alpha1.Lan{}
if err := k.kube.Get(ctx, types.NamespacedName{
Namespace: cr.GetNamespace(),
Expand All @@ -51,19 +51,19 @@ func (k *kubeNicController) Create(ctx context.Context, cr *v1alpha1.ServerSet,
// no NIC found, create one
createNic := k.fromServerSetToNic(cr, name, serverID, lan, replicaIndex, nicIndex, version)
if err := k.kube.Create(ctx, &createNic); err != nil {
return v1alpha1.Nic{}, fmt.Errorf("while creating NIC %w ", err)
return v1alpha1.Nic{}, fmt.Errorf("while creating NIC %s for serverset %s %w ", createNic.Name, cr.Name, err)
}

err := kube.WaitForResource(ctx, kube.ResourceReadyTimeout, k.isAvailable, createNic.Name, cr.Namespace)
if err != nil {
_ = k.Delete(ctx, createNic.Name, cr.Namespace)
return v1alpha1.Nic{}, fmt.Errorf("while waiting for NIC to be populated %w ", err)
return v1alpha1.Nic{}, fmt.Errorf("while waiting for NIC name %s to be populated for serverset %s %w ", createNic.Name, cr.Name, err)
}
createdNic, err := k.Get(ctx, createNic.Name, cr.Namespace)
if err != nil {
return v1alpha1.Nic{}, fmt.Errorf("while getting NIC %w ", err)
return v1alpha1.Nic{}, fmt.Errorf("while getting NIC name %s for serverset %s %w ", createNic.Name, cr.Name, err)
}
k.log.Info("Finished creating NIC", "name", name)
k.log.Info("Finished creating NIC", "name", name, "serverset", cr.Name)
return *createdNic, nil
}

Expand Down Expand Up @@ -119,14 +119,14 @@ func (k *kubeNicController) isNicDeleted(ctx context.Context, name, namespace st

// Delete - deletes the nic k8s client and waits until it is deleted
func (k *kubeNicController) Delete(ctx context.Context, name, namespace string) error {
condemnedVolume, err := k.Get(ctx, name, namespace)
condemnedNIC, err := k.Get(ctx, name, namespace)
if err != nil {
return err
}
if err := k.kube.Delete(ctx, condemnedVolume); err != nil {
if err := k.kube.Delete(ctx, condemnedNIC); err != nil {
return err
}
return kube.WaitForResource(ctx, kube.ResourceReadyTimeout, k.isNicDeleted, condemnedVolume.Name, namespace)
return kube.WaitForResource(ctx, kube.ResourceReadyTimeout, k.isNicDeleted, condemnedNIC.Name, namespace)
}

func (k *kubeNicController) fromServerSetToNic(cr *v1alpha1.ServerSet, name, serverID string, lan v1alpha1.Lan, replicaIndex, nicIndex, version int) v1alpha1.Nic {
Expand Down Expand Up @@ -176,7 +176,7 @@ func (k *kubeNicController) fromServerSetToNic(cr *v1alpha1.ServerSet, name, ser

// EnsureNICs - creates NICS if they do not exist
func (k *kubeNicController) EnsureNICs(ctx context.Context, cr *v1alpha1.ServerSet, replicaIndex, version int) error {
k.log.Info("Ensuring NICs", "index", replicaIndex, "version", version)
k.log.Info("Ensuring NICs", "index", replicaIndex, "version", version, "serverset", cr.Name)
res := &v1alpha1.ServerList{}
if err := listResFromSSetWithIndexAndVersion(ctx, k.kube, cr.GetName(), ResourceServer, replicaIndex, version, res); err != nil {
return err
Expand All @@ -190,7 +190,7 @@ func (k *kubeNicController) EnsureNICs(ctx context.Context, cr *v1alpha1.ServerS
}
}
}
k.log.Info("Finished ensuring NICs", "index", replicaIndex, "version", version)
k.log.Info("Finished ensuring NICs", "index", replicaIndex, "version", version, "serverset", cr.Name)

return nil
}
Expand Down
15 changes: 13 additions & 2 deletions internal/controller/serverset/recreate_only_bootvolume.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package serverset

import (
"context"

"fmt"
"github.com/ionos-cloud/crossplane-provider-ionoscloud/apis/compute/v1alpha1"
)

Expand All @@ -21,6 +21,18 @@ func newCreateBeforeDestroyOnlyBootVolume(bootVolumeController kubeBootVolumeCon
func (c *createBeforeDestroyOnlyBootVolume) update(ctx context.Context, cr *v1alpha1.ServerSet, replicaIndex, volumeVersion, serverVersion int) error {
// todo we need the same IP in case of an update that deletes the bootvolume
newVolumeVersion := volumeVersion + 1

existingVolume, err := c.bootVolumeController.Get(ctx, getNameFrom(cr.Spec.ForProvider.BootVolumeTemplate.Metadata.Name, replicaIndex, volumeVersion), cr.Namespace)
if err != nil {
return err
}
// no need to recreate bootvolume, we created one already. we need to do this because we update the status between creations of replicas, so a new observe runs so it tries
//to create a volume while the other one is creating
// if there are other fields that force re-creation, they should be added here
if existingVolume != nil && existingVolume.Spec.ForProvider.Type == cr.Spec.ForProvider.BootVolumeTemplate.Spec.Type &&
existingVolume.Spec.ForProvider.Image == cr.Spec.ForProvider.BootVolumeTemplate.Spec.Image {
return fmt.Errorf("existing bootvolume %s found, no need to recreate", existingVolume.Name)
}
if err := c.bootVolumeController.Ensure(ctx, cr, replicaIndex, newVolumeVersion); err != nil {
return err
}
Expand All @@ -32,7 +44,6 @@ func (c *createBeforeDestroyOnlyBootVolume) update(ctx context.Context, cr *v1al
if err != nil {
return err
}
// server.Status.AtProvider.VolumeID = createdVolume.Status.AtProvider.VolumeID
server.Spec.ForProvider.VolumeCfg.VolumeID = createdVolume.Status.AtProvider.VolumeID
if err := c.serverController.Update(ctx, server); err != nil {
return err
Expand Down
Loading
Loading