Skip to content

Commit

Permalink
💎 cleanup: VM and VNet spec no longer return arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
Cecile Robert-Michon committed Nov 3, 2020
1 parent fd51606 commit 3386d07
Show file tree
Hide file tree
Showing 11 changed files with 511 additions and 576 deletions.
14 changes: 6 additions & 8 deletions cloud/scope/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,12 @@ func (s *ClusterScope) SubnetSpecs() []azure.SubnetSpec {
}
}

// VNetSpecs returns the virtual network specs.
func (s *ClusterScope) VNetSpecs() []azure.VNetSpec {
return []azure.VNetSpec{
{
ResourceGroup: s.Vnet().ResourceGroup,
Name: s.Vnet().Name,
CIDRs: s.Vnet().CIDRBlocks,
},
// VNetSpec returns the virtual network spec.
func (s *ClusterScope) VNetSpec() azure.VNetSpec {
return azure.VNetSpec{
ResourceGroup: s.Vnet().ResourceGroup,
Name: s.Vnet().Name,
CIDRs: s.Vnet().CIDRBlocks,
}
}

Expand Down
32 changes: 15 additions & 17 deletions cloud/scope/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,21 @@ type MachineScope struct {
AzureMachine *infrav1.AzureMachine
}

// VMSpecs returns the VM specs.
func (m *MachineScope) VMSpecs() []azure.VMSpec {
return []azure.VMSpec{
{
Name: m.Name(),
Role: m.Role(),
NICNames: m.NICNames(),
SSHKeyData: m.AzureMachine.Spec.SSHPublicKey,
Size: m.AzureMachine.Spec.VMSize,
OSDisk: m.AzureMachine.Spec.OSDisk,
DataDisks: m.AzureMachine.Spec.DataDisks,
Zone: m.AvailabilityZone(),
Identity: m.AzureMachine.Spec.Identity,
UserAssignedIdentities: m.AzureMachine.Spec.UserAssignedIdentities,
SpotVMOptions: m.AzureMachine.Spec.SpotVMOptions,
SecurityProfile: m.AzureMachine.Spec.SecurityProfile,
},
// VMSpec returns the VM spec.
func (m *MachineScope) VMSpec() azure.VMSpec {
return azure.VMSpec{
Name: m.Name(),
Role: m.Role(),
NICNames: m.NICNames(),
SSHKeyData: m.AzureMachine.Spec.SSHPublicKey,
Size: m.AzureMachine.Spec.VMSize,
OSDisk: m.AzureMachine.Spec.OSDisk,
DataDisks: m.AzureMachine.Spec.DataDisks,
Zone: m.AvailabilityZone(),
Identity: m.AzureMachine.Spec.Identity,
UserAssignedIdentities: m.AzureMachine.Spec.UserAssignedIdentities,
SpotVMOptions: m.AzureMachine.Spec.SpotVMOptions,
SecurityProfile: m.AzureMachine.Spec.SecurityProfile,
}
}

Expand Down
14 changes: 6 additions & 8 deletions cloud/scope/managedcontrolplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,12 @@ func (s *ManagedControlPlaneScope) Vnet() *infrav1.VnetSpec {
}
}

// VNetSpecs returns the virtual network specs.
func (s *ManagedControlPlaneScope) VNetSpecs() []azure.VNetSpec {
return []azure.VNetSpec{
{
ResourceGroup: s.Vnet().ResourceGroup,
Name: s.Vnet().Name,
CIDRs: s.Vnet().CIDRBlocks,
},
// VNetSpec returns the virtual network spec.
func (s *ManagedControlPlaneScope) VNetSpec() azure.VNetSpec {
return azure.VNetSpec{
ResourceGroup: s.Vnet().ResourceGroup,
Name: s.Vnet().Name,
CIDRs: s.Vnet().CIDRBlocks,
}
}

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cloud/services/virtualmachines/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
type VMScope interface {
logr.Logger
azure.ClusterDescriber
VMSpecs() []azure.VMSpec
VMSpec() azure.VMSpec
GetBootstrapData(ctx context.Context) (string, error)
GetVMImage() (*infrav1.Image, error)
SetAnnotation(string, string)
Expand Down
234 changes: 116 additions & 118 deletions cloud/services/virtualmachines/virtualmachines.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,131 +57,130 @@ func (s *Service) getExisting(ctx context.Context, name string) (*infrav1.VM, er

// Reconcile gets/creates/updates a virtual machine.
func (s *Service) Reconcile(ctx context.Context) error {
for _, vmSpec := range s.Scope.VMSpecs() {
existingVM, err := s.getExisting(ctx, vmSpec.Name)
switch {
case err != nil && !azure.ResourceNotFound(err):
return errors.Wrapf(err, "failed to get VM %s", vmSpec.Name)
case err == nil:
// VM already exists, update the spec and skip creation.
s.Scope.SetProviderID(fmt.Sprintf("azure:///%s", existingVM.ID))
s.Scope.SetAnnotation("cluster-api-provider-azure", "true")
s.Scope.SetAddresses(existingVM.Addresses)
s.Scope.SetVMState(existingVM.State)
default:
s.Scope.V(2).Info("creating VM", "vm", vmSpec.Name)
sku, err := s.ResourceSKUCache.Get(ctx, vmSpec.Size, resourceskus.VirtualMachines)
if err != nil {
return errors.Wrapf(err, "failed to get find vm sku %s in compute api", vmSpec.Size)
}
vmSpec := s.Scope.VMSpec()
existingVM, err := s.getExisting(ctx, vmSpec.Name)
switch {
case err != nil && !azure.ResourceNotFound(err):
return errors.Wrapf(err, "failed to get VM %s", vmSpec.Name)
case err == nil:
// VM already exists, update the spec and skip creation.
s.Scope.SetProviderID(fmt.Sprintf("azure:///%s", existingVM.ID))
s.Scope.SetAnnotation("cluster-api-provider-azure", "true")
s.Scope.SetAddresses(existingVM.Addresses)
s.Scope.SetVMState(existingVM.State)
default:
s.Scope.V(2).Info("creating VM", "vm", vmSpec.Name)
sku, err := s.ResourceSKUCache.Get(ctx, vmSpec.Size, resourceskus.VirtualMachines)
if err != nil {
return errors.Wrapf(err, "failed to get find vm sku %s in compute api", vmSpec.Size)
}

storageProfile, err := s.generateStorageProfile(ctx, vmSpec, sku)
if err != nil {
return err
}
storageProfile, err := s.generateStorageProfile(ctx, vmSpec, sku)
if err != nil {
return err
}

securityProfile, err := getSecurityProfile(vmSpec, sku)
if err != nil {
return err
}
securityProfile, err := getSecurityProfile(vmSpec, sku)
if err != nil {
return err
}

nicRefs := make([]compute.NetworkInterfaceReference, len(vmSpec.NICNames))
for i, nicName := range vmSpec.NICNames {
primary := i == 0
nicRefs[i] = compute.NetworkInterfaceReference{
ID: to.StringPtr(azure.NetworkInterfaceID(s.Scope.SubscriptionID(), s.Scope.ResourceGroup(), nicName)),
NetworkInterfaceReferenceProperties: &compute.NetworkInterfaceReferenceProperties{
Primary: to.BoolPtr(primary),
},
}
nicRefs := make([]compute.NetworkInterfaceReference, len(vmSpec.NICNames))
for i, nicName := range vmSpec.NICNames {
primary := i == 0
nicRefs[i] = compute.NetworkInterfaceReference{
ID: to.StringPtr(azure.NetworkInterfaceID(s.Scope.SubscriptionID(), s.Scope.ResourceGroup(), nicName)),
NetworkInterfaceReferenceProperties: &compute.NetworkInterfaceReferenceProperties{
Primary: to.BoolPtr(primary),
},
}
}

priority, evictionPolicy, billingProfile, err := getSpotVMOptions(vmSpec.SpotVMOptions)
if err != nil {
return errors.Wrapf(err, "failed to get Spot VM options")
}
priority, evictionPolicy, billingProfile, err := getSpotVMOptions(vmSpec.SpotVMOptions)
if err != nil {
return errors.Wrapf(err, "failed to get Spot VM options")
}

sshKey, err := base64.StdEncoding.DecodeString(vmSpec.SSHKeyData)
if err != nil {
return errors.Wrapf(err, "failed to decode ssh public key")
}
bootstrapData, err := s.Scope.GetBootstrapData(ctx)
if err != nil {
return errors.Wrap(err, "failed to retrieve bootstrap data")
}
sshKey, err := base64.StdEncoding.DecodeString(vmSpec.SSHKeyData)
if err != nil {
return errors.Wrapf(err, "failed to decode ssh public key")
}
bootstrapData, err := s.Scope.GetBootstrapData(ctx)
if err != nil {
return errors.Wrap(err, "failed to retrieve bootstrap data")
}

virtualMachine := compute.VirtualMachine{
Plan: s.generateImagePlan(),
Location: to.StringPtr(s.Scope.Location()),
Tags: converters.TagsToMap(infrav1.Build(infrav1.BuildParams{
ClusterName: s.Scope.ClusterName(),
Lifecycle: infrav1.ResourceLifecycleOwned,
Name: to.StringPtr(vmSpec.Name),
Role: to.StringPtr(vmSpec.Role),
Additional: s.Scope.AdditionalTags(),
})),
VirtualMachineProperties: &compute.VirtualMachineProperties{
HardwareProfile: &compute.HardwareProfile{
VMSize: compute.VirtualMachineSizeTypes(vmSpec.Size),
},
StorageProfile: storageProfile,
SecurityProfile: securityProfile,
OsProfile: &compute.OSProfile{
ComputerName: to.StringPtr(vmSpec.Name),
AdminUsername: to.StringPtr(azure.DefaultUserName),
CustomData: to.StringPtr(bootstrapData),
LinuxConfiguration: &compute.LinuxConfiguration{
DisablePasswordAuthentication: to.BoolPtr(true),
SSH: &compute.SSHConfiguration{
PublicKeys: &[]compute.SSHPublicKey{
{
Path: to.StringPtr(fmt.Sprintf("/home/%s/.ssh/authorized_keys", azure.DefaultUserName)),
KeyData: to.StringPtr(string(sshKey)),
},
virtualMachine := compute.VirtualMachine{
Plan: s.generateImagePlan(),
Location: to.StringPtr(s.Scope.Location()),
Tags: converters.TagsToMap(infrav1.Build(infrav1.BuildParams{
ClusterName: s.Scope.ClusterName(),
Lifecycle: infrav1.ResourceLifecycleOwned,
Name: to.StringPtr(vmSpec.Name),
Role: to.StringPtr(vmSpec.Role),
Additional: s.Scope.AdditionalTags(),
})),
VirtualMachineProperties: &compute.VirtualMachineProperties{
HardwareProfile: &compute.HardwareProfile{
VMSize: compute.VirtualMachineSizeTypes(vmSpec.Size),
},
StorageProfile: storageProfile,
SecurityProfile: securityProfile,
OsProfile: &compute.OSProfile{
ComputerName: to.StringPtr(vmSpec.Name),
AdminUsername: to.StringPtr(azure.DefaultUserName),
CustomData: to.StringPtr(bootstrapData),
LinuxConfiguration: &compute.LinuxConfiguration{
DisablePasswordAuthentication: to.BoolPtr(true),
SSH: &compute.SSHConfiguration{
PublicKeys: &[]compute.SSHPublicKey{
{
Path: to.StringPtr(fmt.Sprintf("/home/%s/.ssh/authorized_keys", azure.DefaultUserName)),
KeyData: to.StringPtr(string(sshKey)),
},
},
},
},
NetworkProfile: &compute.NetworkProfile{
NetworkInterfaces: &nicRefs,
},
Priority: priority,
EvictionPolicy: evictionPolicy,
BillingProfile: billingProfile,
DiagnosticsProfile: &compute.DiagnosticsProfile{
BootDiagnostics: &compute.BootDiagnostics{
Enabled: to.BoolPtr(true),
},
},
NetworkProfile: &compute.NetworkProfile{
NetworkInterfaces: &nicRefs,
},
Priority: priority,
EvictionPolicy: evictionPolicy,
BillingProfile: billingProfile,
DiagnosticsProfile: &compute.DiagnosticsProfile{
BootDiagnostics: &compute.BootDiagnostics{
Enabled: to.BoolPtr(true),
},
},
}
},
}

if vmSpec.Zone != "" {
zones := []string{vmSpec.Zone}
virtualMachine.Zones = &zones
}
if vmSpec.Zone != "" {
zones := []string{vmSpec.Zone}
virtualMachine.Zones = &zones
}

if vmSpec.Identity == infrav1.VMIdentitySystemAssigned {
virtualMachine.Identity = &compute.VirtualMachineIdentity{
Type: compute.ResourceIdentityTypeSystemAssigned,
}
} else if vmSpec.Identity == infrav1.VMIdentityUserAssigned {
userIdentitiesMap, err := converters.UserAssignedIdentitiesToVMSDK(vmSpec.UserAssignedIdentities)
if err != nil {
return errors.Wrapf(err, "failed to assign identity %q", vmSpec.Name)
}
virtualMachine.Identity = &compute.VirtualMachineIdentity{
Type: compute.ResourceIdentityTypeUserAssigned,
UserAssignedIdentities: userIdentitiesMap,
}
if vmSpec.Identity == infrav1.VMIdentitySystemAssigned {
virtualMachine.Identity = &compute.VirtualMachineIdentity{
Type: compute.ResourceIdentityTypeSystemAssigned,
}

if err := s.Client.CreateOrUpdate(ctx, s.Scope.ResourceGroup(), vmSpec.Name, virtualMachine); err != nil {
return errors.Wrapf(err, "failed to create VM %s in resource group %s", vmSpec.Name, s.Scope.ResourceGroup())
} else if vmSpec.Identity == infrav1.VMIdentityUserAssigned {
userIdentitiesMap, err := converters.UserAssignedIdentitiesToVMSDK(vmSpec.UserAssignedIdentities)
if err != nil {
return errors.Wrapf(err, "failed to assign identity %q", vmSpec.Name)
}
virtualMachine.Identity = &compute.VirtualMachineIdentity{
Type: compute.ResourceIdentityTypeUserAssigned,
UserAssignedIdentities: userIdentitiesMap,
}
}

s.Scope.V(2).Info("successfully created VM", "vm", vmSpec.Name)
if err := s.Client.CreateOrUpdate(ctx, s.Scope.ResourceGroup(), vmSpec.Name, virtualMachine); err != nil {
return errors.Wrapf(err, "failed to create VM %s in resource group %s", vmSpec.Name, s.Scope.ResourceGroup())
}

s.Scope.V(2).Info("successfully created VM", "vm", vmSpec.Name)
}

return nil
Expand All @@ -208,19 +207,18 @@ func (s *Service) generateImagePlan() *compute.Plan {

// Delete deletes the virtual machine with the provided name.
func (s *Service) Delete(ctx context.Context) error {
for _, vmSpec := range s.Scope.VMSpecs() {
s.Scope.V(2).Info("deleting VM", "vm", vmSpec.Name)
err := s.Client.Delete(ctx, s.Scope.ResourceGroup(), vmSpec.Name)
if err != nil && azure.ResourceNotFound(err) {
// already deleted
continue
}
if err != nil {
return errors.Wrapf(err, "failed to delete VM %s in resource group %s", vmSpec.Name, s.Scope.ResourceGroup())
}

s.Scope.V(2).Info("successfully deleted VM", "vm", vmSpec.Name)
vmSpec := s.Scope.VMSpec()
s.Scope.V(2).Info("deleting VM", "vm", vmSpec.Name)
err := s.Client.Delete(ctx, s.Scope.ResourceGroup(), vmSpec.Name)
if err != nil && azure.ResourceNotFound(err) {
// already deleted
return nil
}
if err != nil {
return errors.Wrapf(err, "failed to delete VM %s in resource group %s", vmSpec.Name, s.Scope.ResourceGroup())
}

s.Scope.V(2).Info("successfully deleted VM", "vm", vmSpec.Name)
return nil
}

Expand Down
Loading

0 comments on commit 3386d07

Please sign in to comment.