Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var RootCmd = &cobra.Command{ Use: "kube-config", Short: "Configure a kubeconfig for Kubernetes Clusters that have Dex as an IDP", Long: `kube-config is a method of authenticating to a Kubernetes cluster which uses Dex an IDP. The tool will authenticate you using your credentials provider, and grab a token. It will also generate you a Kubernetes configuration file based on your login credentials.`, Run: func(cmd *cobra.Command, args []string) { if debug { if a.client == nil { a.client = &http.Client{ Transport: debugTransport{http.DefaultTransport}, } } else { a.client.Transport = debugTransport{a.client.Transport} } } tlsConfig := &tls.Config{ InsecureSkipVerify: insecure, } if a.client == nil { c := cleanhttp.DefaultClient() t := cleanhttp.DefaultTransport() t.TLSClientConfig = tlsConfig c.Transport = t a.client = c } err := viper.UnmarshalKey("tiers", &tiers) if err != nil { log.Fatalf("Failed to unmarshal key for given tiers: %v", tiers) } if listTiers { var entry []string log.Info("Outputting available tiers") table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{"Name", "Issuer", "CAServerName"}) for _, v := range tiers { entry = append(entry, v.Name) entry = append(entry, v.Issuer) entry = append(entry, v.CAServerName) table.Append(entry) entry = entry[:0] } table.Render() os.Exit(0) } for _, i := range tiers { if i.Name == tier { issuerURL = i.Issuer if i.CAServerName != "" { caservername = i.CAServerName } log.Debug("Using Issuer URL: ", issuerURL) } } ctx := oidc.ClientContext(context.Background(), a.client) provider, err := oidc.NewProvider(ctx, issuerURL) if err != nil { log.Fatalf("Failed to query provider %q: %v", issuerURL, err) } var s struct { // What scopes does a provider support? // // See: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata ScopesSupported []string `json:"scopes_supported"` } if err := provider.Claims(&s); err != nil { log.Fatalf("Failed to parse provider scopes_supported: %v", err) } if len(s.ScopesSupported) == 0 { a.offlineAsScope = true } else { a.offlineAsScope = func() bool { for _, scope := range s.ScopesSupported { if scope == oidc.ScopeOfflineAccess { return true } } return false }() } a.provider = provider a.verifier = provider.Verifier(&oidc.Config{ClientID: a.clientID}) a.state, err = generateState() a.tokenRetrieved = make(chan int, 1) if err != nil { log.Fatal("Error generating state: ", err) } fileHandle := os.Stdout if outputFilePath != "" { var ok bool log.Debug(outputFilePath) if _, err := os.Stat(outputFilePath); os.IsNotExist(err) { ok = prompt.Confirm("The kube-config directory doesn't exist at %s - Would you like to create it?: (y/n) ", outputFilePath) if ok { err := os.MkdirAll(outputFilePath, 0700) if err != nil { log.Fatalf("Error creating directory: %s", err) } } else { log.Fatalf("Cannot continue, please create directory %s", outputFilePath) } } fileHandle, err = os.Create(outputFilePath + "/" + tier + "-config.yml") if err != nil { log.Fatalf("Error creating kubeconfig: %v", err) } } userName = viper.GetString("username") a.clientSecret = viper.GetString("client-secret") err = viper.UnmarshalKey("clusters", &clusters) if err != nil { log.Fatalf("Error reading datacenters: %v", err) } if clusters == nil { log.Fatal("No clusters specified in config file") } if userName == "" { log.Fatal("Please specify a username to login with") } if a.clientSecret == "" { log.Fatal("Client secret must be specified in config file") } tierClusters := clusters[:0] for _, c := range clusters { if c.Tier == tier { tierClusters = append(tierClusters, c) } } kubeConfig, err := NewKubeConfig(cluster, tierClusters, userName, namespace, caservername, fileHandle, a.clientID, issuerURL, a.clientSecret) if err != nil { log.Warn("Error generating KubeConfig: ", err) } a.kubeconfig = kubeConfig srv := startHTTPServer(&a, listen) open.Run(listen) <-a.tokenRetrieved ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { log.Info("Error shutting down the server gracefully - this isn't usually an issue: ", err) } log.Infof("Your kubeconfig has been written to %s/%s-config.yml", outputFilePath, tier) kubeconfig := os.Getenv("KUBECONFIG") kc := strings.Split(kubeconfig, ":") valid := stringInSlice(outputFilePath+"/"+tier+"-config.yml", kc) if !valid { fmt.Printf("\nYou have not correctly configured your KUBECONFIG environment variable\nThe file %s/%s-config.yml needs to be added\n", outputFilePath, tier) fmt.Print("Please run the following command:\n\n") fmt.Printf("export KUBECONFIG=$HOME/.kube/config; for i in %s/*.yml; do export KUBECONFIG=$KUBECONFIG:$i; done\n\n", outputFilePath) } }, }
RootCmd represents the base command when called without any subcommands
View Source
var Version string
Version string for the version command
Functions ¶
func Execute ¶
func Execute(version string)
Execute adds all child commands to the root command sets flags appropriately. This is called by main.main(). It only needs to happen once to the rootCmd.
func GetCertificate ¶
GetCertificate fetches remote certificate from the given serverName and address.
Types ¶
type Clusters ¶
type Clusters struct { Name string Address string CAServerName string Certificate string Tier string }
Clusters struct represents type of Cluster.
type KubeConfig ¶
type KubeConfig struct { Cluster string Clusters []Clusters Username string NS string CAServerName string Output io.ReadWriteCloser ClientID string Issuer string ClientSecret string Tier string // contains filtered or unexported fields }
KubeConfig holds the information necessary to generate a Kubernetes configuration file which icludes the server's CA, the api url and where to write the file to.
func NewKubeConfig ¶
func NewKubeConfig(cluster string, clusters []Clusters, username string, namespace string, caservername string, output io.ReadWriteCloser, clientID string, issuer string, clientSecret string) (*KubeConfig, error)
NewKubeConfig returns an initialized KubeConfig struct.
Click to show internal directories.
Click to hide internal directories.