-
Notifications
You must be signed in to change notification settings - Fork 430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
standardize scope local cache #2657
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,9 @@ func NewMachineScope(params MachineScopeParams) (*MachineScope, error) { | |
if params.AzureMachine == nil { | ||
return nil, errors.New("azure machine is required when creating a MachineScope") | ||
} | ||
if params.Cache == nil { | ||
params.Cache = &MachineCache{} | ||
} | ||
|
||
helper, err := patch.NewHelper(params.AzureMachine, params.Client) | ||
if err != nil { | ||
|
@@ -101,59 +104,21 @@ type MachineScope struct { | |
|
||
// MachineCache stores common machine information so we don't have to hit the API multiple times within the same reconcile loop. | ||
type MachineCache struct { | ||
BootstrapData string | ||
BootstrapData *string | ||
VMImage *infrav1.Image | ||
VMSKU resourceskus.SKU | ||
availabilitySetSKU resourceskus.SKU | ||
} | ||
|
||
// InitMachineCache sets cached information about the machine to be used in the scope. | ||
func (m *MachineScope) InitMachineCache(ctx context.Context) error { | ||
ctx, _, done := tele.StartSpanWithLogger(ctx, "azure.MachineScope.InitMachineCache") | ||
defer done() | ||
|
||
if m.cache == nil { | ||
var err error | ||
m.cache = &MachineCache{} | ||
|
||
m.cache.BootstrapData, err = m.GetBootstrapData(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
m.cache.VMImage, err = m.GetVMImage(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
skuCache, err := resourceskus.GetCache(m, m.Location()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
m.cache.VMSKU, err = skuCache.Get(ctx, m.AzureMachine.Spec.VMSize, resourceskus.VirtualMachines) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to get VM SKU %s in compute api", m.AzureMachine.Spec.VMSize) | ||
} | ||
|
||
m.cache.availabilitySetSKU, err = skuCache.Get(ctx, string(compute.AvailabilitySetSkuTypesAligned), resourceskus.AvailabilitySets) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to get availability set SKU %s in compute api", string(compute.AvailabilitySetSkuTypesAligned)) | ||
} | ||
} | ||
|
||
return nil | ||
VMSKU *resourceskus.SKU | ||
availabilitySetSKU *resourceskus.SKU | ||
} | ||
|
||
// VMSpec returns the VM spec. | ||
func (m *MachineScope) VMSpec() azure.ResourceSpecGetter { | ||
func (m *MachineScope) VMSpec(ctx context.Context) azure.ResourceSpecGetter { | ||
spec := &virtualmachines.VMSpec{ | ||
Name: m.Name(), | ||
Location: m.Location(), | ||
ResourceGroup: m.ResourceGroup(), | ||
ClusterName: m.ClusterName(), | ||
Role: m.Role(), | ||
NICIDs: m.NICIDs(), | ||
NICIDs: m.NICIDs(ctx), | ||
SSHKeyData: m.AzureMachine.Spec.SSHPublicKey, | ||
Size: m.AzureMachine.Spec.VMSize, | ||
OSDisk: m.AzureMachine.Spec.OSDisk, | ||
|
@@ -168,10 +133,14 @@ func (m *MachineScope) VMSpec() azure.ResourceSpecGetter { | |
AdditionalCapabilities: m.AzureMachine.Spec.AdditionalCapabilities, | ||
ProviderID: m.ProviderID(), | ||
} | ||
if m.cache != nil { | ||
spec.SKU = m.cache.VMSKU | ||
spec.Image = m.cache.VMImage | ||
spec.BootstrapData = m.cache.BootstrapData | ||
if bootstrapData, err := m.GetBootstrapData(ctx); err == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should be handling the errors here and below if I remember correctly that was one of the main reasons we decided to go with a separate |
||
spec.BootstrapData = bootstrapData | ||
} | ||
if vmSKU, err := m.GetVMSKU(ctx); err == nil { | ||
spec.SKU = *vmSKU | ||
} | ||
if image, err := m.GetVMImage(ctx); err == nil { | ||
spec.Image = image | ||
} | ||
return spec | ||
} | ||
|
@@ -227,7 +196,7 @@ func (m *MachineScope) InboundNatSpecs() []azure.ResourceSpecGetter { | |
} | ||
|
||
// NICSpecs returns the network interface specs. | ||
func (m *MachineScope) NICSpecs() []azure.ResourceSpecGetter { | ||
func (m *MachineScope) NICSpecs(ctx context.Context) []azure.ResourceSpecGetter { | ||
spec := &networkinterfaces.NICSpec{ | ||
Name: azure.GenerateNICName(m.Name()), | ||
ResourceGroup: m.ResourceGroup(), | ||
|
@@ -267,16 +236,16 @@ func (m *MachineScope) NICSpecs() []azure.ResourceSpecGetter { | |
spec.PublicIPName = azure.GenerateNodePublicIPName(m.Name()) | ||
} | ||
|
||
if m.cache != nil { | ||
spec.SKU = &m.cache.VMSKU | ||
if vmSKU, err := m.GetVMSKU(ctx); err == nil { | ||
spec.SKU = vmSKU | ||
} | ||
|
||
return []azure.ResourceSpecGetter{spec} | ||
} | ||
|
||
// NICIDs returns the NIC resource IDs. | ||
func (m *MachineScope) NICIDs() []string { | ||
nicspecs := m.NICSpecs() | ||
func (m *MachineScope) NICIDs(ctx context.Context) []string { | ||
nicspecs := m.NICSpecs(ctx) | ||
nicIDs := make([]string, len(nicspecs)) | ||
for i, nic := range nicspecs { | ||
nicIDs[i] = azure.NetworkInterfaceID(m.SubscriptionID(), nic.ResourceGroupName(), nic.ResourceName()) | ||
|
@@ -359,9 +328,9 @@ func (m *MachineScope) Subnet() infrav1.SubnetSpec { | |
|
||
// AvailabilityZone returns the AzureMachine Availability Zone. | ||
// Priority for selecting the AZ is | ||
// 1) Machine.Spec.FailureDomain | ||
// 2) AzureMachine.Spec.FailureDomain (This is to support deprecated AZ) | ||
// 3) No AZ | ||
// 1. Machine.Spec.FailureDomain | ||
// 2. AzureMachine.Spec.FailureDomain (This is to support deprecated AZ) | ||
// 3. No AZ | ||
func (m *MachineScope) AvailabilityZone() string { | ||
if m.Machine.Spec.FailureDomain != nil { | ||
return *m.Machine.Spec.FailureDomain | ||
|
@@ -423,7 +392,7 @@ func (m *MachineScope) ProviderID() string { | |
} | ||
|
||
// AvailabilitySetSpec returns the availability set spec for this machine if available. | ||
func (m *MachineScope) AvailabilitySetSpec() azure.ResourceSpecGetter { | ||
func (m *MachineScope) AvailabilitySetSpec(ctx context.Context) azure.ResourceSpecGetter { | ||
availabilitySetName, ok := m.AvailabilitySet() | ||
if !ok { | ||
return nil | ||
|
@@ -434,14 +403,12 @@ func (m *MachineScope) AvailabilitySetSpec() azure.ResourceSpecGetter { | |
ResourceGroup: m.ResourceGroup(), | ||
ClusterName: m.ClusterName(), | ||
Location: m.Location(), | ||
SKU: nil, | ||
AdditionalTags: m.AdditionalTags(), | ||
} | ||
|
||
if m.cache != nil { | ||
spec.SKU = &m.cache.availabilitySetSKU | ||
if avSKU, err := m.GetAvailabilitySetSKU(ctx); err == nil { | ||
spec.SKU = avSKU | ||
} | ||
|
||
return spec | ||
} | ||
|
||
|
@@ -617,6 +584,10 @@ func (m *MachineScope) GetBootstrapData(ctx context.Context) (string, error) { | |
ctx, _, done := tele.StartSpanWithLogger(ctx, "scope.MachineScope.GetBootstrapData") | ||
defer done() | ||
|
||
if m.cache.BootstrapData != nil { | ||
return to.String(m.cache.BootstrapData), nil | ||
} | ||
|
||
if m.Machine.Spec.Bootstrap.DataSecretName == nil { | ||
return "", errors.New("error retrieving bootstrap data: linked Machine's bootstrap.dataSecretName is nil") | ||
} | ||
|
@@ -630,7 +601,9 @@ func (m *MachineScope) GetBootstrapData(ctx context.Context) (string, error) { | |
if !ok { | ||
return "", errors.New("error retrieving bootstrap data: secret value key is missing") | ||
} | ||
return base64.StdEncoding.EncodeToString(value), nil | ||
bootstrapData := base64.StdEncoding.EncodeToString(value) | ||
m.cache.BootstrapData = to.StringPtr(bootstrapData) | ||
return bootstrapData, nil | ||
} | ||
|
||
// GetVMImage returns the image from the machine configuration, or a default one. | ||
|
@@ -643,17 +616,70 @@ func (m *MachineScope) GetVMImage(ctx context.Context) (*infrav1.Image, error) { | |
return m.AzureMachine.Spec.Image, nil | ||
} | ||
|
||
if m.cache.VMImage != nil { | ||
return m.cache.VMImage, nil | ||
} | ||
|
||
svc := virtualmachineimages.New(m) | ||
|
||
var ( | ||
err error | ||
defaultImage *infrav1.Image | ||
) | ||
if m.AzureMachine.Spec.OSDisk.OSType == azure.WindowsOS { | ||
runtime := m.AzureMachine.Annotations["runtime"] | ||
windowsServerVersion := m.AzureMachine.Annotations["windowsServerVersion"] | ||
log.Info("No image specified for machine, using default Windows Image", "machine", m.AzureMachine.GetName(), "runtime", runtime, "windowsServerVersion", windowsServerVersion) | ||
return svc.GetDefaultWindowsImage(ctx, m.Location(), to.String(m.Machine.Spec.Version), runtime, windowsServerVersion) | ||
defaultImage, err = svc.GetDefaultWindowsImage(ctx, m.Location(), to.String(m.Machine.Spec.Version), runtime, windowsServerVersion) | ||
} else { | ||
log.Info("No image specified for machine, using default Linux Image", "machine", m.AzureMachine.GetName()) | ||
defaultImage, err = svc.GetDefaultUbuntuImage(ctx, m.Location(), to.String(m.Machine.Spec.Version)) | ||
} | ||
|
||
if err != nil { | ||
return defaultImage, err | ||
} | ||
|
||
m.cache.VMImage = defaultImage | ||
return defaultImage, nil | ||
} | ||
|
||
// GetVMSKU returns the VM image SKU. | ||
func (m *MachineScope) GetVMSKU(ctx context.Context) (*resourceskus.SKU, error) { | ||
if m.cache.VMSKU != nil { | ||
return m.cache.VMSKU, nil | ||
} | ||
|
||
skuCache, err := resourceskus.GetCache(m, m.Location()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Info("No image specified for machine, using default Linux Image", "machine", m.AzureMachine.GetName()) | ||
return svc.GetDefaultUbuntuImage(ctx, m.Location(), to.String(m.Machine.Spec.Version)) | ||
sku, err := skuCache.Get(ctx, m.AzureMachine.Spec.VMSize, resourceskus.VirtualMachines) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed to get VM SKU %s in compute api", m.AzureMachine.Spec.VMSize) | ||
} | ||
m.cache.VMSKU = &sku | ||
return &sku, nil | ||
} | ||
|
||
// GetAvailabilitySetSKU returns the VM image SKU. | ||
func (m *MachineScope) GetAvailabilitySetSKU(ctx context.Context) (*resourceskus.SKU, error) { | ||
if m.cache.availabilitySetSKU != nil { | ||
return m.cache.availabilitySetSKU, nil | ||
} | ||
|
||
skuCache, err := resourceskus.GetCache(m, m.Location()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
sku, err := skuCache.Get(ctx, string(compute.AvailabilitySetSkuTypesAligned), resourceskus.AvailabilitySets) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed to get availability set SKU %s in compute api", string(compute.AvailabilitySetSkuTypesAligned)) | ||
} | ||
m.cache.availabilitySetSKU = &sku | ||
return &sku, nil | ||
} | ||
|
||
// SetSubnetName defaults the AzureMachine subnet name to the name of one the subnets with the machine role when there is only one of them. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devigned do you have any concerns about replacing this "do a one-time initiatlization of all cached properties when we instantiate scope" vs implement the property value caching on demand?
My thinking (and this was @CecileRobertMichon 's thinking when we implemented caching in a prior PR) is that not all scope lifecycles are going to require access to all of these properties, and so in the act of caching them we are actually deoptimizing things by fetching data unnecessarily.