Merge pull request #2694 from lonelyCZ/pr-promote-factory
karmadactl promote uses factory to access cluster
This commit is contained in:
commit
052de02155
|
@ -33,7 +33,6 @@ import (
|
|||
"k8s.io/kubectl/pkg/util/templates"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
karmadaclientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
|
@ -295,18 +294,18 @@ func (g *CommandGetOptions) Run(f util.Factory, cmd *cobra.Command, args []strin
|
|||
return err
|
||||
}
|
||||
|
||||
clusterInfos, err := getClusterInKarmadaForClient(gclient)
|
||||
if err != nil {
|
||||
return fmt.Errorf("method getClusterInKarmadaForClient get cluster info in karmada failed, err is: %w", err)
|
||||
}
|
||||
|
||||
if err := g.getRBInKarmada(gclient); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(g.Clusters) <= 0 {
|
||||
for c := range clusterInfos {
|
||||
g.Clusters = append(g.Clusters, c)
|
||||
clusterList, err := gclient.ClusterV1alpha1().Clusters().List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list all member clusters in control plane, err: %w", err)
|
||||
}
|
||||
|
||||
for i := range clusterList.Items {
|
||||
g.Clusters = append(g.Clusters, clusterList.Items[i].Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -877,33 +876,6 @@ func shouldGetNewPrinterForMapping(printer printers.ResourcePrinter, lastMapping
|
|||
return printer == nil || lastMapping == nil || mapping == nil || mapping.Resource != lastMapping.Resource
|
||||
}
|
||||
|
||||
// ClusterInfo Information about the member in the karmada cluster.
|
||||
type ClusterInfo struct {
|
||||
KubeConfig string
|
||||
Context string
|
||||
|
||||
APIEndpoint string
|
||||
ClusterSyncMode clusterv1alpha1.ClusterSyncMode
|
||||
}
|
||||
|
||||
func getFactory(clusterName string, clusterInfos map[string]*ClusterInfo, namespace string) cmdutil.Factory {
|
||||
kubeConfigFlags := NewConfigFlags(true).WithDeprecatedPasswordFlag()
|
||||
// Build member cluster kubeConfigFlags
|
||||
kubeConfigFlags.APIServer = stringptr(clusterInfos[clusterName].APIEndpoint)
|
||||
|
||||
// Use kubeconfig to access member cluster
|
||||
kubeConfigFlags.KubeConfig = stringptr(clusterInfos[clusterName].KubeConfig)
|
||||
kubeConfigFlags.Context = stringptr(clusterInfos[clusterName].Context)
|
||||
kubeConfigFlags.usePersistentConfig = true
|
||||
|
||||
if namespace != "" {
|
||||
kubeConfigFlags.Namespace = stringptr(namespace)
|
||||
}
|
||||
|
||||
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)
|
||||
return cmdutil.NewFactory(matchVersionKubeConfigFlags)
|
||||
}
|
||||
|
||||
func (g *CommandGetOptions) transformRequests(req *rest.Request) {
|
||||
if !g.ServerPrint || !g.IsHumanReadablePrinter {
|
||||
return
|
||||
|
@ -961,44 +933,6 @@ func (g *CommandGetOptions) getRBInKarmada(gclient karmadaclientset.Interface) e
|
|||
return nil
|
||||
}
|
||||
|
||||
// getClusterInKarmadaForClient get cluster info in karmada cluster
|
||||
func getClusterInKarmadaForClient(gclient karmadaclientset.Interface) (map[string]*ClusterInfo, error) {
|
||||
clusterList, err := gclient.ClusterV1alpha1().Clusters().List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clusterInfos := make(map[string]*ClusterInfo, len(clusterList.Items))
|
||||
for i := range clusterList.Items {
|
||||
cluster := &ClusterInfo{
|
||||
APIEndpoint: clusterList.Items[i].Spec.APIEndpoint,
|
||||
ClusterSyncMode: clusterList.Items[i].Spec.SyncMode,
|
||||
}
|
||||
clusterInfos[clusterList.Items[i].GetName()] = cluster
|
||||
}
|
||||
return clusterInfos, nil
|
||||
}
|
||||
|
||||
// getClusterInKarmada get cluster info in karmada cluster
|
||||
func getClusterInKarmada(client *rest.Config, clusterInfos map[string]*ClusterInfo) error {
|
||||
clusterList := &clusterv1alpha1.ClusterList{}
|
||||
gClient, err := gclient.NewForConfig(client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = gClient.List(context.TODO(), clusterList); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range clusterList.Items {
|
||||
cluster := &ClusterInfo{
|
||||
APIEndpoint: clusterList.Items[i].Spec.APIEndpoint,
|
||||
ClusterSyncMode: clusterList.Items[i].Spec.SyncMode,
|
||||
}
|
||||
clusterInfos[clusterList.Items[i].GetName()] = cluster
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRBKey(gvk schema.GroupVersionKind, row metav1.TableRow, cluster string) string {
|
||||
resourceName, _ := row.Cells[0].(string)
|
||||
rbKey := names.GenerateBindingName(gvk.Kind, resourceName)
|
||||
|
|
|
@ -96,7 +96,7 @@ func NewKarmadaCtlCommand(cmdUse, parentCommand string) *cobra.Command {
|
|||
Message: "Advanced Commands:",
|
||||
Commands: []*cobra.Command{
|
||||
NewCmdApply(f, parentCommand, ioStreams),
|
||||
NewCmdPromote(karmadaConfig, parentCommand),
|
||||
NewCmdPromote(f, parentCommand),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
karmadaclientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/options"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter/defaultinterpreter/prune"
|
||||
"github.com/karmada-io/karmada/pkg/util/gclient"
|
||||
|
@ -55,7 +54,7 @@ var (
|
|||
)
|
||||
|
||||
// NewCmdPromote defines the `promote` command that promote resources from legacy clusters
|
||||
func NewCmdPromote(karmadaConfig KarmadaConfig, parentCommand string) *cobra.Command {
|
||||
func NewCmdPromote(f util.Factory, parentCommand string) *cobra.Command {
|
||||
opts := CommandPromoteOption{}
|
||||
opts.JSONYamlPrintFlags = genericclioptions.NewJSONYamlPrintFlags()
|
||||
|
||||
|
@ -67,13 +66,13 @@ func NewCmdPromote(karmadaConfig KarmadaConfig, parentCommand string) *cobra.Com
|
|||
SilenceUsage: true,
|
||||
DisableFlagsInUseLine: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := opts.Complete(args); err != nil {
|
||||
if err := opts.Complete(f, args); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := opts.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := RunPromote(karmadaConfig, opts, args); err != nil {
|
||||
if err := opts.Run(f, args); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -86,13 +85,14 @@ func NewCmdPromote(karmadaConfig KarmadaConfig, parentCommand string) *cobra.Com
|
|||
flag := cmd.Flags()
|
||||
opts.AddFlags(flag)
|
||||
|
||||
flag.StringVar(defaultConfigFlags.KubeConfig, "kubeconfig", *defaultConfigFlags.KubeConfig, "Path to the kubeconfig file to use for CLI requests.")
|
||||
flag.StringVar(defaultConfigFlags.Context, "karmada-context", *defaultConfigFlags.Context, "The name of the kubeconfig context to use")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// CommandPromoteOption holds all command options for promote
|
||||
type CommandPromoteOption struct {
|
||||
options.GlobalCommandOptions
|
||||
|
||||
// Cluster is the name of legacy cluster
|
||||
Cluster string
|
||||
|
||||
|
@ -121,11 +121,9 @@ type CommandPromoteOption struct {
|
|||
|
||||
// AddFlags adds flags to the specified FlagSet.
|
||||
func (o *CommandPromoteOption) AddFlags(flags *pflag.FlagSet) {
|
||||
o.GlobalCommandOptions.AddFlags(flags)
|
||||
|
||||
flags.StringVarP(&o.OutputFormat, "output", "o", "", "Output format. One of: json|yaml")
|
||||
|
||||
flags.StringVarP(&o.Namespace, "namespace", "n", "default", "-n=namespace or -n namespace")
|
||||
flags.StringVarP(&o.Namespace, "namespace", "n", o.Namespace, "If present, the namespace scope for this CLI request")
|
||||
flags.StringVarP(&o.Cluster, "cluster", "C", "", "the name of legacy cluster (eg -C=member1)")
|
||||
flags.StringVar(&o.ClusterContext, "cluster-context", "",
|
||||
"Context name of legacy cluster in kubeconfig. Only works when there are multiple contexts in the kubeconfig.")
|
||||
|
@ -135,7 +133,9 @@ func (o *CommandPromoteOption) AddFlags(flags *pflag.FlagSet) {
|
|||
}
|
||||
|
||||
// Complete ensures that options are valid and marshals them if necessary
|
||||
func (o *CommandPromoteOption) Complete(args []string) error {
|
||||
func (o *CommandPromoteOption) Complete(f util.Factory, args []string) error {
|
||||
var err error
|
||||
|
||||
if len(args) != 2 {
|
||||
return fmt.Errorf("incorrect command format, please use correct command format")
|
||||
}
|
||||
|
@ -159,6 +159,18 @@ func (o *CommandPromoteOption) Complete(args []string) error {
|
|||
}
|
||||
}
|
||||
|
||||
if o.Namespace == "" {
|
||||
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get namespace from Factory. error: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// If '--cluster-context' not specified, take the cluster name as the context.
|
||||
if len(o.ClusterContext) == 0 {
|
||||
o.ClusterContext = o.Cluster
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -172,81 +184,67 @@ func (o *CommandPromoteOption) Validate() error {
|
|||
return fmt.Errorf("output format is only one of json and yaml")
|
||||
}
|
||||
|
||||
// If '--cluster-context' not specified, take the cluster name as the context.
|
||||
if len(o.ClusterContext) == 0 {
|
||||
o.ClusterContext = o.Cluster
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunPromote promote resources from legacy clusters
|
||||
func RunPromote(karmadaConfig KarmadaConfig, opts CommandPromoteOption, args []string) error {
|
||||
// Get control plane karmada-apiserver client
|
||||
controlPlaneRestConfig, err := karmadaConfig.GetRestConfig(opts.KarmadaContext, opts.KubeConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get control plane rest config. context: %s, kubeconfig: %s, error: %v",
|
||||
opts.KarmadaContext, opts.KubeConfig, err)
|
||||
}
|
||||
// Run promote resources from legacy clusters
|
||||
func (o *CommandPromoteOption) Run(f util.Factory, args []string) error {
|
||||
var memberClusterFactory cmdutil.Factory
|
||||
var err error
|
||||
|
||||
clusterInfos := make(map[string]*ClusterInfo)
|
||||
|
||||
if err := getClusterInKarmada(controlPlaneRestConfig, clusterInfos); err != nil {
|
||||
return fmt.Errorf("failed to get cluster info in karmada control plane. err: %v", err)
|
||||
}
|
||||
|
||||
if _, exist := clusterInfos[opts.Cluster]; !exist {
|
||||
return fmt.Errorf("cluster(%s) does't exist in karmada control plane", opts.Cluster)
|
||||
}
|
||||
|
||||
var f cmdutil.Factory
|
||||
|
||||
if opts.ClusterKubeConfig != "" {
|
||||
if o.ClusterKubeConfig != "" {
|
||||
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
|
||||
kubeConfigFlags.KubeConfig = &opts.ClusterKubeConfig
|
||||
kubeConfigFlags.Context = &opts.ClusterContext
|
||||
kubeConfigFlags.KubeConfig = &o.ClusterKubeConfig
|
||||
kubeConfigFlags.Context = &o.ClusterContext
|
||||
|
||||
f = cmdutil.NewFactory(kubeConfigFlags)
|
||||
memberClusterFactory = cmdutil.NewFactory(kubeConfigFlags)
|
||||
} else {
|
||||
opts.setClusterProxyInfo(controlPlaneRestConfig, opts.Cluster, clusterInfos)
|
||||
f = getFactory(opts.Cluster, clusterInfos, "")
|
||||
memberClusterFactory, err = f.FactoryForMemberCluster(o.Cluster)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get Factory of the member cluster. err: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
objInfo, err := opts.getObjInfo(f, opts.Cluster, args)
|
||||
objInfo, err := o.getObjInfo(memberClusterFactory, o.Cluster, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get resource in cluster(%s). err: %v", opts.Cluster, err)
|
||||
return fmt.Errorf("failed to get resource in cluster(%s). err: %w", o.Cluster, err)
|
||||
}
|
||||
|
||||
obj := objInfo.Info.Object.(*unstructured.Unstructured)
|
||||
|
||||
opts.gvk = obj.GetObjectKind().GroupVersionKind()
|
||||
o.gvk = obj.GetObjectKind().GroupVersionKind()
|
||||
|
||||
controlPlaneRestConfig, err := f.ToRESTConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get control plane rest config. err: %w", err)
|
||||
}
|
||||
|
||||
mapper, err := restmapper.MapperProvider(controlPlaneRestConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create restmapper: %v", err)
|
||||
}
|
||||
|
||||
gvr, err := restmapper.GetGroupVersionResource(mapper, opts.gvk)
|
||||
gvr, err := restmapper.GetGroupVersionResource(mapper, o.gvk)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get gvr from %q: %v", opts.gvk, err)
|
||||
return fmt.Errorf("failed to get gvr from %q: %v", o.gvk, err)
|
||||
}
|
||||
|
||||
return promote(controlPlaneRestConfig, obj, gvr, opts)
|
||||
return o.promote(controlPlaneRestConfig, obj, gvr)
|
||||
}
|
||||
|
||||
func promote(controlPlaneRestConfig *rest.Config, obj *unstructured.Unstructured, gvr schema.GroupVersionResource, opts CommandPromoteOption) error {
|
||||
func (o *CommandPromoteOption) promote(controlPlaneRestConfig *rest.Config, obj *unstructured.Unstructured, gvr schema.GroupVersionResource) error {
|
||||
if err := preprocessResource(obj); err != nil {
|
||||
return fmt.Errorf("failed to preprocess resource %q(%s/%s) in control plane: %v", gvr, opts.Namespace, opts.name, err)
|
||||
return fmt.Errorf("failed to preprocess resource %q(%s/%s) in control plane: %v", gvr, o.Namespace, o.name, err)
|
||||
}
|
||||
|
||||
if opts.OutputFormat != "" {
|
||||
if o.OutputFormat != "" {
|
||||
// only print the resource template and Policy
|
||||
err := printObjectAndPolicy(obj, gvr, opts)
|
||||
err := o.printObjectAndPolicy(obj, gvr)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.DryRun {
|
||||
if o.DryRun {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -255,51 +253,51 @@ func promote(controlPlaneRestConfig *rest.Config, obj *unstructured.Unstructured
|
|||
karmadaClient := karmadaclientset.NewForConfigOrDie(controlPlaneRestConfig)
|
||||
|
||||
if len(obj.GetNamespace()) == 0 {
|
||||
_, err := controlPlaneDynamicClient.Resource(gvr).Get(context.TODO(), opts.name, metav1.GetOptions{})
|
||||
_, err := controlPlaneDynamicClient.Resource(gvr).Get(context.TODO(), o.name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
fmt.Printf("Resource %q(%s) already exist in karmada control plane, you can edit PropagationPolicy and OverridePolicy to propagate it\n",
|
||||
gvr, opts.name)
|
||||
gvr, o.name)
|
||||
return nil
|
||||
}
|
||||
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to get resource %q(%s) in control plane: %v", gvr, opts.name, err)
|
||||
return fmt.Errorf("failed to get resource %q(%s) in control plane: %v", gvr, o.name, err)
|
||||
}
|
||||
|
||||
_, err = controlPlaneDynamicClient.Resource(gvr).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create resource %q(%s) in control plane: %v", gvr, opts.name, err)
|
||||
return fmt.Errorf("failed to create resource %q(%s) in control plane: %v", gvr, o.name, err)
|
||||
}
|
||||
|
||||
err = createOrUpdateClusterPropagationPolicy(karmadaClient, gvr, opts)
|
||||
err = o.createClusterPropagationPolicy(karmadaClient, gvr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Resource %q(%s) is promoted successfully\n", gvr, opts.name)
|
||||
fmt.Printf("Resource %q(%s) is promoted successfully\n", gvr, o.name)
|
||||
} else {
|
||||
_, err := controlPlaneDynamicClient.Resource(gvr).Namespace(opts.Namespace).Get(context.TODO(), opts.name, metav1.GetOptions{})
|
||||
_, err := controlPlaneDynamicClient.Resource(gvr).Namespace(o.Namespace).Get(context.TODO(), o.name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
fmt.Printf("Resource %q(%s/%s) already exist in karmada control plane, you can edit PropagationPolicy and OverridePolicy to propagate it\n",
|
||||
gvr, opts.Namespace, opts.name)
|
||||
gvr, o.Namespace, o.name)
|
||||
return nil
|
||||
}
|
||||
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to get resource %q(%s/%s) in control plane: %v", gvr, opts.Namespace, opts.name, err)
|
||||
return fmt.Errorf("failed to get resource %q(%s/%s) in control plane: %v", gvr, o.Namespace, o.name, err)
|
||||
}
|
||||
|
||||
_, err = controlPlaneDynamicClient.Resource(gvr).Namespace(opts.Namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
_, err = controlPlaneDynamicClient.Resource(gvr).Namespace(o.Namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create resource %q(%s/%s) in control plane: %v", gvr, opts.Namespace, opts.name, err)
|
||||
return fmt.Errorf("failed to create resource %q(%s/%s) in control plane: %v", gvr, o.Namespace, o.name, err)
|
||||
}
|
||||
|
||||
err = createOrUpdatePropagationPolicy(karmadaClient, gvr, opts)
|
||||
err = o.createPropagationPolicy(karmadaClient, gvr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Resource %q(%s/%s) is promoted successfully\n", gvr, opts.Namespace, opts.name)
|
||||
fmt.Printf("Resource %q(%s/%s) is promoted successfully\n", gvr, o.Namespace, o.name)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -307,12 +305,11 @@ func promote(controlPlaneRestConfig *rest.Config, obj *unstructured.Unstructured
|
|||
|
||||
// getObjInfo get obj info in member cluster
|
||||
func (o *CommandPromoteOption) getObjInfo(f cmdutil.Factory, cluster string, args []string) (*Obj, error) {
|
||||
chunkSize := int64(500)
|
||||
r := f.NewBuilder().
|
||||
Unstructured().
|
||||
NamespaceParam(o.Namespace).
|
||||
FilenameParam(false, &o.FilenameOptions).
|
||||
RequestChunksOf(chunkSize).
|
||||
RequestChunksOf(500).
|
||||
ResourceTypeOrNameArgs(true, args...).
|
||||
ContinueOnError().
|
||||
Latest().
|
||||
|
@ -338,24 +335,9 @@ func (o *CommandPromoteOption) getObjInfo(f cmdutil.Factory, cluster string, arg
|
|||
return obj, nil
|
||||
}
|
||||
|
||||
// setClusterProxyInfo set proxy information of cluster
|
||||
func (o *CommandPromoteOption) setClusterProxyInfo(karmadaRestConfig *rest.Config, name string, clusterInfos map[string]*ClusterInfo) {
|
||||
clusterInfos[name].APIEndpoint = karmadaRestConfig.Host + fmt.Sprintf(proxyURL, name)
|
||||
clusterInfos[name].KubeConfig = o.KubeConfig
|
||||
clusterInfos[name].Context = o.KarmadaContext
|
||||
if clusterInfos[name].KubeConfig == "" {
|
||||
env := os.Getenv("KUBECONFIG")
|
||||
if env != "" {
|
||||
clusterInfos[name].KubeConfig = env
|
||||
} else {
|
||||
clusterInfos[name].KubeConfig = defaultKubeConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printObjectAndPolicy print the converted resource
|
||||
func printObjectAndPolicy(obj *unstructured.Unstructured, gvr schema.GroupVersionResource, opts CommandPromoteOption) error {
|
||||
printer, err := opts.Printer(nil, nil, false, false)
|
||||
func (o *CommandPromoteOption) printObjectAndPolicy(obj *unstructured.Unstructured, gvr schema.GroupVersionResource) error {
|
||||
printer, err := o.Printer(nil, nil, false, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize k8s printer. err: %v", err)
|
||||
}
|
||||
|
@ -365,12 +347,12 @@ func printObjectAndPolicy(obj *unstructured.Unstructured, gvr schema.GroupVersio
|
|||
}
|
||||
|
||||
if len(obj.GetNamespace()) == 0 {
|
||||
cpp := buildClusterPropagationPolicy(gvr, opts)
|
||||
cpp := buildClusterPropagationPolicy(o.name, o.Cluster, gvr, o.gvk)
|
||||
if err = printer.PrintObj(cpp, os.Stdout); err != nil {
|
||||
return fmt.Errorf("failed to print the ClusterPropagationPolicy. err: %v", err)
|
||||
}
|
||||
} else {
|
||||
pp := buildPropagationPolicy(gvr, opts)
|
||||
pp := buildPropagationPolicy(o.name, o.Namespace, o.Cluster, gvr, o.gvk)
|
||||
if err = printer.PrintObj(pp, os.Stdout); err != nil {
|
||||
return fmt.Errorf("failed to print the PropagationPolicy. err: %v", err)
|
||||
}
|
||||
|
@ -379,6 +361,44 @@ func printObjectAndPolicy(obj *unstructured.Unstructured, gvr schema.GroupVersio
|
|||
return nil
|
||||
}
|
||||
|
||||
// createPropagationPolicy create PropagationPolicy in karmada control plane
|
||||
func (o *CommandPromoteOption) createPropagationPolicy(karmadaClient *karmadaclientset.Clientset, gvr schema.GroupVersionResource) error {
|
||||
name := names.GeneratePolicyName(o.Namespace, o.name, o.gvk.String())
|
||||
|
||||
_, err := karmadaClient.PolicyV1alpha1().PropagationPolicies(o.Namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil && apierrors.IsNotFound(err) {
|
||||
pp := buildPropagationPolicy(o.name, o.Namespace, o.Cluster, gvr, o.gvk)
|
||||
_, err = karmadaClient.PolicyV1alpha1().PropagationPolicies(o.Namespace).Create(context.TODO(), pp, metav1.CreateOptions{})
|
||||
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get PropagationPolicy(%s/%s) in control plane: %v", o.Namespace, name, err)
|
||||
}
|
||||
|
||||
// PropagationPolicy already exists, not to create it
|
||||
return fmt.Errorf("the PropagationPolicy(%s/%s) already exist, please edit it to propagate resource", o.Namespace, name)
|
||||
}
|
||||
|
||||
// createClusterPropagationPolicy create ClusterPropagationPolicy in karmada control plane
|
||||
func (o *CommandPromoteOption) createClusterPropagationPolicy(karmadaClient *karmadaclientset.Clientset, gvr schema.GroupVersionResource) error {
|
||||
name := names.GeneratePolicyName("", o.name, o.gvk.String())
|
||||
|
||||
_, err := karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil && apierrors.IsNotFound(err) {
|
||||
cpp := buildClusterPropagationPolicy(o.name, o.Cluster, gvr, o.gvk)
|
||||
_, err = karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Create(context.TODO(), cpp, metav1.CreateOptions{})
|
||||
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get ClusterPropagationPolicy(%s) in control plane: %v", name, err)
|
||||
}
|
||||
|
||||
// ClusterPropagationPolicy already exists, not to create it
|
||||
return fmt.Errorf("the ClusterPropagationPolicy(%s) already exist, please edit it to propagate resource", name)
|
||||
}
|
||||
|
||||
// preprocessResource delete redundant fields to convert resource as template
|
||||
func preprocessResource(obj *unstructured.Unstructured) error {
|
||||
// remove fields that generated by kube-apiserver and no need(or can't) propagate to member clusters.
|
||||
|
@ -403,64 +423,26 @@ func addOverwriteAnnotation(obj *unstructured.Unstructured) {
|
|||
}
|
||||
}
|
||||
|
||||
// createOrUpdatePropagationPolicy create PropagationPolicy in karmada control plane
|
||||
func createOrUpdatePropagationPolicy(karmadaClient *karmadaclientset.Clientset, gvr schema.GroupVersionResource, opts CommandPromoteOption) error {
|
||||
name := names.GeneratePolicyName(opts.Namespace, opts.name, opts.gvk.String())
|
||||
|
||||
_, err := karmadaClient.PolicyV1alpha1().PropagationPolicies(opts.Namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil && apierrors.IsNotFound(err) {
|
||||
pp := buildPropagationPolicy(gvr, opts)
|
||||
_, err = karmadaClient.PolicyV1alpha1().PropagationPolicies(opts.Namespace).Create(context.TODO(), pp, metav1.CreateOptions{})
|
||||
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get PropagationPolicy(%s/%s) in control plane: %v", opts.Namespace, name, err)
|
||||
}
|
||||
|
||||
// PropagationPolicy already exists, not to create it
|
||||
return fmt.Errorf("the PropagationPolicy(%s/%s) already exist, please edit it to propagate resource", opts.Namespace, name)
|
||||
}
|
||||
|
||||
// createOrUpdateClusterPropagationPolicy create ClusterPropagationPolicy in karmada control plane
|
||||
func createOrUpdateClusterPropagationPolicy(karmadaClient *karmadaclientset.Clientset, gvr schema.GroupVersionResource, opts CommandPromoteOption) error {
|
||||
name := names.GeneratePolicyName("", opts.name, opts.gvk.String())
|
||||
|
||||
_, err := karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil && apierrors.IsNotFound(err) {
|
||||
cpp := buildClusterPropagationPolicy(gvr, opts)
|
||||
_, err = karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Create(context.TODO(), cpp, metav1.CreateOptions{})
|
||||
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get ClusterPropagationPolicy(%s) in control plane: %v", name, err)
|
||||
}
|
||||
|
||||
// ClusterPropagationPolicy already exists, not to create it
|
||||
return fmt.Errorf("the ClusterPropagationPolicy(%s) already exist, please edit it to propagate resource", name)
|
||||
}
|
||||
|
||||
// buildPropagationPolicy build PropagationPolicy according to resource and cluster
|
||||
func buildPropagationPolicy(gvr schema.GroupVersionResource, opts CommandPromoteOption) *policyv1alpha1.PropagationPolicy {
|
||||
name := names.GeneratePolicyName(opts.Namespace, opts.name, opts.gvk.String())
|
||||
func buildPropagationPolicy(resourceName, namespace, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.PropagationPolicy {
|
||||
policyName := names.GeneratePolicyName(namespace, resourceName, gvk.String())
|
||||
|
||||
pp := &policyv1alpha1.PropagationPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: opts.Namespace,
|
||||
Name: policyName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: policyv1alpha1.PropagationSpec{
|
||||
ResourceSelectors: []policyv1alpha1.ResourceSelector{
|
||||
{
|
||||
APIVersion: gvr.GroupVersion().String(),
|
||||
Kind: opts.gvk.Kind,
|
||||
Name: opts.name,
|
||||
Kind: gvk.Kind,
|
||||
Name: resourceName,
|
||||
},
|
||||
},
|
||||
Placement: policyv1alpha1.Placement{
|
||||
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
|
||||
ClusterNames: []string{opts.Cluster},
|
||||
ClusterNames: []string{cluster},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -470,24 +452,24 @@ func buildPropagationPolicy(gvr schema.GroupVersionResource, opts CommandPromote
|
|||
}
|
||||
|
||||
// buildClusterPropagationPolicy build ClusterPropagationPolicy according to resource and cluster
|
||||
func buildClusterPropagationPolicy(gvr schema.GroupVersionResource, opts CommandPromoteOption) *policyv1alpha1.ClusterPropagationPolicy {
|
||||
name := names.GeneratePolicyName("", opts.name, opts.gvk.String())
|
||||
func buildClusterPropagationPolicy(resourceName, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.ClusterPropagationPolicy {
|
||||
policyName := names.GeneratePolicyName("", resourceName, gvk.String())
|
||||
|
||||
cpp := &policyv1alpha1.ClusterPropagationPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Name: policyName,
|
||||
},
|
||||
Spec: policyv1alpha1.PropagationSpec{
|
||||
ResourceSelectors: []policyv1alpha1.ResourceSelector{
|
||||
{
|
||||
APIVersion: gvr.GroupVersion().String(),
|
||||
Kind: opts.gvk.Kind,
|
||||
Name: opts.name,
|
||||
Kind: gvk.Kind,
|
||||
Name: resourceName,
|
||||
},
|
||||
},
|
||||
Placement: policyv1alpha1.Placement{
|
||||
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
|
||||
ClusterNames: []string{opts.Cluster},
|
||||
ClusterNames: []string{cluster},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -33,14 +33,16 @@ import (
|
|||
)
|
||||
|
||||
var _ = ginkgo.Describe("Karmadactl promote testing", func() {
|
||||
var karmadaConfig karmadactl.KarmadaConfig
|
||||
var member1 string
|
||||
var member1Client kubernetes.Interface
|
||||
var f cmdutil.Factory
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
karmadaConfig = karmadactl.NewKarmadaConfig(clientcmd.NewDefaultPathOptions())
|
||||
member1 = "member1"
|
||||
member1Client = framework.GetClusterClient(member1)
|
||||
defaultConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag().WithDiscoveryBurst(300).WithDiscoveryQPS(50.0)
|
||||
defaultConfigFlags.Context = &karmadaContext
|
||||
f = cmdutil.NewFactory(defaultConfigFlags)
|
||||
})
|
||||
|
||||
ginkgo.Context("Test promoting namespaced resource: deployment", func() {
|
||||
|
@ -85,18 +87,15 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
|
|||
// Step 2, promote namespace used by the deployment from member1 to karmada
|
||||
ginkgo.By(fmt.Sprintf("Promoting namespace %s from member: %s to karmada control plane", deploymentNamespace, member1), func() {
|
||||
namespaceOpts = karmadactl.CommandPromoteOption{
|
||||
GlobalCommandOptions: options.GlobalCommandOptions{
|
||||
KarmadaContext: karmadaContext,
|
||||
},
|
||||
Cluster: member1,
|
||||
}
|
||||
args := []string{"namespace", deploymentNamespace}
|
||||
// init args: place namespace name to CommandPromoteOption.name
|
||||
err := namespaceOpts.Complete(args)
|
||||
err := namespaceOpts.Complete(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
// use karmadactl to promote a namespace from member1
|
||||
err = karmadactl.RunPromote(karmadaConfig, namespaceOpts, args)
|
||||
err = namespaceOpts.Run(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
framework.WaitNamespacePresentOnClusterByClient(kubeClient, deploymentNamespace)
|
||||
|
@ -105,19 +104,16 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
|
|||
// Step 3, promote deployment from cluster member1 to karmada
|
||||
ginkgo.By(fmt.Sprintf("Promoting deployment %s from member: %s to karmada", deploymentName, member1), func() {
|
||||
deploymentOpts = karmadactl.CommandPromoteOption{
|
||||
GlobalCommandOptions: options.GlobalCommandOptions{
|
||||
KarmadaContext: karmadaContext,
|
||||
},
|
||||
Namespace: deploymentNamespace,
|
||||
Cluster: member1,
|
||||
}
|
||||
args := []string{"deployment", deploymentName}
|
||||
// init args: place deployment name to CommandPromoteOption.name
|
||||
err := deploymentOpts.Complete(args)
|
||||
err := deploymentOpts.Complete(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
// use karmadactl to promote a deployment from member1
|
||||
err = karmadactl.RunPromote(karmadaConfig, deploymentOpts, args)
|
||||
err = deploymentOpts.Run(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
|
@ -196,35 +192,29 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
|
|||
// Step2, promote clusterrole and clusterrolebinding from member1
|
||||
ginkgo.By(fmt.Sprintf("Promoting clusterrole %s and clusterrolebindings %s from member to karmada", clusterRoleName, clusterRoleBindingName), func() {
|
||||
clusterRoleOpts = karmadactl.CommandPromoteOption{
|
||||
GlobalCommandOptions: options.GlobalCommandOptions{
|
||||
KarmadaContext: karmadaContext,
|
||||
},
|
||||
Cluster: member1,
|
||||
}
|
||||
|
||||
args := []string{"clusterrole", clusterRoleName}
|
||||
// init args: place clusterrole name to CommandPromoteOption.name
|
||||
err := clusterRoleOpts.Complete(args)
|
||||
err := clusterRoleOpts.Complete(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
// use karmadactl to promote clusterrole from member1
|
||||
err = karmadactl.RunPromote(karmadaConfig, clusterRoleOpts, args)
|
||||
err = clusterRoleOpts.Run(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
clusterRoleBindingOpts = karmadactl.CommandPromoteOption{
|
||||
GlobalCommandOptions: options.GlobalCommandOptions{
|
||||
KarmadaContext: karmadaContext,
|
||||
},
|
||||
Cluster: member1,
|
||||
}
|
||||
|
||||
args = []string{"clusterrolebinding", clusterRoleBindingName}
|
||||
// init args: place clusterrolebinding name to CommandPromoteOption.name
|
||||
err = clusterRoleBindingOpts.Complete(args)
|
||||
err = clusterRoleBindingOpts.Complete(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
// use karmadactl to promote clusterrolebinding from member1
|
||||
err = karmadactl.RunPromote(karmadaConfig, clusterRoleBindingOpts, args)
|
||||
err = clusterRoleBindingOpts.Run(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
|
@ -267,16 +257,13 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
|
|||
|
||||
ginkgo.By(fmt.Sprintf("Promoting namespace %s from member: %s to karmada control plane", serviceNamespace, member1), func() {
|
||||
opts := karmadactl.CommandPromoteOption{
|
||||
GlobalCommandOptions: options.GlobalCommandOptions{
|
||||
KarmadaContext: karmadaContext,
|
||||
},
|
||||
Cluster: member1,
|
||||
}
|
||||
args := []string{"namespace", serviceNamespace}
|
||||
err := opts.Complete(args)
|
||||
err := opts.Complete(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
err = karmadactl.RunPromote(karmadaConfig, opts, args)
|
||||
err = opts.Run(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
framework.WaitNamespacePresentOnClusterByClient(kubeClient, serviceNamespace)
|
||||
|
@ -284,17 +271,14 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
|
|||
|
||||
ginkgo.By(fmt.Sprintf("Promoting service %s from member: %s to karmada control plane", serviceName, member1), func() {
|
||||
opts := karmadactl.CommandPromoteOption{
|
||||
GlobalCommandOptions: options.GlobalCommandOptions{
|
||||
KarmadaContext: karmadaContext,
|
||||
},
|
||||
Namespace: serviceNamespace,
|
||||
Cluster: member1,
|
||||
}
|
||||
args := []string{"service", serviceName}
|
||||
err := opts.Complete(args)
|
||||
err := opts.Complete(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
|
||||
err = karmadactl.RunPromote(karmadaConfig, opts, args)
|
||||
err = opts.Run(f, args)
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue