Esempio n. 1
0
        private async Task PublishFunctionApp(Site functionApp, GitIgnoreParser ignoreParser, IDictionary <string, string> additionalAppSettings)
        {
            ColoredConsole.WriteLine("Getting site publishing info...");
            var functionAppRoot = ScriptHostHelpers.GetFunctionAppRootDirectory(Environment.CurrentDirectory);

            // For dedicated linux apps, we do not support run from package right now
            if (functionApp.IsLinux && !functionApp.IsDynamic && RunFromPackageDeploy)
            {
                ColoredConsole.WriteLine("Assuming --nozip (do not run from package) for publishing to Linux dedicated plan.");
                RunFromPackageDeploy = false;
            }

            var workerRuntime     = _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsWorkerRuntime, StringComparison.OrdinalIgnoreCase)).Value;
            var workerRuntimeEnum = string.IsNullOrEmpty(workerRuntime) ? WorkerRuntime.None : WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(workerRuntime);

            if (workerRuntimeEnum == WorkerRuntime.python && !functionApp.IsLinux)
            {
                throw new CliException("Publishing Python functions is only supported for Linux FunctionApps");
            }

            Func <Task <Stream> > zipStreamFactory = () => ZipHelper.GetAppZipFile(workerRuntimeEnum, functionAppRoot, BuildNativeDeps, NoBuild, ignoreParser, AdditionalPackages, ignoreDotNetCheck: true);

            // If Consumption Linux
            if (functionApp.IsLinux && (functionApp.IsDynamic || functionApp.IsElasticPremium))
            {
                await PublishRunFromPackage(functionApp, await zipStreamFactory());
            }
            // If Windows default
            else if (RunFromPackageDeploy)
            {
                await PublishRunFromPackageLocal(functionApp, zipStreamFactory);
            }
            // If Dedicated Linux or "--no-zip"
            else
            {
                await PublishZipDeploy(functionApp, zipStreamFactory);
            }

            if (PublishLocalSettings)
            {
                await PublishLocalAppSettings(functionApp, additionalAppSettings);
            }
            else if (additionalAppSettings.Any())
            {
                await PublishAppSettings(functionApp, new Dictionary <string, string>(), additionalAppSettings);
            }

            // Syncing triggers is not required when using zipdeploy api
            if ((functionApp.IsLinux && (functionApp.IsDynamic || functionApp.IsElasticPremium)) ||
                RunFromPackageDeploy)
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
                await SyncTriggers(functionApp);
            }
            await AzureHelper.PrintFunctionsInfo(functionApp, AccessToken, showKeys : true);
        }
        public async override Task RunAsync()
        {
            if (Console.IsOutputRedirected || Console.IsInputRedirected)
            {
                if (string.IsNullOrEmpty(TemplateName) ||
                    string.IsNullOrEmpty(FunctionName))
                {
                    ColoredConsole
                    .Error
                    .WriteLine(ErrorColor("Running with stdin\\stdout redirected. Command must specify --template, and --name explicitly."))
                    .WriteLine(ErrorColor("See 'func help function' for more details"));
                    return;
                }
            }

            var templates = await _templatesManager.Templates;

            templates = templates.Concat(_templatesManager.PythonTemplates);

            var language = _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsLanguageSetting, StringComparison.OrdinalIgnoreCase)).Value;

            if (string.IsNullOrWhiteSpace(language))
            {
                ColoredConsole.Write("Select a language: ");
                language = Language ?? SelectionMenuHelper.DisplaySelectionWizard(templates.Select(t => t.Metadata.Language).Distinct());

                ColoredConsole.WriteLine(TitleColor(language));

                language = InitAction.NormalizeLanguage(language);

                _secretsManager.SetSecret(Constants.FunctionsLanguageSetting, language);
                ColoredConsole
                .WriteLine(WarningColor("Starting from 2.0.1-beta.26 it's required to set a language for your project in your settings"))
                .WriteLine(WarningColor($"'{language}' has been set in your local.settings.json"));
            }

            if (language.Equals("csharp", StringComparison.OrdinalIgnoreCase))
            {
                language = "C#";
            }

            ColoredConsole.Write("Select a template: ");
            var name = TemplateName ?? SelectionMenuHelper.DisplaySelectionWizard(templates.Where(t => t.Metadata.Language.Equals(language, StringComparison.OrdinalIgnoreCase)).Select(t => t.Metadata.Name).Distinct());

            ColoredConsole.WriteLine(TitleColor(name));

            var template = templates.FirstOrDefault(t => t.Metadata.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && t.Metadata.Language.Equals(language, StringComparison.OrdinalIgnoreCase));

            if (template == null)
            {
                ColoredConsole.Error.WriteLine(ErrorColor($"Can't find template \"{name}\" in \"{language}\""));
            }
            else
            {
                ColoredConsole.Write($"Function name: [{template.Metadata.DefaultFunctionName}] ");
                var functionName = FunctionName ?? Console.ReadLine();
                functionName = string.IsNullOrEmpty(functionName) ? template.Metadata.DefaultFunctionName : functionName;
                await _templatesManager.Deploy(functionName, template);
            }
        }
