diff --git a/controllers/pkg/go.sum b/controllers/pkg/go.sum index 3c1e5b72..38ab02ad 100644 --- a/controllers/pkg/go.sum +++ b/controllers/pkg/go.sum @@ -331,6 +331,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/controllers/pkg/reconcilers/spire-bootstrap/reconciler.go b/controllers/pkg/reconcilers/spire-bootstrap/reconciler.go index 4d025868..4d04f3e9 100644 --- a/controllers/pkg/reconcilers/spire-bootstrap/reconciler.go +++ b/controllers/pkg/reconcilers/spire-bootstrap/reconciler.go @@ -32,6 +32,7 @@ import ( "github.com/spiffe/go-spiffe/v2/spiffeid" "github.com/spiffe/go-spiffe/v2/svid/jwtsvid" + "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" ctrl "sigs.k8s.io/controller-runtime" @@ -109,11 +110,18 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu return reconcile.Result{}, err } - // secrets := &corev1.SecretList{} - // if err := r.List(ctx, secrets); err != nil { - // msg := "cannot list secrets" - // log.Error(err, msg) - // return ctrl.Result{}, errors.Wrap(err, msg) + secrets := &corev1.SecretList{} + if err := r.List(ctx, secrets); err != nil { + msg := "cannot list secrets" + log.Error(err, msg) + return ctrl.Result{}, errors.Wrap(err, msg) + } + + // for _, secret := range secrets.Items { + // if strings.Contains(secret.GetName(), cl.Name) { + // // secret := secret + // // clusterClient, ok := cluster.Cluster{Client: r.Client}.GetClusterClient(&secret) + // } // } // found := false @@ -170,35 +178,13 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu // } // } - // // Example: Update the status if necessary - - socketPath := "unix:///spiffe-workload-api/agent.sock" - - clientOptions := workloadapi.WithClientOptions(workloadapi.WithAddr(socketPath)) - jwtSource, err := workloadapi.NewJWTSource(ctx, clientOptions) - if err != nil { - log.Info("Unable to create JWTSource: %v", err) - } - defer jwtSource.Close() - - audience := "TESTING" - spiffeID := spiffeid.RequireFromString("spiffe://example.org/nephio") - - jwtSVID, err := jwtSource.FetchJWTSVID(ctx, jwtsvid.Params{ - Audience: audience, - Subject: spiffeID, - }) - if err != nil { - log.Info("Unable to fetch JWT-SVID: %v", err) - } + vaultAddr := "http://10.146.0.21:8200" - fmt.Printf("Fetched JWT-SVID: %v\n", jwtSVID.Marshal()) + jwtSVID, err := getJWT(ctx) if err != nil { - log.Error(err, "Spire auth didnt work") + log.Error(err, "Unable to get jwtSVID") } - vaultAddr := "http://10.146.0.21:8200" - clientToken, err := authenticateToVault(vaultAddr, jwtSVID.Marshal(), "dev") if err != nil { log.Error(err, "Error authenticating to Vault:") @@ -206,7 +192,6 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu fmt.Printf("Successfully authenticated to Vault. Client token: %s\n", clientToken) - // Create a Vault client config := vault.DefaultConfig() config.Address = vaultAddr client, err := vault.NewClient(config) @@ -214,10 +199,8 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu log.Error(err, "Unable to create Vault client:") } - // Set the client token client.SetToken(clientToken) - // Retrieve the secret secret, err := getSecret(client, "secret/my-super-secret") if err != nil { log.Error(err, "Error retrieving secret:") @@ -228,6 +211,35 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu return reconcile.Result{}, nil } +func getJWT(ctx context.Context) (*jwtsvid.SVID, error) { + socketPath := "unix:///spiffe-workload-api/agent.sock" + log := log.FromContext(ctx) + clientOptions := workloadapi.WithClientOptions(workloadapi.WithAddr(socketPath)) + jwtSource, err := workloadapi.NewJWTSource(ctx, clientOptions) + if err != nil { + log.Info("Unable to create JWTSource: %v", err) + } + defer jwtSource.Close() + + audience := "TESTING" + spiffeID := spiffeid.RequireFromString("spiffe://example.org/nephio") + + jwtSVID, err := jwtSource.FetchJWTSVID(ctx, jwtsvid.Params{ + Audience: audience, + Subject: spiffeID, + }) + if err != nil { + log.Info("Unable to fetch JWT-SVID: %v", err) + } + + fmt.Printf("Fetched JWT-SVID: %v\n", jwtSVID.Marshal()) + if err != nil { + log.Error(err, "Spire auth didnt work") + } + + return jwtSVID, err +} + func authenticateToVault(vaultAddr, jwt, role string) (string, error) { // Create a Vault client config := vault.DefaultConfig() @@ -237,7 +249,6 @@ func authenticateToVault(vaultAddr, jwt, role string) (string, error) { return "", fmt.Errorf("unable to create Vault client: %w", err) } - // Prepare the login payload payload := LoginPayload{ Role: role, JWT: jwt, @@ -257,13 +268,11 @@ func authenticateToVault(vaultAddr, jwt, role string) (string, error) { } defer resp.Body.Close() - // Read the response body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("unable to read response body: %w", err) } - // Parse the response var authResp AuthResponse if err := json.Unmarshal(body, &authResp); err != nil { return "", fmt.Errorf("unable to decode response: %w", err) @@ -273,7 +282,6 @@ func authenticateToVault(vaultAddr, jwt, role string) (string, error) { } func getSecret(client *vault.Client, secretPath string) (map[string]interface{}, error) { - // Read the secret secret, err := client.Logical().Read(secretPath) if err != nil { return nil, fmt.Errorf("unable to read secret: %w", err) @@ -285,3 +293,42 @@ func getSecret(client *vault.Client, secretPath string) (map[string]interface{}, return secret.Data, nil } + +// func storeKubeconfig(kubeconfigData corev1.Secret, client *vault.Client, secretPath, clusterName, kubeconfigPath string) error { +// // Read the Kubeconfig file + +// // Prepare the data to store +// data := map[string]interface{}{ +// "data": map[string]interface{}{ +// clusterName: string(), +// }, +// } + +// // Store the data in Vault +// _, err = client.Logical().Write(secretPath, data) +// if err != nil { +// return fmt.Errorf("unable to write secret to Vault: %w", err) +// } + +// return nil +// } + +func fetchKubeconfig(client *vault.Client, secretPath, clusterName string) (string, error) { + // Read the secret + secret, err := client.Logical().Read(secretPath) + if err != nil { + return "", fmt.Errorf("unable to read secret: %w", err) + } + + if secret == nil { + return "", fmt.Errorf("secret not found at path: %s", secretPath) + } + + // Extract the Kubeconfig data + kubeconfig, ok := secret.Data["data"].(map[string]interface{})[clusterName].(string) + if !ok { + return "", fmt.Errorf("kubeconfig for cluster %s not found", clusterName) + } + + return kubeconfig, nil +}