Skip to content

Commit 030594b

Browse files
committed
history feature
1 parent 92aca48 commit 030594b

File tree

7 files changed

+191
-1
lines changed

7 files changed

+191
-1
lines changed

docs/help/gardenctl_target.md

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ gardenctl target value/that/matches/pattern --control-plane
5555
* [gardenctl](gardenctl.md) - Gardenctl is a utility to interact with Gardener installations
5656
* [gardenctl target control-plane](gardenctl_target_control-plane.md) - Target the control plane of the shoot
5757
* [gardenctl target garden](gardenctl_target_garden.md) - Target a garden
58+
* [gardenctl target history](gardenctl_target_history.md) - Print the target history
5859
* [gardenctl target project](gardenctl_target_project.md) - Target a project
5960
* [gardenctl target seed](gardenctl_target_seed.md) - Target a seed
6061
* [gardenctl target shoot](gardenctl_target_shoot.md) - Target a shoot

docs/help/gardenctl_target_history.md

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
## gardenctl target history
2+
3+
Print the target history
4+
5+
```
6+
gardenctl target history [flags]
7+
```
8+
9+
### Options
10+
11+
```
12+
-h, --help help for history
13+
```
14+
15+
### Options inherited from parent commands
16+
17+
```
18+
--add-dir-header If true, adds the file directory to the header of the log messages
19+
--alsologtostderr log to standard error as well as files
20+
--config string config file (default is ~/.garden/gardenctl-v2.yaml)
21+
--control-plane target control plane of shoot, use together with shoot argument
22+
--garden string target the given garden cluster
23+
--log-backtrace-at traceLocation when logging hits line file:N, emit a stack trace (default :0)
24+
--log-dir string If non-empty, write log files in this directory
25+
--log-file string If non-empty, use this log file
26+
--log-file-max-size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
27+
--logtostderr log to standard error instead of files (default true)
28+
--one-output If true, only write logs to their native severity level (vs also writing to each lower severity level)
29+
--project string target the given project
30+
--seed string target the given seed cluster
31+
--shoot string target the given shoot cluster
32+
--skip-headers If true, avoid header prefixes in the log messages
33+
--skip-log-headers If true, avoid headers when opening log files
34+
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
35+
-v, --v Level number for the log level verbosity
36+
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
37+
```
38+
39+
### SEE ALSO
40+
41+
* [gardenctl target](gardenctl_target.md) - Set scope for next operations, using subcommands or pattern
42+

pkg/cmd/env/rc_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ alias gtc-='gardenctl target unset control-plane'
7272
alias gk='eval "$(gardenctl kubectl-env bash)"'
7373
alias gp='eval "$(gardenctl provider-env bash)"'
7474
alias gcv='gardenctl config view -o yaml'
75+
alias gh='gardenctl target history | fzf --tac --no-sort | bash'
7576
source <(gardenctl completion bash)
7677
complete -o default -F __start_gardenctl g
7778
gk
@@ -91,6 +92,7 @@ alias gtc-='gardenctl target unset control-plane'
9192
alias gk='eval "$(gardenctl kubectl-env zsh)"'
9293
alias gp='eval "$(gardenctl provider-env zsh)"'
9394
alias gcv='gardenctl config view -o yaml'
95+
alias gh='gardenctl target history | fzf --tac --no-sort | zsh'
9496
if (( $+commands[gardenctl] )); then
9597
if [ -d "$ZSH_CACHE_DIR/completions" ] && (($fpath[(Ie)$ZSH_CACHE_DIR/completions])); then
9698
GCTL_COMPLETION_FILE="$ZSH_CACHE_DIR/completions/_gardenctl"
@@ -122,6 +124,7 @@ alias gtc-='gardenctl target unset control-plane'
122124
alias gk='eval (gardenctl kubectl-env fish)'
123125
alias gp='eval (gardenctl provider-env fish)'
124126
alias gcv='gardenctl config view -o yaml'
127+
alias gh='gardenctl target history | fzf --tac --no-sort | fish'
125128
gardenctl completion fish | source
126129
complete -c g -w gardenctl
127130
gk

pkg/cmd/env/templates/rc.tmpl

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ alias {{.prefix}}tc-='gardenctl target unset control-plane'
99
alias {{.prefix}}k='eval "$(gardenctl kubectl-env {{.shell}})"'
1010
alias {{.prefix}}p='eval "$(gardenctl provider-env {{.shell}})"'
1111
alias {{.prefix}}cv='gardenctl config view -o yaml'
12+
alias {{.prefix}}h='gardenctl target history | fzf --tac --no-sort | {{.shell}}'
1213
{{if not .noCompletion -}}
1314
source <(gardenctl completion {{.shell}})
1415
complete -o default -F __start_gardenctl {{.prefix}}
@@ -29,6 +30,7 @@ alias {{.prefix}}tc-='gardenctl target unset control-plane'
2930
alias {{.prefix}}k='eval "$(gardenctl kubectl-env {{.shell}})"'
3031
alias {{.prefix}}p='eval "$(gardenctl provider-env {{.shell}})"'
3132
alias {{.prefix}}cv='gardenctl config view -o yaml'
33+
alias {{.prefix}}h='gardenctl target history | fzf --tac --no-sort | {{.shell}}'
3234
{{if not .noCompletion -}}
3335
if (( $+commands[gardenctl] )); then
3436
if [ -d "$ZSH_CACHE_DIR/completions" ] && (($fpath[(Ie)$ZSH_CACHE_DIR/completions])); then
@@ -61,6 +63,7 @@ alias {{.prefix}}tc-='gardenctl target unset control-plane'
6163
alias {{.prefix}}k='eval (gardenctl kubectl-env {{.shell}})'
6264
alias {{.prefix}}p='eval (gardenctl provider-env {{.shell}})'
6365
alias {{.prefix}}cv='gardenctl config view -o yaml'
66+
alias {{.prefix}}h='gardenctl target history | fzf --tac --no-sort | {{.shell}}'
6467
{{if not .noCompletion -}}
6568
gardenctl completion {{.shell}} | source
6669
complete -c {{.prefix}} -w gardenctl

