feat: update tools

This commit is contained in:
franklin 2023-05-25 10:03:43 +02:00
parent adaf7d480a
commit ca1e91d231
31 changed files with 918 additions and 381 deletions

View File

@ -57,7 +57,7 @@ linters:
#- gci # Gci controls golang package import order and makes it always deterministic. [fast: true, auto-fix: false]
#- gochecknoglobals # check that no global variables exist [fast: true, auto-fix: false]
#- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
- gocognit # Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
#- gocognit # Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
- gocritic # Provides diagnostics that check for bugs, performance and style issues. [fast: false, auto-fix: false]
- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]

View File

@ -149,14 +149,30 @@ func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
return err
}
if route.Username != nil && route.Password != nil {
if username, err := c.op.Get(ctx, *route.Username); err != nil {
return err
} else if password, err := c.op.Get(ctx, *route.Password); err != nil {
return err
} else {
u.User = url.UserPassword(username, password)
if route.BasicAuth != nil {
var (
username string
password string
)
{
secret := *route.BasicAuth
secret.Field = "username"
if value, err := c.op.Get(ctx, secret); err != nil {
return err
} else {
username = value
}
}
{
secret := *route.BasicAuth
secret.Field = "password"
if value, err := c.op.Get(ctx, secret); err != nil {
return err
} else {
password = value
}
}
u.User = url.UserPassword(username, password)
}
return browser.OpenURL(u)

View File

@ -14,7 +14,6 @@ type (
ConfigRoute struct {
Path string `yaml:"path"`
Description string `yaml:"description"`
Username *onepassword.Secret `yaml:"username"`
Password *onepassword.Secret `yaml:"password"`
BasicAuth *onepassword.Secret `yaml:"basicAuth"`
}
)

View File

@ -75,6 +75,15 @@ func NewCommand(l log.Logger, kubectl *kubectl.Kubectl, squadron *squadron.Squad
Suggest: inst.completeSquadrons,
},
},
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
if r.Args().HasIndex(0) {
fs.Internal().String("profile", "", "Profile to use.")
if err := fs.Internal().SetValues("profile", inst.kubectl.Cluster(r.Args().At(0)).Profiles(ctx)...); err != nil {
return err
}
}
return nil
},
Execute: inst.execute,
})
return inst
@ -109,10 +118,17 @@ func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
// ------------------------------------------------------------------------------------------------
func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
ifs := r.FlagSets().Internal()
cluster, fleet, squad := r.Args().At(0), r.Args().At(1), r.Args().At(2)
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
return shell.New(ctx, c.l, "k9s", "-n", c.namespaceFn(cluster, fleet, squad), "--logoless").
Args(r.AdditionalArgs()...).
Env(c.kubectl.Cluster(cluster).Env()).
Env(c.kubectl.Cluster(cluster).Env(profile)).
Run()
}

View File

