forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
errors.go
136 lines (113 loc) · 4.62 KB
/
errors.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
package clientcmd
import (
"crypto/x509"
"errors"
"fmt"
"strings"
kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/tools/clientcmd"
)
const (
unknownReason = iota
noServerFoundReason
certificateAuthorityUnknownReason
certificateHostnameErrorReason
certificateInvalidReason
configurationInvalidReason
tlsOversizedRecordReason
certificateAuthorityUnknownMsg = "The server uses a certificate signed by unknown authority. You may need to use the --certificate-authority flag to provide the path to a certificate file for the certificate authority, or --insecure-skip-tls-verify to bypass the certificate check and use insecure connections."
notConfiguredMsg = `The client is not configured. You need to run the login command in order to create a default config for your server and credentials:
oc login
You can also run this command again providing the path to a config file directly, either through the --config flag of the KUBECONFIG environment variable.
`
tlsOversizedRecordMsg = `Unable to connect to %[2]s using TLS: %[1]s.
Ensure the specified server supports HTTPS.`
)
// GetPrettyMessageFor prettifys the message of the provided error
func GetPrettyMessageFor(err error) string {
return GetPrettyMessageForServer(err, "")
}
// GetPrettyMessageForServer prettifys the message of the provided error
func GetPrettyMessageForServer(err error, serverName string) string {
if err == nil {
return ""
}
reason := detectReason(err)
switch reason {
case noServerFoundReason:
return notConfiguredMsg
case certificateAuthorityUnknownReason:
return certificateAuthorityUnknownMsg
case tlsOversizedRecordReason:
if len(serverName) == 0 {
serverName = "server"
}
return fmt.Sprintf(tlsOversizedRecordMsg, err, serverName)
case certificateHostnameErrorReason:
return fmt.Sprintf("The server is using a certificate that does not match its hostname: %s", err)
case certificateInvalidReason:
return fmt.Sprintf("The server is using an invalid certificate: %s", err)
}
return err.Error()
}
// GetPrettyErrorFor prettifys the message of the provided error
func GetPrettyErrorFor(err error) error {
return GetPrettyErrorForServer(err, "")
}
// GetPrettyErrorForServer prettifys the message of the provided error
func GetPrettyErrorForServer(err error, serverName string) error {
return errors.New(GetPrettyMessageForServer(err, serverName))
}
// IsNoServerFound checks whether the provided error is a 'no server found' error or not
func IsNoServerFound(err error) bool {
return detectReason(err) == noServerFoundReason
}
// IsConfigurationInvalid checks whether the provided error is a 'invalid configuration' error or not
func IsConfigurationInvalid(err error) bool {
return detectReason(err) == configurationInvalidReason
}
// IsCertificateAuthorityUnknown checks whether the provided error is a 'certificate authority unknown' error or not
func IsCertificateAuthorityUnknown(err error) bool {
return detectReason(err) == certificateAuthorityUnknownReason
}
// IsForbidden checks whether the provided error is a 'forbidden' error or not
func IsForbidden(err error) bool {
return kerrors.IsForbidden(err)
}
// IsTLSOversizedRecord checks whether the provided error is a url.Error
// with "tls: oversized record received", which usually means TLS not supported.
func IsTLSOversizedRecord(err error) bool {
return detectReason(err) == tlsOversizedRecordReason
}
// IsCertificateHostnameError checks whether the set of authorized names doesn't match the requested name
func IsCertificateHostnameError(err error) bool {
return detectReason(err) == certificateHostnameErrorReason
}
// IsCertificateInvalid checks whether the certificate is invalid for reasons like expired, CA not authorized
// to sign, there are too many cert intermediates, or the cert usage is not valid for the wanted purpose.
func IsCertificateInvalid(err error) bool {
return detectReason(err) == certificateInvalidReason
}
func detectReason(err error) int {
if err != nil {
switch {
case strings.Contains(err.Error(), "certificate signed by unknown authority"):
return certificateAuthorityUnknownReason
case strings.Contains(err.Error(), "no server defined"):
return noServerFoundReason
case clientcmd.IsConfigurationInvalid(err):
return configurationInvalidReason
case strings.Contains(err.Error(), "tls: oversized record received"):
return tlsOversizedRecordReason
}
switch err.(type) {
case x509.UnknownAuthorityError:
return certificateAuthorityUnknownReason
case x509.HostnameError:
return certificateHostnameErrorReason
case x509.CertificateInvalidError:
return certificateInvalidReason
}
}
return unknownReason
}