...

Source file src/k8s.io/kubectl/pkg/cmd/clusterinfo/clusterinfo.go

Documentation: k8s.io/kubectl/pkg/cmd/clusterinfo

     1  /*
     2  Copyright 2015 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package clusterinfo
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  	"strconv"
    23  
    24  	corev1 "k8s.io/api/core/v1"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	utilnet "k8s.io/apimachinery/pkg/util/net"
    27  	"k8s.io/cli-runtime/pkg/genericclioptions"
    28  	"k8s.io/cli-runtime/pkg/genericiooptions"
    29  	"k8s.io/cli-runtime/pkg/resource"
    30  	restclient "k8s.io/client-go/rest"
    31  	cmdutil "k8s.io/kubectl/pkg/cmd/util"
    32  	"k8s.io/kubectl/pkg/scheme"
    33  	"k8s.io/kubectl/pkg/util/i18n"
    34  	"k8s.io/kubectl/pkg/util/templates"
    35  
    36  	ct "github.com/daviddengcn/go-colortext"
    37  	"github.com/spf13/cobra"
    38  )
    39  
    40  var (
    41  	longDescr = templates.LongDesc(i18n.T(`
    42    Display addresses of the control plane and services with label kubernetes.io/cluster-service=true.
    43    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.`))
    44  
    45  	clusterinfoExample = templates.Examples(i18n.T(`
    46  		# Print the address of the control plane and cluster services
    47  		kubectl cluster-info`))
    48  )
    49  
    50  type ClusterInfoOptions struct {
    51  	genericiooptions.IOStreams
    52  
    53  	Namespace string
    54  
    55  	Builder *resource.Builder
    56  	Client  *restclient.Config
    57  }
    58  
    59  func NewCmdClusterInfo(restClientGetter genericclioptions.RESTClientGetter, ioStreams genericiooptions.IOStreams) *cobra.Command {
    60  	o := &ClusterInfoOptions{
    61  		IOStreams: ioStreams,
    62  	}
    63  
    64  	cmd := &cobra.Command{
    65  		Use:     "cluster-info",
    66  		Short:   i18n.T("Display cluster information"),
    67  		Long:    longDescr,
    68  		Example: clusterinfoExample,
    69  		Run: func(cmd *cobra.Command, args []string) {
    70  			cmdutil.CheckErr(o.Complete(restClientGetter, cmd))
    71  			cmdutil.CheckErr(o.Run())
    72  		},
    73  	}
    74  	cmd.AddCommand(NewCmdClusterInfoDump(restClientGetter, ioStreams))
    75  	return cmd
    76  }
    77  
    78  func (o *ClusterInfoOptions) Complete(restClientGetter genericclioptions.RESTClientGetter, cmd *cobra.Command) error {
    79  	var err error
    80  	o.Client, err = restClientGetter.ToRESTConfig()
    81  	if err != nil {
    82  		return err
    83  	}
    84  
    85  	cmdNamespace := cmdutil.GetFlagString(cmd, "namespace")
    86  	if cmdNamespace == "" {
    87  		cmdNamespace = metav1.NamespaceSystem
    88  	}
    89  	o.Namespace = cmdNamespace
    90  
    91  	o.Builder = resource.NewBuilder(restClientGetter)
    92  	return nil
    93  }
    94  
    95  func (o *ClusterInfoOptions) Run() error {
    96  	// TODO use generalized labels once they are implemented (#341)
    97  	b := o.Builder.
    98  		WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
    99  		NamespaceParam(o.Namespace).DefaultNamespace().
   100  		LabelSelectorParam("kubernetes.io/cluster-service=true").
   101  		ResourceTypeOrNameArgs(false, []string{"services"}...).
   102  		Latest()
   103  	err := b.Do().Visit(func(r *resource.Info, err error) error {
   104  		if err != nil {
   105  			return err
   106  		}
   107  		printService(o.Out, "Kubernetes control plane", o.Client.Host)
   108  
   109  		services := r.Object.(*corev1.ServiceList).Items
   110  		for _, service := range services {
   111  			var link string
   112  			if len(service.Status.LoadBalancer.Ingress) > 0 {
   113  				ingress := service.Status.LoadBalancer.Ingress[0]
   114  				ip := ingress.IP
   115  				if ip == "" {
   116  					ip = ingress.Hostname
   117  				}
   118  				for _, port := range service.Spec.Ports {
   119  					link += "http://" + ip + ":" + strconv.Itoa(int(port.Port)) + " "
   120  				}
   121  			} else {
   122  				name := service.ObjectMeta.Name
   123  
   124  				if len(service.Spec.Ports) > 0 {
   125  					port := service.Spec.Ports[0]
   126  
   127  					// guess if the scheme is https
   128  					scheme := ""
   129  					if port.Name == "https" || port.Port == 443 {
   130  						scheme = "https"
   131  					}
   132  
   133  					// format is <scheme>:<service-name>:<service-port-name>
   134  					name = utilnet.JoinSchemeNamePort(scheme, service.ObjectMeta.Name, port.Name)
   135  				}
   136  
   137  				if len(o.Client.GroupVersion.Group) == 0 {
   138  					link = o.Client.Host + "/api/" + o.Client.GroupVersion.Version + "/namespaces/" + service.ObjectMeta.Namespace + "/services/" + name + "/proxy"
   139  				} else {
   140  					link = o.Client.Host + "/api/" + o.Client.GroupVersion.Group + "/" + o.Client.GroupVersion.Version + "/namespaces/" + service.ObjectMeta.Namespace + "/services/" + name + "/proxy"
   141  
   142  				}
   143  			}
   144  			name := service.ObjectMeta.Labels["kubernetes.io/name"]
   145  			if len(name) == 0 {
   146  				name = service.ObjectMeta.Name
   147  			}
   148  			printService(o.Out, name, link)
   149  		}
   150  		return nil
   151  	})
   152  	o.Out.Write([]byte("\nTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.\n"))
   153  	return err
   154  
   155  	// TODO consider printing more information about cluster
   156  }
   157  
   158  func printService(out io.Writer, name, link string) {
   159  	ct.ChangeColor(ct.Green, false, ct.None, false)
   160  	fmt.Fprint(out, name)
   161  	ct.ResetColor()
   162  	fmt.Fprint(out, " is running at ")
   163  	ct.ChangeColor(ct.Yellow, false, ct.None, false)
   164  	fmt.Fprint(out, link)
   165  	ct.ResetColor()
   166  	fmt.Fprintln(out, "")
   167  }
   168  

View as plain text