Skip to content

Commit

Permalink
Enhanced testing of factory/build client
Browse files Browse the repository at this point in the history
[#131726841]

Signed-off-by: Giuseppe Capizzi <[email protected]>
  • Loading branch information
tinygrasshopper authored and gcapizzi committed Mar 15, 2017
1 parent de2e30f commit 761b13b
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 73 deletions.
11 changes: 1 addition & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,10 @@ watch:
test-ci: setup test

test-unit:
BASIC_AUTH_BOSH_URL=https://lite-bosh.backup-and-restore.cf-app.com \
UAA_BOSH_URL=https://lite-bosh-uaa.backup-and-restore.cf-app.com \
ginkgo -r bosh orchestrator ssh artifact instance factory

test-unit-local:
BASIC_AUTH_BOSH_URL=https://lite-bosh.backup-and-restore.cf-app.com \
BASIC_AUTH_BOSH_CLIENT_SECRET=`lpass show LiteBoshDirector --password` \
BASIC_AUTH_BOSH_CERT_PATH=~/workspace/bosh-backup-and-restore-meta/certs/lite-bosh.backup-and-restore.cf-app.com.crt \
UAA_BOSH_URL=https://lite-bosh-uaa.backup-and-restore.cf-app.com \
UAA_BOSH_CLIENT_SECRET=`lpass show GardenBoshUAADirectorGCP --password` \
UAA_BOSH_CERT_PATH=~/workspace/bosh-backup-and-restore-meta/certs/lite-bosh-uaa.backup-and-restore.cf-app.com.crt \
BOSH_GATEWAY_KEY=~/workspace/bosh-backup-and-restore-meta/genesis-bosh/bosh.pem \
ginkgo -r bosh orchestrator ssh artifact instance
ginkgo -r bosh orchestrator ssh artifact instance factory

test-integration:
ginkgo -r integration -nodes 4
Expand Down
4 changes: 0 additions & 4 deletions ci/scripts/unit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ ssh-add bosh-backup-and-restore-meta/keys/github
export GOPATH=$PWD
export PATH=$PATH:$GOPATH/bin

export BASIC_AUTH_BOSH_CERT_PATH=`pwd`/bosh-backup-and-restore-meta/certs/lite-bosh.backup-and-restore.cf-app.com.crt
export UAA_BOSH_CERT_PATH=`pwd`/bosh-backup-and-restore-meta/certs/lite-bosh-uaa.backup-and-restore.cf-app.com.crt
export BOSH_GATEWAY_KEY=`pwd`/bosh-backup-and-restore-meta/genesis-bosh/bosh.pem

cd src/github.com/pivotal-cf/bosh-backup-and-restore
make test-ci
make clean-docker || true
2 changes: 0 additions & 2 deletions ci/tasks/unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,3 @@ run:
params:
TEAM_GPG_KEY:
DOCKER_HOST:
BASIC_AUTH_BOSH_CLIENT_SECRET:
UAA_BOSH_CLIENT_SECRET:
66 changes: 37 additions & 29 deletions factory/build_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,61 +14,69 @@ import (
boshlog "github.com/cloudfoundry/bosh-utils/logger"
)

func BuildClient(targetUrl, username, password, caCert string, logger boshlog.Logger) (orchestrator.BoshClient, error) {
func BuildClient(targetUrl, username, password, caCertFileName string, logger boshlog.Logger) (orchestrator.BoshClient, error) {
config, err := director.NewConfigFromURL(targetUrl)
if err != nil {
return nil, fmt.Errorf("Target director URL is malformed - %s", err.Error())
}

if caCert != "" {
cert, err := ioutil.ReadFile(caCert)
var cert string
if caCertFileName != "" {
certBytes, err := ioutil.ReadFile(caCertFileName)
if err != nil {
return nil, err
}
config.CACert = string(cert)
cert = string(certBytes)
}

factory := director.NewFactory(logger)
infoDirector, err := factory.New(config, director.NewNoopTaskReporter(), director.NewNoopFileReporter())
config.CACert = cert

info, _ := infoDirector.Info()

if info.Auth.Type == "uaa" {
uaaURL := info.Auth.Options["url"]
directorFactory := director.NewFactory(logger)
infoDirector, err := directorFactory.New(config, director.NewNoopTaskReporter(), director.NewNoopFileReporter())
if err != nil {
return nil, err
}

uaaURLStr, ok := uaaURL.(string)
if !ok {
return nil, fmt.Errorf("Expected URL '%s' to be a string", uaaURL)
}
info, err := infoDirector.Info()
if err != nil {
return nil, err
}

uaaConfig, err := boshuaa.NewConfigFromURL(uaaURLStr)
if info.Auth.Type == "uaa" {
uaa, err := buildUaa(info, username, password, cert, logger)
if err != nil {
return nil, err
}

if caCert != "" {
cert, err := ioutil.ReadFile(caCert)
if err != nil {
return nil, err
}
uaaConfig.CACert = string(cert)
}

uaaConfig.Client = username
uaaConfig.ClientSecret = password

uaa, _ := boshuaa.NewFactory(logger).New(uaaConfig)

config.TokenFunc = boshuaa.NewClientTokenSession(uaa).TokenFunc
} else {
config.Client = username
config.ClientSecret = password
}

boshDirector, err := factory.New(config, director.NewNoopTaskReporter(), director.NewNoopFileReporter())
boshDirector, err := directorFactory.New(config, director.NewNoopTaskReporter(), director.NewNoopFileReporter())
if err != nil {
return nil, err
}

return bosh.NewClient(boshDirector, director.NewSSHOpts, ssh.ConnectionCreator, logger, instance.NewJobFinder(logger)), nil
}

func buildUaa(info director.Info, username, password, cert string, logger boshlog.Logger) (boshuaa.UAA, error) {
urlAsInterface := info.Auth.Options["url"]
url, ok := urlAsInterface.(string)
if !ok {
return nil, fmt.Errorf("Expected URL '%s' to be a string", urlAsInterface)
}

uaaConfig, err := boshuaa.NewConfigFromURL(url)
if err != nil {
return nil, err
}

uaaConfig.CACert = cert
uaaConfig.Client = username
uaaConfig.ClientSecret = password

return boshuaa.NewFactory(logger).New(uaaConfig)
}
118 changes: 99 additions & 19 deletions factory/build_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,119 @@ import (
"log"

boshlog "github.com/cloudfoundry/bosh-utils/logger"
"github.com/pivotal-cf-experimental/cf-webmock/mockhttp"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/pivotal-cf-experimental/cf-webmock/mockbosh"
"github.com/pivotal-cf-experimental/cf-webmock/mockuaa"
"github.com/pivotal-cf/bosh-backup-and-restore/factory"
)

var _ = Describe("BuildClient", func() {
logger := boshlog.New(boshlog.LevelDebug, log.New(gbytes.NewBuffer(), "[bosh-package] ", log.Lshortfile), log.New(gbytes.NewBuffer(), "[bosh-package] ", log.Lshortfile))
var logger = boshlog.New(boshlog.LevelDebug, log.New(gbytes.NewBuffer(), "[bosh-package] ", log.Lshortfile), log.New(gbytes.NewBuffer(), "[bosh-package] ", log.Lshortfile))

It("builds a Client that authenticates with HTTP Basic Auth", func() {
username := MustHaveEnv("BOSH_CLIENT")
password := MustHaveEnv("BASIC_AUTH_BOSH_CLIENT_SECRET")
caCertPath := MustHaveEnv("BASIC_AUTH_BOSH_CERT_PATH")
basicAuthDirectorUrl := MustHaveEnv("BASIC_AUTH_BOSH_URL")
var director *mockhttp.Server
var deploymentName = "my-little-deployment"
var sslCertPath = "../fixtures/test.crt"

client, err := factory.BuildClient(basicAuthDirectorUrl, username, password, caCertPath, logger)
Expect(err).NotTo(HaveOccurred())
BeforeEach(func() {
director = mockbosh.NewTLS()
})
AfterEach(func() {
director.VerifyMocks()
})

Context("With Basic Auth", func() {
It("build the client which makes basic auth against director", func() {
username := "foo"
password := "bar"

director.ExpectedBasicAuth(username, password)
director.VerifyAndMock(
mockbosh.Info().WithAuthTypeBasic(),
mockbosh.Manifest(deploymentName).RespondsWith([]byte("manifest contents")),
)

client, err := factory.BuildClient(director.URL, username, password, sslCertPath, logger)

Expect(err).NotTo(HaveOccurred())
manifest, err := client.GetManifest(deploymentName)
Expect(err).NotTo(HaveOccurred())
Expect(manifest).To(Equal("manifest contents"))
})
})

Context("With UAA", func() {
var uaaServer *mockuaa.ClientCredentialsServer

It("build the client which makes basic auth against director", func() {
username := "foo"
password := "bar"
uaaToken := "baz"

uaaServer = mockuaa.NewClientCredentialsServerTLS(username, password, uaaToken)

director.ExpectedAuthorizationHeader("bearer " + uaaToken)
director.VerifyAndMock(
mockbosh.Info().WithAuthTypeUAA(uaaServer.URL),
mockbosh.Manifest(deploymentName).RespondsWith([]byte("manifest contents")),
)

client, err := factory.BuildClient(director.URL, username, password, sslCertPath, logger)

_, err = client.GetManifest("does-not-exist")
Expect(err.Error()).To(ContainSubstring("Director responded with non-successful status code '404'"))
Expect(err).NotTo(HaveOccurred())
manifest, err := client.GetManifest(deploymentName)
Expect(err).NotTo(HaveOccurred())
Expect(manifest).To(Equal("manifest contents"))
})

It("fails if uaa url is not valid", func() {
username := "no-relevant"
password := "no-relevant"

director.VerifyAndMock(
mockbosh.Info().WithAuthTypeUAA(""),
)
_, err := factory.BuildClient(director.URL, username, password, sslCertPath, logger)

Expect(err).To(HaveOccurred())

})
})

It("fails if CA-Cert cant be read", func() {
username := "no-relevant"
password := "no-relevant"
caCertPath := "/invalid/path"
basicAuthDirectorUrl := director.URL

_, err := factory.BuildClient(basicAuthDirectorUrl, username, password, caCertPath, logger)
Expect(err).To(HaveOccurred())
})

It("fails if invalid bosh url", func() {
username := "no-relevant"
password := "no-relevant"
caCertPath := ""
basicAuthDirectorUrl := ""

_, err := factory.BuildClient(basicAuthDirectorUrl, username, password, caCertPath, logger)
Expect(err).To(HaveOccurred())
})

It("builds a Client that authenticates with UAA", func() {
username := MustHaveEnv("BOSH_CLIENT")
password := MustHaveEnv("UAA_BOSH_CLIENT_SECRET")
caCertPath := MustHaveEnv("UAA_BOSH_CERT_PATH")
basicAuthDirectorUrl := MustHaveEnv("UAA_BOSH_URL")
It("fails if info cant be retrieved", func() {
username := "no-relevant"
password := "no-relevant"

director.VerifyAndMock(
mockbosh.Info().Fails("fooo!"),
)

client, err := factory.BuildClient(basicAuthDirectorUrl, username, password, caCertPath, logger)
Expect(err).NotTo(HaveOccurred())
_, err := factory.BuildClient(director.URL, username, password, sslCertPath, logger)

_, err = client.GetManifest("does-not-exist")
Expect(err.Error()).To(ContainSubstring("Director responded with non-successful status code '404'"))
Expect(err).To(HaveOccurred())
})

})
8 changes: 0 additions & 8 deletions factory/factory_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package factory_test

import (
"os"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

Expand All @@ -13,9 +11,3 @@ func TestFactory(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Factory Suite")
}

func MustHaveEnv(keyname string) string {
val := os.Getenv(keyname)
Expect(val).NotTo(BeEmpty(), "Need "+keyname+" for the test")
return val
}
2 changes: 1 addition & 1 deletion glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 761b13b

Please sign in to comment.