Skip to content
This repository has been archived by the owner on Jul 25, 2022. It is now read-only.

Commit

Permalink
Merge pull request #512 from tedteng/history
Browse files Browse the repository at this point in the history
History feature
  • Loading branch information
tedteng authored Jul 6, 2021
2 parents ca39a1a + bba62e0 commit f75ad16
Show file tree
Hide file tree
Showing 110 changed files with 11,824 additions and 18 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/gardener/machine-controller-manager v0.27.0
github.com/golang/mock v1.4.3
github.com/jmoiron/jsonq v0.0.0-20150511023944-e874b168d07e
github.com/manifoldco/promptui v0.8.0
github.com/olekukonko/tablewriter v0.0.4
github.com/onsi/ginkgo v1.10.1
github.com/onsi/gomega v1.7.0
Expand Down
16 changes: 16 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.11.4/go.mod h1:ZB+hp7VycxPLpp0aiozQQezat46npDXhzHi1DVtRCn4=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
Expand Down Expand Up @@ -365,6 +371,8 @@ github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGn
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
Expand All @@ -384,6 +392,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw=
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
Expand All @@ -392,13 +402,17 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/manifoldco/promptui v0.8.0 h1:R95mMF+McvXZQ7j1g8ucVZE1gLP3Sv6j9vlF9kyRqQo=
github.com/manifoldco/promptui v0.8.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
Expand All @@ -408,6 +422,7 @@ github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1
github.com/miekg/dns v1.1.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
Expand Down Expand Up @@ -694,6 +709,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down
48 changes: 48 additions & 0 deletions pkg/cmd/history_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"encoding/json"
"errors"
"os"
)

var tmp string

