Skip to content
This repository has been archived by the owner on Dec 16, 2024. It is now read-only.

Commit

Permalink
feat: add gitlab provider for bootstrapping
Browse files Browse the repository at this point in the history
  • Loading branch information
Skarlso committed Dec 11, 2023
1 parent d38e2ed commit 0b60826
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 3 deletions.
75 changes: 75 additions & 0 deletions cmd/mpas/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func NewBootstrap(cfg *config.MpasConfig) *cobra.Command {

cmd.AddCommand(NewBootstrapGithub(cfg))
cmd.AddCommand(NewBootstrapGitea(cfg))
cmd.AddCommand(NewBootstrapGitlab(cfg))

return cmd
}
Expand Down Expand Up @@ -198,6 +199,80 @@ func NewBootstrapGitea(cfg *config.MpasConfig) *cobra.Command {
return cmd
}

// NewBootstrapGitlab returns a new cobra.Command for gitlab bootstrap
func NewBootstrapGitlab(cfg *config.MpasConfig) *cobra.Command {
c := &config.GitlabConfig{}
cmd := &cobra.Command{
Use: "gitlab [flags]",
Short: "Bootstrap an mpas management repository on Gitlab",
Example: ` - Bootstrap with a private organization repository
mpas bootstrap gitlab --owner ocmOrg --repository mpas --registry ghcr.io/open-component-model/mpas-bootstrap-component --path clusters/my-cluster --hostname gitlab.example.com
- Bootstrap with a private user repository
mpas bootstrap gitlab --owner myUser --repository mpas --registry ghcr.io/open-component-model/mpas-bootstrap-component --personal --path clusters/my-cluster --hostname gitlab.example.com
- Bootstrap with a public user repository
mpas bootstrap gitlab --owner myUser --repository mpas --registry ghcr.io/open-component-model/mpas-bootstrap-component --personal --private=false --path clusters/my-cluster --hostname gitlab.example.com
- Bootstrap with a public organization repository
mpas bootstrap gitlab --owner ocmOrg --repository mpas --registry ghcr.io/open-component-model/mpas-bootstrap-component --private=false --path clusters/my-cluster --hostname gitlab.example.com
`,
RunE: func(cmd *cobra.Command, args []string) (err error) {
b := bootstrap.GitlabCmd{
Owner: c.Owner,
Personal: c.Personal,
Repository: c.Repository,
FromFile: c.FromFile,
Registry: c.Registry,
DockerconfigPath: cfg.DockerconfigPath,
Path: c.Path,
CommitMessageAppendix: c.CommitMessageAppendix,
Hostname: c.Hostname,
Components: append(env.InstallComponents, c.Components...),
CaFile: c.CaFile,
}

token := os.Getenv(env.GitlabTokenVar)
if token == "" {
token, err = passwdFromStdin("Gitlab token: ")
if err != nil {
return fmt.Errorf("failed to read token from stdin: %w", err)
}
}
b.Token = token

if b.Owner == "" {
return fmt.Errorf("owner must be set")
}

if b.Repository == "" {
return fmt.Errorf("repository must be set")
}

if b.Registry == "" {
return fmt.Errorf("registry must be set")
}

b.Timeout, err = time.ParseDuration(cfg.Timeout)
if err != nil {
return err
}

b.Interval, err = time.ParseDuration(c.Interval)
if err != nil {
return err
}

return b.Execute(cmd.Context(), cfg)

},
}

c.AddFlags(cmd.Flags())

return cmd
}

