mirror of
https://github.com/foomo/posh-providers.git
synced 2025-10-16 12:35:41 +00:00
170 lines
3.7 KiB
Go
170 lines
3.7 KiB
Go
package teleport
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/foomo/posh/pkg/cache"
|
|
"github.com/foomo/posh/pkg/env"
|
|
"github.com/foomo/posh/pkg/log"
|
|
"github.com/foomo/posh/pkg/shell"
|
|
"github.com/pterm/pterm"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
// Teleport command
|
|
type (
|
|
Teleport struct {
|
|
l log.Logger
|
|
cfg Config
|
|
cache cache.Namespace
|
|
configKey string
|
|
signedIn bool
|
|
signedInTime time.Time
|
|
}
|
|
Option func(*Teleport) error
|
|
)
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Options
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func CommandWithConfigKey(v string) Option {
|
|
return func(o *Teleport) error {
|
|
o.configKey = v
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Constructor
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// NewTeleport command
|
|
func NewTeleport(l log.Logger, cache cache.Cache, opts ...Option) (*Teleport, error) {
|
|
inst := &Teleport{
|
|
l: l,
|
|
cache: cache.Get("teleport"),
|
|
configKey: "teleport",
|
|
}
|
|
for _, opt := range opts {
|
|
if opt != nil {
|
|
if err := opt(inst); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
}
|
|
if err := viper.UnmarshalKey(inst.configKey, &inst.cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := os.Setenv("TELEPORT_HOME", env.Path(inst.cfg.Path)); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return inst, nil
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Public methods
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func (t *Teleport) Config() Config {
|
|
return t.cfg
|
|
}
|
|
|
|
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 {
|
|
t.signedIn = false
|
|
return false
|
|
} else {
|
|
t.signedIn = true
|
|
t.signedInTime = time.Now()
|
|
return true
|
|
}
|
|
}
|
|
|
|
// Clusters returns a list of cluster
|
|
//
|
|
//nolint:forcetypeassert
|
|
func (t *Teleport) Clusters(ctx context.Context) []string {
|
|
if !t.IsAuthenticated(ctx) {
|
|
return nil
|
|
}
|
|
return t.cache.Get("clusters", func() interface{} {
|
|
ret := []string{}
|
|
|
|
type cluster struct {
|
|
KubeClusterName string `json:"kube_cluster_name"`
|
|
}
|
|
|
|
value, err := shell.New(ctx, t.l, "tsh", "kube", "ls",
|
|
fmt.Sprintf("--query='%s'", t.cfg.Query()),
|
|
"--format", "json",
|
|
).
|
|
Output()
|
|
if err != nil {
|
|
pterm.Error.Println(err.Error())
|
|
return ret
|
|
}
|
|
|
|
var clusters []cluster
|
|
if err := json.Unmarshal(value, &clusters); err != nil {
|
|
pterm.Error.Println(err.Error())
|
|
return ret
|
|
}
|
|
|
|
for _, s := range clusters {
|
|
ret = append(ret, s.KubeClusterName)
|
|
}
|
|
return ret
|
|
}).([]string)
|
|
}
|
|
|
|
// Databases returns a list of cluster
|
|
//
|
|
//nolint:forcetypeassert
|
|
func (t *Teleport) Databases(ctx context.Context) []string {
|
|
if !t.IsAuthenticated(ctx) {
|
|
return nil
|
|
}
|
|
return t.cache.Get("databases", func() interface{} {
|
|
ret := []string{}
|
|
|
|
type (
|
|
metadata struct {
|
|
Name string `json:"name"`
|
|
}
|
|
db struct {
|
|
Metadata metadata `json:"metadata"`
|
|
}
|
|
)
|
|
value, err := shell.New(ctx, t.l, "tsh", "db", "ls",
|
|
fmt.Sprintf("--query='%s'", t.cfg.Query()),
|
|
"--format", "json",
|
|
).
|
|
Output()
|
|
if err != nil {
|
|
pterm.Error.Println(err.Error())
|
|
return ret
|
|
}
|
|
|
|
var dbs []db
|
|
if err := json.Unmarshal(value, &dbs); err != nil {
|
|
pterm.Error.Println(err.Error())
|
|
return ret
|
|
}
|
|
|
|
for _, s := range dbs {
|
|
ret = append(ret, s.Metadata.Name)
|
|
}
|
|
|
|
return ret
|
|
}).([]string)
|
|
}
|