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
Beispiel #10
0
    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
Beispiel #11
0
    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()
Beispiel #13
0
    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
Beispiel #14
0
    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
Beispiel #15
0
    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", "", ""