Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: edit set configmap #5391

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 31 additions & 2 deletions go.work.sum
Expand Up @@ -201,12 +201,11 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
Expand All @@ -224,5 +223,35 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts=
google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 h1:Et6SkiuvnBn+SgrSYXs/BrUpGB4mbdwt4R3vaPIlicA=
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I=
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=
gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
k8s.io/apiserver v0.17.0 h1:XhUix+FKFDcBygWkQNp7wKKvZL030QUlH1o8vFeSgZA=
k8s.io/code-generator v0.17.0 h1:y+KWtDWNqlJzJu/kUy8goJZO0X71PGIpAHLX8a0JYk0=
k8s.io/component-base v0.17.0 h1:BnDFcmBDq+RPpxXjmuYnZXb59XNN9CaFrX8ba9+3xrA=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c h1:GohjlNKauSai7gN4wsJkeZ3WAJx4Sh+oT/b5IYn5suA=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
2 changes: 1 addition & 1 deletion kustomize/commands/edit/add/configmap.go
Expand Up @@ -97,7 +97,7 @@ func runEditAddConfigMap(
return fmt.Errorf("failed to expand file source: %w", err)
}

err = flags.Validate(args)
err = flags.ValidateAdd(args)
if err != nil {
return fmt.Errorf("failed to validate flags: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion kustomize/commands/edit/add/secret.go
Expand Up @@ -89,7 +89,7 @@ func runEditAddSecret(
return fmt.Errorf("failed to expand file source: %w", err)
}

err = flags.Validate(args)
err = flags.ValidateAdd(args)
if err != nil {
return fmt.Errorf("failed to validate flags: %w", err)
}
Expand Down
3 changes: 2 additions & 1 deletion kustomize/commands/edit/all.go
Expand Up @@ -48,7 +48,8 @@ func NewCmdEdit(
set.NewCmdSet(
fSys,
kv.NewLoader(ldrhelper.NewFileLoaderAtCwd(fSys), v),
v),
v,
rf),
fix.NewCmdFix(fSys, w),
remove.NewCmdRemove(fSys, v),
listbuiltin.NewCmdListBuiltinPlugin(),
Expand Down
9 changes: 8 additions & 1 deletion kustomize/commands/edit/set/all.go
Expand Up @@ -6,11 +6,17 @@ package set
import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/kyaml/filesys"
)

// NewCmdSet returns an instance of 'set' subcommand.
func NewCmdSet(fSys filesys.FileSystem, ldr ifc.KvLoader, v ifc.Validator) *cobra.Command {
func NewCmdSet(
fSys filesys.FileSystem,
ldr ifc.KvLoader,
v ifc.Validator,
rf *resource.Factory,
) *cobra.Command {
c := &cobra.Command{
Use: "set",
Short: "Sets the value of different fields in kustomization file",
Expand All @@ -26,6 +32,7 @@ func NewCmdSet(fSys filesys.FileSystem, ldr ifc.KvLoader, v ifc.Validator) *cobr
}

c.AddCommand(
newCmdSetConfigMap(fSys, ldr, rf),
newCmdSetNamePrefix(fSys),
newCmdSetNameSuffix(fSys),
newCmdSetNamespace(fSys, v),
Expand Down
151 changes: 151 additions & 0 deletions kustomize/commands/edit/set/configmap.go
@@ -0,0 +1,151 @@
// Copyright 2023 The Kubernetes Authors.
stormqueen1990 marked this conversation as resolved.
Show resolved Hide resolved
// SPDX-License-Identifier: Apache-2.0

package set

import (
"fmt"

"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kustomize/v5/commands/internal/kustfile"
"sigs.k8s.io/kustomize/kustomize/v5/commands/internal/util"
"sigs.k8s.io/kustomize/kyaml/filesys"
)

func newCmdSetConfigMap(
fSys filesys.FileSystem,
ldr ifc.KvLoader,
rf *resource.Factory,
) *cobra.Command {
var flags util.ConfigMapSecretFlagsAndArgs
cmd := &cobra.Command{
Use: "configmap NAME [--from-literal=key1=value1] [--namespace=namespace-name] [--new-namespace=new-namespace-name]",
Short: "Edits the value for an existing key for a configmap in the kustomization file",
Long: `Edits the value for an existing key in an existing configmap in the kustomization file.
Both configmap name and key name must exist for this command to succeed.`,
Example: `
# Edits an existing configmap in the kustomization file, changing value of key1 to 2
kustomize edit set configmap my-configmap --from-literal=key1=2

# Edits an existing configmap in the kustomization file, changing namespace to 'new-namespace'
kustomize edit set configmap my-configmap --namespace=current-namespace --new-namespace=new-namespace
`,
RunE: func(_ *cobra.Command, args []string) error {
return runEditSetConfigMap(flags, fSys, args, ldr, rf)
},
}

cmd.Flags().StringArrayVar(
&flags.LiteralSources,
util.FromLiteralFlag,
[]string{},
"Specify an existing key and a new value to update a ConfigMap (i.e. mykey=newvalue)")
cmd.Flags().StringVar(
&flags.Namespace,
util.NamespaceFlag,
"",
"Current namespace of the target ConfigMap")
cmd.Flags().StringVar(
&flags.NewNamespace,
util.NewNamespaceFlag,
"",
"New namespace value for the target ConfigMap")

return cmd
}

func runEditSetConfigMap(
flags util.ConfigMapSecretFlagsAndArgs,
fSys filesys.FileSystem,
args []string,
ldr ifc.KvLoader,
rf *resource.Factory,
) error {
err := flags.ExpandFileSource(fSys)
if err != nil {
return fmt.Errorf("failed to expand file source: %w", err)
}

err = flags.ValidateSet(args)
if err != nil {
return fmt.Errorf("failed to validate flags: %w", err)
}

// Load the kustomization file.
mf, err := kustfile.NewKustomizationFile(fSys)
if err != nil {
return fmt.Errorf("failed to load kustomization file: %w", err)
}

kustomization, err := mf.Read()
if err != nil {
return fmt.Errorf("failed to read kustomization file: %w", err)
}

// Updates the existing ConfigMap
err = setConfigMap(ldr, kustomization, flags, rf)
if err != nil {
return fmt.Errorf("failed to create configmap: %w", err)
}

// Write out the kustomization file with added configmap.
err = mf.Write(kustomization)
if err != nil {
return fmt.Errorf("failed to write kustomization file: %w", err)
}

return nil
}

func setConfigMap(
ldr ifc.KvLoader,
k *types.Kustomization,
flags util.ConfigMapSecretFlagsAndArgs,
rf *resource.Factory,
) error {
args, err := findConfigMapArgs(k, flags.Name, flags.Namespace)
if err != nil {
return fmt.Errorf("could not set new ConfigMap value: %w", err)
}

if len(flags.LiteralSources) > 0 {
err := util.UpdateLiteralSources(&args.GeneratorArgs, flags)
if err != nil {
return fmt.Errorf("failed to update literal sources: %w", err)
}
}

// update namespace to new one
if flags.NewNamespace != "" {
args.Namespace = flags.NewNamespace
}

// Validate by trying to create corev1.configmap.
args.Options = types.MergeGlobalOptionsIntoLocal(
args.Options, k.GeneratorOptions)

_, err = rf.MakeConfigMap(ldr, args)
if err != nil {
return fmt.Errorf("failed to validate ConfigMap structure: %w", err)
}

return nil
}

// findConfigMapArgs finds the generator arguments corresponding to the specified
// ConfigMap name. ConfigMap must exist for this command to be successful.
func findConfigMapArgs(m *types.Kustomization, name, namespace string) (*types.ConfigMapArgs, error) {
cmIndex := slices.IndexFunc(m.ConfigMapGenerator, func(cmArgs types.ConfigMapArgs) bool {
return name == cmArgs.Name && util.NamespaceEqual(namespace, cmArgs.Namespace)
})

if cmIndex == -1 {
return nil, fmt.Errorf("unable to find ConfigMap with name '%q'", name)
}

return &m.ConfigMapGenerator[cmIndex], nil
}