Merge pull request #3494 from LronDC/master

Allow user decide whether to automatically generate Propagation-policy and its name when promote
This commit is contained in:
karmada-bot 2023-05-15 10:37:49 +08:00 committed by GitHub
commit 5e4e707779
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 40 deletions

View File

@ -114,6 +114,16 @@ type CommandPromoteOption struct {
// DryRun tells if run the command in dry-run mode, without making any server requests. // DryRun tells if run the command in dry-run mode, without making any server requests.
DryRun bool DryRun bool
// AutoCreatePolicy tells if the promote command should create the
// PropagationPolicy(or ClusterPropagationPolicy) by default.
// It default to true.
AutoCreatePolicy bool
// PolicyName is the name of the PropagationPolicy(or ClusterPropagationPolicy),
// It defaults to the promoting resource name with a random hash suffix.
// It will be ingnored if AutoCreatePolicy is false.
PolicyName string
resource.FilenameOptions resource.FilenameOptions
JSONYamlPrintFlags *genericclioptions.JSONYamlPrintFlags JSONYamlPrintFlags *genericclioptions.JSONYamlPrintFlags
@ -127,6 +137,10 @@ type CommandPromoteOption struct {
// AddFlags adds flags to the specified FlagSet. // AddFlags adds flags to the specified FlagSet.
func (o *CommandPromoteOption) AddFlags(flags *pflag.FlagSet) { func (o *CommandPromoteOption) AddFlags(flags *pflag.FlagSet) {
flags.BoolVar(&o.AutoCreatePolicy, "auto-create-policy", true,
"Automatically create a PropagationPolicy for namespace-scoped resources or create a ClusterPropagationPolicy for cluster-scoped resources.")
flags.StringVar(&o.PolicyName, "policy-name", "",
"The name of the PropagationPolicy(or ClusterPropagationPolicy) that is automatically created after promotion. If not specified, the name will be the resource name with a hash suffix that is generated by resource metadata.")
flags.StringVarP(&o.OutputFormat, "output", "o", "", "Output format. One of: json|yaml") flags.StringVarP(&o.OutputFormat, "output", "o", "", "Output format. One of: json|yaml")
flags.StringVarP(&o.Namespace, "namespace", "n", o.Namespace, "If present, the namespace scope for this CLI request") flags.StringVarP(&o.Namespace, "namespace", "n", o.Namespace, "If present, the namespace scope for this CLI request")
@ -275,9 +289,11 @@ func (o *CommandPromoteOption) promote(controlPlaneRestConfig *rest.Config, obj
return fmt.Errorf("failed to create resource %q(%s) in control plane: %v", gvr, o.name, err) return fmt.Errorf("failed to create resource %q(%s) in control plane: %v", gvr, o.name, err)
} }
err = o.createClusterPropagationPolicy(karmadaClient, gvr) if o.AutoCreatePolicy {
if err != nil { err = o.createClusterPropagationPolicy(karmadaClient, gvr)
return err if err != nil {
return err
}
} }
fmt.Printf("Resource %q(%s) is promoted successfully\n", gvr, o.name) fmt.Printf("Resource %q(%s) is promoted successfully\n", gvr, o.name)
@ -298,9 +314,11 @@ func (o *CommandPromoteOption) promote(controlPlaneRestConfig *rest.Config, obj
return fmt.Errorf("failed to create resource %q(%s/%s) in control plane: %v", gvr, o.Namespace, o.name, err) return fmt.Errorf("failed to create resource %q(%s/%s) in control plane: %v", gvr, o.Namespace, o.name, err)
} }
err = o.createPropagationPolicy(karmadaClient, gvr) if o.AutoCreatePolicy {
if err != nil { err = o.createPropagationPolicy(karmadaClient, gvr)
return err if err != nil {
return err
}
} }
fmt.Printf("Resource %q(%s/%s) is promoted successfully\n", gvr, o.Namespace, o.name) fmt.Printf("Resource %q(%s/%s) is promoted successfully\n", gvr, o.Namespace, o.name)
@ -351,16 +369,23 @@ func (o *CommandPromoteOption) printObjectAndPolicy(obj *unstructured.Unstructur
if err = printer.PrintObj(obj, os.Stdout); err != nil { if err = printer.PrintObj(obj, os.Stdout); err != nil {
return fmt.Errorf("failed to print the resource template. err: %v", err) return fmt.Errorf("failed to print the resource template. err: %v", err)
} }
if o.AutoCreatePolicy {
if len(obj.GetNamespace()) == 0 { var policyName string
cpp := buildClusterPropagationPolicy(o.name, o.Cluster, gvr, o.gvk) if o.PolicyName == "" {
if err = printer.PrintObj(cpp, os.Stdout); err != nil { policyName = names.GeneratePolicyName(o.Namespace, o.name, o.gvk.String())
return fmt.Errorf("failed to print the ClusterPropagationPolicy. err: %v", err) } else {
policyName = o.PolicyName
} }
} else { if len(obj.GetNamespace()) == 0 {
pp := buildPropagationPolicy(o.name, o.Namespace, o.Cluster, gvr, o.gvk) cpp := buildClusterPropagationPolicy(o.name, policyName, o.Cluster, gvr, o.gvk)
if err = printer.PrintObj(pp, os.Stdout); err != nil { if err = printer.PrintObj(cpp, os.Stdout); err != nil {
return fmt.Errorf("failed to print the PropagationPolicy. err: %v", err) return fmt.Errorf("failed to print the ClusterPropagationPolicy. err: %v", err)
}
} else {
pp := buildPropagationPolicy(o.name, policyName, 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)
}
} }
} }
@ -369,40 +394,50 @@ func (o *CommandPromoteOption) printObjectAndPolicy(obj *unstructured.Unstructur
// createPropagationPolicy create PropagationPolicy in karmada control plane // createPropagationPolicy create PropagationPolicy in karmada control plane
func (o *CommandPromoteOption) createPropagationPolicy(karmadaClient *karmadaclientset.Clientset, gvr schema.GroupVersionResource) error { func (o *CommandPromoteOption) createPropagationPolicy(karmadaClient *karmadaclientset.Clientset, gvr schema.GroupVersionResource) error {
name := names.GeneratePolicyName(o.Namespace, o.name, o.gvk.String()) var policyName string
if o.PolicyName == "" {
policyName = names.GeneratePolicyName(o.Namespace, o.name, o.gvk.String())
} else {
policyName = o.PolicyName
}
_, err := karmadaClient.PolicyV1alpha1().PropagationPolicies(o.Namespace).Get(context.TODO(), name, metav1.GetOptions{}) _, err := karmadaClient.PolicyV1alpha1().PropagationPolicies(o.Namespace).Get(context.TODO(), policyName, metav1.GetOptions{})
if err != nil && apierrors.IsNotFound(err) { if err != nil && apierrors.IsNotFound(err) {
pp := buildPropagationPolicy(o.name, o.Namespace, o.Cluster, gvr, o.gvk) pp := buildPropagationPolicy(o.name, policyName, o.Namespace, o.Cluster, gvr, o.gvk)
_, err = karmadaClient.PolicyV1alpha1().PropagationPolicies(o.Namespace).Create(context.TODO(), pp, metav1.CreateOptions{}) _, err = karmadaClient.PolicyV1alpha1().PropagationPolicies(o.Namespace).Create(context.TODO(), pp, metav1.CreateOptions{})
return err return err
} }
if err != nil { if err != nil {
return fmt.Errorf("failed to get PropagationPolicy(%s/%s) in control plane: %v", o.Namespace, name, err) return fmt.Errorf("failed to get PropagationPolicy(%s/%s) in control plane: %v", o.Namespace, policyName, err)
} }
// PropagationPolicy already exists, not to create it // 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) return fmt.Errorf("the PropagationPolicy(%s/%s) already exist, please edit it to propagate resource", o.Namespace, policyName)
} }
// createClusterPropagationPolicy create ClusterPropagationPolicy in karmada control plane // createClusterPropagationPolicy create ClusterPropagationPolicy in karmada control plane
func (o *CommandPromoteOption) createClusterPropagationPolicy(karmadaClient *karmadaclientset.Clientset, gvr schema.GroupVersionResource) error { func (o *CommandPromoteOption) createClusterPropagationPolicy(karmadaClient *karmadaclientset.Clientset, gvr schema.GroupVersionResource) error {
name := names.GeneratePolicyName("", o.name, o.gvk.String()) var policyName string
if o.PolicyName == "" {
policyName = names.GeneratePolicyName("", o.name, o.gvk.String())
} else {
policyName = o.PolicyName
}
_, err := karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), name, metav1.GetOptions{}) _, err := karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), policyName, metav1.GetOptions{})
if err != nil && apierrors.IsNotFound(err) { if err != nil && apierrors.IsNotFound(err) {
cpp := buildClusterPropagationPolicy(o.name, o.Cluster, gvr, o.gvk) cpp := buildClusterPropagationPolicy(o.name, policyName, o.Cluster, gvr, o.gvk)
_, err = karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Create(context.TODO(), cpp, metav1.CreateOptions{}) _, err = karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Create(context.TODO(), cpp, metav1.CreateOptions{})
return err return err
} }
if err != nil { if err != nil {
return fmt.Errorf("failed to get ClusterPropagationPolicy(%s) in control plane: %v", name, err) return fmt.Errorf("failed to get ClusterPropagationPolicy(%s) in control plane: %v", policyName, err)
} }
// ClusterPropagationPolicy already exists, not to create it // ClusterPropagationPolicy already exists, not to create it
return fmt.Errorf("the ClusterPropagationPolicy(%s) already exist, please edit it to propagate resource", name) return fmt.Errorf("the ClusterPropagationPolicy(%s) already exist, please edit it to propagate resource", policyName)
} }
// preprocessResource delete redundant fields to convert resource as template // preprocessResource delete redundant fields to convert resource as template
@ -430,9 +465,7 @@ func addOverwriteAnnotation(obj *unstructured.Unstructured) {
} }
// buildPropagationPolicy build PropagationPolicy according to resource and cluster // buildPropagationPolicy build PropagationPolicy according to resource and cluster
func buildPropagationPolicy(resourceName, namespace, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.PropagationPolicy { func buildPropagationPolicy(resourceName, policyName, namespace, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.PropagationPolicy {
policyName := names.GeneratePolicyName(namespace, resourceName, gvk.String())
pp := &policyv1alpha1.PropagationPolicy{ pp := &policyv1alpha1.PropagationPolicy{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: policyName, Name: policyName,
@ -453,14 +486,11 @@ func buildPropagationPolicy(resourceName, namespace, cluster string, gvr schema.
}, },
}, },
} }
return pp return pp
} }
// buildClusterPropagationPolicy build ClusterPropagationPolicy according to resource and cluster // buildClusterPropagationPolicy build ClusterPropagationPolicy according to resource and cluster
func buildClusterPropagationPolicy(resourceName, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.ClusterPropagationPolicy { func buildClusterPropagationPolicy(resourceName, policyName, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.ClusterPropagationPolicy {
policyName := names.GeneratePolicyName("", resourceName, gvk.String())
cpp := &policyv1alpha1.ClusterPropagationPolicy{ cpp := &policyv1alpha1.ClusterPropagationPolicy{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: policyName, Name: policyName,

View File

@ -90,7 +90,8 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
// Step 2, promote namespace used by the deployment from member1 to karmada // 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() { ginkgo.By(fmt.Sprintf("Promoting namespace %s from member: %s to karmada control plane", deploymentNamespace, member1), func() {
namespaceOpts = promote.CommandPromoteOption{ namespaceOpts = promote.CommandPromoteOption{
Cluster: member1, Cluster: member1,
AutoCreatePolicy: true,
} }
args := []string{"namespace", deploymentNamespace} args := []string{"namespace", deploymentNamespace}
// init args: place namespace name to CommandPromoteOption.name // init args: place namespace name to CommandPromoteOption.name
@ -107,8 +108,9 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
// Step 3, promote deployment from cluster member1 to karmada // Step 3, promote deployment from cluster member1 to karmada
ginkgo.By(fmt.Sprintf("Promoting deployment %s from member: %s to karmada", deploymentName, member1), func() { ginkgo.By(fmt.Sprintf("Promoting deployment %s from member: %s to karmada", deploymentName, member1), func() {
deploymentOpts = promote.CommandPromoteOption{ deploymentOpts = promote.CommandPromoteOption{
Namespace: deploymentNamespace, Namespace: deploymentNamespace,
Cluster: member1, Cluster: member1,
AutoCreatePolicy: true,
} }
args := []string{"deployment", deploymentName} args := []string{"deployment", deploymentName}
// init args: place deployment name to CommandPromoteOption.name // init args: place deployment name to CommandPromoteOption.name
@ -195,7 +197,8 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
// Step2, promote clusterrole and clusterrolebinding from member1 // Step2, promote clusterrole and clusterrolebinding from member1
ginkgo.By(fmt.Sprintf("Promoting clusterrole %s and clusterrolebindings %s from member to karmada", clusterRoleName, clusterRoleBindingName), func() { ginkgo.By(fmt.Sprintf("Promoting clusterrole %s and clusterrolebindings %s from member to karmada", clusterRoleName, clusterRoleBindingName), func() {
clusterRoleOpts = promote.CommandPromoteOption{ clusterRoleOpts = promote.CommandPromoteOption{
Cluster: member1, Cluster: member1,
AutoCreatePolicy: true,
} }
args := []string{"clusterrole", clusterRoleName} args := []string{"clusterrole", clusterRoleName}
@ -208,7 +211,8 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
gomega.Expect(err).ShouldNot(gomega.HaveOccurred()) gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
clusterRoleBindingOpts = promote.CommandPromoteOption{ clusterRoleBindingOpts = promote.CommandPromoteOption{
Cluster: member1, Cluster: member1,
AutoCreatePolicy: true,
} }
args = []string{"clusterrolebinding", clusterRoleBindingName} args = []string{"clusterrolebinding", clusterRoleBindingName}
@ -260,7 +264,8 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
ginkgo.By(fmt.Sprintf("Promoting namespace %s from member: %s to karmada control plane", serviceNamespace, member1), func() { ginkgo.By(fmt.Sprintf("Promoting namespace %s from member: %s to karmada control plane", serviceNamespace, member1), func() {
opts := promote.CommandPromoteOption{ opts := promote.CommandPromoteOption{
Cluster: member1, Cluster: member1,
AutoCreatePolicy: true,
} }
args := []string{"namespace", serviceNamespace} args := []string{"namespace", serviceNamespace}
err := opts.Complete(f, args) err := opts.Complete(f, args)
@ -274,8 +279,9 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
ginkgo.By(fmt.Sprintf("Promoting service %s from member: %s to karmada control plane", serviceName, member1), func() { ginkgo.By(fmt.Sprintf("Promoting service %s from member: %s to karmada control plane", serviceName, member1), func() {
opts := promote.CommandPromoteOption{ opts := promote.CommandPromoteOption{
Namespace: serviceNamespace, Namespace: serviceNamespace,
Cluster: member1, Cluster: member1,
AutoCreatePolicy: true,
} }
args := []string{"service", serviceName} args := []string{"service", serviceName}
err := opts.Complete(f, args) err := opts.Complete(f, args)