如何以编程方式启用/禁用Azure功能

时间:2017-02-22 19:51:49

标签: azure azure-webjobs azure-functions

有没有办法以编程方式启用/禁用Azure功能?

我可以使用“管理”部分下的门户启用/禁用某个功能,这会导致请求发送到https://<myfunctionapp>.scm.azurewebsites.net/api/functions/<myfunction>

JSON有效负载看起来有点像:

{
   "name":"SystemEventFunction",
   "config":{
      "disabled":true,
      "bindings":[ 
         // the bindings for this function
       ]
   }
  // lots of other properties (mostly URIs)
}

我正在门户网站外创建一个管理工具,允许用户启用和禁用功能。

希望我可以避免手动创建JSON有效负载,所以我想知道SDK(WebJobs ??)中是否有具有此功能的东西。

5 个答案:

答案 0 :(得分:7)

继@James Z。的答案之后,我在C#中创建了以下类,允许您以编程方式禁用/启用Azure功能。

functionsSiteRoot构造函数参数是函数应用程序的Kudu根,例如https://your-functions-web-app.scm.azurewebsites.net/api/vfs/site/wwwroot/

用户名和密码可以从&#34;获取发布资料&#34;在您的功能的应用程序服务设置中。

public class FunctionsHelper : IFunctionsHelper
{
    private readonly string _username;
    private readonly string _password;
    private readonly string _functionsSiteRoot;
    private WebClient _webClient;

    public FunctionsHelper(string username, string password, string functionsSiteRoot)
    {
        _username = username;
        _password = password;
        _functionsSiteRoot = functionsSiteRoot;

        _webClient = new WebClient
        {
            Headers = { ["ContentType"] = "application/json" },
            Credentials = new NetworkCredential(username, password),
            BaseAddress = functionsSiteRoot
        };
    }

    public void StopFunction(string functionName)
    {
        SetFunctionState(functionName, isDisabled: true);
    }

    public void StartFunction(string functionName)
    {
        SetFunctionState(functionName, isDisabled: false);
    }

    private void SetFunctionState(string functionName, bool isDisabled)
    {
        var functionJson =
            JsonConvert.DeserializeObject<FunctionSettings>(_webClient.DownloadString(GetFunctionJsonUrl(functionName)));
        functionJson.disabled = isDisabled;
        _webClient.Headers["If-Match"] = "*";
        _webClient.UploadString(GetFunctionJsonUrl(functionName), "PUT", JsonConvert.SerializeObject(functionJson));
    }

    private static string GetFunctionJsonUrl(string functionName)
    {
        return $"{functionName}/function.json";
    }
}

internal class FunctionSettings
{
    public bool disabled { get; set; }
    public List<Binding> bindings { get; set; }
}

internal class Binding
{
    public string name { get; set; }
    public string type { get; set; }
    public string direction { get; set; }
    public string queueName { get; set; }
    public string connection { get; set; }
    public string accessRights { get; set; }
}

答案 1 :(得分:6)

不,目前无法做到这一点。 function.json中的disabled元数据属性决定了是否启用了一个函数。在门户中启用/禁用时,门户网站只会更新该值。

不确定它是否满足您的需求,但我会指出还有一个host.json functions数组,可用于控制将要加载的函数集(记录{{ 3}})。因此,例如,如果您只想启用10个​​函数中的2个,则可以将此属性设置为仅包含这2个函数名称的数组(例如"functions": [ "QueueProcessor", "GitHubWebHook" ]),并且只会加载/启用这些函数。但是,这与启用/禁用略有不同,因为您无法通过门户网站调用排除的函数,而您可以通过门户网站调用禁用的函数。

答案 2 :(得分:2)

我想你可以使用Kudu REST API(特别是VFS)来更新function.json中的禁用元数据属性。会禁用该功能吗? 这是Kudu REST API。 https://github.com/projectkudu/kudu/wiki/REST-API

答案 3 :(得分:2)

