Test SSH as well as HTTP access to git

This commit rearranges update tests so that those that check that
updates are made can be run against a git server using SSH as well as
HTTP.

The local clone, used to provoke automated updates and to check
results, still uses HTTP. Those operations are not under test.

libgit2 wants to be asked for authentication when using SSH, and will
balk if it's not requested by the server. To avoid that, auth must be
switched on for the git test server.

This also switches auth on for HTTP, so it's necessary to use a git
URL that includes credentials for setting things up with a local
clone. I have also used that URL for the git-over-HTTP tests -- it's
arguable whether it's necessary to test that works, here.

Signed-off-by: Michael Bridgen <michael@weave.works>
This commit is contained in:
Michael Bridgen 2021-02-09 10:37:19 +00:00
parent 5d9f0f9958
commit 172dec486c
4 changed files with 119 additions and 31 deletions

View File

@ -53,8 +53,8 @@ import (
"github.com/fluxcd/pkg/runtime/metrics"
"github.com/fluxcd/pkg/runtime/predicates"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
gitstrat "github.com/fluxcd/source-controller/pkg/git"
git "github.com/fluxcd/source-controller/pkg/git/common"
git "github.com/fluxcd/source-controller/pkg/git"
gitstrat "github.com/fluxcd/source-controller/pkg/git/strategy"
imagev1 "github.com/fluxcd/image-automation-controller/api/v1alpha1"
"github.com/fluxcd/image-automation-controller/pkg/update"

View File

@ -22,8 +22,10 @@ import (
"fmt"
"io/ioutil"
"math/rand"
"net/url"
"os"
"path/filepath"
"strings"
"time"
"github.com/go-git/go-billy/v5/memfs"
@ -46,6 +48,7 @@ import (
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1alpha1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/gittestserver"
"github.com/fluxcd/pkg/ssh"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
imagev1 "github.com/fluxcd/image-automation-controller/api/v1alpha1"
@ -69,12 +72,11 @@ func randStringRunes(n int) string {
var _ = Describe("ImageUpdateAutomation", func() {
var (
impl string
branch string
repositoryPath string
repoURL string
namespace *corev1.Namespace
gitServer *gittestserver.GitServer
branch string
repositoryPath string
namespace *corev1.Namespace
username, password string
gitServer *gittestserver.GitServer
)
// Start the git server
@ -89,10 +91,15 @@ var _ = Describe("ImageUpdateAutomation", func() {
var err error
gitServer, err = gittestserver.NewTempGitServer()
Expect(err).NotTo(HaveOccurred())
username = randStringRunes(5)
password = randStringRunes(5)
// using authentication makes using the server more fiddly in
// general, but is required for testing SSH.
gitServer.Auth(username, password)
gitServer.AutoCreate()
Expect(gitServer.StartHTTP()).To(Succeed())
repoURL = gitServer.HTTPAddress() + repositoryPath
gitServer.KeyDir(filepath.Join(gitServer.Root(), "keys"))
Expect(gitServer.ListenSSH()).To(Succeed())
})
AfterEach(func() {
@ -104,8 +111,20 @@ var _ = Describe("ImageUpdateAutomation", func() {
Expect(initGitRepo(gitServer, "testdata/appconfig", branch, repositoryPath)).To(Succeed())
})
// These are used for end-to-end tests; withImagePolicy is
// effectively parameterised on these two values.
var (
// set the proto and impl in BeforeEach
proto string
impl string
)
withImagePolicy := func() {
var (
// for cloning locally
cloneLocalRepoURL string
// for the controller
repoURL string
localRepo *git.Repository
policy *imagev1_reflect.ImagePolicy
policyKey types.NamespacedName
@ -117,13 +136,31 @@ var _ = Describe("ImageUpdateAutomation", func() {
const evenLatestImage = "helloworld:1.2.0"
BeforeEach(func() {
cloneLocalRepoURL = gitServer.HTTPAddressWithCredentials() + repositoryPath
if proto == "http" {
repoURL = cloneLocalRepoURL // NB not testing auth for git over HTTP
} else if proto == "ssh" {
sshURL := gitServer.SSHAddress()
// this is expected to use 127.0.0.1, but host key
// checking usually wants a hostname, so use
// "localhost".
sshURL = strings.Replace(sshURL, "127.0.0.1", "localhost", 1)
repoURL = sshURL + repositoryPath
go func() {
defer GinkgoRecover()
gitServer.StartSSH()
}()
} else {
Fail("proto not set to http or ssh")
}
commitMessage = "Commit a difference " + randStringRunes(5)
Expect(initGitRepo(gitServer, "testdata/appconfig", branch, repositoryPath)).To(Succeed())
var err error
localRepo, err = git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{
URL: repoURL,
URL: cloneLocalRepoURL,
RemoteName: "origin",
ReferenceName: plumbing.NewBranchReferenceName(branch),
})
@ -145,6 +182,31 @@ var _ = Describe("ImageUpdateAutomation", func() {
GitImplementation: impl,
},
}
// If using SSH, we need to provide an identity (private
// key) and known_hosts file in a secret.
if proto == "ssh" {
url, err := url.Parse(repoURL)
Expect(err).ToNot(HaveOccurred())
knownhosts, err := ssh.ScanHostKey(url.Host, 5*time.Second)
Expect(err).ToNot(HaveOccurred())
keygen := ssh.NewRSAGenerator(2048)
pair, err := keygen.Generate()
Expect(err).ToNot(HaveOccurred())
sec := &corev1.Secret{
StringData: map[string]string{
"known_hosts": string(knownhosts),
"identity": string(pair.PrivateKey),
"identity.pub": string(pair.PublicKey),
},
}
sec.Name = "git-secret-" + randStringRunes(5)
sec.Namespace = namespace.Name
Expect(k8sClient.Create(context.Background(), sec)).To(Succeed())
gitRepo.Spec.SecretRef = &meta.LocalObjectReference{Name: sec.Name}
}
Expect(k8sClient.Create(context.Background(), gitRepo)).To(Succeed())
policyKey = types.NamespacedName{
@ -180,6 +242,7 @@ var _ = Describe("ImageUpdateAutomation", func() {
AfterEach(func() {
Expect(k8sClient.Delete(context.Background(), namespace)).To(Succeed())
Expect(k8sClient.Delete(context.Background(), policy)).To(Succeed())
Expect(gitServer.StopSSH()).To(Succeed())
})
Context("defaulting", func() {
@ -234,7 +297,7 @@ var _ = Describe("ImageUpdateAutomation", func() {
BeforeEach(func() {
// Insert a setter reference into the deployment file,
// before creating the automation object itself.
commitInRepo(repoURL, branch, "Install setter marker", func(tmp string) {
commitInRepo(cloneLocalRepoURL, branch, "Install setter marker", func(tmp string) {
replaceMarker(tmp, policyKey)
})
@ -291,7 +354,7 @@ var _ = Describe("ImageUpdateAutomation", func() {
Expect(newObj.Status.LastPushCommit).To(Equal(head.Hash().String()))
Expect(newObj.Status.LastPushTime).ToNot(BeNil())
compareRepoWithExpected(repoURL, branch, "testdata/appconfig-setters-expected", func(tmp string) {
compareRepoWithExpected(cloneLocalRepoURL, branch, "testdata/appconfig-setters-expected", func(tmp string) {
replaceMarker(tmp, policyKey)
})
})
@ -338,21 +401,35 @@ var _ = Describe("ImageUpdateAutomation", func() {
}
Context("Using go-git", func() {
BeforeEach(func() {
impl = sourcev1.GoGitImplementation
BeforeEach(func() { impl = sourcev1.GoGitImplementation })
Context("with HTTP", func() {
BeforeEach(func() { proto = "http" })
Describe("with image policy", withImagePolicy)
})
Context("with image policy", withImagePolicy)
Context("with SSH", func() {
BeforeEach(func() { proto = "ssh" })
Describe("with image policy", withImagePolicy)
})
})
Context("Using libgit2", func() {
BeforeEach(func() {
impl = sourcev1.LibGit2Implementation
BeforeEach(func() { impl = sourcev1.LibGit2Implementation })
Context("with HTTP", func() {
BeforeEach(func() { proto = "http" })
Describe("with image policy", withImagePolicy)
})
Context("with image policy", withImagePolicy)
// Marked "Pending" because the libgit2 SSH implementation
// won't work with the gittestserver yet -- see
// https://github.com/fluxcd/source-controller/issues/287
Context("with SSH", func() {
BeforeEach(func() { proto = "ssh" })
Describe("with image policy", withImagePolicy)
})
})
})
func expectCommittedAndPushed(conditions []metav1.Condition) {
@ -498,7 +575,7 @@ func initGitRepo(gitServer *gittestserver.GitServer, fixture, branch, repository
remote, err := repo.CreateRemote(&config.RemoteConfig{
Name: "origin",
URLs: []string{gitServer.HTTPAddress() + repositoryPath},
URLs: []string{gitServer.HTTPAddressWithCredentials() + repositoryPath},
})
if err != nil {
return err

9
go.mod
View File

@ -11,17 +11,18 @@ require (
github.com/fluxcd/image-automation-controller/api v0.4.0
github.com/fluxcd/image-reflector-controller/api v0.4.0
github.com/fluxcd/pkg/apis/meta v0.7.0
github.com/fluxcd/pkg/gittestserver v0.1.0
github.com/fluxcd/pkg/gittestserver v0.2.1
github.com/fluxcd/pkg/runtime v0.8.1
github.com/fluxcd/source-controller v0.7.0
github.com/fluxcd/pkg/ssh v0.0.5
github.com/fluxcd/source-controller v0.7.4
// If you bump this, change SOURCE_VER in the Makefile to match
github.com/fluxcd/source-controller/api v0.7.0
github.com/fluxcd/source-controller/api v0.7.4
github.com/go-git/go-billy/v5 v5.0.0
github.com/go-git/go-git/v5 v5.2.0
github.com/go-logr/logr v0.3.0
github.com/go-openapi/spec v0.19.5
github.com/google/go-containerregistry v0.1.1
github.com/libgit2/git2go/v31 v31.3.0
github.com/libgit2/git2go/v31 v31.4.7
github.com/onsi/ginkgo v1.14.1
github.com/onsi/gomega v1.10.2
github.com/otiai10/copy v1.2.0

22
go.sum
View File

@ -306,11 +306,11 @@ github.com/fluxcd/image-reflector-controller/api v0.4.0 h1:/7mxmTsjmwmzTchWG06Fa
github.com/fluxcd/image-reflector-controller/api v0.4.0/go.mod h1:MS3mGjZLnzZsfSqVLGbp0WNJr/k8XRFpw4G6ApLFTbc=
github.com/fluxcd/pkg/apis/meta v0.7.0 h1:5e8gm4OLqjuKWdrOIY5DEEsjcwzyJFK8rCDesJ+V8IY=
github.com/fluxcd/pkg/apis/meta v0.7.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
github.com/fluxcd/pkg/gittestserver v0.1.0 h1:BvIG+bBhgbmqhtpSS2qUpOXRIL1P1Ow2jauloH8X86U=
github.com/fluxcd/pkg/gittestserver v0.1.0/go.mod h1:HWZaoib03fQeSsauCAN2iAFdr6bnjKQ+CFxMFD2mwDY=
github.com/fluxcd/pkg/gittestserver v0.2.1 h1:SidG8/2hPVEV4XL7ofI76RMfen9zt1LLIoXddzkAhhI=
github.com/fluxcd/pkg/gittestserver v0.2.1/go.mod h1:HWZaoib03fQeSsauCAN2iAFdr6bnjKQ+CFxMFD2mwDY=
github.com/fluxcd/pkg/helmtestserver v0.1.0/go.mod h1:3L+tbPn74PsHwHsyhbfk/kZAosrwMFTTA92XEFiwVAE=
github.com/fluxcd/pkg/lockedfile v0.0.5/go.mod h1:uAtPUBId6a2RqO84MTH5HKGX0SbM1kNW3Wr/FhYyDVA=
github.com/fluxcd/pkg/runtime v0.8.0/go.mod h1:tQwEN+RESjJmtwSSv7I+6bkNM9raIXpGsCjruaIVX6A=
github.com/fluxcd/pkg/runtime v0.8.1 h1:8UxNz7GeI/HC3U5tpNCfrjRx2V7UjUegQOwCsd+EWxk=
github.com/fluxcd/pkg/runtime v0.8.1/go.mod h1:tQwEN+RESjJmtwSSv7I+6bkNM9raIXpGsCjruaIVX6A=
github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
@ -319,10 +319,10 @@ github.com/fluxcd/pkg/testserver v0.0.2/go.mod h1:pgUZTh9aQ44FSTQo+5NFlh7YMbUfdz
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
github.com/fluxcd/pkg/version v0.0.1 h1:/8asQoDXSThz3csiwi4Qo8Zb6blAxLXbtxNgeMJ9bCg=
github.com/fluxcd/pkg/version v0.0.1/go.mod h1:WAF4FEEA9xyhngF8TDxg3UPu5fA1qhEYV8Pmi2Il01Q=
github.com/fluxcd/source-controller v0.7.0 h1:OvvD0a9ZhlIshZt0NzkXJ5hAD8Zce7xERFC1UyhfXZA=
github.com/fluxcd/source-controller v0.7.0/go.mod h1:hfpk9y5iDJlSZqL+/OZTqvYDFZgIKz1PV26bOy404+M=
github.com/fluxcd/source-controller/api v0.7.0 h1:QDpr6ZjHtTxw+mc+mZ1p9qRujHb+PzPdoQP3YgWlqOA=
github.com/fluxcd/source-controller/api v0.7.0/go.mod h1:u2sdc/QDm0tzXHL7mZVj928hc3MMU+4mKCuAQg+94Bk=
github.com/fluxcd/source-controller v0.7.4 h1:1I+vPPJUHI4f1775E34EUBbATLt2QfEykvlfFJRMiUk=
github.com/fluxcd/source-controller v0.7.4/go.mod h1:W/C32SFn9P7WXwjILjhAfN7F+zuWG5YAaQUUgHDlbes=
github.com/fluxcd/source-controller/api v0.7.4 h1:Hy29SUyanKNHbb4AQZo7PqzmTx4y8TfkeO0GqBcb5PE=
github.com/fluxcd/source-controller/api v0.7.4/go.mod h1:u2sdc/QDm0tzXHL7mZVj928hc3MMU+4mKCuAQg+94Bk=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
@ -548,6 +548,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -694,6 +696,8 @@ github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libgit2/git2go/v31 v31.3.0 h1:d8ciyYVKir+gKwra3KuNxTyVvbgGKn4admdt1PNNAOg=
github.com/libgit2/git2go/v31 v31.3.0/go.mod h1:mnc0hPGPs0nDi9INrurTpioeRzje9DvSXqON/+JEhwY=
github.com/libgit2/git2go/v31 v31.4.7 h1:P85qB5at5un4qPqUcvOZbAom7P0G4KAG/OLVyD29kQ0=
github.com/libgit2/git2go/v31 v31.4.7/go.mod h1:c/rkJcBcUFx6wHaT++UwNpKvIsmPNqCeQ/vzO4DrEec=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
@ -1120,6 +1124,8 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c h1:9HhBz5L/UjnK9XLtiZhYAdue5BVKep3PMmS2LuPDt8k=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1277,6 +1283,10 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=