mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-09 06:31:25 +02:00
feat: new talosctl config remove to remove context
Adds a new sub-command to talosctl config. It takes in the context to be deleted as argument and supports glob matching. A local flag --noconfirm|-y can be passed to bypass the confirmation prompt. It also supports dry run by passing the --dry-run flag similar to apply-config and edit commands. Example: $ talosctl config remove 'ctx-*' Remove context ctx-a? (y/N): y Remove context ctx-b? (y/N): y Signed-off-by: Murtaza Udaipurwala <murtaza@murtazau.xyz> Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
This commit is contained in:
parent
fcb19ff516
commit
ba8265bc5c
@ -10,6 +10,7 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
@ -19,6 +20,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/ryanuber/go-glob"
|
||||
"github.com/siderolabs/gen/maps"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
@ -186,6 +188,89 @@ var configAddCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
// configRemoveCmdFlags represents the `config remove` command flags.
|
||||
var configRemoveCmdFlags struct {
|
||||
noconfirm bool
|
||||
dry bool
|
||||
}
|
||||
|
||||
// configRemoveCmd represents the `config remove` command.
|
||||
var configRemoveCmd = &cobra.Command{
|
||||
Use: "remove <context>",
|
||||
Short: "Remove contexts",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
pattern := args[0]
|
||||
if pattern == "" {
|
||||
return fmt.Errorf("no context specified")
|
||||
}
|
||||
|
||||
c, err := clientconfig.Open(GlobalArgs.Talosconfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading config: %w", err)
|
||||
}
|
||||
|
||||
if len(c.Contexts) == 0 {
|
||||
return errors.New("no contexts defined")
|
||||
}
|
||||
|
||||
matches := sortInPlace(maps.Keys(
|
||||
maps.Filter(c.Contexts, func(context string, _ *clientconfig.Context) bool {
|
||||
return glob.Glob(pattern, context)
|
||||
}),
|
||||
))
|
||||
if len(matches) == 0 {
|
||||
return fmt.Errorf("no contexts matched %q", pattern)
|
||||
}
|
||||
|
||||
// we want to prevent file updates in case there were no changes
|
||||
noChanges := true
|
||||
|
||||
for _, match := range matches {
|
||||
if match == c.Context {
|
||||
fmt.Fprintf(
|
||||
os.Stderr,
|
||||
"skipping removal of current context %q, please change it to another before removing\n",
|
||||
match,
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if !configRemoveCmdFlags.noconfirm {
|
||||
prompt := fmt.Sprintf("remove context %q", match)
|
||||
|
||||
if !helpers.Confirm(prompt + "?") {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "removing context %q\n", match)
|
||||
}
|
||||
|
||||
noChanges = false
|
||||
delete(c.Contexts, match)
|
||||
}
|
||||
|
||||
if configRemoveCmdFlags.dry || noChanges {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = c.Save(GlobalArgs.Talosconfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
ValidArgsFunction: CompleteConfigContext,
|
||||
}
|
||||
|
||||
func sortInPlace(slc []string) []string {
|
||||
sort.Slice(slc, func(i, j int) bool { return slc[i] < slc[j] })
|
||||
|
||||
return slc
|
||||
}
|
||||
|
||||
func checkAndSetCrtAndKey(configContext *clientconfig.Context) error {
|
||||
crt := configAddCmdFlags.crt
|
||||
key := configAddCmdFlags.key
|
||||
@ -430,7 +515,8 @@ var configInfoCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
// CompleteConfigContext represents tab completion for `--context` argument and `config context` command.
|
||||
// CompleteConfigContext represents tab completion for `--context`
|
||||
// argument and `config [context|remove]` command.
|
||||
func CompleteConfigContext(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
c, err := clientconfig.Open(GlobalArgs.Talosconfig)
|
||||
if err != nil {
|
||||
@ -449,6 +535,7 @@ func init() {
|
||||
configNodeCmd,
|
||||
configContextCmd,
|
||||
configAddCmd,
|
||||
configRemoveCmd,
|
||||
configGetContextsCmd,
|
||||
configMergeCmd,
|
||||
configNewCmd,
|
||||
@ -459,6 +546,14 @@ func init() {
|
||||
configAddCmd.Flags().StringVar(&configAddCmdFlags.crt, "crt", "", "the path to the certificate")
|
||||
configAddCmd.Flags().StringVar(&configAddCmdFlags.key, "key", "", "the path to the key")
|
||||
|
||||
configRemoveCmd.Flags().BoolVarP(
|
||||
&configRemoveCmdFlags.noconfirm, "noconfirm", "y", false,
|
||||
"do not ask for confirmation",
|
||||
)
|
||||
configRemoveCmd.Flags().BoolVar(
|
||||
&configRemoveCmdFlags.dry, "dry-run", false, "dry run",
|
||||
)
|
||||
|
||||
configNewCmd.Flags().StringSliceVar(&configNewCmdFlags.roles, "roles", role.MakeSet(role.Admin).Strings(), "roles")
|
||||
configNewCmd.Flags().DurationVar(&configNewCmdFlags.crtTTL, "crt-ttl", 87600*time.Hour, "certificate TTL")
|
||||
|
||||
|
30
cmd/talosctl/pkg/talos/helpers/confirm.go
Normal file
30
cmd/talosctl/pkg/talos/helpers/confirm.go
Normal file
@ -0,0 +1,30 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var okays = []string{"y", "yes"}
|
||||
|
||||
// Confirm asks the user to confirm their action. Anything other than
|
||||
// `y` and `yes` returns false.
|
||||
func Confirm(prompt string) bool {
|
||||
var inp string
|
||||
|
||||
fmt.Printf("%s (y/N): ", prompt)
|
||||
fmt.Scanf("%s", &inp)
|
||||
inp = strings.TrimSpace(inp)
|
||||
|
||||
for _, ok := range okays {
|
||||
if strings.EqualFold(inp, ok) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
@ -571,6 +571,36 @@ talosctl config node <endpoint>... [flags]
|
||||
|
||||
* [talosctl config](#talosctl-config) - Manage the client configuration file (talosconfig)
|
||||
|
||||
## talosctl config remove
|
||||
|
||||
Remove contexts
|
||||
|
||||
```
|
||||
talosctl config remove <context> [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--dry-run dry run
|
||||
-h, --help help for remove
|
||||
-y, --noconfirm do not ask for confirmation
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--cluster string Cluster to connect to if a proxy endpoint is used.
|
||||
--context string Context to be used in command
|
||||
-e, --endpoints strings override default endpoints in Talos configuration
|
||||
-n, --nodes strings target the specified nodes
|
||||
--talosconfig string The path to the Talos configuration file. Defaults to 'TALOSCONFIG' env variable if set, otherwise '$HOME/.talos/config' and '/var/run/secrets/talos.dev/config' in order.
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [talosctl config](#talosctl-config) - Manage the client configuration file (talosconfig)
|
||||
|
||||
## talosctl config
|
||||
|
||||
Manage the client configuration file (talosconfig)
|
||||
@ -602,6 +632,7 @@ Manage the client configuration file (talosconfig)
|
||||
* [talosctl config merge](#talosctl-config-merge) - Merge additional contexts from another client configuration file
|
||||
* [talosctl config new](#talosctl-config-new) - Generate a new client configuration file
|
||||
* [talosctl config node](#talosctl-config-node) - Set the node(s) for the current context
|
||||
* [talosctl config remove](#talosctl-config-remove) - Remove contexts
|
||||
|
||||
## talosctl conformance kubernetes
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user