Esempio n. 3
0
        private async Task <IDictionary <string, string> > GetConfigurationSettings(string scriptPath, Uri uri)
        {
            var settings = _secretsManager.GetSecrets();

            settings.TryAdd(Constants.WebsiteHostname, uri.Authority);

            // Add our connection strings
            var connectionStrings = _secretsManager.GetConnectionStrings();

            settings.AddRange(connectionStrings.ToDictionary(c => $"ConnectionStrings:{c.Name}", c => c.Value));
            settings.TryAdd(EnvironmentSettingNames.AzureWebJobsScriptRoot, scriptPath);

            var environment = Environment
                              .GetEnvironmentVariables()
                              .Cast <DictionaryEntry>()
                              .ToDictionary(k => k.Key.ToString(), v => v.Value.ToString());

            await CheckNonOptionalSettings(settings.Union(environment), scriptPath, SkipAzureStorageCheck);

            // when running locally in CLI we want the host to run in debug mode
            // which optimizes host responsiveness
            settings.TryAdd(Constants.AzureFunctionsEnvorinmentEnvironmentVariable, "Development");
            settings.TryAdd(Constants.AspNetCoreEnvironmentEnvironmentVariable, "Development");
            return(settings);
        }
        private void SetStorageServiceAndTaskHubClient(out AzureStorageOrchestrationService orchestrationService, out TaskHubClient taskHubClient, string connectionStringKey = null, string taskHubName = null)
        {
            _connectionStringKey = connectionStringKey ?? _connectionStringKey;
            _taskHubName         = taskHubName ?? _taskHubName;

            var connectionString = Environment.GetEnvironmentVariable(_connectionStringKey); // Prioritize environment variables

            connectionString = connectionString ?? _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(_connectionStringKey, StringComparison.OrdinalIgnoreCase)).Value;

            if (!string.IsNullOrEmpty(connectionString))
            {
                var settings = new AzureStorageOrchestrationServiceSettings
                {
                    TaskHubName             = _taskHubName,
                    StorageConnectionString = connectionString,
                };

                orchestrationService = new AzureStorageOrchestrationService(settings);
                taskHubClient        = new TaskHubClient(orchestrationService);
            }
            else
            {
                throw new CliException("No storage connection string found.");
            }
        }
Esempio n. 5
0
        public override async Task RunAsync()
        {
            var functionAppRoot = string.IsNullOrEmpty(FolderName)
                ? Path.Combine(Environment.CurrentDirectory, FolderName)
                : ScriptHostHelpers.GetFunctionAppRootDirectory(Environment.CurrentDirectory);

            string outputPath;

            if (string.IsNullOrEmpty(OutputPath))
            {
                outputPath = Path.Combine(Environment.CurrentDirectory, $"{Path.GetFileName(functionAppRoot)}.zip");
            }
            else
            {
                outputPath = Path.Combine(Environment.CurrentDirectory, OutputPath);
                if (FileSystemHelpers.DirectoryExists(outputPath))
                {
                    outputPath = Path.Combine(outputPath, $"{Path.GetFileName(functionAppRoot)}.zip");
                }
            }

            if (!FileSystemHelpers.FileExists(Path.Combine(functionAppRoot, ScriptConstants.HostMetadataFileName)))
            {
                throw new CliException($"Can't find {Path.Combine(functionAppRoot, ScriptConstants.HostMetadataFileName)}");
            }

            var workerRuntime     = _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsWorkerRuntime, StringComparison.OrdinalIgnoreCase)).Value;
            var workerRuntimeEnum = string.IsNullOrEmpty(workerRuntime) ? WorkerRuntime.None : WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(workerRuntime);

            var zipStream = await GetAppZipFile(workerRuntimeEnum, functionAppRoot);

            await FileSystemHelpers.WriteToFile(outputPath, zipStream);
        }
