blob: 2d734f95db18b79d5c997a00a23115004b9f3ed9 [file] [log] [blame]
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/hscloud/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)
}