mirror of
https://gerrit.hackerspace.pl/hscloud
synced 2025-01-24 17:53:53 +00:00
Adds //cluster/k1/certs go package, and changes prodaccess to look up the correct one based on the -cluster flag. This should complete the transition of prodaccess to multicluster. Change-Id: If65fab8f898a48ec16e6de7eeb02fd0aacee30b4 Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2117 Reviewed-by: q3k <q3k@hackerspace.pl>
155 lines
3.5 KiB
Go
155 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"crypto/x509"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/user"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/golang/glog"
|
|
"golang.org/x/term"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
|
|
"code.hackerspace.pl/hscloud/cluster/clustercfg/clusters"
|
|
pb "code.hackerspace.pl/hscloud/cluster/prodvider/proto"
|
|
)
|
|
|
|
var (
|
|
flagCluster string
|
|
flagProdvider string
|
|
flagUsername string
|
|
flagForce bool
|
|
)
|
|
|
|
func init() {
|
|
flag.Set("logtostderr", "true")
|
|
}
|
|
|
|
func main() {
|
|
user, err := user.Current()
|
|
if err == nil {
|
|
flagUsername = user.Username
|
|
}
|
|
|
|
flag.StringVar(&flagCluster, "cluster", "k0", "Cluster short name")
|
|
flag.StringVar(&flagProdvider, "prodvider", "", "Prodvider endpoint")
|
|
flag.StringVar(&flagUsername, "username", flagUsername, "Username to authenticate with")
|
|
flag.BoolVar(&flagForce, "force", false, "Force retrieving certificates even if they already exist")
|
|
flag.Parse()
|
|
|
|
flagUsername = strings.ToLower(flagUsername)
|
|
if flagUsername == "" {
|
|
glog.Exitf("Username could not be detected, please provide with -username flag")
|
|
}
|
|
|
|
cluster, ok := clusters.Clusters[flagCluster]
|
|
if !ok {
|
|
log.Fatalf("Unknown cluster: %q", flagCluster)
|
|
}
|
|
|
|
if flagProdvider == "" {
|
|
flagProdvider = "prodvider." + cluster.Name + ".hswaw.net:443"
|
|
}
|
|
|
|
cp := x509.NewCertPool()
|
|
if ok := cp.AppendCertsFromPEM(getCert(cluster)); !ok {
|
|
glog.Exitf("Could not load k8s CA")
|
|
}
|
|
|
|
creds := credentials.NewClientTLSFromCert(cp, "")
|
|
conn, err := grpc.Dial(flagProdvider, grpc.WithTransportCredentials(creds))
|
|
if err != nil {
|
|
glog.Exitf("Could not dial prodvider: %v", err)
|
|
}
|
|
|
|
prodvider := pb.NewProdviderClient(conn)
|
|
ctx := context.Background()
|
|
|
|
if !needKubernetesCreds(cluster) && !flagForce {
|
|
fmt.Printf("Kubernetes credentials exist. Use `prodaccess -force` to force update.\n")
|
|
os.Exit(0)
|
|
}
|
|
|
|
attempts := 0
|
|
for {
|
|
ok := authenticate(ctx, prodvider, cluster)
|
|
attempts += 1
|
|
if !ok {
|
|
if attempts >= 3 {
|
|
os.Exit(1)
|
|
}
|
|
} else {
|
|
greetings(strings.ToLower(flagUsername))
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
}
|
|
|
|
func authenticate(ctx context.Context, prodvider pb.ProdviderClient, cluster clusters.Cluster) bool {
|
|
req := &pb.AuthenticateRequest{
|
|
Username: flagUsername,
|
|
Password: password(),
|
|
}
|
|
|
|
res, err := prodvider.Authenticate(ctx, req)
|
|
if err != nil {
|
|
glog.Exitf("Prodvider error: %v", err)
|
|
}
|
|
|
|
switch res.Result {
|
|
case pb.AuthenticateResponse_RESULT_AUTHENTICATED:
|
|
break
|
|
case pb.AuthenticateResponse_RESULT_INVALID_CREDENTIALS:
|
|
fmt.Printf("Invalid username or password.\n")
|
|
return false
|
|
default:
|
|
glog.Exitf("Unknown authentication result: %v", res.Result)
|
|
}
|
|
|
|
useKubernetesKeys(res.KubernetesKeys, cluster)
|
|
fmt.Printf("-> Kubernetes credentials installed\n")
|
|
useHSPKIKeys(res.HspkiKeys)
|
|
fmt.Printf("-> HSPKI credentials installed\n")
|
|
|
|
return true
|
|
}
|
|
|
|
func password() string {
|
|
fmt.Printf("Enter SSO/LDAP password for %s@hackerspace.pl: ", flagUsername)
|
|
bytePassword, err := term.ReadPassword(int(syscall.Stdin))
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
fmt.Printf("\n")
|
|
return string(bytePassword)
|
|
}
|
|
|
|
func greetings(username string) {
|
|
fmt.Printf("Good evening %s. I see you have driven here in your %s.\n", userTitle(username), userVehicle(username))
|
|
}
|
|
|
|
func userTitle(username string) string {
|
|
switch username {
|
|
case "drozdziak1":
|
|
return "Dr. Oździak"
|
|
case "radex":
|
|
return "Mr. Secretary"
|
|
default:
|
|
return "professor"
|
|
}
|
|
}
|
|
|
|
func userVehicle(username string) string {
|
|
switch username {
|
|
case "drozdziak1", "krnlexception":
|
|
return "Ford Focus"
|
|
default:
|
|
return "Ferrari"
|
|
}
|
|
}
|