Skip to content

Commit b3b6b08

Browse files
committed
preserve error type in loginoptions
1 parent ea8f407 commit b3b6b08

File tree

9 files changed

+94
-16
lines changed

9 files changed

+94
-16
lines changed

pkg/oc/bootstrap/docker/openshift/login.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
)
1919

2020
// Login logs into the specified server using given credentials and CA file
21-
func Login(username, password, server, configDir string, f *clientcmd.Factory, c *cobra.Command, out io.Writer) error {
21+
func Login(username, password, server, configDir string, f *clientcmd.Factory, c *cobra.Command, out, errOut io.Writer) error {
2222
existingConfig, err := f.OpenShiftClientConfig().RawConfig()
2323
if err != nil {
2424
if !os.IsNotExist(err) {
@@ -72,6 +72,7 @@ func Login(username, password, server, configDir string, f *clientcmd.Factory, c
7272
Username: username,
7373
Password: password,
7474
Out: output,
75+
ErrOut: errOut,
7576
StartingKubeConfig: newConfig,
7677
PathOptions: config.NewPathOptions(c),
7778
}

pkg/oc/bootstrap/docker/up.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ func (c *ClientStartConfig) RegisterTemplateServiceBroker(out io.Writer) error {
11121112
// Login logs into the new server and sets up a default user and project
11131113
func (c *ClientStartConfig) Login(out io.Writer) error {
11141114
server := c.OpenShiftHelper().Master(c.ServerIP)
1115-
return openshift.Login(initialUser, initialPassword, server, c.LocalConfigDir, c.originalFactory, c.command, out)
1115+
return openshift.Login(initialUser, initialPassword, server, c.LocalConfigDir, c.originalFactory, c.command, out, out)
11161116
}
11171117

11181118
// CreateProject creates a new project for the current user

pkg/oc/cli/cli.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) *
8686

8787
f := clientcmd.New(cmds.PersistentFlags())
8888

89-
loginCmd := login.NewCmdLogin(fullName, f, in, out)
89+
loginCmd := login.NewCmdLogin(fullName, f, in, out, errout)
9090
secretcmds := secrets.NewCmdSecrets(secrets.SecretsRecommendedName, fullName+" "+secrets.SecretsRecommendedName, f, in, out, errout, fullName+" edit")
9191

9292
groups := ktemplates.CommandGroups{

pkg/oc/cli/cmd/login/login.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ var (
4646
)
4747

4848
// NewCmdLogin implements the OpenShift cli login command
49-
func NewCmdLogin(fullName string, f *osclientcmd.Factory, reader io.Reader, out io.Writer) *cobra.Command {
49+
func NewCmdLogin(fullName string, f *osclientcmd.Factory, reader io.Reader, out, errOut io.Writer) *cobra.Command {
5050
options := &LoginOptions{
5151
Reader: reader,
5252
Out: out,
53+
ErrOut: errOut,
5354
}
5455

5556
cmds := &cobra.Command{

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

+4-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"fmt"
88
"io"
99
"net"
10-
"net/http"
1110
"os"
1211
"path/filepath"
1312
"time"
@@ -56,6 +55,7 @@ type LoginOptions struct {
5655
Config *restclient.Config
5756
Reader io.Reader
5857
Out io.Writer
58+
ErrOut io.Writer
5959

6060
// cert data to be used when authenticating
6161
CertFile string
@@ -225,16 +225,9 @@ func (o *LoginOptions) gatherAuthInfo() error {
225225
clientConfig.KeyFile = o.KeyFile
226226
token, err := tokencmd.RequestToken(o.Config, o.Reader, o.Username, o.Password)
227227
if err != nil {
228-
suggestion := "verify you have provided the correct host and port and that the server is currently running."
229-
230-
// if internal error occurs, suggest making sure
231-
// client is connecting to the right host:port
232-
if statusErr, ok := err.(*kerrors.StatusError); ok {
233-
if statusErr.Status().Code == http.StatusInternalServerError {
234-
return fmt.Errorf("error: The server was unable to respond - %v", suggestion)
235-
}
236-
}
237-
return fmt.Errorf("%v - %v", err, suggestion)
228+
// return error as-is, as method caller expects to check its type
229+
fmt.Fprintf(o.ErrOut, "error: %v - %v\n", err, "verify you have provided the correct host and port and that the server is currently running.")
230+
return err
238231
}
239232
clientConfig.BearerToken = token
240233

pkg/oc/cli/cmd/login/loginoptions_test.go

+80
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package login
22

33
import (
4+
"bytes"
45
"crypto/tls"
6+
"encoding/json"
57
"fmt"
8+
"io/ioutil"
69
"net/http"
710
"net/http/httptest"
811
"regexp"
@@ -12,12 +15,18 @@ import (
1215
"github.com/MakeNowJust/heredoc"
1316

1417
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
18+
"github.com/openshift/origin/pkg/oauth/util"
1519
"github.com/openshift/origin/pkg/oc/cli/config"
1620

21+
kapierrs "k8s.io/apimachinery/pkg/api/errors"
1722
restclient "k8s.io/client-go/rest"
1823
kclientcmdapi "k8s.io/client-go/tools/clientcmd/api"
1924
)
2025

26+
const (
27+
oauthMetadataEndpoint = "/.well-known/oauth-authorization-server"
28+
)
29+
2130
func TestNormalizeServerURL(t *testing.T) {
2231
testCases := []struct {
2332
originalServerURL string
@@ -256,6 +265,77 @@ func TestDialToHTTPServer(t *testing.T) {
256265
}
257266
}
258267

268+
type oauthMetadataResponse struct {
269+
metadata *util.OauthAuthorizationServerMetadata
270+
}
271+
272+
func (r *oauthMetadataResponse) Serialize() ([]byte, error) {
273+
b, err := json.Marshal(r.metadata)
274+
if err != nil {
275+
return []byte{}, err
276+
}
277+
278+
return b, nil
279+
}
280+
281+
func TestPreserveErrTypeAuthInfo(t *testing.T) {
282+
invoked := make(chan struct{}, 2)
283+
oauthResponse := []byte{}
284+
285+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
286+
select {
287+
case invoked <- struct{}{}:
288+
default:
289+
t.Fatalf("unexpected request handled by test server: %v: %v", r.Method, r.URL)
290+
}
291+
292+
if r.URL.Path == oauthMetadataEndpoint {
293+
w.WriteHeader(http.StatusOK)
294+
w.Write(oauthResponse)
295+
return
296+
}
297+
w.WriteHeader(http.StatusUnauthorized)
298+
}))
299+
defer server.Close()
300+
301+
metadataResponse := &oauthMetadataResponse{}
302+
metadataResponse.metadata = &util.OauthAuthorizationServerMetadata{
303+
Issuer: server.URL,
304+
AuthorizationEndpoint: server.URL + "/oauth/authorize",
305+
TokenEndpoint: server.URL + "/oauth/token",
306+
CodeChallengeMethodsSupported: []string{"plain", "S256"},
307+
}
308+
309+
oauthResponse, err := metadataResponse.Serialize()
310+
if err != nil {
311+
t.Fatalf("unexpected error: %v", err)
312+
}
313+
314+
options := &LoginOptions{
315+
Server: server.URL,
316+
StartingKubeConfig: &kclientcmdapi.Config{},
317+
Username: "test",
318+
Password: "test",
319+
Reader: bytes.NewReader([]byte{}),
320+
321+
Config: &restclient.Config{
322+
Host: server.URL,
323+
},
324+
325+
Out: ioutil.Discard,
326+
ErrOut: ioutil.Discard,
327+
}
328+
329+
err = options.gatherAuthInfo()
330+
if err == nil {
331+
t.Fatalf("expecting unauthorized error when gathering authinfo")
332+
}
333+
334+
if !kapierrs.IsUnauthorized(err) {
335+
t.Fatalf("expecting error of type metav1.StatusReasonUnauthorized, but got %T", err)
336+
}
337+
}
338+
259339
func TestDialToHTTPSServer(t *testing.T) {
260340
invoked := make(chan struct{}, 1)
261341
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

test/integration/login_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ func newLoginOptions(server string, username string, password string, insecure b
139139
Password: password,
140140
InsecureTLS: insecure,
141141

142-
Out: ioutil.Discard,
142+
Out: ioutil.Discard,
143+
ErrOut: ioutil.Discard,
143144
}
144145

145146
return loginOptions

test/integration/oauth_oidc_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ func TestOAuthOIDC(t *testing.T) {
162162
StartingKubeConfig: &clientcmdapi.Config{},
163163
Reader: bytes.NewBufferString("mylogin\nmypassword\n"),
164164
Out: loginOutput,
165+
ErrOut: ioutil.Discard,
165166
}
166167
if err := loginOptions.GatherInfo(); err != nil {
167168
t.Fatalf("Error logging in: %v\n%v", err, loginOutput.String())

test/integration/oauth_request_header_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ func TestOAuthRequestHeader(t *testing.T) {
310310
StartingKubeConfig: &clientcmdapi.Config{},
311311
Reader: bytes.NewBufferString("myusername\nmypassword\n"),
312312
Out: loginOutput,
313+
ErrOut: ioutil.Discard,
313314
}
314315
if err := loginOptions.GatherInfo(); err != nil {
315316
t.Fatalf("Error trying to determine server info: %v\n%v", err, loginOutput.String())

0 commit comments

Comments
 (0)