/
login.go
127 lines (109 loc) · 3.97 KB
/
login.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
package cmd
import (
"time"
"github.com/sky-uk/osprey/v2/client"
"github.com/sky-uk/osprey/v2/client/kubeconfig"
"github.com/spf13/cobra"
"fmt"
"os"
"strings"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
var loginCmd = &cobra.Command{
Use: "login",
Short: "Login to one or more Kubernetes clusters",
Long: `Login will take the user credentials and validate against the configured set of osprey servers.
On a successful authentication it will generate a kubectl config file that will grant the user access to the clusters
via different contexts.
It expects the osprey server(s) to return OpenID Connect required information to set up the kubectl config auth-provider.
It will generate a kubectl configuration file for the specified server(s).
The connection to the osprey servers is via HTTPS.
`,
Run: login,
}
var (
useDeviceCode bool
loginTimeout time.Duration
disableBrowserPopup bool
username string
password string
)
func init() {
userCmd.AddCommand(loginCmd)
loginCmd.Flags().BoolVarP(&useDeviceCode, "use-device-code", "", false,
"set to true to use a device-code flow for authorisation")
loginCmd.Flags().DurationVar(&loginTimeout, "login-timeout", 90*time.Second,
"set to override the login timeout when using local callback or device-code flow for authorisation")
loginCmd.Flags().BoolVarP(&disableBrowserPopup, "disable-browser-popup", "", false,
"enable to disable the browser popup used for authentication")
loginCmd.Flags().StringVarP(&username, "username", "u", "",
"username for authenticating with the osprey server")
loginCmd.Flags().StringVarP(&password, "password", "p", "",
"password for authenticating with the osprey server")
}
func login(_ *cobra.Command, _ []string) {
ospreyconfig, err := client.LoadConfig(ospreyconfigFile)
if err != nil {
log.Fatalf("Failed to load ospreyconfig file %s: %v", ospreyconfigFile, err)
}
err = kubeconfig.LoadConfig(ospreyconfig.Kubeconfig)
if err != nil {
log.Fatalf("Failed to initialise kubeconfig: %v", err)
}
groupName := ospreyconfig.GroupOrDefault(targetGroup)
snapshot := ospreyconfig.Snapshot()
group, ok := snapshot.GetGroup(groupName)
if !ok {
log.Errorf("Group not found: %q", groupName)
os.Exit(1)
}
displayActiveGroup(targetGroup, ospreyconfig.DefaultGroup)
retrieverOptions := client.RetrieverOptions{
UseDeviceCode: useDeviceCode,
LoginTimeout: loginTimeout,
DisableBrowserPopup: disableBrowserPopup,
Username: username,
Password: password,
}
success := true
retrievers, err := ospreyconfig.GetRetrievers(snapshot.ProviderConfigs(), retrieverOptions)
if err != nil {
log.Fatalf("Unable to initialise retrievers: %v", err)
}
for providerName, targets := range group.TargetsForProvider() {
retriever, ok := retrievers[providerName]
if !ok {
log.Fatalf("Unsupported provider: %s", providerName)
}
for _, target := range targets {
targetData, err := retriever.RetrieveClusterDetailsAndAuthTokens(target)
if err != nil {
if state, ok := status.FromError(err); ok && state.Code() == codes.Unauthenticated {
log.Fatalf("Failed to log in to %s: %v", target.Name(), state.Message())
}
success = false
log.Errorf("Failed to log in to %s: %v", target.Name(), err)
continue
}
updateKubeconfig(target, targetData)
}
}
if !success {
log.Fatal("Failed to update credentials for some targets.")
}
}
// updateKubeconfig modifies the loaded kubeconfig file with the client ID and access token required for access
func updateKubeconfig(target client.Target, tokenData *client.TargetInfo) {
err := kubeconfig.UpdateConfig(target.Name(), target.Aliases(), tokenData)
if err != nil {
log.Errorf("Failed to update config for %s: %v", target.Name(), err)
return
}
aliases := ""
if target.HasAliases() {
aliases = fmt.Sprintf(" | %s", strings.Join(target.Aliases(), " | "))
}
log.Infof("Logged in to: %s %s", target.Name(), aliases)
}