mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-25 07:29:38 -05:00
Remove azure single instance support (#402)
This commit is contained in:
parent
9e43701d3c
commit
708c6e057e
@ -23,7 +23,6 @@ const (
|
|||||||
adReplicationLagCheckInterval = time.Second * 5 // 5 seconds
|
adReplicationLagCheckInterval = time.Second * 5 // 5 seconds
|
||||||
adReplicationLagCheckMaxRetries = int((15 * time.Minute) / adReplicationLagCheckInterval) // wait for up to 15 minutes for AD replication
|
adReplicationLagCheckMaxRetries = int((15 * time.Minute) / adReplicationLagCheckInterval) // wait for up to 15 minutes for AD replication
|
||||||
ownerRoleDefinitionID = "8e3af657-a8ff-443c-a75c-2fe8c4bcb635" // https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#owner
|
ownerRoleDefinitionID = "8e3af657-a8ff-443c-a75c-2fe8c4bcb635" // https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#owner
|
||||||
virtualMachineContributorRoleDefinitionID = "9980e02c-c2be-4d73-94e8-173b1dc7cf3c" // https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#virtual-machine-contributor
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateServicePrincipal creates an Azure AD app with a service principal, gives it "Owner" role on the resource group and creates new credentials.
|
// CreateServicePrincipal creates an Azure AD app with a service principal, gives it "Owner" role on the resource group and creates new credentials.
|
||||||
|
@ -52,13 +52,9 @@ type publicIPAddressesAPI interface {
|
|||||||
ipConfigurationName string,
|
ipConfigurationName string,
|
||||||
options *armnetwork.PublicIPAddressesClientListVirtualMachineScaleSetVMPublicIPAddressesOptions,
|
options *armnetwork.PublicIPAddressesClientListVirtualMachineScaleSetVMPublicIPAddressesOptions,
|
||||||
) *runtime.Pager[armnetwork.PublicIPAddressesClientListVirtualMachineScaleSetVMPublicIPAddressesResponse]
|
) *runtime.Pager[armnetwork.PublicIPAddressesClientListVirtualMachineScaleSetVMPublicIPAddressesResponse]
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, publicIPAddressName string,
|
BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, publicIPAddressName string,
|
||||||
parameters armnetwork.PublicIPAddress, options *armnetwork.PublicIPAddressesClientBeginCreateOrUpdateOptions) (
|
parameters armnetwork.PublicIPAddress, options *armnetwork.PublicIPAddressesClientBeginCreateOrUpdateOptions) (
|
||||||
*runtime.Poller[armnetwork.PublicIPAddressesClientCreateOrUpdateResponse], error)
|
*runtime.Poller[armnetwork.PublicIPAddressesClientCreateOrUpdateResponse], error)
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
Get(ctx context.Context, resourceGroupName string, publicIPAddressName string, options *armnetwork.PublicIPAddressesClientGetOptions) (
|
|
||||||
armnetwork.PublicIPAddressesClientGetResponse, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type networkInterfacesAPI interface {
|
type networkInterfacesAPI interface {
|
||||||
@ -66,10 +62,6 @@ type networkInterfacesAPI interface {
|
|||||||
virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string,
|
virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string,
|
||||||
options *armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceOptions,
|
options *armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceOptions,
|
||||||
) (armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceResponse, error)
|
) (armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceResponse, error)
|
||||||
// TODO: deprecate as soon as scale sets are available
|
|
||||||
BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, networkInterfaceName string,
|
|
||||||
parameters armnetwork.Interface, options *armnetwork.InterfacesClientBeginCreateOrUpdateOptions) (
|
|
||||||
*runtime.Poller[armnetwork.InterfacesClientCreateOrUpdateResponse], error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type resourceGroupAPI interface {
|
type resourceGroupAPI interface {
|
||||||
@ -99,14 +91,6 @@ type roleAssignmentsAPI interface {
|
|||||||
Create(ctx context.Context, scope string, roleAssignmentName string, parameters authorization.RoleAssignmentCreateParameters) (authorization.RoleAssignment, error)
|
Create(ctx context.Context, scope string, roleAssignmentName string, parameters authorization.RoleAssignmentCreateParameters) (authorization.RoleAssignment, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
type virtualMachinesAPI interface {
|
|
||||||
BeginCreateOrUpdate(ctx context.Context, resourceGroupName string,
|
|
||||||
vmName string, parameters armcomputev2.VirtualMachine,
|
|
||||||
options *armcomputev2.VirtualMachinesClientBeginCreateOrUpdateOptions) (
|
|
||||||
*runtime.Poller[armcomputev2.VirtualMachinesClientCreateOrUpdateResponse], error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type applicationInsightsAPI interface {
|
type applicationInsightsAPI interface {
|
||||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceName string, insightProperties armapplicationinsights.Component,
|
CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceName string, insightProperties armapplicationinsights.Component,
|
||||||
options *armapplicationinsights.ComponentsClientCreateOrUpdateOptions) (armapplicationinsights.ComponentsClientCreateOrUpdateResponse, error)
|
options *armapplicationinsights.ComponentsClientCreateOrUpdateOptions) (armapplicationinsights.ComponentsClientCreateOrUpdateResponse, error)
|
||||||
|
@ -258,8 +258,6 @@ func (a stubPublicIPAddressesAPI) Get(ctx context.Context, resourceGroupName str
|
|||||||
|
|
||||||
type stubNetworkInterfacesAPI struct {
|
type stubNetworkInterfacesAPI struct {
|
||||||
getErr error
|
getErr error
|
||||||
createErr error
|
|
||||||
pollErr error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubNetworkInterfacesAPI) GetVirtualMachineScaleSetNetworkInterface(ctx context.Context, resourceGroupName string,
|
func (a stubNetworkInterfacesAPI) GetVirtualMachineScaleSetNetworkInterface(ctx context.Context, resourceGroupName string,
|
||||||
@ -284,59 +282,6 @@ func (a stubNetworkInterfacesAPI) GetVirtualMachineScaleSetNetworkInterface(ctx
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func (a stubNetworkInterfacesAPI) BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, networkInterfaceName string,
|
|
||||||
parameters armnetwork.Interface, options *armnetwork.InterfacesClientBeginCreateOrUpdateOptions) (
|
|
||||||
*runtime.Poller[armnetwork.InterfacesClientCreateOrUpdateResponse], error,
|
|
||||||
) {
|
|
||||||
poller, err := runtime.NewPoller(nil, runtime.NewPipeline("", "", runtime.PipelineOptions{}, nil), &runtime.NewPollerOptions[armnetwork.InterfacesClientCreateOrUpdateResponse]{
|
|
||||||
Handler: &stubPoller[armnetwork.InterfacesClientCreateOrUpdateResponse]{
|
|
||||||
result: armnetwork.InterfacesClientCreateOrUpdateResponse{
|
|
||||||
Interface: armnetwork.Interface{
|
|
||||||
ID: to.Ptr("interface-id"),
|
|
||||||
Properties: &armnetwork.InterfacePropertiesFormat{
|
|
||||||
IPConfigurations: []*armnetwork.InterfaceIPConfiguration{
|
|
||||||
{
|
|
||||||
Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
|
|
||||||
PrivateIPAddress: to.Ptr("192.0.2.1"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
resultErr: a.pollErr,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return poller, a.createErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
type stubVirtualMachinesAPI struct {
|
|
||||||
stubResponse armcomputev2.VirtualMachinesClientCreateOrUpdateResponse
|
|
||||||
pollErr error
|
|
||||||
createErr error
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func (a stubVirtualMachinesAPI) BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, vmName string, parameters armcomputev2.VirtualMachine,
|
|
||||||
options *armcomputev2.VirtualMachinesClientBeginCreateOrUpdateOptions,
|
|
||||||
) (*runtime.Poller[armcomputev2.VirtualMachinesClientCreateOrUpdateResponse], error) {
|
|
||||||
poller, err := runtime.NewPoller(nil, runtime.NewPipeline("", "", runtime.PipelineOptions{}, nil), &runtime.NewPollerOptions[armcomputev2.VirtualMachinesClientCreateOrUpdateResponse]{
|
|
||||||
Handler: &stubPoller[armcomputev2.VirtualMachinesClientCreateOrUpdateResponse]{
|
|
||||||
result: a.stubResponse,
|
|
||||||
resultErr: a.pollErr,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return poller, a.createErr
|
|
||||||
}
|
|
||||||
|
|
||||||
type stubApplicationsAPI struct {
|
type stubApplicationsAPI struct {
|
||||||
createErr error
|
createErr error
|
||||||
deleteErr error
|
deleteErr error
|
||||||
|
@ -34,7 +34,6 @@ type Client struct {
|
|||||||
publicIPAddressesAPI
|
publicIPAddressesAPI
|
||||||
networkInterfacesAPI
|
networkInterfacesAPI
|
||||||
loadBalancersAPI
|
loadBalancersAPI
|
||||||
virtualMachinesAPI
|
|
||||||
applicationsAPI
|
applicationsAPI
|
||||||
servicePrincipalsAPI
|
servicePrincipalsAPI
|
||||||
roleAssignmentsAPI
|
roleAssignmentsAPI
|
||||||
@ -104,10 +103,6 @@ func NewFromDefault(subscriptionID, tenantID string) (*Client, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
virtualMachinesAPI, err := armcomputev2.NewVirtualMachinesClient(subscriptionID, cred, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
applicationInsightsAPI, err := armapplicationinsights.NewComponentsClient(subscriptionID, cred, nil)
|
applicationInsightsAPI, err := armapplicationinsights.NewComponentsClient(subscriptionID, cred, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -130,7 +125,6 @@ func NewFromDefault(subscriptionID, tenantID string) (*Client, error) {
|
|||||||
applicationsAPI: applicationsAPI,
|
applicationsAPI: applicationsAPI,
|
||||||
servicePrincipalsAPI: servicePrincipalsAPI,
|
servicePrincipalsAPI: servicePrincipalsAPI,
|
||||||
roleAssignmentsAPI: roleAssignmentsAPI,
|
roleAssignmentsAPI: roleAssignmentsAPI,
|
||||||
virtualMachinesAPI: virtualMachinesAPI,
|
|
||||||
applicationInsightsAPI: applicationInsightsAPI,
|
applicationInsightsAPI: applicationInsightsAPI,
|
||||||
subscriptionID: subscriptionID,
|
subscriptionID: subscriptionID,
|
||||||
tenantID: tenantID,
|
tenantID: tenantID,
|
||||||
|
@ -104,95 +104,6 @@ type CreateInstancesInput struct {
|
|||||||
ConfidentialVM bool
|
ConfidentialVM bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateInstancesVMs creates instances based on standalone VMs.
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func (c *Client) CreateInstancesVMs(ctx context.Context, input CreateInstancesInput) error {
|
|
||||||
pw, err := azure.GeneratePassword()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < input.CountControlPlanes; i++ {
|
|
||||||
vm := azure.VMInstance{
|
|
||||||
Name: c.name + "-control-plane-" + c.uid + "-" + strconv.Itoa(i),
|
|
||||||
Username: "constell",
|
|
||||||
Password: pw,
|
|
||||||
Location: c.location,
|
|
||||||
InstanceType: input.InstanceType,
|
|
||||||
Image: input.Image,
|
|
||||||
}
|
|
||||||
instance, err := c.createInstanceVM(ctx, vm)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.controlPlanes[strconv.Itoa(i)] = instance
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < input.CountWorkers; i++ {
|
|
||||||
vm := azure.VMInstance{
|
|
||||||
Name: c.name + "-worker-" + c.uid + "-" + strconv.Itoa(i),
|
|
||||||
Username: "constell",
|
|
||||||
Password: pw,
|
|
||||||
Location: c.location,
|
|
||||||
InstanceType: input.InstanceType,
|
|
||||||
Image: input.Image,
|
|
||||||
}
|
|
||||||
instance, err := c.createInstanceVM(ctx, vm)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.workers[strconv.Itoa(i)] = instance
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// createInstanceVM creates a single VM with a public IP address
|
|
||||||
// and a network interface.
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func (c *Client) createInstanceVM(ctx context.Context, input azure.VMInstance) (cloudtypes.Instance, error) {
|
|
||||||
pubIPName := input.Name + "-pubIP"
|
|
||||||
pubIP, err := c.createPublicIPAddress(ctx, pubIPName)
|
|
||||||
if err != nil {
|
|
||||||
return cloudtypes.Instance{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
nicName := input.Name + "-NIC"
|
|
||||||
privIP, nicID, err := c.createNIC(ctx, nicName, *pubIP.ID)
|
|
||||||
if err != nil {
|
|
||||||
return cloudtypes.Instance{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
input.NIC = nicID
|
|
||||||
|
|
||||||
poller, err := c.virtualMachinesAPI.BeginCreateOrUpdate(ctx, c.resourceGroup, input.Name, input.Azure(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return cloudtypes.Instance{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
vm, err := poller.PollUntilDone(ctx, &runtime.PollUntilDoneOptions{
|
|
||||||
Frequency: c.pollFrequency,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return cloudtypes.Instance{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if vm.Identity == nil || vm.Identity.PrincipalID == nil {
|
|
||||||
return cloudtypes.Instance{}, errors.New("virtual machine was created without system managed identity")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.assignResourceGroupRole(ctx, *vm.Identity.PrincipalID, virtualMachineContributorRoleDefinitionID); err != nil {
|
|
||||||
return cloudtypes.Instance{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := c.publicIPAddressesAPI.Get(ctx, c.resourceGroup, pubIPName, nil)
|
|
||||||
if err != nil {
|
|
||||||
return cloudtypes.Instance{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return cloudtypes.Instance{PublicIP: *res.PublicIPAddress.Properties.IPAddress, PrivateIP: privIP}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) createScaleSet(ctx context.Context, input CreateScaleSetInput) error {
|
func (c *Client) createScaleSet(ctx context.Context, input CreateScaleSetInput) error {
|
||||||
// TODO: Generating a random password to be able
|
// TODO: Generating a random password to be able
|
||||||
// to create the scale set. This is a temporary fix.
|
// to create the scale set. This is a temporary fix.
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
|
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
|
||||||
"github.com/edgelesssys/constellation/internal/cloud/cloudtypes"
|
"github.com/edgelesssys/constellation/internal/cloud/cloudtypes"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateResourceGroup(t *testing.T) {
|
func TestCreateResourceGroup(t *testing.T) {
|
||||||
@ -234,143 +233,6 @@ func TestCreateInstances(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func TestCreateInstancesVMs(t *testing.T) {
|
|
||||||
someErr := errors.New("failed")
|
|
||||||
testCases := map[string]struct {
|
|
||||||
publicIPAddressesAPI publicIPAddressesAPI
|
|
||||||
networkInterfacesAPI networkInterfacesAPI
|
|
||||||
virtualMachinesAPI virtualMachinesAPI
|
|
||||||
resourceGroupAPI resourceGroupAPI
|
|
||||||
roleAssignmentsAPI roleAssignmentsAPI
|
|
||||||
createInstancesInput CreateInstancesInput
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
"successful create": {
|
|
||||||
publicIPAddressesAPI: stubPublicIPAddressesAPI{},
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{},
|
|
||||||
virtualMachinesAPI: stubVirtualMachinesAPI{
|
|
||||||
stubResponse: armcomputev2.VirtualMachinesClientCreateOrUpdateResponse{VirtualMachine: armcomputev2.VirtualMachine{
|
|
||||||
Identity: &armcomputev2.VirtualMachineIdentity{PrincipalID: to.Ptr("principal-id")},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
resourceGroupAPI: newSuccessfulResourceGroupStub(),
|
|
||||||
roleAssignmentsAPI: &stubRoleAssignmentsAPI{},
|
|
||||||
createInstancesInput: CreateInstancesInput{
|
|
||||||
CountControlPlanes: 3,
|
|
||||||
CountWorkers: 3,
|
|
||||||
InstanceType: "type",
|
|
||||||
Image: "image",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"error when creating scale set": {
|
|
||||||
publicIPAddressesAPI: stubPublicIPAddressesAPI{},
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{},
|
|
||||||
virtualMachinesAPI: stubVirtualMachinesAPI{createErr: someErr},
|
|
||||||
resourceGroupAPI: newSuccessfulResourceGroupStub(),
|
|
||||||
roleAssignmentsAPI: &stubRoleAssignmentsAPI{},
|
|
||||||
createInstancesInput: CreateInstancesInput{
|
|
||||||
CountControlPlanes: 3,
|
|
||||||
CountWorkers: 3,
|
|
||||||
InstanceType: "type",
|
|
||||||
Image: "image",
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
"error when polling create scale set response": {
|
|
||||||
publicIPAddressesAPI: stubPublicIPAddressesAPI{},
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{},
|
|
||||||
virtualMachinesAPI: stubVirtualMachinesAPI{pollErr: someErr},
|
|
||||||
resourceGroupAPI: newSuccessfulResourceGroupStub(),
|
|
||||||
roleAssignmentsAPI: &stubRoleAssignmentsAPI{},
|
|
||||||
createInstancesInput: CreateInstancesInput{
|
|
||||||
CountControlPlanes: 3,
|
|
||||||
CountWorkers: 3,
|
|
||||||
InstanceType: "type",
|
|
||||||
Image: "image",
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
"error when creating NIC": {
|
|
||||||
publicIPAddressesAPI: stubPublicIPAddressesAPI{},
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{createErr: someErr},
|
|
||||||
virtualMachinesAPI: stubVirtualMachinesAPI{},
|
|
||||||
resourceGroupAPI: newSuccessfulResourceGroupStub(),
|
|
||||||
roleAssignmentsAPI: &stubRoleAssignmentsAPI{},
|
|
||||||
createInstancesInput: CreateInstancesInput{
|
|
||||||
CountControlPlanes: 3,
|
|
||||||
CountWorkers: 3,
|
|
||||||
InstanceType: "type",
|
|
||||||
Image: "image",
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
"error when creating public IP": {
|
|
||||||
publicIPAddressesAPI: stubPublicIPAddressesAPI{createErr: someErr},
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{},
|
|
||||||
virtualMachinesAPI: stubVirtualMachinesAPI{},
|
|
||||||
resourceGroupAPI: newSuccessfulResourceGroupStub(),
|
|
||||||
roleAssignmentsAPI: &stubRoleAssignmentsAPI{},
|
|
||||||
createInstancesInput: CreateInstancesInput{
|
|
||||||
CountControlPlanes: 3,
|
|
||||||
CountWorkers: 3,
|
|
||||||
InstanceType: "type",
|
|
||||||
Image: "image",
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
"error when retrieving public IP": {
|
|
||||||
publicIPAddressesAPI: stubPublicIPAddressesAPI{getErr: someErr},
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{},
|
|
||||||
virtualMachinesAPI: stubVirtualMachinesAPI{},
|
|
||||||
resourceGroupAPI: newSuccessfulResourceGroupStub(),
|
|
||||||
roleAssignmentsAPI: &stubRoleAssignmentsAPI{},
|
|
||||||
createInstancesInput: CreateInstancesInput{
|
|
||||||
CountControlPlanes: 3,
|
|
||||||
CountWorkers: 3,
|
|
||||||
InstanceType: "type",
|
|
||||||
Image: "image",
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for name, tc := range testCases {
|
|
||||||
t.Run(name, func(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
require := require.New(t)
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
client := Client{
|
|
||||||
location: "location",
|
|
||||||
name: "name",
|
|
||||||
uid: "uid",
|
|
||||||
resourceGroup: "name",
|
|
||||||
publicIPAddressesAPI: tc.publicIPAddressesAPI,
|
|
||||||
networkInterfacesAPI: tc.networkInterfacesAPI,
|
|
||||||
virtualMachinesAPI: tc.virtualMachinesAPI,
|
|
||||||
resourceGroupAPI: tc.resourceGroupAPI,
|
|
||||||
roleAssignmentsAPI: tc.roleAssignmentsAPI,
|
|
||||||
workers: make(cloudtypes.Instances),
|
|
||||||
controlPlanes: make(cloudtypes.Instances),
|
|
||||||
}
|
|
||||||
|
|
||||||
if tc.wantErr {
|
|
||||||
assert.Error(client.CreateInstancesVMs(ctx, tc.createInstancesInput))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(client.CreateInstancesVMs(ctx, tc.createInstancesInput))
|
|
||||||
assert.Equal(tc.createInstancesInput.CountControlPlanes, len(client.controlPlanes))
|
|
||||||
assert.Equal(tc.createInstancesInput.CountWorkers, len(client.workers))
|
|
||||||
assert.NotEmpty(client.workers["0"].PrivateIP)
|
|
||||||
assert.NotEmpty(client.workers["0"].PublicIP)
|
|
||||||
assert.NotEmpty(client.controlPlanes["0"].PrivateIP)
|
|
||||||
assert.NotEmpty(client.controlPlanes["0"].PublicIP)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSuccessfulResourceGroupStub() *stubResourceGroupAPI {
|
func newSuccessfulResourceGroupStub() *stubResourceGroupAPI {
|
||||||
return &stubResourceGroupAPI{
|
return &stubResourceGroupAPI{
|
||||||
getResourceGroup: armresources.ResourceGroup{
|
getResourceGroup: armresources.ResourceGroup{
|
||||||
|
@ -121,51 +121,6 @@ func (c *Client) CreateSecurityGroup(ctx context.Context, input NetworkSecurityG
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// createNIC creates a network interface that references a public IP address.
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func (c *Client) createNIC(ctx context.Context, name, publicIPAddressID string) (ip string, id string, err error) {
|
|
||||||
poller, err := c.networkInterfacesAPI.BeginCreateOrUpdate(
|
|
||||||
ctx, c.resourceGroup, name,
|
|
||||||
armnetwork.Interface{
|
|
||||||
Location: to.Ptr(c.location),
|
|
||||||
Properties: &armnetwork.InterfacePropertiesFormat{
|
|
||||||
NetworkSecurityGroup: &armnetwork.SecurityGroup{
|
|
||||||
ID: to.Ptr(c.networkSecurityGroup),
|
|
||||||
},
|
|
||||||
IPConfigurations: []*armnetwork.InterfaceIPConfiguration{
|
|
||||||
{
|
|
||||||
Name: to.Ptr(name),
|
|
||||||
Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
|
|
||||||
Subnet: &armnetwork.Subnet{
|
|
||||||
ID: to.Ptr(c.subnetID),
|
|
||||||
},
|
|
||||||
PublicIPAddress: &armnetwork.PublicIPAddress{
|
|
||||||
ID: to.Ptr(publicIPAddressID),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
pollerResp, err := poller.PollUntilDone(ctx, &runtime.PollUntilDoneOptions{
|
|
||||||
Frequency: c.pollFrequency,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
netInterface := pollerResp.Interface
|
|
||||||
|
|
||||||
return *netInterface.Properties.IPConfigurations[0].Properties.PrivateIPAddress,
|
|
||||||
*netInterface.ID,
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) createPublicIPAddress(ctx context.Context, name string) (*armnetwork.PublicIPAddress, error) {
|
func (c *Client) createPublicIPAddress(ctx context.Context, name string) (*armnetwork.PublicIPAddress, error) {
|
||||||
poller, err := c.publicIPAddressesAPI.BeginCreateOrUpdate(
|
poller, err := c.publicIPAddressesAPI.BeginCreateOrUpdate(
|
||||||
ctx, c.resourceGroup, name,
|
ctx, c.resourceGroup, name,
|
||||||
|
@ -117,58 +117,6 @@ func TestCreateSecurityGroup(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func TestCreateNIC(t *testing.T) {
|
|
||||||
someErr := errors.New("failed")
|
|
||||||
|
|
||||||
testCases := map[string]struct {
|
|
||||||
networkInterfacesAPI networkInterfacesAPI
|
|
||||||
name string
|
|
||||||
publicIPAddressID string
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
"successful create": {
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{},
|
|
||||||
name: "nic-name",
|
|
||||||
publicIPAddressID: "pubIP-id",
|
|
||||||
},
|
|
||||||
"failed to get response from successful create": {
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{pollErr: someErr},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
"failed create": {
|
|
||||||
networkInterfacesAPI: stubNetworkInterfacesAPI{createErr: someErr},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, tc := range testCases {
|
|
||||||
t.Run(name, func(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
client := Client{
|
|
||||||
resourceGroup: "resource-group",
|
|
||||||
location: "location",
|
|
||||||
name: "name",
|
|
||||||
uid: "uid",
|
|
||||||
workers: make(cloudtypes.Instances),
|
|
||||||
controlPlanes: make(cloudtypes.Instances),
|
|
||||||
networkInterfacesAPI: tc.networkInterfacesAPI,
|
|
||||||
}
|
|
||||||
|
|
||||||
ip, id, err := client.createNIC(ctx, tc.name, tc.publicIPAddressID)
|
|
||||||
if tc.wantErr {
|
|
||||||
assert.Error(err)
|
|
||||||
} else {
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.NotEmpty(ip)
|
|
||||||
assert.NotEmpty(id)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreatePublicIPAddress(t *testing.T) {
|
func TestCreatePublicIPAddress(t *testing.T) {
|
||||||
someErr := errors.New("failed")
|
someErr := errors.New("failed")
|
||||||
|
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
package azure
|
|
||||||
|
|
||||||
// copy of ec2/instances.go
|
|
||||||
|
|
||||||
// TODO(katexochen): refactor into mulitcloud package.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
|
||||||
armcomputev2 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// VMInstance describes a single instance.
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
type VMInstance struct {
|
|
||||||
Name string
|
|
||||||
Location string
|
|
||||||
InstanceType string
|
|
||||||
Username string
|
|
||||||
Password string
|
|
||||||
NIC string
|
|
||||||
Image string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Azure makes a new virtual machine template with default values.
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func (i VMInstance) Azure() armcomputev2.VirtualMachine {
|
|
||||||
return armcomputev2.VirtualMachine{
|
|
||||||
Name: to.Ptr(i.Name),
|
|
||||||
Location: to.Ptr(i.Location),
|
|
||||||
Properties: &armcomputev2.VirtualMachineProperties{
|
|
||||||
HardwareProfile: &armcomputev2.HardwareProfile{
|
|
||||||
VMSize: (*armcomputev2.VirtualMachineSizeTypes)(to.Ptr(i.InstanceType)),
|
|
||||||
},
|
|
||||||
OSProfile: &armcomputev2.OSProfile{
|
|
||||||
ComputerName: to.Ptr(i.Name),
|
|
||||||
AdminPassword: to.Ptr(i.Password),
|
|
||||||
AdminUsername: to.Ptr(i.Username),
|
|
||||||
},
|
|
||||||
SecurityProfile: &armcomputev2.SecurityProfile{
|
|
||||||
UefiSettings: &armcomputev2.UefiSettings{
|
|
||||||
SecureBootEnabled: to.Ptr(true),
|
|
||||||
VTpmEnabled: to.Ptr(true),
|
|
||||||
},
|
|
||||||
SecurityType: to.Ptr(armcomputev2.SecurityTypesConfidentialVM),
|
|
||||||
},
|
|
||||||
NetworkProfile: &armcomputev2.NetworkProfile{
|
|
||||||
NetworkInterfaces: []*armcomputev2.NetworkInterfaceReference{
|
|
||||||
{
|
|
||||||
ID: to.Ptr(i.NIC),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
StorageProfile: &armcomputev2.StorageProfile{
|
|
||||||
OSDisk: &armcomputev2.OSDisk{
|
|
||||||
CreateOption: to.Ptr(armcomputev2.DiskCreateOptionTypesFromImage),
|
|
||||||
ManagedDisk: &armcomputev2.ManagedDiskParameters{
|
|
||||||
StorageAccountType: to.Ptr(armcomputev2.StorageAccountTypesPremiumLRS),
|
|
||||||
SecurityProfile: &armcomputev2.VMDiskSecurityProfile{
|
|
||||||
SecurityEncryptionType: to.Ptr(armcomputev2.SecurityEncryptionTypesVMGuestStateOnly),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ImageReference: &armcomputev2.ImageReference{
|
|
||||||
Publisher: to.Ptr("0001-com-ubuntu-confidential-vm-focal"),
|
|
||||||
Offer: to.Ptr("canonical"),
|
|
||||||
SKU: to.Ptr("20_04-lts-gen2"),
|
|
||||||
Version: to.Ptr("latest"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DiagnosticsProfile: &armcomputev2.DiagnosticsProfile{
|
|
||||||
BootDiagnostics: &armcomputev2.BootDiagnostics{
|
|
||||||
Enabled: to.Ptr(true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Identity: &armcomputev2.VirtualMachineIdentity{
|
|
||||||
Type: to.Ptr(armcomputev2.ResourceIdentityTypeSystemAssigned),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,8 +31,6 @@ type azureclient interface {
|
|||||||
CreateVirtualNetwork(ctx context.Context) error
|
CreateVirtualNetwork(ctx context.Context) error
|
||||||
CreateSecurityGroup(ctx context.Context, input azurecl.NetworkSecurityGroupInput) error
|
CreateSecurityGroup(ctx context.Context, input azurecl.NetworkSecurityGroupInput) error
|
||||||
CreateInstances(ctx context.Context, input azurecl.CreateInstancesInput) error
|
CreateInstances(ctx context.Context, input azurecl.CreateInstancesInput) error
|
||||||
// TODO: deprecate as soon as scale sets are available
|
|
||||||
CreateInstancesVMs(ctx context.Context, input azurecl.CreateInstancesInput) error
|
|
||||||
CreateServicePrincipal(ctx context.Context) (string, error)
|
CreateServicePrincipal(ctx context.Context) (string, error)
|
||||||
TerminateResourceGroup(ctx context.Context) error
|
TerminateResourceGroup(ctx context.Context) error
|
||||||
TerminateServicePrincipal(ctx context.Context) error
|
TerminateServicePrincipal(ctx context.Context) error
|
||||||
|
@ -115,21 +115,6 @@ func (c *fakeAzureClient) CreateInstances(ctx context.Context, input azurecl.Cre
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func (c *fakeAzureClient) CreateInstancesVMs(ctx context.Context, input azurecl.CreateInstancesInput) error {
|
|
||||||
c.workers = make(cloudtypes.Instances)
|
|
||||||
for i := 0; i < input.CountWorkers; i++ {
|
|
||||||
id := "id-" + strconv.Itoa(i)
|
|
||||||
c.workers[id] = cloudtypes.Instance{PublicIP: "192.0.2.1", PrivateIP: "192.0.2.1"}
|
|
||||||
}
|
|
||||||
c.controlPlanes = make(cloudtypes.Instances)
|
|
||||||
for i := 0; i < input.CountControlPlanes; i++ {
|
|
||||||
id := "id-" + strconv.Itoa(i)
|
|
||||||
c.controlPlanes[id] = cloudtypes.Instance{PublicIP: "192.0.2.1", PrivateIP: "192.0.2.1"}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *fakeAzureClient) CreateServicePrincipal(ctx context.Context) (string, error) {
|
func (c *fakeAzureClient) CreateServicePrincipal(ctx context.Context) (string, error) {
|
||||||
c.adAppObjectID = "00000000-0000-0000-0000-000000000001"
|
c.adAppObjectID = "00000000-0000-0000-0000-000000000001"
|
||||||
return azureshared.ApplicationCredentials{
|
return azureshared.ApplicationCredentials{
|
||||||
@ -206,11 +191,6 @@ func (c *stubAzureClient) CreateInstances(ctx context.Context, input azurecl.Cre
|
|||||||
return c.createInstancesErr
|
return c.createInstancesErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: deprecate as soon as scale sets are available.
|
|
||||||
func (c *stubAzureClient) CreateInstancesVMs(ctx context.Context, input azurecl.CreateInstancesInput) error {
|
|
||||||
return c.createInstancesErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *stubAzureClient) CreateServicePrincipal(ctx context.Context) (string, error) {
|
func (c *stubAzureClient) CreateServicePrincipal(ctx context.Context) (string, error) {
|
||||||
return azureshared.ApplicationCredentials{
|
return azureshared.ApplicationCredentials{
|
||||||
ClientID: "00000000-0000-0000-0000-000000000000",
|
ClientID: "00000000-0000-0000-0000-000000000000",
|
||||||
|
Loading…
Reference in New Issue
Block a user