Esempio n. 6
0
        private async Task PublishAppSettings(Site functionApp)
        {
            var azureAppSettings = await _armManager.GetFunctionAppAppSettings(functionApp);

            var localAppSettings = _secretsManager.GetSecrets();
            var appSettings      = MergeAppSettings(azureAppSettings, localAppSettings);
            await _armManager.UpdateFunctionAppAppSettings(functionApp, appSettings);
        }
Esempio n. 7
0
        private async Task PublishFunctionApp(Site functionApp, GitIgnoreParser ignoreParser, IDictionary <string, string> additionalAppSettings)
        {
            ColoredConsole.WriteLine("Getting site publishing info...");
            var functionAppRoot = ScriptHostHelpers.GetFunctionAppRootDirectory(Environment.CurrentDirectory);

            if (functionApp.IsLinux && !functionApp.IsDynamic && RunFromZipDeploy)
            {
                throw new CliException("--zip is not supported with dedicated linux apps.");
            }

            var workerRuntime     = _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsWorkerRuntime, StringComparison.OrdinalIgnoreCase)).Value;
            var workerRuntimeEnum = string.IsNullOrEmpty(workerRuntime) ? WorkerRuntime.None : WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(workerRuntime);

            if (workerRuntimeEnum == WorkerRuntime.python && !functionApp.IsLinux)
            {
                throw new CliException("Publishing Python functions is only supported for Linux FunctionApps");
            }

            Func <Task <Stream> > zipStreamFactory = () => ZipHelper.GetAppZipFile(workerRuntimeEnum, functionAppRoot, BuildNativeDeps, ignoreParser, AdditionalPackages, ignoreDotNetCheck: true);

            // if consumption Linux, or --zip, run from zip
            if ((functionApp.IsLinux && functionApp.IsDynamic) || RunFromZipDeploy)
            {
                await PublishRunFromZip(functionApp, await zipStreamFactory());
            }
            else
            {
                await PublishZipDeploy(functionApp, zipStreamFactory);
            }

            if (PublishLocalSettings)
            {
                await PublishLocalAppSettings(functionApp, additionalAppSettings);
            }
            else if (additionalAppSettings.Any())
            {
                await PublishAppSettings(functionApp, new Dictionary <string, string>(), additionalAppSettings);
            }

            await Task.Delay(TimeSpan.FromSeconds(5));

            await SyncTriggers(functionApp);

            await AzureHelper.PrintFunctionsInfo(functionApp, AccessToken, showKeys : true);
        }
        private async Task InternalPublishFunctionApp(GitIgnoreParser ignoreParser)
        {
            ColoredConsole.WriteLine("Getting site publishing info...");
            var functionApp = await _armManager.GetFunctionAppAsync(FunctionAppName);

            var functionAppRoot = ScriptHostHelpers.GetFunctionAppRootDirectory(Environment.CurrentDirectory);

            if (functionApp.IsLinux && !functionApp.IsDynamicLinux && RunFromZipDeploy)
            {
                ColoredConsole
                .WriteLine(ErrorColor("--zip is not supported with dedicated linux apps."));
                return;
            }

            var workerRuntime = _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsWorkerRuntime, StringComparison.OrdinalIgnoreCase)).Value;

            if (!string.IsNullOrWhiteSpace(workerRuntime))
            {
                var worker = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(workerRuntime);
                if (worker == WorkerRuntime.python)
                {
                    if (!SkipWheelRestore)
                    {
                        await PythonHelpers.InstallPipWheel();

                        await PythonHelpers.DownloadWheels();
                    }
                    else
                    {
                        ColoredConsole.WriteLine("Skipping wheels download");
                    }
                }
            }

            // if consumption linux, or --zip, run from zip
            if (functionApp.IsDynamicLinux || RunFromZipDeploy)
            {
                await PublishRunFromZip(functionApp, functionAppRoot, ignoreParser);
            }
            else
            {
                await PublishZipDeploy(functionApp, functionAppRoot, ignoreParser);
            }
        }
        private async Task InternalPublishFunctionApp(GitIgnoreParser ignoreParser)
        {
            ColoredConsole.WriteLine("Getting site publishing info...");
            var functionApp = await _armManager.GetFunctionAppAsync(FunctionAppName);

            var functionAppRoot = ScriptHostHelpers.GetFunctionAppRootDirectory(Environment.CurrentDirectory);

            if (functionApp.IsLinux && !functionApp.IsDynamic && RunFromZipDeploy)
            {
                ColoredConsole
                .WriteLine(ErrorColor("--zip is not supported with dedicated linux apps."));
                return;
            }

            var workerRuntime     = _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsWorkerRuntime, StringComparison.OrdinalIgnoreCase)).Value;
            var workerRuntimeEnum = string.IsNullOrEmpty(workerRuntime) ? WorkerRuntime.None : WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(workerRuntime);

            if (workerRuntimeEnum == WorkerRuntime.python && !functionApp.IsLinux)
            {
                throw new CliException("Publishing Python functions is only supported for Linux FunctionApps");
            }

            var zipStream = await ZipHelper.GetAppZipFile(workerRuntimeEnum, functionAppRoot, BuildNativeDeps, ignoreParser);

            // if consumption Linux, or --zip, run from zip
            if ((functionApp.IsLinux && functionApp.IsDynamic) || RunFromZipDeploy)
            {
                await PublishRunFromZip(functionApp, zipStream);
            }
            else
            {
                await PublishZipDeploy(functionApp, zipStream);
            }

            await SyncTriggers(functionApp);

            if (PublishLocalSettings)
            {
                await PublishAppSettings(functionApp);
            }
        }
        public static WorkerRuntime GetCurrentWorkerRuntimeLanguage(ISecretsManager secretsManager)
        {
            var setting = secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsWorkerRuntime, StringComparison.OrdinalIgnoreCase)).Value;

            try
            {
                return(NormalizeWorkerRuntime(setting));
            }
            catch
            {
                return(WorkerRuntime.None);
            }
        }
        /// <summary>
        /// This method reads the secrets from local.settings.json and sets them
        /// AppSettings are set in environment variables, ConfigurationManager.AppSettings
        /// ConnectionStrings are only set in ConfigurationManager.ConnectionStrings
        ///
        /// It also sets up a FileSystemWatcher that kills the current running process
        /// when local.settings.json is updated.
        /// </summary>
        private async Task ReadSecrets(string scriptPath)
        {
            var secrets = _secretsManager.GetSecrets();

            UpdateEnvironmentVariables(secrets);
            UpdateAppSettings(secrets);
            UpdateConnectionStrings(_secretsManager.GetConnectionStrings());

            await CheckNonOptionalSettings(secrets, scriptPath);

            fsWatcher          = new FileSystemWatcher(Path.GetDirectoryName(SecretsManager.AppSettingsFilePath), SecretsManager.AppSettingsFileName);
            fsWatcher.Changed += (s, e) =>
            {
                Environment.Exit(ExitCodes.Success);
            };
            fsWatcher.EnableRaisingEvents = true;
        }
        private async Task <bool> PublishAppSettings(Site functionApp)
        {
            var azureAppSettings = await _armManager.GetFunctionAppAppSettings(functionApp);

            var localAppSettings = _secretsManager.GetSecrets();
            var appSettings      = MergeAppSettings(azureAppSettings, localAppSettings);
            var result           = await _armManager.UpdateFunctionAppAppSettings(functionApp, appSettings);

            if (!result.IsSuccessful)
            {
                ColoredConsole
                .Error
                .WriteLine(ErrorColor("Error updating app settings:"))
                .WriteLine(ErrorColor(result.ErrorResult));
                return(false);
            }
            return(true);
        }
