Add support for http.extraHeader

This commit is contained in:
toomaj 2024-04-15 08:49:41 +10:00
parent c7db0c6b9f
commit 2bbeb6250c

View file

@ -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 {
return fmt.Errorf("failed to create a Git client: %w", err)
}
// Install manifest config if gitArgs.withBearerToken && gitArgs.password != "" {
installOptions := install.Options{ configureGitWithBearerToken(gitArgs.password) // This will configure the local Git configuration
BaseURL: rootArgs.defaults.BaseURL, }
Version: bootstrapArgs.version,
Namespace: *kubeconfigArgs.Namespace,
Components: bootstrapComponents(),
Registry: bootstrapArgs.registry,
ImagePullSecret: bootstrapArgs.imagePullSecret,
WatchAllNamespaces: bootstrapArgs.watchAllNamespaces,
NetworkPolicy: bootstrapArgs.networkPolicy,
LogLevel: bootstrapArgs.logLevel.String(),
NotificationController: rootArgs.defaults.NotificationController,
ManifestFile: rootArgs.defaults.ManifestFile,
Timeout: rootArgs.timeout,
TargetPath: gitArgs.path.ToSlash(),
ClusterDomain: bootstrapArgs.clusterDomain,
TolerationKeys: bootstrapArgs.tolerationKeys,
}
if customBaseURL := bootstrapArgs.manifestsPath; customBaseURL != "" {
installOptions.BaseURL = customBaseURL
}
// Source generation and secret config gitClient, err := gogit.NewClient(tmpDir, authOpts, clientOpts...)
secretOpts := sourcesecret.Options{ if err != nil {
Name: bootstrapArgs.secretName, return fmt.Errorf("failed to create a Git client: %w", err)
Namespace: *kubeconfigArgs.Namespace, }
TargetPath: gitArgs.path.String(),
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
}
if bootstrapArgs.tokenAuth {
secretOpts.Username = gitArgs.username
secretOpts.Password = gitArgs.password
secretOpts.CAFile = caBundle
// Remove port of the given host when not syncing over HTTP/S to not assume port for protocol // Install manifest config
// This _might_ be overwritten later on by e.g. --ssh-hostname installOptions := install.Options{
if repositoryURL.Scheme != "https" && repositoryURL.Scheme != "http" { BaseURL: rootArgs.defaults.BaseURL,
repositoryURL.Host = repositoryURL.Hostname() Version: bootstrapArgs.version,
} Namespace: *kubeconfigArgs.Namespace,
Components: bootstrapComponents(),
Registry: bootstrapArgs.registry,
RegistryCredential: bootstrapArgs.registryCredential,
ImagePullSecret: bootstrapArgs.imagePullSecret,
WatchAllNamespaces: bootstrapArgs.watchAllNamespaces,
NetworkPolicy: bootstrapArgs.networkPolicy,
LogLevel: bootstrapArgs.logLevel.String(),
NotificationController: rootArgs.defaults.NotificationController,
ManifestFile: rootArgs.defaults.ManifestFile,
Timeout: rootArgs.timeout,
TargetPath: gitArgs.path.ToSlash(),
ClusterDomain: bootstrapArgs.clusterDomain,
TolerationKeys: bootstrapArgs.tolerationKeys,
}
if customBaseURL := bootstrapArgs.manifestsPath; customBaseURL != "" {
installOptions.BaseURL = customBaseURL
}
// Configure repository URL to match auth config for sync. // Source generation and secret config
repositoryURL.User = nil secretOpts := sourcesecret.Options{
if !gitArgs.insecureHttpAllowed { Name: bootstrapArgs.secretName,
repositoryURL.Scheme = "https" Namespace: *kubeconfigArgs.Namespace,
} TargetPath: gitArgs.path.String(),
} else { ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm) }
secretOpts.Password = gitArgs.password if bootstrapArgs.tokenAuth {
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits) secretOpts.Username = gitArgs.username
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve 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
// This _might_ be overwritten later on by e.g. --ssh-hostname
if repositoryURL.Scheme != "https" && repositoryURL.Scheme != "http" {
repositoryURL.Host = repositoryURL.Hostname()
}
// Override existing user when user is not already set // Configure repository URL to match auth config for sync.
// or when a username was passed in repositoryURL.User = nil
if repositoryURL.User == nil || gitArgs.username != "git" { if !gitArgs.insecureHttpAllowed {
repositoryURL.User = url.User(gitArgs.username) repositoryURL.Scheme = "https"
} }
} else {
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
secretOpts.Password = gitArgs.password
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve
repositoryURL.Scheme = "ssh" // Configure repository URL to match auth config for sync
if bootstrapArgs.sshHostname != "" {
repositoryURL.Host = bootstrapArgs.sshHostname
}
keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password) // Override existing user when user is not already set
if err != nil { // or when a username was passed in
return err if repositoryURL.User == nil || gitArgs.username != "git" {
} repositoryURL.User = url.User(gitArgs.username)
secretOpts.Keypair = keypair }
// Configure last as it depends on the config above. repositoryURL.Scheme = "ssh"
secretOpts.SSHHostname = repositoryURL.Host if bootstrapArgs.sshHostname != "" {
} repositoryURL.Host = bootstrapArgs.sshHostname
}
// Sync manifest config keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password)
syncOpts := sync.Options{ if err != nil {
Interval: gitArgs.interval, return err
Name: *kubeconfigArgs.Namespace, }
Namespace: *kubeconfigArgs.Namespace, secretOpts.Keypair = keypair
URL: repositoryURL.String(),
Branch: bootstrapArgs.branch,
Secret: bootstrapArgs.secretName,
TargetPath: gitArgs.path.ToSlash(),
ManifestFile: sync.MakeDefaultOptions().ManifestFile,
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
}
entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath) // Configure last as it depends on the config above.
if err != nil { secretOpts.SSHHostname = repositoryURL.Host
return err }
}
// Bootstrap config // Sync manifest config
bootstrapOpts := []bootstrap.GitOption{ syncOpts := sync.Options{
bootstrap.WithRepositoryURL(gitArgs.url), Interval: gitArgs.interval,
bootstrap.WithBranch(bootstrapArgs.branch), Name: *kubeconfigArgs.Namespace,
bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), Namespace: *kubeconfigArgs.Namespace,
bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), URL: repositoryURL.String(),
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions), Branch: bootstrapArgs.branch,
bootstrap.WithPostGenerateSecretFunc(promptPublicKey), Secret: bootstrapArgs.secretName,
bootstrap.WithLogger(logger), TargetPath: gitArgs.path.ToSlash(),
bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID), ManifestFile: sync.MakeDefaultOptions().ManifestFile,
} RecurseSubmodules: bootstrapArgs.recurseSubmodules,
}
// Setup bootstrapper with constructed configs entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath)
b, err := bootstrap.NewPlainGitProvider(gitClient, kubeClient, bootstrapOpts...) if err != nil {
if err != nil { return err
return err }
}
// Run // Bootstrap config
return bootstrap.Run(ctx, b, manifestsBase, installOptions, secretOpts, syncOpts, rootArgs.pollInterval, rootArgs.timeout) bootstrapOpts := []bootstrap.GitOption{
bootstrap.WithRepositoryURL(gitArgs.url),
bootstrap.WithBranch(bootstrapArgs.branch),
bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail),
bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions),
bootstrap.WithPostGenerateSecretFunc(promptPublicKey),
bootstrap.WithLogger(logger),
bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
}
// Setup bootstrapper with constructed configs
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)
}
} }