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")
|
||||
|
||||
func init() {
|
||||
backend.Register("aci", "aci", func(ctx context.Context) (backend.Service, error) {
|
||||
return New(ctx)
|
||||
})
|
||||
backend.Register("aci", "aci", service, getCloudService)
|
||||
}
|
||||
|
||||
// New creates a backend that can manage containers
|
||||
func New(ctx context.Context) (backend.Service, error) {
|
||||
currentContext := apicontext.CurrentContext(ctx)
|
||||
func service(ctx context.Context) (backend.Service, error) {
|
||||
contextStore := store.ContextStore(ctx)
|
||||
|
||||
currentContext := apicontext.CurrentContext(ctx)
|
||||
var aciContext store.AciContext
|
||||
|
||||
if err := contextStore.GetEndpoint(currentContext, &aciContext); err != nil {
|
||||
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()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &aciAPIService{
|
||||
aciContainerService: aciContainerService{
|
||||
ctx: aciCtx,
|
||||
},
|
||||
aciComposeService: aciComposeService{
|
||||
ctx: aciCtx,
|
||||
},
|
||||
aciCloudService: aciCloudService{
|
||||
loginService: service,
|
||||
},
|
||||
return &aciCloudService{
|
||||
loginService: service,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getAciAPIService(aciCtx store.AciContext) *aciAPIService {
|
||||
return &aciAPIService{
|
||||
aciContainerService: &aciContainerService{
|
||||
ctx: aciCtx,
|
||||
},
|
||||
aciComposeService: &aciComposeService{
|
||||
ctx: aciCtx,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type aciAPIService struct {
|
||||
aciContainerService
|
||||
aciComposeService
|
||||
aciCloudService
|
||||
*aciContainerService
|
||||
*aciComposeService
|
||||
}
|
||||
|
||||
func (a *aciAPIService) ContainerService() containers.Service {
|
||||
return &a.aciContainerService
|
||||
return a.aciContainerService
|
||||
}
|
||||
|
||||
func (a *aciAPIService) ComposeService() compose.Service {
|
||||
return &a.aciComposeService
|
||||
}
|
||||
|
||||
func (a *aciAPIService) CloudService() cloud.Service {
|
||||
return &a.aciCloudService
|
||||
return a.aciComposeService
|
||||
}
|
||||
|
||||
type aciContainerService struct {
|
||||
|
|
|
@ -3,13 +3,16 @@ package azure
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
// TestGetContainerName ensures we can read container group name / container name from a containerID
|
||||
func TestGetContainerName(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
type BackendSuiteTest struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func (suite *BackendSuiteTest) TestGetContainerName() {
|
||||
group, container := getGroupAndContainerName("docker1234")
|
||||
Expect(group).To(Equal("docker1234"))
|
||||
Expect(container).To(Equal(singleContainerName))
|
||||
|
@ -22,3 +25,8 @@ func TestGetContainerName(t *testing.T) {
|
|||
Expect(group).To(Equal("compose_stack"))
|
||||
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 getCloudServiceFunc func() (cloud.Service, error)
|
||||
|
||||
type registeredBackend struct {
|
||||
name string
|
||||
backendType string
|
||||
init initFunc
|
||||
name string
|
||||
backendType string
|
||||
init initFunc
|
||||
getCloudService getCloudServiceFunc
|
||||
}
|
||||
|
||||
var backends = struct {
|
||||
|
@ -34,11 +36,10 @@ var backends = struct {
|
|||
type Service interface {
|
||||
ContainerService() containers.Service
|
||||
ComposeService() compose.Service
|
||||
CloudService() cloud.Service
|
||||
}
|
||||
|
||||
// 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 == "" {
|
||||
logrus.Fatal(errNoName)
|
||||
}
|
||||
|
@ -55,6 +56,7 @@ func Register(name string, backendType string, init initFunc) {
|
|||
name,
|
||||
backendType,
|
||||
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)
|
||||
}
|
||||
|
||||
// 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/docker/api/client"
|
||||
apicontext "github.com/docker/api/context"
|
||||
)
|
||||
|
||||
// Command returns the compose command with its child commands
|
||||
|
@ -24,12 +23,12 @@ func azureLoginCommand() *cobra.Command {
|
|||
azureLoginCmd := &cobra.Command{
|
||||
Use: "azure",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
ctx := apicontext.WithCurrentContext(cmd.Context(), "aci")
|
||||
c, err := client.New(ctx)
|
||||
ctx := cmd.Context()
|
||||
cs, err := client.GetCloudService(ctx, "aci")
|
||||
if err != nil {
|
||||
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"
|
||||
)
|
||||
|
||||
// New returns a backend client
|
||||
// New returns a backend client associated with current context
|
||||
func New(ctx context.Context) (*Client, error) {
|
||||
currentContext := apicontext.CurrentContext(ctx)
|
||||
s := store.ContextStore(ctx)
|
||||
|
@ -58,7 +58,11 @@ func New(ctx context.Context) (*Client, error) {
|
|||
backendType: cc.Type,
|
||||
bs: service,
|
||||
}, 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
|
||||
|
@ -76,8 +80,3 @@ func (c *Client) ContainerService() containers.Service {
|
|||
func (c *Client) ComposeService() compose.Service {
|
||||
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
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/api/errdefs"
|
||||
)
|
||||
|
||||
// Service cloud specific services
|
||||
type Service interface {
|
||||
// Login login to cloud provider
|
||||
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
|
||||
}
|
||||
|
||||
func (a *apiService) CloudService() cloud.Service {
|
||||
return nil
|
||||
func init() {
|
||||
backend.Register("example", "example", service, cloud.NotImplementedCloudService)
|
||||
}
|
||||
|
||||
func init() {
|
||||
backend.Register("example", "example", func(ctx context.Context) (backend.Service, error) {
|
||||
return &apiService{}, nil
|
||||
})
|
||||
func service(ctx context.Context) (backend.Service, error) {
|
||||
return &apiService{}, nil
|
||||
}
|
||||
|
||||
type containerService struct{}
|
||||
|
|
|
@ -27,13 +27,10 @@ type mobyService struct {
|
|||
}
|
||||
|
||||
func init() {
|
||||
backend.Register("moby", "moby", func(ctx context.Context) (backend.Service, error) {
|
||||
return New()
|
||||
})
|
||||
backend.Register("moby", "moby", service, cloud.NotImplementedCloudService)
|
||||
}
|
||||
|
||||
// New returns a moby backend implementation
|
||||
func New() (backend.Service, error) {
|
||||
func service(ctx context.Context) (backend.Service, error) {
|
||||
apiClient, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -52,10 +49,6 @@ func (ms *mobyService) ComposeService() compose.Service {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ms *mobyService) CloudService() cloud.Service {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms *mobyService) List(ctx context.Context, all bool) ([]containers.Container, error) {
|
||||
css, err := ms.apiClient.ContainerList(ctx, types.ContainerListOptions{
|
||||
All: all,
|
||||
|
|
Loading…
Reference in New Issue