mirror of https://github.com/docker/compose.git
Merge pull request #159 from docker/fix_azure_login
Fix Azure login : no need for ACI context first
This commit is contained in:
commit
6830724ab9
|
@ -31,58 +31,53 @@ const singleContainerName = "single--container--aci"
|
||||||
var ErrNoSuchContainer = errors.New("no such container")
|
var ErrNoSuchContainer = errors.New("no such container")
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
backend.Register("aci", "aci", func(ctx context.Context) (backend.Service, error) {
|
backend.Register("aci", "aci", service, getCloudService)
|
||||||
return New(ctx)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a backend that can manage containers
|
func service(ctx context.Context) (backend.Service, error) {
|
||||||
func New(ctx context.Context) (backend.Service, error) {
|
|
||||||
currentContext := apicontext.CurrentContext(ctx)
|
|
||||||
contextStore := store.ContextStore(ctx)
|
contextStore := store.ContextStore(ctx)
|
||||||
|
currentContext := apicontext.CurrentContext(ctx)
|
||||||
var aciContext store.AciContext
|
var aciContext store.AciContext
|
||||||
|
|
||||||
if err := contextStore.GetEndpoint(currentContext, &aciContext); err != nil {
|
if err := contextStore.GetEndpoint(currentContext, &aciContext); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return getAciAPIService(aciContext)
|
return getAciAPIService(aciContext), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAciAPIService(aciCtx store.AciContext) (*aciAPIService, error) {
|
func getCloudService() (cloud.Service, error) {
|
||||||
service, err := login.NewAzureLoginService()
|
service, err := login.NewAzureLoginService()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &aciAPIService{
|
return &aciCloudService{
|
||||||
aciContainerService: aciContainerService{
|
loginService: service,
|
||||||
ctx: aciCtx,
|
|
||||||
},
|
|
||||||
aciComposeService: aciComposeService{
|
|
||||||
ctx: aciCtx,
|
|
||||||
},
|
|
||||||
aciCloudService: aciCloudService{
|
|
||||||
loginService: service,
|
|
||||||
},
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAciAPIService(aciCtx store.AciContext) *aciAPIService {
|
||||||
|
return &aciAPIService{
|
||||||
|
aciContainerService: &aciContainerService{
|
||||||
|
ctx: aciCtx,
|
||||||
|
},
|
||||||
|
aciComposeService: &aciComposeService{
|
||||||
|
ctx: aciCtx,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type aciAPIService struct {
|
type aciAPIService struct {
|
||||||
aciContainerService
|
*aciContainerService
|
||||||
aciComposeService
|
*aciComposeService
|
||||||
aciCloudService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aciAPIService) ContainerService() containers.Service {
|
func (a *aciAPIService) ContainerService() containers.Service {
|
||||||
return &a.aciContainerService
|
return a.aciContainerService
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aciAPIService) ComposeService() compose.Service {
|
func (a *aciAPIService) ComposeService() compose.Service {
|
||||||
return &a.aciComposeService
|
return a.aciComposeService
|
||||||
}
|
|
||||||
|
|
||||||
func (a *aciAPIService) CloudService() cloud.Service {
|
|
||||||
return &a.aciCloudService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type aciContainerService struct {
|
type aciContainerService struct {
|
||||||
|
|
|
@ -3,13 +3,16 @@ package azure
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestGetContainerName ensures we can read container group name / container name from a containerID
|
type BackendSuiteTest struct {
|
||||||
func TestGetContainerName(t *testing.T) {
|
suite.Suite
|
||||||
RegisterTestingT(t)
|
}
|
||||||
|
|
||||||
|
func (suite *BackendSuiteTest) TestGetContainerName() {
|
||||||
group, container := getGroupAndContainerName("docker1234")
|
group, container := getGroupAndContainerName("docker1234")
|
||||||
Expect(group).To(Equal("docker1234"))
|
Expect(group).To(Equal("docker1234"))
|
||||||
Expect(container).To(Equal(singleContainerName))
|
Expect(container).To(Equal(singleContainerName))
|
||||||
|
@ -22,3 +25,8 @@ func TestGetContainerName(t *testing.T) {
|
||||||
Expect(group).To(Equal("compose_stack"))
|
Expect(group).To(Equal("compose_stack"))
|
||||||
Expect(container).To(Equal("service1"))
|
Expect(container).To(Equal("service1"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBackendSuite(t *testing.T) {
|
||||||
|
RegisterTestingT(t)
|
||||||
|
suite.Run(t, new(BackendSuiteTest))
|
||||||
|
}
|
||||||
|
|
|
@ -19,11 +19,13 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type initFunc func(context.Context) (Service, error)
|
type initFunc func(context.Context) (Service, error)
|
||||||
|
type getCloudServiceFunc func() (cloud.Service, error)
|
||||||
|
|
||||||
type registeredBackend struct {
|
type registeredBackend struct {
|
||||||
name string
|
name string
|
||||||
backendType string
|
backendType string
|
||||||
init initFunc
|
init initFunc
|
||||||
|
getCloudService getCloudServiceFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
var backends = struct {
|
var backends = struct {
|
||||||
|
@ -34,11 +36,10 @@ var backends = struct {
|
||||||
type Service interface {
|
type Service interface {
|
||||||
ContainerService() containers.Service
|
ContainerService() containers.Service
|
||||||
ComposeService() compose.Service
|
ComposeService() compose.Service
|
||||||
CloudService() cloud.Service
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register adds a typed backend to the registry
|
// Register adds a typed backend to the registry
|
||||||
func Register(name string, backendType string, init initFunc) {
|
func Register(name string, backendType string, init initFunc, getCoudService getCloudServiceFunc) {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
logrus.Fatal(errNoName)
|
logrus.Fatal(errNoName)
|
||||||
}
|
}
|
||||||
|
@ -55,6 +56,7 @@ func Register(name string, backendType string, init initFunc) {
|
||||||
name,
|
name,
|
||||||
backendType,
|
backendType,
|
||||||
init,
|
init,
|
||||||
|
getCoudService,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,3 +71,15 @@ func Get(ctx context.Context, backendType string) (Service, error) {
|
||||||
|
|
||||||
return nil, fmt.Errorf("backend not found for context %q", backendType)
|
return nil, fmt.Errorf("backend not found for context %q", backendType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCloudService returns the backend registered for a particular type, it returns
|
||||||
|
// an error if there is no registered backends for the given type.
|
||||||
|
func GetCloudService(ctx context.Context, backendType string) (cloud.Service, error) {
|
||||||
|
for _, b := range backends.r {
|
||||||
|
if b.backendType == backendType {
|
||||||
|
return b.getCloudService()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("backend not found for backend type %s", backendType)
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/docker/api/client"
|
"github.com/docker/api/client"
|
||||||
apicontext "github.com/docker/api/context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command returns the compose command with its child commands
|
// Command returns the compose command with its child commands
|
||||||
|
@ -24,12 +23,12 @@ func azureLoginCommand() *cobra.Command {
|
||||||
azureLoginCmd := &cobra.Command{
|
azureLoginCmd := &cobra.Command{
|
||||||
Use: "azure",
|
Use: "azure",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
ctx := apicontext.WithCurrentContext(cmd.Context(), "aci")
|
ctx := cmd.Context()
|
||||||
c, err := client.New(ctx)
|
cs, err := client.GetCloudService(ctx, "aci")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "cannot connect to backend")
|
return errors.Wrap(err, "cannot connect to backend")
|
||||||
}
|
}
|
||||||
return c.CloudService().Login(ctx, nil)
|
return cs.Login(ctx, nil)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ import (
|
||||||
"github.com/docker/api/context/store"
|
"github.com/docker/api/context/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns a backend client
|
// New returns a backend client associated with current context
|
||||||
func New(ctx context.Context) (*Client, error) {
|
func New(ctx context.Context) (*Client, error) {
|
||||||
currentContext := apicontext.CurrentContext(ctx)
|
currentContext := apicontext.CurrentContext(ctx)
|
||||||
s := store.ContextStore(ctx)
|
s := store.ContextStore(ctx)
|
||||||
|
@ -58,7 +58,11 @@ func New(ctx context.Context) (*Client, error) {
|
||||||
backendType: cc.Type,
|
backendType: cc.Type,
|
||||||
bs: service,
|
bs: service,
|
||||||
}, nil
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCloudService returns a backend CloudService (typically login, create context)
|
||||||
|
func GetCloudService(ctx context.Context, backendType string) (cloud.Service, error) {
|
||||||
|
return backend.GetCloudService(ctx, backendType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client is a multi-backend client
|
// Client is a multi-backend client
|
||||||
|
@ -76,8 +80,3 @@ func (c *Client) ContainerService() containers.Service {
|
||||||
func (c *Client) ComposeService() compose.Service {
|
func (c *Client) ComposeService() compose.Service {
|
||||||
return c.bs.ComposeService()
|
return c.bs.ComposeService()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloudService returns the backend service for the current context
|
|
||||||
func (c *Client) CloudService() cloud.Service {
|
|
||||||
return c.bs.CloudService()
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,9 +1,25 @@
|
||||||
package cloud
|
package cloud
|
||||||
|
|
||||||
import "context"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/docker/api/errdefs"
|
||||||
|
)
|
||||||
|
|
||||||
// Service cloud specific services
|
// Service cloud specific services
|
||||||
type Service interface {
|
type Service interface {
|
||||||
// Login login to cloud provider
|
// Login login to cloud provider
|
||||||
Login(ctx context.Context, params map[string]string) error
|
Login(ctx context.Context, params map[string]string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotImplementedCloudService to use for backend that don't provide cloud services
|
||||||
|
func NotImplementedCloudService() (Service, error) {
|
||||||
|
return notImplementedCloudService{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type notImplementedCloudService struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs notImplementedCloudService) Login(ctx context.Context, params map[string]string) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
|
@ -26,14 +26,12 @@ func (a *apiService) ComposeService() compose.Service {
|
||||||
return &a.composeService
|
return &a.composeService
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiService) CloudService() cloud.Service {
|
func init() {
|
||||||
return nil
|
backend.Register("example", "example", service, cloud.NotImplementedCloudService)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func service(ctx context.Context) (backend.Service, error) {
|
||||||
backend.Register("example", "example", func(ctx context.Context) (backend.Service, error) {
|
return &apiService{}, nil
|
||||||
return &apiService{}, nil
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type containerService struct{}
|
type containerService struct{}
|
||||||
|
|
|
@ -27,13 +27,10 @@ type mobyService struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
backend.Register("moby", "moby", func(ctx context.Context) (backend.Service, error) {
|
backend.Register("moby", "moby", service, cloud.NotImplementedCloudService)
|
||||||
return New()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a moby backend implementation
|
func service(ctx context.Context) (backend.Service, error) {
|
||||||
func New() (backend.Service, error) {
|
|
||||||
apiClient, err := client.NewClientWithOpts(client.FromEnv)
|
apiClient, err := client.NewClientWithOpts(client.FromEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -52,10 +49,6 @@ func (ms *mobyService) ComposeService() compose.Service {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *mobyService) CloudService() cloud.Service {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mobyService) List(ctx context.Context, all bool) ([]containers.Container, error) {
|
func (ms *mobyService) List(ctx context.Context, all bool) ([]containers.Container, error) {
|
||||||
css, err := ms.apiClient.ContainerList(ctx, types.ContainerListOptions{
|
css, err := ms.apiClient.ContainerList(ctx, types.ContainerListOptions{
|
||||||
All: all,
|
All: all,
|
||||||
|
|
Loading…
Reference in New Issue