Skip to content

Commit

Permalink
Merge pull request #261 from ImMin5/feature-service-accont-auto-sync
Browse files Browse the repository at this point in the history
Add delete workspace related resource with identity
  • Loading branch information
ImMin5 authored Apr 16, 2024
2 parents 6082560 + a43811c commit 95d588c
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 51 deletions.
1 change: 1 addition & 0 deletions src/spaceone/identity/model/workspace/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class WorkspaceUpdateRequest(BaseModel):


class WorkspaceDeleteRequest(BaseModel):
force: Union[bool, None] = False
workspace_id: str
domain_id: str

Expand Down
29 changes: 14 additions & 15 deletions src/spaceone/identity/service/job_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __init__(self, *args, **kwargs):
self.project_group_mgr = ProjectGroupManager()

@transaction(exclude=["authentication", "authorization", "mutation"])
def create_jobs_by_trusted_account(self, params):
def create_jobs_by_trusted_account(self, params: dict):
"""Create jobs by trusted account
Args:
params (dict): {
Expand All @@ -68,7 +68,7 @@ def create_jobs_by_trusted_account(self, params):
current_hour
):
try:
self.created_service_account_job(trusted_account_vo, {})
self.create_service_account_job(trusted_account_vo, {})
except Exception as e:
_LOGGER.error(
f"[create_jobs_by_trusted_account] sync error: {e}", exc_info=True
Expand Down Expand Up @@ -326,7 +326,7 @@ def sync_service_accounts(self, params: dict) -> None:
job_vo.workspace_id,
)

def created_service_account_job(
def create_service_account_job(
self, trusted_account_vo: TrustedAccount, job_options: dict
) -> Union[Job, dict]:
resource_group = trusted_account_vo.resource_group
Expand Down Expand Up @@ -385,19 +385,18 @@ def created_service_account_job(
job_vo, ERROR_DUPLICATE_JOB(trusted_account_id=trusted_account_id)
)
else:
self.job_mgr.push_job(
{
"job_id": job_vo.job_id,
"trusted_account_id": trusted_account_id,
"trusted_secret_id": trusted_account_vo.trusted_secret_id,
"secret_data": trusted_secret_data,
"workspace_id": trusted_account_vo.workspace_id,
"domain_id": domain_id,
"options": job_options,
}
)
try:
pass
self.job_mgr.push_job(
{
"job_id": job_vo.job_id,
"trusted_account_id": trusted_account_id,
"trusted_secret_id": trusted_account_vo.trusted_secret_id,
"secret_data": trusted_secret_data,
"workspace_id": trusted_account_vo.workspace_id,
"domain_id": domain_id,
"options": job_options,
}
)
except Exception as e:
self.job_mgr.change_error_status(job_vo, e)

Expand Down
51 changes: 30 additions & 21 deletions src/spaceone/identity/service/service_account_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from spaceone.identity.manager.agent_manager import AgentManager
from spaceone.identity.manager.app_manager import AppManager
from spaceone.identity.manager.client_secret_manager import ClientSecretManager
from spaceone.identity.model import App
from spaceone.identity.model import App, ServiceAccount
from spaceone.identity.model.app.response import AppResponse
from spaceone.identity.model.service_account.request import *
from spaceone.identity.model.service_account.response import *
Expand Down Expand Up @@ -350,26 +350,7 @@ def delete(self, params: ServiceAccountDeleteRequest) -> None:
# Check is managed resource
self.resource_mgr.check_is_managed_resource(service_account_vo)

condition = {
"service_account_id": service_account_id,
"domain_id": domain_id,
"workspace_id": workspace_id,
}
if user_projects:
condition["project_id"] = user_projects

agent_vos = self.agent_mgr.filter_agents(**condition)

if agent_vos:
app_id = agent_vos[0].app_id
app_vo = self.app_mgr.get_app(app_id, domain_id, workspace_id)
app_vo.delete()
agent_vos.delete()

secret_mgr = SecretManager()
secret_mgr.delete_related_secrets(service_account_vo.service_account_id)

self.service_account_mgr.delete_service_account_by_vo(service_account_vo)
self.delete_service_account(service_account_vo)

@transaction(
permission="identity:ServiceAccount.read",
Expand Down Expand Up @@ -488,6 +469,34 @@ def stat(self, params: ServiceAccountStatQueryRequest) -> dict:
query = params.query or {}
return self.service_account_mgr.stat_service_accounts(query)

def delete_service_account(
self, service_account_vo: ServiceAccount, user_projects=None
):
service_account_id = service_account_vo.service_account_id
domain_id = service_account_vo.domain_id
workspace_id = service_account_vo.workspace_id

condition = {
"service_account_id": service_account_id,
"domain_id": domain_id,
"workspace_id": workspace_id,
}
if user_projects:
condition["project_id"] = user_projects

agent_vos = self.agent_mgr.filter_agents(**condition)

if agent_vos:
app_id = agent_vos[0].app_id
app_vo = self.app_mgr.get_app(app_id, domain_id, workspace_id)
app_vo.delete()
agent_vos.delete()

secret_mgr = SecretManager()
secret_mgr.delete_related_secrets(service_account_vo.service_account_id)

self.service_account_mgr.delete_service_account_by_vo(service_account_vo)

def _create_service_account_app_client_secret(
self, app_vo: App, service_account_id: str
) -> Tuple[str, str]:
Expand Down
28 changes: 18 additions & 10 deletions src/spaceone/identity/service/trusted_account_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self, *args, **kwargs):
)
@convert_model
def create(
self, params: TrustedAccountCreateRequest
self, params: TrustedAccountCreateRequest
) -> Union[TrustedAccountResponse, dict]:
"""create trusted account
Expand Down Expand Up @@ -73,7 +73,9 @@ def create(

# Check provider
if params.schedule or params.sync_options or params.plugin_options:
provider_vo = self.provider_mgr.get_provider(params.provider, params.domain_id)
provider_vo = self.provider_mgr.get_provider(
params.provider, params.domain_id
)
self._check_provider_sync(provider_vo)

# Check data by schema
Expand Down Expand Up @@ -118,7 +120,7 @@ def create(
)
@convert_model
def update(
self, params: TrustedAccountUpdateRequest
self, params: TrustedAccountUpdateRequest
) -> Union[TrustedAccountResponse, dict]:
"""update trusted account
Expand Down Expand Up @@ -171,7 +173,7 @@ def update(
)
@convert_model
def update_secret_data(
self, params: TrustedAccountUpdateSecretRequest
self, params: TrustedAccountUpdateSecretRequest
) -> Union[TrustedAccountResponse, dict]:
"""update trusted account secret data
Expand Down Expand Up @@ -273,7 +275,7 @@ def sync(self, params: TrustedAccountSyncRequest) -> Union[JobResponse, dict]:
trusted_account_vo.provider, domain_id
)
self._check_provider_sync(provider_vo)
job_vo = job_service.created_service_account_job(trusted_account_vo, {})
job_vo = job_service.create_service_account_job(trusted_account_vo, {})
return JobResponse(**job_vo.to_dict())

