chore: delete command namespace (#1372)

* chore: delete command namespace

- Fixes bug where deleting by name fails if current path has no
  initialized function.
- Adds namespace test to delete command
- Moves namespace flag into delete command for
  - Better help text
  - Easier testing
- Sets static default namespace for flag to "default"

* fix comments/docs

* delete tests with nonexistent kubeconfig

* fix help text
This commit is contained in:
Luke Kingland 2022-11-01 04:34:14 +09:00 committed by GitHub
parent e9fb274969
commit b8de6532fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 12 deletions

View File

@ -33,7 +33,7 @@ No local files are deleted.
`,
SuggestFor: []string{"remove", "rm", "del"},
ValidArgsFunction: CompleteFunctionList,
PreRunE: bindEnv("path", "confirm", "all"),
PreRunE: bindEnv("path", "confirm", "all", "namespace"),
SilenceUsage: true, // no usage dump on error
}
@ -45,7 +45,7 @@ No local files are deleted.
// Flags
cmd.Flags().BoolP("confirm", "c", cfg.Confirm, "Prompt to confirm all configuration options (Env: $FUNC_CONFIRM)")
cmd.Flags().StringP("namespace", "n", "", "The namespace in which to delete. (Env: $FUNC_NAMESPACE)")
cmd.Flags().StringP("namespace", "n", cfg.Namespace, "The namespace in which to delete. (Env: $FUNC_NAMESPACE)")
cmd.Flags().StringP("all", "a", "true", "Delete all resources created for a function, eg. Pipelines, Secrets, etc. (Env: $FUNC_ALL) (allowed values: \"true\", \"false\")")
setPathFlag(cmd)
@ -59,7 +59,7 @@ No local files are deleted.
}
func runDelete(cmd *cobra.Command, args []string, newClient ClientFactory) (err error) {
config, err := newDeleteConfig(args).Prompt()
cfg, err := newDeleteConfig(args).Prompt()
if err != nil {
if err == terminal.InterruptErr {
return nil
@ -79,28 +79,29 @@ func runDelete(cmd *cobra.Command, args []string, newClient ClientFactory) (err
Name: args[0],
}
} else {
function, err = fn.NewFunction(config.Path)
function, err = fn.NewFunction(cfg.Path)
if err != nil {
return
}
// Check if the function has been initialized
if !function.Initialized() {
return fmt.Errorf("the given path '%v' does not contain an initialized function", config.Path)
return fmt.Errorf("the given path '%v' does not contain an initialized function", cfg.Path)
}
// If not provided, use the function's extant namespace
if !cmd.Flags().Changed("namespace") {
cfg.Namespace = function.Deploy.Namespace
}
}
// If not provided, use the function's extant namespace
if config.Namespace == "" {
config.Namespace = function.Deploy.Namespace
}
// Create a client instance from the now-final config
client, done := newClient(ClientConfig{Namespace: config.Namespace, Verbose: config.Verbose})
client, done := newClient(ClientConfig{Namespace: cfg.Namespace, Verbose: cfg.Verbose})
defer done()
// Invoke remove using the concrete client impl
return client.Remove(cmd.Context(), function, config.DeleteAll)
return client.Remove(cmd.Context(), function, cfg.DeleteAll)
}
type deleteConfig struct {

View File

@ -2,12 +2,69 @@ package cmd
import (
"os"
"path/filepath"
"testing"
fn "knative.dev/func"
"knative.dev/func/mock"
)
// TestDelete_Namespace ensures that the namespace provided to the client
// for use when deleting a function is set
// 1. The flag /env variable if provided
// 2. The namespace of the function at path if provided
// 3. The user's current active namespace
func TestDelete_Namespace(t *testing.T) {
root := fromTempDirectory(t)
// Ensure that the default is "default" when no context can be identified
t.Setenv("KUBECONFIG", filepath.Join(cwd(), "nonexistent"))
cmd := NewDeleteCmd(func(cc ClientConfig, options ...fn.Option) (*fn.Client, func()) {
if cc.Namespace != "default" {
t.Fatalf("expected 'default', got '%v'", cc.Namespace)
}
return fn.New(), func() {}
})
cmd.SetArgs([]string{"somefunc"}) // delete by name such that no f need be created
if err := cmd.Execute(); err != nil {
t.Fatal(err)
}
// Ensure the extant function's namespace is used
f := fn.Function{
Root: root,
Runtime: "go",
Deploy: fn.DeploySpec{
Namespace: "deployed",
},
}
if err := fn.New().Create(f); err != nil {
t.Fatal(err)
}
cmd = NewDeleteCmd(func(cc ClientConfig, options ...fn.Option) (*fn.Client, func()) {
if cc.Namespace != "deployed" {
t.Fatalf("expected 'deployed', got '%v'", cc.Namespace)
}
return fn.New(), func() {}
})
if err := cmd.Execute(); err != nil {
t.Fatal(err)
}
// Ensure an explicit namespace is plumbed through
cmd = NewDeleteCmd(func(cc ClientConfig, options ...fn.Option) (*fn.Client, func()) {
if cc.Namespace != "ns" {
t.Fatalf("expected 'ns', got '%v'", cc.Namespace)
}
return fn.New(), func() {}
})
cmd.SetArgs([]string{"--namespace", "ns"})
if err := cmd.Execute(); err != nil {
t.Fatal(err)
}
}
// TestDelete_ByName ensures that running delete specifying the name of the
// function explicitly as an argument invokes the remover appropriately.
func TestDelete_ByName(t *testing.T) {

View File

@ -35,7 +35,7 @@ func delete -n apps myfunc
-a, --all string Delete all resources created for a function, eg. Pipelines, Secrets, etc. (Env: $FUNC_ALL) (allowed values: "true", "false") (default "true")
-c, --confirm Prompt to confirm all configuration options (Env: $FUNC_CONFIRM)
-h, --help help for delete
-n, --namespace string The namespace in which to delete. (Env: $FUNC_NAMESPACE)
-n, --namespace string The namespace in which to delete. (Env: $FUNC_NAMESPACE) (default "default")
-p, --path string Path to the project directory (Env: $FUNC_PATH) (default ".")
```