def test_invalid_group_id_key_returns_none(self): """ If there is no group ID key, either old or new style, :func:`NovaServer.group_id_from_metadata` returns `None`. """ for key in (":rax:autoscale:group:id", "rax:autoscaling_group_id", "completely_wrong"): self.assertIsNone(group_id_from_metadata({key: "group_id"})) self.assertIsNone(group_id_from_metadata({}))
def test_invalid_group_id_key_returns_none(self): """ If there is no group ID key, either old or new style, :func:`NovaServer.group_id_from_metadata` returns `None`. """ for key in (":rax:autoscale:group:id", "rax:autoscaling_group_id", "completely_wrong"): self.assertIsNone( group_id_from_metadata({key: "group_id"})) self.assertIsNone(group_id_from_metadata({}))
def get_tenant_metrics(tenant_id, scaling_groups, grouped_servers, _print=False): """ Produce per-group metrics for all the groups of a tenant :param list scaling_groups: Tenant's scaling groups as dict from CASS :param dict grouped_servers: Servers from Nova grouped based on scaling group ID. :return: generator of (tenantId, groupId, desired, actual) GroupMetrics """ if _print: print('processing tenant {} with groups {} and servers {}'.format( tenant_id, len(scaling_groups), len(grouped_servers))) groups = {g['groupId']: g for g in scaling_groups} for group_id in set(groups.keys() + grouped_servers.keys()): servers = grouped_servers.get(group_id, []) if group_id in groups: group = groups[group_id] else: group = {'groupId': group_id_from_metadata(servers[0]['metadata']), 'desired': 0} servers = map(NovaServer.from_server_details_json, servers) _len = compose(len, list, flip(filter, servers)) active = _len(lambda s: s.state == ServerState.ACTIVE) bad = _len(lambda s: s.state in (ServerState.SHUTOFF, ServerState.ERROR, ServerState.DELETED)) yield GroupMetrics(tenant_id, group['groupId'], group['desired'], active, len(servers) - bad - active)
def get_tenant_metrics(tenant_id, scaling_groups, grouped_servers, _print=False): """ Produce per-group metrics for all the groups of a tenant :param list scaling_groups: Tenant's scaling groups as dict from CASS :param dict grouped_servers: Servers from Nova grouped based on scaling group ID. :return: generator of (tenantId, groupId, desired, actual) GroupMetrics """ if _print: print('processing tenant {} with groups {} and servers {}'.format( tenant_id, len(scaling_groups), len(grouped_servers))) groups = {g['groupId']: g for g in scaling_groups} for group_id in set(groups.keys() + grouped_servers.keys()): servers = grouped_servers.get(group_id, []) if group_id in groups: group = groups[group_id] if group.get("status") in ("ERROR", "DISABLED"): continue else: group = {'groupId': group_id_from_metadata(servers[0]['metadata']), 'desired': 0} servers = map(NovaServer.from_server_details_json, servers) counts = defaultdict(lambda: 0) counts.update(countby(get_destiny, servers)) active = counts[Destiny.CONSIDER_AVAILABLE] + \ counts[Destiny.AVOID_REPLACING] ignore = counts[Destiny.DELETE] + counts[Destiny.CLEANUP] + \ counts[Destiny.IGNORE] yield GroupMetrics(tenant_id, group['groupId'], group['desired'], active, len(servers) - ignore - active)
def test_get_group_id_from_metadata(self): """ :func:`group_id_from_metadata` returns the group ID from metadata no matter if it's old style or new style. """ for key in ("rax:autoscale:group:id", "rax:auto_scaling_group_id"): self.assertEqual(group_id_from_metadata({key: "group_id"}), "group_id")
def get_tenant_metrics(tenant_id, scaling_groups, grouped_servers, _print=False): """ Produce per-group metrics for all the groups of a tenant :param list scaling_groups: Tenant's scaling groups as dict from CASS :param dict grouped_servers: Servers from Nova grouped based on scaling group ID. :return: generator of (tenantId, groupId, desired, actual) GroupMetrics """ if _print: print('processing tenant {} with groups {} and servers {}'.format( tenant_id, len(scaling_groups), len(grouped_servers))) groups = {g['groupId']: g for g in scaling_groups} for group_id in set(groups.keys() + grouped_servers.keys()): servers = grouped_servers.get(group_id, []) if group_id in groups: group = groups[group_id] else: group = { 'groupId': group_id_from_metadata(servers[0]['metadata']), 'desired': 0 } servers = map(NovaServer.from_server_details_json, servers) _len = compose(len, list, flip(filter, servers)) active = _len(lambda s: s.state == ServerState.ACTIVE) bad = _len(lambda s: s.state in (ServerState.SHUTOFF, ServerState. ERROR, ServerState.DELETED)) yield GroupMetrics(tenant_id, group['groupId'], group['desired'], active, len(servers) - bad - active)
def test_get_group_id_from_metadata(self): """ :func:`group_id_from_metadata` returns the group ID from metadata no matter if it's old style or new style. """ for key in ("rax:autoscale:group:id", "rax:auto_scaling_group_id"): self.assertEqual( group_id_from_metadata({key: "group_id"}), "group_id")
def _is_server_in_group(group, server_id): """ Given a group and server ID, determines if the server is a member of the group. If it isn't, it raises a :class:`ServerNotFoundError`. """ try: response, server_info = yield Effect( TenantScope( retry_effect(get_server_details(server_id), retry_times(3), exponential_backoff_interval(2)), group.tenant_id, ) ) except NoSuchServerError: raise ServerNotFoundError(group.tenant_id, group.uuid, server_id) group_id = group_id_from_metadata(get_in(("server", "metadata"), server_info, {})) if group_id != group.uuid: raise ServerNotFoundError(group.tenant_id, group.uuid, server_id)
def _is_server_in_group(group, server_id): """ Given a group and server ID, determines if the server is a member of the group. If it isn't, it raises a :class:`ServerNotFoundError`. """ try: response, server_info = yield Effect( TenantScope( retry_effect(get_server_details(server_id), retry_times(3), exponential_backoff_interval(2)), group.tenant_id)) except NoSuchServerError: raise ServerNotFoundError(group.tenant_id, group.uuid, server_id) group_id = group_id_from_metadata( get_in(('server', 'metadata'), server_info, {})) if group_id != group.uuid: raise ServerNotFoundError(group.tenant_id, group.uuid, server_id)
def group_id(s): return group_id_from_metadata(s['metadata'])
def server_of_group(group_id, server): """ Return True if server belongs to group_id. False otherwise """ return group_id_from_metadata(server.get('metadata', {})) == group_id