| Lorenz Brun | 705a402 | 2021-12-23 11:51:06 +0100 | [diff] [blame] | 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "crypto/x509" |
| 5 | "encoding/json" |
| 6 | "encoding/pem" |
| Tim Windelschmidt | d5f851b | 2024-04-23 14:59:37 +0200 | [diff] [blame^] | 7 | "errors" |
| Lorenz Brun | 705a402 | 2021-12-23 11:51:06 +0100 | [diff] [blame] | 8 | "log" |
| 9 | "os" |
| 10 | |
| 11 | "github.com/spf13/cobra" |
| 12 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| Lorenz Brun | 20d1dd1 | 2022-07-01 12:21:42 +0000 | [diff] [blame] | 13 | clientauthentication "k8s.io/client-go/pkg/apis/clientauthentication/v1" |
| Serge Bazanski | cf23ebc | 2023-03-14 17:02:04 +0100 | [diff] [blame] | 14 | |
| 15 | "source.monogon.dev/metropolis/cli/metroctl/core" |
| Lorenz Brun | 705a402 | 2021-12-23 11:51:06 +0100 | [diff] [blame] | 16 | ) |
| 17 | |
| 18 | var k8scredpluginCmd = &cobra.Command{ |
| 19 | Use: "k8scredplugin", |
| 20 | Short: "Kubernetes client-go credential plugin [internal use]", |
| 21 | Long: `This implements a Kubernetes client-go credential plugin to |
| 22 | authenticate client-go based callers including kubectl against a Metropolis |
| 23 | cluster. This should never be directly called by end users.`, |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 24 | Args: cobra.ExactArgs(0), |
| 25 | Hidden: true, |
| 26 | Run: doK8sCredPlugin, |
| Lorenz Brun | 705a402 | 2021-12-23 11:51:06 +0100 | [diff] [blame] | 27 | } |
| 28 | |
| 29 | func doK8sCredPlugin(cmd *cobra.Command, args []string) { |
| Serge Bazanski | cf23ebc | 2023-03-14 17:02:04 +0100 | [diff] [blame] | 30 | cert, key, err := core.GetOwnerCredentials(flags.configPath) |
| Tim Windelschmidt | d5f851b | 2024-04-23 14:59:37 +0200 | [diff] [blame^] | 31 | if errors.Is(err, core.NoCredentialsError) { |
| Lorenz Brun | 705a402 | 2021-12-23 11:51:06 +0100 | [diff] [blame] | 32 | log.Fatal("No credentials found on your machine") |
| 33 | } |
| 34 | if err != nil { |
| 35 | log.Fatalf("failed to get Metropolis credentials: %v", err) |
| 36 | } |
| 37 | |
| 38 | pkcs8Key, err := x509.MarshalPKCS8PrivateKey(key) |
| 39 | if err != nil { |
| 40 | // We explicitly pass an Ed25519 private key in, so this can't happen |
| 41 | panic(err) |
| 42 | } |
| 43 | |
| 44 | cred := clientauthentication.ExecCredential{ |
| 45 | TypeMeta: metav1.TypeMeta{ |
| 46 | APIVersion: clientauthentication.SchemeGroupVersion.String(), |
| 47 | Kind: "ExecCredential", |
| 48 | }, |
| 49 | Status: &clientauthentication.ExecCredentialStatus{ |
| 50 | ClientCertificateData: string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})), |
| 51 | ClientKeyData: string(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: pkcs8Key})), |
| 52 | }, |
| 53 | } |
| 54 | if err := json.NewEncoder(os.Stdout).Encode(cred); err != nil { |
| 55 | log.Fatalf("failed to encode ExecCredential: %v", err) |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | func init() { |
| 60 | rootCmd.AddCommand(k8scredpluginCmd) |
| 61 | } |