Esempio n. 13
0
        /// <summary>
        /// This method reads the secrets from local.settings.json and sets them
        /// AppSettings are set in environment variables, ConfigurationManager.AppSettings
        /// ConnectionStrings are only set in ConfigurationManager.ConnectionStrings
        ///
        /// It also sets up a FileSystemWatcher that kills the current running process
        /// when local.settings.json is updated.
        /// </summary>
        private async Task ReadSecrets(string scriptPath, Uri uri)
        {
            var secrets     = _secretsManager.GetSecrets();
            var environment = Environment
                              .GetEnvironmentVariables()
                              .Cast <DictionaryEntry>()
                              .ToDictionary(k => k.Key.ToString(), v => v.Value.ToString());

            UpdateEnvironmentVariables(secrets, uri);
            UpdateAppSettings(secrets);
            UpdateConnectionStrings(_secretsManager.GetConnectionStrings());

            await CheckNonOptionalSettings(secrets.Union(environment), scriptPath);

            fsWatcher          = new FileSystemWatcher(Path.GetDirectoryName(SecretsManager.AppSettingsFilePath), SecretsManager.AppSettingsFileName);
            fsWatcher.Changed += (s, e) =>
            {
                Environment.Exit(ExitCodes.Success);
            };
            fsWatcher.EnableRaisingEvents = true;
        }
