diff --git a/README.md b/README.md index 2834da8a..ba9e1812 100644 --- a/README.md +++ b/README.md @@ -407,7 +407,7 @@ proxy_url = VALUE | [function\_app\_storage\_account\_prefix](#input\_function\_app\_storage\_account\_prefix) | Weka storage account name prefix | `string` | `"weka"` | no | | [function\_app\_subnet\_delegation\_cidr](#input\_function\_app\_subnet\_delegation\_cidr) | Subnet delegation enables you to designate a specific subnet for an Azure PaaS service. | `string` | `"10.0.1.0/25"` | no | | [function\_app\_subnet\_delegation\_id](#input\_function\_app\_subnet\_delegation\_id) | Required to specify if subnet\_name were used to specify pre-defined subnets for weka. Function subnet delegation requires an additional subnet, and in the case of pre-defined networking this one also should be pre-defined | `string` | `""` | no | -| [function\_app\_version](#input\_function\_app\_version) | Function app code version (hash) | `string` | `"1724b274e2e6e636b84109b2d459000f"` | no | +| [function\_app\_version](#input\_function\_app\_version) | Function app code version (hash) | `string` | `"7b4b459de8ab86c1a9e0c43e34346274"` | no | | [get\_weka\_io\_token](#input\_get\_weka\_io\_token) | The token to download the Weka release from get.weka.io. | `string` | `""` | no | | [hotspare](#input\_hotspare) | Number of hotspares to set on weka cluster. Refer to https://docs.weka.io/overview/ssd-capacity-management#hot-spare | `number` | `1` | no | | [install\_cluster\_dpdk](#input\_install\_cluster\_dpdk) | Install weka cluster with DPDK | `bool` | `true` | no | diff --git a/function-app/code/common/common.go b/function-app/code/common/common.go index a671b3d0..7d7c3106 100644 --- a/function-app/code/common/common.go +++ b/function-app/code/common/common.go @@ -1315,11 +1315,34 @@ func GetScaleSetNameWithLatestConfiguration(ctx context.Context, subscriptionId, err = fmt.Errorf("failed to read vmss state: %v", err) return } + return GetScaleSetNameWithLatestConfigurationFromState(ctx, subscriptionId, resourceGroupName, &vmssState) +} + +func GetScaleSetNameWithLatestConfigurationFromState(ctx context.Context, subscriptionId, resourceGroupName string, vmssState *VMSSState) (scaleSetName string, err error) { latestVersion := vmssState.GetLatestVersion() scaleSetName = GetVmScaleSetName(vmssState.Prefix, vmssState.ClusterName, latestVersion) return scaleSetName, nil } +func GetLatestScaleSetConfiguration(ctx context.Context, subscriptionId, resourceGroupName string, vmssState *VMSSState) (vmssConfig *VMSSConfig, err error) { + logger := logging.LoggerFromCtx(ctx) + + scaleSetName, err := GetScaleSetNameWithLatestConfigurationFromState(ctx, subscriptionId, resourceGroupName, vmssState) + if err != nil { + err = fmt.Errorf("cannot get the latest scale set name: %w", err) + logger.Error().Err(err).Send() + return + } + scaleSet, err := getScaleSet(ctx, subscriptionId, resourceGroupName, scaleSetName) + if err != nil { + err = fmt.Errorf("cannot get the latest scale set: %w", err) + logger.Error().Err(err).Send() + return + } + vmssConfig = GetVmssConfig(ctx, resourceGroupName, scaleSet) + return +} + func GetScaleSetsByVersion(ctx context.Context, subscriptionId, resourceGroupName string, vmssState *VMSSState) (map[int]*armcompute.VirtualMachineScaleSet, error) { logger := logging.LoggerFromCtx(ctx) @@ -1421,13 +1444,20 @@ func GetVmssConfig(ctx context.Context, resourceGroupName string, scaleSet *armc ppg = &val } + var sourceImageID string + if scaleSet.Properties.VirtualMachineProfile.StorageProfile.ImageReference.CommunityGalleryImageID != nil { + sourceImageID = *scaleSet.Properties.VirtualMachineProfile.StorageProfile.ImageReference.CommunityGalleryImageID + } else { + sourceImageID = *scaleSet.Properties.VirtualMachineProfile.StorageProfile.ImageReference.ID + } + vmssConfig := &VMSSConfig{ Name: *scaleSet.Name, Location: *scaleSet.Location, Zones: PtrArrToStrArray(scaleSet.Zones), ResourceGroupName: resourceGroupName, SKU: *scaleSet.SKU.Name, - SourceImageID: *scaleSet.Properties.VirtualMachineProfile.StorageProfile.ImageReference.CommunityGalleryImageID, + SourceImageID: sourceImageID, Tags: PtrMapToStrMap(scaleSet.Tags), UpgradeMode: string(*scaleSet.Properties.UpgradePolicy.Mode), diff --git a/function-app/code/common/vmss_config.go b/function-app/code/common/vmss_config.go index 192ee2c5..d9ee339d 100644 --- a/function-app/code/common/vmss_config.go +++ b/function-app/code/common/vmss_config.go @@ -176,8 +176,9 @@ func (q *VMSSState) RemoveVersion(item int) error { } type VMSSStateVerbose struct { - ActiveVmssNames []string `json:"active_vmss_names"` - TargetConfig VMSSConfig `json:"target_config"` + ActiveVmssNames []string `json:"active_vmss_names"` + TargetConfig VMSSConfig `json:"target_config"` + LatestConfig *VMSSConfig `json:"latest_config,omitempty"` } func ToEnumStrValue[T interface{ ~string }](val string, possibleEnumValues []T) (*T, error) { diff --git a/function-app/code/functions/scale_up/scale_up.go b/function-app/code/functions/scale_up/scale_up.go index 34313b73..e53bab05 100644 --- a/function-app/code/functions/scale_up/scale_up.go +++ b/function-app/code/functions/scale_up/scale_up.go @@ -159,6 +159,10 @@ func HandleVmssUpdate(ctx context.Context, currentConfig, newConfig *common.VMSS msg := fmt.Sprintf("cannot change vmss SKU from %s to %s, need refresh", currentConfig.SKU, newConfig.SKU) logger.Info().Msg(msg) refreshNeeded = true + } else if currentConfig.SourceImageID != newConfig.SourceImageID { + msg := fmt.Sprintf("cannot change vmss source image from %s to %s, need refresh", currentConfig.SourceImageID, newConfig.SourceImageID) + logger.Info().Msg(msg) + refreshNeeded = true } else { _, err := common.CreateOrUpdateVmss(ctx, subscriptionId, resourceGroupName, currentConfig.Name, newConfigHash, *newConfig, desiredSize) if err != nil { diff --git a/function-app/code/functions/status/status.go b/function-app/code/functions/status/status.go index 8733a7bd..95e629fb 100644 --- a/function-app/code/functions/status/status.go +++ b/function-app/code/functions/status/status.go @@ -104,12 +104,15 @@ func GetClusterStatus( return } -func GetRefreshStatus(ctx context.Context, subscriptionId, resourceGroupName, stateStorageName, stateContainerName string) (*common.VMSSStateVerbose, error) { - scaleSetNames, err := common.GetScaleSetsNames(ctx, subscriptionId, resourceGroupName, stateStorageName, stateContainerName) +func GetRefreshStatus(ctx context.Context, subscriptionId, resourceGroupName, stateStorageName, stateContainerName string, extended bool) (*common.VMSSStateVerbose, error) { + vmssState, err := common.ReadVmssState(ctx, stateStorageName, stateContainerName) if err != nil { + err = fmt.Errorf("failed to read vmss state: %v", err) return nil, err } + scaleSetNames := common.GetScaleSetsNamesFromVmssState(ctx, subscriptionId, resourceGroupName, &vmssState) + vmssConfig, err := common.ReadVmssConfig(ctx, stateStorageName, stateContainerName) if err != nil { return nil, err @@ -121,6 +124,16 @@ func GetRefreshStatus(ctx context.Context, subscriptionId, resourceGroupName, st ActiveVmssNames: scaleSetNames, TargetConfig: vmssConfig, } + + if len(scaleSetNames) > 0 && extended { + latestConfig, err := common.GetLatestScaleSetConfiguration(ctx, subscriptionId, resourceGroupName, &vmssState) + if err != nil { + return nil, err + } + latestConfig.CustomData = "" + latestConfig.SshPublicKey = "" + result.LatestConfig = latestConfig + } return result, nil } @@ -172,7 +185,9 @@ func Handler(w http.ResponseWriter, r *http.Request) { } else if requestBody.Type == "progress" { result, err = GetReports(ctx, stateStorageName, stateContainerName) } else if requestBody.Type == "vmss" { - result, err = GetRefreshStatus(ctx, subscriptionId, resourceGroupName, stateStorageName, stateContainerName) + result, err = GetRefreshStatus(ctx, subscriptionId, resourceGroupName, stateStorageName, stateContainerName, false) + } else if requestBody.Type == "vmss-extended" { + result, err = GetRefreshStatus(ctx, subscriptionId, resourceGroupName, stateStorageName, stateContainerName, true) } else { result = "Invalid status type" } diff --git a/variables.tf b/variables.tf index fa00517a..b386d7fa 100644 --- a/variables.tf +++ b/variables.tf @@ -321,7 +321,7 @@ variable "function_app_storage_account_container_prefix" { variable "function_app_version" { type = string description = "Function app code version (hash)" - default = "1724b274e2e6e636b84109b2d459000f" + default = "7b4b459de8ab86c1a9e0c43e34346274" } variable "function_app_dist" {