@transaction(
Expand All @@ -283,7 +285,7 @@ def sync(self, params: TrustedAccountSyncRequest) -> Union[JobResponse, dict]:
@change_value_by_rule("APPEND", "workspace_id", "*")
@convert_model
def get(
self, params: TrustedAccountGetRequest
self, params: TrustedAccountGetRequest
) -> Union[TrustedAccountResponse, dict]:
"""get trusted account
Expand Down Expand Up @@ -323,7 +325,7 @@ def get(
@append_keyword_filter(["trusted_account_id", "name"])
@convert_model
def list(
self, params: TrustedAccountSearchQueryRequest
self, params: TrustedAccountSearchQueryRequest
) -> Union[TrustedAccountsResponse, dict]:
"""list trusted accounts
Expand Down Expand Up @@ -388,7 +390,13 @@ def stat(self, params: TrustedAccountStatQueryRequest) -> dict:
@staticmethod
def _check_provider_sync(provider_vo: Provider) -> None:
options = provider_vo.options or {}
if not options.get("support_trusted_account") and options.get("support_auto_sync"):
raise ERROR_INVALID_PARAMETER(key="provider.options", message="Sync options is disabled")
if not options.get("support_trusted_account") and options.get(
"support_auto_sync"
):
raise ERROR_INVALID_PARAMETER(
key="provider.options", message="Sync options is disabled"
)
elif not provider_vo.plugin_info:
raise ERROR_INVALID_PARAMETER(key="provider.plugin_info", message="Plugin info not found")
raise ERROR_INVALID_PARAMETER(
key="provider.plugin_info", message="Plugin info not found"
)
86 changes: 81 additions & 5 deletions src/spaceone/identity/service/workspace_service.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import logging
from typing import Union

from spaceone.core.error import *
from spaceone.core.service import *
from spaceone.core.service.utils import *

from spaceone.identity.manager import SecretManager
from spaceone.identity.manager.domain_manager import DomainManager
from spaceone.identity.manager.project_group_manager import ProjectGroupManager
from spaceone.identity.manager.project_manager import ProjectManager
from spaceone.identity.manager.resource_manager import ResourceManager
from spaceone.identity.manager.service_account_manager import ServiceAccountManager
from spaceone.identity.manager.trusted_account_manager import TrustedAccountManager
from spaceone.identity.manager.workspace_manager import WorkspaceManager
from spaceone.identity.model import Workspace
from spaceone.identity.model.workspace.request import *
from spaceone.identity.model.workspace.response import *

Expand Down Expand Up @@ -79,20 +86,33 @@ def delete(self, params: WorkspaceDeleteRequest) -> None:
"""Delete workspace
Args:
params (WorkspaceDeleteRequest): {
'force': 'bool',
'workspace_id': 'str', # required
'domain_id': 'str' # injected from auth (required)
}
Returns:
None
"""

workspace_vo = self.workspace_mgr.get_workspace(
params.workspace_id, params.domain_id
)
domain_id = params.domain_id
workspace_id = params.workspace_id

workspace_vo = self.workspace_mgr.get_workspace(workspace_id, domain_id)

# Check is managed resource
self.resource_mgr.check_is_managed_resource(workspace_vo)

service_account_vos = self.workspace_mgr.filter_workspaces(
domain_id=domain_id, workspace_id=workspace_id
)

if params.force:
self._delete_related_resources_in_workspace(workspace_vo)
elif service_account_vos.count() > 0:
raise ERROR_EXIST_RESOURCE(key="Service Account", value=workspace_vo.name)
else:
self._delete_related_resources_in_workspace(workspace_vo)

self.workspace_mgr.delete_workspace_by_vo(workspace_vo)

@transaction(permission="identity:Workspace.write", role_types=["DOMAIN_ADMIN"])
Expand Down Expand Up @@ -120,7 +140,7 @@ def enable(self, params: WorkspaceEnableRequest) -> Union[WorkspaceResponse, dic
@transaction(permission="identity:Workspace.write", role_types=["DOMAIN_ADMIN"])
@convert_model
def disable(
self, params: WorkspaceDisableRequest
self, params: WorkspaceDisableRequest
) -> Union[WorkspaceResponse, dict]:
"""Disable workspace
Args:
Expand Down Expand Up @@ -180,7 +200,7 @@ def check(self, params: WorkspaceCheckRequest) -> None:
@append_keyword_filter(["workspace_id", "name"])
@convert_model
def list(
self, params: WorkspaceSearchQueryRequest
self, params: WorkspaceSearchQueryRequest
) -> Union[WorkspacesResponse, dict]:
"""List workspaces
Args:
Expand Down Expand Up @@ -221,3 +241,59 @@ def stat(self, params: WorkspaceStatQueryRequest) -> dict:

query = params.query or {}
return self.workspace_mgr.stat_workspaces(query)

@staticmethod
def _delete_related_resources_in_workspace(workspace_vo: Workspace):
project_group_mgr = ProjectGroupManager()
project_mgr = ProjectManager()
trusted_account_mgr = TrustedAccountManager()
service_account_mgr = ServiceAccountManager()
secret_mgr = SecretManager()

project_group_vos = project_group_mgr.filter_project_groups(
domain_id=workspace_vo.domain_id, workspace_id=workspace_vo.workspace_id
)

project_vos = project_mgr.filter_projects(
domain_id=workspace_vo.domain_id, workspace_id=workspace_vo.workspace_id
)

trusted_account_vos = trusted_account_mgr.filter_trusted_accounts(
domain_id=workspace_vo.domain_id, workspace_id=workspace_vo.workspace_id
)

service_account_vos = service_account_mgr.filter_service_accounts(
domain_id=workspace_vo.domain_id, workspace_id=workspace_vo.workspace_id
)

_LOGGER.debug(
f"[_delete_related_resources_in_workspace] Start delete related resources in workspace: {workspace_vo.domain_id} {workspace_vo.name}( {workspace_vo.workspace_id} )"
)

if project_group_vos:
_LOGGER.debug(
f"[_delete_related_resources_in_workspace] Delete project groups count {workspace_vo.workspace_id} : {project_group_vos.count()}"
)
project_group_vos.delete()

if project_vos:
_LOGGER.debug(
f"[_delete_related_resources_in_workspace] Delete projects count {workspace_vo.workspace_id} : {project_vos.count()}"
)
project_vos.delete()

for service_account_vo in service_account_vos:
secret_mgr.delete_related_secrets(service_account_vo.service_account_id)
_LOGGER.debug(
f"[_delete_related_resources_in_workspace] Delete service account: {service_account_vo.name} ({service_account_vo.service_account_id})"
)
service_account_mgr.delete_service_account_by_vo(service_account_vo)

for trusted_account_vo in trusted_account_vos:
secret_mgr.delete_related_trusted_secrets(
trusted_account_vo.trusted_account_id
)
_LOGGER.debug(
f"[_delete_related_resources_in_workspace] Delete trusted account: {trusted_account_vo.name} ({trusted_account_vo.trusted_account_id})"
)
trusted_account_mgr.delete_trusted_account_by_vo(trusted_account_vo)

0 comments on commit 95d588c

Please sign in to comment.