// WriteStringln writes history to given path
func (w *GardenctlHistoryWriter) WriteStringln(historyPath string, i interface{}) error {
f, err := os.OpenFile(historyPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
return err
}

switch x := i.(type) {
case map[string]string:
j, err := json.Marshal(x)
if err != nil {
return err
}
tmp = string(j)

case string:
tmp = x
default:
return errors.New("Invalid type not supported")
}

_, err = f.WriteString(tmp + "\n")
return err
}
6 changes: 5 additions & 1 deletion pkg/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ func Execute() {
CreateDir(pathSessionID, 0751)
pathTarget = filepath.Join(pathSessionID, "target")
CreateFileIfNotExists(pathTarget, 0644)
pathHistory = filepath.Join(pathSessionID, "history")
CreateFileIfNotExists(pathHistory, 0644)
gardenConfig = os.Getenv("GARDENCONFIG")
if gardenConfig != "" {
if _, err := os.Stat(gardenConfig); err != nil {
Expand All @@ -126,6 +128,7 @@ func init() {
targetWriter = &GardenctlTargetWriter{}
kubeconfigReader = &GardenctlKubeconfigReader{}
kubeconfigWriter = &GardenctlKubeconfigWriter{}
historyWriter = &GardenctlHistoryWriter{}
ioStreams = IOStreams{
In: os.Stdin,
Out: os.Stdout,
Expand All @@ -143,7 +146,7 @@ func init() {
// Commands
RootCmd.AddCommand(
NewLsCmd(targetReader, configReader, ioStreams),
NewTargetCmd(targetReader, targetWriter, configReader, ioStreams, kubeconfigReader),
NewTargetCmd(targetReader, targetWriter, configReader, ioStreams, kubeconfigReader, historyWriter),
NewDropCmd(targetReader, targetWriter, ioStreams),
NewGetCmd(targetReader, configReader, kubeconfigReader, kubeconfigWriter, ioStreams))
RootCmd.AddCommand(NewDownloadCmd(targetReader), NewShowCmd(targetReader), NewLogsCmd(targetReader))
Expand All @@ -159,6 +162,7 @@ func init() {
RootCmd.AddCommand(NewInfoCmd(targetReader, ioStreams))
RootCmd.AddCommand(NewVersionCmd(), NewUpdateCheckCmd())
RootCmd.AddCommand(NewDiagCmd(targetReader, ioStreams))
RootCmd.AddCommand(NewHistoryCmd(targetWriter, historyWriter))

RootCmd.SuggestionsMinimumDistance = suggestionsMinimumDistance
RootCmd.BashCompletionFunction = bashCompletionFunc
Expand Down
26 changes: 24 additions & 2 deletions pkg/cmd/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var (
)

// NewTargetCmd returns a new target command.
func NewTargetCmd(targetReader TargetReader, targetWriter TargetWriter, configReader ConfigReader, ioStreams IOStreams, kubeconfigReader KubeconfigReader) *cobra.Command {
func NewTargetCmd(targetReader TargetReader, targetWriter TargetWriter, configReader ConfigReader, ioStreams IOStreams, kubeconfigReader KubeconfigReader, historyWriter HistoryWriter) *cobra.Command {
cmd := &cobra.Command{
Use: "target <project|garden|seed|shoot|namespace|server|dashboardUrl> NAME",
Short: "Set scope for next operations, e.g. \"gardenctl target garden garden_name\" to target garden with name of garden_name",
Expand Down Expand Up @@ -103,6 +103,12 @@ func NewTargetCmd(targetReader TargetReader, targetWriter TargetWriter, configRe
err := urlWrapper(targetReader, targetWriter, configReader, ioStreams, pdashboardurl)
checkError(err)
}

err := historyWriter.WriteStringln(pathHistory, targetInfo)
if err != nil {
return err
}

return nil
}
if len(args) < 1 && pgarden == "" && pproject == "" && pseed == "" && pshoot == "" && pnamespace == "" && pserver == "" && pdashboardurl == "" || len(args) > 5 {
Expand Down Expand Up @@ -267,8 +273,13 @@ func NewTargetCmd(targetReader TargetReader, targetWriter TargetWriter, configRe
checkError(err)
}
}
}

err := historyWriter.WriteStringln(pathHistory, targetInfo)
if err != nil {
return err
}

return nil
},
ValidArgs: []string{"project", "garden", "seed", "shoot", "namespace", "server", "dashboardUrl"},
Expand Down Expand Up @@ -336,6 +347,7 @@ func targetProject(targetReader TargetReader, targetWriter TargetWriter, name st
target.SetStack(new)
err := targetWriter.WriteTarget(pathTarget, target)
checkError(err)
toTargetInfo(target)
}

// resolveNameGarden resolves name to garden
Expand Down Expand Up @@ -398,6 +410,7 @@ func targetGarden(targetWriter TargetWriter, name string) {
checkError(err)
fmt.Println("Garden:")
fmt.Println("KUBECONFIG=" + getKubeConfigOfCurrentTarget())
toTargetInfo(target)
}

// resolveNameSeed resolves name to seed
Expand Down Expand Up @@ -476,10 +489,18 @@ func targetSeed(targetReader TargetReader, targetWriter TargetWriter, name strin

err = targetWriter.WriteTarget(pathTarget, target)
checkError(err)
toTargetInfo(target)
fmt.Println("Seed:")
fmt.Println("KUBECONFIG=" + getKubeConfigOfCurrentTarget())
}

func toTargetInfo(target TargetInterface) {
targetInfo["Cmd"] = strings.Join(os.Args[0:], " ")
for _, k := range target.Stack() {
targetInfo[string(k.Kind)] = k.Name
}
}

// resolveNameShoot resolves name to shoot
func resolveNameShoot(target TargetInterface, name string) []gardencorev1beta1.Shoot {
gardenClientset, err := target.GardenerClient()
Expand Down Expand Up @@ -650,6 +671,7 @@ func targetShoot(targetReader TargetReader, targetWriter TargetWriter, shoot gar
// Write target
err = targetWriter.WriteTarget(pathTarget, &target)
checkError(err)
toTargetInfo(&target)

// Cache shoot kubeconfig
var shootCacheDir string
Expand Down Expand Up @@ -866,7 +888,6 @@ func serverWrapper(reader ConfigReader, serverName string, kubeconfigReader Kube
fmt.Println("a garden could not be matched for the provided server address:", serverName)
os.Exit(2)
}

}

func isServerEquals(server1 string, server2 string) (bool, error) {
Expand Down Expand Up @@ -1222,5 +1243,6 @@ func targetNamespace(targetWriter TargetWriter, ns string) error {
if err != nil {
return err
}
toTargetInfo(&target)
return nil
}
128 changes: 128 additions & 0 deletions pkg/cmd/target_history.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"encoding/json"
"fmt"
"os"

"github.com/gardener/gardenctl/pkg/internal/history"
"github.com/spf13/cobra"
)

const (
targetInfoGarden = "garden"
targetInfoProject = "project"
targetInfoSeed = "seed"
targetInfoShoot = "shoot"
targetInfoNamespace = "namespace"
)

//NewHistoryCmd use for list/search targting history
func NewHistoryCmd(targetWriter TargetWriter, historyWriter HistoryWriter) *cobra.Command {
cmd := &cobra.Command{
Use: "history",
Short: "List/Search targeting history, e.g. \"gardenctl x\"",
SilenceUsage: true,
Aliases: []string{"x"},
RunE: func(cmd *cobra.Command, args []string) error {
h := history.SetPath(pathHistory)

if len(h.Load().Items) <= 0 {
fmt.Println("No Target History results")
os.Exit(0)
}

items := h.Load().Reverse().Select()

m, err := toMap(items.PromptItem)
if err != nil {
return err
}

var target Target
if val, ok := m[targetInfoGarden]; ok {
appendTarget(&target, targetInfoGarden, val)
}

if val, ok := m[targetInfoProject]; ok {
appendTarget(&target, targetInfoProject, val)
}

if val, ok := m[targetInfoSeed]; ok {
appendTarget(&target, targetInfoSeed, val)
}

if val, ok := m[targetInfoShoot]; ok {
appendTarget(&target, targetInfoShoot, val)
}

if val, ok := m[targetInfoNamespace]; ok {
appendTarget(&target, targetInfoNamespace, val)

err := namespaceWrapper(nil, targetWriter, val)
if err != nil {
return err
}
}

err = targetWriter.WriteTarget(pathTarget, &target)
if err != nil {
return fmt.Errorf("error write target %s", err)
}

kubeconfigPathOutput(&target)

err = historyWriter.WriteStringln(pathHistory, items.Item)
if err != nil {
return fmt.Errorf("error write history %s", err)
}

return nil
},
}

return cmd
}

func toMap(item history.PromptItem) (map[string]string, error) {
toMap := make(map[string]string)
tmp, err := json.Marshal(item)
if err != nil {
return nil, fmt.Errorf("convert error")
}

err = json.Unmarshal(tmp, &toMap)
if err != nil {
return nil, fmt.Errorf("convert error")
}
return toMap, nil
}

func appendTarget(target *Target, targetKind TargetKind, name string) *Target {
target.Target = append(target.Target, TargetMeta{targetKind, name})
return target
}

func kubeconfigPathOutput(target *Target) {
for _, k := range target.Target {
if k.Kind != targetInfoProject && k.Kind != TargetKindNamespace {
fmt.Println(k.Kind + ":")
KUBECONFIG = getKubeConfigOfClusterType(k.Kind)
fmt.Println("KUBECONFIG=" + KUBECONFIG)
}
}
}
Loading

0 comments on commit f75ad16

Please sign in to comment.