mirror of
https://github.com/gravitational/teleport
synced 2024-10-21 17:53:28 +00:00
Update 'tctl apps/db/nodes ls' to accept filter flags (#11003)
This commit is contained in:
parent
df9c99bceb
commit
628564c801
|
@ -576,6 +576,8 @@ func GetNodesWithLabels(ctx context.Context, clt nodeClient, namespace string, l
|
|||
}
|
||||
|
||||
// GetNodes returns the list of servers registered in the cluster.
|
||||
//
|
||||
// DELETE IN 11.0.0, replaced by GetResourcesWithFilters
|
||||
func (c *Client) GetNodes(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.Server, error) {
|
||||
if resp, err := c.APIClient.GetNodes(ctx, namespace); err != nil {
|
||||
if !trace.IsNotImplemented(err) {
|
||||
|
|
|
@ -25,8 +25,12 @@ import (
|
|||
"github.com/gravitational/trace"
|
||||
|
||||
"github.com/gravitational/teleport"
|
||||
"github.com/gravitational/teleport/api/client"
|
||||
"github.com/gravitational/teleport/api/client/proto"
|
||||
apidefaults "github.com/gravitational/teleport/api/defaults"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/auth"
|
||||
libclient "github.com/gravitational/teleport/lib/client"
|
||||
"github.com/gravitational/teleport/lib/service"
|
||||
)
|
||||
|
||||
|
@ -37,6 +41,10 @@ type AppsCommand struct {
|
|||
// format is the output format (text, json, or yaml)
|
||||
format string
|
||||
|
||||
searchKeywords string
|
||||
predicateExpr string
|
||||
labels string
|
||||
|
||||
// appsList implements the "tctl apps ls" subcommand.
|
||||
appsList *kingpin.CmdClause
|
||||
}
|
||||
|
@ -48,6 +56,9 @@ func (c *AppsCommand) Initialize(app *kingpin.Application, config *service.Confi
|
|||
apps := app.Command("apps", "Operate on applications registered with the cluster.")
|
||||
c.appsList = apps.Command("ls", "List all applications registered with the cluster.")
|
||||
c.appsList.Flag("format", "Output format, 'text', 'json', or 'yaml'").Default("text").StringVar(&c.format)
|
||||
c.appsList.Arg("labels", labelHelp).StringVar(&c.labels)
|
||||
c.appsList.Flag("search", searchHelp).StringVar(&c.searchKeywords)
|
||||
c.appsList.Flag("query", queryHelp).StringVar(&c.predicateExpr)
|
||||
}
|
||||
|
||||
// TryRun attempts to run subcommands like "apps ls".
|
||||
|
@ -63,11 +74,40 @@ func (c *AppsCommand) TryRun(cmd string, client auth.ClientI) (match bool, err e
|
|||
|
||||
// ListApps prints the list of applications that have recently sent heartbeats
|
||||
// to the cluster.
|
||||
func (c *AppsCommand) ListApps(client auth.ClientI) error {
|
||||
servers, err := client.GetApplicationServers(context.TODO(), apidefaults.Namespace)
|
||||
func (c *AppsCommand) ListApps(clt auth.ClientI) error {
|
||||
ctx := context.TODO()
|
||||
|
||||
labels, err := libclient.ParseLabelSpec(c.labels)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
var servers []types.AppServer
|
||||
resources, err := client.GetResourcesWithFilters(ctx, clt, proto.ListResourcesRequest{
|
||||
ResourceType: types.KindAppServer,
|
||||
Labels: labels,
|
||||
PredicateExpression: c.predicateExpr,
|
||||
SearchKeywords: libclient.ParseSearchKeywords(c.searchKeywords, ','),
|
||||
})
|
||||
switch {
|
||||
// Underlying ListResources for app servers not available, use fallback.
|
||||
// Using filter flags with older auth will silently do nothing.
|
||||
//
|
||||
// DELETE IN 11.0.0
|
||||
case trace.IsNotImplemented(err):
|
||||
servers, err = clt.GetApplicationServers(ctx, apidefaults.Namespace)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
case err != nil:
|
||||
return trace.Wrap(err)
|
||||
default:
|
||||
servers, err = types.ResourcesWithLabels(resources).AsAppServers()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
coll := &appServerCollection{servers: servers}
|
||||
|
||||
switch c.format {
|
||||
|
|
|
@ -22,8 +22,12 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/gravitational/teleport"
|
||||
"github.com/gravitational/teleport/api/client"
|
||||
"github.com/gravitational/teleport/api/client/proto"
|
||||
apidefaults "github.com/gravitational/teleport/api/defaults"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/auth"
|
||||
libclient "github.com/gravitational/teleport/lib/client"
|
||||
"github.com/gravitational/teleport/lib/service"
|
||||
|
||||
"github.com/gravitational/kingpin"
|
||||
|
@ -37,6 +41,10 @@ type DBCommand struct {
|
|||
// format is the output format (text, json or yaml).
|
||||
format string
|
||||
|
||||
searchKeywords string
|
||||
predicateExpr string
|
||||
labels string
|
||||
|
||||
// dbList implements the "tctl db ls" subcommand.
|
||||
dbList *kingpin.CmdClause
|
||||
}
|
||||
|
@ -48,6 +56,9 @@ func (c *DBCommand) Initialize(app *kingpin.Application, config *service.Config)
|
|||
db := app.Command("db", "Operate on databases registered with the cluster.")
|
||||
c.dbList = db.Command("ls", "List all databases registered with the cluster.")
|
||||
c.dbList.Flag("format", "Output format, 'text', 'json', or 'yaml'").Default("text").StringVar(&c.format)
|
||||
c.dbList.Arg("labels", labelHelp).StringVar(&c.labels)
|
||||
c.dbList.Flag("search", searchHelp).StringVar(&c.searchKeywords)
|
||||
c.dbList.Flag("query", queryHelp).StringVar(&c.predicateExpr)
|
||||
}
|
||||
|
||||
// TryRun attempts to run subcommands like "db ls".
|
||||
|
@ -63,11 +74,40 @@ func (c *DBCommand) TryRun(cmd string, client auth.ClientI) (match bool, err err
|
|||
|
||||
// ListDatabases prints the list of database proxies that have recently sent
|
||||
// heartbeats to the cluster.
|
||||
func (c *DBCommand) ListDatabases(client auth.ClientI) error {
|
||||
servers, err := client.GetDatabaseServers(context.TODO(), apidefaults.Namespace)
|
||||
func (c *DBCommand) ListDatabases(clt auth.ClientI) error {
|
||||
ctx := context.TODO()
|
||||
|
||||
labels, err := libclient.ParseLabelSpec(c.labels)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
var servers []types.DatabaseServer
|
||||
resources, err := client.GetResourcesWithFilters(ctx, clt, proto.ListResourcesRequest{
|
||||
ResourceType: types.KindDatabaseServer,
|
||||
Labels: labels,
|
||||
PredicateExpression: c.predicateExpr,
|
||||
SearchKeywords: libclient.ParseSearchKeywords(c.searchKeywords, ','),
|
||||
})
|
||||
switch {
|
||||
// Underlying ListResources for db servers not available, use fallback.
|
||||
// Using filter flags with older auth will silently do nothing.
|
||||
//
|
||||
// DELETE IN 11.0.0
|
||||
case trace.IsNotImplemented(err):
|
||||
servers, err = clt.GetDatabaseServers(ctx, apidefaults.Namespace)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
case err != nil:
|
||||
return trace.Wrap(err)
|
||||
default:
|
||||
servers, err = types.ResourcesWithLabels(resources).AsDatabaseServers()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
coll := &databaseServerCollection{servers: servers}
|
||||
switch c.format {
|
||||
case teleport.Text:
|
||||
|
|
|
@ -29,9 +29,12 @@ import (
|
|||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/gravitational/teleport/api/client"
|
||||
"github.com/gravitational/teleport/api/client/proto"
|
||||
apidefaults "github.com/gravitational/teleport/api/defaults"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/auth"
|
||||
libclient "github.com/gravitational/teleport/lib/client"
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
"github.com/gravitational/teleport/lib/service"
|
||||
"github.com/gravitational/teleport/lib/tlsca"
|
||||
|
@ -53,6 +56,10 @@ type NodeCommand struct {
|
|||
// if not specified, is autogenerated
|
||||
token string
|
||||
|
||||
searchKeywords string
|
||||
predicateExpr string
|
||||
labels string
|
||||
|
||||
// CLI subcommands (clauses)
|
||||
nodeAdd *kingpin.CmdClause
|
||||
nodeList *kingpin.CmdClause
|
||||
|
@ -74,6 +81,9 @@ func (c *NodeCommand) Initialize(app *kingpin.Application, config *service.Confi
|
|||
c.nodeList = nodes.Command("ls", "List all active SSH nodes within the cluster")
|
||||
c.nodeList.Flag("namespace", "Namespace of the nodes").Default(apidefaults.Namespace).StringVar(&c.namespace)
|
||||
c.nodeList.Alias(ListNodesHelp)
|
||||
c.nodeList.Arg("labels", labelHelp).StringVar(&c.labels)
|
||||
c.nodeList.Flag("search", searchHelp).StringVar(&c.searchKeywords)
|
||||
c.nodeList.Flag("query", queryHelp).StringVar(&c.predicateExpr)
|
||||
}
|
||||
|
||||
// TryRun takes the CLI command as an argument (like "nodes ls") and executes it.
|
||||
|
@ -190,12 +200,41 @@ func (c *NodeCommand) Invite(client auth.ClientI) error {
|
|||
|
||||
// ListActive retreives the list of nodes who recently sent heartbeats to
|
||||
// to a cluster and prints it to stdout
|
||||
func (c *NodeCommand) ListActive(client auth.ClientI) error {
|
||||
func (c *NodeCommand) ListActive(clt auth.ClientI) error {
|
||||
ctx := context.TODO()
|
||||
nodes, err := client.GetNodes(ctx, c.namespace)
|
||||
|
||||
labels, err := libclient.ParseLabelSpec(c.labels)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
var nodes []types.Server
|
||||
resources, err := client.GetResourcesWithFilters(ctx, clt, proto.ListResourcesRequest{
|
||||
ResourceType: types.KindNode,
|
||||
Namespace: c.namespace,
|
||||
Labels: labels,
|
||||
PredicateExpression: c.predicateExpr,
|
||||
SearchKeywords: libclient.ParseSearchKeywords(c.searchKeywords, ','),
|
||||
})
|
||||
switch {
|
||||
// Underlying ListResources for nodes not available, use fallback.
|
||||
// Using filter flags with older auth will silently do nothing.
|
||||
//
|
||||
// DELETE IN 11.0.0
|
||||
case trace.IsNotImplemented(err):
|
||||
nodes, err = clt.GetNodes(ctx, c.namespace)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
case err != nil:
|
||||
return trace.Wrap(err)
|
||||
default:
|
||||
nodes, err = types.ResourcesWithLabels(resources).AsServers()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
coll := &serverCollection{servers: nodes}
|
||||
if err := coll.writeText(os.Stdout); err != nil {
|
||||
return trace.Wrap(err)
|
||||
|
|
|
@ -41,6 +41,12 @@ import (
|
|||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
searchHelp = `List of comma separated search keywords or phrases enclosed in quotations (e.g. --search=foo,bar,"some phrase")`
|
||||
queryHelp = `Query by predicate language enclosed in single quotes. Supports ==, !=, &&, and || (e.g. --query='labels.key1 == "value1" && labels.key2 != "value2"')`
|
||||
labelHelp = "List of comma separated labels to filter by labels (e.g. key1=value1,key2=value2)"
|
||||
)
|
||||
|
||||
// GlobalCLIFlags keeps the CLI flags that apply to all tctl commands
|
||||
type GlobalCLIFlags struct {
|
||||
// Debug enables verbose logging mode to the console
|
||||
|
|
Loading…
Reference in a new issue