def _process_resource(self, resource): tags = resource.get('tags', {}) # add new tag tags[self.tag] = self.msg TagHelper.update_resource_tags(self, resource, tags)
def test_update_tags(self): resource = tools.get_resource({}) resource_group = tools.get_resource_group_resource({}) client_mock = Mock() action = Mock() action.manager.type = 'resourcegroup' action.session.client.return_value = client_mock TagHelper.update_resource_tags(action, resource_group, self.existing_tags) client_mock.resource_groups.update.assert_called_once() args = client_mock.resource_groups.update.call_args[0] self.assertEqual(args[0], resource_group['name']) self.assertEqual(args[1].tags, self.existing_tags) # Only PATCH tags self.assertListEqual(['tags'], [x for x in args[1].as_dict() if x is not None]) action.manager.type = 'vm' TagHelper.update_resource_tags(action, resource, self.existing_tags) client_mock.resources.update_by_id.assert_called_once() args = client_mock.resources.update_by_id.call_args[0] self.assertEqual(args[0], resource['id']) self.assertEqual(args[2].tags, self.existing_tags) # Only PATCH tags self.assertListEqual(['tags'], [x for x in args[2].as_dict() if x is not None])
def _process_account_set(self, resources, account_client): account_tag_values = [] tag_name = self.data.get('state-tag') cosmos_account = resources[0]['c7n:parent'] for resource in resources: # dividing by multiplier to reduce string size (throughputs are multiples of 100) throughput = int( resource['c7n:offer']['content']['offerThroughput'] / THROUGHPUT_MULTIPLIER) account_tag_values.append('{}:{}'.format(resource['_rid'], throughput)) tag_value = ';'.join(account_tag_values) if len(tag_value) > self.TAG_VALUE_CHAR_LIMIT: raise ValueError( 'Can not add tag, {}, on parent resource, {}, ' 'because tag value exceeds allowed length.' 'Add filters to reduce number of containers.'.format( tag_name, cosmos_account['name'])) TagHelper.add_tags(self, cosmos_account, {tag_name: tag_value}) return resources
def process_resource_set(self, resources): for resource in resources: # get existing tags tags = resource.get('tags', {}) if self.space and len(tags) + self.space <= self.max_tag_count: return # delete tags keys = set(tags) tags_to_preserve = self.preserve.intersection(keys) candidates = keys - tags_to_preserve if self.space: # Free up slots to fit remove = (len(candidates) - (self.max_tag_count - (self.space + len(tags_to_preserve)))) candidates = list(sorted(candidates))[:remove] if not candidates: self.log.warning("Could not find any candidates to trim %s" % resource['id']) return TagHelper.remove_tags(self, resource, candidates)
def process_resource_set(self, resources): for resource in resources: # get existing tags tags = resource.get('tags', {}) # add new tag tags[self.tag] = self.msg TagHelper.update_resource_tags(self, resource, tags)
def process_resource(self, resource, event_item=None): # if the auto-tag-user policy set update to False (or it's unset) then we # will skip writing their UserName tag and not overwrite pre-existing values if not self.should_update and resource.get('tags', {}).get(self.tag_key, None): return user = self.default_user if event_item: principal_type = self.principal_type_jmes_path.search(event_item) if principal_type == 'User': user = self.user_jmes_path.search(event_item) or user elif principal_type == 'ServicePrincipal': user = self.sp_jmes_path.search(event_item) or user else: self.log.error('Principal type of event cannot be determined.') return else: # Calculate start time delta_days = self.data.get('days', self.max_query_days) start_time = utcnow() - datetime.timedelta(days=delta_days) # resource group type if self.manager.type == 'resourcegroup': resource_type = "Microsoft.Resources/subscriptions/resourcegroups" query_filter = " and ".join([ "eventTimestamp ge '%s'" % start_time, "resourceGroupName eq '%s'" % resource['name'], "eventChannels eq 'Operation'" ]) # other Azure resources else: resource_type = resource['type'] query_filter = " and ".join([ "eventTimestamp ge '%s'" % start_time, "resourceUri eq '%s'" % resource['id'], "eventChannels eq 'Operation'" ]) # fetch activity logs logs = self.client.activity_logs.list( filter=query_filter, select=self.query_select ) # get the user who issued the first operation operation_name = "%s/write" % resource_type first_op = self.get_first_operation(logs, operation_name) if first_op is not None: user = first_op.caller # issue tag action to label user try: TagHelper.add_tags(self, resource, {self.tag_key: user}) except CloudError as e: # resources can be locked if e.inner_exception.error == 'ScopeLocked': pass
def test_add_tags(self, update_resource_tags): resource = tools.get_resource(self.existing_tags) TagHelper.add_tags(None, resource, {}) update_resource_tags.assert_not_called() TagHelper.add_tags(None, resource, {'tag3': 'value3'}) expected_tags = self.existing_tags.copy() expected_tags.update({'tag3': 'value3'}) self.assertEqual(tools.get_tags_parameter(update_resource_tags), expected_tags)
def _process_resource(self, resource, event): # if the auto-tag-user policy set update to False (or it's unset) then we # will skip writing their UserName tag and not overwrite pre-existing values if not self.should_update and resource.get('tags', {}).get(self.tag_key, None): return tag_value = self.default_value if event: tag_value = self._get_tag_value_from_event(event) or tag_value else: tag_value = self._get_tag_value_from_resource(resource) or tag_value TagHelper.add_tags(self, resource, {self.tag_key: tag_value})
def _process_resource(self, resource, event): # if the auto-tag-user policy set update to False (or it's unset) then we # will skip writing their UserName tag and not overwrite pre-existing values if not self.should_update and resource.get('tags', {}).get(self.tag_key, None): return user = self.default_user if event: user = self._get_user_from_event(event) or user else: user = self._get_user_from_resource_logs(resource) or user # issue tag action to label user TagHelper.add_tags(self, resource, {self.tag_key: user})
def _process_resource(self, resource, event): # if the auto-tag-user policy set update to False (or it's unset) then we # will skip writing their UserName tag and not overwrite pre-existing values if not self.should_update and resource.get('tags', {}).get( self.tag_key, None): return user = self.default_user if event: user = self._get_user_from_event(event) or user else: user = self._get_user_from_resource_logs(resource) or user # issue tag action to label user TagHelper.add_tags(self, resource, {self.tag_key: user})
def test_get_tag_value(self): resource = { 'tags': { 'tag1': 'value1', 'tAg2': 'VaLuE2', 'TAG3': 'VALUE3' } } self.assertEqual(TagHelper.get_tag_value(resource, 'tag1', True), 'value1') self.assertEqual(TagHelper.get_tag_value(resource, 'tag2', True), 'VaLuE2') self.assertEqual(TagHelper.get_tag_value(resource, 'tag3', True), 'VALUE3')
def process_resource(self, resource): # if the auto-tag-user policy set update to False (or it's unset) then we # will skip writing their UserName tag and not overwrite pre-existing values if not self.should_update and resource.get('tags', {}).get(self.tag_key, None): return user = self.default_user # Calculate start time delta_days = self.data.get('days', self.max_query_days) start_time = utcnow() - datetime.timedelta(days=delta_days) # resource group type if self.manager.type == 'resourcegroup': resource_type = "Microsoft.Resources/subscriptions/resourcegroups" query_filter = " and ".join([ "eventTimestamp ge '%s'" % start_time, "resourceGroupName eq '%s'" % resource['name'], "eventChannels eq 'Operation'" ]) # other Azure resources else: resource_type = resource['type'] query_filter = " and ".join([ "eventTimestamp ge '%s'" % start_time, "resourceUri eq '%s'" % resource['id'], "eventChannels eq 'Operation'" ]) # fetch activity logs logs = self.client.activity_logs.list( filter=query_filter, select=self.query_select ) # get the user who issued the first operation operation_name = "%s/write" % resource_type first_op = self.get_first_operation(logs, operation_name) if first_op is not None: user = first_op.caller # issue tag action to label user try: TagHelper.add_tags(self, resource, {self.tag_key: user}) except CloudError as e: # resources can be locked if e.inner_exception.error == 'ScopeLocked': pass
def _process_account_set(self, resources, account_client): try: parent_account = resources[0]['c7n:parent'] tag_name = self.data.get('state-tag') container_states_tag_value = TagHelper.get_tag_value( parent_account, tag_name) if container_states_tag_value: for state in container_states_tag_value.split(';'): state_data = state.split(':') container_rid = state_data[0] # restoring throughput size with multiplier since it was stored to save space container_throughput = int(state_data[1]) * THROUGHPUT_MULTIPLIER container = next((c for c in resources if c['_rid'] == container_rid), None) if container: self._process_resource(container, account_client, container_throughput) else: log.warning('No tag {} on parent resource, {}.'.format( tag_name, parent_account)) except Exception as e: log.warning(e) return resources
def get_tag_value(self, i): tag_value = TagHelper.get_tag_value(resource=i, tag=self.tag_key, utf_8=True) if tag_value is not False: tag_value = tag_value.lower().strip("'\"") return tag_value
def process_resource_set(self, resources, event=None): for resource in resources: # if the auto-tag-user policy set update to False (or it's unset) then we # will skip writing their UserName tag and not overwrite pre-existing values if not self.should_update and resource.get('tags', {}).get(self.tag_key, None): return user = self.default_user if event: user = self._get_user_from_event(event) or user else: user = self._get_user_from_resource_logs(resource) or user # issue tag action to label user try: TagHelper.add_tags(self, resource, {self.tag_key: user}) except CloudError as e: # resources can be locked if e.inner_exception.error == 'ScopeLocked': pass
def _process_resource(self, resource): tags = resource.get('tags', {}) if self.space and len(tags) + self.space <= self.max_tag_count: return # delete tags keys = set(tags) tags_to_preserve = self.preserve.intersection(keys) candidates = keys - tags_to_preserve if self.space: # Free up slots to fit remove = (len(candidates) - (self.max_tag_count - (self.space + len(tags_to_preserve)))) candidates = list(sorted(candidates))[:remove] if not candidates: self.log.warning( "Could not find any candidates to trim %s" % resource['id']) return TagHelper.remove_tags(self, resource, candidates)
def test_remove_tags(self, update_resource_tags): resource = tools.get_resource(self.existing_tags) TagHelper.remove_tags(None, resource, []) update_resource_tags.assert_not_called() TagHelper.remove_tags(None, resource, ['tag3']) update_resource_tags.assert_not_called() TagHelper.remove_tags(None, resource, ['tag2']) expected_tags = {'tag1': 'value1'} self.assertEqual(tools.get_tags_parameter(update_resource_tags), expected_tags)
def process_resource(self, resource): tags_to_delete = self.data.get('tags') TagHelper.remove_tags(self, resource, tags_to_delete)
def process_resource(self, resource): new_tags = self.data.get('tags') or { self.data.get('tag'): self.data.get('value') } TagHelper.add_tags(self, resource, new_tags)
def process_resource(self, resource): new_tags = self.data.get('tags') or {self.data.get('tag'): self.data.get('value')} TagHelper.add_tags(self, resource, new_tags)
def _process_resource(self, resource): new_tags = self._get_tags(resource) TagHelper.add_tags(self, resource, new_tags)
def _process_resource(self, resource): TagHelper.add_tags(self, resource, self.new_tags)
def _process_resource(self, resource): TagHelper.remove_tags(self, resource, self.tags_to_delete)
def test_get_tag_value(self): resource = tools.get_resource(self.existing_tags) self.assertEqual(TagHelper.get_tag_value(resource, 'tag1'), 'value1') self.assertEqual(TagHelper.get_tag_value(resource, 'tag2'), 'value2') self.assertFalse(TagHelper.get_tag_value(resource, 'tag3'))
def test_get_tag_value(self): resource = {'tags': {'tag1': 'value1', 'tAg2': 'VaLuE2', 'TAG3': 'VALUE3'}} self.assertEqual(TagHelper.get_tag_value(resource, 'tag1', True), 'value1') self.assertEqual(TagHelper.get_tag_value(resource, 'tag2', True), 'VaLuE2') self.assertEqual(TagHelper.get_tag_value(resource, 'tag3', True), 'VALUE3')
def process_resource_set(self, resources): for resource in resources: new_tags = self.data.get('tags') or { self.data.get('tag'): self.data.get('value') } TagHelper.add_tags(self, resource, new_tags)
def process_resource_set(self, resources): for resource in resources: tags_to_delete = self.data.get('tags') TagHelper.remove_tags(self, resource, tags_to_delete)