예제 #1
0
    def __init__(self, policy):
        self.policy = policy
        self.log = logging.getLogger('custodian.azure.AzureFunctionMode')

        self.template_util = TemplateUtilities()
        self.parameters = self._get_parameters(self.template_util)
        self.group_name = self.parameters['servicePlanName']['value']
        self.webapp_name = self.parameters['name']['value']
        self.policy_name = self.policy.data['name'].replace(' ', '-').lower()
예제 #2
0
class TemplateUtilsTest(BaseTest):
    def setUp(self):
        super(TemplateUtilsTest, self).setUp()
        self.template_util = TemplateUtilities()

    def test_deploy_template_with_parameters(self):
        s = Session()
        client = s.client('azure.mgmt.resource.ResourceManagementClient')

        group_name = 'cloud-custodian-test'
        self.template_util.create_resource_group(group_name,
                                                 {'location': 'West US 2'})
        resource_group = client.resource_groups.get(group_name)

        self.assertIsNotNone(resource_group)

        template_file = 'dedicated_functionapp.json'
        parameters = self.template_util.get_default_parameters(
            'dedicated_functionapp.test.parameters.json')
        self.template_util.deploy_resource_template(group_name, template_file,
                                                    parameters)

        resources = client.resources.list_by_resource_group(group_name)
        self.assertIsNotNone(resources)

        # Cleaning up resource group
        client.resource_groups.delete('cloud-custodian-test')

    def test_get_json_template(self):
        template_file_name = 'dedicated_functionapp.json'
        template = self.template_util.get_json_template(template_file_name)

        self.assertIsNotNone(template)

    def test_get_default_parameters(self):
        params_file_name = 'dedicated_functionapp.test.parameters.json'
        params_file = self.template_util.get_json_template(params_file_name)

        params = self.template_util.get_default_parameters(params_file_name)

        self.assertEqual(params_file['parameters'], params)

    def test_update_parameters(self):
        params_file_name = 'dedicated_functionapp.test.parameters.json'
        params_to_update = {
            'location': 'test_location',
            'appInsightsLocation': 'test_location_2'
        }
        params = self.template_util.get_default_parameters(params_file_name)
        updated_params = self.template_util.update_parameters(
            params, params_to_update)

        self.assertEqual(updated_params['location']['value'],
                         params_to_update['location'])
        self.assertEqual(updated_params['appInsightsLocation']['value'],
                         params_to_update['appInsightsLocation'])
예제 #3
0
    def __init__(self, policy):
        self.policy = policy
        self.log = logging.getLogger('custodian.azure.AzureFunctionMode')
        self.session = local_session(self.policy.session_factory)
        self.client = self.session.client('azure.mgmt.web.WebSiteManagementClient')

        self.template_util = TemplateUtilities()
        self.parameters = self._get_parameters(self.template_util)
        self.group_name = self.parameters['servicePlanName']['value']
        self.webapp_name = self.parameters['name']['value']
        self.policy_name = self.policy.data['name'].replace(' ', '-').lower()
예제 #4
0
    def provision(self):
        """Provision any resources needed for the policy."""
        template_util = TemplateUtilities()

        parameters = self._get_parameters(template_util)
        group_name = parameters['servicePlanName']['value']
        webapp_name = parameters['name']['value']
        policy_name = self.policy.data['name'].replace(' ', '-').lower()

        existing_webapp = template_util.resource_exist(group_name, webapp_name)

        if not existing_webapp:
            template_util.create_resource_group(
                group_name, {'location': parameters['location']['value']})

            template_util.deploy_resource_template(
                group_name, 'dedicated_functionapp.json', parameters).wait()
        else:
            self.log.info("Found existing App %s (%s) in group %s" %
                          (webapp_name, existing_webapp.location, group_name))

        self.log.info("Building function package for %s" % webapp_name)

        archive = FunctionPackage(policy_name)
        archive.build(self.policy.data)
        archive.close()

        if archive.wait_for_status(webapp_name):
            archive.publish(webapp_name)
        else:
            self.log.error("Aborted deployment, ensure Application Service is healthy.")