Esempio n. 14
0
        public override Task RunAsync()
        {
            ColoredConsole.WriteLine(TitleColor("App Settings:"));
            foreach (var pair in _secretsManager.GetSecrets())
            {
                ColoredConsole
                .WriteLine($"   -> {TitleColor("Name")}: {pair.Key}")
                .WriteLine($"      {TitleColor("Value")}: {(ShowValues ? pair.Value : "*****")}")
                .WriteLine();
            }

            ColoredConsole.WriteLine(TitleColor("Connection Strings:"));
            foreach (var pair in _secretsManager.GetConnectionStrings())
            {
                ColoredConsole
                .WriteLine($"   -> {TitleColor("Name")}: {pair.Key}")
                .WriteLine($"      {TitleColor("Value")}: {(ShowValues ? pair.Value : "*****")}")
                .WriteLine();
            }

            return(Task.CompletedTask);
        }
        public override async Task RunAsync()
        {
            (var resolvedImageName, var shouldBuild) = ResolveImageName();
            TriggersPayload triggers = null;

            if (DryRun)
            {
                if (shouldBuild)
                {
                    // don't build on a --dry-run.
                    // read files from the local dir
                    triggers = await GetTriggersLocalFiles();
                }
                else
                {
                    triggers = await DockerHelpers.GetTriggersFromDockerImage(resolvedImageName);
                }
            }
            else
            {
                if (shouldBuild)
                {
                    await DockerHelpers.DockerBuild(resolvedImageName, Environment.CurrentDirectory);
                }
                triggers = await DockerHelpers.GetTriggersFromDockerImage(resolvedImageName);
            }

            (var resources, var funcKeys) = await KubernetesHelper.GetFunctionsDeploymentResources(
                Name,
                resolvedImageName,
                Namespace,
                triggers,
                _secretsManager.GetSecrets(),
                PullSecret,
                SecretsCollectionName,
                ConfigMapName,
                UseConfigMap,
                PollingInterval,
                CooldownPeriod,
                ServiceType,
                MinReplicaCount,
                MaxReplicaCount,
                KeysSecretCollectionName,
                MountFuncKeysAsContainerVolume);

            if (DryRun)
            {
                ColoredConsole.WriteLine(KubernetesHelper.SerializeResources(resources, OutputSerializationOptions.Yaml));
            }
            else
            {
                if (!await KubernetesHelper.NamespaceExists(Namespace))
                {
                    await KubernetesHelper.CreateNamespace(Namespace);
                }

                if (shouldBuild)
                {
                    await DockerHelpers.DockerPush(resolvedImageName);
                }

                foreach (var resource in resources)
                {
                    await KubectlHelper.KubectlApply(resource, showOutput : true, ignoreError : IgnoreErrors, @namespace : Namespace);
                }

                //Print the function keys message to the console
                await KubernetesHelper.PrintFunctionsInfo($"{Name}-http", Namespace, funcKeys, triggers);
            }
        }