结合使用@Satya V 和@DavidGouge 的解决方案,我想出了这个:

public class FunctionsHelper
{
    private readonly ClientSecretCredential _tokenCredential;
    private readonly HttpClient _httpClient;

    public FunctionsHelper(string tenantId, string clientId, string clientSecret, string subscriptionId, string resourceGroup, string functionAppName)
    {
        var baseUrl =
            $"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{functionAppName}/";
        var httpClient = new HttpClient
        {
            BaseAddress = new Uri(baseUrl)
        };

        _httpClient = httpClient;
        
        _tokenCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
    }

    private async Task SetAuthHeader()
    {
        var accessToken = await GetAccessToken();
        _httpClient.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse($"Bearer {accessToken}");
    }

    private async Task<string> GetAccessToken()
    {
        return (await _tokenCredential.GetTokenAsync(
            new TokenRequestContext(new[] {"https://management.azure.com/.default"}))).Token;
    }
    
    public async Task StopFunction(string functionName)
    {
        await SetFunctionState(functionName, isDisabled: true);
    }

    public async Task StartFunction(string functionName)
    {
        await SetFunctionState(functionName, isDisabled: false);
    }

    private async Task SetFunctionState(string functionName, bool isDisabled)
    {
        await SetAuthHeader();
        var appSettings = await GetAppSettings();
        appSettings.properties[$"AzureWebJobs.{functionName}.Disabled"] = isDisabled ? "1" : "0";

        var payloadJson = JsonConvert.SerializeObject(new
        {
            kind = "<class 'str'>", appSettings.properties
        });

        var stringContent = new StringContent(payloadJson, Encoding.UTF8, "application/json");
        
        await _httpClient.PutAsync("config/appsettings?api-version=2019-08-01", stringContent);
    }
    
    private async Task<AppSettings> GetAppSettings()
    {
        var res  = await _httpClient.PostAsync("config/appsettings/list?api-version=2019-08-01", null);
        
        var content = await res.Content.ReadAsStringAsync();
        
        return JsonConvert.DeserializeObject<AppSettings>(content);
    }
}

internal class AppSettings
{ 
    public Dictionary<string, string> properties { get; set; }
}

使用 Kudu api 更新 function.json 文件的问题是它会在任何后续部署中被覆盖。这使用 Azure 的 Rest Api 来更新应用程序的配置。不过,您首先需要一个 Azure 服务原则才能使用该 API。

使用 Azure Cli,您可以运行 az ad sp create-for-rbac 来生成服务原则并获取客户端 ID 和客户端机密。由于 UpdateConfiguration 端点不允许您更新单个值,并且会用新值覆盖整个 Configuration 对象,因此您必须首先获取所有当前 Configuration 值,更新您想要的值,然后使用新值调用 Update 端点配置键和值。

答案 4 :(得分:0)

用于通过CLI禁用Azure功能的CLI命令-已记录here

 az functionapp config appsettings set --name <myFunctionApp> \
    --resource-group <myResourceGroup> \
    --settings AzureWebJobs.QueueTrigger.Disabled=true

我在运行上述命令时捕获了提琴手。 Azure CLI在Python进程上运行python进程正在向以下对象发出请求

https://management.azure.com更新应用设置。

enter image description here

在以下REST端点中获得了对同一端点的引用: https://docs.microsoft.com/en-us/rest/api/appservice/webapps/updateapplicationsettings

请求URI:

输入 https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/appsettings?api-version=2019-08-01

标题:

授权:承载<>; 内容类型:application / json; charset = utf-8

请求正文:

{“种类”:“ ”,“属性”: JSON }

我们可以对属性进行硬编码或动态获取。要禁用该功能,必须更新Properties的JSON节点: Azure.WebJobs.QueueTrigger.Disabled = True

要获取属性,可以使用终结点,可以引用Web Apps - List Application Settings 输出看起来如下:

enter image description here

希望这会有所帮助:)

相关问题