예제 #5
0
    def provision(self):
        """Provision any resources needed for the policy."""
        template_util = TemplateUtilities()

        parameters = self._get_parameters(template_util)
        group_name = parameters['servicePlanName']['value']
        webapp_name = parameters['name']['value']
        policy_name = self.policy.data['name'].replace(' ', '-').lower()

        existing_service_plan = self.client.app_service_plans.get(
            group_name, parameters['servicePlanName']['value'])

        if not existing_service_plan:
            template_util.create_resource_group(
                group_name, {'location': parameters['location']['value']})

            template_util.deploy_resource_template(
                group_name, 'dedicated_functionapp.json', parameters).wait()

        else:
            existing_webapp = self.client.web_apps.get(group_name, webapp_name)
            if not existing_webapp:
                functionapp_util = FunctionAppUtilities()
                functionapp_util.deploy_webapp(webapp_name, group_name, existing_service_plan,
                                               parameters['storageName']['value'])
            else:
                self.log.info("Found existing App %s (%s) in group %s" %
                              (webapp_name, existing_webapp.location, group_name))

        self.log.info("Building function package for %s" % webapp_name)

        archive = FunctionPackage(policy_name)
        archive.build(self.policy.data)
        archive.close()

        if archive.wait_for_status(webapp_name):
            archive.publish(webapp_name)
        else:
            self.log.error("Aborted deployment, ensure Application Service is healthy.")
예제 #6
0
 def __init__(self, policy):
     self.policy = policy
     self.template_util = TemplateUtilities()
예제 #7
0
class AzureFunctionMode(ServerlessExecutionMode):
    """A policy that runs/executes in azure functions."""

    schema = {
        'type': 'object',
        'additionalProperties': False,
        'properties': {
            'provision-options': {
                'type': 'object',
                'location': 'string',
                'appInsightsLocation': 'string',
                'servicePlanName': 'string',
                'sku': 'string',
                'workerSize': 'number',
                'skuCode': 'string'
            }
        }
    }

    POLICY_METRICS = ('ResourceCount', 'ResourceTime', 'ActionTime')

    def __init__(self, policy):
        self.policy = policy
        self.template_util = TemplateUtilities()

    def run(self, event=None, lambda_context=None):
        """Run the actual policy."""
        raise NotImplementedError("subclass responsibility")

    def provision(self):
        """Provision any resources needed for the policy."""
        parameters = self.get_parameters()
        group_name = parameters['servicePlanName']['value']

        self.template_util.create_resource_group(
            group_name, {'location': parameters['location']['value']})

        self.template_util.deploy_resource_template(
            group_name, 'dedicated_functionapp.json', parameters).wait()

    def get_parameters(self):
        parameters = self.template_util.get_default_parameters(
            'dedicated_functionapp.parameters.json')

        data = self.policy.data
        updated_parameters = {
            'name': data['name'].replace(' ', '-').lower(),
            'storageName': data['name'].replace('-', '').lower()
        }

        if 'mode' in data:
            if 'provision-options' in data['mode']:
                updated_parameters.update(data['mode']['provision-options'])

        parameters = self.template_util.update_parameters(
            parameters, updated_parameters)

        return parameters

    def get_logs(self, start, end):
        """Retrieve logs for the policy"""
        raise NotImplementedError("subclass responsibility")

    def validate(self):
        """Validate configuration settings for execution mode."""
예제 #8
0
class AzureFunctionMode(ServerlessExecutionMode):
    """A policy that runs/executes in azure functions."""

    schema = {
        'type': 'object',
        'additionalProperties': False,
        'properties': {
            'provision-options': {
                'type': 'object',
                'location': 'string',
                'appInsightsLocation': 'string',
                'servicePlanName': 'string',
                'sku': 'string',
                'workerSize': 'number',
                'skuCode': 'string'
            },
            'execution-options': {
                'type': 'object'
            }
        }
    }

    POLICY_METRICS = ('ResourceCount', 'ResourceTime', 'ActionTime')

    def __init__(self, policy):
        self.policy = policy
        self.log = logging.getLogger('custodian.azure.AzureFunctionMode')

        self.template_util = TemplateUtilities()
        self.parameters = self._get_parameters(self.template_util)
        self.group_name = self.parameters['servicePlanName']['value']
        self.webapp_name = self.parameters['name']['value']
        self.policy_name = self.policy.data['name'].replace(' ', '-').lower()

    def run(self, event=None, lambda_context=None):
        """Run the actual policy."""
        raise NotImplementedError("subclass responsibility")

    def provision(self):
        """Provision any resources needed for the policy."""
        session = local_session(self.policy.session_factory)
        client = session.client('azure.mgmt.web.WebSiteManagementClient')

        existing_service_plan = client.app_service_plans.get(
            self.group_name, self.parameters['servicePlanName']['value'])

        if not existing_service_plan:
            self.template_util.create_resource_group(
                self.group_name,
                {'location': self.parameters['location']['value']})

            self.template_util.deploy_resource_template(
                self.group_name, 'dedicated_functionapp.json',
                self.parameters).wait()

        else:
            existing_webapp = client.web_apps.get(self.group_name,
                                                  self.webapp_name)
            if not existing_webapp:
                functionapp_util = FunctionAppUtilities()
                functionapp_util.deploy_webapp(
                    self.webapp_name, self.group_name, existing_service_plan,
                    self.parameters['storageName']['value'])
            else:
                self.log.info("Found existing App %s (%s) in group %s" %
                              (self.webapp_name, existing_webapp.location,
                               self.group_name))

        self.log.info("Building function package for %s" % self.webapp_name)

        archive = FunctionPackage(self.policy_name)
        archive.build(self.policy.data)
        archive.close()

        self.log.info("Function package built, size is %dMB" %
                      (archive.pkg.size / (1024 * 1024)))

        if archive.wait_for_status(self.webapp_name):
            archive.publish(self.webapp_name)
        else:
            self.log.error(
                "Aborted deployment, ensure Application Service is healthy.")

    def _get_parameters(self, template_util):
        parameters = template_util.get_default_parameters(
            'dedicated_functionapp.parameters.json')

        data = self.policy.data

        updated_parameters = {
            'dockerVersion':
            CONST_DOCKER_VERSION,
            'functionsExtVersion':
            CONST_FUNCTIONS_EXT_VERSION,
            'machineDecryptionKey':
            FunctionAppUtilities.generate_machine_decryption_key()
        }

        if 'mode' in data:
            if 'provision-options' in data['mode']:
                updated_parameters.update(data['mode']['provision-options'])
                if 'servicePlanName' in data['mode']['provision-options']:
                    updated_parameters['name'] = (
                        data['mode']['provision-options']['servicePlanName'] +
                        '-' + data['name']).replace(' ', '-').lower()

                    updated_parameters['storageName'] = (
                        data['mode']['provision-options']['servicePlanName']
                    ).replace('-', '').lower()

        parameters = template_util.update_parameters(parameters,
                                                     updated_parameters)

        return parameters

    def get_logs(self, start, end):
        """Retrieve logs for the policy"""
        raise NotImplementedError("subclass responsibility")

    def validate(self):
        """Validate configuration settings for execution mode."""
