Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/spaceone/inventory/managed_resource/metric/iam_user_count.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
metric_id: metric-managed-iam-user
name: User Count
metric_type: GAUGE
resource_type: identity.User
query_options:
group_by:
- key: state
name: State
default: true
- key: role_type
name: Role Type
- key: auth_type
name: Auth Type
fields:
value:
operator: count
unit: Count
namespace_id: ns-managed-iam-summary
version: '1.0'
12 changes: 12 additions & 0 deletions src/spaceone/inventory/manager/identity_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,15 @@ def analyze_workspaces(self, query: dict, domain_id: str) -> dict:
return self.identity_conn.dispatch(
"Workspace.analyze", {"query": query}, x_domain_id=domain_id
)

def list_rolebindings(self, query: dict, domain_id: str) -> dict:
# For background job, use system token
return self.identity_conn.dispatch(
"RoleBinding.list", {"query": query}, x_domain_id=domain_id
)

def list_users(self, query: dict, domain_id: str) -> dict:
# For background job, use system token
return self.identity_conn.dispatch(
"User.list", {"query": query}, x_domain_id=domain_id
)
68 changes: 67 additions & 1 deletion src/spaceone/inventory/manager/metric_manager.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import logging
import copy
import time
from typing import Tuple, Union
from typing import Tuple, Union, List, Dict, Any
from datetime import datetime
from dateutil.relativedelta import relativedelta
from collections import defaultdict

from spaceone.core import config, queue
from spaceone.core.model.mongo_model import QuerySet
Expand Down Expand Up @@ -241,6 +242,8 @@ def analyze_resource(
return self._analyze_service_accounts(query, domain_id)
elif metric_vo.resource_type == "identity.Workspace":
return self._analyze_workspaces(query, domain_id)
elif metric_vo.resource_type == "identity.User":
return self._analyze_users(query, domain_id)
else:
raise ERROR_NOT_SUPPORT_RESOURCE_TYPE(resource_type=resource_type)
except Exception as e:
Expand Down Expand Up @@ -788,3 +791,66 @@ def _analyze_workspaces(query: dict, domain_id: str) -> list:
response = identity_mgr.analyze_workspaces(query, domain_id)

return response.get("results", [])

@staticmethod
def _analyze_users(query: dict, domain_id: str) -> list:
identity_mgr = IdentityManager()

# role binding list
rolebinding_results = identity_mgr.list_rolebindings(
{
"only": ["domain_id", "workspace_id", "role_type", "user_id"],
}, domain_id)

rolebindings_info = rolebinding_results.get("results", [])

# user list
user_results = identity_mgr.list_users(
{
"only": ["user_id", "state", "auth_type"],
}, domain_id)

users_info = user_results.get("results", [])
user_lookup = {user['user_id']: user for user in users_info}

# role binding list + user list
joined_list = []
for rolebinding in rolebindings_info:
user = user_lookup.get(rolebinding['user_id'], {})
joined = rolebinding.copy()
joined['state'] = user.get('state')
joined['auth_type'] = user.get('auth_type')
joined_list.append(joined)

# group by keys
group_by_keys = ['domain_id', 'workspace_id']
group_by_specs = query.get('group_by', [])
if 'group_by' in query and group_by_specs:
for specs in group_by_specs:
key = specs['key']
if key not in group_by_keys:
group_by_keys.append(key)

# count
counter: Dict[tuple, int] = defaultdict(int)
for rec in joined_list:
# tuple of group by keys
key = tuple(rec.get(k) for k in group_by_keys)
counter[key] += 1

# result
result: List[Dict[str, Any]] = []
for key_tuple, cnt in counter.items():
out: Dict[str, Any] = {
'domain_id': key_tuple[0],
'workspace_id': key_tuple[1],
}

for idx, spec in enumerate(group_by_specs, start=2):
name = spec.get('name')
out[name] = key_tuple[idx]

out['value'] = float(cnt)
result.append(out)

return result
Loading