Merge "Add implementation of document/repo interface"
This commit is contained in:
commit
ad9ee69cce
@ -821,8 +821,9 @@ func (m *Manifest) Equal(n *Manifest) bool {
|
||||
if n == nil {
|
||||
return n == m
|
||||
}
|
||||
repositoryEq := reflect.DeepEqual(m.Repositories, n.Repositories)
|
||||
return repositoryEq && m.TargetPath == n.TargetPath
|
||||
repositoryEq := reflect.DeepEqual(m.Repository, n.Repository)
|
||||
extraReposEq := reflect.DeepEqual(m.ExtraRepositories, n.ExtraRepositories)
|
||||
return repositoryEq && extraReposEq && m.TargetPath == n.TargetPath
|
||||
}
|
||||
|
||||
func (m *Manifest) String() string {
|
||||
@ -833,30 +834,6 @@ func (m *Manifest) String() string {
|
||||
return string(yamlData)
|
||||
}
|
||||
|
||||
// Repository functions
|
||||
func (r *Repository) Equal(s *Repository) bool {
|
||||
if s == nil {
|
||||
return r == s
|
||||
}
|
||||
var urlMatches bool
|
||||
if r.Url != nil && s.Url != nil {
|
||||
urlMatches = r.Url.String() == s.Url.String()
|
||||
} else {
|
||||
// this catches cases where one or both are nil
|
||||
urlMatches = r.Url == s.Url
|
||||
}
|
||||
return urlMatches &&
|
||||
r.Username == s.Username &&
|
||||
r.TargetPath == s.TargetPath
|
||||
}
|
||||
func (r *Repository) String() string {
|
||||
yamlData, err := yaml.Marshal(&r)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(yamlData)
|
||||
}
|
||||
|
||||
// Modules functions
|
||||
func (m *Modules) Equal(n *Modules) bool {
|
||||
if n == nil {
|
||||
|
@ -68,6 +68,14 @@ func TestString(t *testing.T) {
|
||||
name: "repository",
|
||||
stringer: DummyRepository(),
|
||||
},
|
||||
{
|
||||
name: "repo-auth",
|
||||
stringer: DummyRepoAuth(),
|
||||
},
|
||||
{
|
||||
name: "repo-checkout",
|
||||
stringer: DummyRepoCheckout(),
|
||||
},
|
||||
{
|
||||
name: "bootstrap",
|
||||
stringer: DummyBootstrap(),
|
||||
@ -157,12 +165,28 @@ func TestEqual(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("repository-equal", func(t *testing.T) {
|
||||
testRepository1 := &Repository{TargetPath: "same"}
|
||||
testRepository2 := &Repository{TargetPath: "different"}
|
||||
testRepository1 := &Repository{URLString: "same"}
|
||||
testRepository2 := &Repository{URLString: "different"}
|
||||
assert.True(t, testRepository1.Equal(testRepository1))
|
||||
assert.False(t, testRepository1.Equal(testRepository2))
|
||||
assert.False(t, testRepository1.Equal(nil))
|
||||
})
|
||||
t.Run("auth-equal", func(t *testing.T) {
|
||||
testSpec1 := &RepoAuth{}
|
||||
testSpec2 := &RepoAuth{}
|
||||
testSpec2.Type = "ssh-key"
|
||||
assert.True(t, testSpec1.Equal(testSpec1))
|
||||
assert.False(t, testSpec1.Equal(testSpec2))
|
||||
assert.False(t, testSpec1.Equal(nil))
|
||||
})
|
||||
t.Run("checkout-equal", func(t *testing.T) {
|
||||
testSpec1 := &RepoCheckout{}
|
||||
testSpec2 := &RepoCheckout{}
|
||||
testSpec2.Branch = "Master"
|
||||
assert.True(t, testSpec1.Equal(testSpec1))
|
||||
assert.False(t, testSpec1.Equal(testSpec2))
|
||||
assert.False(t, testSpec1.Equal(nil))
|
||||
})
|
||||
|
||||
t.Run("modules-equal", func(t *testing.T) {
|
||||
testModules1 := NewModules()
|
||||
|
@ -2,8 +2,54 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Repo errors
|
||||
|
||||
// ErrMutuallyExclusiveAuthSSHPass is returned when ssh-pass type
|
||||
// is selected and http-pass, ssh-key or key-pass options are defined
|
||||
type ErrIncompatibleAuthOptions struct {
|
||||
ForbiddenOptions []string
|
||||
AuthType string
|
||||
}
|
||||
|
||||
func NewErrIncompetibleAuthOptions(fo []string, ao string) error {
|
||||
return ErrIncompatibleAuthOptions{
|
||||
ForbiddenOptions: fo,
|
||||
AuthType: ao,
|
||||
}
|
||||
}
|
||||
|
||||
func (e ErrIncompatibleAuthOptions) Error() string {
|
||||
return fmt.Sprintf("Can not use %s options, with auth type %s", e.ForbiddenOptions, e.AuthType)
|
||||
}
|
||||
|
||||
// ErrAuthTypeNotSupported is returned with wrong AuthType is provided
|
||||
type ErrAuthTypeNotSupported struct {
|
||||
}
|
||||
|
||||
func (e ErrAuthTypeNotSupported) Error() string {
|
||||
return "Invalid auth, allowed types: " + strings.Join(AllowedAuthTypes, ",")
|
||||
}
|
||||
|
||||
// ErrRepoSpecRequiresURL is returned when repository URL is not specified
|
||||
type ErrRepoSpecRequiresURL struct {
|
||||
}
|
||||
|
||||
func (e ErrRepoSpecRequiresURL) Error() string {
|
||||
return "Repostory spec requires url"
|
||||
}
|
||||
|
||||
// ErrMutuallyExclusiveCheckout is returned if
|
||||
// mutually exclusive options are given as checkout options
|
||||
type ErrMutuallyExclusiveCheckout struct {
|
||||
}
|
||||
|
||||
func (e ErrMutuallyExclusiveCheckout) Error() string {
|
||||
return "Chekout mutually execlusive, use either: commit-hash, branch or tag"
|
||||
}
|
||||
|
||||
// ErrBootstrapInfoNotFound returned if bootstrap
|
||||
// information is not found for cluster
|
||||
type ErrBootstrapInfoNotFound struct {
|
||||
|
202
pkg/config/repo.go
Normal file
202
pkg/config/repo.go
Normal file
@ -0,0 +1,202 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/transport"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
SSHAuth = "ssh-key"
|
||||
SSHPass = "ssh-pass"
|
||||
HTTPBasic = "http-basic"
|
||||
)
|
||||
|
||||
// RepoCheckout methods
|
||||
|
||||
func (c *RepoCheckout) Equal(s *RepoCheckout) bool {
|
||||
if s == nil {
|
||||
return s == c
|
||||
}
|
||||
return c.CommitHash == s.CommitHash &&
|
||||
c.Branch == s.Branch &&
|
||||
c.Tag == s.Tag &&
|
||||
c.RemoteRef == s.RemoteRef
|
||||
}
|
||||
|
||||
func (r *RepoCheckout) String() string {
|
||||
yaml, err := yaml.Marshal(&r)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(yaml)
|
||||
}
|
||||
|
||||
func (c *RepoCheckout) Validate() error {
|
||||
possibleValues := []string{c.CommitHash, c.Branch, c.Tag, c.RemoteRef}
|
||||
var count int
|
||||
for _, val := range possibleValues {
|
||||
if val != "" {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count > 1 {
|
||||
return ErrMutuallyExclusiveCheckout{}
|
||||
}
|
||||
if c.RemoteRef != "" {
|
||||
return fmt.Errorf("Repository checkout by RemoteRef is not yet implemented\n%w", errors.ErrNotImplemented{})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RepoAuth methods
|
||||
var (
|
||||
AllowedAuthTypes = []string{SSHAuth, SSHPass, HTTPBasic}
|
||||
)
|
||||
|
||||
func (auth *RepoAuth) Equal(s *RepoAuth) bool {
|
||||
if s == nil {
|
||||
return s == auth
|
||||
}
|
||||
return auth.Type == s.Type &&
|
||||
auth.KeyPassword == s.KeyPassword &&
|
||||
auth.KeyPath == s.KeyPath &&
|
||||
auth.SSHPassword == s.SSHPassword &&
|
||||
auth.Username == s.Username
|
||||
}
|
||||
|
||||
func (r *RepoAuth) String() string {
|
||||
yaml, err := yaml.Marshal(&r)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(yaml)
|
||||
}
|
||||
|
||||
func (auth *RepoAuth) Validate() error {
|
||||
if !stringInSlice(auth.Type, AllowedAuthTypes) {
|
||||
return ErrAuthTypeNotSupported{}
|
||||
}
|
||||
|
||||
switch auth.Type {
|
||||
case SSHAuth:
|
||||
if auth.HTTPPassword != "" || auth.SSHPassword != "" {
|
||||
return NewErrIncompetibleAuthOptions([]string{"http-pass, ssh-pass"}, auth.Type)
|
||||
}
|
||||
case HTTPBasic:
|
||||
if auth.SSHPassword != "" || auth.KeyPath != "" || auth.KeyPassword != "" {
|
||||
return NewErrIncompetibleAuthOptions([]string{"ssh-pass, ssh-key, key-pass"}, auth.Type)
|
||||
}
|
||||
case SSHPass:
|
||||
if auth.KeyPath != "" || auth.KeyPassword != "" || auth.HTTPPassword != "" {
|
||||
return NewErrIncompetibleAuthOptions([]string{"ssh-key, key-pass, http-pass"}, auth.Type)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stringInSlice(a string, list []string) bool {
|
||||
for _, b := range list {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Repository functions
|
||||
// Equal compares repository specs
|
||||
func (repo *Repository) Equal(s *Repository) bool {
|
||||
if s == nil {
|
||||
return s == repo
|
||||
}
|
||||
|
||||
return repo.URLString == s.URLString &&
|
||||
reflect.DeepEqual(s.Auth, repo.Auth) &&
|
||||
reflect.DeepEqual(s.CheckoutOptions, repo.CheckoutOptions)
|
||||
}
|
||||
|
||||
func (r *Repository) String() string {
|
||||
yaml, err := yaml.Marshal(&r)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(yaml)
|
||||
}
|
||||
|
||||
func (spec *Repository) Validate() error {
|
||||
if spec.URLString == "" {
|
||||
return ErrRepoSpecRequiresURL{}
|
||||
}
|
||||
|
||||
if spec.Auth != nil {
|
||||
err := spec.Auth.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if spec.CheckoutOptions != nil {
|
||||
err := spec.CheckoutOptions.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *Repository) ToAuth() (transport.AuthMethod, error) {
|
||||
if repo.Auth == nil {
|
||||
return nil, nil
|
||||
}
|
||||
switch repo.Auth.Type {
|
||||
case SSHAuth:
|
||||
return ssh.NewPublicKeysFromFile(repo.Auth.Username, repo.Auth.KeyPath, repo.Auth.KeyPassword)
|
||||
case SSHPass:
|
||||
return &ssh.Password{User: repo.Auth.Username, Password: repo.Auth.HTTPPassword}, nil
|
||||
case HTTPBasic:
|
||||
return &http.BasicAuth{Username: repo.Auth.Username, Password: repo.Auth.HTTPPassword}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Error building auth opts, repo\n%s\n: %w", repo.String(), errors.ErrNotImplemented{})
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *Repository) ToCheckoutOptions(force bool) *git.CheckoutOptions {
|
||||
co := &git.CheckoutOptions{
|
||||
Force: force,
|
||||
}
|
||||
switch {
|
||||
case repo.CheckoutOptions == nil:
|
||||
case repo.CheckoutOptions.Branch != "":
|
||||
co.Branch = plumbing.NewBranchReferenceName(repo.CheckoutOptions.Branch)
|
||||
case repo.CheckoutOptions.Tag != "":
|
||||
co.Branch = plumbing.NewTagReferenceName(repo.CheckoutOptions.Tag)
|
||||
case repo.CheckoutOptions.CommitHash != "":
|
||||
co.Hash = plumbing.NewHash(repo.CheckoutOptions.CommitHash)
|
||||
}
|
||||
return co
|
||||
}
|
||||
|
||||
func (repo *Repository) ToCloneOptions(auth transport.AuthMethod) *git.CloneOptions {
|
||||
return &git.CloneOptions{
|
||||
Auth: auth,
|
||||
URL: repo.URLString,
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *Repository) ToFetchOptions(auth transport.AuthMethod) *git.FetchOptions {
|
||||
return &git.FetchOptions{Auth: auth}
|
||||
}
|
||||
|
||||
func (repo *Repository) URL() string {
|
||||
return repo.URLString
|
||||
}
|
261
pkg/config/repo_test.go
Normal file
261
pkg/config/repo_test.go
Normal file
@ -0,0 +1,261 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
validateTestName = "ToCheckout"
|
||||
validateFailuresTestName = "Validate"
|
||||
toAuthTestName = "ToAuth"
|
||||
toAuthNilTestName = "ToAuthNil"
|
||||
ToFetchOptionsTestName = "ToFetchOptions"
|
||||
toAuthNilError = "toAuthNilError"
|
||||
URLTestName = "URLTest"
|
||||
StringTestData = `test-data:
|
||||
no-auth:
|
||||
url: https://github.com/src-d/go-git.git
|
||||
checkout:
|
||||
tag: v3.0.0
|
||||
ssh-key-auth:
|
||||
url: git@github.com:src-d/go-git.git
|
||||
auth:
|
||||
type: ssh-key
|
||||
ssh-key: "testdata/test-key.pem"
|
||||
username: git
|
||||
checkout:
|
||||
branch: master
|
||||
ssh-pass:
|
||||
url: /home/ubuntu/some-gitrepo
|
||||
auth:
|
||||
type: ssh-pass
|
||||
ssh-pass: "qwerty123"
|
||||
username: deployer
|
||||
checkout:
|
||||
commit-hash: 01c4f7f32beb9851ae8f119a6b8e497d2b1e2bb8
|
||||
http-basic-auth:
|
||||
url: /home/ubuntu/some-gitrepo
|
||||
auth:
|
||||
type: http-basic
|
||||
http-pass: "qwerty123"
|
||||
username: deployer
|
||||
checkout:
|
||||
commit-hash: 01c4f7f32beb9851ae8f119a6b8e497d2b1e2bb8
|
||||
empty-checkout:
|
||||
url: /home/ubuntu/some-gitrepo
|
||||
auth:
|
||||
type: http-basic
|
||||
http-pass: "qwerty123"
|
||||
username: deployer
|
||||
wrong-type-auth:
|
||||
url: /home/ubuntu/some-gitrepo
|
||||
auth:
|
||||
type: wrong-type
|
||||
http-pass: "qwerty123"
|
||||
username: deployer
|
||||
checkout:
|
||||
commit-hash: 01c4f7f32beb9851ae8f119a6b8e497d2b1e2bb8
|
||||
mutually-exclusive-auth-opts:
|
||||
url: /home/ubuntu/some-gitrepo
|
||||
auth:
|
||||
type: http-basic
|
||||
ssh-key: "/path-to-key"
|
||||
username: deployer
|
||||
mutually-exclusive-checkout-opts:
|
||||
url: /home/ubuntu/some-gitrepo
|
||||
checkout:
|
||||
commit-hash: 01c4f7f32beb9851ae8f119a6b8e497d2b1e2bb8
|
||||
branch: master
|
||||
mutually-exclusive-auth-opts-ssh-key:
|
||||
url: /home/ubuntu/some-gitrepo
|
||||
auth:
|
||||
type: ssh-key
|
||||
http-pass: "qwerty123"
|
||||
ssh-key: "/path-to-key"
|
||||
username: deployer
|
||||
checkout:
|
||||
commit-hash: 01c4f7f32beb9851ae8f119a6b8e497d2b1e2bb8
|
||||
mutually-exclusive-auth-opts-ssh-pass:
|
||||
url: /home/ubuntu/some-gitrepo
|
||||
auth:
|
||||
type: ssh-pass
|
||||
ssh-pass: "qwerty123"
|
||||
http-pass: "qwerty123"
|
||||
ssh-key: "/path-to-key"
|
||||
username: deployer
|
||||
checkout:
|
||||
commit-hash: 01c4f7f32beb9851ae8f119a6b8e497d2b1e2bb8`
|
||||
)
|
||||
|
||||
var (
|
||||
TestCaseMap = map[string]*TestCase{
|
||||
validateTestName: {
|
||||
expectError: false,
|
||||
dataMapEntry: []string{"http-basic-auth", "ssh-key-auth", "no-auth", "empty-checkout"},
|
||||
expectedNil: false,
|
||||
},
|
||||
validateFailuresTestName: {
|
||||
expectError: true,
|
||||
dataMapEntry: []string{"wrong-type-auth",
|
||||
"mutually-exclusive-auth-opts",
|
||||
"mutually-exclusive-checkout-opts",
|
||||
"mutually-exclusive-auth-opts-ssh-key",
|
||||
"mutually-exclusive-auth-opts-ssh-pass"},
|
||||
expectedNil: false,
|
||||
},
|
||||
toAuthTestName: {
|
||||
expectError: false,
|
||||
dataMapEntry: []string{"ssh-key-auth",
|
||||
"http-basic-auth",
|
||||
"ssh-pass"},
|
||||
|
||||
expectedNil: false,
|
||||
},
|
||||
toAuthNilError: {
|
||||
expectError: true,
|
||||
dataMapEntry: []string{"wrong-type-auth"},
|
||||
expectedNil: true,
|
||||
},
|
||||
toAuthNilTestName: {
|
||||
expectError: false,
|
||||
dataMapEntry: []string{"no-auth"},
|
||||
expectedNil: true,
|
||||
},
|
||||
ToFetchOptionsTestName: {
|
||||
expectError: false,
|
||||
dataMapEntry: []string{"no-auth"},
|
||||
expectedNil: false,
|
||||
},
|
||||
URLTestName: {
|
||||
expectError: false,
|
||||
expectedNil: false,
|
||||
dataMapEntry: []string{"no-auth"},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type TestCase struct {
|
||||
expectError bool
|
||||
// this maps to TestData map in TestRepos struct
|
||||
dataMapEntry []string
|
||||
expectedNil bool
|
||||
}
|
||||
|
||||
type TestRepos struct {
|
||||
TestData map[string]*Repository `json:"test-data"`
|
||||
}
|
||||
|
||||
func TestToCheckout(t *testing.T) {
|
||||
data := &TestRepos{}
|
||||
err := yaml.Unmarshal([]byte(StringTestData), data)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCase := TestCaseMap[validateTestName]
|
||||
|
||||
for _, name := range testCase.dataMapEntry {
|
||||
repo := data.TestData[name]
|
||||
require.NotNil(t, repo)
|
||||
co := repo.ToCheckoutOptions(false)
|
||||
if testCase.expectedNil {
|
||||
assert.Nil(t, co)
|
||||
} else {
|
||||
assert.NotNil(t, co)
|
||||
assert.NoError(t, co.Validate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestToAuth(t *testing.T) {
|
||||
data := &TestRepos{}
|
||||
err := yaml.Unmarshal([]byte(StringTestData), data)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, testCaseName := range []string{toAuthTestName, toAuthNilTestName, toAuthNilError} {
|
||||
testCase := TestCaseMap[testCaseName]
|
||||
for _, name := range testCase.dataMapEntry {
|
||||
repo := data.TestData[name]
|
||||
auth, authErr := repo.ToAuth()
|
||||
if testCase.expectError {
|
||||
assert.Error(t, authErr)
|
||||
} else {
|
||||
assert.NoError(t, authErr)
|
||||
}
|
||||
if testCase.expectedNil {
|
||||
assert.Nil(t, auth)
|
||||
} else {
|
||||
assert.NotNil(t, auth)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateRepository(t *testing.T) {
|
||||
data := &TestRepos{}
|
||||
err := yaml.Unmarshal([]byte(StringTestData), data)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, testCaseName := range []string{validateTestName, validateFailuresTestName} {
|
||||
testCase := TestCaseMap[testCaseName]
|
||||
for _, name := range testCase.dataMapEntry {
|
||||
repo := data.TestData[name]
|
||||
err := repo.Validate()
|
||||
if testCase.expectError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
if testCase.expectedNil {
|
||||
assert.Nil(t, repo)
|
||||
} else {
|
||||
assert.NotNil(t, repo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestToFetchOptions(t *testing.T) {
|
||||
data := &TestRepos{}
|
||||
err := yaml.Unmarshal([]byte(StringTestData), data)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCase := TestCaseMap[ToFetchOptionsTestName]
|
||||
|
||||
for _, name := range testCase.dataMapEntry {
|
||||
repo := data.TestData[name]
|
||||
require.NotNil(t, repo)
|
||||
assert.NotNil(t, repo.ToFetchOptions(nil))
|
||||
}
|
||||
}
|
||||
|
||||
func TestToCloneOptions(t *testing.T) {
|
||||
data := &TestRepos{}
|
||||
err := yaml.Unmarshal([]byte(StringTestData), data)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCase := TestCaseMap[ToFetchOptionsTestName]
|
||||
|
||||
for _, name := range testCase.dataMapEntry {
|
||||
repo := data.TestData[name]
|
||||
require.NotNil(t, repo)
|
||||
assert.NotNil(t, repo.ToCloneOptions(nil))
|
||||
}
|
||||
}
|
||||
|
||||
func TestURL(t *testing.T) {
|
||||
data := &TestRepos{}
|
||||
err := yaml.Unmarshal([]byte(StringTestData), data)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCase := TestCaseMap[URLTestName]
|
||||
|
||||
for _, name := range testCase.dataMapEntry {
|
||||
repo := data.TestData[name]
|
||||
require.NotNil(t, repo)
|
||||
assert.Equal(t, repo.URLString, repo.URL())
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@ package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@ -86,19 +85,34 @@ func DummyCluster() *Cluster {
|
||||
func DummyManifest() *Manifest {
|
||||
m := NewManifest()
|
||||
// Repositories is the map of repository adddressable by a name
|
||||
m.Repositories["dummy"] = DummyRepository()
|
||||
m.Repository = DummyRepository()
|
||||
m.TargetPath = "/var/tmp/"
|
||||
return m
|
||||
}
|
||||
|
||||
func DummyRepository() *Repository {
|
||||
// TODO(howell): handle this error
|
||||
//nolint: errcheck
|
||||
parsedUrl, _ := url.Parse("http://dummy.url.com")
|
||||
return &Repository{
|
||||
Url: parsedUrl,
|
||||
Username: "dummy_user",
|
||||
TargetPath: "dummy_targetpath",
|
||||
URLString: "http://dummy.url.com",
|
||||
CheckoutOptions: &RepoCheckout{
|
||||
Tag: "v1.0.1",
|
||||
},
|
||||
Auth: &RepoAuth{
|
||||
Type: "ssh-key",
|
||||
KeyPath: "testdata/test-key.pem",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func DummyRepoAuth() *RepoAuth {
|
||||
return &RepoAuth{
|
||||
Type: "ssh-key",
|
||||
KeyPath: "testdata/test-key.pem",
|
||||
}
|
||||
}
|
||||
|
||||
func DummyRepoCheckout() *RepoCheckout {
|
||||
return &RepoCheckout{
|
||||
Tag: "v1.0.1",
|
||||
}
|
||||
}
|
||||
|
||||
|
23
pkg/config/testdata/config-string.yaml
vendored
23
pkg/config/testdata/config-string.yaml
vendored
@ -16,20 +16,15 @@ current-context: dummy_context
|
||||
kind: Config
|
||||
manifests:
|
||||
dummy_manifest:
|
||||
repositories:
|
||||
dummy:
|
||||
target-path: dummy_targetpath
|
||||
url:
|
||||
ForceQuery: false
|
||||
Fragment: ""
|
||||
Host: dummy.url.com
|
||||
Opaque: ""
|
||||
Path: ""
|
||||
RawPath: ""
|
||||
RawQuery: ""
|
||||
Scheme: http
|
||||
User: null
|
||||
username: dummy_user
|
||||
repository:
|
||||
auth:
|
||||
ssh-key: testdata/test-key.pem
|
||||
type: ssh-key
|
||||
checkout:
|
||||
branch: ""
|
||||
remote-ref: ""
|
||||
tag: v1.0.1
|
||||
url: http://dummy.url.com
|
||||
target-path: /var/tmp/
|
||||
modules-config:
|
||||
bootstrapInfo:
|
||||
|
23
pkg/config/testdata/manifest-string.yaml
vendored
23
pkg/config/testdata/manifest-string.yaml
vendored
@ -1,15 +1,10 @@
|
||||
repositories:
|
||||
dummy:
|
||||
target-path: dummy_targetpath
|
||||
url:
|
||||
ForceQuery: false
|
||||
Fragment: ""
|
||||
Host: dummy.url.com
|
||||
Opaque: ""
|
||||
Path: ""
|
||||
RawPath: ""
|
||||
RawQuery: ""
|
||||
Scheme: http
|
||||
User: null
|
||||
username: dummy_user
|
||||
repository:
|
||||
auth:
|
||||
ssh-key: testdata/test-key.pem
|
||||
type: ssh-key
|
||||
checkout:
|
||||
branch: ""
|
||||
remote-ref: ""
|
||||
tag: v1.0.1
|
||||
url: http://dummy.url.com
|
||||
target-path: /var/tmp/
|
||||
|
2
pkg/config/testdata/repo-auth-string.yaml
vendored
Normal file
2
pkg/config/testdata/repo-auth-string.yaml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
ssh-key: testdata/test-key.pem
|
||||
type: ssh-key
|
3
pkg/config/testdata/repo-checkout-string.yaml
vendored
Normal file
3
pkg/config/testdata/repo-checkout-string.yaml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
branch: ""
|
||||
remote-ref: ""
|
||||
tag: v1.0.1
|
20
pkg/config/testdata/repository-string.yaml
vendored
20
pkg/config/testdata/repository-string.yaml
vendored
@ -1,12 +1,8 @@
|
||||
target-path: dummy_targetpath
|
||||
url:
|
||||
ForceQuery: false
|
||||
Fragment: ""
|
||||
Host: dummy.url.com
|
||||
Opaque: ""
|
||||
Path: ""
|
||||
RawPath: ""
|
||||
RawQuery: ""
|
||||
Scheme: http
|
||||
User: null
|
||||
username: dummy_user
|
||||
auth:
|
||||
ssh-key: testdata/test-key.pem
|
||||
type: ssh-key
|
||||
checkout:
|
||||
branch: ""
|
||||
remote-ref: ""
|
||||
tag: v1.0.1
|
||||
url: http://dummy.url.com
|
||||
|
28
pkg/config/testdata/test-key.pem
vendored
Normal file
28
pkg/config/testdata/test-key.pem
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAQEA7Myn0IKrKpR3oORtrk7lblDT5EurDMt0BW1wJ21wD8+vXaIh6LcR
|
||||
KMoBsus/lo7gPHPckl5nBp9fUThxqMMS3YEJBdDUFgE7cAo8O5zL4KjRVKvELuz+CqYUT7
|
||||
uZLtWQXtAFBwwMKktrkP3td2KlTIthF8MdCBoXwuj3I/Mw/PDavvtoW2uWPm769GLl9gAf
|
||||
RWCexSpjfiOW2Uw3m68yzI4ET/AVAXSATkAEmB0r4+SCZnfoC+Nha3Y3TjLD08B35/RwAF
|
||||
r53Zh4vKhkTnIbb2ks1zr0MdH3usuAc2xVRmjz0PU/ckcBsZRVp/KVCtrCyEHW6FNVHeAx
|
||||
zzGe5Sz2YQAAA+hFhfzsRYX87AAAAAdzc2gtcnNhAAABAQDszKfQgqsqlHeg5G2uTuVuUN
|
||||
PkS6sMy3QFbXAnbXAPz69doiHotxEoygGy6z+WjuA8c9ySXmcGn19ROHGowxLdgQkF0NQW
|
||||
ATtwCjw7nMvgqNFUq8Qu7P4KphRPu5ku1ZBe0AUHDAwqS2uQ/e13YqVMi2EXwx0IGhfC6P
|
||||
cj8zD88Nq++2hba5Y+bvr0YuX2AB9FYJ7FKmN+I5bZTDebrzLMjgRP8BUBdIBOQASYHSvj
|
||||
5IJmd+gL42FrdjdOMsPTwHfn9HAAWvndmHi8qGROchtvaSzXOvQx0fe6y4BzbFVGaPPQ9T
|
||||
9yRwGxlFWn8pUK2sLIQdboU1Ud4DHPMZ7lLPZhAAAAAwEAAQAAAQATfkl2Rbt3dt9eNE+/
|
||||
IKmMakT3Ly92jy0O4VJxPHYUJyGlkJpAAQn9lJuNMgZ7C2n0MAmBVxoeFnKPShk5Lk3YRC
|
||||
4M94LuCM3uzDjnI2I5LUyGLtmoj0PedouHgMb8bwJCe9deHCTIOosxVWX+BPXclkC45wv1
|
||||
xcgc+HaX1AY9XCHpC9UEJ6oNIX990W+1D4wbsXjw3nal2jzaIe6we/FUwrrF0QRM8CHpB+
|
||||
GAZN7Z8GjzVidmLRiS88EDDMnjhkfww362WrKd53THCtahZma8nfvJonKAsT8fWEXf8WMK
|
||||
QKquNLJoVgHydPnH8S2+R61W7r3wuiuVEUbgB8VbCAN9AAAAgQCvrmEiDJyiB0n2fn4POt
|
||||
WPHHYjzshtTau+vVcnDd218TTRHOzwn243+q9wQwEKTtTFKMMhqDLwqkUkoJppg/zXtfFj
|
||||
zawnF3fBrqlqHCxfzH/hqqf5s+Xwm5wflivhgg+XH3Hm9RzX9QfVTovrnYgPGVpNN/LLCB
|
||||
t579gzKjM/5wAAAIEA/HKnVXNNVwcA7JfDSF4E+dp1FaGNn9qHm0zfBKZt9owl+dLjMUOV
|
||||
0DXZdgwIRNsumMrgEKFhn4pSk3HlfKyjPKTKz3Z3zA4Nkc5u+Bd+nXpPWtMXoewQfMjBM+
|
||||
U3w/ksVFywa7A+JtqyCqrBEHAwZh4mrmOftvWtk7WVjbJ0MNMAAACBAPAhomm+R/6M0PZu
|
||||
a9I9t2zSDT5W736tY8RMMArv0LyrQ5KyBBsGTrpKI7hWuoshOwTPNxnI6VsArcXMLYkwsP
|
||||
kQy8sP6wKBq+VXTMA9WwY8n5EGpEmhNNff5SJcap2Prr8cOoxv4GmxfvdJ7JYLY9HjR/VX
|
||||
8yP1Yk8UN4wC99t7AAAAMGtrYWxpbm92c2tpeUB2cG4tNjgtOTAtMTA1LTE0Ny52cG4uc2
|
||||
JjaXMuc2JjLmNvbQEC
|
||||
-----END OPENSSH PRIVATE KEY-----
|
@ -17,8 +17,6 @@ limitations under the License.
|
||||
package config
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
kubeconfig "k8s.io/client-go/tools/clientcmd/api"
|
||||
)
|
||||
|
||||
@ -119,9 +117,10 @@ type AuthInfo struct {
|
||||
// find the yaml manifests that airship uses to perform its operations)
|
||||
type Manifest struct {
|
||||
// Repositories is the map of repository adddressable by a name
|
||||
Repositories map[string]*Repository `json:"repositories"`
|
||||
|
||||
// Local Target path for working or home directory for all Manifest Cloned/Returned/Generated
|
||||
Repository *Repository `json:"repository"`
|
||||
// ExtraRepositories is the map of extra repositories addressable by a name
|
||||
ExtraRepositories map[string]*Repository `json:"extra-repositories,omitempty"`
|
||||
// TargetPath Local Target path for working or home dirctory for all Manifest Cloned/Returned/Generated
|
||||
TargetPath string `json:"target-path"`
|
||||
}
|
||||
|
||||
@ -129,16 +128,45 @@ type Manifest struct {
|
||||
// Information such as location, authentication info,
|
||||
// as well as details of what to get such as branch, tag, commit it, etc.
|
||||
type Repository struct {
|
||||
// URL for Repository
|
||||
Url *url.URL `json:"url"`
|
||||
// URLString for Repository
|
||||
URLString string `json:"url"`
|
||||
// Auth holds authentication options against remote
|
||||
Auth *RepoAuth `json:"auth,omitempty"`
|
||||
// CheckoutOptions holds options to checkout repository
|
||||
CheckoutOptions *RepoCheckout `json:"checkout,omitempty"`
|
||||
}
|
||||
|
||||
// Username is the username for authentication to the repository .
|
||||
// +optional
|
||||
// RepoAuth struct describes method of authentication agaist given repository
|
||||
type RepoAuth struct {
|
||||
// Type of authentication method to be used with given repository
|
||||
// supported types are "ssh-key", "ssh-pass", "http-basic"
|
||||
Type string `json:"type,omitempty"`
|
||||
//KeyPassword is a password decrypt ssh private key (used with ssh-key auth type)
|
||||
KeyPassword string `json:"key-pass,omitempty"`
|
||||
// KeyPath is path to private ssh key on disk (used with ssh-key auth type)
|
||||
KeyPath string `json:"ssh-key,omitempty"`
|
||||
//HTTPPassword is password for basic http authentication (used with http-basic auth type)
|
||||
HTTPPassword string `json:"http-pass,omitempty"`
|
||||
// SSHPassword is password for ssh password authentication (used with ssh-pass)
|
||||
SSHPassword string `json:"ssh-pass,omitempty"`
|
||||
// Username to authenticate against git remote (used with any type)
|
||||
Username string `json:"username,omitempty"`
|
||||
}
|
||||
|
||||
// Clone To Name Should always be relative to the setting of Manifest TargetPath.
|
||||
// Defines where ths repo will be cloned to locally.
|
||||
TargetPath string `json:"target-path"`
|
||||
// RepoCheckout container holds information how to checkout repository
|
||||
// Each field is mutually exclusive
|
||||
type RepoCheckout struct {
|
||||
// CommitHash is full hash of the commit that will be used to checkout
|
||||
CommitHash string `json:"commit-hash,omitempty"`
|
||||
// Branch is the branch name to checkout
|
||||
Branch string `json:"branch"`
|
||||
// Tag is the tag name to checkout
|
||||
Tag string `json:"tag"`
|
||||
// RemoteRef is not supported currently TODO
|
||||
// RemoteRef is used for remote checkouts such as gerrit change requests/github pull request
|
||||
// for example refs/changes/04/691202/5
|
||||
// TODO Add support for fetching remote refs
|
||||
RemoteRef string `json:"remote-ref"`
|
||||
}
|
||||
|
||||
// Holds the complex cluster name information
|
||||
|
@ -43,7 +43,8 @@ func NewCluster() *Cluster {
|
||||
// object with non-nil maps
|
||||
func NewManifest() *Manifest {
|
||||
return &Manifest{
|
||||
Repositories: make(map[string]*Repository),
|
||||
Repository: NewRepository(),
|
||||
ExtraRepositories: make(map[string]*Repository),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user