예제 #9
0
def provision(config):
    log = logging.getLogger('c7n_mailer.azure.deploy')

    function_name = config.get('function_name', 'mailer')

    func_config = dict(
        name=function_name,
        servicePlanName=config.get('function_servicePlanName',
                                   'cloudcustodian'),
        location=config.get('function_location'),
        appInsightsLocation=config.get('function_appInsightsLocation'),
        schedule=config.get('function_schedule', '0 */10 * * * *'),
        skuCode=config.get('function_skuCode'),
        sku=config.get('function_sku'))

    template_util = TemplateUtilities()

    parameters = _get_parameters(template_util, func_config)
    group_name = parameters['servicePlanName']['value']
    webapp_name = parameters['name']['value']

    # Check if already existing
    existing_webapp = template_util.resource_exist(group_name, webapp_name)

    # Deploy
    if not existing_webapp:
        template_util.create_resource_group(
            group_name, {'location': parameters['location']['value']})

        template_util.deploy_resource_template(group_name,
                                               'dedicated_functionapp.json',
                                               parameters).wait()
    else:
        log.info("Found existing App %s (%s) in group %s" %
                 (webapp_name, existing_webapp.location, group_name))

    log.info("Building function package for %s" % webapp_name)

    # Build package
    packager = FunctionPackage(
        function_name, os.path.join(os.path.dirname(__file__), 'function.py'))

    packager.build(None,
                   entry_point=os.path.join(os.path.dirname(__file__),
                                            'handle.py'),
                   extra_modules={'c7n_mailer', 'ruamel'})

    packager.pkg.add_contents(function_name + '/config.json',
                              contents=json.dumps(config))

    packager.pkg.add_contents(function_name + '/function.json',
                              contents=packager.get_function_config({
                                  'mode': {
                                      'type': 'azure-periodic',
                                      'schedule': func_config['schedule']
                                  }
                              }))
    # Add mail templates
    template_dir = os.path.abspath(
        os.path.join(os.path.dirname(__file__), '../..', 'msg-templates'))

    for t in os.listdir(template_dir):
        with open(os.path.join(template_dir, t)) as fh:
            packager.pkg.add_contents('msg-templates/%s' % t, fh.read())

    packager.close()

    if packager.wait_for_status(webapp_name):
        packager.publish(webapp_name)
    else:
        log.error("Aborted deployment, ensure Application Service is healthy.")
