Merge pull request #19615 from runcom/add-registry-with-auth-testsuite
integration-cli: add suite for testing registries with auth
This commit is contained in:
commit
15cc67b73d
4 changed files with 93 additions and 17 deletions
|
@ -49,7 +49,7 @@ type DockerRegistrySuite struct {
|
|||
|
||||
func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
s.reg = setupRegistry(c, false)
|
||||
s.reg = setupRegistry(c, false, false)
|
||||
s.d = NewDaemon(c)
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ type DockerSchema1RegistrySuite struct {
|
|||
|
||||
func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
s.reg = setupRegistry(c, true)
|
||||
s.reg = setupRegistry(c, true, false)
|
||||
s.d = NewDaemon(c)
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,36 @@ func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) {
|
|||
s.ds.TearDownTest(c)
|
||||
}
|
||||
|
||||
func init() {
|
||||
check.Suite(&DockerRegistryAuthSuite{
|
||||
ds: &DockerSuite{},
|
||||
})
|
||||
}
|
||||
|
||||
type DockerRegistryAuthSuite struct {
|
||||
ds *DockerSuite
|
||||
reg *testRegistryV2
|
||||
d *Daemon
|
||||
}
|
||||
|
||||
func (s *DockerRegistryAuthSuite) SetUpTest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
s.reg = setupRegistry(c, false, true)
|
||||
s.d = NewDaemon(c)
|
||||
}
|
||||
|
||||
func (s *DockerRegistryAuthSuite) TearDownTest(c *check.C) {
|
||||
if s.reg != nil {
|
||||
out, err := s.d.Cmd("logout", privateRegistryURL)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
s.reg.Close()
|
||||
}
|
||||
if s.d != nil {
|
||||
s.d.Stop()
|
||||
}
|
||||
s.ds.TearDownTest(c)
|
||||
}
|
||||
|
||||
func init() {
|
||||
check.Suite(&DockerDaemonSuite{
|
||||
ds: &DockerSuite{},
|
||||
|
@ -128,7 +158,7 @@ type DockerTrustSuite struct {
|
|||
}
|
||||
|
||||
func (s *DockerTrustSuite) SetUpTest(c *check.C) {
|
||||
s.reg = setupRegistry(c, false)
|
||||
s.reg = setupRegistry(c, false, false)
|
||||
s.not = setupNotary(c)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,5 +17,14 @@ func (s *DockerSuite) TestLoginWithoutTTY(c *check.C) {
|
|||
// run the command and block until it's done
|
||||
err := cmd.Run()
|
||||
c.Assert(err, checker.NotNil) //"Expected non nil err when loginning in & TTY not available"
|
||||
|
||||
}
|
||||
|
||||
func (s *DockerRegistryAuthSuite) TestLoginToPrivateRegistry(c *check.C) {
|
||||
// wrong credentials
|
||||
out, _, err := dockerCmdWithError("login", "-u", s.reg.username, "-p", "WRONGPASSWORD", "-e", s.reg.email, privateRegistryURL)
|
||||
c.Assert(err, checker.NotNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "401 Unauthorized")
|
||||
|
||||
// now it's fine
|
||||
dockerCmd(c, "login", "-u", s.reg.username, "-p", s.reg.password, "-e", s.reg.email, privateRegistryURL)
|
||||
}
|
||||
|
|
|
@ -1554,9 +1554,9 @@ func daemonTime(c *check.C) time.Time {
|
|||
return dt
|
||||
}
|
||||
|
||||
func setupRegistry(c *check.C, schema1 bool) *testRegistryV2 {
|
||||
func setupRegistry(c *check.C, schema1, auth bool) *testRegistryV2 {
|
||||
testRequires(c, RegistryHosting)
|
||||
reg, err := newTestRegistryV2(c, schema1)
|
||||
reg, err := newTestRegistryV2(c, schema1, auth)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
// Wait for registry to be ready to serve requests.
|
||||
|
|
|
@ -18,28 +18,55 @@ const (
|
|||
)
|
||||
|
||||
type testRegistryV2 struct {
|
||||
cmd *exec.Cmd
|
||||
dir string
|
||||
cmd *exec.Cmd
|
||||
dir string
|
||||
username string
|
||||
password string
|
||||
email string
|
||||
}
|
||||
|
||||
func newTestRegistryV2(c *check.C, schema1 bool) (*testRegistryV2, error) {
|
||||
func newTestRegistryV2(c *check.C, schema1, auth bool) (*testRegistryV2, error) {
|
||||
tmp, err := ioutil.TempDir("", "registry-test-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
template := `version: 0.1
|
||||
loglevel: debug
|
||||
storage:
|
||||
filesystem:
|
||||
rootdirectory: %s
|
||||
http:
|
||||
addr: %s`
|
||||
tmp, err := ioutil.TempDir("", "registry-test-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
addr: %s
|
||||
%s`
|
||||
var (
|
||||
htpasswd string
|
||||
username string
|
||||
password string
|
||||
email string
|
||||
)
|
||||
if auth {
|
||||
htpasswdPath := filepath.Join(tmp, "htpasswd")
|
||||
// generated with: htpasswd -Bbn testuser testpassword
|
||||
userpasswd := "testuser:$2y$05$sBsSqk0OpSD1uTZkHXc4FeJ0Z70wLQdAX/82UiHuQOKbNbBrzs63m"
|
||||
username = "testuser"
|
||||
password = "testpassword"
|
||||
email = "test@test.org"
|
||||
if err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
htpasswd = fmt.Sprintf(`auth:
|
||||
htpasswd:
|
||||
realm: basic-realm
|
||||
path: %s
|
||||
`, htpasswdPath)
|
||||
}
|
||||
|
||||
confPath := filepath.Join(tmp, "config.yaml")
|
||||
config, err := os.Create(confPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := fmt.Fprintf(config, template, tmp, privateRegistryURL); err != nil {
|
||||
if _, err := fmt.Fprintf(config, template, tmp, privateRegistryURL, htpasswd); err != nil {
|
||||
os.RemoveAll(tmp)
|
||||
return nil, err
|
||||
}
|
||||
|
@ -57,8 +84,11 @@ http:
|
|||
return nil, err
|
||||
}
|
||||
return &testRegistryV2{
|
||||
cmd: cmd,
|
||||
dir: tmp,
|
||||
cmd: cmd,
|
||||
dir: tmp,
|
||||
username: username,
|
||||
password: password,
|
||||
email: email,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -68,7 +98,14 @@ func (t *testRegistryV2) Ping() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
resp.Body.Close()
|
||||
|
||||
fail := resp.StatusCode != http.StatusOK
|
||||
if t.username != "" {
|
||||
// unauthorized is a _good_ status when pinging v2/ and it needs auth
|
||||
fail = fail && resp.StatusCode != http.StatusUnauthorized
|
||||
}
|
||||
if fail {
|
||||
return fmt.Errorf("registry ping replied with an unexpected status code %d", resp.StatusCode)
|
||||
}
|
||||
return nil
|
||||
|
|
Loading…
Reference in a new issue