mirror of https://github.com/docker/cli.git
Query UCP Kubernetes user namespaces endpoint
Signed-off-by: Mathieu Champlon <mathieu.champlon@docker.com>
This commit is contained in:
parent
5d54584f03
commit
bd20885ac8
|
@ -1,22 +1,27 @@
|
|||
package kubernetes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/pkg/errors"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// GetStacks lists the kubernetes stacks
|
||||
func GetStacks(dockerCli command.Cli, opts options.List, kopts Options) ([]*formatter.Stack, error) {
|
||||
kubeCli, err := WrapCli(dockerCli, kopts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func GetStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
||||
if opts.AllNamespaces || len(opts.Namespaces) == 0 {
|
||||
return getStacks(kubeCli, opts)
|
||||
return getStacksWithAllNamespaces(kubeCli, opts)
|
||||
}
|
||||
return getStacksWithNamespaces(kubeCli, opts)
|
||||
return getStacksWithNamespaces(kubeCli, opts, removeDuplicates(opts.Namespaces))
|
||||
}
|
||||
|
||||
func getStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
||||
|
@ -44,9 +49,62 @@ func getStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error)
|
|||
return formattedStacks, nil
|
||||
}
|
||||
|
||||
func getStacksWithNamespaces(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
||||
func getStacksWithAllNamespaces(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
||||
stacks, err := getStacks(kubeCli, opts)
|
||||
if !apierrs.IsForbidden(err) {
|
||||
return stacks, err
|
||||
}
|
||||
namespaces, err2 := getUserVisibleNamespaces(*kubeCli)
|
||||
if err2 != nil {
|
||||
return nil, errors.Wrap(err2, "failed to query user visible namespaces")
|
||||
}
|
||||
if namespaces == nil {
|
||||
// UCP API not present, fall back to Kubernetes error
|
||||
return nil, err
|
||||
}
|
||||
opts.AllNamespaces = false
|
||||
return getStacksWithNamespaces(kubeCli, opts, namespaces)
|
||||
}
|
||||
|
||||
func getUserVisibleNamespaces(dockerCli command.Cli) ([]string, error) {
|
||||
host := dockerCli.Client().DaemonHost()
|
||||
endpoint, err := url.Parse(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endpoint.Scheme = "https"
|
||||
endpoint.Path = "/kubernetesNamespaces"
|
||||
resp, err := dockerCli.Client().HTTPClient().Get(endpoint.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "received %d status and unable to read response", resp.StatusCode)
|
||||
}
|
||||
switch resp.StatusCode {
|
||||
case http.StatusOK:
|
||||
nms := &core_v1.NamespaceList{}
|
||||
if err := json.Unmarshal(body, nms); err != nil {
|
||||
return nil, errors.Wrapf(err, "unmarshal failed: %s", string(body))
|
||||
}
|
||||
namespaces := make([]string, len(nms.Items))
|
||||
for i, namespace := range nms.Items {
|
||||
namespaces[i] = namespace.Name
|
||||
}
|
||||
return namespaces, nil
|
||||
case http.StatusNotFound:
|
||||
// UCP API not present
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("received %d status while retrieving namespaces: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
}
|
||||
|
||||
func getStacksWithNamespaces(kubeCli *KubeCli, opts options.List, namespaces []string) ([]*formatter.Stack, error) {
|
||||
stacks := []*formatter.Stack{}
|
||||
for _, namespace := range removeDuplicates(opts.Namespaces) {
|
||||
for _, namespace := range namespaces {
|
||||
kubeCli.kubeNamespace = namespace
|
||||
ss, err := getStacks(kubeCli, opts)
|
||||
if err != nil {
|
||||
|
|
|
@ -47,7 +47,11 @@ func runList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error
|
|||
stacks = append(stacks, ss...)
|
||||
}
|
||||
if dockerCli.ClientInfo().HasKubernetes() {
|
||||
ss, err := kubernetes.GetStacks(dockerCli, opts, kubernetes.NewOptions(cmd.Flags()))
|
||||
kubeCli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ss, err := kubernetes.GetStacks(kubeCli, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue