forked from hswaw/hscloud
Serge Bazanski
0f8e5a2132
This removes the need to source env.{sh,fish} when working with hscloud. This is done by: 1. Implementing a Go library to reliably detect the location of the active hscloud checkout. That in turn is enabled by BUILD_WORKSPACE_DIRECTORY being now a thing in Bazel. 2. Creating a tool `hscloud`, with a command `hscloud workspace` that returns the workspace path. 3. Wrapping this tool to be accessible from Python and Bash. 4. Bumping all users of hscloud_root to use either the Go library or one of the two implemented wrappers. We also drive-by replace tools/install.sh to be a proper sh_binary, and make it yell at people if it isn't being ran as `bazel run //tools:install`. Finally, we also drive-by delete cluster/tools/nixops.sh which was never used. Change-Id: I7873714319bfc38bbb930b05baa605c5aa36470a Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1169 Reviewed-by: informatic <informatic@hackerspace.pl>
111 lines
2.5 KiB
Go
111 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/golang/glog"
|
|
|
|
pb "code.hackerspace.pl/hscloud/cluster/prodvider/proto"
|
|
"code.hackerspace.pl/hscloud/go/workspace"
|
|
)
|
|
|
|
func kubernetesPaths() (string, string, string) {
|
|
ws, err := workspace.Get()
|
|
if err != nil {
|
|
glog.Exitf("%v", err)
|
|
}
|
|
|
|
localKey := path.Join(ws, ".kubectl", fmt.Sprintf("%s.key", flagUsername))
|
|
localCert := path.Join(ws, ".kubectl", fmt.Sprintf("%s.crt", flagUsername))
|
|
localCA := path.Join(ws, ".kubectl", fmt.Sprintf("ca.crt"))
|
|
|
|
return localKey, localCert, localCA
|
|
}
|
|
|
|
func needKubernetesCreds() bool {
|
|
localKey, localCert, _ := kubernetesPaths()
|
|
|
|
// Check for existence of cert/key.
|
|
if _, err := os.Stat(localKey); os.IsNotExist(err) {
|
|
return true
|
|
}
|
|
if _, err := os.Stat(localCert); os.IsNotExist(err) {
|
|
return true
|
|
}
|
|
|
|
// Cert/key exist, try to load and parse.
|
|
creds, err := tls.LoadX509KeyPair(localCert, localKey)
|
|
if err != nil {
|
|
return true
|
|
}
|
|
if len(creds.Certificate) != 1 {
|
|
return true
|
|
}
|
|
cert, err := x509.ParseCertificate(creds.Certificate[0])
|
|
if err != nil {
|
|
return true
|
|
}
|
|
creds.Leaf = cert
|
|
|
|
// Check if certificate will still be valid in 2 hours.
|
|
target := time.Now().Add(2 * time.Hour)
|
|
if creds.Leaf.NotAfter.Before(target) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func useKubernetesKeys(keys *pb.KubernetesKeys) {
|
|
localKey, localCert, localCA := kubernetesPaths()
|
|
|
|
parent := filepath.Dir(localKey)
|
|
if _, err := os.Stat(parent); os.IsNotExist(err) {
|
|
os.MkdirAll(parent, 0700)
|
|
}
|
|
|
|
if err := ioutil.WriteFile(localKey, keys.Key, 0600); err != nil {
|
|
glog.Exitf("WriteFile(%q): %v", localKey, err)
|
|
}
|
|
if err := ioutil.WriteFile(localCert, keys.Cert, 0600); err != nil {
|
|
glog.Exitf("WriteFile(%q): %v", localCert, err)
|
|
}
|
|
if err := ioutil.WriteFile(localCA, keys.Ca, 0600); err != nil {
|
|
glog.Exitf("WriteFile(%q): %v", localCA, err)
|
|
}
|
|
|
|
kubectl := func(args ...string) {
|
|
cmd := exec.Command("kubectl", args...)
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
glog.Exitf("kubectl %v: %v: %v", args, err, string(out))
|
|
}
|
|
}
|
|
|
|
kubectl("config",
|
|
"set-cluster", keys.Cluster,
|
|
"--certificate-authority="+localCA,
|
|
"--embed-certs=true",
|
|
"--server=https://"+keys.Cluster+":4001")
|
|
|
|
kubectl("config",
|
|
"set-credentials", flagUsername,
|
|
"--client-certificate="+localCert,
|
|
"--client-key="+localKey,
|
|
"--embed-certs=true")
|
|
|
|
kubectl("config",
|
|
"set-context", keys.Cluster,
|
|
"--cluster="+keys.Cluster,
|
|
"--user="+flagUsername)
|
|
|
|
kubectl("config", "use-context", keys.Cluster)
|
|
}
|