This repository has been archived by the owner on Nov 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
vmsku.go
118 lines (98 loc) · 2.84 KB
/
vmsku.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package vmsku
import (
"context"
"fmt"
"strings"
"sync"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
"github.com/giantswarm/microerror"
"github.com/giantswarm/micrologger"
"github.com/giantswarm/azure-operator/v7/client"
)
const (
// CapabilitySupported is the value returned by this API from Azure when the capability is supported
CapabilitySupported = "True"
CapabilityAcceleratedNetworking = "AcceleratedNetworkingEnabled"
CapabilityPremiumIO = "PremiumIO"
)
type Config struct {
AzureClientSet *client.AzureClientSet
Location string
Logger micrologger.Logger
}
type VMSKUs struct {
azureClientSet *client.AzureClientSet
location string
skus map[string]*compute.ResourceSku
logger micrologger.Logger
initMutex sync.Mutex
}
func New(config Config) (*VMSKUs, error) {
if config.AzureClientSet == nil {
return nil, microerror.Maskf(invalidConfigError, "%T.AzureClientSet must not be empty", config)
}
if config.Location == "" {
return nil, microerror.Maskf(invalidConfigError, "%T.Location must not be empty", config)
}
if config.Logger == nil {
return nil, microerror.Maskf(invalidConfigError, "%T.Logger must not be empty", config)
}
return &VMSKUs{
azureClientSet: config.AzureClientSet,
location: config.Location,
logger: config.Logger,
}, nil
}
func (v *VMSKUs) HasCapability(ctx context.Context, vmType string, name string) (bool, error) {
err := v.ensureInitialized(ctx)
if err != nil {
return false, microerror.Mask(err)
}
vmsku, found := v.skus[vmType]
if !found {
return false, microerror.Maskf(skuNotFoundError, vmType)
}
if vmsku.Capabilities != nil {
for _, capability := range *vmsku.Capabilities {
if capability.Name != nil && *capability.Name == name {
if capability.Value != nil && strings.EqualFold(*capability.Value, string(CapabilitySupported)) {
return true, nil
}
}
}
}
return false, nil
}
func (v *VMSKUs) ensureInitialized(ctx context.Context) error {
v.initMutex.Lock()
defer v.initMutex.Unlock()
if len(v.skus) == 0 {
err := v.initCache(ctx)
if err != nil {
return microerror.Mask(err)
}
}
return nil
}
func (v *VMSKUs) initCache(ctx context.Context) error {
v.logger.Debugf(ctx, "Initializing cache for VMSKU")
cl := v.azureClientSet.ResourceSkusClient
filter := fmt.Sprintf("location eq '%s'", v.location)
v.logger.Debugf(ctx, "Filter is: '%s'", filter)
iterator, err := cl.ListComplete(ctx, filter)
if err != nil {
return microerror.Mask(err)
}
skus := map[string]*compute.ResourceSku{}
for iterator.NotDone() {
sku := iterator.Value()
skus[*sku.Name] = &sku
err := iterator.NextWithContext(ctx)
if err != nil {
return microerror.Mask(err)
}
}
v.skus = skus
v.logger.Debugf(ctx, "Number of SKUs in cache: '%d'", len(skus))
return nil
}