From a920cf62f22c43a519c052042b4ed5aa14684266 Mon Sep 17 00:00:00 2001 From: Ahmed ElSayed Date: Fri, 8 Sep 2017 10:24:40 -0700 Subject: [PATCH] Add a command to list functions in a function app. Closes #187 (#190) --- .../AzureActions/ListFunctionsActions.cs | 68 +++++++++++++++++++ .../Arm/Models/FunctionInfo.cs | 41 +++++++++++ .../Azure.Functions.Cli.csproj | 2 + 3 files changed, 111 insertions(+) create mode 100644 src/Azure.Functions.Cli/Actions/AzureActions/ListFunctionsActions.cs create mode 100644 src/Azure.Functions.Cli/Arm/Models/FunctionInfo.cs diff --git a/src/Azure.Functions.Cli/Actions/AzureActions/ListFunctionsActions.cs b/src/Azure.Functions.Cli/Actions/AzureActions/ListFunctionsActions.cs new file mode 100644 index 000000000..e64d7b36c --- /dev/null +++ b/src/Azure.Functions.Cli/Actions/AzureActions/ListFunctionsActions.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Azure.Functions.Cli.Arm; +using Colors.Net; +using static Azure.Functions.Cli.Common.OutputTheme; +using Azure.Functions.Cli.Helpers; +using System.Net.Http; +using Azure.Functions.Cli.Common; +using Azure.Functions.Cli.Interfaces; +using Azure.Functions.Cli.Arm.Models; + +namespace Azure.Functions.Cli.Actions.AzureActions +{ + [Action(Name = "list-functions", Context = Context.Azure, SubContext = Context.FunctionApp, HelpText = "List functions in a given function app on azure.")] + internal class ListFunctionsActions : BaseFunctionAppAction + { + private readonly ISettings _settings; + + public ListFunctionsActions(IArmManager armManager, ISettings settings) : base(armManager) + { + _settings = settings; + } + + public override async Task RunAsync() + { + var functionApp = await _armManager.GetFunctionAppAsync(FunctionAppName); + if (functionApp != null) + { + await RetryHelper.Retry(async () => + { + using (var client = new HttpClient() { BaseAddress = new Uri($"https://{functionApp.ScmUri}") }) + { + client.DefaultRequestHeaders.Authorization = await _armManager.GetAuthenticationHeader(_settings.CurrentSubscription); + + var response = await client.GetAsync(new Uri("api/functions", UriKind.Relative)); + + if (!response.IsSuccessStatusCode) + { + throw new CliException($"Error trying to retrieve list of functions ({response.StatusCode})."); + } + + var functions = await response.Content.ReadAsAsync>(); + + ColoredConsole.WriteLine(TitleColor($"Functions in {FunctionAppName}:")); + foreach (var function in functions) + { + var trigger = function + .Config?["bindings"] + ?.FirstOrDefault(o => o["type"]?.ToString().IndexOf("Trigger", StringComparison.OrdinalIgnoreCase) != -1) + ?["type"]; + + trigger = trigger ?? "No Trigger Found"; + + ColoredConsole.WriteLine($" {function.Name} - [{VerboseColor(trigger.ToString())}]"); + } + } + }, 2); + } + else + { + ColoredConsole.Error.WriteLine(ErrorColor($"Can't find function app by name {FunctionAppName}")); + } + } + } +} diff --git a/src/Azure.Functions.Cli/Arm/Models/FunctionInfo.cs b/src/Azure.Functions.Cli/Arm/Models/FunctionInfo.cs new file mode 100644 index 000000000..8a9fecbe4 --- /dev/null +++ b/src/Azure.Functions.Cli/Arm/Models/FunctionInfo.cs @@ -0,0 +1,41 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; + +namespace Azure.Functions.Cli.Arm.Models +{ + // https://github.com/projectkudu/kudu/blob/master/Kudu.Contracts/Functions/FunctionEnvelope.cs + internal class FunctionInfo + { + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + + [JsonProperty(PropertyName = "function_app_id")] + public string FunctionAppId { get; set; } + + [JsonProperty(PropertyName = "script_root_path_href")] + public Uri ScriptRootPathHref { get; set; } + + [JsonProperty(PropertyName = "script_href")] + public Uri ScriptHref { get; set; } + + [JsonProperty(PropertyName = "config_href")] + public Uri ConfigHref { get; set; } + + [JsonProperty(PropertyName = "secrets_file_href")] + public Uri SecretsFileHref { get; set; } + + [JsonProperty(PropertyName = "href")] + public Uri Href { get; set; } + + [JsonProperty(PropertyName = "config")] + public JObject Config { get; set; } + + [JsonProperty(PropertyName = "files")] + public IDictionary Files { get; set; } + + [JsonProperty(PropertyName = "test_data")] + public string TestData { get; set; } + } +} diff --git a/src/Azure.Functions.Cli/Azure.Functions.Cli.csproj b/src/Azure.Functions.Cli/Azure.Functions.Cli.csproj index 9efb1181e..ee36e01e5 100644 --- a/src/Azure.Functions.Cli/Azure.Functions.Cli.csproj +++ b/src/Azure.Functions.Cli/Azure.Functions.Cli.csproj @@ -579,6 +579,7 @@ + @@ -619,6 +620,7 @@ +