Skip to content

Commit b6ba8ec

Browse files
author
OpenShift Bot
authored
Merge pull request #11120 from deads2k/oc-project-on-kube
Merged by openshift-bot
2 parents 0127d5d + d00a6ef commit b6ba8ec

File tree

8 files changed

+304
-72
lines changed

8 files changed

+304
-72
lines changed

pkg/cmd/cli/cmd/login/helpers.go

+25-6
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@ import (
99
"net/url"
1010
"os"
1111

12-
"github.com/openshift/origin/pkg/client"
13-
"github.com/openshift/origin/pkg/user/api"
14-
"k8s.io/kubernetes/pkg/client/restclient"
15-
kclientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
16-
1712
cmdutil "github.com/openshift/origin/pkg/cmd/util"
13+
kapi "k8s.io/kubernetes/pkg/api"
14+
kerrors "k8s.io/kubernetes/pkg/api/errors"
15+
"k8s.io/kubernetes/pkg/client/restclient"
1816
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
17+
kclientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
1918
"k8s.io/kubernetes/pkg/util/sets"
2019
"k8s.io/kubernetes/pkg/util/term"
20+
21+
"github.com/openshift/origin/pkg/client"
22+
"github.com/openshift/origin/pkg/user/api"
2123
)
2224

2325
// getMatchingClusters examines the kubeconfig for all clusters that point to the same server
@@ -108,8 +110,25 @@ func getHostPort(hostURL string) (string, string, *url.URL, error) {
108110
return host, port, parsedURL, err
109111
}
110112