pkg/cmd/target/history.go

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
SPDX-FileCopyrightText: 2021 SAP SE or an SAP affiliate company and Gardener contributors
3+
SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package target
7+
8+
import (
9+
"errors"
10+
"fmt"
11+
"io/ioutil"
12+
"os"
13+
"os/exec"
14+
15+
"github.com/spf13/cobra"
16+
17+
"github.com/gardener/gardenctl-v2/internal/util"
18+
"github.com/gardener/gardenctl-v2/pkg/cmd/base"
19+
)
20+
21+
const (
22+
historyFile string = "history"
23+
)
24+
25+
// NewCmdHistory returns a new target history command.
26+
func NewCmdHistory(f util.Factory, o base.Options) *cobra.Command {
27+
cmd := &cobra.Command{
28+
Use: "history",
29+
Short: "Print the target history",
30+
RunE: func(cmd *cobra.Command, args []string) error {
31+
return runHistoryCommand(f, o)
32+
},
33+
}
34+
35+
return cmd
36+
}
37+
38+
func runHistoryCommand(f util.Factory, o base.Options) error {
39+
if err := checkInstalled("fzf"); err != nil {
40+
return errors.New("fzf not installed. Please install from https://github.com/junegunn/fzf")
41+
}
42+
43+
if err := HistoryOutput(historyPath(f), o); err != nil {
44+
return err
45+
}
46+
47+
return nil
48+
}
49+
50+
func HistoryWrite(path string, s string) error {
51+
f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
52+
if err != nil {
53+
return fmt.Errorf("history file open error %s", path)
54+
}
55+
defer f.Close()
56+
57+
if _, err := f.WriteString(s); err != nil {
58+
return fmt.Errorf("history file write error %s", path)
59+
}
60+
61+
return nil
62+
}
63+
64+
func HistoryOutput(path string, o base.Options) error {
65+
content, err := ioutil.ReadFile(path)
66+
if err != nil {
67+
return err
68+
}
69+
70+
return o.PrintObject(string(content))
71+
}
72+
73+
func checkInstalled(name string) error {
74+
if _, err := exec.LookPath(name); err != nil {
75+
return fmt.Errorf(name + " is not installed")
76+
}
77+
78+
return nil
79+
}
80+
81+
func historyPath(f util.Factory) string {
82+
return f.GardenHomeDir() + "/" + historyFile
83+
}

pkg/cmd/target/history_test.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
SPDX-FileCopyrightText: 2021 SAP SE or an SAP affiliate company and Gardener contributors
3+
SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package target_test
7+
8+
import (
9+
"os"
10+
11+
"github.com/gardener/gardenctl-v2/internal/util"
12+
"github.com/gardener/gardenctl-v2/pkg/cmd/base"
13+
cmdtarget "github.com/gardener/gardenctl-v2/pkg/cmd/target"
14+
15+
. "github.com/onsi/ginkgo"
16+
. "github.com/onsi/gomega"
17+
)
18+
19+
var _ = Describe("history Command", func() {
20+
21+
const (
22+
historyPath = "./history"
23+
)
24+
25+
var (
26+
streams util.IOStreams
27+
options *base.Options
28+
out *util.SafeBytesBuffer
29+
)
30+
31+
BeforeEach(func() {
32+
streams, _, out, _ = util.NewTestIOStreams()
33+
options = base.NewOptions(streams)
34+
})
35+
36+
AfterSuite(func() {
37+
err := os.Remove(historyPath)
38+
Expect(err).NotTo(HaveOccurred())
39+
})
40+
41+
Describe("#HistoryWrite", func() {
42+
It("should write history file", func() {
43+
err := cmdtarget.HistoryWrite(historyPath, "hello")
44+
Expect(err).NotTo(HaveOccurred())
45+
})
46+
})
47+
48+
Describe("#HistoryOutput", func() {
49+
It("should print history output", func() {
50+
err := cmdtarget.HistoryOutput(historyPath, *options)
51+
Expect(err).NotTo(HaveOccurred())
52+
Expect(out.String()).Should(ContainSubstring("hello"))
53+
})
54+
})
55+
})

pkg/cmd/target/target.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ gardenctl target shoot my-shoot
3737
# Target shoot control-plane using values that match a pattern defined for a specific garden
3838
gardenctl target value/that/matches/pattern --control-plane`,
3939
RunE: base.WrapRunE(o, f),
40+
PostRunE: func(cmd *cobra.Command, args []string) error {
41+
return HistoryWrite(historyPath(f), strings.Join(os.Args[0:], " ")+"\n")
42+
},
4043
}
4144

4245
cmd.AddCommand(NewCmdTargetGarden(f, ioStreams))
@@ -47,7 +50,7 @@ gardenctl target value/that/matches/pattern --control-plane`,
4750

4851
cmd.AddCommand(NewCmdUnset(f, NewUnsetOptions(ioStreams)))
4952
cmd.AddCommand(NewCmdView(f, NewViewOptions(ioStreams)))
50-
53+
cmd.AddCommand(NewCmdHistory(f, o.Options))
5154
o.AddFlags(cmd.Flags())
5255

5356
return cmd

0 commit comments

Comments
 (0)