Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cli/cmds/cluster_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func createAction(appCtx *AppContext, config *CreateConfig) func(cmd *cobra.Comm
}
}

logrus.Infof("Creating cluster [%s] in namespace [%s]", name, namespace)
logrus.Infof("Creating cluster '%s' in namespace '%s'", name, namespace)

cluster := newCluster(name, namespace, config)

Expand All @@ -138,7 +138,7 @@ func createAction(appCtx *AppContext, config *CreateConfig) func(cmd *cobra.Comm

if err := client.Create(ctx, cluster); err != nil {
if apierrors.IsAlreadyExists(err) {
logrus.Infof("Cluster [%s] already exists", name)
logrus.Infof("Cluster '%s' already exists", name)
} else {
return err
}
Expand All @@ -161,7 +161,7 @@ func createAction(appCtx *AppContext, config *CreateConfig) func(cmd *cobra.Comm
return fmt.Errorf("failed to wait for cluster to become ready (status: %s): %w", cluster.Status.Phase, err)
}

logrus.Infof("Extracting Kubeconfig for [%s] cluster", name)
logrus.Infof("Extracting Kubeconfig for '%s' cluster", name)

// retry every 5s for at most 2m, or 25 times
availableBackoff := wait.Backoff{
Expand Down
2 changes: 1 addition & 1 deletion cli/cmds/cluster_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func delete(appCtx *AppContext) func(cmd *cobra.Command, args []string) error {

namespace := appCtx.Namespace(name)

logrus.Infof("Deleting [%s] cluster in namespace [%s]", name, namespace)
logrus.Infof("Deleting '%s' cluster in namespace '%s'", name, namespace)

cluster := v1beta1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Expand Down
74 changes: 70 additions & 4 deletions cli/cmds/policy_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type VirtualClusterPolicyCreateConfig struct {
mode string
labels []string
annotations []string
namespaces []string
overwrite bool
}

func NewPolicyCreateCmd(appCtx *AppContext) *cobra.Command {
Expand All @@ -45,6 +47,8 @@ func NewPolicyCreateCmd(appCtx *AppContext) *cobra.Command {
cmd.Flags().StringVar(&config.mode, "mode", "shared", "The allowed mode type of the policy")
cmd.Flags().StringArrayVar(&config.labels, "labels", []string{}, "Labels to add to the policy object (e.g. key=value)")
cmd.Flags().StringArrayVar(&config.annotations, "annotations", []string{}, "Annotations to add to the policy object (e.g. key=value)")
cmd.Flags().StringSliceVar(&config.namespaces, "namespace", []string{}, "The namespaces where to bind the policy")
cmd.Flags().BoolVar(&config.overwrite, "overwrite", false, "Overwrite namespace binding of existing policy")

return cmd
}
Expand All @@ -56,8 +60,11 @@ func policyCreateAction(appCtx *AppContext, config *VirtualClusterPolicyCreateCo
policyName := args[0]

_, err := createPolicy(ctx, client, config, policyName)
if err != nil {
return err
}

return err
return bindPolicyToNamespaces(ctx, client, config, policyName)
}
}

Expand All @@ -75,7 +82,7 @@ func createNamespace(ctx context.Context, client client.Client, name, policyName
return err
}

logrus.Infof(`Creating namespace [%s]`, name)
logrus.Infof(`Creating namespace '%s'`, name)

if err := client.Create(ctx, ns); err != nil {
return err
Expand All @@ -86,7 +93,7 @@ func createNamespace(ctx context.Context, client client.Client, name, policyName
}

func createPolicy(ctx context.Context, client client.Client, config *VirtualClusterPolicyCreateConfig, policyName string) (*v1beta1.VirtualClusterPolicy, error) {
logrus.Infof("Creating policy [%s]", policyName)
logrus.Infof("Creating policy '%s'", policyName)

policy := &v1beta1.VirtualClusterPolicy{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -108,8 +115,67 @@ func createPolicy(ctx context.Context, client client.Client, config *VirtualClus
return nil, err
}

logrus.Infof("Policy [%s] already exists", policyName)
logrus.Infof("Policy '%s' already exists", policyName)
}

return policy, nil
}

func bindPolicyToNamespaces(ctx context.Context, client client.Client, config *VirtualClusterPolicyCreateConfig, policyName string) error {
var errs []error

for _, namespace := range config.namespaces {
var ns v1.Namespace
if err := client.Get(ctx, types.NamespacedName{Name: namespace}, &ns); err != nil {
if apierrors.IsNotFound(err) {
logrus.Warnf(`Namespace '%s' not found, skipping`, namespace)
} else {
errs = append(errs, err)
}

continue
}

if ns.Labels == nil {
ns.Labels = map[string]string{}
}

oldPolicy := ns.Labels[policy.PolicyNameLabelKey]

// same policy found, no need to update
if oldPolicy == policyName {
logrus.Debugf(`Policy '%s' already bound to namespace '%s'`, policyName, namespace)
continue
}

// no old policy, safe to update
if oldPolicy == "" {
if err := client.Update(ctx, &ns); err != nil {
errs = append(errs, err)
} else {
logrus.Infof(`Added policy '%s' to namespace '%s'`, policyName, namespace)
}

continue
}

// different policy, warn or check for overwrite flag
if oldPolicy != policyName {
if config.overwrite {
logrus.Infof(`Found policy '%s' bound to namespace '%s'. Overwriting it with '%s'`, oldPolicy, namespace, policyName)

ns.Labels[policy.PolicyNameLabelKey] = policyName

if err := client.Update(ctx, &ns); err != nil {
errs = append(errs, err)
} else {
logrus.Infof(`Added policy '%s' to namespace '%s'`, policyName, namespace)
}
} else {
logrus.Warnf(`Found policy '%s' bound to namespace '%s'. Skipping. To overwrite it use the --overwrite flag`, oldPolicy, namespace)
}
}
}

return errors.Join(errs...)
}
10 changes: 7 additions & 3 deletions cli/cmds/policy_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,17 @@ func policyDeleteAction(appCtx *AppContext) func(cmd *cobra.Command, args []stri
policy.Name = name

if err := client.Delete(ctx, policy); err != nil {
if apierrors.IsNotFound(err) {
logrus.Warnf("Policy not found")
} else {
if !apierrors.IsNotFound(err) {
return err
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check if the policy was ever bound to one more namespaces and clear it when deleted?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline this should probably responsibility of the controller itself, I've opened an issue about this: #563

logrus.Warnf("Policy '%s' not found", name)

return nil
}

logrus.Infof("Policy '%s' deleted", name)

return nil
}
}
2 changes: 2 additions & 0 deletions docs/cli/k3kcli_policy_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ k3kcli policy create [command options] NAME
-h, --help help for create
--labels stringArray Labels to add to the policy object (e.g. key=value)
--mode string The allowed mode type of the policy (default "shared")
--namespace strings The namespaces where to bind the policy
--overwrite Overwrite namespace binding of existing policy
```

### Options inherited from parent commands
Expand Down
8 changes: 4 additions & 4 deletions tests/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var _ = When("using the k3kcli", Label("cli"), func() {

_, stderr, err = K3kcli("cluster", "delete", clusterName)
Expect(err).To(Not(HaveOccurred()), string(stderr))
Expect(stderr).To(ContainSubstring("Deleting [%s] cluster in namespace [%s]", clusterName, clusterNamespace))
Expect(stderr).To(ContainSubstring(`Deleting '%s' cluster in namespace '%s'`, clusterName, clusterNamespace))

// The deletion could take a bit
Eventually(func() string {
Expand All @@ -92,7 +92,7 @@ var _ = When("using the k3kcli", Label("cli"), func() {

_, stderr, err = K3kcli("policy", "create", policyName)
Expect(err).To(Not(HaveOccurred()), string(stderr))
Expect(stderr).To(ContainSubstring("Creating policy [%s]", policyName))
Expect(stderr).To(ContainSubstring(`Creating policy '%s'`, policyName))

stdout, stderr, err = K3kcli("policy", "list")
Expect(err).To(Not(HaveOccurred()), string(stderr))
Expand All @@ -102,7 +102,7 @@ var _ = When("using the k3kcli", Label("cli"), func() {
stdout, stderr, err = K3kcli("policy", "delete", policyName)
Expect(err).To(Not(HaveOccurred()), string(stderr))
Expect(stdout).To(BeEmpty())
Expect(stderr).To(BeEmpty())
Expect(stderr).To(ContainSubstring(`Policy '%s' deleted`, policyName))

stdout, stderr, err = K3kcli("policy", "list")
Expect(err).To(Not(HaveOccurred()), string(stderr))
Expand Down Expand Up @@ -140,7 +140,7 @@ var _ = When("using the k3kcli", Label("cli"), func() {

_, stderr, err = K3kcli("cluster", "delete", clusterName)
Expect(err).To(Not(HaveOccurred()), string(stderr))
Expect(stderr).To(ContainSubstring("Deleting [%s] cluster in namespace [%s]", clusterName, clusterNamespace))
Expect(stderr).To(ContainSubstring(`Deleting '%s' cluster in namespace '%s'`, clusterName, clusterNamespace))
})
})
})
Loading