metropolis/cli/metroctl: refactor to use RunE instead of log.Fatal

Change-Id: Id5ca65980816e1715a8f08afcdf712292117012a
Reviewed-on: https://review.monogon.dev/c/monogon/+/3441
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
Tested-by: Jenkins CI
diff --git a/metropolis/cli/metroctl/cmd_certs.go b/metropolis/cli/metroctl/cmd_certs.go
index 8475546..9aa0953 100644
--- a/metropolis/cli/metroctl/cmd_certs.go
+++ b/metropolis/cli/metroctl/cmd_certs.go
@@ -4,6 +4,7 @@
 	"crypto/x509"
 	"encoding/pem"
 	"errors"
+	"fmt"
 	"log"
 	"os"
 
@@ -27,10 +28,10 @@
 	Short:   "Exports certificates for use in other programs",
 	Use:     "export",
 	Example: "metroctl cert export",
-	Run: func(cmd *cobra.Command, args []string) {
+	RunE: func(cmd *cobra.Command, args []string) error {
 		ocert, opkey, err := core.GetOwnerCredentials(flags.configPath)
 		if errors.Is(err, core.ErrNoCredentials) {
-			log.Fatalf("You have to take ownership of the cluster first: %v", err)
+			return fmt.Errorf("you have to take ownership of the cluster first: %w", err)
 		}
 
 		pkcs8Key, err := x509.MarshalPKCS8PrivateKey(opkey)
@@ -40,13 +41,15 @@
 		}
 
 		if err := os.WriteFile("owner.crt", pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: ocert.Raw}), 0755); err != nil {
-			log.Fatal(err)
+			return err
 		}
 
 		if err := os.WriteFile("owner.key", pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: pkcs8Key}), 0755); err != nil {
-			log.Fatal(err)
+			return err
 		}
+
 		log.Println("Wrote files to current dir: cert.pem, key.pem")
+		return nil
 	},
 	Args: PrintUsageOnWrongArgs(cobra.NoArgs),
 }