def set_website_settings(cmd, name, database_provider, database_admin, database_password, ai): settings = [] if ai: from azure.mgmt.cognitiveservices import CognitiveServicesManagementClient cogsvcs_client = get_mgmt_service_client( cmd.cli_ctx, CognitiveServicesManagementClient) cogsvcs_key = cogsvcs_client.accounts.list_keys(name, name).key1 settings.append('COGNITIVE_SERVICES_KEY={}'.format(cogsvcs_key)) if database_provider.lower() == 'cosmosdb': from azure.mgmt.cosmosdb import CosmosDB cosmosdb_client = get_mgmt_service_client(cmd.cli_ctx, CosmosDB) result = cosmosdb_client.database_accounts.list_keys( resource_group_name=name, account_name=name) database_password = result.primary_master_key # TODO: Update username to avoid issues database_options = DATABASES[database_provider.lower()] settings.append('DATABASE_NAME={}'.format(name)) settings.append('DATABASE_HOST={}'.format( database_options['host'].format(name))) settings.append('DATABASE_PORT={}'.format(database_options['port'])) settings.append('DATABASE_USER={}'.format(database_admin)) settings.append('DATABASE_PASSWORD={}'.format(database_password)) update_app_settings(cmd, resource_group_name=name, name=name, settings=settings) return settings
def update_settings(self, settings): app_settings = [] for key in settings: app_settings.append('{}={}'.format(key, settings[key])) if app_settings: update_app_settings(self.__cmd, resource_group_name=self.resource_group, name=self.name, settings=app_settings)
def __write_kv_to_app_service(cmd, key_values, appservice_account): try: non_slot_settings = [] slot_settings = [] for kv in key_values: name = kv.key value = kv.value if 'AppService:SlotSetting' not in kv.tags: raise CLIError( "key-values must contain 'AppService:SlotSetting' tag in order to export to AppService correctly." ) is_slot_setting = (kv.tags['AppService:SlotSetting'] == 'true') if is_slot_setting: slot_settings.append(name + '=' + value) else: non_slot_settings.append(name + '=' + value) # known issue 4/26: with in-place update, AppService could change slot-setting true/false incorrectly from azure.cli.command_modules.appservice.custom import update_app_settings update_app_settings( cmd, resource_group_name=appservice_account["resource_group"], name=appservice_account["name"], settings=non_slot_settings, slot_settings=slot_settings) except Exception as exception: raise CLIError("Fail to write key-values to appservice: " + str(exception))
def __write_kv_to_app_service(cmd, key_values, appservice_account): try: non_slot_settings = [] slot_settings = [] for kv in key_values: name = kv.key value = kv.value # If its a KeyVault ref, convert the format to AppService KeyVault ref format if kv.content_type and kv.content_type.lower() == KeyVaultConstants.KEYVAULT_CONTENT_TYPE: try: secret_uri = json.loads(value).get("uri") if secret_uri: value = KeyVaultConstants.APPSVC_KEYVAULT_PREFIX + '(SecretUri={0})'.format(secret_uri) else: logger.debug( 'Key "%s" with value "%s" is not a well-formatted KeyVault reference. It will be treated like a regular key-value.\n', name, value) except (AttributeError, TypeError, ValueError) as e: logger.debug( 'Key "%s" with value "%s" is not a well-formatted KeyVault reference. It will be treated like a regular key-value.\n%s', name, value, str(e)) if 'AppService:SlotSetting' in kv.tags and kv.tags['AppService:SlotSetting'] == 'true': slot_settings.append(name + '=' + value) else: non_slot_settings.append(name + '=' + value) # known issue 4/26: with in-place update, AppService could change slot-setting true/false incorrectly from azure.cli.command_modules.appservice.custom import update_app_settings update_app_settings(cmd, resource_group_name=appservice_account["resource_group"], name=appservice_account["name"], settings=non_slot_settings, slot_settings=slot_settings) except Exception as exception: raise CLIError("Failed to write key-values to appservice: " + str(exception))
def update_github_settings( cmd, resource_group_name, name, slot=None, # pylint: disable=unused-argument client_id=None, client_secret_setting_name=None, # pylint: disable=unused-argument scopes=None, client_secret=None, yes=False): # pylint: disable=unused-argument if client_secret is not None and client_secret_setting_name is not None: raise CLIError( 'Usage Error: --client-secret and --client-secret-setting-name cannot ' 'both be configured to non empty strings') if client_secret is not None and not yes: msg = 'Configuring --client-secret will add app settings to the web app. Are you sure you want to continue?' if not prompt_y_n(msg, default="n"): raise CLIError( 'Usage Error: --client-secret cannot be used without agreeing to add ' 'app settings to the web app.') existing_auth = get_auth_settings_v2(cmd, resource_group_name, name, slot)["properties"] registration = {} if "identityProviders" not in existing_auth.keys(): existing_auth["identityProviders"] = {} if "gitHub" not in existing_auth["identityProviders"].keys(): existing_auth["identityProviders"]["gitHub"] = {} if client_id is not None or client_secret is not None or client_secret_setting_name is not None: if "registration" not in existing_auth["identityProviders"][ "gitHub"].keys(): existing_auth["identityProviders"]["gitHub"]["registration"] = {} registration = existing_auth["identityProviders"]["gitHub"][ "registration"] if scopes is not None: if "login" not in existing_auth["identityProviders"]["gitHub"].keys(): existing_auth["identityProviders"]["gitHub"]["login"] = {} if client_id is not None: registration["clientId"] = client_id if client_secret_setting_name is not None: registration["clientSecretSettingName"] = client_secret_setting_name if client_secret is not None: registration["clientSecretSettingName"] = GITHUB_SECRET_SETTING_NAME settings = [] settings.append(GITHUB_SECRET_SETTING_NAME + '=' + client_secret) update_app_settings(cmd, resource_group_name, name, settings, slot) if scopes is not None: existing_auth["identityProviders"]["gitHub"]["login"][ "scopes"] = scopes.split(",") if client_id is not None or client_secret is not None or client_secret_setting_name is not None: existing_auth["identityProviders"]["gitHub"][ "registration"] = registration updated_auth_settings = update_auth_settings_v2_rest_call( cmd, resource_group_name, name, existing_auth, slot) return updated_auth_settings["identityProviders"]["gitHub"]
def prep_auth_settings_for_v2(cmd, resource_group_name, name, slot=None): # pylint: disable=unused-argument site_auth_settings = get_auth_settings(cmd, resource_group_name, name, slot) settings = [] if site_auth_settings.client_secret is not None: settings.append(MICROSOFT_SECRET_SETTING_NAME + '=' + site_auth_settings.client_secret) site_auth_settings.client_secret_setting_name = MICROSOFT_SECRET_SETTING_NAME if site_auth_settings.facebook_app_secret is not None: settings.append(FACEBOOK_SECRET_SETTING_NAME + '=' + site_auth_settings.facebook_app_secret) site_auth_settings.facebook_app_secret_setting_name = FACEBOOK_SECRET_SETTING_NAME if site_auth_settings.git_hub_client_secret is not None: settings.append(GITHUB_SECRET_SETTING_NAME + '=' + site_auth_settings.git_hub_client_secret) site_auth_settings.git_hub_client_secret_setting_name = GITHUB_SECRET_SETTING_NAME if site_auth_settings.google_client_secret is not None: settings.append(GOOGLE_SECRET_SETTING_NAME + '=' + site_auth_settings.google_client_secret) site_auth_settings.google_client_secret_setting_name = GOOGLE_SECRET_SETTING_NAME if site_auth_settings.microsoft_account_client_secret is not None: settings.append(MSA_SECRET_SETTING_NAME + '=' + site_auth_settings.microsoft_account_client_secret) site_auth_settings.microsoft_account_client_secret_setting_name = MSA_SECRET_SETTING_NAME if site_auth_settings.twitter_consumer_secret is not None: settings.append(TWITTER_SECRET_SETTING_NAME + '=' + site_auth_settings.twitter_consumer_secret) site_auth_settings.twitter_consumer_secret_setting_name = TWITTER_SECRET_SETTING_NAME if len(settings) > 0: update_app_settings(cmd, resource_group_name, name, settings, slot) remove_all_auth_settings_secrets(cmd, resource_group_name, name, slot) update_auth_classic_settings( cmd, resource_group_name, name, site_auth_settings.enabled, None, site_auth_settings.client_id, site_auth_settings.token_store_enabled, site_auth_settings.runtime_version, site_auth_settings.token_refresh_extension_hours, site_auth_settings.allowed_external_redirect_urls, None, site_auth_settings.client_secret_certificate_thumbprint, site_auth_settings.allowed_audiences, site_auth_settings.issuer, site_auth_settings.facebook_app_id, None, site_auth_settings.facebook_o_auth_scopes, site_auth_settings.twitter_consumer_key, None, site_auth_settings.google_client_id, None, site_auth_settings.google_o_auth_scopes, site_auth_settings.microsoft_account_client_id, None, site_auth_settings.microsoft_account_o_auth_scopes, slot, site_auth_settings.git_hub_client_id, None, site_auth_settings.git_hub_o_auth_scopes, site_auth_settings.client_secret_setting_name, site_auth_settings.facebook_app_secret_setting_name, site_auth_settings.google_client_secret_setting_name, site_auth_settings.microsoft_account_client_secret_setting_name, site_auth_settings.twitter_consumer_secret_setting_name, site_auth_settings.git_hub_client_secret_setting_name)
def update_twitter_settings( cmd, resource_group_name, name, slot=None, # pylint: disable=unused-argument consumer_key=None, consumer_secret_setting_name=None, # pylint: disable=unused-argument consumer_secret=None, yes=False): # pylint: disable=unused-argument if consumer_secret is not None and consumer_secret_setting_name is not None: raise CLIError( 'Usage Error: --consumer-secret and --consumer-secret-setting-name cannot ' 'both be configured to non empty strings') if consumer_secret is not None and not yes: msg = 'Configuring --consumer-secret will add app settings to the web app. Are you sure you want to continue?' if not prompt_y_n(msg, default="n"): raise CLIError( 'Usage Error: --consumer-secret cannot be used without agreeing ' 'to add app settings to the web app.') registration = {} existing_auth = get_auth_settings_v2(cmd, resource_group_name, name, slot)["properties"] if "identityProviders" not in existing_auth.keys(): existing_auth["identityProviders"] = {} if "twitter" not in existing_auth["identityProviders"].keys(): existing_auth["identityProviders"]["twitter"] = {} if consumer_key is not None or consumer_secret is not None or consumer_secret_setting_name is not None: if "registration" not in existing_auth["identityProviders"][ "twitter"].keys(): existing_auth["identityProviders"]["twitter"]["registration"] = {} registration = existing_auth["identityProviders"]["twitter"][ "registration"] if consumer_key is not None: registration["consumerKey"] = consumer_key if consumer_secret_setting_name is not None: registration[ "consumerSecretSettingName"] = consumer_secret_setting_name if consumer_secret is not None: registration["consumerSecretSettingName"] = TWITTER_SECRET_SETTING_NAME settings = [] settings.append(TWITTER_SECRET_SETTING_NAME + '=' + consumer_secret) update_app_settings(cmd, resource_group_name, name, settings, slot) if consumer_key is not None or consumer_secret is not None or consumer_secret_setting_name is not None: existing_auth["identityProviders"]["twitter"][ "registration"] = registration updated_auth_settings = update_auth_settings_v2_rest_call( cmd, resource_group_name, name, existing_auth, slot) return updated_auth_settings["identityProviders"]["twitter"]
def connect_webapp(cmd, client, resource_group_name, application, app_service, enable_profiler=None, enable_snapshot_debugger=None): from azure.cli.command_modules.appservice.custom import update_app_settings app_insights = client.get(resource_group_name, application) if app_insights is None or app_insights.instrumentation_key is None: raise InvalidArgumentValueError( "App Insights {} under resource group {} was not found.".format( application, resource_group_name)) settings = [ "APPINSIGHTS_INSTRUMENTATIONKEY={}".format( app_insights.instrumentation_key) ] if enable_profiler is True: settings.append("APPINSIGHTS_PROFILERFEATURE_VERSION=1.0.0") elif enable_profiler is False: settings.append("APPINSIGHTS_PROFILERFEATURE_VERSION=disabled") if enable_snapshot_debugger is True: settings.append("APPINSIGHTS_SNAPSHOTFEATURE_VERSION=1.0.0") elif enable_snapshot_debugger is False: settings.append("APPINSIGHTS_SNAPSHOTFEATURE_VERSION=disabled") return update_app_settings(cmd, resource_group_name, app_service, settings)
def connect_function(cmd, client, resource_group_name, application, app_service): from azure.cli.command_modules.appservice.custom import update_app_settings app_insights = client.get(resource_group_name, application) if app_insights is None or app_insights.instrumentation_key is None: raise InvalidArgumentValueError("App Insights {} under resource group {} was not found.".format(application, resource_group_name)) settings = ["APPINSIGHTS_INSTRUMENTATIONKEY={}".format(app_insights.instrumentation_key)] return update_app_settings(cmd, resource_group_name, app_service, settings)
def connect_webapp(cmd, resource_group_name, webapp_name, enable_profiler=None, enable_snapshot_debugger=None): from azure.cli.command_modules.appservice.custom import update_app_settings settings = [] if enable_profiler is True: settings.append("APPINSIGHTS_PROFILERFEATURE_VERSION=1.0.0") elif enable_profiler is False: settings.append("APPINSIGHTS_PROFILERFEATURE_VERSION=disabled") if enable_snapshot_debugger is True: settings.append("APPINSIGHTS_SNAPSHOTFEATURE_VERSION=1.0.0") elif enable_snapshot_debugger is False: settings.append("APPINSIGHTS_SNAPSHOTFEATURE_VERSION=disabled") return update_app_settings(cmd, resource_group_name, webapp_name, settings)
def create_deploy_webapp(cmd, name, location=None, dryrun=False): import os client = web_client_factory(cmd.cli_ctx) # the code to deploy is expected to be the current directory the command is running from src_dir = os.getcwd() # if dir is empty, show a message in dry run do_deployment = False if os.listdir(src_dir) == [] else True # determine the details for app to be created from src contents lang_details = get_lang_from_content(src_dir) # we support E2E create and deploy for Node & dotnetcore, any other stack, set defaults for os & runtime # and skip deployment if lang_details['language'] is None: do_deployment = False sku = 'F1' os_val = OS_DEFAULT detected_version = '-' runtime_version = '-' else: sku = lang_details.get("default_sku") language = lang_details.get("language") is_skip_build = language.lower() == STATIC_RUNTIME_NAME os_val = "Linux" if language.lower( ) == NODE_RUNTIME_NAME else OS_DEFAULT # detect the version data = get_runtime_version_details(lang_details.get('file_loc'), language) version_used_create = data.get('to_create') detected_version = data.get('detected') runtime_version = "{}|{}".format(language, version_used_create) if \ version_used_create != "-" else version_used_create if location is None: locs = client.list_geo_regions(sku, True) available_locs = [] for loc in locs: available_locs.append(loc.geo_region_name) location = available_locs[0] # Remove spaces from the location string, incase the GeoRegion string is used loc_name = location.replace(" ", "") full_sku = get_sku_name(sku) is_linux = True if os_val == 'Linux' else False asp = "appsvc_asp_{}_{}".format(os_val, loc_name) rg_name = "appsvc_rg_{}_{}".format(os_val, loc_name) str_no_contents_warn = "" if not do_deployment: str_no_contents_warn = "[Empty directory, no deployment will be triggered]" # Resource group: check if default RG is set default_rg = cmd.cli_ctx.config.get('defaults', 'group', fallback=None) if default_rg and check_resource_group_exists(cmd, default_rg) and \ check_resource_group_supports_os(cmd, default_rg, location, is_linux): rg_name = default_rg rg_mssg = "[Using default Resource group]" else: rg_mssg = "" src_path = "{} {}".format(src_dir.replace("\\", "\\\\"), str_no_contents_warn) rg_str = "{} {}".format(rg_name, rg_mssg) dry_run_str = r""" { "name" : "%s", "serverfarm" : "%s", "resourcegroup" : "%s", "sku": "%s", "os": "%s", "location" : "%s", "src_path" : "%s", "version_detected": "%s", "version_to_create": "%s" } """ % (name, asp, rg_str, full_sku, os_val, location, src_path, detected_version, runtime_version) create_json = json.loads(dry_run_str) if dryrun: logger.warning( "Web app will be created with the below configuration,re-run command " "without the --dryrun flag to create & deploy a new app") return create_json # create RG if the RG doesn't already exist if not check_resource_group_exists(cmd, rg_name): logger.warning("Creating Resource group '%s' ...", rg_name) create_resource_group(cmd, rg_name, location) logger.warning("Resource group creation complete") else: logger.warning("Resource group '%s' already exists.", rg_name) # create asp if not check_if_asp_exists(cmd, rg_name, asp): logger.warning("Creating App service plan '%s' ...", asp) sku_def = SkuDescription(tier=full_sku, name=sku, capacity=(1 if is_linux else None)) plan_def = AppServicePlan(loc_name, app_service_plan_name=asp, sku=sku_def, reserved=(is_linux or None)) client.app_service_plans.create_or_update(rg_name, asp, plan_def) logger.warning("App service plan creation complete") else: logger.warning("App service plan '%s' already exists.", asp) # create the app if not check_app_exists(cmd, rg_name, name): logger.warning("Creating app '%s' ....", name) create_webapp(cmd, rg_name, name, asp, runtime_version if is_linux else None) logger.warning("Webapp creation complete") else: logger.warning("App '%s' already exists", name) # update create_json to include the app_url url = _get_app_url( cmd, rg_name, name) # picks the custom domain URL incase a domain is assigned if do_deployment: if not is_skip_build: # setting to build after deployment logger.warning( "Updating app settings to enable build after deployment") update_app_settings(cmd, rg_name, name, ["SCM_DO_BUILD_DURING_DEPLOYMENT=true"]) # work around until the timeout limits issue for linux is investigated & fixed # wakeup kudu, by making an SCM call _ping_scm_site(cmd, rg_name, name) logger.warning("Creating zip with contents of dir %s ...", src_dir) # zip contents & deploy zip_file_path = zip_contents_from_dir(src_dir, language) logger.warning("Preparing to deploy %s contents to app.", '' if is_skip_build else 'and build') enable_zip_deploy(cmd, rg_name, name, zip_file_path) # Remove the file afer deployment, handling exception if user removed the file manually try: os.remove(zip_file_path) except OSError: pass else: logger.warning( 'No known package (Node, ASP.NET, .NETCORE, or Static Html) ' 'found skipping zip and deploy process') create_json.update({'app_url': url}) logger.warning("All done.") return create_json
def create_deploy_webapp(cmd, name, location=None, dryrun=False): import os import json client = web_client_factory(cmd.cli_ctx) # the code to deploy is expected to be the current directory the command is running from src_dir = os.getcwd() # if dir is empty, show a message in dry run do_deployment = False if os.listdir(src_dir) == [] else True # determine the details for app to be created from src contents lang_details = get_lang_from_content(src_dir) # we support E2E create and deploy for Node & dotnetcore, any other stack, set defaults for os & runtime # and skip deployment if lang_details['language'] is None: do_deployment = False sku = 'F1' os_val = OS_DEFAULT detected_version = '-' runtime_version = '-' else: sku = lang_details.get("default_sku") language = lang_details.get("language") os_val = "Linux" if language.lower( ) == NODE_RUNTIME_NAME else OS_DEFAULT # detect the version data = get_runtime_version_details(lang_details.get('file_loc'), language) version_used_create = data.get('to_create') detected_version = data.get('detected') runtime_version = "{}|{}".format(language, version_used_create) if location is None: locs = client.list_geo_regions(sku, True) available_locs = [] for loc in locs: available_locs.append(loc.geo_region_name) location = available_locs[0] # Remove spaces from the location string, incase the GeoRegion string is used loc_name = location.replace(" ", "") full_sku = _get_sku_name(sku) is_linux = True if os_val == 'Linux' else False asp = "appsvc_asp_{}_{}".format(os_val, loc_name) rg_name = "appsvc_rg_{}_{}".format(os_val, loc_name) str_no_contents_warn = "" if not do_deployment: str_no_contents_warn = "[Empty directory, no deployment will be triggered]" # Resource group: check if default RG is set default_rg = cmd.cli_ctx.config.get('defaults', 'group', fallback=None) if default_rg and check_resource_group_supports_os(cmd, default_rg, location, is_linux): rg_name = default_rg rg_mssg = "[Using default Resource group]" else: rg_mssg = "" src_path = "{} {}".format(src_dir.replace("\\", "\\\\"), str_no_contents_warn) rg_str = "{} {}".format(rg_name, rg_mssg) dry_run_str = r""" { "name" : "%s", "serverfarm" : "%s", "resourcegroup" : "%s", "sku": "%s", "os": "%s", "location" : "%s", "src_path" : "%s", "version_detected": "%s", "version_to_create": "%s" } """ % (name, asp, rg_str, full_sku, os_val, location, src_path, detected_version, runtime_version) create_json = json.dumps(json.loads(dry_run_str), indent=4, sort_keys=True) if dryrun: logger.warning( "Web app will be created with the below configuration,re-run command " "without the --dryrun flag to create & deploy a new app") logger.warning(create_json) return None # create RG if the RG doesn't already exist if not check_resource_group_exists(cmd, rg_name): logger.warning("Creating Resource group '%s' ...", rg_name) create_resource_group(cmd, rg_name, location) logger.warning("Resource group creation complete") else: logger.warning("Resource group '%s' already exists.", rg_name) # create asp if not check_if_asp_exists(cmd, rg_name, asp): logger.warning("Creating App service plan '%s' ...", asp) sku_def = SkuDescription(tier=full_sku, name=sku, capacity=(1 if is_linux else None)) plan_def = AppServicePlan(loc_name, app_service_plan_name=asp, sku=sku_def, reserved=(is_linux or None)) client.app_service_plans.create_or_update(rg_name, asp, plan_def) logger.warning("App service plan creation complete") else: logger.warning("App service plan '%s' already exists.", asp) # create the app if not check_app_exists(cmd, rg_name, name): logger.warning("Creating app '%s' ....", name) create_webapp(cmd, rg_name, name, asp, runtime_version if is_linux else None) logger.warning("Webapp creation complete") else: logger.warning("App '%s' already exists", name) if do_deployment: # setting to build after deployment logger.warning( "Updating app settings to enable build after deployment") update_app_settings(cmd, rg_name, name, ["SCM_DO_BUILD_DURING_DEPLOYMENT=true"]) # work around until the timeout limits issue for linux is investigated & fixed # wakeup kudu, by making an SCM call import requests # work around until the timeout limits issue for linux is investigated & fixed user_name, password = _get_site_credential(cmd.cli_ctx, rg_name, name) scm_url = _get_scm_url(cmd, rg_name, name) import urllib3 authorization = urllib3.util.make_headers( basic_auth='{0}:{1}'.format(user_name, password)) requests.get(scm_url + '/api/settings', headers=authorization) logger.warning("Creating zip with contents of dir %s ...", src_dir) # zip contents & deploy zip_file_path = zip_contents_from_dir(src_dir, language) logger.warning("Deploying and building contents to app." "This operation can take some time to finish...") enable_zip_deploy(cmd, rg_name, name, zip_file_path) else: logger.warning( "No 'NODE' or 'DOTNETCORE' package detected, skipping zip and deploy process" ) logger.warning("All done. %s", create_json) return None
def update_facebook_settings( cmd, resource_group_name, name, slot=None, # pylint: disable=unused-argument app_id=None, app_secret_setting_name=None, # pylint: disable=unused-argument graph_api_version=None, scopes=None, app_secret=None, yes=False): # pylint: disable=unused-argument if app_secret is not None and app_secret_setting_name is not None: raise CLIError( 'Usage Error: --app-secret and --app-secret-setting-name cannot both be configured ' 'to non empty strings') if app_secret is not None and not yes: msg = 'Configuring --app-secret will add app settings to the web app. Are you sure you want to continue?' if not prompt_y_n(msg, default="n"): raise CLIError( 'Usage Error: --app-secret cannot be used without agreeing to add app ' 'settings to the web app.') existing_auth = get_auth_settings_v2(cmd, resource_group_name, name, slot)["properties"] registration = {} if "identityProviders" not in existing_auth.keys(): existing_auth["identityProviders"] = {} if "facebook" not in existing_auth["identityProviders"].keys(): existing_auth["identityProviders"]["facebook"] = {} if app_id is not None or app_secret is not None or app_secret_setting_name is not None: if "registration" not in existing_auth["identityProviders"][ "facebook"].keys(): existing_auth["identityProviders"]["facebook"]["registration"] = {} registration = existing_auth["identityProviders"]["facebook"][ "registration"] if scopes is not None: if "login" not in existing_auth["identityProviders"]["facebook"].keys( ): existing_auth["identityProviders"]["facebook"]["login"] = {} if app_id is not None: registration["appId"] = app_id if app_secret_setting_name is not None: registration["appSecretSettingName"] = app_secret_setting_name if app_secret is not None: registration["appSecretSettingName"] = FACEBOOK_SECRET_SETTING_NAME settings = [] settings.append(FACEBOOK_SECRET_SETTING_NAME + '=' + app_secret) update_app_settings(cmd, resource_group_name, name, settings, slot) if graph_api_version is not None: existing_auth["identityProviders"]["facebook"][ "graphApiVersion"] = graph_api_version if scopes is not None: existing_auth["identityProviders"]["facebook"]["login"][ "scopes"] = scopes.split(",") if app_id is not None or app_secret is not None or app_secret_setting_name is not None: existing_auth["identityProviders"]["facebook"][ "registration"] = registration updated_auth_settings = update_auth_settings_v2_rest_call( cmd, resource_group_name, name, existing_auth, slot) return updated_auth_settings["identityProviders"]["facebook"]
def update_aad_settings( cmd, resource_group_name, name, slot=None, # pylint: disable=unused-argument client_id=None, client_secret_setting_name=None, # pylint: disable=unused-argument issuer=None, allowed_token_audiences=None, client_secret=None, yes=False): # pylint: disable=unused-argument if client_secret is not None and client_secret_setting_name is not None: raise CLIError( 'Usage Error: --client-secret and --client-secret-setting-name cannot both be ' 'configured to non empty strings') if client_secret is not None and not yes: msg = 'Configuring --client-secret will add app settings to the web app. Are you sure you want to continue?' if not prompt_y_n(msg, default="n"): raise CLIError( 'Usage Error: --client-secret cannot be used without agreeing to add app settings ' 'to the web app.') existing_auth = get_auth_settings_v2(cmd, resource_group_name, name, slot)["properties"] registration = {} validation = {} if "identityProviders" not in existing_auth.keys(): existing_auth["identityProviders"] = {} if "azureActiveDirectory" not in existing_auth["identityProviders"].keys(): existing_auth["identityProviders"]["azureActiveDirectory"] = {} if (client_id is not None or client_secret is not None or client_secret_setting_name is not None or issuer is not None): if "registration" not in existing_auth["identityProviders"][ "azureActiveDirectory"].keys(): existing_auth["identityProviders"]["azureActiveDirectory"][ "registration"] = {} registration = existing_auth["identityProviders"][ "azureActiveDirectory"]["registration"] if allowed_token_audiences is not None: if "validation" not in existing_auth["identityProviders"][ "azureActiveDirectory"].keys(): existing_auth["identityProviders"]["azureActiveDirectory"][ "validation"] = {} validation = existing_auth["identityProviders"][ "azureActiveDirectory"]["validation"] if client_id is not None: registration["clientId"] = client_id if client_secret_setting_name is not None: registration["clientSecretSettingName"] = client_secret_setting_name if client_secret is not None: registration["clientSecretSettingName"] = MICROSOFT_SECRET_SETTING_NAME settings = [] settings.append(MICROSOFT_SECRET_SETTING_NAME + '=' + client_secret) update_app_settings(cmd, resource_group_name, name, settings, slot) if issuer is not None: registration["openIdIssuer"] = issuer if allowed_token_audiences is not None: validation["allowedAudiences"] = allowed_token_audiences.split(",") existing_auth["identityProviders"]["azureActiveDirectory"][ "validation"] = validation if (client_id is not None or client_secret is not None or client_secret_setting_name is not None or issuer is not None): existing_auth["identityProviders"]["azureActiveDirectory"][ "registration"] = registration updated_auth_settings = update_auth_settings_v2_rest_call( cmd, resource_group_name, name, existing_auth, slot) return updated_auth_settings["identityProviders"]["azureActiveDirectory"]
def create_deploy_webapp(cmd, name, location=None, dryrun=False): import os import json client = web_client_factory(cmd.cli_ctx) sku = "S1" os_val = "Linux" language = "node" full_sku = _get_sku_name(sku) if location is None: locs = client.list_geo_regions(sku, True) available_locs = [] for loc in locs: available_locs.append(loc.geo_region_name) location = available_locs[0] # Remove spaces from the location string, incase the GeoRegion string is used loc_name = location.replace(" ", "") asp = "appsvc_asp_{}_{}".format(os_val, loc_name) rg_name = "appsvc_rg_{}_{}".format(os_val, loc_name) # the code to deploy is expected to be the current directory the command is running from src_dir = os.getcwd() # if dir is empty, show a message in dry run do_deployment = False if os.listdir(src_dir) == [] else True package_json_path = is_node_application(src_dir) str_no_contents_warn = "" if not do_deployment: str_no_contents_warn = "[Empty directory, no deployment will be triggered]" if package_json_path == '': node_version = "[No package.json file found in root directory, not a Node app?]" version_used_create = "8.0" else: with open(package_json_path) as data_file: data = json.load(data_file) node_version = data['version'] version_used_create = get_node_runtime_version_toSet() # Resource group: check if default RG is set default_rg = cmd.cli_ctx.config.get('defaults', 'group', fallback=None) if default_rg and check_resource_group_supports_linux( cmd, default_rg, location): rg_name = default_rg rg_mssg = "[Using default Resource group]" else: rg_mssg = "" runtime_version = "{}|{}".format(language, version_used_create) src_path = "{} {}".format(src_dir.replace("\\", "\\\\"), str_no_contents_warn) rg_str = "{} {}".format(rg_name, rg_mssg) dry_run_str = r""" { "name" : "%s", "serverfarm" : "%s", "resourcegroup" : "%s", "sku": "%s", "os": "%s", "location" : "%s", "src_path" : "%s", "version_detected": "%s", "version_to_create": "%s" } """ % (name, asp, rg_str, full_sku, os_val, location, src_path, node_version, runtime_version) create_json = json.dumps(json.loads(dry_run_str), indent=4, sort_keys=True) if dryrun: logger.warning( "Web app will be created with the below configuration,re-run command " "without the --dryrun flag to create & deploy a new app") logger.warning(create_json) return None # create RG if the RG doesn't already exist if not check_resource_group_exists(cmd, rg_name): logger.warning("Creating Resource group '%s' ...", rg_name) create_resource_group(cmd, rg_name, location) logger.warning("Resource group creation complete") else: logger.warning("Resource group '%s' already exists.", rg_name) # create asp if not check_if_asp_exists(cmd, rg_name, asp): logger.warning("Creating App service plan '%s' ...", asp) sku_def = SkuDescription(tier=full_sku, name=sku, capacity=1) plan_def = AppServicePlan(loc_name, app_service_plan_name=asp, sku=sku_def, reserved=True) client.app_service_plans.create_or_update(rg_name, asp, plan_def) logger.warning("App service plan creation complete") else: logger.warning("App service plan '%s' already exists.", asp) # create the Linux app if not check_app_exists(cmd, rg_name, name): logger.warning("Creating app '%s' ....", name) create_webapp(cmd, rg_name, name, asp, runtime_version) logger.warning("Webapp creation complete") else: logger.warning("App '%s' already exists", name) # setting to build after deployment logger.warning("Updating app settings to enable build after deployment") update_app_settings(cmd, rg_name, name, ["SCM_DO_BUILD_DURING_DEPLOYMENT=true"]) # work around until the timeout limits issue for linux is investigated & fixed # wakeup kudu, by making an SCM call import requests # work around until the timeout limits issue for linux is investigated & fixed user_name, password = _get_site_credential(cmd.cli_ctx, rg_name, name) scm_url = _get_scm_url(cmd, rg_name, name) import urllib3 authorization = urllib3.util.make_headers( basic_auth='{0}:{1}'.format(user_name, password)) requests.get(scm_url + '/api/settings', headers=authorization) if package_json_path != '': logger.warning("Creating zip with contents of dir %s ...", src_dir) # zip contents & deploy zip_file_path = zip_contents_from_dir(src_dir) logger.warning("Deploying and building contents to app." "This operation can take some time to finish...") enable_zip_deploy(cmd, rg_name, name, zip_file_path) else: logger.warning( "No package.json found, skipping zip and deploy process") logger.warning("All done. %s", create_json) return None