From 16f0ed548eb33307507585955edea7a6ebe4daf5 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Fri, 16 Oct 2020 20:30:41 +0300 Subject: [PATCH 1/2] Add GitLab HTTPS auth to bootstrap options Signed-off-by: Stefan Prodan --- cmd/gotk/bootstrap_gitlab.go | 69 +++++++++++++++++++++---------- docs/cmd/gotk_bootstrap_gitlab.md | 9 ++-- docs/guides/installation.md | 16 +++++++ 3 files changed, 69 insertions(+), 25 deletions(-) diff --git a/cmd/gotk/bootstrap_gitlab.go b/cmd/gotk/bootstrap_gitlab.go index f94824d7..3426b7f4 100644 --- a/cmd/gotk/bootstrap_gitlab.go +++ b/cmd/gotk/bootstrap_gitlab.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/pkg/git" ) @@ -41,14 +43,17 @@ the bootstrap command will perform an upgrade if needed.`, Example: ` # Create a GitLab API token and export it as an env var export GITLAB_TOKEN= - # Run bootstrap for a private repo owned by a GitLab group + # Run bootstrap for a private repo using HTTPS token authentication gotk bootstrap gitlab --owner= --repository= + # Run bootstrap for a private repo using SSH authentication + gotk bootstrap gitlab --owner= --repository= --ssh-hostname=gitlab.com + # Run bootstrap for a repository path gotk bootstrap gitlab --owner= --repository= --path=dev-cluster # Run bootstrap for a public repository on a personal account - gotk bootstrap gitlab --owner= --repository= --private=false --personal=true + gotk bootstrap gitlab --owner= --repository= --private=false --personal=true # Run bootstrap for a private repo hosted on a GitLab server gotk bootstrap gitlab --owner= --repository= --hostname= @@ -77,7 +82,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, defaults to hostname if not specified") + bootstrapGitLabCmd.Flags().StringVar(&glSSHHostname, "ssh-hostname", "", "GitLab SSH hostname, when specified a deploy key will be added to the repository") bootstrapGitLabCmd.Flags().StringVar(&glPath, "path", "", "repository path, when specified the cluster sync will be scoped to this path") bootstrapCmd.AddCommand(bootstrapGitLabCmd) @@ -172,34 +177,54 @@ func bootstrapGitLabCmdRun(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) - } + repoURL := repository.GetURL() - key, err := generateDeployKey(ctx, kubeClient, u, namespace) - if err != nil { - return fmt.Errorf("generating deploy key failed: %w", err) + if glSSHHostname != "" { + // setup SSH deploy key + repoURL = repository.GetSSH() + if shouldCreateDeployKey(ctx, kubeClient, namespace) { + logger.Actionf("configuring deploy key") + u, err := url.Parse(repoURL) + if err != nil { + return fmt.Errorf("git URL parse failed: %w", err) + } + + key, err := generateDeployKey(ctx, kubeClient, u, namespace) + if err != nil { + return fmt.Errorf("generating deploy key failed: %w", err) + } + + keyName := "gotk" + if glPath != "" { + keyName = fmt.Sprintf("gotk-%s", glPath) + } + + if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { + return err + } else if changed { + logger.Successf("deploy key configured") + } } - - keyName := "gotk" - if glPath != "" { - keyName = fmt.Sprintf("gotk-%s", glPath) + } else { + // setup HTTPS token auth + secret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + Namespace: namespace, + }, + StringData: map[string]string{ + "username": "git", + "password": glToken, + }, } - - if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { + if err := upsertSecret(ctx, kubeClient, secret); err != nil { return err - } else if changed { - logger.Successf("deploy key configured") } } // configure repo synchronization logger.Actionf("generating sync manifests") - if err := generateSyncManifests(repository.GetSSH(), bootstrapBranch, namespace, namespace, glPath, tmpDir, glInterval); err != nil { + if err := generateSyncManifests(repoURL, bootstrapBranch, namespace, namespace, glPath, tmpDir, glInterval); err != nil { return err } diff --git a/docs/cmd/gotk_bootstrap_gitlab.md b/docs/cmd/gotk_bootstrap_gitlab.md index 34cdd2c1..68f066a0 100644 --- a/docs/cmd/gotk_bootstrap_gitlab.md +++ b/docs/cmd/gotk_bootstrap_gitlab.md @@ -20,14 +20,17 @@ gotk bootstrap gitlab [flags] # Create a GitLab API token and export it as an env var export GITLAB_TOKEN= - # Run bootstrap for a private repo owned by a GitLab group + # Run bootstrap for a private repo using HTTPS token authentication gotk bootstrap gitlab --owner= --repository= + # Run bootstrap for a private repo using SSH authentication + gotk bootstrap gitlab --owner= --repository= --ssh-hostname=gitlab.com + # Run bootstrap for a repository path gotk bootstrap gitlab --owner= --repository= --path=dev-cluster # Run bootstrap for a public repository on a personal account - gotk bootstrap gitlab --owner= --repository= --private=false --personal=true + gotk bootstrap gitlab --owner= --repository= --private=false --personal=true # Run bootstrap for a private repo hosted on a GitLab server gotk bootstrap gitlab --owner= --repository= --hostname= @@ -48,7 +51,7 @@ gotk bootstrap gitlab [flags] --personal is personal repository --private is private repository (default true) --repository string GitLab repository name - --ssh-hostname string GitLab SSH hostname, defaults to hostname if not specified + --ssh-hostname string GitLab SSH hostname, when specified a deploy key will be added to the repository ``` ### Options inherited from parent commands diff --git a/docs/guides/installation.md b/docs/guides/installation.md index 457167de..5f6fb80b 100644 --- a/docs/guides/installation.md +++ b/docs/guides/installation.md @@ -154,6 +154,22 @@ gotk bootstrap gitlab \ --personal ``` +To run the bootstrap for a repository using deploy keys for authentication, you have to specify the SSH hostname: + +```sh +gotk bootstrap gitlab \ + --ssh-hostname=gitlab.com \ + --owner=my-gitlab-username \ + --repository=my-repository \ + --branch=master \ + --path=my-cluster +``` + +!!! hint "Authentication" + When providing the `--ssh-hostname`, a readonly deploy key will be added + to your repository, otherwise your GitLab personal token will be used to + authenticate against the HTTPS endpoint instead of SSH. + Run the bootstrap for a repository owned by a GitLab group: ```sh From b041dbd14f13070ceb8456898ac37453e1d63f9c Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Fri, 16 Oct 2020 20:30:41 +0300 Subject: [PATCH 2/2] Add GitLab HTTPS auth to bootstrap options Signed-off-by: Stefan Prodan --- cmd/gotk/bootstrap_gitlab.go | 69 +++++++++++++++++++++---------- docs/cmd/gotk_bootstrap_gitlab.md | 9 ++-- docs/guides/installation.md | 16 +++++++ 3 files changed, 69 insertions(+), 25 deletions(-) diff --git a/cmd/gotk/bootstrap_gitlab.go b/cmd/gotk/bootstrap_gitlab.go index f94824d7..3426b7f4 100644 --- a/cmd/gotk/bootstrap_gitlab.go +++ b/cmd/gotk/bootstrap_gitlab.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/pkg/git" ) @@ -41,14 +43,17 @@ the bootstrap command will perform an upgrade if needed.`, Example: ` # Create a GitLab API token and export it as an env var export GITLAB_TOKEN= - # Run bootstrap for a private repo owned by a GitLab group + # Run bootstrap for a private repo using HTTPS token authentication gotk bootstrap gitlab --owner= --repository= + # Run bootstrap for a private repo using SSH authentication + gotk bootstrap gitlab --owner= --repository= --ssh-hostname=gitlab.com + # Run bootstrap for a repository path gotk bootstrap gitlab --owner= --repository= --path=dev-cluster # Run bootstrap for a public repository on a personal account - gotk bootstrap gitlab --owner= --repository= --private=false --personal=true + gotk bootstrap gitlab --owner= --repository= --private=false --personal=true # Run bootstrap for a private repo hosted on a GitLab server gotk bootstrap gitlab --owner= --repository= --hostname= @@ -77,7 +82,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, defaults to hostname if not specified") + bootstrapGitLabCmd.Flags().StringVar(&glSSHHostname, "ssh-hostname", "", "GitLab SSH hostname, when specified a deploy key will be added to the repository") bootstrapGitLabCmd.Flags().StringVar(&glPath, "path", "", "repository path, when specified the cluster sync will be scoped to this path") bootstrapCmd.AddCommand(bootstrapGitLabCmd) @@ -172,34 +177,54 @@ func bootstrapGitLabCmdRun(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) - } + repoURL := repository.GetURL() - key, err := generateDeployKey(ctx, kubeClient, u, namespace) - if err != nil { - return fmt.Errorf("generating deploy key failed: %w", err) + if glSSHHostname != "" { + // setup SSH deploy key + repoURL = repository.GetSSH() + if shouldCreateDeployKey(ctx, kubeClient, namespace) { + logger.Actionf("configuring deploy key") + u, err := url.Parse(repoURL) + if err != nil { + return fmt.Errorf("git URL parse failed: %w", err) + } + + key, err := generateDeployKey(ctx, kubeClient, u, namespace) + if err != nil { + return fmt.Errorf("generating deploy key failed: %w", err) + } + + keyName := "gotk" + if glPath != "" { + keyName = fmt.Sprintf("gotk-%s", glPath) + } + + if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { + return err + } else if changed { + logger.Successf("deploy key configured") + } } - - keyName := "gotk" - if glPath != "" { - keyName = fmt.Sprintf("gotk-%s", glPath) + } else { + // setup HTTPS token auth + secret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + Namespace: namespace, + }, + StringData: map[string]string{ + "username": "git", + "password": glToken, + }, } - - if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { + if err := upsertSecret(ctx, kubeClient, secret); err != nil { return err - } else if changed { - logger.Successf("deploy key configured") } } // configure repo synchronization logger.Actionf("generating sync manifests") - if err := generateSyncManifests(repository.GetSSH(), bootstrapBranch, namespace, namespace, glPath, tmpDir, glInterval); err != nil { + if err := generateSyncManifests(repoURL, bootstrapBranch, namespace, namespace, glPath, tmpDir, glInterval); err != nil { return err } diff --git a/docs/cmd/gotk_bootstrap_gitlab.md b/docs/cmd/gotk_bootstrap_gitlab.md index 34cdd2c1..68f066a0 100644 --- a/docs/cmd/gotk_bootstrap_gitlab.md +++ b/docs/cmd/gotk_bootstrap_gitlab.md @@ -20,14 +20,17 @@ gotk bootstrap gitlab [flags] # Create a GitLab API token and export it as an env var export GITLAB_TOKEN= - # Run bootstrap for a private repo owned by a GitLab group + # Run bootstrap for a private repo using HTTPS token authentication gotk bootstrap gitlab --owner= --repository= + # Run bootstrap for a private repo using SSH authentication + gotk bootstrap gitlab --owner= --repository= --ssh-hostname=gitlab.com + # Run bootstrap for a repository path gotk bootstrap gitlab --owner= --repository= --path=dev-cluster # Run bootstrap for a public repository on a personal account - gotk bootstrap gitlab --owner= --repository= --private=false --personal=true + gotk bootstrap gitlab --owner= --repository= --private=false --personal=true # Run bootstrap for a private repo hosted on a GitLab server gotk bootstrap gitlab --owner= --repository= --hostname= @@ -48,7 +51,7 @@ gotk bootstrap gitlab [flags] --personal is personal repository --private is private repository (default true) --repository string GitLab repository name - --ssh-hostname string GitLab SSH hostname, defaults to hostname if not specified + --ssh-hostname string GitLab SSH hostname, when specified a deploy key will be added to the repository ``` ### Options inherited from parent commands diff --git a/docs/guides/installation.md b/docs/guides/installation.md index 457167de..5f6fb80b 100644 --- a/docs/guides/installation.md +++ b/docs/guides/installation.md @@ -154,6 +154,22 @@ gotk bootstrap gitlab \ --personal ``` +To run the bootstrap for a repository using deploy keys for authentication, you have to specify the SSH hostname: + +```sh +gotk bootstrap gitlab \ + --ssh-hostname=gitlab.com \ + --owner=my-gitlab-username \ + --repository=my-repository \ + --branch=master \ + --path=my-cluster +``` + +!!! hint "Authentication" + When providing the `--ssh-hostname`, a readonly deploy key will be added + to your repository, otherwise your GitLab personal token will be used to + authenticate against the HTTPS endpoint instead of SSH. + Run the bootstrap for a repository owned by a GitLab group: ```sh