@@ -21,6 +21,8 @@ type VirtualClusterPolicyCreateConfig struct {
2121 mode string
2222 labels []string
2323 annotations []string
24+ namespaces []string
25+ overwrite bool
2426}
2527
2628func NewPolicyCreateCmd (appCtx * AppContext ) * cobra.Command {
@@ -45,6 +47,8 @@ func NewPolicyCreateCmd(appCtx *AppContext) *cobra.Command {
4547 cmd .Flags ().StringVar (& config .mode , "mode" , "shared" , "The allowed mode type of the policy" )
4648 cmd .Flags ().StringArrayVar (& config .labels , "labels" , []string {}, "Labels to add to the policy object (e.g. key=value)" )
4749 cmd .Flags ().StringArrayVar (& config .annotations , "annotations" , []string {}, "Annotations to add to the policy object (e.g. key=value)" )
50+ cmd .Flags ().StringSliceVar (& config .namespaces , "namespace" , []string {}, "The namespaces where to bind the policy" )
51+ cmd .Flags ().BoolVar (& config .overwrite , "overwrite" , false , "Overwrite namespace binding of existing policy" )
4852
4953 return cmd
5054}
@@ -56,8 +60,11 @@ func policyCreateAction(appCtx *AppContext, config *VirtualClusterPolicyCreateCo
5660 policyName := args [0 ]
5761
5862 _ , err := createPolicy (ctx , client , config , policyName )
63+ if err != nil {
64+ return err
65+ }
5966
60- return err
67+ return bindPolicyToNamespaces ( ctx , client , config , policyName )
6168 }
6269}
6370
@@ -75,7 +82,7 @@ func createNamespace(ctx context.Context, client client.Client, name, policyName
7582 return err
7683 }
7784
78- logrus .Infof (`Creating namespace [%s] ` , name )
85+ logrus .Infof (`Creating namespace '%s' ` , name )
7986
8087 if err := client .Create (ctx , ns ); err != nil {
8188 return err
@@ -86,7 +93,7 @@ func createNamespace(ctx context.Context, client client.Client, name, policyName
8693}
8794
8895func createPolicy (ctx context.Context , client client.Client , config * VirtualClusterPolicyCreateConfig , policyName string ) (* v1beta1.VirtualClusterPolicy , error ) {
89- logrus .Infof ("Creating policy [%s] " , policyName )
96+ logrus .Infof ("Creating policy '%s' " , policyName )
9097
9198 policy := & v1beta1.VirtualClusterPolicy {
9299 ObjectMeta : metav1.ObjectMeta {
@@ -108,8 +115,67 @@ func createPolicy(ctx context.Context, client client.Client, config *VirtualClus
108115 return nil , err
109116 }
110117
111- logrus .Infof ("Policy [%s] already exists" , policyName )
118+ logrus .Infof ("Policy '%s' already exists" , policyName )
112119 }
113120
114121 return policy , nil
115122}
123+
124+ func bindPolicyToNamespaces (ctx context.Context , client client.Client , config * VirtualClusterPolicyCreateConfig , policyName string ) error {
125+ var errs []error
126+
127+ for _ , namespace := range config .namespaces {
128+ var ns v1.Namespace
129+ if err := client .Get (ctx , types.NamespacedName {Name : namespace }, & ns ); err != nil {
130+ if apierrors .IsNotFound (err ) {
131+ logrus .Warnf (`Namespace '%s' not found, skipping` , namespace )
132+ } else {
133+ errs = append (errs , err )
134+ }
135+
136+ continue
137+ }
138+
139+ if ns .Labels == nil {
140+ ns .Labels = map [string ]string {}
141+ }
142+
143+ oldPolicy := ns .Labels [policy .PolicyNameLabelKey ]
144+
145+ // same policy found, no need to update
146+ if oldPolicy == policyName {
147+ logrus .Debugf (`Policy '%s' already bound to namespace '%s'` , policyName , namespace )
148+ continue
149+ }
150+
151+ // no old policy, safe to update
152+ if oldPolicy == "" {
153+ if err := client .Update (ctx , & ns ); err != nil {
154+ errs = append (errs , err )
155+ } else {
156+ logrus .Infof (`Added policy '%s' to namespace '%s'` , policyName , namespace )
157+ }
158+
159+ continue
160+ }
161+
162+ // different policy, warn or check for overwrite flag
163+ if oldPolicy != policyName {
164+ if config .overwrite {
165+ logrus .Infof (`Found policy '%s' bound to namespace '%s'. Overwriting it with '%s'` , oldPolicy , namespace , policyName )
166+
167+ ns .Labels [policy .PolicyNameLabelKey ] = policyName
168+
169+ if err := client .Update (ctx , & ns ); err != nil {
170+ errs = append (errs , err )
171+ } else {
172+ logrus .Infof (`Added policy '%s' to namespace '%s'` , policyName , namespace )
173+ }
174+ } else {
175+ logrus .Warnf (`Found policy '%s' bound to namespace '%s'. Skipping. To overwrite it use the --overwrite flag` , oldPolicy , namespace )
176+ }
177+ }
178+ }
179+
180+ return errors .Join (errs ... )
181+ }
0 commit comments