-
Notifications
You must be signed in to change notification settings - Fork 0
/
console.go
182 lines (137 loc) · 4.07 KB
/
console.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package console
import (
"context"
"fmt"
"os"
"github.com/pkg/browser"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/kubectl/pkg/util/templates"
)
const (
openShiftConfigManagedNamespaceName = "openshift-config-managed"
consolePublicConfigMap = "console-public"
)
var (
consoleShort = templates.LongDesc(`
Open the OpenShift console in your default browser.`)
consoleExample = templates.Examples(`
# Open the OpenShift console in your default browser
%[1]s %[2]s
# Display the URL for the OpenShift console
%[1]s %[2]s --url`)
)
// ConsoleCmdOptions are options supported by the console command.
type ConsoleCmdOptions struct { //nolint:golint
configFlags *genericclioptions.ConfigFlags
ClientConfig *rest.Config
KubeClient kubernetes.Interface
// URL is true if the command should print the URL of the console instead of
// opening the browser.
URL bool
// args is the slice of strings containing any arguments passed
args []string
context context.Context
genericclioptions.IOStreams
}
// NewConsoleCmdOptions provides an instance of ConsoleCmdOptions with default values
func NewConsoleCmdOptions(streams genericclioptions.IOStreams) *ConsoleCmdOptions {
return &ConsoleCmdOptions{
configFlags: genericclioptions.NewConfigFlags(false),
IOStreams: streams,
context: context.Background(),
}
}
// NewCmdConsoleConfig provides a cobra command wrapping ConsoleCmdOptions
func NewCmdConsoleConfig(streams genericclioptions.IOStreams) *cobra.Command {
o := NewConsoleCmdOptions(streams)
callingBinary := getCallingBinary()
cmd := &cobra.Command{
Use: fmt.Sprintf("%s console", callingBinary),
Short: consoleShort,
Example: fmt.Sprintf(consoleExample, callingBinary, "console"),
RunE: func(c *cobra.Command, args []string) error {
if err := o.Complete(args); err != nil {
return err
}
if err := o.Validate(); err != nil {
return err
}
if err := o.Run(); err != nil {
return err
}
return nil
},
}
cmd.Flags().BoolVar(&o.URL, "url", o.URL, "Print the console URL instead of opening it.")
o.configFlags.AddFlags(cmd.Flags())
return cmd
}
func getCallingBinary() string {
if os.Getenv("KUBECTL_PLUGINS_CALLER") != "" {
return os.Getenv("KUBECTL_PLUGINS_CALLER")
}
return "oc"
}
// Complete sets up the KubeClient
func (o *ConsoleCmdOptions) Complete(args []string) error {
var err error
o.args = args
o.ClientConfig, err = o.configFlags.ToRESTConfig()
if err != nil {
return err
}
kubeClient, err := kubernetes.NewForConfig(o.ClientConfig)
if err != nil {
return err
}
o.KubeClient = kubeClient
return err
}
// Validate ensures that all required arguments and flag values are provided
func (o *ConsoleCmdOptions) Validate() error {
if len(o.args) > 0 {
return fmt.Errorf("no arguments are allowed")
}
return nil
}
// getWebConsoleURL retrieves the web console URL from the appropriate configmap
func (o *ConsoleCmdOptions) getWebConsoleURL() (string, error) {
consolePublicConfig, err := o.KubeClient.CoreV1().
ConfigMaps(openShiftConfigManagedNamespaceName).
Get(o.context, consolePublicConfigMap, metav1.GetOptions{})
// This means the command was run against 3.x server
if err != nil {
if errors.IsNotFound(err) {
return o.ClientConfig.Host, nil
}
return "", fmt.Errorf("unable to determine console location: %v", err)
}
consoleURL, exists := consolePublicConfig.Data["consoleURL"]
if !exists {
return "", fmt.Errorf("unable to determine console location from the cluster")
}
return consoleURL, nil
}
// Run grabs the console URL, and either prints it to the terminal or opens it
// in your default web browser
func (o *ConsoleCmdOptions) Run() error {
var err error
consoleURL, err := o.getWebConsoleURL()
if err != nil {
return err
}
if o.URL {
fmt.Fprintf(o.Out, "%s\n", consoleURL)
return nil
}
err = browser.OpenURL(consoleURL)
if err != nil {
return err
}
return nil
}