Esempio n. 16
0
        private async Task <bool> PublishLocalAppSettings(Site functionApp, IDictionary <string, string> additionalAppSettings)
        {
            var localAppSettings = _secretsManager.GetSecrets();

            return(await PublishAppSettings(functionApp, localAppSettings, additionalAppSettings));
        }
        public async override Task RunAsync()
        {
            if (Console.IsOutputRedirected || Console.IsInputRedirected)
            {
                if (string.IsNullOrEmpty(TemplateName) ||
                    string.IsNullOrEmpty(FunctionName))
                {
                    ColoredConsole
                    .Error
                    .WriteLine(ErrorColor("Running with stdin\\stdout redirected. Command must specify --template, and --name explicitly."))
                    .WriteLine(ErrorColor("See 'func help function' for more details"));
                    return;
                }
            }

            var templates     = await _templatesManager.Templates;
            var workerRuntime = _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsWorkerRuntime, StringComparison.OrdinalIgnoreCase)).Value;

            if (!string.IsNullOrWhiteSpace(workerRuntime) && !string.IsNullOrWhiteSpace(Language))
            {
                // validate
                var worker   = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(workerRuntime);
                var language = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(Language);
                if (worker != language)
                {
                    throw new CliException("Selected language doesn't match worker set in local.settings.json." +
                                           $"Selected worker is: {worker} and selected language is: {language}");
                }
            }
            else if (string.IsNullOrWhiteSpace(Language))
            {
                if (string.IsNullOrWhiteSpace(workerRuntime))
                {
                    ColoredConsole.Write("Select a language: ");
                    Language = SelectionMenuHelper.DisplaySelectionWizard(templates.Select(t => t.Metadata.Language).Where(l => !l.Equals("python", StringComparison.OrdinalIgnoreCase)).Distinct());
                    var worker = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(Language);

                    _secretsManager.SetSecret(Constants.FunctionsWorkerRuntime, worker.ToString());
                    ColoredConsole
                    .WriteLine(WarningColor("Starting from 2.0.1-beta.26 it's required to set a language for your project in your settings"))
                    .WriteLine(WarningColor($"'{worker}' has been set in your local.settings.json"));
                }
                else
                {
                    var worker    = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(workerRuntime);
                    var languages = WorkerRuntimeLanguageHelper.LanguagesForWorker(worker);
                    ColoredConsole.Write("Select a language: ");
                    var displayList = templates
                                      .Select(t => t.Metadata.Language)
                                      .Where(l => languages.Contains(l, StringComparer.OrdinalIgnoreCase))
                                      .Distinct()
                                      .ToArray();
                    if (displayList.Length == 1)
                    {
                        Language = displayList.First();
                    }
                    else
                    {
                        Language = SelectionMenuHelper.DisplaySelectionWizard(displayList);
                    }
                }
            }
            else if (!string.IsNullOrWhiteSpace(Language))
            {
                var worker = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(Language);
                _secretsManager.SetSecret(Constants.FunctionsWorkerRuntime, worker.ToString());
                ColoredConsole
                .WriteLine(WarningColor("Starting from 2.0.1-beta.26 it's required to set a language for your project in your settings"))
                .WriteLine(WarningColor($"'{worker}' has been set in your local.settings.json"));
            }

            ColoredConsole.Write("Select a template: ");
            var name = TemplateName ?? SelectionMenuHelper.DisplaySelectionWizard(templates.Where(t => t.Metadata.Language.Equals(Language, StringComparison.OrdinalIgnoreCase)).Select(t => t.Metadata.Name).Distinct());

            ColoredConsole.WriteLine(TitleColor(name));

            var template = templates.FirstOrDefault(t => t.Metadata.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && t.Metadata.Language.Equals(Language, StringComparison.OrdinalIgnoreCase));

            if (template == null)
            {
                ColoredConsole.Error.WriteLine(ErrorColor($"Can't find template \"{name}\" in \"{Language}\""));
            }
            else
            {
                ColoredConsole.Write($"Function name: [{template.Metadata.DefaultFunctionName}] ");
                var functionName = FunctionName ?? Console.ReadLine();
                functionName = string.IsNullOrEmpty(functionName) ? template.Metadata.DefaultFunctionName : functionName;
                await _templatesManager.Deploy(functionName, template);
            }
        }
