From b55d1ad5486a076e943482efef4891e1b7fb9fac Mon Sep 17 00:00:00 2001 From: Tobias Wolf Date: Wed, 16 Jun 2021 14:21:52 +0200 Subject: [PATCH] Remove workaround for machine image names --- pkg/controller/worker/machine_images.go | 42 +++++++++++++++++++++ pkg/controller/worker/machines.go | 11 ++++-- pkg/hcloud/apis/transcoder/cloud_profile.go | 21 +++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/pkg/controller/worker/machine_images.go b/pkg/controller/worker/machine_images.go index 7c95143c6..06518f88d 100644 --- a/pkg/controller/worker/machine_images.go +++ b/pkg/controller/worker/machine_images.go @@ -20,15 +20,57 @@ package worker import ( "context" + "github.com/23technologies/gardener-extension-provider-hcloud/pkg/hcloud" "github.com/23technologies/gardener-extension-provider-hcloud/pkg/hcloud/apis" "github.com/23technologies/gardener-extension-provider-hcloud/pkg/hcloud/apis/transcoder" "github.com/23technologies/gardener-extension-provider-hcloud/pkg/hcloud/apis/v1alpha1" "github.com/gardener/gardener/extensions/pkg/controller" + "github.com/gardener/gardener/extensions/pkg/controller/worker" + hcloudclient "github.com/hetznercloud/hcloud-go/hcloud" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/util/retry" ) +func (w *workerDelegate) findMachineImageName(ctx context.Context, name, version string) (string, error) { + machineImage, err := transcoder.DecodeMachineImageNameFromCloudProfile(w.cloudProfileConfig, name, version) + if err == nil { + return machineImage, nil + } + + secret, err := w.getSecretData(ctx) + if err != nil { + return "", err + } + + credentials, err := hcloud.ExtractCredentials(secret) + if err != nil { + return "", err + } + + client := apis.GetClientForToken(string(credentials.HcloudMCM().Token)) + + opts := hcloudclient.ImageListOpts{ + Type: []hcloudclient.ImageType{"system"}, + Status: []hcloudclient.ImageStatus{"available"}, + } + + images, _, err := client.Image.List(ctx, opts) + if nil != err { + return "", err + } + + for _, image := range images { + if image.OSFlavor != name || image.OSVersion != version { + continue + } + + return image.Name, nil + } + + return "", worker.ErrorMachineImageNotFound(name, version) +} + // GetMachineImages returns the used machine images for the `Worker` resource. func (w *workerDelegate) UpdateMachineImagesStatus(ctx context.Context) error { if w.machineImages == nil { diff --git a/pkg/controller/worker/machines.go b/pkg/controller/worker/machines.go index 488c8e11f..c2926ace3 100644 --- a/pkg/controller/worker/machines.go +++ b/pkg/controller/worker/machines.go @@ -21,7 +21,6 @@ import ( "context" "fmt" "path/filepath" - "strings" "github.com/23technologies/gardener-extension-provider-hcloud/pkg/hcloud" @@ -35,6 +34,7 @@ import ( "github.com/gardener/gardener/pkg/client/kubernetes" mcmv1alpha1 "github.com/gardener/machine-controller-manager/pkg/apis/machine/v1alpha1" "github.com/pkg/errors" + corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -73,8 +73,12 @@ func (w *workerDelegate) GenerateMachineDeployments(ctx context.Context) (worker return w.machineDeployments, nil } +func (w *workerDelegate) getSecretData(ctx context.Context) (*corev1.Secret, error) { + return extensionscontroller.GetSecretByReference(ctx, w.Client(), &w.worker.Spec.SecretRef) +} + func (w *workerDelegate) generateMachineClassSecretData(ctx context.Context) (map[string][]byte, error) { - secret, err := extensionscontroller.GetSecretByReference(ctx, w.Client(), &w.worker.Spec.SecretRef) + secret, err := w.getSecretData(ctx) if err != nil { return nil, err } @@ -121,6 +125,7 @@ func (w *workerDelegate) generateMachineConfig(ctx context.Context) error { return err } + imageName, err := w.findMachineImageName(ctx, pool.MachineImage.Name, pool.MachineImage.Version) if err != nil { return err } @@ -133,7 +138,7 @@ func (w *workerDelegate) generateMachineConfig(ctx context.Context) error { machineClassSpec := map[string]interface{}{ "cluster": w.worker.Namespace, "zone": string(w.worker.Spec.Region), - "imageName": strings.Join([]string{pool.MachineImage.Name, pool.MachineImage.Version}, "-"), //FIXME + "imageName": imageName, "sshFingerprint": sshFingerprint, "machineType": string(pool.MachineType), "networkName": fmt.Sprintf("%s-workers", w.worker.Namespace), diff --git a/pkg/hcloud/apis/transcoder/cloud_profile.go b/pkg/hcloud/apis/transcoder/cloud_profile.go index 2d9a14114..fed18f5fa 100644 --- a/pkg/hcloud/apis/transcoder/cloud_profile.go +++ b/pkg/hcloud/apis/transcoder/cloud_profile.go @@ -20,6 +20,7 @@ package transcoder import ( "context" "errors" + "fmt" "github.com/23technologies/gardener-extension-provider-hcloud/pkg/hcloud/apis" "github.com/23technologies/gardener-extension-provider-hcloud/pkg/hcloud/apis/validation" @@ -72,3 +73,23 @@ func DecodeConfigFromCloudProfile(profile *v1beta1.CloudProfile) (*apis.CloudPro return cloudProfileConfig, nil } + +// DecodeMachineImageNameFromCloudProfile takes a list of machine images, and the desired image name and version. It tries +// to find the image with the given name and version in the desired cloud profile. If it cannot be found then an error +// is returned. +func DecodeMachineImageNameFromCloudProfile(cpConfig *apis.CloudProfileConfig, imageName, imageVersion string) (string, error) { + if cpConfig != nil { + for _, machineImage := range cpConfig.MachineImages { + if machineImage.Name != imageName { + continue + } + for _, version := range machineImage.Versions { + if imageVersion == version.Version { + return fmt.Sprintf("%s-%s", imageName, imageVersion), nil + } + } + } + } + + return "", fmt.Errorf("Could not find an image for name %q in version %q", imageName, imageVersion) +}