ls consistency: add tctl kube ls command

```
Cluster     Labels Version
----------- ------ -------------
minikube           8.0.0-alpha.1
honkcluster        8.0.3
```

```yaml
kind: kube_service
metadata:
  expires: "2021-12-16T16:07:14.898611765Z"
  id: 1639670234899200604
  name: 7b3ca8d8-710c-4305-aa29-e73628ac572c
spec:
  addr: 127.0.0.1:3027
  hostname: ""
  kube_clusters:
  - name: minikube
  rotation:
    current_id: ""
    last_rotated: "0001-01-01T00:00:00Z"
    schedule:
      standby: "0001-01-01T00:00:00Z"
      update_clients: "0001-01-01T00:00:00Z"
      update_servers: "0001-01-01T00:00:00Z"
    started: "0001-01-01T00:00:00Z"
  version: 8.0.0-alpha.1
version: v2
---
kind: kube_service
metadata:
  expires: "2021-12-16T16:10:13.068855399Z"
  id: 1639670413069866294
  name: 9153a5a9-e85e-4972-8c50-6fa8923282b2
spec:
  addr: remote.kube.proxy.teleport.cluster.local
  hostname: ""
  kube_clusters:
  - name: honkcluster
  rotation:
    current_id: ""
    last_rotated: "0001-01-01T00:00:00Z"
    schedule:
      standby: "0001-01-01T00:00:00Z"
      update_clients: "0001-01-01T00:00:00Z"
      update_servers: "0001-01-01T00:00:00Z"
    started: "0001-01-01T00:00:00Z"
  version: 8.0.3
version: v2
```yaml
This commit is contained in:
Alex McGrath 2021-12-16 16:05:37 +00:00 committed by Alex McGrath
parent 5fcc19789f
commit 1627d79275
3 changed files with 107 additions and 0 deletions

View file

@ -751,3 +751,27 @@ func (c *tokenCollection) writeText(w io.Writer) error {
}
return nil
}
type kubeServerCollection struct {
servers []types.Server
}
func (c *kubeServerCollection) writeText(w io.Writer) error {
t := asciitable.MakeTable([]string{"Cluster", "Labels", "Version"})
for _, server := range c.servers {
kubes := server.GetKubernetesClusters()
for _, kube := range kubes {
t.AddRow([]string{
kube.Name,
types.LabelsAsString(kube.StaticLabels, kube.DynamicLabels),
server.GetTeleportVersion(),
})
}
}
_, err := t.AsBuffer().WriteTo(w)
return trace.Wrap(err)
}
func (c *kubeServerCollection) writeYAML(w io.Writer) error {
return utils.WriteYAML(w, c.servers)
}

View file

@ -0,0 +1,82 @@
/*
Copyright 2021 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package common
import (
"context"
"os"
"github.com/gravitational/kingpin"
"github.com/gravitational/trace"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/lib/auth"
"github.com/gravitational/teleport/lib/service"
)
// KubeCommand implements "tctl kube" group of commands.
type KubeCommand struct {
config *service.Config
// format is the output format (text or yaml)
format string
// kubeList implements the "tctl kube ls" subcommand.
kubeList *kingpin.CmdClause
}
// Initialize allows KubeCommand to plug itself into the CLI parser
func (c *KubeCommand) Initialize(app *kingpin.Application, config *service.Config) {
c.config = config
kube := app.Command("kube", "Operate on registered kubernetes clusters.")
c.kubeList = kube.Command("ls", "List all kubernetes clusters registered with the cluster.")
c.kubeList.Flag("format", "Output format, 'text', or 'yaml'").Default("text").StringVar(&c.format)
}
// TryRun attempts to run subcommands like "kube ls".
func (c *KubeCommand) TryRun(cmd string, client auth.ClientI) (match bool, err error) {
switch cmd {
case c.kubeList.FullCommand():
err = c.ListKube(client)
default:
return false, nil
}
return true, trace.Wrap(err)
}
// ListKube prints the list of kube clusters that have recently sent heartbeats
// to the cluster.
func (c *KubeCommand) ListKube(client auth.ClientI) error {
kubes, err := client.GetKubeServices(context.TODO())
if err != nil {
return trace.Wrap(err)
}
coll := &kubeServerCollection{servers: kubes}
switch c.format {
case teleport.Text:
err = coll.writeText(os.Stdout)
case teleport.YAML:
err = coll.writeYAML(os.Stdout)
default:
return trace.BadParameter("unknown format %q", c.format)
}
if err != nil {
return trace.Wrap(err)
}
return nil
}

View file

@ -32,6 +32,7 @@ func main() {
&common.AccessRequestCommand{},
&common.AppsCommand{},
&common.DBCommand{},
&common.KubeCommand{},
&common.AccessCommand{},
&common.LockCommand{},
&common.BotsCommand{},