Skip to content

Commit 7f14c0b

Browse files
committed
Merge branch 'ecf' into integrate-bm
2 parents 6a5c139 + 4ac0b52 commit 7f14c0b

18 files changed

+255
-45
lines changed

Makefile

+6-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ KUBECTL=$(TOOLS_BIN_DIR)/kubectl
5151
KUBE_APISERVER=$(TOOLS_BIN_DIR)/kube-apiserver
5252
ETCD=$(TOOLS_BIN_DIR)/etcd
5353

54+
TAGSUFFIX_APPEND :=
55+
ifdef TAGSUFFIX
56+
TAGSUFFIX_APPEND := -${TAGSUFFIX}
57+
endif
58+
5459
# Version
5560
MAJOR_VER ?= 0
5661
MINOR_VER ?= 3
@@ -62,7 +67,7 @@ STAGING_REGISTRY := mocimages.azurecr.io
6267
PROD_REGISTRY := mocimages.azurecr.io
6368
IMAGE_NAME ?= caphcontroller
6469
CONTROLLER_IMG ?= $(REGISTRY)/$(IMAGE_NAME)
65-
TAG := $(MAJOR_VER).$(MINOR_VER).$(PATCH_VER)
70+
TAG := $(MAJOR_VER).$(MINOR_VER).$(PATCH_VER)${TAGSUFFIX_APPEND}
6671
ARCH := amd64
6772
ALL_ARCH = amd64 arm arm64 ppc64le s390x
6873

