private FunctionAppSecrets WriteStartContextCache(string path) { var secrets = new FunctionAppSecrets(); secrets.Host = new FunctionAppSecrets.HostSecrets { Master = "test-master-key" }; secrets.Host.Function = new Dictionary <string, string> { { "test-host-function-1", "hostfunction1value" }, { "test-host-function-2", "hostfunction2value" } }; secrets.Host.System = new Dictionary <string, string> { { "test-system-1", "system1value" }, { "test-system-2", "system2value" } }; secrets.Function = new FunctionAppSecrets.FunctionSecrets[] { new FunctionAppSecrets.FunctionSecrets { Name = "function1", Secrets = new Dictionary <string, string> { { "test-function-1", "function1value" }, { "test-function-2", "function2value" } } }, new FunctionAppSecrets.FunctionSecrets { Name = "function2", Secrets = new Dictionary <string, string> { { "test-function-1", "function1value" }, { "test-function-2", "function2value" } } } }; var context = new JObject { { "secrets", JObject.FromObject(secrets) } }; string json = JsonConvert.SerializeObject(context); var encryptionKey = Convert.FromBase64String(TestEncryptionKey); string encryptedJson = SimpleWebTokenHelper.Encrypt(json, encryptionKey); File.WriteAllText(path, encryptedJson); return(secrets); }
public StartupContextProviderTests() { _secrets = new FunctionAppSecrets(); _secrets.Host = new FunctionAppSecrets.HostSecrets { Master = "test-master-key" }; _secrets.Host.Function = new Dictionary <string, string> { { "test-host-function-1", "hostfunction1value" }, { "test-host-function-2", "hostfunction2value" } }; _secrets.Host.System = new Dictionary <string, string> { { "test-system-1", "system1value" }, { "test-system-2", "system2value" } }; _secrets.Function = new FunctionAppSecrets.FunctionSecrets[] { new FunctionAppSecrets.FunctionSecrets { Name = "function1", Secrets = new Dictionary <string, string> { { "test-function-1", "function1value" }, { "test-function-2", "function2value" } } }, new FunctionAppSecrets.FunctionSecrets { Name = "function2", Secrets = new Dictionary <string, string> { { "test-function-1", "function1value" }, { "test-function-2", "function2value" } } } }; _environment = new TestEnvironment(); var loggerFactory = new LoggerFactory(); _loggerProvider = new TestLoggerProvider(); loggerFactory.AddProvider(_loggerProvider); _environment.SetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestEncryptionKey); _startupContextProvider = new StartupContextProvider(_environment, loggerFactory.CreateLogger <StartupContextProvider>()); }
public async Task Assigns_Context_From_CONTAINER_START_CONTEXT() { var containerEncryptionKey = TestHelpers.GenerateKeyHexString(); var hostAssignmentContext = GetHostAssignmentContext(); var secrets = new FunctionAppSecrets(); secrets.Host = new FunctionAppSecrets.HostSecrets { Master = "test-key", Function = new Dictionary <string, string> { { "host-function-key-1", "test-key" } }, System = new Dictionary <string, string> { { "host-system-key-1", "test-key" } } }; hostAssignmentContext.Secrets = secrets; hostAssignmentContext.MSIContext = new MSIContext(); var encryptedHostAssignmentContext = GetEncryptedHostAssignmentContext(hostAssignmentContext, containerEncryptionKey); var serializedContext = JsonConvert.SerializeObject(new { encryptedContext = encryptedHostAssignmentContext }); _environment.SetEnvironmentVariable(ContainerStartContext, serializedContext); _environment.SetEnvironmentVariable(ContainerEncryptionKey, containerEncryptionKey); AddLinuxConsumptionSettings(_environment); _instanceManagerMock.Setup(m => m.SpecializeMSISidecar(It.Is <HostAssignmentContext>(context => hostAssignmentContext.Equals(context) && !context.IsWarmupRequest))).Returns(Task.FromResult(string.Empty)); _instanceManagerMock.Setup(manager => manager.StartAssignment(It.Is <HostAssignmentContext>(context => hostAssignmentContext.Equals(context) && !context.IsWarmupRequest))).Returns(true); var initializationHostService = new LinuxContainerInitializationHostService(_environment, _instanceManagerMock.Object, NullLogger <LinuxContainerInitializationHostService> .Instance, _startupContextProvider); await initializationHostService.StartAsync(CancellationToken.None); _instanceManagerMock.Verify(m => m.SpecializeMSISidecar(It.Is <HostAssignmentContext>(context => hostAssignmentContext.Equals(context) && !context.IsWarmupRequest)), Times.Once); _instanceManagerMock.Verify(manager => manager.StartAssignment(It.Is <HostAssignmentContext>(context => hostAssignmentContext.Equals(context) && !context.IsWarmupRequest)), Times.Once); var hostSecrets = _startupContextProvider.GetHostSecretsOrNull(); Assert.Equal("test-key", hostSecrets.MasterKey); }
public async Task <SyncTriggersPayload> GetSyncTriggersPayload() { var hostOptions = _applicationHostOptions.CurrentValue.ToHostOptions(); var functionsMetadata = _functionMetadataManager.GetFunctionMetadata(); // trigger information used by the ScaleController var triggers = await GetFunctionTriggers(functionsMetadata, hostOptions); var triggersArray = new JArray(triggers); int count = triggersArray.Count; if (!ArmCacheEnabled) { // extended format is disabled - just return triggers return(new SyncTriggersPayload { Content = JsonConvert.SerializeObject(triggersArray), Count = count }); } // Add triggers to the payload JObject result = new JObject(); result.Add("triggers", triggersArray); // Add all listable functions details to the payload JObject functions = new JObject(); string routePrefix = await WebFunctionsManager.GetRoutePrefix(hostOptions.RootScriptPath); var listableFunctions = _functionMetadataManager.GetFunctionMetadata().Where(m => !m.IsCodeless()); var functionDetails = await WebFunctionsManager.GetFunctionMetadataResponse(listableFunctions, hostOptions, _hostNameProvider); 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.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."); return(new SyncTriggersPayload { Content = JsonConvert.SerializeObject(triggersArray), Count = count }); } return(new SyncTriggersPayload { Content = json, Count = count }); }