@ -112,9 +112,9 @@ func (c *Command) completePaths(ctx context.Context) []goprompt.Suggest {
//nolint:forcetypeassert
func (c *Command) paths(ctx context.Context) []string {
return c.cache.Get("paths", func() any {
if value, err := files.Find(ctx, ".", "zeus"); err != nil {
if value, err := files.Find(ctx, ".", "zeus", files.FindWithIgnore(`^\.`, "node_modules"), files.FindWithIsDir(true)); err != nil {
c.l.Debug("failed to walk files", err.Error())
return nil
return []string{}
} else {
return value
}

View File

@ -9,7 +9,9 @@ import (
"strings"
prompt2 "github.com/c-bata/go-prompt"
"github.com/foomo/posh-providers/kubernets/kubectl"
"github.com/foomo/posh/pkg/command/tree"
"github.com/foomo/posh/pkg/env"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/prompt/goprompt"
"github.com/foomo/posh/pkg/readline"
@ -21,6 +23,7 @@ import (
type Command struct {
l log.Logger
etcd *ETCD
kubectl *kubectl.Kubectl
commandTree tree.Root
}
@ -28,21 +31,33 @@ type Command struct {
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewCommand(l log.Logger, etcd *ETCD, opts ...Option) *Command {
func NewCommand(l log.Logger, etcd *ETCD, kubectl *kubectl.Kubectl, opts ...Option) *Command {
inst := &Command{
l: l.Named("etcd"),
etcd: etcd,
l: l.Named("etcd"),
etcd: etcd,
kubectl: kubectl,
}
pathArg := &tree.Arg{
Name: "path",
Suggest: func(ctx context.Context, t tree.Root, r *readline.Readline) []prompt2.Suggest {
if value, ok := inst.etcd.cfg.Cluster(r.Args().At(0)); ok {
return suggests.List(value.Paths)
}
return nil
args := tree.Args{
{
Name: "path",
Suggest: func(ctx context.Context, t tree.Root, r *readline.Readline) []prompt2.Suggest {
if value, ok := inst.etcd.cfg.Cluster(r.Args().At(0)); ok {
return suggests.List(value.Paths)
}
return nil
},
},
}
flags := func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
if r.Args().HasIndex(0) {
fs.Internal().String("profile", "", "Profile to use.")
if err := fs.Internal().SetValues("profile", inst.kubectl.Cluster(r.Args().At(0)).Profiles(ctx)...); err != nil {
return err
}
}
return nil
}
inst.commandTree = tree.New(&tree.Node{
Name: "etcd",
@ -62,12 +77,14 @@ func NewCommand(l log.Logger, etcd *ETCD, opts ...Option) *Command {
Nodes: tree.Nodes{
{
Name: "get",
Args: tree.Args{pathArg},
Args: args,
Flags: flags,
Execute: inst.get,
},
{
Name: "edit",
Args: tree.Args{pathArg},
Args: args,
Flags: flags,
Execute: inst.edit,
},
},
@ -108,9 +125,16 @@ func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
func (c *Command) get(ctx context.Context, r *readline.Readline) error {
etcdPath := r.Args().At(2)
ifs := r.FlagSets().Internal()
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
if cluster, ok := c.etcd.cfg.Cluster(r.Args().At(0)); !ok {
return errors.New("invalid cluster")
} else if out, err := c.etcd.GetPath(ctx, cluster, etcdPath); err != nil {
} else if out, err := c.etcd.GetPath(ctx, cluster, profile, etcdPath); err != nil {
return errors.Wrap(err, out)
} else {
prints.Code(c.l, etcdPath, out+"\n", "yaml")
@ -129,10 +153,16 @@ func (c *Command) edit(ctx context.Context, r *readline.Readline) error {
}
etcdPath := r.Args().At(2)
filename := path.Join(os.Getenv("PROJECT_ROOT"), c.etcd.cfg.ConfigPath, etcdPath)
ifs := r.FlagSets().Internal()
filename := env.Path(c.etcd.cfg.ConfigPath, etcdPath)
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
{ // retrieve data
if value, err := c.etcd.GetPath(ctx, cluster, etcdPath); err != nil {
if value, err := c.etcd.GetPath(ctx, cluster, profile, etcdPath); err != nil {
return err
} else {
prev = []byte(strings.ReplaceAll(value, "\r\r\n", "\n"))
@ -173,7 +203,7 @@ func (c *Command) edit(ctx context.Context, r *readline.Readline) error {
}
c.l.Info("updating config")
if out, err := c.etcd.SetPath(ctx, cluster, etcdPath, string(next)); err != nil {
if out, err := c.etcd.SetPath(ctx, cluster, profile, etcdPath, string(next)); err != nil {
return errors.Wrap(err, out)
}
return nil

View File

@ -65,13 +65,13 @@ func New(l log.Logger, kubectl *kubectl.Kubectl, opts ...Option) (*ETCD, error)
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *ETCD) GetPath(ctx context.Context, cluster Cluster, path string) (string, error) {
func (c *ETCD) GetPath(ctx context.Context, cluster Cluster, profile, path string) (string, error) {
if out, err := shell.New(ctx, c.l, "kubectl", "exec",
"-it", cluster.PodName,
"--namespace", cluster.Namespace,
"--", "/bin/sh", "-c", "'etcdctl get "+path+" --print-value-only'",
).
Env(c.kubectl.Cluster(cluster.Name).Env()).
Env(c.kubectl.Cluster(cluster.Name).Env(profile)).
Output(); err != nil {
return "", err
} else {
@ -79,13 +79,13 @@ func (c *ETCD) GetPath(ctx context.Context, cluster Cluster, path string) (strin
}
}
func (c *ETCD) SetPath(ctx context.Context, cluster Cluster, path, value string) (string, error) {
func (c *ETCD) SetPath(ctx context.Context, cluster Cluster, profile, path, value string) (string, error) {
if out, err := shell.New(ctx, c.l, "kubectl", "exec",
"-it", cluster.PodName,
"--namespace", cluster.Namespace,
"--", "/bin/sh", "-c", fmt.Sprintf("'echo \"%s\" | etcdctl put "+path+"'", strings.ReplaceAll(value, "\n", "\\n")),
).
Env(c.kubectl.Cluster(cluster.Name).Env()).
Env(c.kubectl.Cluster(cluster.Name).Env(profile)).
Output(); err != nil {
return "", err
} else {

View File

@ -159,7 +159,7 @@ func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
//nolint:forcetypeassert
func (c *Command) paths(ctx context.Context) []string {
return c.cache.Get("paths", func() any {
if value, err := files.Find(ctx, ".", "gocontentful.yml"); err != nil {
if value, err := files.Find(ctx, ".", "gocontentful.yaml", files.FindWithIgnore(`^\.`, "node_modules")); err != nil {
c.l.Debug("failed to walk files", err.Error())
return []string{}
} else {

View File

@ -40,8 +40,9 @@ func NewCommand(l log.Logger, cache cache.Cache) *Command {
},
Args: tree.Args{
{
Name: "path",
Suggest: inst.completePaths,
Name: "path",
Optional: true,
Suggest: inst.completePaths,
},
},
Execute: inst.execute,

View File

@ -101,6 +101,15 @@ func NewCommand(l log.Logger, squadron *Squadron, kubectl *kubectl.Kubectl, op *
fs.Internal().Bool("slack", false, "send slack notification")
}
}
profileFlag := func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
if r.Args().HasIndex(0) {
fs.Internal().String("profile", "", "Profile to use.")
if err := fs.Internal().SetValues("profile", inst.kubectl.Cluster(r.Args().At(0)).Profiles(ctx)...); err != nil {
return err
}
}
return nil
}
commonFlags := func(fs *readline.FlagSets) {
fs.Internal().Bool("no-override", false, "ignore override files")
fs.Default().Bool("verbose", inst.l.IsLevel(log.LevelDebug), "set verbose level")
@ -153,6 +162,9 @@ func NewCommand(l log.Logger, squadron *Squadron, kubectl *kubectl.Kubectl, op *
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
slackFlag(fs)
commonFlags(fs)
if err := profileFlag(ctx, r, fs); err != nil {
return err
}
fs.Default().Bool("diff", false, "show diff")
fs.Default().Bool("push", false, "push image")
fs.Default().Bool("build", false, "build image")
@ -178,8 +190,11 @@ func NewCommand(l log.Logger, squadron *Squadron, kubectl *kubectl.Kubectl, op *
Description: "Uninstalls the squadron chart",
Args: tree.Args{unitsArg},
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
commonFlags(fs)
slackFlag(fs)
commonFlags(fs)
if err := profileFlag(ctx, r, fs); err != nil {
return err
}
return nil
},
Execute: inst.execute,
@ -216,6 +231,9 @@ func NewCommand(l log.Logger, squadron *Squadron, kubectl *kubectl.Kubectl, op *
Args: tree.Args{unitsArg},
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
commonFlags(fs)
if err := profileFlag(ctx, r, fs); err != nil {
return err
}
return nil
},
Execute: inst.execute,
@ -236,9 +254,12 @@ func NewCommand(l log.Logger, squadron *Squadron, kubectl *kubectl.Kubectl, op *
Description: "Roll back the squadron chart",
Args: tree.Args{unitsArg},
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
slackFlag(fs)
commonFlags(fs)
fs.Default().String("revision", "", "revision number to rollback to")
slackFlag(fs)
if err := profileFlag(ctx, r, fs); err != nil {
return err
}
return nil
},
Execute: inst.execute,
@ -316,9 +337,14 @@ func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
tag, _ := ifs.GetString("tag")
noOverride := log.MustGet(ifs.GetBool("no-override"))(c.l)
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
{ // handle 1password
if c.op != nil {
if ok, _ := c.op.Session(); !ok {
if ok, _ := c.op.IsAuthenticated(); !ok {
c.l.Info("missing 1password session, please login")
if err := c.op.SignIn(ctx); err != nil {
return err
@ -343,7 +369,7 @@ func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
if tag != "" {
env = append(env, fmt.Sprintf("TAG=%q", tag))
}
env = append(env, c.kubectl.Cluster(cluster).Env())
env = append(env, c.kubectl.Cluster(cluster).Env(profile))
}
{ // handle squadrons

29
go.mod
View File

@ -8,30 +8,35 @@ require (
github.com/1Password/connect-sdk-go v1.5.0
github.com/c-bata/go-prompt v0.2.6
github.com/cloudrecipes/packagejson v1.0.0
github.com/foomo/posh v0.4.0
github.com/foomo/posh v0.4.1
github.com/google/go-github/v47 v47.1.0
github.com/joho/godotenv v1.5.1
github.com/pkg/errors v0.9.1
github.com/pterm/pterm v0.12.57
github.com/pterm/pterm v0.12.62
github.com/samber/lo v1.38.1
github.com/slack-go/slack v0.12.1
github.com/slack-go/slack v0.12.2
github.com/spf13/viper v1.15.0
golang.org/x/exp v0.0.0-20230126173853-a67bb567ff2e
golang.org/x/sync v0.1.0
golang.org/x/exp v0.0.0-20230307190834-24139beb5833
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783
golang.org/x/sync v0.2.0
gopkg.in/yaml.v3 v3.0.1
)
require (
atomicgo.dev/cursor v0.1.1 // indirect
atomicgo.dev/keyboard v0.2.9 // indirect
atomicgo.dev/schedule v0.0.2 // indirect
github.com/alecthomas/chroma v0.10.0 // indirect
github.com/charlievieth/fastwalk v1.0.1 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gookit/color v1.5.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/gookit/color v1.5.3 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/lithammer/fuzzysearch v1.1.5 // indirect
github.com/lithammer/fuzzysearch v1.1.8 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
@ -51,9 +56,13 @@ require (
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/term v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

74
go.sum
View File

@ -3,6 +3,8 @@ atomicgo.dev/cursor v0.1.1 h1:0t9sxQomCTRh5ug+hAMCs59x/UmC9QL6Ci5uosINKD4=
atomicgo.dev/cursor v0.1.1/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU=
atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8=
atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ=
atomicgo.dev/schedule v0.0.2 h1:2e/4KY6t3wokja01Cyty6qgkQM8MotJzjtqCH70oX2Q=
atomicgo.dev/schedule v0.0.2/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@ -86,8 +88,8 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/foomo/posh v0.4.0 h1:vL+EJ+nQKaswAnrqvMn9ptx+s/BY6xOddHY/aJPIxug=
github.com/foomo/posh v0.4.0/go.mod h1:+ir4dZiQ3ReOQP3cfpK8IAYd4xymMOEpHaOxbWJ32mc=
github.com/foomo/posh v0.4.1 h1:2gUEzrwlNS/KqVOq5DcQi7oHovrsDQOJ6wJSjchxDV0=
github.com/foomo/posh v0.4.1/go.mod h1:Q631XvEisDS5UDJe4UO10R8ENBMO9c9+qmSPM0CV2WI=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/franklinkim/go-prompt v0.2.7-0.20210427061716-a8f4995d7aa5 h1:kXNtle4AoQnngdm+gwt4ku6Llbzw3EFHgZYpL618JaI=
github.com/franklinkim/go-prompt v0.2.7-0.20210427061716-a8f4995d7aa5/go.mod h1:+syUfnvYJUO5A+6QMQYXAyzkxHMNlj9dH2LIeQfBSjc=
@ -124,6 +126,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@ -135,8 +140,13 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-github/v47 v47.1.0 h1:Cacm/WxQBOa9lF0FT0EMjZ2BWMetQ1TQfyurn4yF1z8=
github.com/google/go-github/v47 v47.1.0/go.mod h1:VPZBXNbFSJGjyjFRUKo9vZGawTajnWzC/YjGw/oFKi0=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -159,8 +169,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg=
github.com/gookit/color v1.5.3 h1:twfIhZs4QLCtimkP7MOxlF3A0U/5cDPseRT9M/+2SCE=
github.com/gookit/color v1.5.3/go.mod h1:NUzwzeehUfl7GIb36pqId+UGmRfQcU/WiiyTTeNjHtE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@ -188,8 +198,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c=
github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@ -230,8 +240,8 @@ github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEej
github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE=
github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8=
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
github.com/pterm/pterm v0.12.57 h1:HTjDUmILmh6hIsEidRdpxQAiqcoHCdvRCxIR3KZ0/XE=
github.com/pterm/pterm v0.12.57/go.mod h1:7rswprkyxYOse1IMh79w42jvReNHxro4z9oHfqjIdzM=
github.com/pterm/pterm v0.12.62 h1:Xjj5Wl6UR4Il9xOiDUOZRwReRTdO75if/JdWsn9I59s=
github.com/pterm/pterm v0.12.62/go.mod h1:+c3ujjE7N5qmNx6eKAa7YVSC6m/gCorJJKhzwYTbL90=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@ -241,8 +251,8 @@ github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/slack-go/slack v0.12.1 h1:X97b9g2hnITDtNsNe5GkGx6O2/Sz/uC20ejRZN6QxOw=
github.com/slack-go/slack v0.12.1/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ=
github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
@ -266,7 +276,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
@ -280,6 +290,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@ -294,7 +305,10 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -308,8 +322,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230126173853-a67bb567ff2e h1:nEzRHNOazEST44vMvEwxGxnYGrzXEmxJmnti5mKSWTk=
golang.org/x/exp v0.0.0-20230126173853-a67bb567ff2e/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/exp v0.0.0-20230307190834-24139beb5833 h1:SChBja7BCQewoTAU7IgvucQKMIXrEpFxNMs0spT3/5s=
golang.org/x/exp v0.0.0-20230307190834-24139beb5833/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@ -334,6 +348,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -365,6 +381,10 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -374,6 +394,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk=
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -384,8 +406,10 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -432,15 +456,19 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -448,8 +476,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -502,6 +531,8 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
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/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -535,6 +566,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -598,6 +630,10 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

147
goharbor/harbor/command.go Normal file
View File

@ -0,0 +1,147 @@
package harbor
import (
"context"
"os"
"github.com/foomo/posh/pkg/command/tree"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/prompt/goprompt"
"github.com/foomo/posh/pkg/readline"
"github.com/foomo/posh/pkg/shell"
"github.com/foomo/posh/pkg/util"
"github.com/foomo/posh/pkg/util/browser"
"github.com/google/go-github/v47/github"
"github.com/pterm/pterm"
"github.com/spf13/viper"
"golang.org/x/oauth2"
)
type (
Command struct {
l log.Logger
cfg Config
name string
configKey string
commandTree tree.Root
}
CommandOption func(*Command)
)
// ------------------------------------------------------------------------------------------------
// ~ Options
// ------------------------------------------------------------------------------------------------
func CommandWithName(v string) CommandOption {
return func(o *Command) {
o.name = v
}
}
func WithConfigKey(v string) CommandOption {
return func(o *Command) {
o.configKey = v
}
}
// ------------------------------------------------------------------------------------------------
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewCommand(l log.Logger, opts ...CommandOption) *Command {
inst := &Command{
l: l.Named("harbor"),
name: "harbor",
configKey: "open",
}
for _, opt := range opts {
if opt != nil {
opt(inst)
}
}
if err := viper.UnmarshalKey(inst.configKey, &inst.cfg); err != nil {
return nil
}
inst.commandTree = tree.New(&tree.Node{
Name: inst.name,
Description: "Run harbor",
Execute: inst.auth,
Nodes: tree.Nodes{
{
Name: "auth",
Args: nil,
Description: "Sign in to Harbor",
Execute: inst.auth,
},
{
Name: "docker",
Args: nil,
Description: "Configure docker.",
Execute: inst.docker,
},
},
})
return inst
}
// ------------------------------------------------------------------------------------------------
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *Command) Name() string {
return c.commandTree.Node().Name
}
func (c *Command) Description() string {
return c.commandTree.Node().Description
}
func (c *Command) Complete(ctx context.Context, r *readline.Readline) []goprompt.Suggest {
return c.commandTree.Complete(ctx, r)
}
func (c *Command) Execute(ctx context.Context, r *readline.Readline) error {
return c.commandTree.Execute(ctx, r)
}
func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
return c.commandTree.Help(ctx, r)
}
// ------------------------------------------------------------------------------------------------
// ~ Private methods
// ------------------------------------------------------------------------------------------------
func (c *Command) auth(ctx context.Context, r *readline.Readline) error {
return browser.OpenRawURL(c.cfg.AuthURL)
}
func (c *Command) docker(ctx context.Context, r *readline.Readline) error {
client := github.NewClient(
oauth2.NewClient(
ctx,
oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
),
),
)
var username string
user, _, err := client.Users.Get(ctx, "")
if err == nil && user != nil && user.Login != nil {
username = *user.Login
} else if username, err = util.Prompt("github username"); err != nil {
return err
}
pterm.Info.Println("registry: " + c.cfg.URL)
pterm.Info.Println("username: " + username)
pterm.Info.Println("please enter your CLI secret as password...")
return shell.New(ctx, c.l, "docker", "login", c.cfg.URL, "-u", username).
Args(r.AdditionalArgs()...).
Args(r.AdditionalFlags()...).
Run()
}

View File

@ -0,0 +1,6 @@
package harbor
type Config struct {
URL string `json:"url" yaml:"url"`
AuthURL string `json:"authUrl" yaml:"authUrl"`
}

View File

@ -2,18 +2,19 @@ package gcloud
import (
"context"
"fmt"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/prompt/check"
)
func AccountChecker(p *GCloud) check.Checker {
func AuthChecker(p *GCloud) check.Checker {
return func(ctx context.Context, l log.Logger) check.Info {
name := "GCloud: Account"
name := "GCloud"
if account, err := p.ActiveAccount(ctx, l); err != nil {
return check.NewFailureInfo(name, "Error: "+err.Error())
} else {
return check.NewSuccessInfo(name, account)
return check.NewSuccessInfo(name, fmt.Sprintf("Authenticated (%s)", account))
}
}
}

View File

@ -108,6 +108,10 @@ func NewCommand(l log.Logger, gcloud *GCloud, kubectl *kubectl.Kubectl, opts ...
},
},
},
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
fs.Internal().String("profile", "", "Store credentials in given profile.")
return fs.Internal().SetValues("profile", "gcloud")
},
Execute: inst.containerClustersGetCredentials,
},
},
@ -206,11 +210,14 @@ func (c *Command) authConfigureDocker(ctx context.Context, r *readline.Readline)
func (c *Command) containerClustersGetCredentials(ctx context.Context, r *readline.Readline) error {
var args []string
ifs := r.FlagSets().Internal()
clusterName := r.Args().At(1)
cluster, err := c.gcloud.cfg.Cluster(clusterName)
if err != nil {
return errors.Errorf("failed to retrieve cluster for: %q", clusterName)
}
kubectlCluster := c.kubectl.Cluster(c.clusterNameFn(clusterName, cluster))
if kubectlCluster == nil {
return errors.Errorf("failed to retrieve kubectl cluster for: %q", cluster.Name)
@ -224,12 +231,17 @@ func (c *Command) containerClustersGetCredentials(ctx context.Context, r *readli
}
}
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
return shell.New(ctx, c.l, "gcloud", "container", "clusters", "get-credentials", cluster.Name,
"--project", cluster.Project,
"--region", cluster.Region,
).
Args(args...).
Args(r.AdditionalArgs()...).
Env(kubectlCluster.Env()).
Env(kubectlCluster.Env(profile)).
Run()
}

View File

@ -0,0 +1,19 @@
package teleport
import (
"context"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/prompt/check"
)
func AuthChecker(p *Teleport) check.Checker {
return func(ctx context.Context, l log.Logger) check.Info {
name := "Teleport"
if p.IsAuthenticated(ctx) {
return check.NewSuccessInfo(name, "Authenticated")
} else {
return check.NewFailureInfo(name, "Run `teleport auth` to sign into teleport")
}
}
}

View File

@ -14,34 +14,54 @@ import (
"github.com/foomo/posh/pkg/util/suggests"
)
type Command struct {
l log.Logger
name string
cache cache.Cache
kubectl *kubectl.Kubectl
teleport *Teleport
commandTree tree.Root
type (
Command struct {
l log.Logger
name string
cache cache.Cache
kubectl *kubectl.Kubectl
teleport *Teleport
commandTree tree.Root
}
CommandOption func(*Command)
)
// ------------------------------------------------------------------------------------------------
// ~ Options
// ------------------------------------------------------------------------------------------------
func CommandWithName(v string) CommandOption {
return func(o *Command) {
o.name = v
}
}
// ------------------------------------------------------------------------------------------------
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewCommand(l log.Logger, cache cache.Cache, teleport *Teleport, kubectl *kubectl.Kubectl, opts ...Option) *Command {
func NewCommand(l log.Logger, cache cache.Cache, teleport *Teleport, kubectl *kubectl.Kubectl, opts ...CommandOption) *Command {
inst := &Command{
l: l.Named("teleport"),
name: "teleport",
cache: cache,
kubectl: kubectl,
teleport: teleport,
}
for _, opt := range opts {
if opt != nil {
opt(inst)
}
}
inst.commandTree = tree.New(&tree.Node{
Name: "teleport",
Description: "Manage access points through teleport",
Execute: inst.auth,
Nodes: tree.Nodes{
{
Name: "login",
Execute: inst.login,
Name: "auth",
Execute: inst.auth,
},
{
Name: "kubeconfig",
@ -55,6 +75,10 @@ func NewCommand(l log.Logger, cache cache.Cache, teleport *Teleport, kubectl *ku
},
},
},
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
fs.Internal().String("profile", "", "Profile to use.")
return fs.Internal().SetValues("profile", "teleport")
},
Execute: inst.kubeconfig,
},
{
@ -74,64 +98,6 @@ func NewCommand(l log.Logger, cache cache.Cache, teleport *Teleport, kubectl *ku
},
})
/*
// Execute ...
func (c *Teleport) Execute(args, passArgs, pipeArgs []string) error {
var env []string
cmd, args := args[0], args[1:]
env = append(env, "HOME="+path.Join(os.Getenv("PROJECT_ROOT"), "devops", "config"))
switch cmd {
case "login":
if err := shell.New("tsh", "login").
WithArgs(
"--auth=github",
fmt.Sprintf("--proxy=%s:443", c.config().Hostname),
).
WithPassArgs(passArgs...).
WithPipeArgs(pipeArgs...).
WithEnv(env).
Run(); err != nil {
return err
}
case "database":
database, _ := args[0], args[1:]
databaseUser := "developers"
if value := os.Getenv("TELEPORT_DATABASE_USER"); value != "" {
databaseUser = value
}
if err := shell.New("tsh", "db", "login", "--db-user", databaseUser, database).
WithPassArgs(passArgs...).
WithPipeArgs(pipeArgs...).
WithEnv(env).
Run(); err != nil {
return err
}
case "kubeconfig":
cluster, _ := args[0], args[1:]
env = append(env, fmt.Sprintf("KUBECONFIG=%s", kubectl.Cluster(cluster).GetConfig()))
// delete old config
kubectl.Cluster(cluster).DeleteConfig()
// generate & filter new config
if err := shell.New("tsh", "kube", "login", cluster).
WithPassArgs(passArgs...).
WithPipeArgs(pipeArgs...).
WithEnv(env).
Run(); err != nil {
return err
} else if err = config.GenerateTeleportKubeconfig(kubectl.Cluster(cluster).GetConfig(), cluster); err != nil {
return errors.Wrap(err, "failed to create teleport kubeconfig")
}
}
cache.Clear("")
return nil
}
*/
return inst
}
@ -167,7 +133,6 @@ func (c *Command) database(ctx context.Context, r *readline.Readline) error {
databse := r.Args().At(1)
return shell.New(ctx, c.l, "tsh", "db", "login",
fmt.Sprintf("--proxy=%s", c.teleport.Config().Hostname),
"--db-user", c.teleport.Config().Database.EnvUser(),
databse,
).
@ -178,26 +143,31 @@ func (c *Command) database(ctx context.Context, r *readline.Readline) error {
}
func (c *Command) kubeconfig(ctx context.Context, r *readline.Readline) error {
ifs := r.FlagSets().Internal()
cluster := c.kubectl.Cluster(r.Args().At(1))
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
// delete old config
if err := cluster.DeleteConfig(); err != nil {
if err := cluster.DeleteConfig(profile); err != nil {
return err
}
// generate & filter new config
return shell.New(ctx, c.l, "tsh", "kube", "login",
fmt.Sprintf("--proxy=%s", c.teleport.Config().Hostname),
cluster.Name(),
).
Env(cluster.Env()).
Env(cluster.Env(profile)).
Args(r.Flags()...).
Args(r.AdditionalArgs()...).
Args(r.AdditionalFlags()...).
Run()
}
func (c *Command) login(ctx context.Context, r *readline.Readline) error {
func (c *Command) auth(ctx context.Context, r *readline.Readline) error {
if err := shell.New(ctx, c.l, "tsh", "login",
fmt.Sprintf("--proxy=%s", c.teleport.Config().Hostname),
"--auth=github",

View File

@ -76,7 +76,7 @@ func (t *Teleport) Config() Config {
return t.cfg
}
func (t *Teleport) IsSignedIn(ctx context.Context) bool {
func (t *Teleport) IsAuthenticated(ctx context.Context) bool {
if t.signedIn && time.Since(t.signedInTime) < 12*time.Hour {
return true
} else if _, err := shell.New(ctx, t.l, "tsh", "status").Quiet().Output(); err != nil {
@ -90,8 +90,10 @@ func (t *Teleport) IsSignedIn(ctx context.Context) bool {
}
// Clusters returns a list of cluster
//
//nolint:forcetypeassert
func (t *Teleport) Clusters(ctx context.Context) []string {
if !t.IsSignedIn(ctx) {
if !t.IsAuthenticated(ctx) {
return nil
}
return t.cache.Get("clusters", func() interface{} {
@ -102,7 +104,6 @@ func (t *Teleport) Clusters(ctx context.Context) []string {
}
value, err := shell.New(ctx, t.l, "tsh", "kube", "ls",
fmt.Sprintf("--proxy=%s", t.cfg.Hostname),
fmt.Sprintf("--query='%s'", t.cfg.Query()),
"--format", "json",
).
@ -126,8 +127,10 @@ func (t *Teleport) Clusters(ctx context.Context) []string {
}
// Databases returns a list of cluster
//
//nolint:forcetypeassert
func (t *Teleport) Databases(ctx context.Context) []string {
if !t.IsSignedIn(ctx) {
if !t.IsAuthenticated(ctx) {
return nil
}
return t.cache.Get("databases", func() interface{} {
@ -142,7 +145,6 @@ func (t *Teleport) Databases(ctx context.Context) []string {
}
)
value, err := shell.New(ctx, t.l, "tsh", "db", "ls",
fmt.Sprintf("--proxy=%s", t.cfg.Hostname),
fmt.Sprintf("--query='%s'", t.cfg.Query()),
"--format", "json",
).

18
hashicorp/cdktf/README.md Normal file
View File

@ -0,0 +1,18 @@
# POSH CDKTF provider
## Config
```yaml
cdktf:
path: devops/cdktf
```
## Usage
```go
func New(l log.Logger) (plugin.Plugin, error) {
// ...
inst.commands.Add(helm.NewCommand(l, kubectl))
// ...
}
```

181
hashicorp/cdktf/command.go Normal file
View File

@ -0,0 +1,181 @@
package cdktf
import (
"context"
"errors"
"os/exec"
"github.com/foomo/posh/pkg/cache"
"github.com/foomo/posh/pkg/command/tree"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/prompt/goprompt"
"github.com/foomo/posh/pkg/readline"
"github.com/foomo/posh/pkg/shell"
"github.com/spf13/viper"
)
type (
Command struct {
l log.Logger
cfg Config
name string
cache cache.Namespace
configKey string
commandTree tree.Root
}
CommandOption func(*Command)
)
// ------------------------------------------------------------------------------------------------
// ~ Options
// ------------------------------------------------------------------------------------------------
func CommandWithName(v string) CommandOption {
return func(o *Command) {
o.name = v
}
}
func WithConfigKey(v string) CommandOption {
return func(o *Command) {
o.configKey = v
}
}
// ------------------------------------------------------------------------------------------------
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewCommand(l log.Logger, cache cache.Cache, opts ...CommandOption) (*Command, error) {
inst := &Command{
l: l.Named("cdktf"),
name: "cdktf",
cache: cache.Get("cdktf"),
}
for _, opt := range opts {
if opt != nil {
opt(inst)
}
}
if err := viper.UnmarshalKey(inst.configKey, &inst.cfg); err != nil {
return nil, err
}
inst.commandTree = tree.New(&tree.Node{
Name: inst.name,
Description: "Run cdktf",
Nodes: tree.Nodes{
{
Name: "list",
Description: "List stacks in app",
Execute: inst.list,
},
{
Name: "diff",
Description: "Perform a diff (terraform plan) for the given stack",
Execute: inst.diff,
},
{
Name: "deploy",
Description: "Deploy the given stacks",
Execute: inst.deploy,
},
{
Name: "destroy",
Description: "Destroy the given stacks",
Execute: inst.destroy,
},
{
Name: "output",
Description: "Prints the output of stacks",
Execute: inst.output,
},
},
})
return inst, nil
}
// ------------------------------------------------------------------------------------------------
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *Command) Name() string {
return c.commandTree.Node().Name
}
func (c *Command) Description() string {
return c.commandTree.Node().Description
}
func (c *Command) Complete(ctx context.Context, r *readline.Readline) []goprompt.Suggest {
return c.commandTree.Complete(ctx, r)
}
func (c *Command) Execute(ctx context.Context, r *readline.Readline) error {
return c.commandTree.Execute(ctx, r)
}
func (c *Command) Validate(ctx context.Context, r *readline.Readline) error {
if _, err := exec.LookPath("cdktf"); err != nil {
c.l.Print()
return errors.New(`
Please ensure you have the cdktf installed!
- Install binary:
$ npm install --global cdktf-cli
`)
}
return nil
}
func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
return c.commandTree.Help(ctx, r)
}
// ------------------------------------------------------------------------------------------------
// ~ Private methods
// ------------------------------------------------------------------------------------------------
func (c *Command) list(ctx context.Context, r *readline.Readline) error {
return shell.New(ctx, c.l, "cdktf", "list").
Dir(c.cfg.Path).
Run()
}
func (c *Command) diff(ctx context.Context, r *readline.Readline) error {
return shell.New(ctx, c.l, "cdktf", "diff").
Dir(c.cfg.Path).
Run()
}
func (c *Command) deploy(ctx context.Context, r *readline.Readline) error {
return shell.New(ctx, c.l, "cdktf", "deploy").
Dir(c.cfg.Path).
Run()
}
func (c *Command) destroy(ctx context.Context, r *readline.Readline) error {
return shell.New(ctx, c.l, "cdktf", "destroy").
Dir(c.cfg.Path).
Run()
}
func (c *Command) output(ctx context.Context, r *readline.Readline) error {
return shell.New(ctx, c.l, "cdktf", "output").
Dir(c.cfg.Path).
Run()
}
//nolint:forcetypeassert
//func (c *Command) paths(ctx context.Context) []string {
// return c.cache.Get("paths", func() any {
// if value, err := files.Find(ctx, ".", "cdktf.yml"); err != nil {
// c.l.Debug("failed to walk files", err.Error())
// return []string{}
// } else {
// return value
// }
// }).([]string)
//}

View File

@ -0,0 +1,5 @@
package cdktf
type Config struct {
Path string `yaml:"path"`
}

View File

@ -2,6 +2,7 @@ package helm
import (
"context"
"fmt"
"github.com/foomo/posh-providers/kubernets/kubectl"
"github.com/foomo/posh/pkg/command/tree"
@ -43,7 +44,8 @@ func NewCommand(l log.Logger, kubectl *kubectl.Kubectl) *Command {
name: "helm",
kubectl: kubectl,
}
allFlags := func(fs *readline.FlagSets) {
allFlags := func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
fs.Default().Bool("help", false, "help for helm")
fs.Default().Bool("debug", false, "enable verbose output")
fs.Default().String("namespace", "", "namespace scope for this request")
@ -53,6 +55,13 @@ func NewCommand(l log.Logger, kubectl *kubectl.Kubectl) *Command {
fs.Default().Bool("dry-run", false, "assume aws profile")
fs.Default().Bool("atomic", false, "delete installation on failure")
fs.Default().Bool("wait", false, "wait until all resources a ready")
fs.Internal().String("profile", "", "Profile to use.")
if r.Args().HasIndex(0) {
if err := fs.Internal().SetValues("profile", inst.kubectl.Cluster(r.Args().At(0)).Profiles(ctx)...); err != nil {
return err
}
}
return nil
}
inst.commandTree = tree.New(&tree.Node{
@ -69,46 +78,33 @@ func NewCommand(l log.Logger, kubectl *kubectl.Kubectl) *Command {
{
Name: "create",
Description: "Create a new chart with the given name",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "dependency",
Description: "Manage a chart's dependencies",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "diff",
Description: "Preview helm upgrade changes as a diff",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "env",
Description: "Helm client environment information",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "get",
Description: "Download extended information of a named release",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
fs.Default().String("revision", "", "get the named release with revision")
return nil
return allFlags(ctx, r, fs)
},
Args: tree.Args{
{
@ -131,174 +127,119 @@ func NewCommand(l log.Logger, kubectl *kubectl.Kubectl) *Command {
{
Name: "help",
Description: "Help about any command",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "history",
Description: "Fetch release history",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "install",
Description: "Install a chart",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "lint",
Description: "Examine a chart for possible issues",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "list",
Description: "List releases",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "package",
Description: "Package a chart directory into a chart archive",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "plugin",
Description: "Install, list, or uninstall Helm plugins",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "pull",
Description: "Download a chart from a repository and (optionally) unpack it in local directory",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "repo",
Description: "Add, list, remove, update, and index chart repositories",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "rollback",
Description: "Roll back a release to a previous revision",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "search",
Description: "Search for a keyword in charts",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "show",
Description: "Show information of a chart",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "status",
Description: "Display the status of the named release",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
fs.Default().Bool("show-desc", false, "show description")
return nil
return allFlags(ctx, r, fs)
},
Execute: inst.execute,
},
{
Name: "template",
Description: "Locally render templates",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "test",
Description: "Run tests for a release",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "uninstall",
Description: "Uninstall a release",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "upgrade",
Description: "Upgrade a release",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "verify",
Description: "Verify that a chart at the given path has been signed and is valid",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
{
Name: "version",
Description: "Print the client version information",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
allFlags(fs)
return nil
},
Execute: inst.execute,
Flags: allFlags,
Execute: inst.execute,
},
},
},
@ -328,7 +269,7 @@ func (c *Command) Validate(ctx context.Context, r *readline.Readline) error {
switch {
case r.Args().LenIs(0):
return errors.New("missing [CLUSTER] argument")
case !c.kubectl.Cluster(r.Args().At(0)).ConfigExists():
case !c.kubectl.Cluster(r.Args().At(0)).ConfigExists(""):
return errors.New("invalid [CLUSTER] argument")
case r.Args().LenIs(1):
return errors.New("missing [CMD] argument")
@ -350,12 +291,22 @@ func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
// ------------------------------------------------------------------------------------------------
func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
fs := r.FlagSets().Default()
ifs := r.FlagSets().Internal()
cluster, args := c.kubectl.Cluster(r.Args().At(0)), r.Args()[1:]
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
fmt.Println(args)
return shell.New(ctx, c.l, "helm").
Args(args...).
Args(r.Flags()...).
Args(fs.Visited().Args()...).
Args(r.AdditionalArgs()...).
Env(cluster.Env()).
Args(r.AdditionalFlags()...).
Env(cluster.Env(profile)).
Run()
}

View File

@ -36,6 +36,15 @@ func NewCommand(l log.Logger, kubectl *kubectl.Kubectl) *Command {
Suggest: inst.completeClusters,
},
},
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
if r.Args().HasIndex(0) {
fs.Internal().String("profile", "", "Profile to use.")
if err := fs.Internal().SetValues("profile", inst.kubectl.Cluster(r.Args().At(0)).Profiles(ctx)...); err != nil {
return err
}
}
return nil
},
Execute: inst.execute,
})
@ -71,9 +80,16 @@ func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
// ------------------------------------------------------------------------------------------------
func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
ifs := r.FlagSets().Internal()
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
return shell.New(ctx, c.l, "kube-prompt").
Args(r.AdditionalArgs()...).
Env(c.kubectl.Cluster(r.Args().At(0)).Env()).
Env(c.kubectl.Cluster(r.Args().At(0)).Env(profile)).
Run()
}

View File

@ -41,32 +41,54 @@ func (c *Cluster) String() string {
return c.name
}
func (c *Cluster) Env() string {
return fmt.Sprintf("KUBECONFIG=%s", c.Config())
func (c *Cluster) Env(profile string) string {
return fmt.Sprintf("KUBECONFIG=%s", c.Config(profile))
}
func (c *Cluster) Config() string {
func (c *Cluster) Config(profile string) string {
if profile != "" {
return env.Path(c.kubectl.cfg.ConfigPath, profile, c.Name()+".yaml")
}
return env.Path(c.kubectl.cfg.ConfigPath, c.Name()+".yaml")
}
func (c *Cluster) ConfigExists() bool {
if _, err := os.Stat(c.Config()); err == nil {
func (c *Cluster) ConfigExists(profile string) bool {
if _, err := os.Stat(c.Config(profile)); err == nil {
return true
}
return false
}
func (c *Cluster) DeleteConfig() error {
if !c.ConfigExists() {
func (c *Cluster) DeleteConfig(profile string) error {
if !c.ConfigExists(profile) {
return nil
}
return os.Remove(c.Config())
return os.Remove(c.Config(profile))
}
//nolint:forcetypeassert
func (c *Cluster) Namespaces(ctx context.Context) []string {
return c.kubectl.cache.Get(c.name+"-namespaces", func() any {
if sh, err := c.shell(ctx,
func (c *Cluster) Profiles(ctx context.Context) []string {
return c.kubectl.cache.Get("profiles", func() any {
files, err := os.ReadDir(c.kubectl.cfg.ConfigPath)
if err != nil {
c.l.Debug(err.Error())
return []string{}
}
ret := []string{}
for _, f := range files {
if f.IsDir() && !strings.HasPrefix(f.Name(), ".") {
ret = append(ret, f.Name())
}
}
return ret
}).([]string)
}
//nolint:forcetypeassert
func (c *Cluster) Namespaces(ctx context.Context, profile string) []string {
return c.kubectl.cache.Get(profile+"-"+c.name+"-namespaces", func() any {
if sh, err := c.shell(ctx, profile,
"get", "namespaces",
"-o", "jsonpath='{.items[*].metadata.name}'",
); err != nil {
@ -82,9 +104,9 @@ func (c *Cluster) Namespaces(ctx context.Context) []string {
}
//nolint:forcetypeassert
func (c *Cluster) Pods(ctx context.Context, namespace string) []string {
return c.kubectl.cache.Get(c.name+"-"+namespace+"-pods", func() any {
if sh, err := c.shell(ctx,
func (c *Cluster) Pods(ctx context.Context, profile, namespace string) []string {
return c.kubectl.cache.Get(profile+"-"+c.name+"-"+namespace+"-pods", func() any {
if sh, err := c.shell(ctx, profile,
"get", "pods",
"-n", namespace,
"-o", "jsonpath='{.items[*].metadata.name}'",
@ -104,7 +126,7 @@ func (c *Cluster) Pods(ctx context.Context, namespace string) []string {
// ~ Private methods
// ------------------------------------------------------------------------------------------------
func (c *Cluster) shell(ctx context.Context, args ...string) (*shell.Shell, error) {
func (c *Cluster) shell(ctx context.Context, profile string, args ...string) (*shell.Shell, error) {
sh := shell.New(ctx, c.l, "kubectl").Args(args...)
if c.kubectl.authTokenProvider != nil {
if token, err := c.kubectl.authTokenProvider(ctx, c.Name()); err != nil {
@ -113,5 +135,6 @@ func (c *Cluster) shell(ctx context.Context, args ...string) (*shell.Shell, erro
sh.Args("--token", token)
}
}
return sh.Env(c.Env()), nil
return sh.Env(c.Env(profile)), nil
}

View File

@ -7,13 +7,13 @@ import (
"github.com/foomo/posh/pkg/prompt/check"
)
func SessionChecker(p *OnePassword) check.Checker {
func AuthChecker(p *OnePassword) check.Checker {
return func(ctx context.Context, l log.Logger) check.Info {
name := "1Password: Session"
if ok, _ := p.Session(); ok {
return check.NewSuccessInfo(name, "Signed in")
name := "1Password"
if ok, _ := p.IsAuthenticated(); ok {
return check.NewSuccessInfo(name, "Authenticated")
} else {
return check.NewFailureInfo(name, "Run `op signin` to sign into 1password")
return check.NewFailureInfo(name, "Run `op auth` to sign into 1password")
}
}
}

View File

@ -42,12 +42,12 @@ func NewCommand(l log.Logger, op *OnePassword, opts ...CommandOption) (*Command,
inst.commandTree = tree.New(&tree.Node{
Name: "op",
Description: "Execute 1Password commands",
Execute: inst.signin,
Execute: inst.auth,
Nodes: tree.Nodes{
{
Name: "signin",
Name: "auth",
Description: "Sign into your account",
Execute: inst.signin,
Execute: inst.auth,
},
{
Name: "get",
@ -125,8 +125,8 @@ func (c *Command) register(ctx context.Context, r *readline.Readline) error {
Wait()
}
func (c *Command) signin(ctx context.Context, r *readline.Readline) error {
if ok, _ := c.op.Session(); ok {
func (c *Command) auth(ctx context.Context, r *readline.Readline) error {
if ok, _ := c.op.IsAuthenticated(); ok {
c.l.Info("Already signed in")
return nil
} else if err := c.op.SignIn(ctx); err != nil {

View File

@ -85,7 +85,7 @@ func New(l log.Logger, cache cache.Cache, opts ...Option) (*OnePassword, error)
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (op *OnePassword) Session() (bool, error) {
func (op *OnePassword) IsAuthenticated() (bool, error) {
var sessChanged bool
sess := os.Getenv("OP_SESSION_" + op.cfg.Account)
op.isSignedInLock.Lock()
@ -127,7 +127,7 @@ func (op *OnePassword) Session() (bool, error) {
}
func (op *OnePassword) SignIn(ctx context.Context) error {
if ok, _ := op.Session(); ok {
if ok, _ := op.IsAuthenticated(); ok {
return nil
}
@ -189,7 +189,7 @@ func (op *OnePassword) Get(ctx context.Context, secret Secret) (string, error) {
return strings.ReplaceAll(strings.TrimSpace(value), "\\n", "\n"), nil
}
} else {
if ok, _ := op.Session(); !ok {
if ok, _ := op.IsAuthenticated(); !ok {
return "", ErrNotSignedIn
} else if fields := op.clientGet(ctx, secret.Vault, secret.Item); len(fields) == 0 {
return "", fmt.Errorf("could not find secret '%s' '%s'", secret.Vault, secret.Item)
@ -209,7 +209,7 @@ func (op *OnePassword) GetDocument(ctx context.Context, secret Secret) (string,
return value, nil
}
} else {
if ok, _ := op.Session(); !ok {
if ok, _ := op.IsAuthenticated(); !ok {
return "", ErrNotSignedIn
} else if value := op.clientGetDoument(ctx, secret.Vault, secret.Item); len(value) == 0 {
return "", fmt.Errorf("could not find document '%s' '%s'", secret.Vault, secret.Item)
@ -220,7 +220,7 @@ func (op *OnePassword) GetDocument(ctx context.Context, secret Secret) (string,
}
func (op *OnePassword) GetOnetimePassword(ctx context.Context, account, uuid string) (string, error) {
if ok, _ := op.Session(); !ok {
if ok, _ := op.IsAuthenticated(); !ok {
return "", ErrNotSignedIn
}
@ -421,7 +421,7 @@ func (op *OnePassword) watch() {
if v, ok := op.watching[op.cfg.Account]; !ok || !v {
go func() {
for {
if ok, err := op.Session(); err != nil {
if ok, err := op.IsAuthenticated(); err != nil {
op.l.Warnf("\n1password session keep alive failed for '%s' (%s)", op.cfg.Account, err.Error())
op.watching[op.cfg.Account] = false
return

View File

@ -2,9 +2,9 @@ package licensefinder
import (
"context"
"os"
"os/exec"
"path"
"sort"
"strings"
"github.com/foomo/posh/pkg/cache"
@ -15,6 +15,8 @@ import (
"github.com/foomo/posh/pkg/shell"
"github.com/foomo/posh/pkg/util/files"
"github.com/pkg/errors"
"github.com/samber/lo"
"github.com/spf13/viper"
)
type (
@ -49,11 +51,11 @@ func CommandWithConfigKey(v string) CommandOption {
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewCommand(l log.Logger, cache cache.Cache, opts ...CommandOption) *Command {
func NewCommand(l log.Logger, cache cache.Cache, opts ...CommandOption) (*Command, error) {
inst := &Command{
l: l.Named("licensefinder"),
name: "licensefinder",
configKey: "licensefinder",
configKey: "licenseFinder",
cache: cache.Get("licensefinder"),
}
for _, opt := range opts {
@ -61,77 +63,82 @@ func NewCommand(l log.Logger, cache cache.Cache, opts ...CommandOption) *Command
opt(inst)
}
}
if err := viper.UnmarshalKey(inst.configKey, &inst.cfg); err != nil {
return nil, err
}
addNode := tree.Node{
Name: "add",
Args: tree.Args{{Name: "name"}},
Description: "Add entry",
Execute: inst.execute,
}
listNode := tree.Node{
Name: "list",
Description: "List entry",
Execute: inst.execute,
}
removeNode := tree.Node{
Name: "remove",
Args: tree.Args{{Name: "name"}},
Description: "Remove entry",
Execute: inst.execute,
nameArg := &tree.Arg{
Name: "name",
Description: "Name of the license",
}
inst.commandTree = tree.New(&tree.Node{
Name: inst.name,
Description: "Run license finder",
Execute: inst.execute,
Description: "List unapproved dependencies",
Execute: inst.actionItems,
Nodes: tree.Nodes{
{
Name: "restricted_licenses",
Description: "Manage restricted licenses",
Name: "report",
Description: "Print a report of the project's dependencies",
Execute: inst.report,
},
{
Name: "add",
Description: "Add licenses or dependencies",
Nodes: tree.Nodes{
&addNode,
&listNode,
&removeNode,
{
Name: "permitted",
Description: "Add permitted licenses",
Args: tree.Args{nameArg},
Execute: inst.addPermitted,
},
{
Name: "ignored",
Description: "Add ignored dependencies",
Args: tree.Args{nameArg},
Execute: inst.addIgnored,
},
},
},
{
Name: "ignored_dependencies",
Description: "Manage ignored dependencies",
Name: "list",
Description: "List licenses or dependencies",
Nodes: tree.Nodes{
&addNode,
&listNode,
&removeNode,
{
Name: "permitted",
Description: "Add permitted licenses",
Execute: inst.listPermitted,
},
{
Name: "ignored",
Description: "List ignored dependencies",
Args: tree.Args{nameArg},
Execute: inst.listIgnored,
},
},
},
{
Name: "permitted_licenses",
Description: "Manage permitted licenses",
Name: "remove",
Description: "Remove licenses or dependencies",
Nodes: tree.Nodes{
&addNode,
&listNode,
&removeNode,
},
},
{
Name: "approvals",
Description: "Manage approvals",
Nodes: tree.Nodes{
&addNode,
&removeNode,
},
},
{
Name: "licenses",
Description: "Manage licenses",
Nodes: tree.Nodes{
&addNode,
&removeNode,
{
Name: "permitted",
Description: "Add permitted licenses",
Args: tree.Args{nameArg},
Execute: inst.removePermitted,
},
{
Name: "ignored",
Description: "Remove ignored dependencies",
Args: tree.Args{nameArg},
Execute: inst.removeIgnored,
},
},
},
},
})
return inst
return inst, nil
}
// ------------------------------------------------------------------------------------------------
@ -162,17 +169,6 @@ $ brew update
$ brew install licensefinder
`)
}
switch {
case r.Args().LenIs(0):
return nil
case r.Args().LenGt(1):
return errors.New("too many arguments")
}
if info, err := os.Stat(r.Args().At(0)); err != nil || info.IsDir() {
return errors.New("invalid [path] parameter")
}
return nil
}
@ -188,31 +184,70 @@ func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
// ~ Private methods
// ------------------------------------------------------------------------------------------------
func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
var paths []string
args := []string{
"--log-directory=" + c.cfg.LogPath,
"--decisions_file=" + c.cfg.DecisionsPath,
}
if r.Args().LenIs(0) {
paths = append(paths, c.paths(ctx, "go.sum")...)
paths = append(paths, c.paths(ctx, "yarn.lock")...)
args = append(args, "--aggregate_paths="+strings.Join(paths, " "))
}
func (c *Command) addPermitted(ctx context.Context, r *readline.Readline) error {
return c.execute(ctx, r, append([]string{"permitted_licenses", "add"}, r.Args().From(2)...)...)
}
func (c *Command) listPermitted(ctx context.Context, r *readline.Readline) error {
return c.execute(ctx, r, "permitted_licenses", "list")
}
func (c *Command) removePermitted(ctx context.Context, r *readline.Readline) error {
return c.execute(ctx, r, append([]string{"permitted_licenses", "remove"}, r.Args().From(2)...)...)
}
func (c *Command) addIgnored(ctx context.Context, r *readline.Readline) error {
return c.execute(ctx, r, append([]string{"ignored_dependencies", "add"}, r.Args().From(2)...)...)
}
func (c *Command) listIgnored(ctx context.Context, r *readline.Readline) error {
return c.execute(ctx, r, "ignored_dependencies", "list")
}
func (c *Command) removeIgnored(ctx context.Context, r *readline.Readline) error {
return c.execute(ctx, r, append([]string{"ignored_dependencies", "remove"}, r.Args().From(2)...)...)
}
func (c *Command) actionItems(ctx context.Context, r *readline.Readline) error {
return c.execute(ctx, r, "action_items", c.aggregatePaths(ctx))
}
func (c *Command) report(ctx context.Context, r *readline.Readline) error {
return c.execute(ctx, r, "report", c.aggregatePaths(ctx))
}
func (c *Command) execute(ctx context.Context, r *readline.Readline, args ...string) error {
return shell.New(ctx, c.l, "license_finder").
Args(args...).
Args(r.Args()...).
Args(
"--log-directory="+c.cfg.LogPath,
"--decisions-file="+c.cfg.DecisionsPath,
).
Args(r.Flags()...).
Args(r.AdditionalArgs()...).
Args(r.AdditionalFlags()...).
Run()
}
func (c *Command) aggregatePaths(ctx context.Context) string {
var paths []string
paths = append(paths, c.paths(ctx, "go.sum")...)
paths = append(paths, c.paths(ctx, "yarn.lock")...)
paths = lo.Uniq(paths)
sort.Strings(paths)
c.l.Info("Aggregating liceses from:")
for _, value := range paths {
c.l.Info("└ " + value)
}
return "--aggregate_paths=" + strings.Join(paths, " ")
}
//nolint:forcetypeassert
func (c *Command) paths(ctx context.Context, filename string) []string {
return c.cache.Get("paths-"+filename, func() any {
if value, err := files.Find(ctx, ".", filename); err != nil {
if value, err := files.Find(ctx, ".", filename, files.FindWithIgnore(`^\.`, "vendor", "node_modules")); err != nil {
c.l.Debug("failed to walk files", err.Error())
return nil
return []string{}
} else {
for i, s := range value {
value[i] = path.Dir(s)

View File

@ -69,6 +69,12 @@ func NewCommand(l log.Logger, kubectl *kubectl.Kubectl, squadron *squadron.Squad
fs.Default().String("selector", "", "Selector (label query) to filter on. If present, default to \".*\" for the pod-query.")
fs.Default().String("since", "", "Return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to 48h")
fs.Default().String("tail", "", "The number of lines from the end of the logs to show. Defaults to -1, showing all logs. (default -1)")
fs.Internal().String("profile", "", "Profile to use.")
if r.Args().HasIndex(0) {
if err := fs.Internal().SetValues("profile", inst.kubectl.Cluster(r.Args().At(0)).Profiles(ctx)...); err != nil {
return err
}
}
return nil
},
Args: tree.Args{
@ -124,9 +130,16 @@ func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
// ------------------------------------------------------------------------------------------------
func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
ifs := r.FlagSets().Internal()
cluster, fleet, squad, unit := r.Args().At(0), r.Args().At(1), r.Args().At(2), r.Args().At(3)
profile, err := ifs.GetString("profile")
if err != nil {
return err
}
return shell.New(ctx, c.l, "stern").
Env(c.kubectl.Cluster(cluster).Env()).
Env(c.kubectl.Cluster(cluster).Env(profile)).
Args("--namespace", c.namespaceFn(cluster, fleet, squad)).
Args("--selector", "\"app.kubernetes.io/name="+squad+"-"+unit+"\"").
Args(r.AdditionalArgs()...).
@ -152,6 +165,7 @@ func (c *Command) completeSquadrons(ctx context.Context, t tree.Root, r *readlin
return suggests.List(value)
}
}
func (c *Command) completeSquadronUnits(ctx context.Context, t tree.Root, r *readline.Readline) []goprompt.Suggest {
cluster, fleet, squad := r.Args().At(0), r.Args().At(1), r.Args().At(2)
if value, err := c.squadron.ListUnits(ctx, squad, cluster, fleet, true); err != nil {

View File

@ -195,17 +195,21 @@ func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
if log.MustGet(ifs.GetBool("debug"))(c.l) {
envs = append(envs, fmt.Sprintf("debug=%s", "true"))
}
if log.MustGet(ifs.GetBool("headless"))(c.l) {
envs = append(envs, fmt.Sprintf("HEADLESS=%s", "true"))
}
if log.MustGet(ifs.GetBool("ci"))(c.l) {
envs = append(envs, fmt.Sprintf("E2E_ENV=%s", "ci"))
} else {
envs = append(envs, fmt.Sprintf("E2E_ENV=%s", "chromium"))
}
if value := log.MustGet(ifs.GetString("scenario"))(c.l); value != "" {
envs = append(envs, fmt.Sprintf("SCENARIOS=%s", strings.Trim(value, "\"")))
}
if value := log.MustGet(ifs.GetString("tag"))(c.l); value != "" {
args = append(args, "--cucumberOpts.tagExpression", "'"+strings.Trim(value, "\"")+"'")
}