Move `git/common` to `git`
Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit is contained in:
parent
7e63ef841c
commit
fac1afa2a8
|
@ -44,7 +44,7 @@ import (
|
||||||
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
"github.com/fluxcd/source-controller/pkg/git"
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
"github.com/fluxcd/source-controller/pkg/git/strategy"
|
||||||
)
|
)
|
||||||
|
|
||||||
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories,verbs=get;list;watch;create;update;patch;delete
|
||||||
|
@ -178,9 +178,9 @@ func (r *GitRepositoryReconciler) reconcile(ctx context.Context, repository sour
|
||||||
defer os.RemoveAll(tmpGit)
|
defer os.RemoveAll(tmpGit)
|
||||||
|
|
||||||
// determine auth method
|
// determine auth method
|
||||||
auth := &common.Auth{}
|
auth := &git.Auth{}
|
||||||
if repository.Spec.SecretRef != nil {
|
if repository.Spec.SecretRef != nil {
|
||||||
authStrategy, err := git.AuthSecretStrategyForURL(repository.Spec.URL, repository.Spec.GitImplementation)
|
authStrategy, err := strategy.AuthSecretStrategyForURL(repository.Spec.URL, repository.Spec.GitImplementation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sourcev1.GitRepositoryNotReady(repository, sourcev1.AuthenticationFailedReason, err.Error()), err
|
return sourcev1.GitRepositoryNotReady(repository, sourcev1.AuthenticationFailedReason, err.Error()), err
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ func (r *GitRepositoryReconciler) reconcile(ctx context.Context, repository sour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkoutStrategy, err := git.CheckoutStrategyForRef(repository.Spec.Reference, repository.Spec.GitImplementation)
|
checkoutStrategy, err := strategy.CheckoutStrategyForRef(repository.Spec.Reference, repository.Spec.GitImplementation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err
|
return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020 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 common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
|
||||||
git2go "github.com/libgit2/git2go/v31"
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
DefaultOrigin = "origin"
|
|
||||||
DefaultBranch = "master"
|
|
||||||
DefaultPublicKeyAuthUser = "git"
|
|
||||||
CAFile = "caFile"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Commit interface {
|
|
||||||
Verify(secret corev1.Secret) error
|
|
||||||
Hash() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type CheckoutStrategy interface {
|
|
||||||
Checkout(ctx context.Context, path, url string, auth *Auth) (Commit, string, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Auth struct {
|
|
||||||
AuthMethod transport.AuthMethod
|
|
||||||
CredCallback git2go.CredentialsCallback
|
|
||||||
CertCallback git2go.CertificateCheckCallback
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthSecretStrategy interface {
|
|
||||||
Method(secret corev1.Secret) (*Auth, error)
|
|
||||||
}
|
|
|
@ -17,32 +17,37 @@ limitations under the License.
|
||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"context"
|
||||||
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
git2go "github.com/libgit2/git2go/v31"
|
||||||
"github.com/fluxcd/source-controller/pkg/git/gogit"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"github.com/fluxcd/source-controller/pkg/git/libgit2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef, gitImplementation string) (common.CheckoutStrategy, error) {
|
const (
|
||||||
switch gitImplementation {
|
DefaultOrigin = "origin"
|
||||||
case sourcev1.GoGitImplementation:
|
DefaultBranch = "master"
|
||||||
return gogit.CheckoutStrategyForRef(ref), nil
|
DefaultPublicKeyAuthUser = "git"
|
||||||
case sourcev1.LibGit2Implementation:
|
CAFile = "caFile"
|
||||||
return libgit2.CheckoutStrategyForRef(ref), nil
|
)
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid git implementation %s", gitImplementation)
|
type Commit interface {
|
||||||
}
|
Verify(secret corev1.Secret) error
|
||||||
|
Hash() string
|
||||||
}
|
}
|
||||||
|
|
||||||
func AuthSecretStrategyForURL(url string, gitImplementation string) (common.AuthSecretStrategy, error) {
|
type CheckoutStrategy interface {
|
||||||
switch gitImplementation {
|
Checkout(ctx context.Context, path, url string, auth *Auth) (Commit, string, error)
|
||||||
case sourcev1.GoGitImplementation:
|
}
|
||||||
return gogit.AuthSecretStrategyForURL(url)
|
|
||||||
case sourcev1.LibGit2Implementation:
|
// TODO(hidde): candidate for refactoring, so that we do not directly
|
||||||
return libgit2.AuthSecretStrategyForURL(url)
|
// depend on implementation specifics here.
|
||||||
default:
|
type Auth struct {
|
||||||
return nil, fmt.Errorf("invalid git implementation %s", gitImplementation)
|
AuthMethod transport.AuthMethod
|
||||||
}
|
CredCallback git2go.CredentialsCallback
|
||||||
|
CertCallback git2go.CertificateCheckCallback
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthSecretStrategy interface {
|
||||||
|
Method(secret corev1.Secret) (*Auth, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,19 +23,19 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Masterminds/semver/v3"
|
"github.com/Masterminds/semver/v3"
|
||||||
"github.com/go-git/go-git/v5"
|
extgogit "github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/version"
|
"github.com/fluxcd/pkg/version"
|
||||||
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef) common.CheckoutStrategy {
|
func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef) git.CheckoutStrategy {
|
||||||
switch {
|
switch {
|
||||||
case ref == nil:
|
case ref == nil:
|
||||||
return &CheckoutBranch{branch: common.DefaultBranch}
|
return &CheckoutBranch{branch: git.DefaultBranch}
|
||||||
case ref.SemVer != "":
|
case ref.SemVer != "":
|
||||||
return &CheckoutSemVer{semVer: ref.SemVer}
|
return &CheckoutSemVer{semVer: ref.SemVer}
|
||||||
case ref.Tag != "":
|
case ref.Tag != "":
|
||||||
|
@ -43,13 +43,13 @@ func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef) common.CheckoutStrat
|
||||||
case ref.Commit != "":
|
case ref.Commit != "":
|
||||||
strategy := &CheckoutCommit{branch: ref.Branch, commit: ref.Commit}
|
strategy := &CheckoutCommit{branch: ref.Branch, commit: ref.Commit}
|
||||||
if strategy.branch == "" {
|
if strategy.branch == "" {
|
||||||
strategy.branch = common.DefaultBranch
|
strategy.branch = git.DefaultBranch
|
||||||
}
|
}
|
||||||
return strategy
|
return strategy
|
||||||
case ref.Branch != "":
|
case ref.Branch != "":
|
||||||
return &CheckoutBranch{branch: ref.Branch}
|
return &CheckoutBranch{branch: ref.Branch}
|
||||||
default:
|
default:
|
||||||
return &CheckoutBranch{branch: common.DefaultBranch}
|
return &CheckoutBranch{branch: git.DefaultBranch}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,18 +57,18 @@ type CheckoutBranch struct {
|
||||||
branch string
|
branch string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth *common.Auth) (common.Commit, string, error) {
|
func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
|
||||||
repo, err := git.PlainCloneContext(ctx, path, false, &git.CloneOptions{
|
repo, err := extgogit.PlainCloneContext(ctx, path, false, &extgogit.CloneOptions{
|
||||||
URL: url,
|
URL: url,
|
||||||
Auth: auth.AuthMethod,
|
Auth: auth.AuthMethod,
|
||||||
RemoteName: common.DefaultOrigin,
|
RemoteName: git.DefaultOrigin,
|
||||||
ReferenceName: plumbing.NewBranchReferenceName(c.branch),
|
ReferenceName: plumbing.NewBranchReferenceName(c.branch),
|
||||||
SingleBranch: true,
|
SingleBranch: true,
|
||||||
NoCheckout: false,
|
NoCheckout: false,
|
||||||
Depth: 1,
|
Depth: 1,
|
||||||
RecurseSubmodules: 0,
|
RecurseSubmodules: 0,
|
||||||
Progress: nil,
|
Progress: nil,
|
||||||
Tags: git.NoTags,
|
Tags: extgogit.NoTags,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
|
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
|
||||||
|
@ -88,18 +88,18 @@ type CheckoutTag struct {
|
||||||
tag string
|
tag string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, auth *common.Auth) (common.Commit, string, error) {
|
func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
|
||||||
repo, err := git.PlainCloneContext(ctx, path, false, &git.CloneOptions{
|
repo, err := extgogit.PlainCloneContext(ctx, path, false, &extgogit.CloneOptions{
|
||||||
URL: url,
|
URL: url,
|
||||||
Auth: auth.AuthMethod,
|
Auth: auth.AuthMethod,
|
||||||
RemoteName: common.DefaultOrigin,
|
RemoteName: git.DefaultOrigin,
|
||||||
ReferenceName: plumbing.NewTagReferenceName(c.tag),
|
ReferenceName: plumbing.NewTagReferenceName(c.tag),
|
||||||
SingleBranch: true,
|
SingleBranch: true,
|
||||||
NoCheckout: false,
|
NoCheckout: false,
|
||||||
Depth: 1,
|
Depth: 1,
|
||||||
RecurseSubmodules: 0,
|
RecurseSubmodules: 0,
|
||||||
Progress: nil,
|
Progress: nil,
|
||||||
Tags: git.NoTags,
|
Tags: extgogit.NoTags,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
|
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
|
||||||
|
@ -120,17 +120,17 @@ type CheckoutCommit struct {
|
||||||
commit string
|
commit string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *common.Auth) (common.Commit, string, error) {
|
func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
|
||||||
repo, err := git.PlainCloneContext(ctx, path, false, &git.CloneOptions{
|
repo, err := extgogit.PlainCloneContext(ctx, path, false, &extgogit.CloneOptions{
|
||||||
URL: url,
|
URL: url,
|
||||||
Auth: auth.AuthMethod,
|
Auth: auth.AuthMethod,
|
||||||
RemoteName: common.DefaultOrigin,
|
RemoteName: git.DefaultOrigin,
|
||||||
ReferenceName: plumbing.NewBranchReferenceName(c.branch),
|
ReferenceName: plumbing.NewBranchReferenceName(c.branch),
|
||||||
SingleBranch: true,
|
SingleBranch: true,
|
||||||
NoCheckout: false,
|
NoCheckout: false,
|
||||||
RecurseSubmodules: 0,
|
RecurseSubmodules: 0,
|
||||||
Progress: nil,
|
Progress: nil,
|
||||||
Tags: git.NoTags,
|
Tags: extgogit.NoTags,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
|
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
|
||||||
|
@ -143,7 +143,7 @@ func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *c
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("git commit '%s' not found: %w", c.commit, err)
|
return nil, "", fmt.Errorf("git commit '%s' not found: %w", c.commit, err)
|
||||||
}
|
}
|
||||||
err = w.Checkout(&git.CheckoutOptions{
|
err = w.Checkout(&extgogit.CheckoutOptions{
|
||||||
Hash: commit.Hash,
|
Hash: commit.Hash,
|
||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
|
@ -157,21 +157,21 @@ type CheckoutSemVer struct {
|
||||||
semVer string
|
semVer string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth *common.Auth) (common.Commit, string, error) {
|
func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
|
||||||
verConstraint, err := semver.NewConstraint(c.semVer)
|
verConstraint, err := semver.NewConstraint(c.semVer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("semver parse range error: %w", err)
|
return nil, "", fmt.Errorf("semver parse range error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := git.PlainCloneContext(ctx, path, false, &git.CloneOptions{
|
repo, err := extgogit.PlainCloneContext(ctx, path, false, &extgogit.CloneOptions{
|
||||||
URL: url,
|
URL: url,
|
||||||
Auth: auth.AuthMethod,
|
Auth: auth.AuthMethod,
|
||||||
RemoteName: common.DefaultOrigin,
|
RemoteName: git.DefaultOrigin,
|
||||||
NoCheckout: false,
|
NoCheckout: false,
|
||||||
Depth: 1,
|
Depth: 1,
|
||||||
RecurseSubmodules: 0,
|
RecurseSubmodules: 0,
|
||||||
Progress: nil,
|
Progress: nil,
|
||||||
Tags: git.AllTags,
|
Tags: extgogit.AllTags,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
|
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
|
||||||
|
@ -238,7 +238,7 @@ func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth *c
|
||||||
return nil, "", fmt.Errorf("git worktree error: %w", err)
|
return nil, "", fmt.Errorf("git worktree error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w.Checkout(&git.CheckoutOptions{
|
err = w.Checkout(&extgogit.CheckoutOptions{
|
||||||
Branch: plumbing.NewTagReferenceName(t),
|
Branch: plumbing.NewTagReferenceName(t),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -22,11 +22,11 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCheckoutTagSemVer_Checkout(t *testing.T) {
|
func TestCheckoutTagSemVer_Checkout(t *testing.T) {
|
||||||
auth := &common.Auth{}
|
auth := &git.Auth{}
|
||||||
tag := CheckoutTag{
|
tag := CheckoutTag{
|
||||||
tag: "v1.7.0",
|
tag: "v1.7.0",
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,10 @@ import (
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/ssh/knownhosts"
|
"github.com/fluxcd/pkg/ssh/knownhosts"
|
||||||
|
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AuthSecretStrategyForURL(URL string) (common.AuthSecretStrategy, error) {
|
func AuthSecretStrategyForURL(URL string) (git.AuthSecretStrategy, error) {
|
||||||
u, err := url.Parse(URL)
|
u, err := url.Parse(URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse URL to determine auth strategy: %w", err)
|
return nil, fmt.Errorf("failed to parse URL to determine auth strategy: %w", err)
|
||||||
|
@ -47,8 +47,8 @@ func AuthSecretStrategyForURL(URL string) (common.AuthSecretStrategy, error) {
|
||||||
|
|
||||||
type BasicAuth struct{}
|
type BasicAuth struct{}
|
||||||
|
|
||||||
func (s *BasicAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
func (s *BasicAuth) Method(secret corev1.Secret) (*git.Auth, error) {
|
||||||
if _, ok := secret.Data[common.CAFile]; ok {
|
if _, ok := secret.Data[git.CAFile]; ok {
|
||||||
return nil, fmt.Errorf("found caFile key in secret '%s' but go-git HTTP transport does not support custom certificates", secret.Name)
|
return nil, fmt.Errorf("found caFile key in secret '%s' but go-git HTTP transport does not support custom certificates", secret.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,18 +62,17 @@ func (s *BasicAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
||||||
if auth.Username == "" || auth.Password == "" {
|
if auth.Username == "" || auth.Password == "" {
|
||||||
return nil, fmt.Errorf("invalid '%s' secret data: required fields 'username' and 'password'", secret.Name)
|
return nil, fmt.Errorf("invalid '%s' secret data: required fields 'username' and 'password'", secret.Name)
|
||||||
}
|
}
|
||||||
return &common.Auth{AuthMethod: auth}, nil
|
return &git.Auth{AuthMethod: auth}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublicKeyAuth struct {
|
type PublicKeyAuth struct {
|
||||||
user string
|
user string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
func (s *PublicKeyAuth) Method(secret corev1.Secret) (*git.Auth, error) {
|
||||||
if _, ok := secret.Data[common.CAFile]; ok {
|
if _, ok := secret.Data[git.CAFile]; ok {
|
||||||
return nil, fmt.Errorf("found caFile key in secret '%s' but go-git SSH transport does not support custom certificates", secret.Name)
|
return nil, fmt.Errorf("found caFile key in secret '%s' but go-git SSH transport does not support custom certificates", secret.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
identity := secret.Data["identity"]
|
identity := secret.Data["identity"]
|
||||||
knownHosts := secret.Data["known_hosts"]
|
knownHosts := secret.Data["known_hosts"]
|
||||||
if len(identity) == 0 || len(knownHosts) == 0 {
|
if len(identity) == 0 || len(knownHosts) == 0 {
|
||||||
|
@ -82,7 +81,7 @@ func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
||||||
|
|
||||||
user := s.user
|
user := s.user
|
||||||
if user == "" {
|
if user == "" {
|
||||||
user = common.DefaultPublicKeyAuthUser
|
user = git.DefaultPublicKeyAuthUser
|
||||||
}
|
}
|
||||||
|
|
||||||
pk, err := ssh.NewPublicKeys(user, identity, "")
|
pk, err := ssh.NewPublicKeys(user, identity, "")
|
||||||
|
@ -95,5 +94,5 @@ func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pk.HostKeyCallback = callback
|
pk.HostKeyCallback = callback
|
||||||
return &common.Auth{AuthMethod: pk}, nil
|
return &git.Auth{AuthMethod: pk}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport/http"
|
"github.com/go-git/go-git/v5/plumbing/transport/http"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -69,7 +69,7 @@ func TestAuthSecretStrategyForURL(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
url string
|
url string
|
||||||
want common.AuthSecretStrategy
|
want git.AuthSecretStrategy
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{"HTTP", "http://git.example.com/org/repo.git", &BasicAuth{}, false},
|
{"HTTP", "http://git.example.com/org/repo.git", &BasicAuth{}, false},
|
||||||
|
@ -97,10 +97,10 @@ func TestBasicAuthStrategy_Method(t *testing.T) {
|
||||||
name string
|
name string
|
||||||
secret corev1.Secret
|
secret corev1.Secret
|
||||||
modify func(secret *corev1.Secret)
|
modify func(secret *corev1.Secret)
|
||||||
want *common.Auth
|
want *git.Auth
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{"username and password", basicAuthSecretFixture, nil, &common.Auth{AuthMethod: &http.BasicAuth{Username: "git", Password: "password"}}, false},
|
{"username and password", basicAuthSecretFixture, nil, &git.Auth{AuthMethod: &http.BasicAuth{Username: "git", Password: "password"}}, false},
|
||||||
{"without username", basicAuthSecretFixture, func(s *corev1.Secret) { delete(s.Data, "username") }, nil, true},
|
{"without username", basicAuthSecretFixture, func(s *corev1.Secret) { delete(s.Data, "username") }, nil, true},
|
||||||
{"without password", basicAuthSecretFixture, func(s *corev1.Secret) { delete(s.Data, "password") }, nil, true},
|
{"without password", basicAuthSecretFixture, func(s *corev1.Secret) { delete(s.Data, "password") }, nil, true},
|
||||||
{"empty", corev1.Secret{}, nil, nil, true},
|
{"empty", corev1.Secret{}, nil, nil, true},
|
||||||
|
|
|
@ -24,13 +24,13 @@ import (
|
||||||
git2go "github.com/libgit2/git2go/v31"
|
git2go "github.com/libgit2/git2go/v31"
|
||||||
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef) common.CheckoutStrategy {
|
func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef) git.CheckoutStrategy {
|
||||||
switch {
|
switch {
|
||||||
case ref == nil:
|
case ref == nil:
|
||||||
return &CheckoutBranch{branch: common.DefaultBranch}
|
return &CheckoutBranch{branch: git.DefaultBranch}
|
||||||
case ref.SemVer != "":
|
case ref.SemVer != "":
|
||||||
return &CheckoutSemVer{semVer: ref.SemVer}
|
return &CheckoutSemVer{semVer: ref.SemVer}
|
||||||
case ref.Tag != "":
|
case ref.Tag != "":
|
||||||
|
@ -38,13 +38,13 @@ func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef) common.CheckoutStrat
|
||||||
case ref.Commit != "":
|
case ref.Commit != "":
|
||||||
strategy := &CheckoutCommit{branch: ref.Branch, commit: ref.Commit}
|
strategy := &CheckoutCommit{branch: ref.Branch, commit: ref.Commit}
|
||||||
if strategy.branch == "" {
|
if strategy.branch == "" {
|
||||||
strategy.branch = common.DefaultBranch
|
strategy.branch = git.DefaultBranch
|
||||||
}
|
}
|
||||||
return strategy
|
return strategy
|
||||||
case ref.Branch != "":
|
case ref.Branch != "":
|
||||||
return &CheckoutBranch{branch: ref.Branch}
|
return &CheckoutBranch{branch: ref.Branch}
|
||||||
default:
|
default:
|
||||||
return &CheckoutBranch{branch: common.DefaultBranch}
|
return &CheckoutBranch{branch: git.DefaultBranch}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ type CheckoutBranch struct {
|
||||||
branch string
|
branch string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth *common.Auth) (common.Commit, string, error) {
|
func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
|
||||||
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
|
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
|
||||||
FetchOptions: &git2go.FetchOptions{
|
FetchOptions: &git2go.FetchOptions{
|
||||||
DownloadTags: git2go.DownloadTagsNone,
|
DownloadTags: git2go.DownloadTagsNone,
|
||||||
|
@ -81,7 +81,7 @@ type CheckoutTag struct {
|
||||||
tag string
|
tag string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, auth *common.Auth) (common.Commit, string, error) {
|
func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
|
||||||
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
|
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
|
||||||
FetchOptions: &git2go.FetchOptions{
|
FetchOptions: &git2go.FetchOptions{
|
||||||
DownloadTags: git2go.DownloadTagsAll,
|
DownloadTags: git2go.DownloadTagsAll,
|
||||||
|
@ -118,7 +118,7 @@ type CheckoutCommit struct {
|
||||||
commit string
|
commit string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *common.Auth) (common.Commit, string, error) {
|
func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
|
||||||
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
|
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
|
||||||
FetchOptions: &git2go.FetchOptions{
|
FetchOptions: &git2go.FetchOptions{
|
||||||
DownloadTags: git2go.DownloadTagsNone,
|
DownloadTags: git2go.DownloadTagsNone,
|
||||||
|
@ -158,7 +158,7 @@ type CheckoutSemVer struct {
|
||||||
semVer string
|
semVer string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth *common.Auth) (common.Commit, string, error) {
|
func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
|
||||||
rng, err := semver.ParseRange(c.semVer)
|
rng, err := semver.ParseRange(c.semVer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("semver parse range error: %w", err)
|
return nil, "", fmt.Errorf("semver parse range error: %w", err)
|
||||||
|
|
|
@ -22,15 +22,16 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
|
||||||
git2go "github.com/libgit2/git2go/v31"
|
git2go "github.com/libgit2/git2go/v31"
|
||||||
|
|
||||||
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCheckoutTagSemVer_Checkout(t *testing.T) {
|
func TestCheckoutTagSemVer_Checkout(t *testing.T) {
|
||||||
certCallback := func(cert *git2go.Certificate, valid bool, hostname string) git2go.ErrorCode {
|
certCallback := func(cert *git2go.Certificate, valid bool, hostname string) git2go.ErrorCode {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
auth := &common.Auth{CertCallback: certCallback}
|
auth := &git.Auth{CertCallback: certCallback}
|
||||||
|
|
||||||
tag := CheckoutTag{
|
tag := CheckoutTag{
|
||||||
tag: "v1.7.0",
|
tag: "v1.7.0",
|
||||||
|
|
|
@ -30,10 +30,10 @@ import (
|
||||||
git2go "github.com/libgit2/git2go/v31"
|
git2go "github.com/libgit2/git2go/v31"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AuthSecretStrategyForURL(URL string) (common.AuthSecretStrategy, error) {
|
func AuthSecretStrategyForURL(URL string) (git.AuthSecretStrategy, error) {
|
||||||
u, err := url.Parse(URL)
|
u, err := url.Parse(URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse URL to determine auth strategy: %w", err)
|
return nil, fmt.Errorf("failed to parse URL to determine auth strategy: %w", err)
|
||||||
|
@ -51,7 +51,7 @@ func AuthSecretStrategyForURL(URL string) (common.AuthSecretStrategy, error) {
|
||||||
|
|
||||||
type BasicAuth struct{}
|
type BasicAuth struct{}
|
||||||
|
|
||||||
func (s *BasicAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
func (s *BasicAuth) Method(secret corev1.Secret) (*git.Auth, error) {
|
||||||
var credCallback git2go.CredentialsCallback
|
var credCallback git2go.CredentialsCallback
|
||||||
var username string
|
var username string
|
||||||
if d, ok := secret.Data["username"]; ok {
|
if d, ok := secret.Data["username"]; ok {
|
||||||
|
@ -72,7 +72,7 @@ func (s *BasicAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var certCallback git2go.CertificateCheckCallback
|
var certCallback git2go.CertificateCheckCallback
|
||||||
if caFile, ok := secret.Data[common.CAFile]; ok {
|
if caFile, ok := secret.Data[git.CAFile]; ok {
|
||||||
certCallback = func(cert *git2go.Certificate, valid bool, hostname string) git2go.ErrorCode {
|
certCallback = func(cert *git2go.Certificate, valid bool, hostname string) git2go.ErrorCode {
|
||||||
roots := x509.NewCertPool()
|
roots := x509.NewCertPool()
|
||||||
ok := roots.AppendCertsFromPEM(caFile)
|
ok := roots.AppendCertsFromPEM(caFile)
|
||||||
|
@ -92,18 +92,17 @@ func (s *BasicAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &common.Auth{CredCallback: credCallback, CertCallback: certCallback}, nil
|
return &git.Auth{CredCallback: credCallback, CertCallback: certCallback}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublicKeyAuth struct {
|
type PublicKeyAuth struct {
|
||||||
user string
|
user string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
func (s *PublicKeyAuth) Method(secret corev1.Secret) (*git.Auth, error) {
|
||||||
if _, ok := secret.Data[common.CAFile]; ok {
|
if _, ok := secret.Data[git.CAFile]; ok {
|
||||||
return nil, fmt.Errorf("found caFile key in secret '%s' but libgit2 SSH transport does not support custom certificates", secret.Name)
|
return nil, fmt.Errorf("found caFile key in secret '%s' but libgit2 SSH transport does not support custom certificates", secret.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
identity := secret.Data["identity"]
|
identity := secret.Data["identity"]
|
||||||
knownHosts := secret.Data["known_hosts"]
|
knownHosts := secret.Data["known_hosts"]
|
||||||
if len(identity) == 0 || len(knownHosts) == 0 {
|
if len(identity) == 0 || len(knownHosts) == 0 {
|
||||||
|
@ -124,7 +123,7 @@ func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
||||||
|
|
||||||
user := s.user
|
user := s.user
|
||||||
if user == "" {
|
if user == "" {
|
||||||
user = common.DefaultPublicKeyAuthUser
|
user = git.DefaultPublicKeyAuthUser
|
||||||
}
|
}
|
||||||
|
|
||||||
credCallback := func(url string, username_from_url string, allowed_types git2go.CredType) (*git2go.Cred, error) {
|
credCallback := func(url string, username_from_url string, allowed_types git2go.CredType) (*git2go.Cred, error) {
|
||||||
|
@ -143,7 +142,7 @@ func (s *PublicKeyAuth) Method(secret corev1.Secret) (*common.Auth, error) {
|
||||||
return git2go.ErrGeneric
|
return git2go.ErrGeneric
|
||||||
}
|
}
|
||||||
|
|
||||||
return &common.Auth{CredCallback: credCallback, CertCallback: certCallback}, nil
|
return &git.Auth{CredCallback: credCallback, CertCallback: certCallback}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type knownKey struct {
|
type knownKey struct {
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
"github.com/fluxcd/source-controller/pkg/git/common"
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -68,7 +68,7 @@ func TestAuthSecretStrategyForURL(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
url string
|
url string
|
||||||
want common.AuthSecretStrategy
|
want git.AuthSecretStrategy
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{"HTTP", "http://git.example.com/org/repo.git", &BasicAuth{}, false},
|
{"HTTP", "http://git.example.com/org/repo.git", &BasicAuth{}, false},
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 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 strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
|
"github.com/fluxcd/source-controller/pkg/git"
|
||||||
|
"github.com/fluxcd/source-controller/pkg/git/gogit"
|
||||||
|
"github.com/fluxcd/source-controller/pkg/git/libgit2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef, gitImplementation string) (git.CheckoutStrategy, error) {
|
||||||
|
switch gitImplementation {
|
||||||
|
case sourcev1.GoGitImplementation:
|
||||||
|
return gogit.CheckoutStrategyForRef(ref), nil
|
||||||
|
case sourcev1.LibGit2Implementation:
|
||||||
|
return libgit2.CheckoutStrategyForRef(ref), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid git implementation %s", gitImplementation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AuthSecretStrategyForURL(url string, gitImplementation string) (git.AuthSecretStrategy, error) {
|
||||||
|
switch gitImplementation {
|
||||||
|
case sourcev1.GoGitImplementation:
|
||||||
|
return gogit.AuthSecretStrategyForURL(url)
|
||||||
|
case sourcev1.LibGit2Implementation:
|
||||||
|
return libgit2.AuthSecretStrategyForURL(url)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid git implementation %s", gitImplementation)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue