diff --git a/deploy/crd/operatingsystemmanager.k8c.io_operatingsystemconfigs.yaml b/deploy/crd/operatingsystemmanager.k8c.io_operatingsystemconfigs.yaml index 79db2bf6..16a17b73 100644 --- a/deploy/crd/operatingsystemmanager.k8c.io_operatingsystemconfigs.yaml +++ b/deploy/crd/operatingsystemmanager.k8c.io_operatingsystemconfigs.yaml @@ -178,6 +178,7 @@ spec: - aws - azure - digitalocean + - edge - gce - hetzner - kubevirt diff --git a/deploy/crd/operatingsystemmanager.k8c.io_operatingsystemprofiles.yaml b/deploy/crd/operatingsystemmanager.k8c.io_operatingsystemprofiles.yaml index 05037ca6..fb4641e2 100644 --- a/deploy/crd/operatingsystemmanager.k8c.io_operatingsystemprofiles.yaml +++ b/deploy/crd/operatingsystemmanager.k8c.io_operatingsystemprofiles.yaml @@ -469,6 +469,7 @@ spec: - aws - azure - digitalocean + - edge - gce - hetzner - kubevirt diff --git a/pkg/cloudprovider/cloudprovider.go b/pkg/cloudprovider/cloudprovider.go index ca91f1bb..b02f8406 100644 --- a/pkg/cloudprovider/cloudprovider.go +++ b/pkg/cloudprovider/cloudprovider.go @@ -51,7 +51,7 @@ func GetCloudConfig(pconfig providerconfigtypes.Config, kubeletVersion string) ( case osmv1alpha1.CloudProviderAlibaba, osmv1alpha1.CloudProviderAnexia, osmv1alpha1.CloudProviderDigitalocean, osmv1alpha1.CloudProviderHetzner, osmv1alpha1.CloudProviderLinode, osmv1alpha1.CloudProviderEquinixMetal, osmv1alpha1.CloudProviderScaleway, osmv1alpha1.CloudProviderNutanix, osmv1alpha1.CloudProviderVMwareCloudDirector, - osmv1alpha1.CloudProviderOpenNebula: + osmv1alpha1.CloudProviderOpenNebula, osmv1alpha1.CloudProviderEdge: return "", nil } diff --git a/pkg/controllers/osc/osc_controller.go b/pkg/controllers/osc/osc_controller.go index 7af936d6..36ff5607 100644 --- a/pkg/controllers/osc/osc_controller.go +++ b/pkg/controllers/osc/osc_controller.go @@ -34,6 +34,7 @@ import ( osmv1alpha1 "k8c.io/operating-system-manager/pkg/crd/osm/v1alpha1" "k8c.io/operating-system-manager/pkg/generator" kuberneteshelper "k8c.io/operating-system-manager/pkg/kubernetes" + "k8s.io/client-go/tools/clientcmd/api" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,13 @@ func (r *Reconciler) reconcileOperatingSystemConfigs(ctx context.Context, md *cl r.containerRuntimeConfig, r.kubeletFeatureGates, ) + + if osc.Spec.CloudProvider.Name == "edge" { + if err := r.generateEdgeScript(ctx, md, token, bootstrapKubeconfig); err != nil { + return fmt.Errorf("failed to generate edge provider bootstrap script: %w", err) + } + } + if err != nil { return fmt.Errorf("failed to generate %s osc: %w", oscName, err) } @@ -458,6 +466,37 @@ func (r *Reconciler) checkOSP(ctx context.Context, md *clusterv1alpha1.MachineDe return err } +func (r *Reconciler) generateEdgeScript(ctx context.Context, md *clusterv1alpha1.MachineDeployment, token string, config *api.Config) error { + var clusterName string + for key := range config.Clusters { + clusterName = key + break + } + + serverURL := config.Clusters[clusterName].Server + bootstrapSecretName := fmt.Sprintf("%s-%s-bootstrap-config", md.Name, md.Namespace) + script := fmt.Sprintf("curl -s -k -v --header 'Authorization: Bearer %s' %s/api/v1/namespaces/cloud-init-settings/secrets/%s | jq '.data[\"cloud-config\"]' -r| base64 -d > /etc/cloud/cloud.cfg.d/%s.cfg \ncloud-init --file /etc/cloud/cloud.cfg.d/%s.cfg init\n", + token, serverURL, bootstrapSecretName, bootstrapSecretName, bootstrapSecretName) + + scriptSecretName := fmt.Sprintf("edge-provider-script-%s-%s", md.Name, md.Namespace) + secret := &corev1.Secret{} + if err := r.workerClient.Get(ctx, types.NamespacedName{Name: scriptSecretName, Namespace: bootstrap.CloudInitNamespace}, secret); err != nil { + if !kerrors.IsNotFound(err) { + return fmt.Errorf("failed to get %s secret in namespace %s: %w", scriptSecretName, bootstrap.CloudInitNamespace, err) + } + } + + if secret.Data == nil { + secret.Data = map[string][]byte{} + } + + secret.Name = scriptSecretName + secret.Namespace = bootstrap.CloudInitNamespace + secret.Data["fetch-bootstrap-script"] = []byte(script) + + return r.workerClient.Create(ctx, secret) +} + // filterMachineDeploymentPredicate will filter machine deployments based on the presence of OSP annotation func filterMachineDeploymentPredicate() predicate.Predicate { return predicate.NewPredicateFuncs(func(o ctrlruntimeclient.Object) bool { diff --git a/pkg/crd/osm/v1alpha1/common_types.go b/pkg/crd/osm/v1alpha1/common_types.go index 617e8efd..2e9c0310 100644 --- a/pkg/crd/osm/v1alpha1/common_types.go +++ b/pkg/crd/osm/v1alpha1/common_types.go @@ -34,7 +34,7 @@ const ( ) // CloudProvider represents supported cloud provider. -// +kubebuilder:validation:Enum=aws;azure;digitalocean;gce;hetzner;kubevirt;linode;nutanix;openstack;equinixmetal;vsphere;fake;alibaba;anexia;scaleway;baremetal;external;vmware-cloud-director;opennebula +// +kubebuilder:validation:Enum=aws;azure;digitalocean;edge;gce;hetzner;kubevirt;linode;nutanix;openstack;equinixmetal;vsphere;fake;alibaba;anexia;scaleway;baremetal;external;vmware-cloud-director;opennebula type CloudProvider string const ( @@ -44,6 +44,7 @@ const ( CloudProviderAzure CloudProvider = "azure" CloudProviderBaremetal CloudProvider = "baremetal" CloudProviderDigitalocean CloudProvider = "digitalocean" + CloudProviderEdge CloudProvider = "edge" CloudProviderEquinixMetal CloudProvider = "equinixmetal" CloudProviderExternal CloudProvider = "external" CloudProviderFake CloudProvider = "fake" @@ -54,9 +55,9 @@ const ( CloudProviderNutanix CloudProvider = "nutanix" CloudProviderOpenNebula CloudProvider = "opennebula" CloudProviderOpenstack CloudProvider = "openstack" - CloudProviderVsphere CloudProvider = "vsphere" - CloudProviderVMwareCloudDirector CloudProvider = "vmware-cloud-director" CloudProviderScaleway CloudProvider = "scaleway" + CloudProviderVMwareCloudDirector CloudProvider = "vmware-cloud-director" + CloudProviderVsphere CloudProvider = "vsphere" ) // ContainerRuntime represents supported container runtime