Skip to content

Commit

Permalink
Merge pull request #114 from BenTheElder/clusters
Browse files Browse the repository at this point in the history
add `kind get clusters`
  • Loading branch information
k8s-ci-robot authored Nov 15, 2018
2 parents 200294e + 0ed8530 commit 4d7dded
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 5 deletions.
52 changes: 52 additions & 0 deletions cmd/kind/get/clusters/clusters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
Copyright 2018 The Kubernetes Authors.
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 clusters implements the `clusters` command
package clusters

import (
"fmt"

"github.com/pkg/errors"
"github.com/spf13/cobra"

"sigs.k8s.io/kind/pkg/cluster"
)

// NewCommand returns a new cobra.Command for getting the list of clusters
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
// TODO(bentheelder): more detailed usage
Use: "clusters",
Short: "lists existing kind clusters by their name",
Long: "lists existing kind clusters by their name",
RunE: func(cmd *cobra.Command, args []string) error {
return runE(cmd, args)
},
}
return cmd
}

func runE(cmd *cobra.Command, args []string) error {
clusters, err := cluster.List()
if err != nil {
return errors.Wrap(err, "error listing clusters")
}
for _, cluster := range clusters {
fmt.Println(cluster.Name())
}
return nil
}
6 changes: 4 additions & 2 deletions cmd/kind/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package get
import (
"github.com/spf13/cobra"

"sigs.k8s.io/kind/cmd/kind/get/clusters"
"sigs.k8s.io/kind/cmd/kind/get/kubeconfigpath"
)

Expand All @@ -28,13 +29,14 @@ func NewCommand() *cobra.Command {
cmd := &cobra.Command{
// TODO(bentheelder): more detailed usage
Use: "get",
Short: "Gets one of [kubeconfig-path]",
Long: "Gets one of [kubeconfig-path]",
Short: "Gets one of [clusters, kubeconfig-path]",
Long: "Gets one of [clusters, kubeconfig-path]",
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Help()
},
}
// add subcommands
cmd.AddCommand(clusters.NewCommand())
cmd.AddCommand(kubeconfigpath.NewCommand())
return cmd
}
36 changes: 36 additions & 0 deletions pkg/cluster/clusters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright 2018 The Kubernetes Authors.
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 cluster

import (
"github.com/pkg/errors"

"sigs.k8s.io/kind/pkg/cluster/nodes"
)

// List returns a list of clusters for which node containers exist
func List() ([]Context, error) {
n, err := nodes.ListByCluster()
if err != nil {
return nil, errors.Wrap(err, "could not list clusters, failed to list nodes")
}
clusters := []Context{}
for name := range n {
clusters = append(clusters, *newContextNoValidation(name))
}
return clusters, nil
}
13 changes: 12 additions & 1 deletion pkg/cluster/cluster.go → pkg/cluster/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ var validNameRE = regexp.MustCompile(`^[a-zA-Z0-9_.-]+$`)
// NewContext returns a new cluster management context
// if name is "" the default ("1") will be used
func NewContext(name string) (ctx *Context, err error) {
// TODO(bentheelder): move validation out of NewContext and into create type
// calls, so that EG delete still works on previously valid, now invalid
// names if kind updates
if name == "" {
name = "1"
}
Expand All @@ -63,9 +66,17 @@ func NewContext(name string) (ctx *Context, err error) {
name, validNameRE.String(),
)
}
return newContextNoValidation(name), nil
}

// internal helper that does the actual allocation consitently, but does not
// validate the cluster name
// we need this so that if we tighten the validation, other internal code
// can still create contexts to existing clusters by name (see List())
func newContextNoValidation(name string) *Context {
return &Context{
name: name,
}, nil
}
}

// ClusterLabel returns the docker object label that will be applied
Expand Down
File renamed without changes.
38 changes: 36 additions & 2 deletions pkg/cluster/nodes/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ limitations under the License.
package nodes

import (
"fmt"
"strings"

"github.com/pkg/errors"
"sigs.k8s.io/kind/pkg/cluster/consts"

Expand Down Expand Up @@ -52,8 +55,9 @@ func Delete(nodes ...*Node) error {
func List(filters ...string) ([]*Node, error) {
args := []string{
"ps",
"-q", // quiet output for parsing
"-a", // show stopped nodes
"-q", // quiet output for parsing
"-a", // show stopped nodes
"--no-trunc", // don't truncate
// filter for nodes with the cluster label
"--filter", "label=" + consts.ClusterLabelKey,
}
Expand All @@ -72,3 +76,33 @@ func List(filters ...string) ([]*Node, error) {
}
return nodes, nil
}

// ListByCluster returns a list of nodes by the kind cluster name
func ListByCluster() (map[string][]Node, error) {
args := []string{
"ps",
"-q", // quiet output for parsing
"-a", // show stopped nodes
"--no-trunc", // don't truncate
// filter for nodes with the cluster label
"--filter", "label=" + consts.ClusterLabelKey,
// format to include friendly name and the cluster name
"--format", fmt.Sprintf(`{{.Names}}\t{{.Label "%s"}}`, consts.ClusterLabelKey),
}
cmd := exec.Command("docker", args...)
lines, err := exec.CombinedOutputLines(cmd)
if err != nil {
return nil, errors.Wrap(err, "failed to list nodes")
}
nodes := make(map[string][]Node)
for _, line := range lines {
parts := strings.Split(line, "\t")
if len(parts) != 2 {
return nil, fmt.Errorf("invalid output when listing nodes: %s", line)
}
names := strings.Split(parts[0], ",")
cluster := parts[1]
nodes[cluster] = append(nodes[cluster], *FromID(names[0]))
}
return nodes, nil
}

0 comments on commit 4d7dded

Please sign in to comment.