def deploy_webapp(self, app_name, group_name, service_plan, storage_account_name): self.log.info("Deploying Function App %s (%s) in group %s" % (app_name, service_plan.location, group_name)) site_config = SiteConfig(app_settings=[]) functionapp_def = Site(location=service_plan.location, site_config=site_config) functionapp_def.kind = 'functionapp,linux' functionapp_def.server_farm_id = service_plan.id site_config.linux_fx_version = CONST_DOCKER_VERSION site_config.always_on = True app_insights_key = self.get_application_insights_key(group_name, service_plan.app_service_plan_name) if app_insights_key: site_config.app_settings.append( NameValuePair('APPINSIGHTS_INSTRUMENTATIONKEY', app_insights_key)) con_string = self.get_storage_connection_string(group_name, storage_account_name) site_config.app_settings.append(NameValuePair('AzureWebJobsStorage', con_string)) site_config.app_settings.append(NameValuePair('AzureWebJobsDashboard', con_string)) site_config.app_settings.append(NameValuePair('FUNCTIONS_EXTENSION_VERSION', CONST_FUNCTIONS_EXT_VERSION)) site_config.app_settings.append(NameValuePair('FUNCTIONS_WORKER_RUNTIME', 'python')) #: :type: azure.mgmt.web.WebSiteManagementClient web_client = self.local_session.client('azure.mgmt.web.WebSiteManagementClient') web_client.web_apps.create_or_update(group_name, app_name, functionapp_def).wait()
def test_config_source_control_vsts(self, profile_mock, cd_manager_mock, client_factory_mock): # Mock the result of get auth token (avoiding REST call) profile = mock.Mock() profile.get_subscription.return_value = {'id': 'id1', 'name': 'sub1', 'tenantId': 'tenant1'} profile.get_current_account_user.return_value = None profile.get_login_credentials.return_value = None, None, None profile.get_access_token_for_resource.return_value = None profile_mock.return_value = profile # Mock the cd manager class so no REST calls are made cd_manager = mock.Mock() status = ContinuousDeliveryResult(None, None, None, None, None, None, "message1", None, None, None) cd_manager.setup_continuous_delivery.return_value = status cd_manager_mock.return_value = cd_manager # Mock the client and set the location client = mock.Mock() client_factory_mock.return_value = client site = Site('antarctica') site.default_host_name = 'myweb.com' client.web_apps.get.return_value = site config_source_control('group1', 'myweb', 'http://github.com/repo1', None, None, None, None, "slot1", 'vsts', 'ASPNetWap', 'account1', False) cd_manager.setup_continuous_delivery.assert_called_with('slot1', 'ASPNetWap', 'account1', True, None)
def _provision(self, params): site_config = SiteConfig(app_settings=[]) functionapp_def = Site(location=params['location'], site_config=site_config) functionapp_def.kind = 'functionapp,linux' functionapp_def.server_farm_id = params['app_service_plan_id'] site_config.linux_fx_version = FUNCTION_DOCKER_VERSION site_config.always_on = True app_insights_key = params['app_insights_key'] if app_insights_key: site_config.app_settings.append( azure_name_value_pair('APPINSIGHTS_INSTRUMENTATIONKEY', app_insights_key)) con_string = params['storage_account_connection_string'] site_config.app_settings.append(azure_name_value_pair('AzureWebJobsStorage', con_string)) site_config.app_settings.append(azure_name_value_pair('AzureWebJobsDashboard', con_string)) site_config.app_settings.append(azure_name_value_pair('FUNCTIONS_EXTENSION_VERSION', FUNCTION_EXT_VERSION)) site_config.app_settings.append(azure_name_value_pair('FUNCTIONS_WORKER_RUNTIME', 'python')) site_config.app_settings.append( azure_name_value_pair('MACHINEKEY_DecryptionKey', FunctionAppDeploymentUnit.generate_machine_decryption_key())) return self.client.web_apps.create_or_update(params['resource_group_name'], params['name'], functionapp_def).result()
def test_browse_with_trace(self, webbrowser_mock, log_mock, site_op_mock): site = Site('antarctica') site.default_host_name = 'haha.com' site.host_name_ssl_states = [HostNameSslState('does not matter', ssl_state=SslState.ip_based_enabled)] site_op_mock.return_value = site # action view_in_browser('myRG', 'myweb', logs=True) # assert webbrowser_mock.assert_called_with('https://haha.com') log_mock.assert_called_with('myRG', 'myweb', None, None)
def test_get_external_ip_from_dns(self, resolve_hostname_mock, client_factory_mock): client = mock.Mock() client_factory_mock.return_value = client # set up the web inside a ASE, with an ip based ssl binding site = Site('antarctica') site.default_host_name = 'myweb.com' client.web_apps.get.return_value = site # action get_external_ip('myRg', 'myWeb') # assert, we return the virtual ip from the ip based ssl binding resolve_hostname_mock.assert_called_with('myweb.com')
def create_webapp_slot(resource_group_name, webapp, slot, configuration_source=None): client = web_client_factory() site = client.web_apps.get(resource_group_name, webapp) location = site.location slot_def = Site(server_farm_id=site.server_farm_id, location=location) clone_from_prod = None slot_def.site_config = SiteConfig(location) poller = client.web_apps.create_or_update_slot(resource_group_name, webapp, slot_def, slot) result = AppServiceLongRunningOperation()(poller) if configuration_source: clone_from_prod = configuration_source.lower() == webapp.lower() site_config = get_site_configs( resource_group_name, webapp, None if clone_from_prod else configuration_source) _generic_site_operation(resource_group_name, webapp, 'update_configuration', slot, site_config) # slot create doesn't clone over the app-settings and connection-strings, so we do it here # also make sure slot settings don't get propagated. if configuration_source: slot_cfg_names = client.web_apps.list_slot_configuration_names(resource_group_name, webapp) src_slot = None if clone_from_prod else configuration_source app_settings = _generic_site_operation(resource_group_name, webapp, 'list_application_settings', src_slot) for a in (slot_cfg_names.app_setting_names or []): app_settings.properties.pop(a, None) connection_strings = _generic_site_operation(resource_group_name, webapp, 'list_connection_strings', src_slot) for a in (slot_cfg_names.connection_string_names or []): connection_strings.properties.pop(a, None) _generic_site_operation(resource_group_name, webapp, 'update_application_settings', slot, app_settings) _generic_site_operation(resource_group_name, webapp, 'update_connection_strings', slot, connection_strings) result.name = result.name.split('/')[-1] return result
def test_set_domain_name(self, client_factory_mock): client_factory_mock.return_value = self.client # set up the return value for getting a webapp webapp = Site('westus') webapp.name = 'veryNiceWebApp' self.client.web_apps.get = lambda _, _1: webapp # set up the result value of putting a domain name domain = 'veryNiceDomain' binding = HostNameBinding(webapp.location, name=domain, custom_host_name_dns_record_type='A', host_name_type='Managed') self.client.web_apps._client = mock.MagicMock() self.client.web_apps._client.send.return_value = FakedResponse(200) self.client.web_apps._deserialize = mock.MagicMock() self.client.web_apps._deserialize.return_value = binding # action result = add_hostname('g1', webapp.name, domain) # assert self.assertEqual(result.name, domain)
def test_config_source_control_vsts(self, profile_mock, cd_manager_mock, client_factory_mock): # Mock the result of get auth token (avoiding REST call) profile = mock.Mock() profile.get_subscription.return_value = {'id': 'id1', 'name': 'sub1', 'tenantId': 'tenant1'} profile.get_current_account_user.return_value = None profile.get_login_credentials.return_value = None, None, None profile.get_access_token_for_resource.return_value = None profile_mock.return_value = profile # Mock the cd manager class so no REST calls are made cd_manager = mock.Mock() status = ContinuousDeliveryResult(None, None, None, None, None, None, "message1", None, None, None) cd_manager.setup_continuous_delivery.return_value = status cd_manager_mock.return_value = cd_manager # Mock the client and set the location client = mock.Mock() client_factory_mock.return_value = client site = Site('antarctica') site.default_host_name = 'myweb.com' client.web_apps.get.return_value = site config_source_control(mock.MagicMock(), 'group1', 'myweb', 'http://github.com/repo1', None, None, None, None, None, 'ASPNet', 'working_directory', 'Gulp', 'Django', 'Python 2.7.12 x64', True, 'https://account1.visualstudio.com', None, 'slot1', None, None) cd_app_type_details = { 'cd_app_type': 'ASPNet', 'app_working_dir': 'working_directory', 'nodejs_task_runner': 'Gulp', 'python_framework': 'Django', 'python_version': 'Python 2.7.12 x64' } cd_manager.setup_continuous_delivery.assert_called_with('slot1', cd_app_type_details, 'https://account1.visualstudio.com', True, None, None, None)
def exec_module(self, **kwargs): for key in self.module_arg_spec: setattr(self, key, kwargs[key]) if self.app_settings is None: self.app_settings = dict() try: resource_group = self.rm_client.resource_groups.get(self.resource_group) except CloudError: self.fail('Unable to retrieve resource group') self.location = self.location or resource_group.location try: function_app = self.web_client.web_apps.get( resource_group_name=self.resource_group, name=self.name ) exists = True except CloudError as exc: exists = False if self.state == 'absent': if exists: if self.check_mode: self.results['changed'] = True return self.results try: self.web_client.web_apps.delete( resource_group_name=self.resource_group, name=self.name ) self.results['changed'] = True except CloudError as exc: self.fail('Failure while deleting web app: {}'.format(exc)) else: self.results['changed'] = False else: if not exists: function_app = Site( location=self.location, kind='functionapp', site_config=SiteConfig( app_settings=self.aggregated_app_settings(), scm_type='LocalGit' ) ) self.results['changed'] = True else: self.results['changed'], function_app = self.update(function_app) if self.check_mode: self.results['state'] = function_app.as_dict() elif self.results['changed']: try: new_function_app = self.web_client.web_apps.create_or_update( resource_group_name=self.resource_group, name=self.name, site_envelope=function_app ).result() self.results['state'] = new_function_app.as_dict() except CloudError as exc: self.fail('Error creating or updating web app: {}'.format(exc)) return self.results
def exec_module(self, **kwargs): """Main module execution method""" for key in list(self.module_arg_spec.keys()) + ['tags']: if hasattr(self, key): setattr(self, key, kwargs[key]) elif kwargs[key] is not None: if key == "scm_type": self.site_config[key] = kwargs[key] old_response = None response = None to_be_updated = False # set location resource_group = self.get_resource_group(self.resource_group) if not self.location: self.location = resource_group.location # get web app webapp_response = self.get_webapp() if not webapp_response: self.fail( "Web app {0} does not exist in resource group {1}.".format( self.webapp_name, self.resource_group)) # get slot old_response = self.get_slot() # set is_linux is_linux = True if webapp_response['reserved'] else False if self.state == 'present': if self.frameworks: # java is mutually exclusive with other frameworks if len(self.frameworks) > 1 and any(f['name'] == 'java' for f in self.frameworks): self.fail( 'Java is mutually exclusive with other frameworks.') if is_linux: if len(self.frameworks) != 1: self.fail( 'Can specify one framework only for Linux web app.' ) if self.frameworks[0][ 'name'] not in self.supported_linux_frameworks: self.fail( 'Unsupported framework {0} for Linux web app.'. format(self.frameworks[0]['name'])) self.site_config['linux_fx_version'] = ( self.frameworks[0]['name'] + '|' + self.frameworks[0]['version']).upper() if self.frameworks[0]['name'] == 'java': if self.frameworks[0]['version'] != '8': self.fail("Linux web app only supports java 8.") if self.frameworks[0].get('settings', {}) and self.frameworks[0]['settings'].get('java_container', None) and \ self.frameworks[0]['settings']['java_container'].lower() != 'tomcat': self.fail( "Linux web app only supports tomcat container." ) if self.frameworks[0].get('settings', {}) and self.frameworks[0]['settings'].get('java_container', None) and \ self.frameworks[0]['settings']['java_container'].lower() == 'tomcat': self.site_config[ 'linux_fx_version'] = 'TOMCAT|' + self.frameworks[ 0]['settings'][ 'java_container_version'] + '-jre8' else: self.site_config[ 'linux_fx_version'] = 'JAVA|8-jre8' else: for fx in self.frameworks: if fx.get('name' ) not in self.supported_windows_frameworks: self.fail( 'Unsupported framework {0} for Windows web app.' .format(fx.get('name'))) else: self.site_config[fx.get('name') + '_version'] = fx.get('version') if 'settings' in fx and fx['settings'] is not None: for key, value in fx['settings'].items(): self.site_config[key] = value if not self.app_settings: self.app_settings = dict() if self.container_settings: linux_fx_version = 'DOCKER|' if self.container_settings.get('registry_server_url'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_URL'] = 'https://' + self.container_settings[ 'registry_server_url'] linux_fx_version += self.container_settings[ 'registry_server_url'] + '/' linux_fx_version += self.container_settings['name'] self.site_config['linux_fx_version'] = linux_fx_version if self.container_settings.get('registry_server_user'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_USERNAME'] = self.container_settings[ 'registry_server_user'] if self.container_settings.get('registry_server_password'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_PASSWORD'] = self.container_settings[ 'registry_server_password'] # set auto_swap_slot_name if self.auto_swap_slot_name and isinstance( self.auto_swap_slot_name, str): self.site_config[ 'auto_swap_slot_name'] = self.auto_swap_slot_name if self.auto_swap_slot_name is False: self.site_config['auto_swap_slot_name'] = None # init site self.site = Site(location=self.location, site_config=self.site_config) # check if the slot already present in the webapp if not old_response: self.log("Web App slot doesn't exist") to_be_updated = True self.to_do = Actions.CreateOrUpdate self.site.tags = self.tags # if linux, setup startup_file if self.startup_file: self.site_config['app_command_line'] = self.startup_file # set app setting if self.app_settings: app_settings = [] for key in self.app_settings.keys(): app_settings.append( NameValuePair(key, self.app_settings[key])) self.site_config['app_settings'] = app_settings # clone slot if self.configuration_source: self.clone = True else: # existing slot, do update self.log("Web App slot already exists") self.log('Result: {0}'.format(old_response)) update_tags, self.site.tags = self.update_tags( old_response.get('tags', None)) if update_tags: to_be_updated = True # check if site_config changed old_config = self.get_configuration_slot(self.name) if self.is_site_config_changed(old_config): to_be_updated = True self.to_do = Actions.CreateOrUpdate self.app_settings_strDic = self.list_app_settings_slot( self.name) # purge existing app_settings: if self.purge_app_settings: to_be_updated = True self.to_do = Actions.UpdateAppSettings self.app_settings_strDic.properties = dict() # check if app settings changed if self.purge_app_settings or self.is_app_settings_changed(): to_be_updated = True self.to_do = Actions.UpdateAppSettings if self.app_settings: for key in self.app_settings.keys(): self.app_settings_strDic.properties[ key] = self.app_settings[key] elif self.state == 'absent': if old_response: self.log("Delete Web App slot") self.results['changed'] = True if self.check_mode: return self.results self.delete_slot() self.log('Web App slot deleted') else: self.log("Web app slot {0} not exists.".format(self.name)) if to_be_updated: self.log('Need to Create/Update web app') self.results['changed'] = True if self.check_mode: return self.results if self.to_do == Actions.CreateOrUpdate: response = self.create_update_slot() self.results['id'] = response['id'] if self.clone: self.clone_slot() if self.to_do == Actions.UpdateAppSettings: self.update_app_settings_slot() slot = None if response: slot = response if old_response: slot = old_response if slot: if (slot['state'] != 'Stopped' and self.app_state == 'stopped') or \ (slot['state'] != 'Running' and self.app_state == 'started') or \ self.app_state == 'restarted': self.results['changed'] = True if self.check_mode: return self.results self.set_state_slot(self.app_state) if self.swap: self.results['changed'] = True if self.check_mode: return self.results self.swap_slot() return self.results
def exec_module(self, **kwargs): """Main module execution method""" for key in list(self.module_arg_spec.keys()) + ['tags']: if hasattr(self, key): setattr(self, key, kwargs[key]) elif kwargs[key] is not None: if key == "scm_type": self.site_config[key] = kwargs[key] # azure sdk linux_fx_version: # for docker web app, value is like DOCKER|imagename:tag # for linux web app, value is like NODE|6.6 if key == "linux_framework": self.site_config['linux_fx_version'] = (kwargs[key]['name'] + '|' + kwargs[key]['version']).upper() if key == "java_container_settings": if 'name' in kwargs['java_container_settings']: self.site_config['java_container'] = kwargs['java_container_settings']['name'] if 'version' in kwargs['java_container_settings']: self.site_config['java_container_version'] = kwargs['java_container_settings']['version'] old_response = None response = None to_be_updated = False if self.windows_framework is not None: if self.windows_framework.get('java_version', None) is not None and len(self.windows_framework) > 1: self.fail('java_version is mutually exclusive with other framework version in windows_framework.') for key in list(self.windows_framework.keys()): self.site_config[key] = self.windows_framework[key] if self.app_settings is None: self.app_settings = dict() if self.plan: self.plan = self.parse_resource_to_dict(self.plan) if self.container_settings is not None: if hasattr(self.site_config, 'linux_fx_version'): self.fail("Cannot set linux_framework with container_settings at same time.") linux_fx_version = 'DOCKER|' if self.container_settings.get('registry_server_url', None) is not None: self.app_settings['DOCKER_REGISTRY_SERVER_URL'] = 'https://' + self.container_settings['registry_server_url'] linux_fx_version += self.container_settings['registry_server_url'] + '/' linux_fx_version += self.container_settings['name'] self.site_config['linux_fx_version'] = linux_fx_version if self.container_settings.get('registry_server_user', None) is not None: self.app_settings['DOCKER_REGISTRY_SERVER_USERNAME'] = self.container_settings['registry_server_user'] if self.container_settings.get('registry_server_password', None) is not None: self.app_settings['DOCKER_REGISTRY_SERVER_PASSWORD'] = self.container_settings['registry_server_password'] # set location resource_group = self.get_resource_group(self.resource_group) if not self.location: self.location = resource_group.location # init site self.site = Site(location=self.location, site_config=self.site_config) if self.https_only is not None: self.site.https_only = self.https_only if self.client_affinity_enabled: self.site.client_affinity_enabled = self.client_affinity_enabled # get existing web app old_response = self.get_webapp() # check if the web app already present in the resource group if not old_response: self.log("Web App instance doesn't exist") if self.state == "present": to_be_updated = True self.to_do = Actions.CreateOrUpdate # service plan is required for creation if not self.plan: self.fail("Please specify app service plan in plan parameter.") # get app service plan old_plan = self.get_app_service_plan() if not old_plan: # no existing service plan, create one if (self.plan['name'] is None or self.plan['sku'] is None): self.fail('Please specify name, is_linux, sku in plan') if 'location' not in self.plan: plan_resource_group = self.get_resource_group(self.plan['resource_group']) self.plan['location'] = plan_resource_group.location old_plan = self.create_app_service_plan() self.site.server_farm_id = old_plan['id'] # if linux, setup startup_file if hasattr(old_plan, 'is_linux'): if hasattr(self, 'startup_file'): self.site_config['app_command_line'] = self.startup_file # set app setting if self.app_settings is not None: app_settings = [] for key in self.app_settings.keys(): app_settings.append(NameValuePair(key, self.app_settings[key])) self.site_config['app_settings'] = app_settings else: # existing web app, do update self.log("Web App instance already exists") if self.state == 'present': self.log('Result: {0}'.format(old_response)) update_tags, old_response['tags'] = self.update_tags( old_response.get('tags', dict())) if update_tags: to_be_updated = True # check if root level property changed if self.is_updatable_property_changed(old_response): to_be_updated = True self.to_do = Actions.CreateOrUpdate # check if site_config changed old_config = self.get_webapp_configuration() if self.is_site_config_changed(old_config): to_be_updated = True self.to_do = Actions.CreateOrUpdate # check if linux_fx_version changed if old_config.linux_fx_version != self.site_config.get('linux_fx_version', None): to_be_updated = True self.to_do = Actions.CreateOrUpdate self.app_settings_strDic = self.list_app_settings() # purge existing app_settings: if self.purge_app_settings: self.app_settings_strDic.properties = dict() # check if app settings changed if self.purge_app_settings or self.is_app_settings_changed(): to_be_updated = True self.to_do = Actions.UpdateAppSettings if self.app_settings is not None: for key in self.app_settings.keys(): self.app_settings_strDic.properties[key] = self.app_settings[key] if old_response: self.results['ansible_facts']['azure_webapp'] = old_response if to_be_updated: self.log('Need to Create/Update web app') self.results['changed'] = True if self.check_mode: return self.results if self.to_do == Actions.CreateOrUpdate: response = self.create_update_webapp() self.results['ansible_facts']['azure_webapp'] = response if self.to_do == Actions.UpdateAppSettings: response = self.update_app_settings() self.results['ansible_facts']['azure_webapp']['app_settings'] = response if self.state == 'absent' and old_response: self.log("Delete Web App instance") self.results['changed'] = True if self.check_mode: return self.results self.delete_webapp() self.log('Web App instance deleted') return self.results
def run_example(): """Web Site management example.""" # # Create the Resource Manager Client with an Application (service principal) token provider # subscription_id = os.environ['AZURE_SUBSCRIPTION_ID'] credentials = ServicePrincipalCredentials( client_id=os.environ['AZURE_CLIENT_ID'], secret=os.environ['AZURE_CLIENT_SECRET'], tenant=os.environ['AZURE_TENANT_ID']) resource_client = ResourceManagementClient(credentials, subscription_id) web_client = WebSiteManagementClient(credentials, subscription_id) # Create Resource group print('Create Resource Group') resource_group_params = {'location': 'westus'} print_item( resource_client.resource_groups.create_or_update( GROUP_NAME, resource_group_params)) # # Create an App Service plan for your WebApp # print('Create an App Service plan for your WebApp') service_plan_async_operation = web_client.app_service_plans.create_or_update( GROUP_NAME, SERVER_FARM_NAME, AppServicePlan(app_service_plan_name=SERVER_FARM_NAME, location=WEST_US, sku=SkuDescription(name='S1', capacity=1, tier='Standard'))) service_plan = service_plan_async_operation.result() print_item(service_plan) # # Create a Site to be hosted on the App Service plan # print('Create a Site to be hosted on the App Service plan') site_async_operation = web_client.web_apps.create_or_update( GROUP_NAME, SITE_NAME, Site(location=WEST_US, server_farm_id=service_plan.id)) site = site_async_operation.result() print_item(site) # # List Sites by Resource Group # print('List Sites by Resource Group') for site in web_client.web_apps.list_by_resource_group(GROUP_NAME): print_item(site) # # Get a single Site # print('Get a single Site') site = web_client.web_apps.get(GROUP_NAME, SITE_NAME) print_item(site) print("Your site and server farm have been created. " "You can now go and visit at http://{}/".format( site.default_host_name)) input("Press enter to delete the site and server farm.") # # Delete a Site # print('Deleting the Site') web_client.web_apps.delete(GROUP_NAME, SITE_NAME) # # Delete the Resource Group # print('Deleting the resource group') delete_async_operation = resource_client.resource_groups.delete(GROUP_NAME) delete_async_operation.wait()
def exec_module(self, **kwargs): """Main module execution method""" for key in list(self.module_arg_spec.keys()) + ['tags']: if hasattr(self, key): setattr(self, key, kwargs[key]) elif kwargs[key] is not None: if key == "scm_type": self.site_config[key] = kwargs[key] old_response = None response = None to_be_updated = False # set location resource_group = self.get_resource_group(self.resource_group) if not self.location: self.location = resource_group.location # get existing web app old_response = self.get_webapp() if old_response: self.results['id'] = old_response['id'] if self.state == 'present': if not self.plan and not old_response: self.fail("Please specify plan for newly created web app.") if not self.plan: self.plan = old_response['server_farm_id'] self.plan = self.parse_resource_to_dict(self.plan) # get app service plan is_linux = False old_plan = self.get_app_service_plan() if old_plan: is_linux = old_plan['reserved'] else: is_linux = self.plan[ 'is_linux'] if 'is_linux' in self.plan else False if self.frameworks: # java is mutually exclusive with other frameworks if len(self.frameworks) > 1 and any(f['name'] == 'java' for f in self.frameworks): self.fail( 'Java is mutually exclusive with other frameworks.') if is_linux: if len(self.frameworks) != 1: self.fail( 'Can specify one framework only for Linux web app.' ) if self.frameworks[0][ 'name'] not in self.supported_linux_frameworks: self.fail( 'Unsupported framework {0} for Linux web app.'. format(self.frameworks[0]['name'])) self.site_config['linux_fx_version'] = ( self.frameworks[0]['name'] + '|' + self.frameworks[0]['version']).upper() if self.frameworks[0]['name'] == 'java': if self.frameworks[0]['version'] != '8': self.fail("Linux web app only supports java 8.") if self.frameworks[0]['settings'] and self.frameworks[ 0]['settings']['java_container'].lower( ) != 'tomcat': self.fail( "Linux web app only supports tomcat container." ) if self.frameworks[0]['settings'] and self.frameworks[ 0]['settings']['java_container'].lower( ) == 'tomcat': self.site_config[ 'linux_fx_version'] = 'TOMCAT|' + self.frameworks[ 0]['settings'][ 'java_container_version'] + '-jre8' else: self.site_config[ 'linux_fx_version'] = 'JAVA|8-jre8' else: for fx in self.frameworks: if fx.get('name' ) not in self.supported_windows_frameworks: self.fail( 'Unsupported framework {0} for Windows web app.' .format(fx.get('name'))) else: self.site_config[fx.get('name') + '_version'] = fx.get('version') if 'settings' in fx and fx['settings'] is not None: for key, value in fx['settings'].items(): self.site_config[key] = value if not self.app_settings: self.app_settings = dict() if self.container_settings: linux_fx_version = 'DOCKER|' if self.container_settings.get('registry_server_url'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_URL'] = 'https://' + self.container_settings[ 'registry_server_url'] linux_fx_version += self.container_settings[ 'registry_server_url'] + '/' linux_fx_version += self.container_settings['name'] self.site_config['linux_fx_version'] = linux_fx_version if self.container_settings.get('registry_server_user'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_USERNAME'] = self.container_settings[ 'registry_server_user'] if self.container_settings.get('registry_server_password'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_PASSWORD'] = self.container_settings[ 'registry_server_password'] # init site self.site = Site(location=self.location, site_config=self.site_config) if self.https_only is not None: self.site.https_only = self.https_only if self.client_affinity_enabled: self.site.client_affinity_enabled = self.client_affinity_enabled # check if the web app already present in the resource group if not old_response: self.log("Web App instance doesn't exist") to_be_updated = True self.to_do = Actions.CreateOrUpdate # service plan is required for creation if not self.plan: self.fail( "Please specify app service plan in plan parameter.") if not old_plan: # no existing service plan, create one if (not self.plan.get('name') or not self.plan.get('sku')): self.fail('Please specify name, is_linux, sku in plan') if 'location' not in self.plan: plan_resource_group = self.get_resource_group( self.plan['resource_group']) self.plan['location'] = plan_resource_group.location old_plan = self.create_app_service_plan() self.site.server_farm_id = old_plan['id'] # if linux, setup startup_file if old_plan.get('is_linux'): if self.startup_file: self.site_config[ 'app_command_line'] = self.startup_file # set app setting if self.app_settings: app_settings = [] for key in self.app_settings.keys(): app_settings.append( NameValuePair(key, self.app_settings[key])) self.site_config['app_settings'] = app_settings else: # existing web app, do update self.log("Web App instance already exists") self.log('Result: {0}'.format(old_response)) update_tags, old_response['tags'] = self.update_tags( old_response.get('tags', dict())) if update_tags: to_be_updated = True # check if root level property changed if self.is_updatable_property_changed(old_response): to_be_updated = True self.to_do = Actions.CreateOrUpdate # check if site_config changed old_config = self.get_webapp_configuration() if self.is_site_config_changed(old_config): to_be_updated = True self.to_do = Actions.CreateOrUpdate # check if linux_fx_version changed if old_config.linux_fx_version != self.site_config.get( 'linux_fx_version', ''): to_be_updated = True self.to_do = Actions.CreateOrUpdate self.app_settings_strDic = self.list_app_settings() # purge existing app_settings: if self.purge_app_settings: to_be_updated = True self.app_settings_strDic.properties = dict() # check if app settings changed if self.purge_app_settings or self.is_app_settings_changed(): to_be_updated = True self.to_do = Actions.CreateOrUpdate if self.app_settings: for key in self.app_settings.keys(): self.app_settings_strDic.properties[ key] = self.app_settings[key] elif self.state == 'absent': if old_response: self.log("Delete Web App instance") self.results['changed'] = True if self.check_mode: return self.results self.delete_webapp() self.log('Web App instance deleted') else: self.fail("Web app {0} not exists.".format(self.name)) if to_be_updated: self.log('Need to Create/Update web app') self.results['changed'] = True if self.check_mode: return self.results if self.to_do == Actions.CreateOrUpdate: response = self.create_update_webapp() self.results['id'] = response['id'] return self.results
def exec_module(self, **kwargs): for key in self.module_arg_spec: setattr(self, key, kwargs[key]) if self.app_settings is None: self.app_settings = dict() try: resource_group = self.rm_client.resource_groups.get( self.resource_group) except CloudError: self.fail('Unable to retrieve resource group') self.location = self.location or resource_group.location try: function_app = self.web_client.web_apps.get( resource_group_name=self.resource_group, name=self.name) exists = True except CloudError as exc: exists = False if self.state == 'absent': if exists: if self.check_mode: self.results['changed'] = True return self.results try: self.web_client.web_apps.delete( resource_group_name=self.resource_group, name=self.name) self.results['changed'] = True except CloudError as exc: self.fail( 'Failure while deleting web app: {0}'.format(exc)) else: self.results['changed'] = False else: if not exists: function_app = Site( location=self.location, kind='functionapp', site_config=SiteConfig( app_settings=self.aggregated_app_settings(), scm_type='LocalGit')) self.results['changed'] = True else: self.results['changed'], function_app = self.update( function_app) if self.check_mode: self.results['state'] = function_app.as_dict() elif self.results['changed']: try: new_function_app = self.web_client.web_apps.create_or_update( resource_group_name=self.resource_group, name=self.name, site_envelope=function_app).result() self.results['state'] = new_function_app.as_dict() except CloudError as exc: self.fail( 'Error creating or updating web app: {0}'.format(exc)) return self.results
def exec_module(self, **kwargs): for key in self.module_arg_spec: setattr(self, key, kwargs[key]) if self.app_settings is None: self.app_settings = dict() try: resource_group = self.rm_client.resource_groups.get( self.resource_group) except CloudError: self.fail('Unable to retrieve resource group') self.location = self.location or resource_group.location try: function_app = self.web_client.web_apps.get( resource_group_name=self.resource_group, name=self.name) # Newer SDK versions (0.40.0+) seem to return None if it doesn't exist instead of raising CloudError exists = function_app is not None except CloudError as exc: exists = False if self.state == 'absent': if exists: if self.check_mode: self.results['changed'] = True return self.results try: self.web_client.web_apps.delete( resource_group_name=self.resource_group, name=self.name) self.results['changed'] = True except CloudError as exc: self.fail( 'Failure while deleting web app: {0}'.format(exc)) else: self.results['changed'] = False else: kind = 'functionapp' linux_fx_version = None if self.container_settings and self.container_settings.get('name'): kind = 'functionapp,linux,container' linux_fx_version = 'DOCKER|' if self.container_settings.get('registry_server_url'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_URL'] = 'https://' + self.container_settings[ 'registry_server_url'] linux_fx_version += self.container_settings[ 'registry_server_url'] + '/' linux_fx_version += self.container_settings['name'] if self.container_settings.get('registry_server_user'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_USERNAME'] = self.container_settings.get( 'registry_server_user') if self.container_settings.get('registry_server_password'): self.app_settings[ 'DOCKER_REGISTRY_SERVER_PASSWORD'] = self.container_settings.get( 'registry_server_password') if not self.plan and function_app: self.plan = function_app.server_farm_id if not exists: function_app = Site( location=self.location, kind=kind, site_config=SiteConfig( app_settings=self.aggregated_app_settings(), scm_type='LocalGit')) self.results['changed'] = True else: self.results['changed'], function_app = self.update( function_app) # get app service plan if self.plan: if isinstance(self.plan, dict): self.plan = "/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Web/serverfarms/{2}".format( self.subscription_id, self.plan.get('resource_group', self.resource_group), self.plan.get('name')) function_app.server_farm_id = self.plan # set linux fx version if linux_fx_version: function_app.site_config.linux_fx_version = linux_fx_version if self.check_mode: self.results['state'] = function_app.as_dict() elif self.results['changed']: try: new_function_app = self.web_client.web_apps.create_or_update( resource_group_name=self.resource_group, name=self.name, site_envelope=function_app).result() self.results['state'] = new_function_app.as_dict() except CloudError as exc: self.fail( 'Error creating or updating web app: {0}'.format(exc)) return self.results
def run(job, **kwargs): resource = kwargs.get("resource") create_custom_fields_as_needed() env_id = "{{ azure_env }}" resource_group_id = "{{ resource_groups }}" web_app_name = "{{ web_app_name }}" service_plan_name = "{{ service_plan_name }}" set_progress( f"Environment {env_id} ResourceId {resource_group_id} And KWARGS {kwargs}" ) # Clean Resource name to Azure acceptable web-app name web_app_name = web_app_name.replace(" ", "-") web_app_name = web_app_name.replace("(", "-") web_app_name = web_app_name.replace(")", "") resource_group = ARMResourceGroup.objects.get(id=resource_group_id) # Connect to Azure Management Service web_client = _get_client(resource_group.handler) if service_plan_name: # User selected a pre-existing service plan, so just get it. service_plan_obj = web_client.app_service_plans.get( resource_group_name=resource_group.name, name=service_plan_name ) else: # Auto-create a new service plan. # Use the web_app_name and append 5 random digits to have a decent probability of uniqueness. service_plan_name = web_app_name + '-' + str(random.randint(10000, 99999)) set_progress(f"Environment {env_id}") env = Environment.objects.get(id=env_id) service_plan_async_operation = web_client.app_service_plans.create_or_update( resource_group.name, service_plan_name, AppServicePlan( app_service_plan_name=service_plan_name, location=env.node_location, sku=SkuDescription(name="S1", capacity=1, tier="Standard"), ), ) service_plan_async_operation.result() service_plan_obj = web_client.app_service_plans.get( resource_group_name=resource_group.name, name=service_plan_name ) # Create Web App site_async_operation = web_client.web_apps.create_or_update( resource_group.name, web_app_name, Site(location=service_plan_obj.location, server_farm_id=service_plan_obj.id), ) site = site_async_operation.result() # Store Web App metadata on the resource as parameters for teardown resource.azure_web_app_name = web_app_name resource.name = web_app_name resource.azure_web_app_id = site.id resource.azure_web_app_default_host_name = site.default_host_name resource.resource_group_name = resource_group resource.azure_location = site.location resource.save() return "SUCCESS", "", ""