@@ -18,134 +18,98 @@ package availabilitysets
1818
1919import (
2020 "context"
21- "strconv"
2221
2322 "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2021-04-01/compute"
24- "github.com/Azure/go-autorest/autorest/to"
2523 "github.com/pkg/errors"
2624 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
2725 "sigs.k8s.io/cluster-api-provider-azure/azure"
28- "sigs.k8s.io/cluster-api-provider-azure/azure/converters "
26+ "sigs.k8s.io/cluster-api-provider-azure/azure/services/async "
2927 "sigs.k8s.io/cluster-api-provider-azure/azure/services/resourceskus"
28+ "sigs.k8s.io/cluster-api-provider-azure/util/reconciler"
3029 "sigs.k8s.io/cluster-api-provider-azure/util/tele"
3130)
3231
32+ const serviceName = "availabilitysets"
33+
3334// AvailabilitySetScope defines the scope interface for a availability sets service.
3435type AvailabilitySetScope interface {
3536 azure.ClusterDescriber
36- AvailabilitySet () (string , bool )
37+ azure.AsyncStatusUpdater
38+ AvailabilitySetSpec () azure.ResourceSpecGetter
3739}
3840
3941// Service provides operations on Azure resources.
4042type Service struct {
4143 Scope AvailabilitySetScope
4244 Client
45+ async.Reconciler
4346 resourceSKUCache * resourceskus.Cache
4447}
4548
4649// New creates a new availability sets service.
4750func New (scope AvailabilitySetScope , skuCache * resourceskus.Cache ) * Service {
51+ client := NewClient (scope )
4852 return & Service {
4953 Scope : scope ,
50- Client : NewClient ( scope ) ,
54+ Client : client ,
5155 resourceSKUCache : skuCache ,
56+ Reconciler : async .New (scope , client , client ),
5257 }
5358}
5459
5560// Reconcile creates or updates availability sets.
5661func (s * Service ) Reconcile (ctx context.Context ) error {
57- ctx , log , done := tele .StartSpanWithLogger (
58- ctx ,
59- "availabilitysets.Service.Reconcile" ,
60- )
62+ ctx , log , done := tele .StartSpanWithLogger (ctx , "availabilitysets.Service.Reconcile" )
6163 defer done ()
6264
63- availabilitySetName , ok := s .Scope .AvailabilitySet ()
64- if ! ok {
65- return nil
66- }
67-
68- asSku , err := s .resourceSKUCache .Get (ctx , string (compute .AvailabilitySetSkuTypesAligned ), resourceskus .AvailabilitySets )
69- if err != nil {
70- return errors .Wrap (err , "failed to get availability sets sku" )
71- }
72-
73- faultDomainCountStr , ok := asSku .GetCapability (resourceskus .MaximumPlatformFaultDomainCount )
74- if ! ok {
75- return errors .Errorf ("cannot find capability %s sku %s" , resourceskus .MaximumPlatformFaultDomainCount , * asSku .Name )
76- }
65+ ctx , cancel := context .WithTimeout (ctx , reconciler .DefaultAzureServiceReconcileTimeout )
66+ defer cancel ()
7767
78- faultDomainCount , err := strconv .ParseUint (faultDomainCountStr , 10 , 32 )
79- if err != nil {
80- return errors .Wrap (err , "failed to determine max fault domain count" )
68+ setSpec := s .Scope .AvailabilitySetSpec ()
69+ var err error
70+ if setSpec != nil {
71+ _ , err = s .CreateResource (ctx , setSpec , serviceName )
72+ } else {
73+ log .V (2 ).Info ("skip creation when no availability set spec is found" )
8174 }
8275
83- log .V (2 ).Info ("creating availability set" , "availability set" , availabilitySetName )
84-
85- asParams := compute.AvailabilitySet {
86- Sku : & compute.Sku {
87- Name : to .StringPtr (string (compute .AvailabilitySetSkuTypesAligned )),
88- },
89- AvailabilitySetProperties : & compute.AvailabilitySetProperties {
90- PlatformFaultDomainCount : to .Int32Ptr (int32 (faultDomainCount )),
91- },
92- Tags : converters .TagsToMap (infrav1 .Build (infrav1.BuildParams {
93- ClusterName : s .Scope .ClusterName (),
94- Lifecycle : infrav1 .ResourceLifecycleOwned ,
95- Name : to .StringPtr (availabilitySetName ),
96- Role : to .StringPtr (infrav1 .CommonRole ),
97- Additional : s .Scope .AdditionalTags (),
98- })),
99- Location : to .StringPtr (s .Scope .Location ()),
100- }
101-
102- _ , err = s .Client .CreateOrUpdate (ctx , s .Scope .ResourceGroup (), availabilitySetName , asParams )
103- if err != nil {
104- return errors .Wrapf (err , "failed to create availability set %s" , availabilitySetName )
105- }
106-
107- log .V (2 ).Info ("successfully created availability set" , "availability set" , availabilitySetName )
108-
109- return nil
76+ s .Scope .UpdatePutStatus (infrav1 .AvailabilitySetReadyCondition , serviceName , err )
77+ return err
11078}
11179
11280// Delete deletes availability sets.
11381func (s * Service ) Delete (ctx context.Context ) error {
11482 ctx , log , done := tele .StartSpanWithLogger (ctx , "availabilitysets.Service.Delete" )
11583 defer done ()
11684
117- availabilitySetName , ok := s .Scope .AvailabilitySet ()
118- if ! ok {
119- return nil
85+ ctx , cancel := context .WithTimeout (ctx , reconciler .DefaultAzureServiceReconcileTimeout )
86+ defer cancel ()
87+
88+ setSpec := s .Scope .AvailabilitySetSpec ()
89+ var resultingErr error
90+ if setSpec == nil {
91+ log .V (2 ).Info ("skip deletion when no availability set spec is found" )
92+ } else {
93+ existingSet , err := s .Client .Get (ctx , setSpec )
94+ if err != nil {
95+ if ! azure .ResourceNotFound (err ) {
96+ resultingErr = errors .Wrapf (err , "failed to get availability set %s in resource group %s" , setSpec .ResourceName (), setSpec .ResourceGroupName ())
97+ }
98+ } else {
99+ availabilitySet , ok := existingSet .(compute.AvailabilitySet )
100+ if ! ok {
101+ resultingErr = errors .Errorf ("%T is not a compute.AvailabilitySet" , existingSet )
102+ } else {
103+ // only delete when the availability set does not have any vms
104+ if availabilitySet .AvailabilitySetProperties != nil && availabilitySet .VirtualMachines != nil && len (* availabilitySet .VirtualMachines ) > 0 {
105+ log .V (2 ).Info ("skip deleting availability set with VMs" , "availability set" , setSpec .ResourceName ())
106+ } else {
107+ resultingErr = s .DeleteResource (ctx , setSpec , serviceName )
108+ }
109+ }
110+ }
120111 }
121112
122- as , err := s .Client .Get (ctx , s .Scope .ResourceGroup (), availabilitySetName )
123- if err != nil && azure .ResourceNotFound (err ) {
124- // already deleted
125- return nil
126- }
127-
128- if err != nil {
129- return errors .Wrapf (err , "failed to get availability set %s in resource group %s" , availabilitySetName , s .Scope .ResourceGroup ())
130- }
131-
132- // only delete when the availability set does not have any vms
133- if as .AvailabilitySetProperties != nil && as .VirtualMachines != nil && len (* as .VirtualMachines ) > 0 {
134- return nil
135- }
136-
137- log .V (2 ).Info ("deleting availability set" , "availability set" , availabilitySetName )
138- err = s .Client .Delete (ctx , s .Scope .ResourceGroup (), availabilitySetName )
139- if err != nil && azure .ResourceNotFound (err ) {
140- // already deleted
141- return nil
142- }
143-
144- if err != nil {
145- return errors .Wrapf (err , "failed to delete availability set %s in resource group %s" , availabilitySetName , s .Scope .ResourceGroup ())
146- }
147-
148- log .V (2 ).Info ("successfully delete availability set" , "availability set" , availabilitySetName )
149-
150- return nil
113+ s .Scope .UpdateDeleteStatus (infrav1 .AvailabilitySetReadyCondition , serviceName , resultingErr )
114+ return resultingErr
151115}
0 commit comments