mirror of
				https://github.com/fluxcd/flux2.git
				synced 2025-10-31 16:26:36 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			561 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			561 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2021 The Flux authors
 | |
| 
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
| 
 | |
|     http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| package bootstrap
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"net/url"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| 
 | |
| 	corev1 "k8s.io/api/core/v1"
 | |
| 	"sigs.k8s.io/controller-runtime/pkg/client"
 | |
| 
 | |
| 	"github.com/fluxcd/go-git-providers/gitprovider"
 | |
| 
 | |
| 	"github.com/fluxcd/flux2/internal/bootstrap/git"
 | |
| 	"github.com/fluxcd/flux2/pkg/manifestgen/sourcesecret"
 | |
| 	"github.com/fluxcd/flux2/pkg/manifestgen/sync"
 | |
| )
 | |
| 
 | |
| type GitProviderBootstrapper struct {
 | |
| 	*PlainGitBootstrapper
 | |
| 
 | |
| 	owner      string
 | |
| 	repository string
 | |
| 	personal   bool
 | |
| 
 | |
| 	description   string
 | |
| 	defaultBranch string
 | |
| 	visibility    string
 | |
| 
 | |
| 	reconcile bool
 | |
| 
 | |
| 	teams map[string]string
 | |
| 
 | |
| 	readWriteKey bool
 | |
| 
 | |
| 	bootstrapTransportType string
 | |
| 	syncTransportType      string
 | |
| 
 | |
| 	sshHostname string
 | |
| 
 | |
| 	provider gitprovider.Client
 | |
| }
 | |
| 
 | |
| func NewGitProviderBootstrapper(git git.Git, provider gitprovider.Client, kube client.Client, opts ...GitProviderOption) (*GitProviderBootstrapper, error) {
 | |
| 	b := &GitProviderBootstrapper{
 | |
| 		PlainGitBootstrapper: &PlainGitBootstrapper{
 | |
| 			git:  git,
 | |
| 			kube: kube,
 | |
| 		},
 | |
| 		bootstrapTransportType: "https",
 | |
| 		syncTransportType:      "ssh",
 | |
| 		provider:               provider,
 | |
| 	}
 | |
| 	b.PlainGitBootstrapper.postGenerateSecret = append(b.PlainGitBootstrapper.postGenerateSecret, b.reconcileDeployKey)
 | |
| 	for _, opt := range opts {
 | |
| 		opt.applyGitProvider(b)
 | |
| 	}
 | |
| 	return b, nil
 | |
| }
 | |
| 
 | |
| type GitProviderOption interface {
 | |
| 	applyGitProvider(b *GitProviderBootstrapper)
 | |
| }
 | |
| 
 | |
