package init import ( "context" "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" "k8s.io/utils/strings/slices" cmdinit "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/kubernetes" "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils" ) // CommandAddonsEnableOption options for addons list. type CommandAddonsEnableOption struct { GlobalCommandOptions KarmadaSearchImage string KarmadaSearchReplicas int32 KarmadaDeschedulerImage string KarmadaDeschedulerReplicas int32 KarmadaSchedulerEstimatorImage string KarmadaEstimatorReplicas int32 KarmadaKubeClientSet *kubernetes.Clientset WaitPodReadyTimeout int WaitAPIServiceReadyTimeout int MemberKubeConfig string MemberContext string } // Complete the conditions required to be able to run enable. func (o *CommandAddonsEnableOption) Complete() error { err := o.GlobalCommandOptions.Complete() if err != nil { return err } o.KarmadaKubeClientSet, err = utils.NewClientSet(o.KarmadaRestConfig) if err != nil { return err } return nil } // Validate Check that there are enough conditions to run addon enable. func (o *CommandAddonsEnableOption) Validate(args []string) error { err := validAddonNames(args) if err != nil { return err } secretClient := o.KubeClientSet.CoreV1().Secrets(o.Namespace) _, err = secretClient.Get(context.TODO(), cmdinit.KubeConfigSecretAndMountName, metav1.GetOptions{}) if err != nil { if apierrors.IsNotFound(err) { return fmt.Errorf("secrets `kubeconfig` is not found in namespace %s, please execute karmadactl init to deploy karmada first", o.Namespace) } } if o.Cluster == "" { if slices.Contains(args, EstimatorResourceName) { return fmt.Errorf("member cluster is needed when enable karmada-scheduler-estimator,use `--cluster=member --member-kubeconfig /root/.kube/config --member-context member1` to enable karmada-scheduler-estimator") } } else { if !slices.Contains(args, EstimatorResourceName) && !slices.Contains(args, "all") { return fmt.Errorf("cluster is needed only when enable karmada-scheduler-estimator or enable all") } if o.MemberKubeConfig == "" { return fmt.Errorf("member config is needed when enable karmada-scheduler-estimator,use `--cluster=member --member-kubeconfig /root/.kube/member.config --member-context member1` to enable karmada-scheduler-estimator") } // Check member kubeconfig and context is valid memberConfig, err := utils.RestConfig(o.MemberContext, o.MemberKubeConfig) if err != nil { return fmt.Errorf("failed to get member cluster config. error: %v", err) } memberKubeClient := kubernetes.NewForConfigOrDie(memberConfig) _, err = memberKubeClient.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) if err != nil { return fmt.Errorf("failed to get nodes from cluster %s with member-kubeconfig and member-context. error: %v, Please check the Role or ClusterRole of the serviceAccount in your member-kubeconfig", o.Cluster, err) } _, err = memberKubeClient.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{}) if err != nil { return fmt.Errorf("failed to get pods from cluster %s with member-kubeconfig and member-context. error: %v, Please check the Role or ClusterRole of the serviceAccount in your member-kubeconfig", o.Cluster, err) } } return nil } // Run start enable Karmada addons func (o *CommandAddonsEnableOption) Run(args []string) error { var enableAddons = map[string]*Addon{} // collect enabled addons for _, item := range args { if item == "all" { enableAddons = Addons break } if addon := Addons[item]; addon != nil { enableAddons[item] = addon } } // enable addons for name, addon := range enableAddons { klog.Infof("Start to enable addon %s", name) if err := addon.Enable(o); err != nil { klog.Errorf("Install addon %s failed", name) return err } klog.Infof("Successfully enable addon %s", name) } return nil } // validAddonNames valid whether addon names is supported now func validAddonNames(addonNames []string) error { if len(addonNames) == 0 { return fmt.Errorf("addonNames must be not be null") } for _, addonName := range addonNames { if addonName == "all" { continue } _, ok := Addons[addonName] if !ok { return fmt.Errorf("addon %s is not be supported now", addonName) } } return nil }