// passwdFromStdin reads a password from stdin.
func passwdFromStdin(prompt string) (string, error) {
// Get the initial state of the terminal.
Expand Down
133 changes: 133 additions & 0 deletions cmd/mpas/bootstrap/bootstrap_gitlab.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Gardener contributors.
//
// SPDX-License-Identifier: Apache-2.0

package bootstrap

import (
"context"
"time"

"github.com/open-component-model/mpas/cmd/mpas/config"
"github.com/open-component-model/mpas/internal/bootstrap"
"github.com/open-component-model/mpas/internal/bootstrap/provider"
"github.com/open-component-model/mpas/internal/env"
"github.com/open-component-model/mpas/internal/kubeutils"
)

// GitlabCmd is a command for bootstrapping a Gitlab repository
type GitlabCmd struct {
// Owner is the owner of the repository
Owner string
// Token is the token to use for authentication
Token string
// Personal indicates whether the repository is a personal repository
Personal bool
// Hostname is the hostname of the Gitlab instance
Hostname string
// Repository is the name of the repository
Repository string
// FromFile is the path to a file archive to use for bootstrapping
FromFile string
// Registry is the registry to use for the bootstrap components
Registry string
// DockerconfigPath is the path to the docker config file
DockerconfigPath string
// Path is the path in the repository to use to host the bootstrapped components yaml files
Path string
// CommitMessageAppendix is the appendix to add to the commit message
// for example to skip CI
CommitMessageAppendix string
// Private indicates whether the repository is private
Private bool
// Interval is the interval to use for reconciling
Interval time.Duration
// Timeout is the timeout to use for operations
Timeout time.Duration
// Components is the list of components to install
Components []string
// DestructiveActions indicates whether destructive actions are allowed
DestructiveActions bool
// TestURL is the URL to use for testing the management repository
TestURL string
// CaFile defines and optional root certificate for the git repository used by flux.
CaFile string
bootstrapper *bootstrap.Bootstrap
}

// Execute executes the command and returns an error if one occurred.
func (b *GitlabCmd) Execute(ctx context.Context, cfg *config.MpasConfig) error {
t, err := time.ParseDuration(cfg.Timeout)
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(ctx, t)
defer cancel()

//if b.Hostname == "" {
// return fmt.Errorf("hostname must be specified")
//}

providerOpts := provider.ProviderOptions{
Provider: env.ProviderGitlab,
Hostname: b.Hostname,
Token: b.Token,
DestructiveActions: b.DestructiveActions,
}

providerClient, err := provider.New().Build(providerOpts)
if err != nil {
return err
}

kubeClient, err := kubeutils.KubeClient(cfg.KubeConfigArgs)
if err != nil {
return err
}

visibility := "public"
if b.Private {
visibility = "private"
}

transport := "https"
if cfg.PlainHTTP {
transport = "http"
}

b.bootstrapper, err = bootstrap.New(providerClient,
bootstrap.WithOwner(b.Owner),
bootstrap.WithRepositoryName(b.Repository),
bootstrap.WithPersonal(b.Personal),
bootstrap.WithFromFile(b.FromFile),
bootstrap.WithRegistry(b.Registry),
bootstrap.WithPrinter(cfg.Printer),
bootstrap.WithComponents(b.Components),
bootstrap.WithToken(b.Token),
bootstrap.WithTransportType(transport),
bootstrap.WithDockerConfigPath(b.DockerconfigPath),
bootstrap.WithTarget(b.Path),
bootstrap.WithKubeClient(kubeClient),
bootstrap.WithRESTClientGetter(cfg.KubeConfigArgs),
bootstrap.WithInterval(b.Interval),
bootstrap.WithTimeout(b.Timeout),
bootstrap.WithCommitMessageAppendix(b.CommitMessageAppendix),
bootstrap.WithVisibility(visibility),
bootstrap.WithTestURL(b.TestURL),
bootstrap.WithRootFile(b.CaFile),
)

if err != nil {
return err
}

return b.bootstrapper.Run(ctx)
}

// Cleanup cleans up the resources created by the command.
func (b *GitlabCmd) Cleanup(ctx context.Context) error {
if b.bootstrapper != nil {
return b.bootstrapper.DeleteManagementRepository(ctx)
}
return nil
}
18 changes: 15 additions & 3 deletions cmd/mpas/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,19 @@ func (m *BootstrapConfig) AddFlags(flags *pflag.FlagSet) {
flags.StringVar(&m.CaFile, "ca-file", "", "Root certificate for the remote git server.")
}

// GithubConfig is the configuration for the Github bootstrap command.
// GithubConfig is the configuration for the GitHub bootstrap command.
type GithubConfig struct {
BootstrapConfig
Personal bool
}

// AddFlags adds the Github bootstrap flags to the given flag set.
// AddFlags adds the GitHub bootstrap flags to the given flag set.
func (g *GithubConfig) AddFlags(flags *pflag.FlagSet) {
flags.BoolVar(&g.Personal, "personal", false, "The personal access token to use to access the Github API")
g.BootstrapConfig.AddFlags(flags)
}

// GiteaConfig is the configuration for the Github bootstrap command.
// GiteaConfig is the configuration for the GitHub bootstrap command.
type GiteaConfig struct {
BootstrapConfig
Personal bool
Expand All @@ -108,6 +108,18 @@ func (g *GiteaConfig) AddFlags(flags *pflag.FlagSet) {
g.BootstrapConfig.AddFlags(flags)
}

// GitlabConfig is the configuration for the Gitlab bootstrap command.
type GitlabConfig struct {
BootstrapConfig
Personal bool
}

// AddFlags adds the Gitea bootstrap flags to the given flag set.
func (g *GitlabConfig) AddFlags(flags *pflag.FlagSet) {
flags.BoolVar(&g.Personal, "personal", false, "The personal access token to use to access the Gitlab API")
g.BootstrapConfig.AddFlags(flags)
}

// CreateConfig is the configuration shared by the create commands.
type CreateConfig struct {
Prune bool
Expand Down
12 changes: 12 additions & 0 deletions internal/bootstrap/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/fluxcd/go-git-providers/gitea"
"github.com/fluxcd/go-git-providers/github"
"github.com/fluxcd/go-git-providers/gitlab"
"github.com/fluxcd/go-git-providers/gitprovider"
"github.com/open-component-model/mpas/internal/env"
)
Expand All @@ -26,6 +27,7 @@ func init() {
providers = make(providerMap)
providers.register(env.ProviderGithub, githubProviderFunc)
providers.register(env.ProviderGitea, giteaProviderFunc)
providers.register(env.ProviderGitlab, gitlabProviderFunc)
}

// ProviderOptions contains the options for the provider
Expand Down Expand Up @@ -83,6 +85,16 @@ func giteaProviderFunc(opts ProviderOptions) (gitprovider.Client, error) {
return client, err
}

func gitlabProviderFunc(opts ProviderOptions) (gitprovider.Client, error) {
o := makeProviderOpts(opts)
// TODO: Put that into an option somewhere.
client, err := gitlab.NewClient(opts.Token, "oauth2", o...)
if err != nil {
return nil, err
}
return client, err
}

func makeProviderOpts(opts ProviderOptions) []gitprovider.ClientOption {
o := []gitprovider.ClientOption{
gitprovider.WithOAuth2Token(opts.Token),
Expand Down
4 changes: 4 additions & 0 deletions internal/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,17 @@ const (
GithubTokenVar = "GITHUB_TOKEN"
// GiteaTokenVar is the name of the environment variable to use to get the gitea token.
GiteaTokenVar = "GITEA_TOKEN"
// GitlabTokenVar is the name of the environment variable to use to get the gitlab token.
GitlabTokenVar = "GITLAB_TOKEN"
)

const (
// ProviderGithub is the github provider.
ProviderGithub = "github"
// ProviderGitea is the gitea provider.
ProviderGitea = "gitea"
// ProviderGitlab is the gitlab provider.
ProviderGitlab = "gitlab"
)

const (
Expand Down

0 comments on commit 0b60826

Please sign in to comment.