Skip to content

Commit d870eba

Browse files
committed
- Update the replace flag, use create when resource does not exist
- Do not pass extra kubectl args when running kubectl get commands
1 parent c8c1f0a commit d870eba

File tree

2 files changed

+75
-46
lines changed

2 files changed

+75
-46
lines changed

README.md

+31-13
Original file line numberDiff line numberDiff line change
@@ -85,27 +85,45 @@ You can fail an ongoing deployment if there's been a new deployment by adding `-
8585
kd will use the `apply` verb to create / update resources which is [appropriate
8686
in most cases](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#in-place-updates-of-resources).
8787

88-
The flag `--replace` can be used to override this behaviour can be useful in
89-
some very specific scenarios but the result is a [disruptive update](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#disruptive-updates)
90-
which should not be the default.
91-
92-
To have the desired affect when updating objects, `--force` is used to enable
93-
creation of objects created with replace. **NOTE** history of an object is lost
94-
with `--force`.
88+
The flag `--replace` can be used to override this behaviour and may be useful in
89+
some very specific scenarios however the result can be a [disruptive update](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#disruptive-updates)
90+
if extra kubectl flags are applied (such as `-- --force`). Additionally, the last-applied-configuration is not saved when using this flag.
9591

9692
#### Cronjobs
9793

98-
When a cronjob object is created and only updated, any old jobs will continue
99-
and some fields are imutable so use of the force option may be required.
94+
When a cronjob object is created and only updated, any old jobs will continue and some
95+
fields are immutable, so use of the replace command and force option may be required.
10096

101-
E.g. to update a large cron job use `kd --replace -f cronjob.yml`.
97+
```bash
98+
# The cronjob resource does not yet exist, and so a create action is performed
99+
$ kd --replace -f cronjob.yml -- --force
100+
[INFO] 2018/08/07 22:54:00 main.go:724: resource does not exist, dropping --force flag for create action
101+
[INFO] 2018/08/07 22:54:00 main.go:466: deploying cronjob/etcd-backup
102+
[INFO] 2018/08/07 22:54:00 main.go:473: cronjob "etcd-backup" created
103+
104+
# The resource now exists, so a kubectl replace is performed with the extra --force arg
105+
$ kd --replace -f cronjob.yml -- --force
106+
[INFO] 2018/08/07 22:54:02 main.go:466: deploying cronjob/etcd-backup
107+
[INFO] 2018/08/07 22:54:03 main.go:473: cronjob "etcd-backup" deleted
108+
cronjob "etcd-backup" replaced
109+
```
102110

103-
#### Large Objects e.g. Configmaps
111+
#### Large Objects
104112

105113
As an apply uses 'patch' internally, there is a limit to the size of objects
106-
that can be updated this way.
114+
that can be updated this way and you may receive an error such as: `metadata.annotations: Too long: must have at most 262144 characters`
107115

108-
E.g. to update a large config map use `kd --replace -f myconfigmap.yml`.
116+
Below is an example for updating a large ConfigMap:
117+
```bash
118+
# 859KB ConfigMap resource
119+
$ kd --replace -f configmap.yaml
120+
[INFO] 2018/08/07 23:02:39 main.go:466: deploying configmap/bundle
121+
[INFO] 2018/08/07 23:02:40 main.go:473: configmap "bundle" created
122+
123+
$ kd --replace -f configmap.yaml
124+
[INFO] 2018/08/07 23:02:41 main.go:466: deploying configmap/bundle
125+
[INFO] 2018/08/07 23:02:42 main.go:473: configmap "bundle" replaced
126+
```
109127

110128
### Run command
111129

main.go

+44-33
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ func runKubectl(c *cli.Context) error {
256256
}
257257

258258
// Allow the lib to render args and then create array
259-
cmd, err := newKubeCmdSub(c.Parent(), c.Args(), true)
259+
cmd, err := newKubeCmdSub(c.Parent(), c.Args(), true, true)
260260
if err != nil {
261261
return err
262262
}
@@ -404,26 +404,34 @@ func splitYamlDocs(data string) []string {
404404
func deploy(c *cli.Context, r *ObjectResource) error {
405405

406406
exists := false
407-
if r.CreateOnly {
407+
if r.CreateOnly || c.Bool(FlagReplace) {
408408
var err error
409409
exists, err = checkResourceExist(c, r)
410410
if err != nil {
411411
return fmt.Errorf(
412412
"problem checking if resource %s/%s exists", r.Kind, r.Name)
413413
}
414-
if exists {
415-
log.Printf(
416-
"skipping deploy for resource (%s/%s) marked as create only.",
417-
r.Kind,
418-
r.Name)
419-
return nil
414+
415+
if r.CreateOnly {
416+
if exists {
417+
log.Printf(
418+
"skipping deploy for resource (%s/%s) marked as create only.",
419+
r.Kind,
420+
r.Name)
421+
return nil
422+
}
420423
}
421424
}
422425

423426
name := r.Name
424427
command := "apply"
428+
425429
if c.Bool(FlagReplace) {
426-
command = "replace"
430+
if exists {
431+
command = "replace"
432+
} else {
433+
command = "create"
434+
}
427435
}
428436

429437
if r.GenerateName != "" {
@@ -433,7 +441,7 @@ func deploy(c *cli.Context, r *ObjectResource) error {
433441

434442
logDebug.Printf("about to deploy resource %s/%s (from file:%q)", r.Kind, name, r.FileName)
435443
args := []string{command, "-f", "-"}
436-
cmd, err := newKubeCmd(c, args)
444+
cmd, err := newKubeCmd(c, args, true)
437445
if err != nil {
438446
return err
439447
}
@@ -594,7 +602,7 @@ func watchResource(c *cli.Context, r *ObjectResource) error {
594602

595603
func updateResourceStatus(c *cli.Context, r *ObjectResource) error {
596604
args := []string{"get", r.Kind + "/" + r.Name, "-o", "yaml"}
597-
cmd, err := newKubeCmd(c, args)
605+
cmd, err := newKubeCmd(c, args, false)
598606
if err != nil {
599607
return err
600608
}
@@ -615,7 +623,8 @@ func updateResourceStatus(c *cli.Context, r *ObjectResource) error {
615623

616624
func checkResourceExist(c *cli.Context, r *ObjectResource) (bool, error) {
617625
args := []string{"get", r.Kind + "/" + r.Name, "-o", "custom-columns=:.metadata.name", "--no-headers"}
618-
cmd, err := newKubeCmd(c, args)
626+
627+
cmd, err := newKubeCmd(c, args, false)
619628
if err != nil {
620629
return false, err
621630
}
@@ -636,16 +645,16 @@ func checkResourceExist(c *cli.Context, r *ObjectResource) (bool, error) {
636645
}
637646
if strings.TrimSpace(string(data[:])) == r.Name {
638647
return true, nil
639-
} else {
640-
return false, nil
641648
}
649+
650+
return false, nil
642651
}
643652

644-
func newKubeCmd(c *cli.Context, args []string) (*exec.Cmd, error) {
645-
return newKubeCmdSub(c, args, false)
653+
func newKubeCmd(c *cli.Context, args []string, addExtraFlags bool) (*exec.Cmd, error) {
654+
return newKubeCmdSub(c, args, false, addExtraFlags)
646655
}
647656

648-
func newKubeCmdSub(c *cli.Context, args []string, subCommand bool) (*exec.Cmd, error) {
657+
func newKubeCmdSub(c *cli.Context, args []string, subCommand bool, addExtraFlags bool) (*exec.Cmd, error) {
649658

650659
kube := "kubectl"
651660
if c.IsSet("namespace") {
@@ -684,25 +693,27 @@ func newKubeCmdSub(c *cli.Context, args []string, subCommand bool) (*exec.Cmd, e
684693
args = append([]string{"--server=" + c.String("kube-server")}, args...)
685694
}
686695

687-
flags, err := extraFlags(c, subCommand)
688-
if err != nil {
689-
return nil, err
690-
}
691-
// If we've been asked to replace and we haven't provided the '-- --force'
692-
// extra args, add it here (a update will fail if the object doesn't exist)
693-
if c.Bool(FlagReplace) {
694-
forceSet := false
695-
for _, flag := range flags {
696-
if strings.Contains(flag, "--force") {
697-
forceSet = true
698-
break
699-
}
696+
if addExtraFlags {
697+
flags, err := extraFlags(c, subCommand)
698+
if err != nil {
699+
return nil, err
700700
}
701-
if !forceSet {
702-
flags = append(flags, "--force")
701+
702+
// If the --replace flag is given but the resource doesn't yet exist, the create
703+
// command is used. Providing the --force flag is invalid here and so should be
704+
// removed if it is present.
705+
if c.Bool(FlagReplace) && args[0] == "create" {
706+
for i, flag := range flags {
707+
if strings.Contains(flag, "--force") {
708+
logInfo.Printf("resource does not exist, dropping --force flag for create action")
709+
flags = append(flags[:i], flags[i+1:]...)
710+
break
711+
}
712+
}
703713
}
714+
715+
args = append(args, flags...)
704716
}
705-
args = append(args, flags...)
706717

707718
return exec.Command(kube, args...), nil
708719
}

0 commit comments

Comments
 (0)