111-
func whoAmI(client *client.Client) (*api.User, error) {
113+
func whoAmI(clientConfig *restclient.Config) (*api.User, error) {
114+
client, err := client.New(clientConfig)
115+
112116
me, err := client.Users().Get("~")
117+
118+
// if we're talking to kube (or likely talking to kube),
119+
if kerrors.IsNotFound(err) {
120+
switch {
121+
case len(clientConfig.BearerToken) > 0:
122+
// the user has already been willing to provide the token on the CLI, so they probably
123+
// don't mind using it again if they switch to and from this user
124+
return &api.User{ObjectMeta: kapi.ObjectMeta{Name: clientConfig.BearerToken}}, nil
125+
126+
case len(clientConfig.Username) > 0:
127+
return &api.User{ObjectMeta: kapi.ObjectMeta{Name: clientConfig.Username}}, nil
128+
129+
}
130+
}
131+
113132
if err != nil {
114133
return nil, err
115134
}

pkg/cmd/cli/cmd/login/loginoptions.go

+27-35
Original file line numberDiff line numberDiff line change
@@ -173,21 +173,19 @@ func (o *LoginOptions) gatherAuthInfo() error {
173173
// if a token were explicitly provided, try to use it
174174
if o.tokenProvided() {
175175
clientConfig.BearerToken = o.Token
176-
if osClient, err := client.New(clientConfig); err == nil {
177-
me, err := whoAmI(osClient)
178-
if err == nil {
179-
o.Username = me.Name
180-
o.Config = clientConfig
181-
182-
fmt.Fprintf(o.Out, "Logged into %q as %q using the token provided.\n\n", o.Config.Host, o.Username)
183-
return nil
184-
}
176+
if me, err := whoAmI(clientConfig); err == nil {
177+
o.Username = me.Name
178+
o.Config = clientConfig
179+
180+
fmt.Fprintf(o.Out, "Logged into %q as %q using the token provided.\n\n", o.Config.Host, o.Username)
181+
return nil
185182

186-
if !kerrors.IsUnauthorized(err) {
187-
return err
183+
} else {
184+
if kerrors.IsUnauthorized(err) {
185+
return fmt.Errorf("The token provided is invalid or expired.\n\n")
188186
}
189187

190-
return fmt.Errorf("The token provided is invalid or expired.\n\n")
188+
return err
191189
}
192190
}
193191

@@ -202,20 +200,18 @@ func (o *LoginOptions) gatherAuthInfo() error {
202200
if matchingClusters.Has(context.Cluster) {
203201
clientcmdConfig := kclientcmd.NewDefaultClientConfig(kubeconfig, &kclientcmd.ConfigOverrides{CurrentContext: key})
204202
if kubeconfigClientConfig, err := clientcmdConfig.ClientConfig(); err == nil {
205-
if osClient, err := client.New(kubeconfigClientConfig); err == nil {
206-
if me, err := whoAmI(osClient); err == nil && (o.Username == me.Name) {
207-
clientConfig.BearerToken = kubeconfigClientConfig.BearerToken
208-
clientConfig.CertFile = kubeconfigClientConfig.CertFile
209-
clientConfig.CertData = kubeconfigClientConfig.CertData
210-
clientConfig.KeyFile = kubeconfigClientConfig.KeyFile
211-
clientConfig.KeyData = kubeconfigClientConfig.KeyData
203+
if me, err := whoAmI(kubeconfigClientConfig); err == nil && (o.Username == me.Name) {
204+
clientConfig.BearerToken = kubeconfigClientConfig.BearerToken
205+
clientConfig.CertFile = kubeconfigClientConfig.CertFile
206+
clientConfig.CertData = kubeconfigClientConfig.CertData
207+
clientConfig.KeyFile = kubeconfigClientConfig.KeyFile
208+
clientConfig.KeyData = kubeconfigClientConfig.KeyData
212209

213-
o.Config = clientConfig
210+
o.Config = clientConfig
214211

215-
fmt.Fprintf(o.Out, "Logged into %q as %q using existing credentials.\n\n", o.Config.Host, o.Username)
212+
fmt.Fprintf(o.Out, "Logged into %q as %q using existing credentials.\n\n", o.Config.Host, o.Username)
216213

217-
return nil
218-
}
214+
return nil
219215
}
220216
}
221217
}
@@ -234,12 +230,7 @@ func (o *LoginOptions) gatherAuthInfo() error {
234230
}
235231
clientConfig.BearerToken = token
236232

237-
osClient, err := client.New(clientConfig)
238-
if err != nil {
239-
return err
240-
}
241-
242-
me, err := whoAmI(osClient)
233+
me, err := whoAmI(clientConfig)
243234
if err != nil {
244235
return err
245236
}
@@ -270,6 +261,12 @@ func (o *LoginOptions) gatherProjectInfo() error {
270261
}
271262

272263
projectsList, err := oClient.Projects().List(kapi.ListOptions{})
264+
// if we're running on kube (or likely kube), just set it to "default"
265+
if kerrors.IsNotFound(err) {
266+
fmt.Fprintf(o.Out, "Using \"default\". You can switch projects with '%s project <projectname>':\n\n", o.CommandName)
267+
o.Project = "default"
268+
return nil
269+
}
273270
if err != nil {
274271
return err
275272
}
@@ -389,12 +386,7 @@ func (o *LoginOptions) SaveConfig() (bool, error) {
389386
}
390387

391388
func (o LoginOptions) whoAmI() (*api.User, error) {
392-
client, err := client.New(o.Config)
393-
if err != nil {
394-
return nil, err
395-
}
396-
397-
return whoAmI(client)
389+
return whoAmI(o.Config)
398390
}
399391

400392
func (o *LoginOptions) usernameProvided() bool {

pkg/cmd/cli/cmd/login/logout.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ func (o LogoutOptions) RunLogout() error {
117117
return err
118118
}
119119

120-
userInfo, err := whoAmI(client)
120+
userInfo, err := whoAmI(o.Config)
121121
if err != nil {
122122
return err
123123
}

pkg/cmd/cli/cmd/project.go

+40-16
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
kapi "k8s.io/kubernetes/pkg/api"
1010
kapierrors "k8s.io/kubernetes/pkg/api/errors"
1111
"k8s.io/kubernetes/pkg/client/restclient"
12+
kclient "k8s.io/kubernetes/pkg/client/unversioned"
1213
kclientcmd "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
1314
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
1415
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@@ -17,14 +18,15 @@ import (
1718
cliconfig "github.com/openshift/origin/pkg/cmd/cli/config"
1819
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
1920
"github.com/openshift/origin/pkg/project/api"
21+
projectutil "github.com/openshift/origin/pkg/project/util"
2022

2123
"github.com/spf13/cobra"
2224
)
2325

2426
type ProjectOptions struct {
2527
Config clientcmdapi.Config
2628
ClientConfig *restclient.Config
27-
ClientFn func() (*client.Client, error)
29+
ClientFn func() (*client.Client, kclient.Interface, error)
2830
Out io.Writer
2931
PathOptions *kclientcmd.PathOptions
3032

@@ -103,9 +105,8 @@ func (o *ProjectOptions) Complete(f *clientcmd.Factory, args []string, out io.Wr
103105
return err
104106
}
105107

106-
o.ClientFn = func() (*client.Client, error) {
107-
client, _, err := f.Clients()
108-
return client, err
108+
o.ClientFn = func() (*client.Client, kclient.Interface, error) {
109+
return f.Clients()
109110
}
110111

111112
o.Out = out
@@ -136,18 +137,17 @@ func (o ProjectOptions) RunProject() error {
136137
return nil
137138
}
138139

139-
client, err := o.ClientFn()
140+
client, kubeclient, err := o.ClientFn()
140141
if err != nil {
141142
return err
142143
}
143144

144-
if _, err := client.Projects().Get(currentProject); err != nil {
145-
if kapierrors.IsNotFound(err) {
146-
return fmt.Errorf("the project %q specified in your config does not exist.", currentProject)
147-
}
148-
if clientcmd.IsForbidden(err) {
149-
return fmt.Errorf("you do not have rights to view project %q.", currentProject)
150-
}
145+
switch err := confirmProjectAccess(currentProject, client, kubeclient); {
146+
case clientcmd.IsForbidden(err):
147+
return fmt.Errorf("you do not have rights to view project %q.", currentProject)
148+
case kapierrors.IsNotFound(err):
149+
return fmt.Errorf("the project %q specified in your config does not exist.", currentProject)
150+
case err != nil:
151151
return err
152152
}
153153

@@ -187,12 +187,12 @@ func (o ProjectOptions) RunProject() error {
187187

188188
} else {
189189
if !o.SkipAccessValidation {
190-
client, err := o.ClientFn()
190+
client, kubeclient, err := o.ClientFn()
191191
if err != nil {
192192
return err
193193
}
194194

195-
if _, err := client.Projects().Get(argument); err != nil {
195+
if err := confirmProjectAccess(argument, client, kubeclient); err != nil {
196196
if isNotFound, isForbidden := kapierrors.IsNotFound(err), clientcmd.IsForbidden(err); isNotFound || isForbidden {
197197
var msg string
198198
if isForbidden {
@@ -201,7 +201,7 @@ func (o ProjectOptions) RunProject() error {
201201
msg = fmt.Sprintf("A project named %q does not exist on %q.", argument, clientCfg.Host)
202202
}
203203

204-
projects, err := getProjects(client)
204+
projects, err := getProjects(client, kubeclient)
205205
if err == nil {
206206
switch len(projects) {
207207
case 0:
@@ -277,11 +277,35 @@ func (o ProjectOptions) RunProject() error {
277277
return nil
278278
}
279279

280-
func getProjects(oClient *client.Client) ([]api.Project, error) {
280+
func confirmProjectAccess(currentProject string, oClient *client.Client, kClient kclient.Interface) error {
281+
_, projectErr := oClient.Projects().Get(currentProject)
282+
if !kapierrors.IsNotFound(projectErr) {
283+
return projectErr
284+
}
285+
286+
// at this point we know the error is a not found, but we'll test namespaces just in case we're running on kube
287+
if _, err := kClient.Namespaces().Get(currentProject); err == nil {
288+
return nil
289+
}
290+
291+
// otherwise return the openshift error default
292+
return projectErr
293+
}
294+
295+
func getProjects(oClient *client.Client, kClient kclient.Interface) ([]api.Project, error) {
281296
projects, err := oClient.Projects().List(kapi.ListOptions{})
297+
if err == nil {
298+
return projects.Items, nil
299+
}
300+
if err != nil && !kapierrors.IsNotFound(err) {
301+
return nil, err
302+
}
303+
304+
namespaces, err := kClient.Namespaces().List(kapi.ListOptions{})
282305
if err != nil {
283306
return nil, err
284307
}
308+
projects = projectutil.ConvertNamespaceList(namespaces)
285309
return projects.Items, nil
286310
}
287311

pkg/cmd/cli/cmd/projects.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"sort"
77

88
"k8s.io/kubernetes/pkg/client/restclient"
9+
kclient "k8s.io/kubernetes/pkg/client/unversioned"
910
kclientcmd "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
1011
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
1112
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@@ -22,6 +23,7 @@ type ProjectsOptions struct {
2223
Config clientcmdapi.Config
2324
ClientConfig *restclient.Config
2425
Client *client.Client
26+
KubeClient kclient.Interface
2527
Out io.Writer
2628
PathOptions *kclientcmd.PathOptions
2729

@@ -95,7 +97,7 @@ func (o *ProjectsOptions) Complete(f *clientcmd.Factory, args []string, commandN
9597
return err
9698
}
9799

98-
o.Client, _, err = f.Clients()
100+
o.Client, o.KubeClient, err = f.Clients()
99101
if err != nil {
100102
return err
101103
}
@@ -123,7 +125,7 @@ func (o ProjectsOptions) RunProjects() error {
123125
client := o.Client
124126

125127
if len(currentProject) > 0 {
126-
if _, currentProjectErr := client.Projects().Get(currentProject); currentProjectErr == nil {
128+
if currentProjectErr := confirmProjectAccess(currentProject, o.Client, o.KubeClient); currentProjectErr == nil {
127129
currentProjectExists = true
128130
}
129131
}
@@ -134,7 +136,7 @@ func (o ProjectsOptions) RunProjects() error {
134136
}
135137

136138
var msg string
137-
projects, err := getProjects(client)
139+
projects, err := getProjects(client, o.KubeClient)
138140
if err == nil {
139141
switch len(projects) {
140142
case 0:

0 commit comments

Comments
 (0)