m/c/metroctl: add configurable credentials path
This lets metroctl users provide an alternative path to their cluster
credentials. This will be used by the upcoming metroctl test harness.
Change-Id: I49647e3b9d038c230b9678ebb73ba19da038a6d7
Reviewed-on: https://review.monogon.dev/c/monogon/+/833
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/cli/metroctl/credentials.go b/metropolis/cli/metroctl/credentials.go
index 5c23f50..a8885bb 100644
--- a/metropolis/cli/metroctl/credentials.go
+++ b/metropolis/cli/metroctl/credentials.go
@@ -8,8 +8,6 @@
"fmt"
"os"
"path/filepath"
-
- "github.com/adrg/xdg"
)
var noCredentialsError = errors.New("owner certificate or key does not exist")
@@ -17,7 +15,7 @@
// getCredentials returns Metropolis credentials (if any) from the current
// metroctl config directory.
func getCredentials() (cert *x509.Certificate, key ed25519.PrivateKey, err error) {
- ownerPrivateKeyPEM, err := os.ReadFile(filepath.Join(xdg.ConfigHome, "metroctl/owner-key.pem"))
+ ownerPrivateKeyPEM, err := os.ReadFile(filepath.Join(flags.configPath, "owner-key.pem"))
if os.IsNotExist(err) {
return nil, nil, noCredentialsError
} else if err != nil {
@@ -34,7 +32,7 @@
return nil, nil, errors.New("owner-key.pem contains a non-Ed25519 key")
}
key = block.Bytes
- ownerCertPEM, err := os.ReadFile(filepath.Join(xdg.ConfigHome, "metroctl/owner.pem"))
+ ownerCertPEM, err := os.ReadFile(filepath.Join(flags.configPath, "owner.pem"))
if os.IsNotExist(err) {
return nil, nil, noCredentialsError
} else if err != nil {
diff --git a/metropolis/cli/metroctl/install.go b/metropolis/cli/metroctl/install.go
index cbbb9b6..38b82bf 100644
--- a/metropolis/cli/metroctl/install.go
+++ b/metropolis/cli/metroctl/install.go
@@ -12,7 +12,6 @@
"os"
"path/filepath"
- "github.com/adrg/xdg"
"github.com/spf13/cobra"
"source.monogon.dev/metropolis/cli/metroctl/core"
@@ -76,21 +75,21 @@
ctx := clicontext.WithInterrupt(context.Background())
// TODO(lorenz): Have a key management story for this
- if err := os.MkdirAll(filepath.Join(xdg.ConfigHome, "metroctl"), 0700); err != nil {
+ if err := os.MkdirAll(flags.configPath, 0700); err != nil && !os.IsExist(err) {
log.Fatalf("Failed to create config directory: %v", err)
}
var params *api.NodeParameters
if bootstrap {
var ownerPublicKey ed25519.PublicKey
- ownerPrivateKeyPEM, err := os.ReadFile(filepath.Join(xdg.ConfigHome, "metroctl/owner-key.pem"))
+ ownerPrivateKeyPEM, err := os.ReadFile(filepath.Join(flags.configPath, "owner-key.pem"))
if os.IsNotExist(err) {
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
log.Fatalf("Failed to generate owner private key: %v", err)
}
pemPriv := pem.EncodeToMemory(&pem.Block{Type: ownerKeyType, Bytes: priv})
- if err := os.WriteFile(filepath.Join(xdg.ConfigHome, "metroctl/owner-key.pem"), pemPriv, 0600); err != nil {
+ if err := os.WriteFile(filepath.Join(flags.configPath, "owner-key.pem"), pemPriv, 0600); err != nil {
log.Fatalf("Failed to store owner private key: %v", err)
}
ownerPublicKey = pub
diff --git a/metropolis/cli/metroctl/main.go b/metropolis/cli/metroctl/main.go
index 9224598..7c1e050 100644
--- a/metropolis/cli/metroctl/main.go
+++ b/metropolis/cli/metroctl/main.go
@@ -1,6 +1,9 @@
package main
import (
+ "path/filepath"
+
+ "github.com/adrg/xdg"
"github.com/spf13/cobra"
)
@@ -16,6 +19,8 @@
clusterEndpoints []string
// proxyAddr is a SOCKS5 proxy address the cluster will be accessed through.
proxyAddr string
+ // configPath overrides the default XDG config path
+ configPath string
}
var flags metroctlFlags
@@ -23,6 +28,7 @@
func init() {
rootCmd.PersistentFlags().StringArrayVar(&flags.clusterEndpoints, "endpoints", nil, "A list of the target cluster's endpoints.")
rootCmd.PersistentFlags().StringVar(&flags.proxyAddr, "proxy", "", "SOCKS5 proxy address")
+ rootCmd.PersistentFlags().StringVar(&flags.configPath, "config", filepath.Join(xdg.ConfigHome, "metroctl"), "An alternative cluster config path")
}
func main() {
diff --git a/metropolis/cli/metroctl/takeownership.go b/metropolis/cli/metroctl/takeownership.go
index b399d17..975bd38 100644
--- a/metropolis/cli/metroctl/takeownership.go
+++ b/metropolis/cli/metroctl/takeownership.go
@@ -10,7 +10,6 @@
"os/exec"
"path/filepath"
- "github.com/adrg/xdg"
"github.com/spf13/cobra"
"google.golang.org/grpc"
clientauthentication "k8s.io/client-go/pkg/apis/clientauthentication/v1"
@@ -41,7 +40,7 @@
clusterEp := flags.clusterEndpoints[0]
ctx := clicontext.WithInterrupt(context.Background())
- ownerPrivateKeyPEM, err := os.ReadFile(filepath.Join(xdg.ConfigHome, "metroctl/owner-key.pem"))
+ ownerPrivateKeyPEM, err := os.ReadFile(filepath.Join(flags.configPath, "owner-key.pem"))
if os.IsNotExist(err) {
log.Fatalf("Owner key does not exist. takeownership needs to be executed on the same system that has previously installed the cluster using metroctl install.")
} else if err != nil {
@@ -77,7 +76,7 @@
Type: "CERTIFICATE",
Bytes: ownerCert.Certificate[0],
}
- if err := os.WriteFile(filepath.Join(xdg.ConfigHome, "metroctl/owner.pem"), pem.EncodeToMemory(&ownerCertPEM), 0644); err != nil {
+ if err := os.WriteFile(filepath.Join(flags.configPath, "owner.pem"), pem.EncodeToMemory(&ownerCertPEM), 0644); err != nil {
log.Printf("Failed to store retrieved owner certificate: %v", err)
log.Fatalln("Sorry, the cluster has been lost as taking ownership cannot be repeated. Fix the reason the file couldn't be written and reinstall the node.")
}