예제 #10
0
def provision(config):
    log = logging.getLogger('c7n_mailer.azure.deploy')

    function_name = config.get('function_name', 'mailer')

    func_config = dict(
        name=function_name,
        servicePlanName=config.get('function_servicePlanName', 'cloudcustodian'),
        location=config.get('function_location'),
        appInsightsLocation=config.get('function_appInsightsLocation'),
        schedule=config.get('function_schedule', '0 */10 * * * *'),
        skuCode=config.get('function_skuCode'),
        sku=config.get('function_sku'))

    template_util = TemplateUtilities()

    parameters = _get_parameters(template_util, func_config)
    group_name = parameters['servicePlanName']['value']
    webapp_name = parameters['name']['value']

    # Check if already existing
    existing_webapp = template_util.resource_exist(group_name, webapp_name)

    # Deploy
    if not existing_webapp:
        template_util.create_resource_group(
            group_name, {'location': parameters['location']['value']})

        template_util.deploy_resource_template(
            group_name, 'dedicated_functionapp.json', parameters).wait()
    else:
        log.info("Found existing App %s (%s) in group %s" %
                 (webapp_name, existing_webapp.location, group_name))

    log.info("Building function package for %s" % webapp_name)

    # Build package
    packager = FunctionPackage(
        function_name,
        os.path.join(os.path.dirname(__file__), 'function.py'))

    packager.build(None,
                   entry_point=os.path.join(os.path.dirname(__file__), 'handle.py'),
                   extra_modules={'c7n_mailer', 'ruamel'})

    packager.pkg.add_contents(
        function_name + '/config.json',
        contents=json.dumps(config))

    packager.pkg.add_contents(
        function_name + '/function.json',
        contents=packager.get_function_config({'mode':
                                              {'type': 'azure-periodic',
                                               'schedule': func_config['schedule']}}))
    # Add mail templates
    template_dir = os.path.abspath(
        os.path.join(os.path.dirname(__file__), '../..', 'msg-templates'))

    for t in os.listdir(template_dir):
        with open(os.path.join(template_dir, t)) as fh:
            packager.pkg.add_contents('msg-templates/%s' % t, fh.read())

    packager.close()

    if packager.wait_for_status(webapp_name):
        packager.publish(webapp_name)
    else:
        log.error("Aborted deployment, ensure Application Service is healthy.")
예제 #11
0
 def setUp(self):
     super(TemplateUtilsTest, self).setUp()
     self.template_util = TemplateUtilities()
예제 #12
0
 def __init__(self, policy):
     self.policy = policy
     self.template_util = TemplateUtilities()
     self.log = logging.getLogger('custodian.azure.AzureFunctionMode')
예제 #13
0
class AzureFunctionMode(ServerlessExecutionMode):
    """A policy that runs/executes in azure functions."""

    schema = {
        'type': 'object',
        'additionalProperties': False,
        'properties': {
            'provision-options': {
                'type': 'object',
                'location': 'string',
                'appInsightsLocation': 'string',
                'servicePlanName': 'string',
                'sku': 'string',
                'workerSize': 'number',
                'skuCode': 'string'
            }
        }
    }

    POLICY_METRICS = ('ResourceCount', 'ResourceTime', 'ActionTime')

    def __init__(self, policy):
        self.policy = policy
        self.template_util = TemplateUtilities()
        self.log = logging.getLogger('custodian.azure.AzureFunctionMode')

    def run(self, event=None, lambda_context=None):
        """Run the actual policy."""
        raise NotImplementedError("subclass responsibility")

    def provision(self):
        """Provision any resources needed for the policy."""
        parameters = self.get_parameters()
        group_name = parameters['servicePlanName']['value']
        webapp_name = parameters['name']['value']

        existing_webapp = self.template_util.resource_exist(
            group_name, webapp_name)

        if not existing_webapp:
            self.template_util.create_resource_group(
                group_name, {'location': parameters['location']['value']})

            self.template_util.deploy_resource_template(
                group_name, 'dedicated_functionapp.json', parameters).wait()
        else:
            self.log.info("Found existing App %s (%s) in group %s" %
                          (webapp_name, existing_webapp.location, group_name))

        self.log.info("Building function package for %s" % webapp_name)

        archive = FunctionPackage(self.policy.data)
        archive.build()

        if archive.status(webapp_name):
            archive.publish(webapp_name)
        else:
            self.log.error(
                "Aborted deployment, ensure Application Service is healthy.")

    def get_parameters(self):
        parameters = self.template_util.get_default_parameters(
            'dedicated_functionapp.parameters.json')

        data = self.policy.data

        updated_parameters = {
            'name': (data['mode']['provision-options']['servicePlanName'] +
                     '-' + data['name']).replace(' ', '-').lower(),
            'storageName':
            data['mode']['provision-options']['servicePlanName']
        }

        if 'mode' in data:
            if 'provision-options' in data['mode']:
                updated_parameters.update(data['mode']['provision-options'])

        parameters = self.template_util.update_parameters(
            parameters, updated_parameters)

        return parameters

    def get_logs(self, start, end):
        """Retrieve logs for the policy"""
        raise NotImplementedError("subclass responsibility")

    def validate(self):
        """Validate configuration settings for execution mode."""