| package main |
| |
| import ( |
| "context" |
| "crypto/x509" |
| "flag" |
| "fmt" |
| "os" |
| "os/user" |
| "syscall" |
| |
| "github.com/golang/glog" |
| "golang.org/x/crypto/ssh/terminal" |
| "google.golang.org/grpc" |
| "google.golang.org/grpc/credentials" |
| |
| "code.hackerspace.pl/cluster/certs" |
| pb "code.hackerspace.pl/hscloud/cluster/prodvider/proto" |
| ) |
| |
| var ( |
| 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(&flagProdvider, "prodvider", "prodvider.hswaw.net:443", "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() |
| |
| if flagUsername == "" { |
| glog.Exitf("Username could not be detected, please provide with -username flag") |
| } |
| |
| cp := x509.NewCertPool() |
| if ok := cp.AppendCertsFromPEM(certs.Data["ca-kube.crt"]); !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() && !flagForce { |
| fmt.Printf("Kubernetes credentials exist. Use `prodaccess -force` to force update.\n") |
| os.Exit(0) |
| } |
| |
| attempts := 0 |
| for { |
| ok := authenticate(ctx, prodvider) |
| attempts += 1 |
| if !ok { |
| if attempts >= 3 { |
| os.Exit(1) |
| } |
| } else { |
| fmt.Printf("Good evening professor. I see you have driven here in your Ferrari.\n") |
| os.Exit(0) |
| } |
| } |
| } |
| |
| func authenticate(ctx context.Context, prodvider pb.ProdviderClient) 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) |
| 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 := terminal.ReadPassword(int(syscall.Stdin)) |
| if err != nil { |
| return "" |
| } |
| fmt.Printf("\n") |
| return string(bytePassword) |
| } |