def test_event_package_files(self, session_mock):
        p = self.load_policy({
            'name': 'test-azure-package',
            'resource': 'azure.resourcegroup',
            'mode': {
                'type': FUNCTION_EVENT_TRIGGER_MODE,
                'events': ['VmWrite']
            },
        })

        packer = FunctionPackage(p.data['name'])
        packer.pkg = AzurePythonPackageArchive()

        packer._add_functions_required_files(p.data, 'test-queue')
        files = packer.pkg._zip_file.filelist

        self.assertTrue(
            FunctionPackageTest._file_exists(files,
                                             'test-azure-package/function.py'))
        self.assertTrue(
            FunctionPackageTest._file_exists(files,
                                             'test-azure-package/__init__.py'))
        self.assertTrue(
            FunctionPackageTest._file_exists(
                files, 'test-azure-package/function.json'))
        self.assertTrue(
            FunctionPackageTest._file_exists(files,
                                             'test-azure-package/config.json'))
        self.assertTrue(FunctionPackageTest._file_exists(files, 'host.json'))
    def test_publish_functions_package_consumption(self, _1):
        function_app_name = 'cloud-custodian-test-consumption%s' % self.subscription_id[
            -12:]
        parameters = FunctionAppUtilities.FunctionAppInfrastructureParameters(
            app_insights={
                'id': '',
                'resource_group_name': CONST_GROUP_NAME,
                'name': 'cloud-custodian-test'
            },
            storage_account={
                'id': '',
                'resource_group_name': CONST_GROUP_NAME,
                'name': self.storage_name
            },
            service_plan={
                'id': '',
                'resource_group_name': CONST_GROUP_NAME,
                'name': 'cloud-custodian-test',
                'sku_tier': 'dynamic'
            },
            function_app_resource_group_name=CONST_GROUP_NAME,
            function_app_name=function_app_name)

        package = FunctionPackage("TestPolicy")
        package.pkg = AzurePythonPackageArchive()
        package.close()

        FunctionAppUtilities.publish_functions_package(parameters, package)

        # verify app setting updated
        wc = self.session.client('azure.mgmt.web.WebSiteManagementClient')
        app_settings = wc.web_apps.list_application_settings(
            CONST_GROUP_NAME, function_app_name)
        self.assertIsNotNone(
            app_settings.properties['WEBSITE_RUN_FROM_PACKAGE'])
    def test_auth_file_user_assigned_identity(self):
        p = self.load_policy({
            'name': 'test-azure-public-ip',
            'resource': 'azure.publicip',
            'mode': {
                'type': FUNCTION_EVENT_TRIGGER_MODE,
                'provision-options': {
                    'identity': {
                        'type': 'SystemAssigned'
                    }
                },
                'events': ['PublicIpWrite']
            }
        })
        packer = FunctionPackage(p.data['name'])
        packer.pkg = AzurePythonPackageArchive()
        packer._add_functions_required_files(p.data, 'c7n-azure==1.0',
                                             'test-queue')

        packer.pkg.close()
        with zipfile.ZipFile(packer.pkg.path) as zf:
            content = json.loads(zf.read('test-azure-public-ip/auth.json'))
            self.assertEqual(content, {
                'subscription_id': None,
                'use_msi': True
            })
    def test_publish_functions_package_dedicated(self, _1):
        parameters = FunctionAppUtilities.FunctionAppInfrastructureParameters(
            app_insights={
                'id': '',
                'resource_group_name': CONST_GROUP_NAME,
                'name': 'cloud-custodian-test'
            },
            storage_account={
                'id': '',
                'resource_group_name': CONST_GROUP_NAME,
                'name': self.storage_name
            },
            service_plan={
                'id': '',
                'resource_group_name': CONST_GROUP_NAME,
                'name': 'cloud-custodian-test',
                'sku_tier': 'Basic'
            },
            function_app={
                'resource_group_name': CONST_GROUP_NAME,
                'name': self.dedicated_function_name})

        package = FunctionPackage("TestPolicy")
        package.pkg = AzurePythonPackageArchive()
        package.close()

        FunctionAppUtilities.publish_functions_package(parameters, package)
    def test_no_policy_add_required_files(self, session_mock):
        """ Tools such as mailer will package with no policy """

        packer = FunctionPackage('name')
        packer.pkg = AzurePythonPackageArchive()

        packer._add_functions_required_files(None)
        files = packer.pkg._zip_file.filelist

        self.assertTrue(FunctionPackageTest._file_exists(files, 'host.json'))
    def test_zipped_files_have_modified_timestamp(self):
        t = time.gmtime(1577854800)
        package = AzurePythonPackageArchive()
        package.package_time = t
        package.add_contents('test.txt', 'Hello, World')
        package.close()

        zinfo = package._zip_file.infolist()[0]
        self.assertEqual('test.txt', zinfo.filename)
        self.assertEqual(t[0:6], zinfo.date_time)
    def test_add_host_config(self):
        packer = FunctionPackage('test')
        packer.pkg = AzurePythonPackageArchive()
        with patch('c7n_azure.function_package.AzurePythonPackageArchive.add_contents') as mock:
            packer._add_host_config(FUNCTION_EVENT_TRIGGER_MODE)
            mock.assert_called_once()
            self.assertEqual(mock.call_args[1]['dest'], 'host.json')
            self.assertTrue('extensionBundle' in json.loads(mock.call_args[1]['contents']))

        with patch('c7n_azure.function_package.AzurePythonPackageArchive.add_contents') as mock:
            packer._add_host_config(FUNCTION_TIME_TRIGGER_MODE)
            mock.assert_called_once()
            self.assertEqual(mock.call_args[1]['dest'], 'host.json')
            self.assertFalse('extensionBundle' in json.loads(mock.call_args[1]['contents']))
    def test_publish(self, post_mock):
        status_mock = MagicMock()
        post_mock.return_value = status_mock
        packer = FunctionPackage('test')
        packer.pkg = AzurePythonPackageArchive()
        creds = User(publishing_user_name='user',
                     publishing_password='******',
                     scm_uri='https://uri')

        packer.publish(creds)

        post_mock.assert_called_once()
        status_mock.raise_for_status.assert_called_once()

        self.assertEqual(post_mock.call_args[0][0],
                         'https://uri/api/zipdeploy?isAsync=true&synctriggers=true')
        self.assertEqual(post_mock.call_args[1]['headers']['content-type'],
                         'application/octet-stream')
    def test_zipped_files_with_zip_cache_unmodified_cache_timestamps(self):
        cache_ts = time.gmtime(1577000000)
        cache = AzurePythonPackageArchive()
        cache.package_time = cache_ts
        cache.add_contents('cache.txt', 'I am a cache file')
        cache.close()

        new_ts = time.gmtime(1577854800)
        package = AzurePythonPackageArchive(cache_file=cache.path)
        package.package_time = new_ts
        package.add_contents('new.txt', 'I am a new file')
        package.close()

        cache_file = package._zip_file.infolist()[0]
        self.assertEqual('cache.txt', cache_file.filename)
        self.assertEqual(cache_ts[0:6], cache_file.date_time)

        new_file = package._zip_file.infolist()[1]
        self.assertEqual('new.txt', new_file.filename)
        self.assertEqual(new_ts[0:6], new_file.date_time)