mirror of
https://github.com/docker/compose.git
synced 2025-04-08 17:05:13 +02:00
Added tests on ACI volume conversion, mock storageLogin required to get storage account keys
Signed-off-by: Guillaume Tardif <guillaume.tardif@docker.com>
This commit is contained in:
parent
772493d70d
commit
0092de6df1
@ -88,13 +88,11 @@ func getCloudService() (cloud.Service, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAciAPIService(aciCtx store.AciContext) *aciAPIService {
|
func getAciAPIService(aciCtx store.AciContext) *aciAPIService {
|
||||||
|
containerService := newContainerService(aciCtx)
|
||||||
|
composeService := newComposeService(aciCtx)
|
||||||
return &aciAPIService{
|
return &aciAPIService{
|
||||||
aciContainerService: &aciContainerService{
|
aciContainerService: &containerService,
|
||||||
ctx: aciCtx,
|
aciComposeService: &composeService,
|
||||||
},
|
|
||||||
aciComposeService: &aciComposeService{
|
|
||||||
ctx: aciCtx,
|
|
||||||
},
|
|
||||||
aciVolumeService: &aciVolumeService{
|
aciVolumeService: &aciVolumeService{
|
||||||
aciContext: aciCtx,
|
aciContext: aciCtx,
|
||||||
},
|
},
|
||||||
|
@ -34,11 +34,19 @@ import (
|
|||||||
|
|
||||||
type aciComposeService struct {
|
type aciComposeService struct {
|
||||||
ctx store.AciContext
|
ctx store.AciContext
|
||||||
|
storageLogin login.StorageLoginImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func newComposeService(ctx store.AciContext) aciComposeService {
|
||||||
|
return aciComposeService{
|
||||||
|
ctx: ctx,
|
||||||
|
storageLogin: login.StorageLoginImpl{AciContext: ctx},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *aciComposeService) Up(ctx context.Context, project *types.Project) error {
|
func (cs *aciComposeService) Up(ctx context.Context, project *types.Project) error {
|
||||||
logrus.Debugf("Up on project with name %q", project.Name)
|
logrus.Debugf("Up on project with name %q", project.Name)
|
||||||
groupDefinition, err := convert.ToContainerGroup(ctx, cs.ctx, *project)
|
groupDefinition, err := convert.ToContainerGroup(ctx, cs.ctx, *project, cs.storageLogin)
|
||||||
addTag(&groupDefinition, composeContainerTag)
|
addTag(&groupDefinition, composeContainerTag)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -38,6 +38,14 @@ import (
|
|||||||
|
|
||||||
type aciContainerService struct {
|
type aciContainerService struct {
|
||||||
ctx store.AciContext
|
ctx store.AciContext
|
||||||
|
storageLogin login.StorageLoginImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func newContainerService(ctx store.AciContext) aciContainerService {
|
||||||
|
return aciContainerService{
|
||||||
|
ctx: ctx,
|
||||||
|
storageLogin: login.StorageLoginImpl{AciContext: ctx},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *aciContainerService) List(ctx context.Context, all bool) ([]containers.Container, error) {
|
func (cs *aciContainerService) List(ctx context.Context, all bool) ([]containers.Container, error) {
|
||||||
@ -73,7 +81,7 @@ func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf("Running container %q with name %q", r.Image, r.ID)
|
logrus.Debugf("Running container %q with name %q", r.Image, r.ID)
|
||||||
groupDefinition, err := convert.ToContainerGroup(ctx, cs.ctx, project)
|
groupDefinition, err := convert.ToContainerGroup(ctx, cs.ctx, project, cs.storageLogin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -26,17 +26,16 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/compose-cli/api/compose"
|
|
||||||
"github.com/docker/compose-cli/utils/formatter"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
|
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/docker/compose-cli/aci/login"
|
"github.com/docker/compose-cli/aci/login"
|
||||||
|
"github.com/docker/compose-cli/api/compose"
|
||||||
"github.com/docker/compose-cli/api/containers"
|
"github.com/docker/compose-cli/api/containers"
|
||||||
"github.com/docker/compose-cli/context/store"
|
"github.com/docker/compose-cli/context/store"
|
||||||
|
"github.com/docker/compose-cli/utils/formatter"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -54,12 +53,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ToContainerGroup converts a compose project into a ACI container group
|
// ToContainerGroup converts a compose project into a ACI container group
|
||||||
func ToContainerGroup(ctx context.Context, aciContext store.AciContext, p types.Project) (containerinstance.ContainerGroup, error) {
|
func ToContainerGroup(ctx context.Context, aciContext store.AciContext, p types.Project, storageHelper login.StorageLogin) (containerinstance.ContainerGroup, error) {
|
||||||
project := projectAciHelper(p)
|
project := projectAciHelper(p)
|
||||||
containerGroupName := strings.ToLower(project.Name)
|
containerGroupName := strings.ToLower(project.Name)
|
||||||
storageHelper := login.StorageLogin{
|
|
||||||
AciContext: aciContext,
|
|
||||||
}
|
|
||||||
volumesCache, volumesSlice, err := project.getAciFileVolumes(ctx, storageHelper)
|
volumesCache, volumesSlice, err := project.getAciFileVolumes(ctx, storageHelper)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return containerinstance.ContainerGroup{}, err
|
return containerinstance.ContainerGroup{}, err
|
||||||
|
@ -21,29 +21,33 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/compose-cli/api/compose"
|
"github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance"
|
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
|
|
||||||
|
"github.com/docker/compose-cli/api/compose"
|
||||||
"github.com/docker/compose-cli/api/containers"
|
"github.com/docker/compose-cli/api/containers"
|
||||||
"github.com/docker/compose-cli/context/store"
|
"github.com/docker/compose-cli/context/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
var convertCtx = store.AciContext{
|
var (
|
||||||
|
convertCtx = store.AciContext{
|
||||||
SubscriptionID: "subID",
|
SubscriptionID: "subID",
|
||||||
ResourceGroup: "rg",
|
ResourceGroup: "rg",
|
||||||
Location: "eu",
|
Location: "eu",
|
||||||
}
|
}
|
||||||
|
mockStorageHelper = &mockStorageLogin{}
|
||||||
|
)
|
||||||
|
|
||||||
func TestProjectName(t *testing.T) {
|
func TestProjectName(t *testing.T) {
|
||||||
project := types.Project{
|
project := types.Project{
|
||||||
Name: "TEST",
|
Name: "TEST",
|
||||||
}
|
}
|
||||||
containerGroup, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
containerGroup, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, *containerGroup.Name, "test")
|
assert.Equal(t, *containerGroup.Name, "test")
|
||||||
}
|
}
|
||||||
@ -157,7 +161,7 @@ func TestComposeContainerGroupToContainerWithDnsSideCarSide(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Assert(t, is.Len(*group.Containers, 3))
|
assert.Assert(t, is.Len(*group.Containers, 3))
|
||||||
|
|
||||||
@ -182,7 +186,7 @@ func TestComposeSingleContainerGroupToContainerNoDnsSideCarSide(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
assert.Assert(t, is.Len(*group.Containers, 1))
|
assert.Assert(t, is.Len(*group.Containers, 1))
|
||||||
@ -190,6 +194,96 @@ func TestComposeSingleContainerGroupToContainerNoDnsSideCarSide(t *testing.T) {
|
|||||||
assert.Equal(t, *(*group.Containers)[0].Image, "image1")
|
assert.Equal(t, *(*group.Containers)[0].Image, "image1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestComposeVolumes(t *testing.T) {
|
||||||
|
ctx := context.TODO()
|
||||||
|
accountName := "myAccount"
|
||||||
|
mockStorageHelper.On("GetAzureStorageAccountKey", ctx, accountName).Return("123456", nil)
|
||||||
|
project := types.Project{
|
||||||
|
Services: []types.ServiceConfig{
|
||||||
|
{
|
||||||
|
Name: "service1",
|
||||||
|
Image: "image1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Volumes: types.Volumes{
|
||||||
|
"vol1": types.VolumeConfig{
|
||||||
|
Driver: "azure_file",
|
||||||
|
DriverOpts: map[string]string{
|
||||||
|
"share_name": "myFileshare",
|
||||||
|
"storage_account_name": accountName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := ToContainerGroup(ctx, convertCtx, project, mockStorageHelper)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
assert.Assert(t, is.Len(*group.Containers, 1))
|
||||||
|
assert.Equal(t, *(*group.Containers)[0].Name, "service1")
|
||||||
|
expectedGroupVolume := containerinstance.Volume{
|
||||||
|
Name: to.StringPtr("vol1"),
|
||||||
|
AzureFile: &containerinstance.AzureFileVolume{
|
||||||
|
ShareName: to.StringPtr("myFileshare"),
|
||||||
|
StorageAccountName: &accountName,
|
||||||
|
StorageAccountKey: to.StringPtr("123456"),
|
||||||
|
ReadOnly: to.BoolPtr(false),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.Equal(t, len(*group.Volumes), 1)
|
||||||
|
assert.DeepEqual(t, (*group.Volumes)[0], expectedGroupVolume)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComposeVolumesRO(t *testing.T) {
|
||||||
|
ctx := context.TODO()
|
||||||
|
accountName := "myAccount"
|
||||||
|
mockStorageHelper.On("GetAzureStorageAccountKey", ctx, accountName).Return("123456", nil)
|
||||||
|
project := types.Project{
|
||||||
|
Services: []types.ServiceConfig{
|
||||||
|
{
|
||||||
|
Name: "service1",
|
||||||
|
Image: "image1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Volumes: types.Volumes{
|
||||||
|
"vol1": types.VolumeConfig{
|
||||||
|
Driver: "azure_file",
|
||||||
|
DriverOpts: map[string]string{
|
||||||
|
"share_name": "myFileshare",
|
||||||
|
"storage_account_name": accountName,
|
||||||
|
"read_only": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := ToContainerGroup(ctx, convertCtx, project, mockStorageHelper)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
assert.Assert(t, is.Len(*group.Containers, 1))
|
||||||
|
assert.Equal(t, *(*group.Containers)[0].Name, "service1")
|
||||||
|
expectedGroupVolume := containerinstance.Volume{
|
||||||
|
Name: to.StringPtr("vol1"),
|
||||||
|
AzureFile: &containerinstance.AzureFileVolume{
|
||||||
|
ShareName: to.StringPtr("myFileshare"),
|
||||||
|
StorageAccountName: &accountName,
|
||||||
|
StorageAccountKey: to.StringPtr("123456"),
|
||||||
|
ReadOnly: to.BoolPtr(true),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.Equal(t, len(*group.Volumes), 1)
|
||||||
|
assert.DeepEqual(t, (*group.Volumes)[0], expectedGroupVolume)
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockStorageLogin struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *mockStorageLogin) GetAzureStorageAccountKey(ctx context.Context, accountName string) (string, error) {
|
||||||
|
args := s.Called(ctx, accountName)
|
||||||
|
return args.String(0), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
func TestComposeSingleContainerRestartPolicy(t *testing.T) {
|
func TestComposeSingleContainerRestartPolicy(t *testing.T) {
|
||||||
project := types.Project{
|
project := types.Project{
|
||||||
Services: []types.ServiceConfig{
|
Services: []types.ServiceConfig{
|
||||||
@ -205,7 +299,7 @@ func TestComposeSingleContainerRestartPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
assert.Assert(t, is.Len(*group.Containers, 1))
|
assert.Assert(t, is.Len(*group.Containers, 1))
|
||||||
@ -237,7 +331,7 @@ func TestComposeMultiContainerRestartPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
assert.Assert(t, is.Len(*group.Containers, 3))
|
assert.Assert(t, is.Len(*group.Containers, 3))
|
||||||
@ -271,7 +365,7 @@ func TestComposeInconsistentMultiContainerRestartPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
_, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.Error(t, err, "ACI integration does not support specifying different restart policies on containers in the same compose application")
|
assert.Error(t, err, "ACI integration does not support specifying different restart policies on containers in the same compose application")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +382,7 @@ func TestLabelsErrorMessage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
_, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.Error(t, err, "ACI integration does not support labels in compose applications")
|
assert.Error(t, err, "ACI integration does not support labels in compose applications")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +396,7 @@ func TestComposeSingleContainerGroupToContainerDefaultRestartPolicy(t *testing.T
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
assert.Assert(t, is.Len(*group.Containers, 1))
|
assert.Assert(t, is.Len(*group.Containers, 1))
|
||||||
@ -336,7 +430,7 @@ func TestComposeContainerGroupToContainerMultiplePorts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Assert(t, is.Len(*group.Containers, 3))
|
assert.Assert(t, is.Len(*group.Containers, 3))
|
||||||
|
|
||||||
@ -375,7 +469,7 @@ func TestComposeContainerGroupToContainerResourceLimits(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
limits := *((*group.Containers)[0]).Resources.Limits
|
limits := *((*group.Containers)[0]).Resources.Limits
|
||||||
@ -401,7 +495,7 @@ func TestComposeContainerGroupToContainerResourceLimitsDefaults(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
limits := *((*group.Containers)[0]).Resources.Limits
|
limits := *((*group.Containers)[0]).Resources.Limits
|
||||||
@ -425,7 +519,7 @@ func TestComposeContainerGroupToContainerenvVar(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := ToContainerGroup(context.TODO(), convertCtx, project)
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
envVars := *((*group.Containers)[0]).EnvironmentVariables
|
envVars := *((*group.Containers)[0]).EnvironmentVariables
|
||||||
|
@ -26,12 +26,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// StorageLogin helper for Azure Storage Login
|
// StorageLogin helper for Azure Storage Login
|
||||||
type StorageLogin struct {
|
type StorageLogin interface {
|
||||||
|
// GetAzureStorageAccountKey retrieves the storage account ket from the current azure login
|
||||||
|
GetAzureStorageAccountKey(ctx context.Context, accountName string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StorageLoginImpl implementation of StorageLogin
|
||||||
|
type StorageLoginImpl struct {
|
||||||
AciContext store.AciContext
|
AciContext store.AciContext
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAzureStorageAccountKey retrieves the storage account ket from the current azure login
|
// GetAzureStorageAccountKey retrieves the storage account ket from the current azure login
|
||||||
func (helper StorageLogin) GetAzureStorageAccountKey(ctx context.Context, accountName string) (string, error) {
|
func (helper StorageLoginImpl) GetAzureStorageAccountKey(ctx context.Context, accountName string) (string, error) {
|
||||||
client, err := NewStorageAccountsClient(helper.AciContext.SubscriptionID)
|
client, err := NewStorageAccountsClient(helper.AciContext.SubscriptionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -197,7 +197,7 @@ func TestContainerRunVolume(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("upload file", func(t *testing.T) {
|
t.Run("upload file", func(t *testing.T) {
|
||||||
storageLogin := login.StorageLogin{AciContext: aciContext}
|
storageLogin := login.StorageLoginImpl{AciContext: aciContext}
|
||||||
|
|
||||||
key, err := storageLogin.GetAzureStorageAccountKey(context.TODO(), accountName)
|
key, err := storageLogin.GetAzureStorageAccountKey(context.TODO(), accountName)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user