|  |  | @ -17,36 +17,37 @@ limitations under the License. | 
			
		
	
		
		
			
				
					
					|  |  |  | package main |  |  |  | package main | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | import ( |  |  |  | import ( | 
			
		
	
		
		
			
				
					
					|  |  |  | 	"context" |  |  |  |   "context" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"fmt" |  |  |  |   "fmt" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"net/url" |  |  |  |   "net/url" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"os" |  |  |  |   "os" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"strings" |  |  |  |   "strings" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"time" |  |  |  |   "time" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/manifoldco/promptui" |  |  |  |   "github.com/manifoldco/promptui" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/spf13/cobra" |  |  |  |   "github.com/spf13/cobra" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	corev1 "k8s.io/api/core/v1" |  |  |  |   corev1 "k8s.io/api/core/v1" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/flux2/v2/internal/flags" |  |  |  |   "github.com/fluxcd/pkg/git" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/flux2/v2/internal/utils" |  |  |  |   "github.com/fluxcd/pkg/git/gogit" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/flux2/v2/pkg/bootstrap" |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/flux2/v2/pkg/manifestgen" |  |  |  |   "github.com/fluxcd/flux2/v2/internal/flags" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/flux2/v2/pkg/manifestgen/install" |  |  |  |   "github.com/fluxcd/flux2/v2/internal/utils" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/flux2/v2/pkg/manifestgen/sourcesecret" |  |  |  |   "github.com/fluxcd/flux2/v2/pkg/bootstrap" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/flux2/v2/pkg/manifestgen/sync" |  |  |  |   "github.com/fluxcd/flux2/v2/pkg/manifestgen" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/pkg/git" |  |  |  |   "github.com/fluxcd/flux2/v2/pkg/manifestgen/install" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	"github.com/fluxcd/pkg/git/gogit" |  |  |  |   "github.com/fluxcd/flux2/v2/pkg/manifestgen/sourcesecret" | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   "github.com/fluxcd/flux2/v2/pkg/manifestgen/sync" | 
			
		
	
		
		
			
				
					
					|  |  |  | ) |  |  |  | ) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | var bootstrapGitCmd = &cobra.Command{ |  |  |  | var bootstrapGitCmd = &cobra.Command{ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	Use:   "git", |  |  |  |   Use:   "git", | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	Short: "Deploy Flux on a cluster connected to a Git repository", |  |  |  |   Short: "Deploy Flux on a cluster connected to a Git repository", | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	Long: `The bootstrap git command commits the Flux manifests to the |  |  |  |   Long: `The bootstrap git command commits the Flux manifests to the | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | branch of a Git repository. And then it configures the target cluster to synchronize with |  |  |  | branch of a Git repository. And then it configures the target cluster to synchronize with | 
			
		
	
		
		
			
				
					
					|  |  |  | that repository. If the Flux components are present on the cluster, the bootstrap |  |  |  | that repository. If the Flux components are present on the cluster, the bootstrap | 
			
		
	
		
		
			
				
					
					|  |  |  | command will perform an upgrade if needed.`, |  |  |  | command will perform an upgrade if needed.`, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	Example: `  # Run bootstrap for a Git repository and authenticate with your SSH agent |  |  |  |   Example: `  # Run bootstrap for a Git repository and authenticate with your SSH agent | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   flux bootstrap git --url=ssh://git@example.com/repository.git --path=clusters/my-cluster
 |  |  |  |   flux bootstrap git --url=ssh://git@example.com/repository.git --path=clusters/my-cluster
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   # Run bootstrap for a Git repository and authenticate using a password |  |  |  |   # Run bootstrap for a Git repository and authenticate using a password | 
			
		
	
	
		
		
			
				
					|  |  | @ -66,246 +67,257 @@ command will perform an upgrade if needed.`, | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   # Run bootstrap for a Git repository on Azure Devops |  |  |  |   # Run bootstrap for a Git repository on Azure Devops | 
			
		
	
		
		
			
				
					
					|  |  |  |   flux bootstrap git --url=ssh://git@ssh.dev.azure.com/v3/<org>/<project>/<repository> --ssh-key-algorithm=rsa --ssh-rsa-bits=4096 --path=clusters/my-cluster
 |  |  |  |   flux bootstrap git --url=ssh://git@ssh.dev.azure.com/v3/<org>/<project>/<repository> --ssh-key-algorithm=rsa --ssh-rsa-bits=4096 --path=clusters/my-cluster
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | # Run bootstrap for a Git repository on Oracle VBS | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   flux bootstrap git --url=https://repository_url.git --with-bearer-token=true --password=PAT --path=clusters/my-cluster
 | 
			
		
	
		
		
			
				
					
					|  |  |  | `, |  |  |  | `, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	RunE: bootstrapGitCmdRun, |  |  |  |   RunE: bootstrapGitCmdRun, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | type gitFlags struct { |  |  |  | type gitFlags struct { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	url                 string |  |  |  |   url                 string | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	interval            time.Duration |  |  |  |   interval            time.Duration | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	path                flags.SafeRelativePath |  |  |  |   path                flags.SafeRelativePath | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	username            string |  |  |  |   username            string | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	password            string |  |  |  |   password            string | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	silent              bool |  |  |  |   silent              bool | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	insecureHttpAllowed bool |  |  |  |   insecureHttpAllowed bool | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   withBearerToken     bool | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | const ( |  |  |  | const ( | 
			
		
	
		
		
			
				
					
					|  |  |  | 	gitPasswordEnvVar = "GIT_PASSWORD" |  |  |  |   gitPasswordEnvVar = "GIT_PASSWORD" | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | ) |  |  |  | ) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | var gitArgs gitFlags |  |  |  | var gitArgs gitFlags | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | func init() { |  |  |  | func init() { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapGitCmd.Flags().StringVar(&gitArgs.url, "url", "", "Git repository URL") |  |  |  |   bootstrapGitCmd.Flags().StringVar(&gitArgs.url, "url", "", "Git repository URL") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapGitCmd.Flags().DurationVar(&gitArgs.interval, "interval", time.Minute, "sync interval") |  |  |  |   bootstrapGitCmd.Flags().DurationVar(&gitArgs.interval, "interval", time.Minute, "sync interval") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapGitCmd.Flags().Var(&gitArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path") |  |  |  |   bootstrapGitCmd.Flags().Var(&gitArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapGitCmd.Flags().StringVarP(&gitArgs.username, "username", "u", "git", "basic authentication username") |  |  |  |   bootstrapGitCmd.Flags().StringVarP(&gitArgs.username, "username", "u", "git", "basic authentication username") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapGitCmd.Flags().StringVarP(&gitArgs.password, "password", "p", "", "basic authentication password") |  |  |  |   bootstrapGitCmd.Flags().StringVarP(&gitArgs.password, "password", "p", "", "basic authentication password") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapGitCmd.Flags().BoolVarP(&gitArgs.silent, "silent", "s", false, "assumes the deploy key is already setup, skips confirmation") |  |  |  |   bootstrapGitCmd.Flags().BoolVarP(&gitArgs.silent, "silent", "s", false, "assumes the deploy key is already setup, skips confirmation") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapGitCmd.Flags().BoolVar(&gitArgs.insecureHttpAllowed, "allow-insecure-http", false, "allows insecure HTTP connections") |  |  |  |   bootstrapGitCmd.Flags().BoolVar(&gitArgs.insecureHttpAllowed, "allow-insecure-http", false, "allows insecure HTTP connections") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |   bootstrapGitCmd.Flags().BoolVar(&gitArgs.withBearerToken, "with-bearer-token", false, "use password as bearer token for Authorization header") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapCmd.AddCommand(bootstrapGitCmd) |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   bootstrapCmd.AddCommand(bootstrapGitCmd) | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { |  |  |  | func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	gitPassword := os.Getenv(gitPasswordEnvVar) |  |  |  |   gitPassword := os.Getenv(gitPasswordEnvVar) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if gitPassword != "" && gitArgs.password == "" { |  |  |  |   if gitPassword != "" && gitArgs.password == "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		gitArgs.password = gitPassword |  |  |  |     gitArgs.password = gitPassword | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if bootstrapArgs.tokenAuth && gitArgs.password == "" { |  |  |  |   if bootstrapArgs.tokenAuth && gitArgs.password == "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		var err error |  |  |  |     var err error | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		gitPassword, err = readPasswordFromStdin("Please enter your Git repository password: ") |  |  |  |     gitPassword, err = readPasswordFromStdin("Please enter your Git repository password: ") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if err != nil { |  |  |  |     if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			return fmt.Errorf("could not read token: %w", err) |  |  |  |       return fmt.Errorf("could not read token: %w", err) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		gitArgs.password = gitPassword |  |  |  |     gitArgs.password = gitPassword | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err := bootstrapValidate(); err != nil { |  |  |  |   if err := bootstrapValidate(); err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return err |  |  |  |     return err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	repositoryURL, err := url.Parse(gitArgs.url) |  |  |  |   repositoryURL, err := url.Parse(gitArgs.url) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err != nil { |  |  |  |   if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return err |  |  |  |     return err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if strings.Contains(repositoryURL.Hostname(), "git-codecommit") && strings.Contains(repositoryURL.Hostname(), "amazonaws.com") { |  |  |  |   if strings.Contains(repositoryURL.Hostname(), "git-codecommit") && strings.Contains(repositoryURL.Hostname(), "amazonaws.com") { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if repositoryURL.Scheme == string(git.SSH) { |  |  |  |     if repositoryURL.Scheme == string(git.SSH) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			if repositoryURL.User == nil { |  |  |  |       if repositoryURL.User == nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				return fmt.Errorf("invalid AWS CodeCommit url: ssh username should be specified in the url") |  |  |  |         return fmt.Errorf("invalid AWS CodeCommit url: ssh username should be specified in the url") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |       } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			if repositoryURL.User.Username() == git.DefaultPublicKeyAuthUser { |  |  |  |       if repositoryURL.User.Username() == git.DefaultPublicKeyAuthUser { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				return fmt.Errorf("invalid AWS CodeCommit url: ssh username should be the SSH key ID for the provided private key") |  |  |  |         return fmt.Errorf("invalid AWS CodeCommit url: ssh username should be the SSH key ID for the provided private key") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |       } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			if bootstrapArgs.privateKeyFile == "" { |  |  |  |       if bootstrapArgs.privateKeyFile == "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				return fmt.Errorf("private key file is required for bootstrapping against AWS CodeCommit using ssh") |  |  |  |         return fmt.Errorf("private key file is required for bootstrapping against AWS CodeCommit using ssh") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |       } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if repositoryURL.Scheme == string(git.HTTPS) && !bootstrapArgs.tokenAuth { |  |  |  |     if repositoryURL.Scheme == string(git.HTTPS) && !bootstrapArgs.tokenAuth { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			return fmt.Errorf("--token-auth=true must be specified for using an HTTPS AWS CodeCommit url") |  |  |  |       return fmt.Errorf("--token-auth=true must be specified for using an HTTPS AWS CodeCommit url") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) |  |  |  |   ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	defer cancel() |  |  |  |   defer cancel() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions) |  |  |  |   kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err != nil { |  |  |  |   if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return err |  |  |  |     return err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if !bootstrapArgs.force { |  |  |  |   if !bootstrapArgs.force { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		err = confirmBootstrap(ctx, kubeClient) |  |  |  |     err = confirmBootstrap(ctx, kubeClient) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if err != nil { |  |  |  |     if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			return err |  |  |  |       return err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	// Manifest base
 |  |  |  |   // Manifest base
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if ver, err := getVersion(bootstrapArgs.version); err != nil { |  |  |  |   if ver, err := getVersion(bootstrapArgs.version); err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return err |  |  |  |     return err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} else { |  |  |  |   } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrapArgs.version = ver |  |  |  |     bootstrapArgs.version = ver | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	manifestsBase, err := buildEmbeddedManifestBase() |  |  |  |   manifestsBase, err := buildEmbeddedManifestBase() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err != nil { |  |  |  |   if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return err |  |  |  |     return err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	defer os.RemoveAll(manifestsBase) |  |  |  |   defer os.RemoveAll(manifestsBase) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	// Lazy go-git repository
 |  |  |  |   // Lazy go-git repository
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	tmpDir, err := manifestgen.MkdirTempAbs("", "flux-bootstrap-") |  |  |  |   tmpDir, err := manifestgen.MkdirTempAbs("", "flux-bootstrap-") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err != nil { |  |  |  |   if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return fmt.Errorf("failed to create temporary working dir: %w", err) |  |  |  |     return fmt.Errorf("failed to create temporary working dir: %w", err) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	defer os.RemoveAll(tmpDir) |  |  |  |   defer os.RemoveAll(tmpDir) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	var caBundle []byte |  |  |  |   var caBundle []byte | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if bootstrapArgs.caFile != "" { |  |  |  |   if bootstrapArgs.caFile != "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		var err error |  |  |  |     var err error | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		caBundle, err = os.ReadFile(bootstrapArgs.caFile) |  |  |  |     caBundle, err = os.ReadFile(bootstrapArgs.caFile) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if err != nil { |  |  |  |     if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			return fmt.Errorf("unable to read TLS CA file: %w", err) |  |  |  |       return fmt.Errorf("unable to read TLS CA file: %w", err) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	authOpts, err := getAuthOpts(repositoryURL, caBundle) |  |  |  |   authOpts, err := getAuthOpts(repositoryURL, caBundle) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err != nil { |  |  |  |   if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return fmt.Errorf("failed to create authentication options for %s: %w", repositoryURL.String(), err) |  |  |  |     return fmt.Errorf("failed to create authentication options for %s: %w", repositoryURL.String(), err) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	clientOpts := []gogit.ClientOption{gogit.WithDiskStorage(), gogit.WithFallbackToDefaultKnownHosts()} |  |  |  |   clientOpts := []gogit.ClientOption{gogit.WithDiskStorage(), gogit.WithFallbackToDefaultKnownHosts()} | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if gitArgs.insecureHttpAllowed { |  |  |  |   if gitArgs.insecureHttpAllowed { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		clientOpts = append(clientOpts, gogit.WithInsecureCredentialsOverHTTP()) |  |  |  |     clientOpts = append(clientOpts, gogit.WithInsecureCredentialsOverHTTP()) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	gitClient, err := gogit.NewClient(tmpDir, authOpts, clientOpts...) |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err != nil { |  |  |  |   if gitArgs.withBearerToken && gitArgs.password != "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return fmt.Errorf("failed to create a Git client: %w", err) |  |  |  |     configureGitWithBearerToken(gitArgs.password) // This will configure the local Git configuration
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	// Install manifest config
 |  |  |  |   gitClient, err := gogit.NewClient(tmpDir, authOpts, clientOpts...) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	installOptions := install.Options{ |  |  |  |   if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		BaseURL:                rootArgs.defaults.BaseURL, |  |  |  |     return fmt.Errorf("failed to create a Git client: %w", err) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Version:                bootstrapArgs.version, |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Namespace:              *kubeconfigArgs.Namespace, |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Components:             bootstrapComponents(), |  |  |  |   // Install manifest config
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Registry:               bootstrapArgs.registry, |  |  |  |   installOptions := install.Options{ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		ImagePullSecret:        bootstrapArgs.imagePullSecret, |  |  |  |     BaseURL:                rootArgs.defaults.BaseURL, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		WatchAllNamespaces:     bootstrapArgs.watchAllNamespaces, |  |  |  |     Version:                bootstrapArgs.version, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		NetworkPolicy:          bootstrapArgs.networkPolicy, |  |  |  |     Namespace:              *kubeconfigArgs.Namespace, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		LogLevel:               bootstrapArgs.logLevel.String(), |  |  |  |     Components:             bootstrapComponents(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		NotificationController: rootArgs.defaults.NotificationController, |  |  |  |     Registry:               bootstrapArgs.registry, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		ManifestFile:           rootArgs.defaults.ManifestFile, |  |  |  |     RegistryCredential:     bootstrapArgs.registryCredential, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Timeout:                rootArgs.timeout, |  |  |  |     ImagePullSecret:        bootstrapArgs.imagePullSecret, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		TargetPath:             gitArgs.path.ToSlash(), |  |  |  |     WatchAllNamespaces:     bootstrapArgs.watchAllNamespaces, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		ClusterDomain:          bootstrapArgs.clusterDomain, |  |  |  |     NetworkPolicy:          bootstrapArgs.networkPolicy, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		TolerationKeys:         bootstrapArgs.tolerationKeys, |  |  |  |     LogLevel:               bootstrapArgs.logLevel.String(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |     NotificationController: rootArgs.defaults.NotificationController, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if customBaseURL := bootstrapArgs.manifestsPath; customBaseURL != "" { |  |  |  |     ManifestFile:           rootArgs.defaults.ManifestFile, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		installOptions.BaseURL = customBaseURL |  |  |  |     Timeout:                rootArgs.timeout, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |     TargetPath:             gitArgs.path.ToSlash(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |     ClusterDomain:          bootstrapArgs.clusterDomain, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	// Source generation and secret config
 |  |  |  |     TolerationKeys:         bootstrapArgs.tolerationKeys, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	secretOpts := sourcesecret.Options{ |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Name:         bootstrapArgs.secretName, |  |  |  |   if customBaseURL := bootstrapArgs.manifestsPath; customBaseURL != "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Namespace:    *kubeconfigArgs.Namespace, |  |  |  |     installOptions.BaseURL = customBaseURL | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		TargetPath:   gitArgs.path.String(), |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   // Source generation and secret config
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if bootstrapArgs.tokenAuth { |  |  |  |   secretOpts := sourcesecret.Options{ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.Username = gitArgs.username |  |  |  |     Name:         bootstrapArgs.secretName, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.Password = gitArgs.password |  |  |  |     Namespace:    *kubeconfigArgs.Namespace, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.CAFile = caBundle |  |  |  |     TargetPath:   gitArgs.path.String(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |     ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		// Remove port of the given host when not syncing over HTTP/S to not assume port for protocol
 |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		// This _might_ be overwritten later on by e.g. --ssh-hostname
 |  |  |  |   if bootstrapArgs.tokenAuth { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if repositoryURL.Scheme != "https" && repositoryURL.Scheme != "http" { |  |  |  |     secretOpts.Username = gitArgs.username | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			repositoryURL.Host = repositoryURL.Hostname() |  |  |  |     secretOpts.Password = gitArgs.password | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     secretOpts.CAFile = caBundle | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		// Configure repository URL to match auth config for sync.
 |  |  |  |     // Remove port of the given host when not syncing over HTTP/S to not assume port for protocol
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		repositoryURL.User = nil |  |  |  |     // This _might_ be overwritten later on by e.g. --ssh-hostname
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if !gitArgs.insecureHttpAllowed { |  |  |  |     if repositoryURL.Scheme != "https" && repositoryURL.Scheme != "http" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			repositoryURL.Scheme = "https" |  |  |  |       repositoryURL.Host = repositoryURL.Hostname() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} else { |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm) |  |  |  |     // Configure repository URL to match auth config for sync.
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.Password = gitArgs.password |  |  |  |     repositoryURL.User = nil | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits) |  |  |  |     if !gitArgs.insecureHttpAllowed { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve |  |  |  |       repositoryURL.Scheme = "https" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		// Configure repository URL to match auth config for sync
 |  |  |  |   } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |     secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		// Override existing user when user is not already set
 |  |  |  |     secretOpts.Password = gitArgs.password | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		// or when a username was passed in
 |  |  |  |     secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if repositoryURL.User == nil || gitArgs.username != "git" { |  |  |  |     secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			repositoryURL.User = url.User(gitArgs.username) |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     // Configure repository URL to match auth config for sync
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		repositoryURL.Scheme = "ssh" |  |  |  |     // Override existing user when user is not already set
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if bootstrapArgs.sshHostname != "" { |  |  |  |     // or when a username was passed in
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			repositoryURL.Host = bootstrapArgs.sshHostname |  |  |  |     if repositoryURL.User == nil || gitArgs.username != "git" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |       repositoryURL.User = url.User(gitArgs.username) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password) |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if err != nil { |  |  |  |     repositoryURL.Scheme = "ssh" | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			return err |  |  |  |     if bootstrapArgs.sshHostname != "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |       repositoryURL.Host = bootstrapArgs.sshHostname | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.Keypair = keypair |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		// Configure last as it depends on the config above.
 |  |  |  |     keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		secretOpts.SSHHostname = repositoryURL.Host |  |  |  |     if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |       return err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	// Sync manifest config
 |  |  |  |     secretOpts.Keypair = keypair | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	syncOpts := sync.Options{ |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Interval:          gitArgs.interval, |  |  |  |     // Configure last as it depends on the config above.
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Name:              *kubeconfigArgs.Namespace, |  |  |  |     secretOpts.SSHHostname = repositoryURL.Host | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Namespace:         *kubeconfigArgs.Namespace, |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		URL:               repositoryURL.String(), |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Branch:            bootstrapArgs.branch, |  |  |  |   // Sync manifest config
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Secret:            bootstrapArgs.secretName, |  |  |  |   syncOpts := sync.Options{ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		TargetPath:        gitArgs.path.ToSlash(), |  |  |  |     Interval:          gitArgs.interval, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		ManifestFile:      sync.MakeDefaultOptions().ManifestFile, |  |  |  |     Name:              *kubeconfigArgs.Namespace, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		RecurseSubmodules: bootstrapArgs.recurseSubmodules, |  |  |  |     Namespace:         *kubeconfigArgs.Namespace, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |     URL:               repositoryURL.String(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |     Branch:            bootstrapArgs.branch, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath) |  |  |  |     Secret:            bootstrapArgs.secretName, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err != nil { |  |  |  |     TargetPath:        gitArgs.path.ToSlash(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return err |  |  |  |     ManifestFile:      sync.MakeDefaultOptions().ManifestFile, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |     RecurseSubmodules: bootstrapArgs.recurseSubmodules, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	// Bootstrap config
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	bootstrapOpts := []bootstrap.GitOption{ |  |  |  |   entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrap.WithRepositoryURL(gitArgs.url), |  |  |  |   if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrap.WithBranch(bootstrapArgs.branch), |  |  |  |     return err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions), |  |  |  |   // Bootstrap config
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrap.WithPostGenerateSecretFunc(promptPublicKey), |  |  |  |   bootstrapOpts := []bootstrap.GitOption{ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrap.WithLogger(logger), |  |  |  |     bootstrap.WithRepositoryURL(gitArgs.url), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID), |  |  |  |     bootstrap.WithBranch(bootstrapArgs.branch), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |     bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |     bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	// Setup bootstrapper with constructed configs
 |  |  |  |     bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	b, err := bootstrap.NewPlainGitProvider(gitClient, kubeClient, bootstrapOpts...) |  |  |  |     bootstrap.WithPostGenerateSecretFunc(promptPublicKey), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if err != nil { |  |  |  |     bootstrap.WithLogger(logger), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return err |  |  |  |     bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	// Run
 |  |  |  |   // Setup bootstrapper with constructed configs
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	return bootstrap.Run(ctx, b, manifestsBase, installOptions, secretOpts, syncOpts, rootArgs.pollInterval, rootArgs.timeout) |  |  |  |   b, err := bootstrap.NewPlainGitProvider(gitClient, kubeClient, bootstrapOpts...) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if err != nil { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return err | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   // Run
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return bootstrap.Run(ctx, b, manifestsBase, installOptions, secretOpts, syncOpts, rootArgs.pollInterval, rootArgs.timeout) | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // getAuthOpts retruns a AuthOptions based on the scheme
 |  |  |  | // getAuthOpts retruns a AuthOptions based on the scheme
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -313,64 +325,73 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { | 
			
		
	
		
		
			
				
					
					|  |  |  | // "ssh" but no private key is configured, authentication using the local
 |  |  |  | // "ssh" but no private key is configured, authentication using the local
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // SSH-agent is attempted.
 |  |  |  | // SSH-agent is attempted.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | func getAuthOpts(u *url.URL, caBundle []byte) (*git.AuthOptions, error) { |  |  |  | func getAuthOpts(u *url.URL, caBundle []byte) (*git.AuthOptions, error) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	switch u.Scheme { |  |  |  |   switch u.Scheme { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	case "http": |  |  |  |   case "http": | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if !gitArgs.insecureHttpAllowed { |  |  |  |     if !gitArgs.insecureHttpAllowed { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			return nil, fmt.Errorf("scheme http is insecure, pass --allow-insecure-http=true to allow it") |  |  |  |       return nil, fmt.Errorf("scheme http is insecure, pass --allow-insecure-http=true to allow it") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return &git.AuthOptions{ |  |  |  |     return &git.AuthOptions{ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Transport: git.HTTP, |  |  |  |       Transport: git.HTTP, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Username:  gitArgs.username, |  |  |  |       Username:  gitArgs.username, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Password:  gitArgs.password, |  |  |  |       Password:  gitArgs.password, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		}, nil |  |  |  |     }, nil | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	case "https": |  |  |  |   case "https": | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return &git.AuthOptions{ |  |  |  |     return &git.AuthOptions{ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Transport: git.HTTPS, |  |  |  |       Transport: git.HTTPS, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Username:  gitArgs.username, |  |  |  |       Username:  gitArgs.username, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Password:  gitArgs.password, |  |  |  |       Password:  gitArgs.password, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			CAFile:    caBundle, |  |  |  |       CAFile:    caBundle, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		}, nil |  |  |  |     }, nil | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	case "ssh": |  |  |  |   case "ssh": | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		authOpts := &git.AuthOptions{ |  |  |  |     authOpts := &git.AuthOptions{ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Transport: git.SSH, |  |  |  |       Transport: git.SSH, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Username:  u.User.Username(), |  |  |  |       Username:  u.User.Username(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Password:  gitArgs.password, |  |  |  |       Password:  gitArgs.password, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if bootstrapArgs.privateKeyFile != "" { |  |  |  |     if bootstrapArgs.privateKeyFile != "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			pk, err := os.ReadFile(bootstrapArgs.privateKeyFile) |  |  |  |       pk, err := os.ReadFile(bootstrapArgs.privateKeyFile) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			if err != nil { |  |  |  |       if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				return nil, err |  |  |  |         return nil, err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |       } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			kh, err := sourcesecret.ScanHostKey(u.Host) |  |  |  |       kh, err := sourcesecret.ScanHostKey(u.Host) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			if err != nil { |  |  |  |       if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				return nil, err |  |  |  |         return nil, err | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |       } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			authOpts.Identity = pk |  |  |  |       authOpts.Identity = pk | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			authOpts.KnownHosts = kh |  |  |  |       authOpts.KnownHosts = kh | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return authOpts, nil |  |  |  |     return authOpts, nil | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	default: |  |  |  |   default: | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return nil, fmt.Errorf("scheme %q is not supported", u.Scheme) |  |  |  |     return nil, fmt.Errorf("scheme %q is not supported", u.Scheme) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | func promptPublicKey(ctx context.Context, secret corev1.Secret, _ sourcesecret.Options) error { |  |  |  | func promptPublicKey(ctx context.Context, secret corev1.Secret, _ sourcesecret.Options) error { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	ppk, ok := secret.StringData[sourcesecret.PublicKeySecretKey] |  |  |  |   ppk, ok := secret.StringData[sourcesecret.PublicKeySecretKey] | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if !ok { |  |  |  |   if !ok { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		return nil |  |  |  |     return nil | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	logger.Successf("public key: %s", strings.TrimSpace(ppk)) |  |  |  |   logger.Successf("public key: %s", strings.TrimSpace(ppk)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	if !gitArgs.silent { |  |  |  |   if !gitArgs.silent { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		prompt := promptui.Prompt{ |  |  |  |     prompt := promptui.Prompt{ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			Label:     "Please give the key access to your repository", |  |  |  |       Label:     "Please give the key access to your repository", | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			IsConfirm: true, |  |  |  |       IsConfirm: true, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		_, err := prompt.Run() |  |  |  |     _, err := prompt.Run() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if err != nil { |  |  |  |     if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			return fmt.Errorf("aborting") |  |  |  |       return fmt.Errorf("aborting") | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |     } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |   } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	return nil |  |  |  |   return nil | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | func configureGitWithBearerToken(token string) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   cmd := exec.Command("git", "config", "--global", "http.extraHeader", fmt.Sprintf("Authorization: Bearer %s", token)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   cmd.Stdout = os.Stdout | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   cmd.Stderr = os.Stderr | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if err := cmd.Run(); err != nil { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     log.Printf("Failed to set global git config: %v", err) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |