def test_init_azure_function_mode_with_service_plan(self): p = self.load_policy({ 'name': 'test-azure-serverless-mode', 'resource': 'azure.vm', 'mode': {'type': FUNCTION_EVENT_TRIGGER_MODE, 'events': ['VmWrite'], 'provision-options': { 'servicePlan': { 'name': 'test-cloud-custodian', 'location': 'eastus', 'resourceGroupName': 'test'} }} }) function_mode = AzureFunctionMode(p) params = function_mode.get_function_app_params() self.assertEqual(function_mode.policy_name, p.data['name']) self.assertTrue(params.storage_account['name'].startswith('custodian')) self.assertEqual(params.app_insights['name'], 'test-cloud-custodian') self.assertEqual(params.service_plan['name'], "test-cloud-custodian") self.assertEqual(params.service_plan['location'], "eastus") self.assertEqual(params.app_insights['location'], "eastus") self.assertEqual(params.storage_account['location'], "eastus") self.assertEqual(params.storage_account['resource_group_name'], 'test') self.assertEqual(params.app_insights['resource_group_name'], 'test') self.assertEqual(params.service_plan['resource_group_name'], "test") self.assertTrue(params.function_app_name.startswith('test-azure-serverless-mode-'))
def test_init_azure_function_mode_no_service_plan_name(self): p = self.load_policy({ 'name': 'test-azure-serverless-mode', 'resource': 'azure.vm', 'mode': {'type': FUNCTION_EVENT_TRIGGER_MODE, 'events': ['VmWrite']} }) function_mode = AzureFunctionMode(p) params = function_mode.get_function_app_params() self.assertEqual(function_mode.policy_name, p.data['name']) self.assertEqual(params.service_plan['name'], "cloud-custodian") self.assertEqual(params.service_plan['location'], "westus2") self.assertEqual(params.service_plan['resource_group_name'], "cloud-custodian") self.assertEqual(params.app_insights['name'], 'cloud-custodian') self.assertEqual(params.app_insights['location'], "westus2") self.assertEqual(params.app_insights['resource_group_name'], 'cloud-custodian') self.assertEqual(params.storage_account['name'], 'custodian7564f106') self.assertEqual(params.storage_account['location'], "westus2") self.assertEqual(params.storage_account['resource_group_name'], 'cloud-custodian') self.assertEqual(params.function_app_name, 'test-azure-serverless-mode-7564f106')
def provision(config): log = logging.getLogger('c7n_mailer.azure.deploy') function_name = config.get('function_name', 'mailer') function_properties = config.get('function_properties', {}) # service plan is parse first, because its location might be shared with storage & insights service_plan = AzureFunctionMode.extract_properties(function_properties, 'servicePlan', { 'name': 'cloud-custodian', 'location': 'eastus', 'resource_group_name': 'cloud-custodian', 'sku_tier': 'Dynamic', # consumption plan 'sku_name': 'Y1' }) location = service_plan.get('location', 'eastus') rg_name = service_plan['resource_group_name'] sub_id = local_session(Session).get_subscription_id() suffix = StringUtils.naming_hash(rg_name + sub_id) storage_account = AzureFunctionMode.extract_properties(function_properties, 'storageAccount', {'name': 'mailerstorage' + suffix, 'location': location, 'resource_group_name': rg_name}) app_insights = AzureFunctionMode.extract_properties(function_properties, 'appInsights', {'name': service_plan['name'], 'location': location, 'resource_group_name': rg_name}) function_app_name = FunctionAppUtilities.get_function_name( '-'.join([service_plan['name'], function_name]), suffix) FunctionAppUtilities.validate_function_name(function_app_name) params = FunctionAppUtilities.FunctionAppInfrastructureParameters( app_insights=app_insights, service_plan=service_plan, storage_account=storage_account, function_app_resource_group_name=service_plan['resource_group_name'], function_app_name=function_app_name) FunctionAppUtilities.deploy_function_app(params) log.info("Building function package for %s" % function_app_name) package = build_function_package(config, function_name) log.info("Function package built, size is %dMB" % (package.pkg.size / (1024 * 1024))) FunctionAppUtilities.publish_functions_package(params, package)
def test_init_azure_function_mode_invalid_characters_in_policy_name(self): p = self.load_policy({ 'name': 'invalid_policy_name1', 'resource': 'azure.vm', 'mode': {'type': FUNCTION_EVENT_TRIGGER_MODE, 'events': ['VmWrite']} }) function_mode = AzureFunctionMode(p) params = function_mode.get_function_app_params() self.assertRegexpMatches(params.function_app_name, "invalid-policy-name1-[a-zA-Z0-9]+")
def test_init_azure_function_mode_invalid_policy_name(self): p = self.load_policy({ 'name': 'this-policy-name-is-going-to-be-too-long-since-the-maximum-size-is-60', 'resource': 'azure.vm', 'mode': {'type': FUNCTION_EVENT_TRIGGER_MODE, 'events': ['VmWrite']} }) function_mode = AzureFunctionMode(p) with self.assertRaises(ValueError): function_mode.get_function_app_params()
def test_init_azure_function_mode_with_resource_ids(self): ai_id = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups' \ '/testrg/providers/microsoft.insights/components/testai' sp_id = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups' \ '/testrg/providers/Microsoft.Web/serverFarms/testsp' sa_id = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups' \ '/testrg/providers/Microsoft.Storage/storageAccounts/testsa' p = self.load_policy({ 'name': 'test-azure-serverless-mode', 'resource': 'azure.vm', 'mode': {'type': FUNCTION_EVENT_TRIGGER_MODE, 'events': ['VmWrite'], 'provision-options': { 'servicePlan': sp_id, 'storageAccount': sa_id, 'appInsights': ai_id }} }) function_mode = AzureFunctionMode(p) params = function_mode.get_function_app_params() self.assertEqual(function_mode.policy_name, p.data['name']) self.assertEqual(params.storage_account['id'], sa_id) self.assertEqual(params.storage_account['name'], 'testsa') self.assertEqual(params.storage_account['resource_group_name'], 'testrg') self.assertEqual(params.app_insights['id'], ai_id) self.assertEqual(params.app_insights['name'], 'testai') self.assertEqual(params.app_insights['resource_group_name'], 'testrg') self.assertEqual(params.service_plan['id'], sp_id) self.assertEqual(params.service_plan['name'], "testsp") self.assertEqual(params.service_plan['resource_group_name'], "testrg") self.assertEqual(params.function_app_name, 'test-azure-serverless-mode-8614f79d')
def provision(config): log = logging.getLogger('c7n_mailer.azure.deploy') function_name = config.get('function_name', 'mailer') schedule = config.get('function_schedule', '0 */10 * * * *') function_properties = config.get('function_properties', {}) # service plan is parse first, because its location might be shared with storage & insights service_plan = AzureFunctionMode.extract_properties(function_properties, 'servicePlan', {'name': 'cloud-custodian', 'location': 'westus2', 'resource_group_name': 'cloud-custodian', 'sku_name': 'B1', 'sku_tier': 'Basic'}) location = service_plan.get('location', 'westus2') rg_name = service_plan['resource_group_name'] sub_id = local_session(Session).get_subscription_id() suffix = StringUtils.naming_hash(rg_name + sub_id) storage_account = AzureFunctionMode.extract_properties(function_properties, 'storageAccount', {'name': 'mailerstorage' + suffix, 'location': location, 'resource_group_name': rg_name}) app_insights = AzureFunctionMode.extract_properties(function_properties, 'appInsights', {'name': service_plan['name'], 'location': location, 'resource_group_name': rg_name}) function_app_name = \ '-'.join([service_plan['name'], function_name, suffix]) \ .replace(' ', '-').lower() params = FunctionAppUtilities.FunctionAppInfrastructureParameters( app_insights=app_insights, service_plan=service_plan, storage_account=storage_account, function_app_resource_group_name=service_plan['resource_group_name'], function_app_name=function_app_name) function_app = FunctionAppUtilities().deploy_dedicated_function_app(params) log.info("Building function package for %s" % function_app_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': 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(function_app): packager.publish(function_app) else: log.error("Aborted deployment, ensure Application Service is healthy.")
def provision(config): log = logging.getLogger('c7n_mailer.azure.deploy') function_name = config.get('function_name', 'mailer') schedule = config.get('function_schedule', '0 */10 * * * *') function_properties = config.get('function_properties', {}) # service plan is parse first, because its location might be shared with storage & insights service_plan = AzureFunctionMode.extract_properties( function_properties, 'servicePlan', { 'name': 'cloud-custodian', 'location': 'westus2', 'resource_group_name': 'cloud-custodian', 'sku_name': 'B1', 'sku_tier': 'Basic' }) location = service_plan.get('location', 'westus2') rg_name = service_plan['resource_group_name'] storage_account = AzureFunctionMode.extract_properties( function_properties, 'storageAccount', { 'name': 'custodianstorageaccount', 'location': location, 'resource_group_name': rg_name }) app_insights = AzureFunctionMode.extract_properties( function_properties, 'appInsights', { 'name': service_plan['name'], 'location': location, 'resource_group_name': rg_name }) functionapp_name = (service_plan['name'] + '-' + function_name).replace( ' ', '-').lower() params = FunctionAppUtilities.FunctionAppInfrastructureParameters( app_insights=app_insights, service_plan=service_plan, storage_account=storage_account, functionapp_name=functionapp_name) FunctionAppUtilities().deploy_dedicated_function_app(params) log.info("Building function package for %s" % functionapp_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': 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(functionapp_name): packager.publish(functionapp_name) else: log.error("Aborted deployment, ensure Application Service is healthy.")