Esempio n. 18
0
        private async Task PublishFunctionApp(Site functionApp, GitIgnoreParser ignoreParser, IDictionary <string, string> additionalAppSettings)
        {
            ColoredConsole.WriteLine("Getting site publishing info...");
            var functionAppRoot = ScriptHostHelpers.GetFunctionAppRootDirectory(Environment.CurrentDirectory);

            // For dedicated linux apps, we do not support run from package right now
            var isFunctionAppDedicated = !functionApp.IsDynamic && !functionApp.IsElasticPremium;

            if (functionApp.IsLinux && isFunctionAppDedicated && RunFromPackageDeploy)
            {
                ColoredConsole.WriteLine("Assuming --nozip (do not run from package) for publishing to Linux dedicated plan.");
                RunFromPackageDeploy = false;
            }

            var workerRuntime     = _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsWorkerRuntime, StringComparison.OrdinalIgnoreCase)).Value;
            var workerRuntimeEnum = string.IsNullOrEmpty(workerRuntime) ? WorkerRuntime.None : WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(workerRuntime);

            if (workerRuntimeEnum == WorkerRuntime.python && !functionApp.IsLinux)
            {
                throw new CliException("Publishing Python functions is only supported for Linux FunctionApps");
            }

            Func <Task <Stream> > zipStreamFactory = () => ZipHelper.GetAppZipFile(workerRuntimeEnum, functionAppRoot, BuildNativeDeps, NoBuild, ignoreParser, AdditionalPackages, ignoreDotNetCheck: true);

            bool shouldSyncTriggers  = true;
            var  fileNameNoExtension = string.Format("{0}-{1}", DateTimeOffset.UtcNow.ToString("yyyyMMddHHmmss"), Guid.NewGuid());

            if (functionApp.IsLinux && functionApp.IsDynamic)
            {
                // Consumption Linux, try squashfs as a package format.
                if (workerRuntimeEnum == WorkerRuntime.python && !NoBuild && BuildNativeDeps)
                {
                    await PublishRunFromPackage(functionApp, await PythonHelpers.ZipToSquashfsStream(await zipStreamFactory()), $"{fileNameNoExtension}.squashfs");
                }
                else
                {
                    await PublishRunFromPackage(functionApp, await zipStreamFactory(), $"{fileNameNoExtension}.zip");
                }
            }
            else if (functionApp.IsLinux && functionApp.IsElasticPremium)
            {
                // Elastic Premium Linux
                await PublishRunFromPackage(functionApp, await zipStreamFactory(), $"{fileNameNoExtension}.zip");
            }
            else if (RunFromPackageDeploy)
            {
                // Windows default
                await PublishRunFromPackageLocal(functionApp, zipStreamFactory);
            }
            else
            {
                // ZipDeploy takes care of the SyncTriggers operation so we don't
                // need to perform one
                shouldSyncTriggers = false;

                // Dedicated Linux or "--no-zip"
                await PublishZipDeploy(functionApp, zipStreamFactory);
            }

            if (PublishLocalSettings)
            {
                await PublishLocalAppSettings(functionApp, additionalAppSettings);
            }
            else if (additionalAppSettings.Any())
            {
                await PublishAppSettings(functionApp, new Dictionary <string, string>(), additionalAppSettings);
            }

            if (shouldSyncTriggers)
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
                await SyncTriggers(functionApp);
            }

            // Linux Elastic Premium functions take longer to deploy. Right now, we cannot guarantee that functions info will be most up to date.
            // So, we only show the info, if Function App is not Linux Elastic Premium
            if (!(functionApp.IsLinux && functionApp.IsElasticPremium))
            {
                await AzureHelper.PrintFunctionsInfo(functionApp, AccessToken, ManagementURL, showKeys : true);
            }
        }