| func WithProviderRepository(owner, repository string, personal bool) GitProviderOption {
 | |
| 	return providerRepositoryOption{
 | |
| 		owner:      owner,
 | |
| 		repository: repository,
 | |
| 		personal:   personal,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type providerRepositoryOption struct {
 | |
| 	owner      string
 | |
| 	repository string
 | |
| 	personal   bool
 | |
| }
 | |
| 
 | |
| func (o providerRepositoryOption) applyGitProvider(b *GitProviderBootstrapper) {
 | |
| 	b.owner = o.owner
 | |
| 	b.repository = o.repository
 | |
| 	b.personal = o.personal
 | |
| }
 | |
| 
 | |
| func WithProviderRepositoryConfig(description, defaultBranch, visibility string) GitProviderOption {
 | |
| 	return providerRepositoryConfigOption{
 | |
| 		description:   description,
 | |
| 		defaultBranch: defaultBranch,
 | |
| 		visibility:    visibility,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type providerRepositoryConfigOption struct {
 | |
| 	description   string
 | |
| 	defaultBranch string
 | |
| 	visibility    string
 | |
| }
 | |
| 
 | |
| func (o providerRepositoryConfigOption) applyGitProvider(b *GitProviderBootstrapper) {
 | |
| 	b.description = o.description
 | |
| 	b.defaultBranch = o.defaultBranch
 | |
| 	b.visibility = o.visibility
 | |
| }
 | |
| 
 | |
| func WithProviderTeamPermissions(teams map[string]string) GitProviderOption {
 | |
| 	return providerRepositoryTeamPermissionsOption(teams)
 | |
| }
 | |
| 
 | |
| type providerRepositoryTeamPermissionsOption map[string]string
 | |
| 
 | |
| func (o providerRepositoryTeamPermissionsOption) applyGitProvider(b *GitProviderBootstrapper) {
 | |
| 	b.teams = o
 | |
| }
 | |
| 
 | |
| func WithReadWriteKeyPermissions(b bool) GitProviderOption {
 | |
| 	return withReadWriteKeyPermissionsOption(b)
 | |
| }
 | |
| 
 | |
| type withReadWriteKeyPermissionsOption bool
 | |
| 
 | |
| func (o withReadWriteKeyPermissionsOption) applyGitProvider(b *GitProviderBootstrapper) {
 | |
| 	b.readWriteKey = bool(o)
 | |
| }
 | |
| 
 | |
| func WithBootstrapTransportType(protocol string) GitProviderOption {
 | |
| 	return bootstrapTransportTypeOption(protocol)
 | |
| }
 | |
| 
 | |
| type bootstrapTransportTypeOption string
 | |
| 
 | |
| func (o bootstrapTransportTypeOption) applyGitProvider(b *GitProviderBootstrapper) {
 | |
| 	b.bootstrapTransportType = string(o)
 | |
| }
 | |
| 
 | |
| func WithSyncTransportType(protocol string) GitProviderOption {
 | |
| 	return syncProtocolOption(protocol)
 | |
| }
 | |
| 
 | |
| type syncProtocolOption string
 | |
| 
 | |
| func (o syncProtocolOption) applyGitProvider(b *GitProviderBootstrapper) {
 | |
| 	b.syncTransportType = string(o)
 | |
| }
 | |
| 
 | |
| func WithSSHHostname(hostname string) GitProviderOption {
 | |
| 	return sshHostnameOption(hostname)
 | |
| }
 | |
| 
 | |
| type sshHostnameOption string
 | |
| 
 | |
| func (o sshHostnameOption) applyGitProvider(b *GitProviderBootstrapper) {
 | |
| 	b.sshHostname = string(o)
 | |
| }
 | |
| 
 | |
| func WithReconcile() GitProviderOption {
 | |
| 	return reconcileOption(true)
 | |
| }
 | |
| 
 | |
| type reconcileOption bool
 | |
| 
 | |
| func (o reconcileOption) applyGitProvider(b *GitProviderBootstrapper) {
 | |
| 	b.reconcile = true
 | |
| }
 | |
| 
 | |
| func (b *GitProviderBootstrapper) ReconcileSyncConfig(ctx context.Context, options sync.Options) error {
 | |
| 	repo, err := b.getRepository(ctx)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	if b.url == "" {
 | |
| 		bootstrapURL, err := b.getCloneURL(repo, gitprovider.TransportType(b.bootstrapTransportType))
 | |
| 		if err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 		WithRepositoryURL(bootstrapURL).applyGit(b.PlainGitBootstrapper)
 | |
| 	}
 | |
| 	if options.URL == "" {
 | |
| 		syncURL, err := b.getCloneURL(repo, gitprovider.TransportType(b.syncTransportType))
 | |
| 		if err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 		options.URL = syncURL
 | |
| 	}
 | |
| 	return b.PlainGitBootstrapper.ReconcileSyncConfig(ctx, options)
 | |
| }
 | |
| 
 | |
| // ReconcileRepository reconciles an organization or user repository with the
 | |
| // GitProviderBootstrapper configuration. On success, the URL in the embedded
 | |
| // PlainGitBootstrapper is set to clone URL for the configured protocol.
 | |
| //
 | |
| // When part of the reconciliation fails with a warning without aborting, an
 | |
| // ErrReconciledWithWarning error is returned.
 | |
| func (b *GitProviderBootstrapper) ReconcileRepository(ctx context.Context) error {
 | |
| 	var repo gitprovider.UserRepository
 | |
| 	var err error
 | |
| 
 | |
| 	if b.personal {
 | |
| 		repo, err = b.reconcileUserRepository(ctx)
 | |
| 	} else {
 | |
| 		repo, err = b.reconcileOrgRepository(ctx)
 | |
| 	}
 | |
| 	if err != nil && !errors.Is(err, ErrReconciledWithWarning) {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	cloneURL := repo.Repository().GetCloneURL(gitprovider.TransportType(b.bootstrapTransportType))
 | |
| 	// TODO(hidde): https://github.com/fluxcd/go-git-providers/issues/55
 | |
| 	if strings.HasPrefix(cloneURL, "https://https://") {
 | |
| 		cloneURL = strings.TrimPrefix(cloneURL, "https://")
 | |
| 	}
 | |
| 	WithRepositoryURL(cloneURL).applyGit(b.PlainGitBootstrapper)
 | |
| 
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| func (b *GitProviderBootstrapper) reconcileDeployKey(ctx context.Context, secret corev1.Secret, options sourcesecret.Options) error {
 | |
| 	ppk, ok := secret.StringData[sourcesecret.PublicKeySecretKey]
 | |
| 	if !ok {
 | |
| 		return nil
 | |
| 	}
 | |
| 	b.logger.Successf("public key: %s", strings.TrimSpace(ppk))
 | |
| 
 | |
| 	repo, err := b.getRepository(ctx)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	name := deployKeyName(options.Namespace, b.branch, options.Name, options.TargetPath)
 | |
| 	deployKeyInfo := newDeployKeyInfo(name, ppk, b.readWriteKey)
 | |
| 	var changed bool
 | |
| 	if _, changed, err = repo.DeployKeys().Reconcile(ctx, deployKeyInfo); err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	if changed {
 | |
| 		b.logger.Successf("configured deploy key %q for %q", deployKeyInfo.Name, repo.Repository().String())
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // reconcileOrgRepository reconciles a gitprovider.OrgRepository
 | |
| // with the GitProviderBootstrapper values, including any
 | |
| // gitprovider.TeamAccessInfo configurations.
 | |
| //
 | |
| // If one of the gitprovider.TeamAccessInfo does not reconcile
 | |
| // successfully, the gitprovider.UserRepository and an
 | |
| // ErrReconciledWithWarning error are returned.
 | |
| func (b *GitProviderBootstrapper) reconcileOrgRepository(ctx context.Context) (gitprovider.UserRepository, error) {
 | |
| 	b.logger.Actionf("connecting to %s", b.provider.SupportedDomain())
 | |
| 
 | |
| 	// Construct the repository and other configuration objects
 | |
| 	// go-git-provider likes to work with
 | |
| 	subOrgs, repoName := splitSubOrganizationsFromRepositoryName(b.repository)
 | |
| 	orgRef := newOrganizationRef(b.provider.SupportedDomain(), b.owner, subOrgs)
 | |
| 	repoRef := newOrgRepositoryRef(orgRef, repoName)
 | |
| 	repoInfo := newRepositoryInfo(b.description, b.defaultBranch, b.visibility)
 | |
| 
 | |
| 	// Reconcile the organization repository
 | |
| 	repo, err := b.provider.OrgRepositories().Get(ctx, repoRef)
 | |
| 	if err != nil {
 | |
| 		if !errors.Is(err, gitprovider.ErrNotFound) {
 | |
| 			return nil, fmt.Errorf("failed to get Git repository %q: %w", repoRef.String(), err)
 | |
| 		}
 | |
| 		// go-git-providers has at present some issues with the idempotency
 | |
| 		// of the available Reconcile methods, and setting e.g. the default
 | |
| 		// branch correctly. Resort to Create until this has been resolved.
 | |
| 		repo, err = b.provider.OrgRepositories().Create(ctx, repoRef, repoInfo)
 | |
| 		if err != nil {
 | |
| 			return nil, fmt.Errorf("failed to create new Git repository %q: %w", repoRef.String(), err)
 | |
| 		}
 | |
| 		b.logger.Successf("repository %q created", repoRef.String())
 | |
| 	}
 | |
| 
 | |
| 	var changed bool
 | |
| 	if b.reconcile {
 | |
| 		// Set default branch before calling Reconcile due to bug described
 | |
| 		// above.
 | |
| 		repoInfo.DefaultBranch = repo.Get().DefaultBranch
 | |
| 		if err = retry(1, 2*time.Second, func() (err error) {
 | |
| 			repo, changed, err = b.provider.OrgRepositories().Reconcile(ctx, repoRef, repoInfo)
 | |
| 			return
 | |
| 		}); err != nil {
 | |
| 			return nil, fmt.Errorf("failed to reconcile Git repository %q: %w", repoRef.String(), err)
 | |
| 		}
 | |
| 		if changed {
 | |
| 			b.logger.Successf("repository %q reconciled", repoRef.String())
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Build the team access config
 | |
| 	teamAccessInfo, err := buildTeamAccessInfo(b.teams, gitprovider.RepositoryPermissionVar(gitprovider.RepositoryPermissionMaintain))
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("failed to reconcile repository team access: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	// Reconcile the team access config on best effort (that being:
 | |
| 	// record the error as a warning, but continue with the
 | |
| 	// reconciliation of the others)
 | |
| 	var warning error
 | |
| 	if count := len(teamAccessInfo); count > 0 {
 | |
| 		b.logger.Actionf("reconciling repository permissions")
 | |
| 		for _, i := range teamAccessInfo {
 | |
| 			var err error
 | |
| 			// Don't reconcile team if team already exists and b.reconcile is false
 | |
| 			if team, err := repo.TeamAccess().Get(ctx, i.Name); err == nil && !b.reconcile && team != nil {
 | |
| 				continue
 | |
| 			}
 | |
| 			_, changed, err = repo.TeamAccess().Reconcile(ctx, i)
 | |
| 			if err != nil {
 | |
| 				warning = fmt.Errorf("failed to grant permissions to team: %w", ErrReconciledWithWarning)
 | |
| 				b.logger.Failuref("failed to grant %q permissions to %q: %s", *i.Permission, i.Name, err.Error())
 | |
| 			} else if changed {
 | |
| 				b.logger.Successf("granted %q permissions to %q", *i.Permission, i.Name)
 | |
| 			}
 | |
| 		}
 | |
| 		b.logger.Successf("reconciled repository permissions")
 | |
| 	}
 | |
| 	return repo, warning
 | |
| }
 | |
| 
 | |
| // reconcileUserRepository reconciles a gitprovider.UserRepository
 | |
| // with the GitProviderBootstrapper values. It returns the reconciled
 | |
| // gitprovider.UserRepository, or an error.
 | |
| func (b *GitProviderBootstrapper) reconcileUserRepository(ctx context.Context) (gitprovider.UserRepository, error) {
 | |
| 	b.logger.Actionf("connecting to %s", b.provider.SupportedDomain())
 | |
| 
 | |
| 	// Construct the repository and other metadata objects
 | |
| 	// go-git-provider likes to work with.
 | |
| 	_, repoName := splitSubOrganizationsFromRepositoryName(b.repository)
 | |
| 	userRef := newUserRef(b.provider.SupportedDomain(), b.owner)
 | |
| 	repoRef := newUserRepositoryRef(userRef, repoName)
 | |
| 	repoInfo := newRepositoryInfo(b.description, b.defaultBranch, b.visibility)
 | |
| 
 | |
| 	// Reconcile the user repository
 | |
| 	repo, err := b.provider.UserRepositories().Get(ctx, repoRef)
 | |
| 	if err != nil {
 | |
| 		if !errors.Is(err, gitprovider.ErrNotFound) {
 | |
| 			return nil, fmt.Errorf("failed to get Git repository %q: %w", repoRef.String(), err)
 | |
| 		}
 | |
| 		// go-git-providers has at present some issues with the idempotency
 | |
| 		// of the available Reconcile methods, and setting e.g. the default
 | |
| 		// branch correctly. Resort to Create until this has been resolved.
 | |
| 		repo, err = b.provider.UserRepositories().Create(ctx, repoRef, repoInfo)
 | |
| 		if err != nil {
 | |
| 			return nil, fmt.Errorf("failed to create new Git repository %q: %w", repoRef.String(), err)
 | |
| 		}
 | |
| 		b.logger.Successf("repository %q created", repoRef.String())
 | |
| 	}
 | |
| 
 | |
| 	if b.reconcile {
 | |
| 		// Set default branch before calling Reconcile due to bug described
 | |
| 		// above.
 | |
| 		repoInfo.DefaultBranch = repo.Get().DefaultBranch
 | |
| 		var changed bool
 | |
| 		if err = retry(1, 2*time.Second, func() (err error) {
 | |
| 			repo, changed, err = b.provider.UserRepositories().Reconcile(ctx, repoRef, repoInfo)
 | |
| 			return
 | |
| 		}); err != nil {
 | |
| 			return nil, fmt.Errorf("failed to reconcile Git repository %q: %w", repoRef.String(), err)
 | |
| 		}
 | |
| 		if changed {
 | |
| 			b.logger.Successf("repository %q reconciled", repoRef.String())
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return repo, nil
 | |
| }
 | |
| 
 | |
| // getRepository retrieves and returns the gitprovider.UserRepository
 | |
| // for organization and user repositories using the
 | |
| // GitProviderBootstrapper values.
 | |
| // As gitprovider.OrgRepository is a superset of gitprovider.UserRepository, this
 | |
| // type is returned.
 | |
| func (b *GitProviderBootstrapper) getRepository(ctx context.Context) (gitprovider.UserRepository, error) {
 | |
| 	subOrgs, repoName := splitSubOrganizationsFromRepositoryName(b.repository)
 | |
| 
 | |
| 	if b.personal {
 | |
| 		userRef := newUserRef(b.provider.SupportedDomain(), b.owner)
 | |
| 		return b.provider.UserRepositories().Get(ctx, newUserRepositoryRef(userRef, repoName))
 | |
| 	}
 | |
| 
 | |
| 	orgRef := newOrganizationRef(b.provider.SupportedDomain(), b.owner, subOrgs)
 | |
| 	return b.provider.OrgRepositories().Get(ctx, newOrgRepositoryRef(orgRef, repoName))
 | |
| }
 | |
| 
 | |
| // getCloneURL returns the Git clone URL for the given
 | |
| // gitprovider.UserRepository. If the given transport type is
 | |
| // gitprovider.TransportTypeSSH and a custom SSH hostname is configured,
 | |
| // the hostname of the URL will be modified to this hostname.
 | |
| func (b *GitProviderBootstrapper) getCloneURL(repository gitprovider.UserRepository, transport gitprovider.TransportType) (string, error) {
 | |
| 	u := repository.Repository().GetCloneURL(transport)
 | |
| 	// TODO(hidde): https://github.com/fluxcd/go-git-providers/issues/55
 | |
| 	if strings.HasPrefix(u, "https://https://") {
 | |
| 		u = strings.TrimPrefix(u, "https://")
 | |
| 	}
 | |
| 	var err error
 | |
| 	if transport == gitprovider.TransportTypeSSH && b.sshHostname != "" {
 | |
| 		if u, err = setHostname(u, b.sshHostname); err != nil {
 | |
| 			err = fmt.Errorf("failed to set SSH hostname for URL %q: %w", u, err)
 | |
| 		}
 | |
| 	}
 | |
| 	return u, err
 | |
| }
 | |
| 
 | |
| // splitSubOrganizationsFromRepositoryName removes any prefixed sub
 | |
| // organizations from the given repository name by splitting the
 | |
| // string into a slice by '/'.
 | |
| // The last (or only) item of the slice result is assumed to be the
 | |
| // repository name, other items (nested) sub organizations.
 | |
| func splitSubOrganizationsFromRepositoryName(name string) ([]string, string) {
 | |
| 	elements := strings.Split(name, "/")
 | |
| 	i := len(elements)
 | |
| 	switch i {
 | |
| 	case 1:
 | |
| 		return nil, name
 | |
| 	default:
 | |
| 		return elements[:i-1], elements[i-1]
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // buildTeamAccessInfo constructs a gitprovider.TeamAccessInfo slice
 | |
| // from the given string map of team names to permissions.
 | |
| //
 | |
| // Providing a default gitprovider.RepositoryPermission is optional,
 | |
| // and omitting it will make it default to the go-git-provider default.
 | |
| //
 | |
| // An error is returned if any of the given permissions is invalid.
 | |
| func buildTeamAccessInfo(m map[string]string, defaultPermissions *gitprovider.RepositoryPermission) ([]gitprovider.TeamAccessInfo, error) {
 | |
| 	var infos []gitprovider.TeamAccessInfo
 | |
| 	if defaultPermissions != nil {
 | |
| 		if err := gitprovider.ValidateRepositoryPermission(*defaultPermissions); err != nil {
 | |
| 			return nil, fmt.Errorf("invalid default team permission %q", *defaultPermissions)
 | |
| 		}
 | |
| 	}
 | |
| 	for n, p := range m {
 | |
| 		permission := defaultPermissions
 | |
| 		if p != "" {
 | |
| 			p := gitprovider.RepositoryPermission(p)
 | |
| 			if err := gitprovider.ValidateRepositoryPermission(p); err != nil {
 | |
| 				return nil, fmt.Errorf("invalid permission %q for team %q", p, n)
 | |
| 			}
 | |
| 			permission = &p
 | |
| 		}
 | |
| 		i := gitprovider.TeamAccessInfo{
 | |
| 			Name:       n,
 | |
| 			Permission: permission,
 | |
| 		}
 | |
| 		infos = append(infos, i)
 | |
| 	}
 | |
| 	return infos, nil
 | |
| }
 | |
| 
 | |
| // newOrganizationRef constructs a gitprovider.OrganizationRef with the
 | |
| // given values and returns the result.
 | |
| func newOrganizationRef(domain, organization string, subOrganizations []string) gitprovider.OrganizationRef {
 | |
| 	return gitprovider.OrganizationRef{
 | |
| 		Domain:           domain,
 | |
| 		Organization:     organization,
 | |
| 		SubOrganizations: subOrganizations,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // newOrgRepositoryRef constructs a gitprovider.OrgRepositoryRef with
 | |
| // the given values and returns the result.
 | |
| func newOrgRepositoryRef(organizationRef gitprovider.OrganizationRef, name string) gitprovider.OrgRepositoryRef {
 | |
| 	return gitprovider.OrgRepositoryRef{
 | |
| 		OrganizationRef: organizationRef,
 | |
| 		RepositoryName:  name,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // newUserRef constructs a gitprovider.UserRef with the given values
 | |
| // and returns the result.
 | |
| func newUserRef(domain, login string) gitprovider.UserRef {
 | |
| 	return gitprovider.UserRef{
 | |
| 		Domain:    domain,
 | |
| 		UserLogin: login,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // newUserRepositoryRef constructs a gitprovider.UserRepositoryRef with
 | |
| // the given values and returns the result.
 | |
| func newUserRepositoryRef(userRef gitprovider.UserRef, name string) gitprovider.UserRepositoryRef {
 | |
| 	return gitprovider.UserRepositoryRef{
 | |
| 		UserRef:        userRef,
 | |
| 		RepositoryName: name,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // newRepositoryInfo constructs a gitprovider.RepositoryInfo with the
 | |
| // given values and returns the result.
 | |
| func newRepositoryInfo(description, defaultBranch, visibility string) gitprovider.RepositoryInfo {
 | |
| 	var i gitprovider.RepositoryInfo
 | |
| 	if description != "" {
 | |
| 		i.Description = gitprovider.StringVar(description)
 | |
| 	}
 | |
| 	if defaultBranch != "" {
 | |
| 		i.DefaultBranch = gitprovider.StringVar(defaultBranch)
 | |
| 	}
 | |
| 	if visibility != "" {
 | |
| 		i.Visibility = gitprovider.RepositoryVisibilityVar(gitprovider.RepositoryVisibility(visibility))
 | |
| 	}
 | |
| 	return i
 | |
| }
 | |
| 
 | |
| // newDeployKeyInfo constructs a gitprovider.DeployKeyInfo with the
 | |
| // given values and returns the result.
 | |
| func newDeployKeyInfo(name, publicKey string, readWrite bool) gitprovider.DeployKeyInfo {
 | |
| 	keyInfo := gitprovider.DeployKeyInfo{
 | |
| 		Name: name,
 | |
| 		Key:  []byte(publicKey),
 | |
| 	}
 | |
| 	if readWrite {
 | |
| 		keyInfo.ReadOnly = gitprovider.BoolVar(false)
 | |
| 	}
 | |
| 	return keyInfo
 | |
| }
 | |
| 
 | |
| func deployKeyName(namespace, secretName, branch, path string) string {
 | |
| 	var name string
 | |
| 	for _, v := range []string{namespace, secretName, branch, path} {
 | |
| 		if v == "" {
 | |
| 			continue
 | |
| 		}
 | |
| 		if name == "" {
 | |
| 			name = v
 | |
| 		} else {
 | |
| 			name = name + "-" + v
 | |
| 		}
 | |
| 	}
 | |
| 	return name
 | |
| }
 | |
| 
 | |
| // setHostname is a helper to replace the hostname of the given URL.
 | |
| // TODO(hidde): support for this should be added in go-git-providers.
 | |
| func setHostname(URL, hostname string) (string, error) {
 | |
| 	u, err := url.Parse(URL)
 | |
| 	if err != nil {
 | |
| 		return URL, err
 | |
| 	}
 | |
| 	u.Host = hostname
 | |
| 	return u.String(), nil
 | |
| }
 | 