api/v1alpha3/azurestackhciloadbalancer_types.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ const (
3131
type AzureStackHCILoadBalancerSpec struct {
3232
SSHPublicKey string `json:"sshPublicKey"`
3333
Image Image `json:"image"`
34-
VMSize string `json:"vmSize"`
34+
35+
// +optional
36+
HostType HostType `json:"hostType,omitempty"`
37+
38+
VMSize string `json:"vmSize"`
3539

3640
// Number of desired loadbalancer machines. Defaults to 1.
3741
// This is a pointer to distinguish between explicit zero and not specified.

api/v1alpha3/azurestackhcimachine_types.go

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ type AzureStackHCIMachineSpec struct {
3636
// +optional
3737
ProviderID *string `json:"providerID,omitempty"`
3838

39+
// +optional
40+
HostType HostType `json:"hostType,omitempty"`
41+
3942
VMSize string `json:"vmSize"`
4043

4144
AvailabilityZone AvailabilityZone `json:"availabilityZone,omitempty"`

api/v1alpha3/azurestackhcivirtualmachine_types.go

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ const (
3232

3333
// AzureStackHCIVirtualMachineSpec defines the desired state of AzureStackHCIVirtualMachine
3434
type AzureStackHCIVirtualMachineSpec struct {
35+
// +optional
36+
HostType HostType `json:"hostType,omitempty"`
37+
3538
VMSize string `json:"vmSize"`
3639
AvailabilityZone AvailabilityZone `json:"availabilityZone,omitempty"`
3740
Image Image `json:"image"`

api/v1alpha3/types.go

+12
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,15 @@ const (
222222
ValueReady = "true"
223223
AnnotationControlPlaneReady = "azurestackhci.cluster.sigs.k8s.io/control-plane-ready"
224224
)
225+
226+
// HostType specifies what type of machine a node should be deployed on.
227+
type HostType string
228+
229+
const (
230+
// HostTypeVM specifies that the node should be deployed on a virtual machine.
231+
// Default value.
232+
HostTypeVM = HostType("vm")
233+
234+
// HostTypeBareMetal specifies that the node should be deployed on a bare metal machine.
235+
HostTypeBareMetal = HostType("baremetal")
236+
)

cloud/converters/vm.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,18 @@ import (
2323
"github.com/microsoft/moc-sdk-for-go/services/compute"
2424
)
2525

26-
// SDKToVM converts an SDK VirtualMachine to the provider VM type.
27-
func SDKToVM(v compute.VirtualMachine) (*infrav1.VM, error) {
26+
// VMConvertToCAPH converts an SDK VirtualMachine to the provider VM type.
27+
func VMConvertToCAPH(v compute.VirtualMachine) (*infrav1.VM, error) {
28+
vm := &infrav1.VM{
29+
ID: to.String(v.ID),
30+
Name: to.String(v.Name),
31+
State: infrav1.VMStateSucceeded, // Hard-coded for now until we expose provisioning state
32+
}
33+
return vm, nil
34+
}
35+
36+
// BareMetalMachineConvertToCAPH converts an SDK BareMetalMachine to the provider VM type.
37+
func BareMetalMachineConvertToCAPH(v compute.BareMetalMachine) (*infrav1.VM, error) {
2838
vm := &infrav1.VM{
2939
ID: to.String(v.ID),
3040
Name: to.String(v.Name),

cloud/services/virtualmachines/service.go

+13-5
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@ package virtualmachines
2020
import (
2121
azurestackhci "github.com/microsoft/cluster-api-provider-azurestackhci/cloud"
2222
"github.com/microsoft/cluster-api-provider-azurestackhci/cloud/scope"
23-
"github.com/microsoft/moc/pkg/auth"
23+
"github.com/microsoft/moc-sdk-for-go/services/compute/baremetalmachine"
2424
"github.com/microsoft/moc-sdk-for-go/services/compute/virtualmachine"
25+
"github.com/microsoft/moc/pkg/auth"
2526
)
2627

2728
var _ azurestackhci.Service = (*Service)(nil)
2829

2930
// Service provides operations on virtual machines.
3031
type Service struct {
31-
Client virtualmachine.VirtualMachineClient
32-
Scope scope.ScopeInterface
32+
VMClient virtualmachine.VirtualMachineClient
33+
BareMetalClient baremetalmachine.BareMetalMachineClient
34+
Scope scope.ScopeInterface
3335
}
3436

3537
// getVirtualMachinesClient creates a new virtual machines client.
@@ -38,10 +40,16 @@ func getVirtualMachinesClient(cloudAgentFqdn string, authorizer auth.Authorizer)
3840
return *vmClient
3941
}
4042

43+
func getBareMetalMachinesClient(cloudAgentFqdn string, authorizer auth.Authorizer) baremetalmachine.BareMetalMachineClient {
44+
bareMetalClient, _ := baremetalmachine.NewBareMetalMachineClient(cloudAgentFqdn, authorizer)
45+
return *bareMetalClient
46+
}
47+
4148
// NewService creates a new virtual machines service.
4249
func NewService(scope scope.ScopeInterface) *Service {
4350
return &Service{
44-
Client: getVirtualMachinesClient(scope.GetCloudAgentFqdn(), scope.GetAuthorizer()),
45-
Scope: scope,
51+
VMClient: getVirtualMachinesClient(scope.GetCloudAgentFqdn(), scope.GetAuthorizer()),
52+
BareMetalClient: getBareMetalMachinesClient(scope.GetCloudAgentFqdn(), scope.GetAuthorizer()),
53+
Scope: scope,
4654
}
4755
}

cloud/services/virtualmachines/virtualmachines.go

+95-21
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,43 @@ type Spec struct {
5353
OSDisk infrav1.OSDisk
5454
CustomData string
5555
VMType compute.VMType
56+
HostType infrav1.HostType
5657
}
5758

5859
// Get provides information about a virtual machine.
5960
func (s *Service) Get(ctx context.Context, spec interface{}) (interface{}, error) {
61+
var err error
6062
vmSpec, ok := spec.(*Spec)
6163
if !ok {
62-
return compute.VirtualMachine{}, errors.New("invalid vm specification")
64+
return nil, errors.New("invalid vm specification")
6365
}
6466

65-
vm, err := s.Client.Get(ctx, s.Scope.GetResourceGroup(), vmSpec.Name)
66-
if err != nil {
67-
return nil, err
68-
}
69-
if vm == nil || len(*vm) == 0 {
70-
return nil, errors.Wrapf(err, "vm %s not found", vmSpec.Name)
71-
}
67+
switch vmSpec.HostType {
68+
case infrav1.HostTypeBareMetal:
69+
var baremetalmachine *[]compute.BareMetalMachine
70+
71+
baremetalmachine, err = s.BareMetalClient.Get(ctx, s.Scope.GetResourceGroup(), vmSpec.Name)
72+
if err != nil {
73+
return nil, err
74+
}
75+
76+
if baremetalmachine == nil || len(*baremetalmachine) == 0 {
77+
return nil, errors.Errorf("bare-metal machine %s not found", vmSpec.Name)
78+
}
79+
80+
return converters.BareMetalMachineConvertToCAPH((*baremetalmachine)[0])
7281

73-
return converters.SDKToVM((*vm)[0])
82+
default:
83+
vm, err := s.VMClient.Get(ctx, s.Scope.GetResourceGroup(), vmSpec.Name)
84+
if err != nil {
85+
return nil, err
86+
}
87+
if vm == nil || len(*vm) == 0 {
88+
return nil, errors.Errorf("vm %s not found", vmSpec.Name)
89+
}
90+
91+
return converters.VMConvertToCAPH((*vm)[0])
92+
}
7493
}
7594

7695
// Reconcile gets/creates/updates a virtual machine.
@@ -173,36 +192,91 @@ func (s *Service) Reconcile(ctx context.Context, spec interface{}) error {
173192
}
174193
}
175194

176-
_, err = s.Client.CreateOrUpdate(
177-
ctx,
178-
s.Scope.GetResourceGroup(),
179-
vmSpec.Name,
180-
&virtualMachine)
181-
if err != nil {
182-
return errors.Wrapf(err, "cannot create vm")
183-
}
195+
switch vmSpec.HostType {
196+
case infrav1.HostTypeBareMetal:
197+
_, err := s.createOrUpdateBareMetal(
198+
ctx,
199+
&virtualMachine)
200+
if err != nil {
201+
return errors.Wrapf(err, "cannot create bare-metal machine")
202+
}
184203

204+
default:
205+
_, err = s.VMClient.CreateOrUpdate(
206+
ctx,
207+
s.Scope.GetResourceGroup(),
208+
vmSpec.Name,
209+
&virtualMachine)
210+
if err != nil {
211+
return errors.Wrapf(err, "cannot create vm")
212+
}
213+
}
185214
klog.V(2).Infof("successfully created vm %s ", vmSpec.Name)
186215
return err
187216
}
188217

218+
func (s *Service) createOrUpdateBareMetal(ctx context.Context, virtualMachine *compute.VirtualMachine) (*compute.BareMetalMachine, error) {
219+
// Create a new baremetal machine
220+
bareMetalMachine := &compute.BareMetalMachine{
221+
Name: virtualMachine.Name,
222+
}
223+
224+
bareMetalMachine.BareMetalMachineProperties = &compute.BareMetalMachineProperties{
225+
StorageProfile: &compute.BareMetalMachineStorageProfile{
226+
ImageReference: &compute.BareMetalMachineImageReference{
227+
ID: virtualMachine.VirtualMachineProperties.StorageProfile.ImageReference.ID,
228+
Name: virtualMachine.VirtualMachineProperties.StorageProfile.ImageReference.Name,
229+
},
230+
},
231+
OsProfile: &compute.BareMetalMachineOSProfile{
232+
ComputerName: virtualMachine.VirtualMachineProperties.OsProfile.ComputerName,
233+
AdminUsername: virtualMachine.VirtualMachineProperties.OsProfile.AdminUsername,
234+
AdminPassword: virtualMachine.VirtualMachineProperties.OsProfile.AdminPassword,
235+
CustomData: virtualMachine.VirtualMachineProperties.OsProfile.CustomData,
236+
LinuxConfiguration: virtualMachine.VirtualMachineProperties.OsProfile.LinuxConfiguration,
237+
},
238+
SecurityProfile: virtualMachine.VirtualMachineProperties.SecurityProfile,
239+
ProvisioningState: virtualMachine.VirtualMachineProperties.ProvisioningState,
240+
Statuses: virtualMachine.VirtualMachineProperties.Statuses,
241+
}
242+
243+
// Try to apply the update.
244+
_, err := s.BareMetalClient.CreateOrUpdate(ctx, s.Scope.GetResourceGroup(), *bareMetalMachine.Name, bareMetalMachine)
245+
246+
if err != nil {
247+
return nil, errors.Wrap(err, "Failed to create baremetal machine.")
248+
}
249+
250+
klog.V(2).Infof("Successfully created baremetal machine %s ", bareMetalMachine.Name)
251+
return bareMetalMachine, nil
252+
}
253+
189254
// Delete deletes the virtual machine with the provided name.
190255
func (s *Service) Delete(ctx context.Context, spec interface{}) error {
191256
vmSpec, ok := spec.(*Spec)
192257
if !ok {
193258
return errors.New("invalid vm Specification")
194259
}
195-
klog.V(2).Infof("deleting vm %s ", vmSpec.Name)
196-
err := s.Client.Delete(ctx, s.Scope.GetResourceGroup(), vmSpec.Name)
260+
261+
var err error
262+
switch vmSpec.HostType {
263+
case infrav1.HostTypeBareMetal:
264+
klog.V(2).Infof("deleting bare-metal machine %s ", vmSpec.Name)
265+
err = s.BareMetalClient.Delete(ctx, s.Scope.GetResourceGroup(), vmSpec.Name)
266+
default:
267+
klog.V(2).Infof("deleting vm %s ", vmSpec.Name)
268+
err = s.VMClient.Delete(ctx, s.Scope.GetResourceGroup(), vmSpec.Name)
269+
}
270+
197271
if err != nil && azurestackhci.ResourceNotFound(err) {
198272
// already deleted
199273
return nil
200274
}
201275
if err != nil {
202-
return errors.Wrapf(err, "failed to delete vm %s in resource group %s", vmSpec.Name, s.Scope.GetResourceGroup())
276+
return errors.Wrapf(err, "failed to delete %s %s in resource group %s", vmSpec.HostType, vmSpec.Name, s.Scope.GetResourceGroup())
203277
}
204278

205-
klog.V(2).Infof("successfully deleted vm %s ", vmSpec.Name)
279+
klog.V(2).Infof("successfully deleted %s %s ", vmSpec.HostType, vmSpec.Name)
206280
return err
207281
}
208282

config/crd/bases/infrastructure.cluster.x-k8s.io_azurestackhciclusters.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ spec:
4848
description: AzureStackHCILoadBalancer is used to declare the AzureStackHCILoadBalancerSpec
4949
if a LoadBalancer is desired for the AzureStackHCICluster.
5050
properties:
51+
hostType:
52+
description: HostType specifies what type of machine a node should
53+
be deployed on.
54+
type: string
5155
image:
5256
description: 'Image defines information about the image to use
5357
for VM creation. There are three ways to specify an image: by

config/crd/bases/infrastructure.cluster.x-k8s.io_azurestackhciloadbalancers.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ spec:
6969
type: object
7070
spec:
7171
properties:
72+
hostType:
73+
description: HostType specifies what type of machine a node should
74+
be deployed on.
75+
type: string
7276
image:
7377
description: 'Image defines information about the image to use for
7478
VM creation. There are three ways to specify an image: by ID, by

config/crd/bases/infrastructure.cluster.x-k8s.io_azurestackhcimachines.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ spec:
5454
id:
5555
type: string
5656
type: object
57+
hostType:
58+
description: HostType specifies what type of machine a node should
59+
be deployed on.
60+
type: string
5761
image:
5862
description: 'Image defines information about the image to use for
5963
VM creation. There are three ways to specify an image: by ID, by

config/crd/bases/infrastructure.cluster.x-k8s.io_azurestackhcimachinetemplates.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ spec:
6363
id:
6464
type: string
6565
type: object
66+
hostType:
67+
description: HostType specifies what type of machine a node
68+
should be deployed on.
69+
type: string
6670
image:
6771
description: 'Image defines information about the image to
6872
use for VM creation. There are three ways to specify an

config/crd/bases/infrastructure.cluster.x-k8s.io_azurestackhcivirtualmachines.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ spec:
5959
type: string
6060
clusterName:
6161
type: string
62+
hostType:
63+
description: HostType specifies what type of machine a node should
64+
be deployed on.
65+
type: string
6266
identity:
6367
description: VMIdentity defines the identity of the virtual machine,
6468
if configured.

controllers/azurestackhcimachine_controller.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ import (
2121
"context"
2222
"time"
2323

24-
"fmt"
25-
2624
"github.com/Azure/go-autorest/autorest/to"
2725
"github.com/go-logr/logr"
2826
infrav1 "github.com/microsoft/cluster-api-provider-azurestackhci/api/v1alpha3"
2927
azurestackhci "github.com/microsoft/cluster-api-provider-azurestackhci/cloud"
3028
"github.com/microsoft/cluster-api-provider-azurestackhci/cloud/scope"
29+
"github.com/microsoft/moc/pkg/providerid"
3130

3231
"github.com/pkg/errors"
3332
corev1 "k8s.io/api/core/v1"
@@ -217,7 +216,7 @@ func (r *AzureStackHCIMachineReconciler) reconcileNormal(machineScope *scope.Mac
217216
}
218217

219218
// Make sure Spec.ProviderID is always set.
220-
machineScope.SetProviderID(fmt.Sprintf("moc://%s", vm.Name))
219+
machineScope.SetProviderID(providerid.FormatProviderID(providerid.HostType(vm.Spec.HostType), vm.Name))
221220

222221
// TODO(vincepri): Remove this annotation when clusterctl is no longer relevant.
223222
machineScope.SetAnnotation("cluster-api-provider-azurestackhci", "true")
@@ -299,6 +298,7 @@ func (r *AzureStackHCIMachineReconciler) reconcileVirtualMachineNormal(machineSc
299298
}
300299
image.DeepCopyInto(&vm.Spec.Image)
301300

301+
vm.Spec.HostType = machineScope.AzureStackHCIMachine.Spec.HostType
302302
vm.Spec.VMSize = machineScope.AzureStackHCIMachine.Spec.VMSize
303303
machineScope.AzureStackHCIMachine.Spec.AvailabilityZone.DeepCopyInto(&vm.Spec.AvailabilityZone)
304304
machineScope.AzureStackHCIMachine.Spec.OSDisk.DeepCopyInto(&vm.Spec.OSDisk)

0 commit comments

Comments
 (0)