...
1
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
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
128 scheme := ""
129 if port.Name == "https" || port.Port == 443 {
130 scheme = "https"
131 }
132
133
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
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