diff --git a/cmd/flux/bootstrap_git.go b/cmd/flux/bootstrap_git.go index 1a583a2a..e7130243 100644 --- a/cmd/flux/bootstrap_git.go +++ b/cmd/flux/bootstrap_git.go @@ -199,6 +199,15 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { RecurseSubmodules: bootstrapArgs.recurseSubmodules, } + var caBundle []byte + if bootstrapArgs.caFile != "" { + var err error + caBundle, err = os.ReadFile(bootstrapArgs.caFile) + if err != nil { + return fmt.Errorf("unable to read TLS CA file: %w", err) + } + } + // Bootstrap config bootstrapOpts := []bootstrap.GitOption{ bootstrap.WithRepositoryURL(gitArgs.url), @@ -208,6 +217,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext), bootstrap.WithPostGenerateSecretFunc(promptPublicKey), bootstrap.WithLogger(logger), + bootstrap.WithCABundle(caBundle), } // Setup bootstrapper with constructed configs diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index 34d54840..91a9fa3c 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -47,7 +47,7 @@ type Reconciler interface { // manifests with the provided values, committing them to Git and // pushing to remote if there are any changes, and applying them // to the cluster. - ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options) error + ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options, secretOpts sourcesecret.Options) error // ReconcileSourceSecret reconciles the source secret by generating // a new secret with the provided values if the secret does not @@ -87,7 +87,7 @@ func Run(ctx context.Context, reconciler Reconciler, manifestsBase string, } } - if err := reconciler.ReconcileComponents(ctx, manifestsBase, installOpts); err != nil { + if err := reconciler.ReconcileComponents(ctx, manifestsBase, installOpts, secretOpts); err != nil { return err } if err := reconciler.ReconcileSourceSecret(ctx, secretOpts); err != nil { diff --git a/internal/bootstrap/bootstrap_plain_git.go b/internal/bootstrap/bootstrap_plain_git.go index e0018b89..6475c40f 100644 --- a/internal/bootstrap/bootstrap_plain_git.go +++ b/internal/bootstrap/bootstrap_plain_git.go @@ -46,8 +46,9 @@ import ( ) type PlainGitBootstrapper struct { - url string - branch string + url string + branch string + caBundle []byte author git.Author commitMessageAppendix string @@ -70,6 +71,16 @@ func WithRepositoryURL(url string) GitOption { return repositoryURLOption(url) } +func WithCABundle(b []byte) GitOption { + return caBundleOption(b) +} + +type caBundleOption []byte + +func (o caBundleOption) applyGit(b *PlainGitBootstrapper) { + b.caBundle = o +} + type repositoryURLOption string func (o repositoryURLOption) applyGit(b *PlainGitBootstrapper) { @@ -97,7 +108,7 @@ func NewPlainGitProvider(git git.Git, kube client.Client, opts ...GitOption) (*P return b, nil } -func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options) error { +func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options, secretOpts sourcesecret.Options) error { // Clone if not already if _, err := b.git.Status(); err != nil { if err != git.ErrNoGitRepository { @@ -107,7 +118,7 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest b.logger.Actionf("cloning branch %q from Git repository %q", b.branch, b.url) var cloned bool if err = retry(1, 2*time.Second, func() (err error) { - cloned, err = b.git.Clone(ctx, b.url, b.branch) + cloned, err = b.git.Clone(ctx, b.url, b.branch, b.caBundle) return }); err != nil { return fmt.Errorf("failed to clone repository: %w", err) @@ -145,7 +156,7 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest if err == nil { b.logger.Successf("committed sync manifests to %q (%q)", b.branch, commit) b.logger.Actionf("pushing component manifests to %q", b.url) - if err = b.git.Push(ctx); err != nil { + if err = b.git.Push(ctx, b.caBundle); err != nil { return fmt.Errorf("failed to push manifests: %w", err) } } else { @@ -260,7 +271,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options b.logger.Actionf("cloning branch %q from Git repository %q", b.branch, b.url) var cloned bool if err = retry(1, 2*time.Second, func() (err error) { - cloned, err = b.git.Clone(ctx, b.url, b.branch) + cloned, err = b.git.Clone(ctx, b.url, b.branch, b.caBundle) return }); err != nil { return fmt.Errorf("failed to clone repository: %w", err) @@ -309,7 +320,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options if err == nil { b.logger.Successf("committed sync manifests to %q (%q)", b.branch, commit) b.logger.Actionf("pushing sync manifests to %q", b.url) - if err = b.git.Push(ctx); err != nil { + if err = b.git.Push(ctx, b.caBundle); err != nil { return fmt.Errorf("failed to push sync manifests: %w", err) } } else { diff --git a/internal/bootstrap/git/git.go b/internal/bootstrap/git/git.go index 86466e79..103ea49b 100644 --- a/internal/bootstrap/git/git.go +++ b/internal/bootstrap/git/git.go @@ -42,10 +42,10 @@ type Commit struct { // remote repository. type Git interface { Init(url, branch string) (bool, error) - Clone(ctx context.Context, url, branch string) (bool, error) + Clone(ctx context.Context, url, branch string, caBundle []byte) (bool, error) Write(path string, reader io.Reader) error Commit(message Commit) (string, error) - Push(ctx context.Context) error + Push(ctx context.Context, caBundle []byte) error Status() (bool, error) Head() (string, error) Path() string diff --git a/internal/bootstrap/git/gogit/gogit.go b/internal/bootstrap/git/gogit/gogit.go index b11acd0c..07248791 100644 --- a/internal/bootstrap/git/gogit/gogit.go +++ b/internal/bootstrap/git/gogit/gogit.go @@ -82,7 +82,7 @@ func (g *GoGit) Init(url, branch string) (bool, error) { return true, nil } -func (g *GoGit) Clone(ctx context.Context, url, branch string) (bool, error) { +func (g *GoGit) Clone(ctx context.Context, url, branch string, caBundle []byte) (bool, error) { branchRef := plumbing.NewBranchReferenceName(branch) r, err := gogit.PlainCloneContext(ctx, g.path, false, &gogit.CloneOptions{ URL: url, @@ -94,6 +94,7 @@ func (g *GoGit) Clone(ctx context.Context, url, branch string) (bool, error) { NoCheckout: false, Progress: nil, Tags: gogit.NoTags, + CABundle: caBundle, }) if err != nil { if err == transport.ErrEmptyRemoteRepository || isRemoteBranchNotFoundErr(err, branchRef.String()) { @@ -185,7 +186,7 @@ func (g *GoGit) Commit(message git.Commit) (string, error) { return commit.String(), nil } -func (g *GoGit) Push(ctx context.Context) error { +func (g *GoGit) Push(ctx context.Context, caBundle []byte) error { if g.repository == nil { return git.ErrNoGitRepository } @@ -194,6 +195,7 @@ func (g *GoGit) Push(ctx context.Context) error { RemoteName: gogit.DefaultRemoteName, Auth: g.auth, Progress: nil, + CABundle: caBundle, }) }