diff --git a/cmd/flux/bootstrap.go b/cmd/flux/bootstrap.go index 47b01127eebba156bab78be17524adcd617fe89c..1cef362e22a0d2380b2e283f138742a170448a8d 100644 --- a/cmd/flux/bootstrap.go +++ b/cmd/flux/bootstrap.go @@ -57,6 +57,7 @@ var ( bootstrapArch = flags.Arch(defaults.Arch) bootstrapLogLevel = flags.LogLevel(defaults.LogLevel) bootstrapRequiredComponents = []string{"source-controller", "kustomize-controller"} + bootstrapTokenAuth bool ) const ( @@ -75,14 +76,16 @@ func init() { bootstrapCmd.PersistentFlags().Var(&bootstrapArch, "arch", bootstrapArch.Description()) bootstrapCmd.PersistentFlags().StringVar(&bootstrapBranch, "branch", bootstrapDefaultBranch, "default branch (for GitHub this must match the default branch setting for the organization)") - rootCmd.AddCommand(bootstrapCmd) bootstrapCmd.PersistentFlags().BoolVar(&bootstrapWatchAllNamespaces, "watch-all-namespaces", true, "watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed") bootstrapCmd.PersistentFlags().BoolVar(&bootstrapNetworkPolicy, "network-policy", true, "deny ingress access to the toolkit controllers from other namespaces using network policies") + bootstrapCmd.PersistentFlags().BoolVar(&bootstrapTokenAuth, "token-auth", false, + "when enabled, the personal access token will be used instead of SSH deploy key") bootstrapCmd.PersistentFlags().Var(&bootstrapLogLevel, "log-level", bootstrapLogLevel.Description()) bootstrapCmd.PersistentFlags().StringVar(&bootstrapManifestsPath, "manifests", "", "path to the manifest directory") bootstrapCmd.PersistentFlags().MarkHidden("manifests") + rootCmd.AddCommand(bootstrapCmd) } func bootstrapValidate() error { diff --git a/cmd/flux/bootstrap_github.go b/cmd/flux/bootstrap_github.go index 5565a98ac895d171f2dd12309b8f3fd7b411242f..0fd0a1aa6d41058c29ab66af49f2cffcbc52750d 100644 --- a/cmd/flux/bootstrap_github.go +++ b/cmd/flux/bootstrap_github.go @@ -26,6 +26,8 @@ import ( "time" "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fluxcd/flux2/internal/utils" "github.com/fluxcd/pkg/git" @@ -35,7 +37,7 @@ var bootstrapGitHubCmd = &cobra.Command{ Use: "github", Short: "Bootstrap toolkit components in a GitHub repository", Long: `The bootstrap github command creates the GitHub repository if it doesn't exists and -commits the toolkit components manifests to the master branch. +commits the toolkit components manifests to the main branch. Then it configures the target cluster to synchronize with the repository. If the toolkit components are present on the cluster, the bootstrap command will perform an upgrade if needed.`, @@ -54,8 +56,11 @@ the bootstrap command will perform an upgrade if needed.`, # Run bootstrap for a public repository on a personal account flux bootstrap github --owner=<user> --repository=<repo name> --private=false --personal=true - # Run bootstrap for a private repo hosted on GitHub Enterprise - flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> + # Run bootstrap for a private repo hosted on GitHub Enterprise using SSH auth + flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> --ssh-hostname=<domain> + + # Run bootstrap for a private repo hosted on GitHub Enterprise using HTTPS auth + flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> --token-auth # Run bootstrap for a an existing repository with a branch named main flux bootstrap github --owner=<organization> --repository=<repo name> --branch=main @@ -64,15 +69,16 @@ the bootstrap command will perform an upgrade if needed.`, } var ( - ghOwner string - ghRepository string - ghInterval time.Duration - ghPersonal bool - ghPrivate bool - ghHostname string - ghPath string - ghTeams []string - ghDelete bool + ghOwner string + ghRepository string + ghInterval time.Duration + ghPersonal bool + ghPrivate bool + ghHostname string + ghPath string + ghTeams []string + ghDelete bool + ghSSHHostname string ) const ( @@ -87,6 +93,7 @@ func init() { bootstrapGitHubCmd.Flags().BoolVar(&ghPrivate, "private", true, "is private repository") bootstrapGitHubCmd.Flags().DurationVar(&ghInterval, "interval", time.Minute, "sync interval") bootstrapGitHubCmd.Flags().StringVar(&ghHostname, "hostname", git.GitHubDefaultHostname, "GitHub hostname") + bootstrapGitHubCmd.Flags().StringVar(&ghSSHHostname, "ssh-hostname", "", "GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one") bootstrapGitHubCmd.Flags().StringVar(&ghPath, "path", "", "repository path, when specified the cluster sync will be scoped to this path") bootstrapGitHubCmd.Flags().BoolVar(&ghDelete, "delete", false, "delete repository (used for testing only)") @@ -110,6 +117,10 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { return err } + if ghSSHHostname != "" { + repository.SSHHost = ghSSHHostname + } + provider := &git.GithubProvider{ IsPrivate: ghPrivate, IsPersonal: ghPersonal, @@ -155,7 +166,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { } } - // clone repository and checkout the master branch + // clone repository and checkout the main branch if err := repository.Checkout(ctx, bootstrapBranch, tmpDir); err != nil { return err } @@ -201,28 +212,45 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("install completed") } - // setup SSH deploy key - if shouldCreateDeployKey(ctx, kubeClient, namespace) { - logger.Actionf("configuring deploy key") - u, err := url.Parse(repository.GetSSH()) - if err != nil { - return fmt.Errorf("git URL parse failed: %w", err) + if bootstrapTokenAuth { + // setup HTTPS token auth + secret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + Namespace: namespace, + }, + StringData: map[string]string{ + "username": "git", + "password": ghToken, + }, } - - key, err := generateDeployKey(ctx, kubeClient, u, namespace) - if err != nil { - return fmt.Errorf("generating deploy key failed: %w", err) + if err := upsertSecret(ctx, kubeClient, secret); err != nil { + return err } + } else { + // setup SSH deploy key + if shouldCreateDeployKey(ctx, kubeClient, namespace) { + logger.Actionf("configuring deploy key") + u, err := url.Parse(repository.GetSSH()) + if err != nil { + return fmt.Errorf("git URL parse failed: %w", err) + } - keyName := "flux" - if ghPath != "" { - keyName = fmt.Sprintf("flux-%s", ghPath) - } + key, err := generateDeployKey(ctx, kubeClient, u, namespace) + if err != nil { + return fmt.Errorf("generating deploy key failed: %w", err) + } - if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { - return err - } else if changed { - logger.Successf("deploy key configured") + keyName := "flux" + if ghPath != "" { + keyName = fmt.Sprintf("flux-%s", ghPath) + } + + if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { + return err + } else if changed { + logger.Successf("deploy key configured") + } } } diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go index 5d504def91d84a73b40fcf62c872991a56605d42..546d93fb0be68e8833022501a83e510179bde0ad 100644 --- a/cmd/flux/bootstrap_gitlab.go +++ b/cmd/flux/bootstrap_gitlab.go @@ -45,22 +45,22 @@ the bootstrap command will perform an upgrade if needed.`, export GITLAB_TOKEN=<my-token> # Run bootstrap for a private repo using HTTPS token authentication - flux bootstrap gitlab --owner=<group> --repository=<repo name> + flux bootstrap gitlab --owner=<group> --repository=<repo name> --token-auth # Run bootstrap for a private repo using SSH authentication - flux bootstrap gitlab --owner=<group> --repository=<repo name> --ssh-hostname=gitlab.com + flux bootstrap gitlab --owner=<group> --repository=<repo name> # Run bootstrap for a repository path flux bootstrap gitlab --owner=<group> --repository=<repo name> --path=dev-cluster # Run bootstrap for a public repository on a personal account - flux bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal=true + flux bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal --token-auth # Run bootstrap for a private repo hosted on a GitLab server - flux bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain> + flux bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain> --token-auth # Run bootstrap for a an existing repository with a branch named main - flux bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main + flux bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main --token-auth `, RunE: bootstrapGitLabCmdRun, } @@ -83,7 +83,7 @@ func init() { bootstrapGitLabCmd.Flags().BoolVar(&glPrivate, "private", true, "is private repository") bootstrapGitLabCmd.Flags().DurationVar(&glInterval, "interval", time.Minute, "sync interval") bootstrapGitLabCmd.Flags().StringVar(&glHostname, "hostname", git.GitLabDefaultHostname, "GitLab hostname") - bootstrapGitLabCmd.Flags().StringVar(&glSSHHostname, "ssh-hostname", "", "GitLab SSH hostname, when specified a deploy key will be added to the repository") + bootstrapGitLabCmd.Flags().StringVar(&glSSHHostname, "ssh-hostname", "", "GitLab SSH hostname, to be used when the SSH host differs from the HTTPS one") bootstrapGitLabCmd.Flags().StringVar(&glPath, "path", "", "repository path, when specified the cluster sync will be scoped to this path") bootstrapCmd.AddCommand(bootstrapGitLabCmd) @@ -180,7 +180,22 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { repoURL := repository.GetURL() - if glSSHHostname != "" { + if bootstrapTokenAuth { + // setup HTTPS token auth + secret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + Namespace: namespace, + }, + StringData: map[string]string{ + "username": "git", + "password": glToken, + }, + } + if err := upsertSecret(ctx, kubeClient, secret); err != nil { + return err + } + } else { // setup SSH deploy key repoURL = repository.GetSSH() if shouldCreateDeployKey(ctx, kubeClient, namespace) { @@ -206,21 +221,6 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("deploy key configured") } } - } else { - // setup HTTPS token auth - secret := corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - Namespace: namespace, - }, - StringData: map[string]string{ - "username": "git", - "password": glToken, - }, - } - if err := upsertSecret(ctx, kubeClient, secret); err != nil { - return err - } } // configure repo synchronization diff --git a/docs/cmd/flux_bootstrap.md b/docs/cmd/flux_bootstrap.md index 5a74161ae959c4e7f1a4b398acb4223bfca5f7a4..4d1f20b0f3efdbf5f34588655c8610f1fe5b5a46 100644 --- a/docs/cmd/flux_bootstrap.md +++ b/docs/cmd/flux_bootstrap.md @@ -17,6 +17,7 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git --log-level logLevel log level, available options are: (debug, info, error) (default info) --network-policy deny ingress access to the toolkit controllers from other namespaces using network policies (default true) --registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd") + --token-auth when enabled, the personal access token will be used instead of SSH deploy key -v, --version string toolkit version (default "latest") --watch-all-namespaces watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed (default true) ``` diff --git a/docs/cmd/flux_bootstrap_github.md b/docs/cmd/flux_bootstrap_github.md index a105a216fc15385b06837f7778fb8331b59f4460..4186515a7f2bf1062e35498c7c16c95881050548 100644 --- a/docs/cmd/flux_bootstrap_github.md +++ b/docs/cmd/flux_bootstrap_github.md @@ -5,7 +5,7 @@ Bootstrap toolkit components in a GitHub repository ### Synopsis The bootstrap github command creates the GitHub repository if it doesn't exists and -commits the toolkit components manifests to the master branch. +commits the toolkit components manifests to the main branch. Then it configures the target cluster to synchronize with the repository. If the toolkit components are present on the cluster, the bootstrap command will perform an upgrade if needed. @@ -32,8 +32,11 @@ flux bootstrap github [flags] # Run bootstrap for a public repository on a personal account flux bootstrap github --owner=<user> --repository=<repo name> --private=false --personal=true - # Run bootstrap for a private repo hosted on GitHub Enterprise - flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> + # Run bootstrap for a private repo hosted on GitHub Enterprise using SSH auth + flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> --ssh-hostname=<domain> + + # Run bootstrap for a private repo hosted on GitHub Enterprise using HTTPS auth + flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> --token-auth # Run bootstrap for a an existing repository with a branch named main flux bootstrap github --owner=<organization> --repository=<repo name> --branch=main @@ -43,15 +46,16 @@ flux bootstrap github [flags] ### Options ``` - -h, --help help for github - --hostname string GitHub hostname (default "github.com") - --interval duration sync interval (default 1m0s) - --owner string GitHub user or organization name - --path string repository path, when specified the cluster sync will be scoped to this path - --personal is personal repository - --private is private repository (default true) - --repository string GitHub repository name - --team stringArray GitHub team to be given maintainer access + -h, --help help for github + --hostname string GitHub hostname (default "github.com") + --interval duration sync interval (default 1m0s) + --owner string GitHub user or organization name + --path string repository path, when specified the cluster sync will be scoped to this path + --personal is personal repository + --private is private repository (default true) + --repository string GitHub repository name + --ssh-hostname string GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one + --team stringArray GitHub team to be given maintainer access ``` ### Options inherited from parent commands @@ -68,6 +72,7 @@ flux bootstrap github [flags] --network-policy deny ingress access to the toolkit controllers from other namespaces using network policies (default true) --registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd") --timeout duration timeout for this operation (default 5m0s) + --token-auth when enabled, the personal access token will be used instead of SSH deploy key --verbose print generated objects -v, --version string toolkit version (default "latest") --watch-all-namespaces watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed (default true) diff --git a/docs/cmd/flux_bootstrap_gitlab.md b/docs/cmd/flux_bootstrap_gitlab.md index 131d7441b9fd6842983edce60f2e42eb97cdff8b..a4682511c8455945c7da04b4f19fa84e60c60a88 100644 --- a/docs/cmd/flux_bootstrap_gitlab.md +++ b/docs/cmd/flux_bootstrap_gitlab.md @@ -21,22 +21,22 @@ flux bootstrap gitlab [flags] export GITLAB_TOKEN=<my-token> # Run bootstrap for a private repo using HTTPS token authentication - flux bootstrap gitlab --owner=<group> --repository=<repo name> + flux bootstrap gitlab --owner=<group> --repository=<repo name> --token-auth # Run bootstrap for a private repo using SSH authentication - flux bootstrap gitlab --owner=<group> --repository=<repo name> --ssh-hostname=gitlab.com + flux bootstrap gitlab --owner=<group> --repository=<repo name> # Run bootstrap for a repository path flux bootstrap gitlab --owner=<group> --repository=<repo name> --path=dev-cluster # Run bootstrap for a public repository on a personal account - flux bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal=true + flux bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal --token-auth # Run bootstrap for a private repo hosted on a GitLab server - flux bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain> + flux bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain> --token-auth # Run bootstrap for a an existing repository with a branch named main - flux bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main + flux bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main --token-auth ``` @@ -51,7 +51,7 @@ flux bootstrap gitlab [flags] --personal is personal repository --private is private repository (default true) --repository string GitLab repository name - --ssh-hostname string GitLab SSH hostname, when specified a deploy key will be added to the repository + --ssh-hostname string GitLab SSH hostname, to be used when the SSH host differs from the HTTPS one ``` ### Options inherited from parent commands @@ -68,6 +68,7 @@ flux bootstrap gitlab [flags] --network-policy deny ingress access to the toolkit controllers from other namespaces using network policies (default true) --registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd") --timeout duration timeout for this operation (default 5m0s) + --token-auth when enabled, the personal access token will be used instead of SSH deploy key --verbose print generated objects -v, --version string toolkit version (default "latest") --watch-all-namespaces watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed (default true) diff --git a/docs/guides/installation.md b/docs/guides/installation.md index bfd34816495e675962eab0b4b7341786f977630c..f8270a3a42addcf07c59dad52b646f834c89f080 100644 --- a/docs/guides/installation.md +++ b/docs/guides/installation.md @@ -129,6 +129,19 @@ To run the bootstrap for a repository hosted on GitHub Enterprise, you have to s ```sh flux bootstrap github \ + --hostname=my-github-enterprise.com \ + --ssh-hostname=my-github-enterprise.com \ + --owner=my-github-organization \ + --repository=my-repository \ + --branch=main \ + --path=clusters/my-cluster +``` + +If your GitHub Enterprise has SSH access disabled, you can use HTTPS and token authentication with: + +```sh +flux bootstrap github \ + --token-auth \ --hostname=my-github-enterprise.com \ --owner=my-github-organization \ --repository=my-repository \ @@ -155,6 +168,7 @@ flux bootstrap gitlab \ --repository=my-repository \ --branch=master \ --path=clusters/my-cluster \ + --token-auth \ --personal ``` @@ -189,6 +203,7 @@ To run the bootstrap for a repository hosted on GitLab on-prem or enterprise, yo ```sh flux bootstrap gitlab \ --hostname=my-gitlab.com \ + --token-auth \ --owner=my-gitlab-group \ --repository=my-repository \ --branch=master \