in src/WebJobs.Script.WebHost/Management/FunctionsSyncManager.cs [307:417]
private async Task<SyncTriggersPayload> GetSyncTriggersPayload()
{
PrepareSyncTriggers();
var hostOptions = _applicationHostOptions.CurrentValue.ToHostOptions();
var functionsMetadata = _functionMetadataManager.GetFunctionMetadata().Where(m => !m.IsProxy());
// trigger information used by the ScaleController
var triggers = await GetFunctionTriggers(functionsMetadata, hostOptions);
var triggersArray = new JArray(triggers);
int count = triggersArray.Count;
// add host configuration
JObject hostConfig = null;
if (Utility.TryGetHostService<IHostOptionsProvider>(_scriptHostManager, out IHostOptionsProvider hostOptionsProvider))
{
hostConfig = hostOptionsProvider.GetOptions();
}
// Form the base minimal result
string hostId = await _hostIdProvider.GetHostIdAsync(CancellationToken.None);
JObject result = GetMinimalPayload(hostId, triggersArray, hostConfig);
if (!ArmCacheEnabled)
{
// extended format is disabled - just return minimal results
return new SyncTriggersPayload
{
Content = JsonConvert.SerializeObject(result),
Count = count
};
}
// Add all listable functions details to the payload
var listableFunctions = _functionMetadataManager.GetFunctionMetadata().Where(m => !m.IsCodeless());
var functionDetails = await WebFunctionsManager.GetFunctionMetadataResponse(listableFunctions, hostOptions, _hostNameProvider, excludeTestData: _hostingConfigOptions.Value.IsTestDataSuppressionEnabled);
result.Add("functions", new JArray(functionDetails.Select(p => JObject.FromObject(p))));
// TEMP: refactor this code to properly add extensions in all scenario(#7394)
// Add the host.json extensions to the payload
if (_environment.IsKubernetesManagedHosting())
{
JObject extensionsPayload = await GetHostJsonExtensionsAsync(_applicationHostOptions, _logger);
if (extensionsPayload != null)
{
result.Add("extensions", extensionsPayload);
}
}
if (_secretManagerProvider.SecretsEnabled)
{
// Add functions secrets to the payload
// Only secret types we own/control can we cache directly
// Encryption is handled by Antares before storage
var secretsStorageType = _environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageType);
if (string.IsNullOrEmpty(secretsStorageType) ||
string.Equals(secretsStorageType, "files", StringComparison.OrdinalIgnoreCase) ||
string.Equals(secretsStorageType, "blob", StringComparison.OrdinalIgnoreCase))
{
var functionAppSecrets = new FunctionAppSecrets();
// add host secrets
var hostSecretsInfo = await _secretManagerProvider.Current.GetHostSecretsAsync();
functionAppSecrets.Host = new FunctionAppSecrets.HostSecrets
{
Master = hostSecretsInfo.MasterKey,
Function = hostSecretsInfo.FunctionKeys,
System = hostSecretsInfo.SystemKeys
};
// add function secrets
var httpFunctions = functionsMetadata.Where(p => !p.IsProxy() && p.InputBindings.Any(q => q.IsTrigger && string.Equals(q.Type, "httptrigger", StringComparison.OrdinalIgnoreCase))).Select(p => p.Name).ToArray();
functionAppSecrets.Function = new FunctionAppSecrets.FunctionSecrets[httpFunctions.Length];
for (int i = 0; i < httpFunctions.Length; i++)
{
var currFunctionName = httpFunctions[i];
var currSecrets = await _secretManagerProvider.Current.GetFunctionSecretsAsync(currFunctionName);
functionAppSecrets.Function[i] = new FunctionAppSecrets.FunctionSecrets
{
Name = currFunctionName,
Secrets = currSecrets
};
}
result.Add("secrets", JObject.FromObject(functionAppSecrets));
}
else
{
// TODO: handle other external key storage types
// like KeyVault when the feature comes online
}
}
string json = JsonConvert.SerializeObject(result);
if (json.Length > ScriptConstants.MaxTriggersStringLength && !_environment.IsKubernetesManagedHosting())
{
// The settriggers call to the FE enforces a max request size limit.
// If we're over limit, revert to the minimal triggers format.
_logger.LogWarning($"SyncTriggers payload of length '{json.Length}' exceeds max length of '{ScriptConstants.MaxTriggersStringLength}'. Reverting to minimal format.");
var minimalResult = GetMinimalPayload(hostId, triggersArray, hostConfig);
json = JsonConvert.SerializeObject(minimalResult);
}
return new SyncTriggersPayload
{
Content = json,
Count = count
};
}