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 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
JSONYamlPrintFlags *genericclioptions.JSONYamlPrintFlags
@ -127,6 +137,10 @@ type CommandPromoteOption struct {
// AddFlags adds flags to the specified 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.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)
}
err = o.createClusterPropagationPolicy(karmadaClient, gvr)
if err != nil {
return err
if o.AutoCreatePolicy {
err = o.createClusterPropagationPolicy(karmadaClient, gvr)
if err != nil {
return err
}
}
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)
}
err = o.createPropagationPolicy(karmadaClient, gvr)
if err != nil {
return err
if o.AutoCreatePolicy {
err = o.createPropagationPolicy(karmadaClient, gvr)
if err != nil {
return err
}
}
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 {
return fmt.Errorf("failed to print the resource template. err: %v", err)
}
if len(obj.GetNamespace()) == 0 {
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)
if o.AutoCreatePolicy {
var policyName string
if o.PolicyName == "" {
policyName = names.GeneratePolicyName(o.Namespace, o.name, o.gvk.String())
} else {
policyName = o.PolicyName
}
} else {
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)
if len(obj.GetNamespace()) == 0 {
cpp := buildClusterPropagationPolicy(o.name, policyName, 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(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
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) {
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{})
return err
}
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
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
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) {
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{})
return err
}
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
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
@ -430,9 +465,7 @@ func addOverwriteAnnotation(obj *unstructured.Unstructured) {
}
// buildPropagationPolicy build PropagationPolicy according to resource and cluster
func buildPropagationPolicy(resourceName, namespace, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.PropagationPolicy {
policyName := names.GeneratePolicyName(namespace, resourceName, gvk.String())
func buildPropagationPolicy(resourceName, policyName, namespace, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.PropagationPolicy {
pp := &policyv1alpha1.PropagationPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: policyName,
@ -453,14 +486,11 @@ func buildPropagationPolicy(resourceName, namespace, cluster string, gvr schema.
},
},
}
return pp
}
// buildClusterPropagationPolicy build ClusterPropagationPolicy according to resource and cluster
func buildClusterPropagationPolicy(resourceName, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.ClusterPropagationPolicy {
policyName := names.GeneratePolicyName("", resourceName, gvk.String())
func buildClusterPropagationPolicy(resourceName, policyName, cluster string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind) *policyv1alpha1.ClusterPropagationPolicy {
cpp := &policyv1alpha1.ClusterPropagationPolicy{
ObjectMeta: metav1.ObjectMeta{
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
ginkgo.By(fmt.Sprintf("Promoting namespace %s from member: %s to karmada control plane", deploymentNamespace, member1), func() {
namespaceOpts = promote.CommandPromoteOption{
Cluster: member1,
Cluster: member1,
AutoCreatePolicy: true,
}
args := []string{"namespace", deploymentNamespace}
// 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
ginkgo.By(fmt.Sprintf("Promoting deployment %s from member: %s to karmada", deploymentName, member1), func() {
deploymentOpts = promote.CommandPromoteOption{
Namespace: deploymentNamespace,
Cluster: member1,
Namespace: deploymentNamespace,
Cluster: member1,
AutoCreatePolicy: true,
}
args := []string{"deployment", deploymentName}
// 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
ginkgo.By(fmt.Sprintf("Promoting clusterrole %s and clusterrolebindings %s from member to karmada", clusterRoleName, clusterRoleBindingName), func() {
clusterRoleOpts = promote.CommandPromoteOption{
Cluster: member1,
Cluster: member1,
AutoCreatePolicy: true,
}
args := []string{"clusterrole", clusterRoleName}
@ -208,7 +211,8 @@ var _ = ginkgo.Describe("Karmadactl promote testing", func() {
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
clusterRoleBindingOpts = promote.CommandPromoteOption{
Cluster: member1,
Cluster: member1,
AutoCreatePolicy: true,
}
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() {
opts := promote.CommandPromoteOption{
Cluster: member1,
Cluster: member1,
AutoCreatePolicy: true,
}
args := []string{"namespace", serviceNamespace}
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() {
opts := promote.CommandPromoteOption{
Namespace: serviceNamespace,
Cluster: member1,
Namespace: serviceNamespace,
Cluster: member1,
AutoCreatePolicy: true,
}
args := []string{"service", serviceName}
err := opts.Complete(f, args)