Merge "Add implementation of document/repo interface"

This commit is contained in:
Zuul 2020-02-12 14:41:12 +00:00 committed by Gerrit Code Review
commit ad9ee69cce
14 changed files with 661 additions and 89 deletions

View File

@ -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 {

View File

@ -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()

View File

@ -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
View 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
View 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())
}
}

View File

@ -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",
}
}

View File

@ -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:

View File

@ -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/

View File

@ -0,0 +1,2 @@
ssh-key: testdata/test-key.pem
type: ssh-key

View File

@ -0,0 +1,3 @@
branch: ""
remote-ref: ""
tag: v1.0.1

View File

@ -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
View 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-----

View File

@ -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

View File

@ -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),
}
}