Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set STRONGBOX_HOME and gitconfig before running apply command #278

Merged
merged 2 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ func main() {
PruneBlacklist: pruneBlacklistSlice,
Repository: repo,
RepoPath: *fRepoPath,
Strongbox: &run.Strongboxer{},
WorkerCount: *fWorkerCount,
}

Expand Down
38 changes: 11 additions & 27 deletions run/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type Runner struct {
PruneBlacklist []string
RepoPath string
Repository *git.Repository
Strongbox StrongboxInterface
WorkerCount int
workerGroup *sync.WaitGroup
workerQueue chan Request
Expand Down Expand Up @@ -210,7 +211,14 @@ func (r *Runner) processRequest(request Request) error {
if err != nil {
return fmt.Errorf("failed setting up repository clone: %w", err)
}

// We need to setup a .gitconfig for strongbox under the temp home dir
// in order to be available when we invoke git via running kustomize.
// That way we should also be able to decrypt files cloned from remote
// bases on kustomize build.
applyOptions.EnvironmentVariables = append(applyOptions.EnvironmentVariables, fmt.Sprintf("STRONGBOX_HOME=%s", tmpHomeDir))
if err := r.Strongbox.SetupGitConfigForStrongbox(ctx, request.Waybill, applyOptions.EnvironmentVariables); err != nil {
return err
}
r.apply(ctx, tmpRepoPath, delegateToken, request.Waybill, applyOptions)

request.Waybill.Status.LastRun.Commit = hash
Expand Down Expand Up @@ -321,40 +329,16 @@ func (r *Runner) setupTempDirs(waybill *kubeapplierv1alpha1.Waybill) (string, st
return tmpHomeDir, tmpRepoDir, func() { os.RemoveAll(tmpHomeDir); os.RemoveAll(tmpRepoDir) }, nil
}

func (r *Runner) setupStrongboxKeyring(ctx context.Context, waybill *kubeapplierv1alpha1.Waybill, tmpHomeDir string) error {
if waybill.Spec.StrongboxKeyringSecretRef == nil {
return nil
}
sbNamespace := waybill.Spec.StrongboxKeyringSecretRef.Namespace
if sbNamespace == "" {
sbNamespace = waybill.Namespace
}
secret, err := r.KubeClient.GetSecret(ctx, sbNamespace, waybill.Spec.StrongboxKeyringSecretRef.Name)
if err != nil {
return err
}
if err := checkSecretIsAllowed(waybill, secret); err != nil {
return err
}
strongboxData, ok := secret.Data[".strongbox_keyring"]
if !ok {
return fmt.Errorf(`secret "%s/%s" does not contain key '.strongbox_keyring'`, secret.Namespace, secret.Name)
}
if err := os.WriteFile(filepath.Join(tmpHomeDir, ".strongbox_keyring"), strongboxData, 0400); err != nil {
return err
}
return nil
}

func (r *Runner) setupRepositoryClone(ctx context.Context, waybill *kubeapplierv1alpha1.Waybill, tmpHomeDir, tmpRepoDir string) (string, string, error) {
if err := r.setupStrongboxKeyring(ctx, waybill, tmpHomeDir); err != nil {
if err := r.Strongbox.SetupStrongboxKeyring(ctx, r.KubeClient, waybill, tmpHomeDir); err != nil {
return "", "", err
}
repositoryPath := waybill.Spec.RepositoryPath
if repositoryPath == "" {
repositoryPath = waybill.Namespace
}
subpath := filepath.Join(r.RepoPath, repositoryPath)
// Point strongbox home to the temporary home to be able to decrypt files based on waybill cnfiguratn
hash, err := r.Repository.CloneLocal(ctx, []string{fmt.Sprintf("STRONGBOX_HOME=%s", tmpHomeDir)}, tmpRepoDir, subpath)
if err != nil {
return "", "", err
Expand Down
1 change: 1 addition & 0 deletions run/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ var _ = Describe("Runner", func() {
PruneBlacklist: []string{"apps/v1/ControllerRevision"},
Repository: repo,
RepoPath: "testdata/manifests",
Strongbox: &mockStrongboxer{},
WorkerCount: 1, // limit to one to prevent race issues
}

Expand Down
74 changes: 74 additions & 0 deletions run/strongbox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package run

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"

kubeapplierv1alpha1 "github.com/utilitywarehouse/kube-applier/apis/kubeapplier/v1alpha1"
"github.com/utilitywarehouse/kube-applier/client"
)

// strongboxInterface holds functions to configure strongbox for waybill runs
type StrongboxInterface interface {
SetupGitConfigForStrongbox(ctx context.Context, waybill *kubeapplierv1alpha1.Waybill, env []string) error
SetupStrongboxKeyring(ctx context.Context, kubeClient *client.Client, waybill *kubeapplierv1alpha1.Waybill, homeDir string) error
}

type strongboxBase struct{}

func (sb *strongboxBase) SetupStrongboxKeyring(ctx context.Context, kubeClient *client.Client, waybill *kubeapplierv1alpha1.Waybill, homeDir string) error {
if waybill.Spec.StrongboxKeyringSecretRef == nil {
return nil
}
sbNamespace := waybill.Spec.StrongboxKeyringSecretRef.Namespace
if sbNamespace == "" {
sbNamespace = waybill.Namespace
}
secret, err := kubeClient.GetSecret(ctx, sbNamespace, waybill.Spec.StrongboxKeyringSecretRef.Name)
if err != nil {
return err
}
if err := checkSecretIsAllowed(waybill, secret); err != nil {
return err
}
strongboxData, ok := secret.Data[".strongbox_keyring"]
if !ok {
return fmt.Errorf(`secret "%s/%s" does not contain key '.strongbox_keyring'`, secret.Namespace, secret.Name)
}
if err := os.WriteFile(filepath.Join(homeDir, ".strongbox_keyring"), strongboxData, 0400); err != nil {
return err
}
return nil
}

type Strongboxer struct {
strongboxBase
}

func (s *Strongboxer) SetupGitConfigForStrongbox(ctx context.Context, waybill *kubeapplierv1alpha1.Waybill, env []string) error {
if waybill.Spec.StrongboxKeyringSecretRef == nil {
return nil
}

cmd := exec.CommandContext(ctx, "strongbox", "-git-config")
// Set PATH so we can find strongbox bin
cmd.Env = append(env, fmt.Sprintf("PATH=%s", os.Getenv("PATH")))
stderr, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("error running strongbox err:%s %w ", stderr, err)
}

return nil
}

// Mock Strongboxer for testing
type mockStrongboxer struct {
strongboxBase
}

func (m *mockStrongboxer) SetupGitConfigForStrongbox(ctx context.Context, waybill *kubeapplierv1alpha1.Waybill, env []string) error {
return nil
}
Loading