Identity: Migrate 'project' commands to SDK
Change-Id: I0f673658bc02423c18af82fe52ed9f0587763882 Signed-off-by: 0weng <oweng@osuosl.org>
This commit is contained in:
@@ -256,6 +256,37 @@ def find_project(identity_client, name_or_id, domain_name_or_id=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def find_project_id_sdk(
|
||||||
|
identity_client,
|
||||||
|
name_or_id,
|
||||||
|
domain_name_or_id=None,
|
||||||
|
*,
|
||||||
|
validate_actor_existence=True,
|
||||||
|
validate_domain_actor_existence=None,
|
||||||
|
):
|
||||||
|
if domain_name_or_id is None:
|
||||||
|
return _find_sdk_id(
|
||||||
|
identity_client.find_project,
|
||||||
|
name_or_id=name_or_id,
|
||||||
|
validate_actor_existence=validate_actor_existence,
|
||||||
|
)
|
||||||
|
|
||||||
|
if validate_domain_actor_existence is None:
|
||||||
|
validate_domain_actor_existence = validate_actor_existence
|
||||||
|
|
||||||
|
domain_id = find_domain_id_sdk(
|
||||||
|
identity_client,
|
||||||
|
name_or_id=domain_name_or_id,
|
||||||
|
validate_actor_existence=validate_domain_actor_existence,
|
||||||
|
)
|
||||||
|
return _find_sdk_id(
|
||||||
|
identity_client.find_project,
|
||||||
|
name_or_id=name_or_id,
|
||||||
|
validate_actor_existence=validate_actor_existence,
|
||||||
|
domain_id=domain_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def find_user(identity_client, name_or_id, domain_name_or_id=None):
|
def find_user(identity_client, name_or_id, domain_name_or_id=None):
|
||||||
if domain_name_or_id is None:
|
if domain_name_or_id is None:
|
||||||
return _find_identity_resource(
|
return _find_identity_resource(
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from keystoneauth1 import exceptions as ks_exc
|
from openstack import exceptions as sdk_exc
|
||||||
from osc_lib.cli import parseractions
|
from osc_lib.cli import parseractions
|
||||||
from osc_lib import exceptions
|
from osc_lib import exceptions
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
@@ -30,6 +30,21 @@ from openstackclient.identity.v3 import tag
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _format_project(project):
|
||||||
|
# NOTE(0weng): Projects allow unknown attributes in the body, so extract
|
||||||
|
# the column names separately.
|
||||||
|
(column_headers, columns) = utils.get_osc_show_columns_for_sdk_resource(
|
||||||
|
project,
|
||||||
|
{'is_enabled': 'enabled'},
|
||||||
|
['links', 'location', 'parents_as_ids', 'subtree_as_ids'],
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
column_headers,
|
||||||
|
utils.get_item_properties(project, columns),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CreateProject(command.ShowOne):
|
class CreateProject(command.ShowOne):
|
||||||
_description = _("Create new project")
|
_description = _("Create new project")
|
||||||
|
|
||||||
@@ -90,22 +105,13 @@ class CreateProject(command.ShowOne):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
identity_client = self.app.client_manager.identity
|
identity_client = self.app.client_manager.sdk_connection.identity
|
||||||
|
|
||||||
domain = None
|
|
||||||
if parsed_args.domain:
|
|
||||||
domain = common.find_domain(identity_client, parsed_args.domain).id
|
|
||||||
|
|
||||||
parent = None
|
|
||||||
if parsed_args.parent:
|
|
||||||
parent = utils.find_resource(
|
|
||||||
identity_client.projects,
|
|
||||||
parsed_args.parent,
|
|
||||||
).id
|
|
||||||
|
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
|
|
||||||
if parsed_args.properties:
|
if parsed_args.properties:
|
||||||
kwargs = parsed_args.properties.copy()
|
kwargs = parsed_args.properties.copy()
|
||||||
|
|
||||||
if 'is_domain' in kwargs.keys():
|
if 'is_domain' in kwargs.keys():
|
||||||
if kwargs['is_domain'].lower() == "true":
|
if kwargs['is_domain'].lower() == "true":
|
||||||
kwargs['is_domain'] = True
|
kwargs['is_domain'] = True
|
||||||
@@ -114,35 +120,54 @@ class CreateProject(command.ShowOne):
|
|||||||
elif kwargs['is_domain'].lower() == "none":
|
elif kwargs['is_domain'].lower() == "none":
|
||||||
kwargs['is_domain'] = None
|
kwargs['is_domain'] = None
|
||||||
|
|
||||||
kwargs['tags'] = list(set(parsed_args.tags))
|
if parsed_args.description:
|
||||||
|
kwargs['description'] = parsed_args.description
|
||||||
|
|
||||||
|
if parsed_args.name:
|
||||||
|
kwargs['name'] = parsed_args.name
|
||||||
|
|
||||||
|
domain = None
|
||||||
|
if parsed_args.domain:
|
||||||
|
domain = common.find_domain_id_sdk(
|
||||||
|
identity_client, parsed_args.domain
|
||||||
|
)
|
||||||
|
kwargs['domain_id'] = domain
|
||||||
|
|
||||||
|
if parsed_args.parent:
|
||||||
|
kwargs['parent_id'] = common.find_project_id_sdk(
|
||||||
|
identity_client,
|
||||||
|
parsed_args.parent,
|
||||||
|
)
|
||||||
|
|
||||||
|
kwargs['is_enabled'] = parsed_args.enabled
|
||||||
|
|
||||||
|
if parsed_args.tags:
|
||||||
|
kwargs['tags'] = list(set(parsed_args.tags))
|
||||||
|
|
||||||
options = {}
|
|
||||||
if parsed_args.immutable is not None:
|
if parsed_args.immutable is not None:
|
||||||
options['immutable'] = parsed_args.immutable
|
kwargs['options'] = {'immutable': parsed_args.immutable}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
project = identity_client.projects.create(
|
project = identity_client.create_project(
|
||||||
name=parsed_args.name,
|
|
||||||
domain=domain,
|
|
||||||
parent=parent,
|
|
||||||
description=parsed_args.description,
|
|
||||||
enabled=parsed_args.enabled,
|
|
||||||
options=options,
|
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
except ks_exc.Conflict:
|
except sdk_exc.ConflictException:
|
||||||
if parsed_args.or_show:
|
if parsed_args.or_show:
|
||||||
project = utils.find_resource(
|
if parsed_args.domain:
|
||||||
identity_client.projects,
|
project = identity_client.find_project(
|
||||||
parsed_args.name,
|
parsed_args.name,
|
||||||
domain_id=domain,
|
domain_id=domain,
|
||||||
)
|
ignore_missing=False,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
project = identity_client.find_project(
|
||||||
|
parsed_args.name, ignore_missing=False
|
||||||
|
)
|
||||||
LOG.info(_('Returning existing project %s'), project.name)
|
LOG.info(_('Returning existing project %s'), project.name)
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
project._info.pop('links')
|
return _format_project(project)
|
||||||
return zip(*sorted(project._info.items()))
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteProject(command.Command):
|
class DeleteProject(command.Command):
|
||||||
@@ -171,23 +196,19 @@ class DeleteProject(command.Command):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
identity_client = self.app.client_manager.identity
|
identity_client = self.app.client_manager.sdk_connection.identity
|
||||||
|
|
||||||
domain = None
|
|
||||||
if parsed_args.domain:
|
|
||||||
domain = common.find_domain(identity_client, parsed_args.domain)
|
|
||||||
errors = 0
|
errors = 0
|
||||||
for project in parsed_args.projects:
|
for project in parsed_args.projects:
|
||||||
try:
|
try:
|
||||||
if domain is not None:
|
project = common.find_project_id_sdk(
|
||||||
project_obj = utils.find_resource(
|
identity_client,
|
||||||
identity_client.projects, project, domain_id=domain.id
|
project,
|
||||||
)
|
domain_name_or_id=parsed_args.domain,
|
||||||
else:
|
validate_actor_existence=True,
|
||||||
project_obj = utils.find_resource(
|
validate_domain_actor_existence=False,
|
||||||
identity_client.projects, project
|
)
|
||||||
)
|
identity_client.delete_project(project)
|
||||||
identity_client.projects.delete(project_obj.id)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
errors += 1
|
errors += 1
|
||||||
LOG.error(
|
LOG.error(
|
||||||
@@ -268,38 +289,44 @@ class ListProject(command.Lister):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
identity_client = self.app.client_manager.identity
|
identity_client = self.app.client_manager.sdk_connection.identity
|
||||||
columns: tuple[str, ...] = ('ID', 'Name')
|
|
||||||
|
column_headers: tuple[str, ...] = ('ID', 'Name')
|
||||||
if parsed_args.long:
|
if parsed_args.long:
|
||||||
columns += ('Domain ID', 'Description', 'Enabled')
|
column_headers += ('Domain ID', 'Description', 'Enabled')
|
||||||
|
|
||||||
|
columns: tuple[str, ...] = ('id', 'name')
|
||||||
|
if parsed_args.long:
|
||||||
|
columns += ('domain_id', 'description', 'is_enabled')
|
||||||
|
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
|
|
||||||
domain_id = None
|
domain_id = None
|
||||||
if parsed_args.domain:
|
if parsed_args.domain:
|
||||||
domain_id = common.find_domain(
|
domain_id = common.find_domain_id_sdk(
|
||||||
identity_client, parsed_args.domain
|
identity_client, parsed_args.domain
|
||||||
).id
|
)
|
||||||
kwargs['domain'] = domain_id
|
kwargs['domain_id'] = domain_id
|
||||||
|
|
||||||
if parsed_args.parent:
|
if parsed_args.parent:
|
||||||
parent_id = common.find_project(
|
parent_id = common.find_project_id_sdk(
|
||||||
identity_client, parsed_args.parent
|
identity_client, parsed_args.parent
|
||||||
).id
|
)
|
||||||
kwargs['parent'] = parent_id
|
kwargs['parent_id'] = parent_id
|
||||||
|
|
||||||
|
user = None
|
||||||
if parsed_args.user:
|
if parsed_args.user:
|
||||||
if parsed_args.domain:
|
if parsed_args.domain:
|
||||||
user_id = utils.find_resource(
|
user = common.find_user_id_sdk(
|
||||||
identity_client.users,
|
identity_client,
|
||||||
parsed_args.user,
|
parsed_args.user,
|
||||||
domain_id=domain_id,
|
domain_name_or_id=domain_id,
|
||||||
).id
|
)
|
||||||
else:
|
else:
|
||||||
user_id = utils.find_resource(
|
user = common.find_user_id_sdk(
|
||||||
identity_client.users, parsed_args.user
|
identity_client,
|
||||||
).id
|
parsed_args.user,
|
||||||
|
)
|
||||||
kwargs['user'] = user_id
|
|
||||||
|
|
||||||
if parsed_args.is_enabled is not None:
|
if parsed_args.is_enabled is not None:
|
||||||
kwargs['is_enabled'] = parsed_args.is_enabled
|
kwargs['is_enabled'] = parsed_args.is_enabled
|
||||||
@@ -308,32 +335,29 @@ class ListProject(command.Lister):
|
|||||||
|
|
||||||
if parsed_args.my_projects:
|
if parsed_args.my_projects:
|
||||||
# NOTE(adriant): my-projects supersedes all the other filters.
|
# NOTE(adriant): my-projects supersedes all the other filters.
|
||||||
kwargs = {'user': self.app.client_manager.auth_ref.user_id}
|
kwargs = {}
|
||||||
|
user = self.app.client_manager.auth_ref.user_id
|
||||||
|
|
||||||
try:
|
if user:
|
||||||
data = identity_client.projects.list(**kwargs)
|
data = identity_client.user_projects(user, **kwargs)
|
||||||
except ks_exc.Forbidden:
|
else:
|
||||||
# NOTE(adriant): if no filters, assume a forbidden is non-admin
|
try:
|
||||||
# wanting their own project list.
|
data = identity_client.projects(**kwargs)
|
||||||
if not kwargs:
|
except sdk_exc.ForbiddenException:
|
||||||
user = self.app.client_manager.auth_ref.user_id
|
# NOTE(adriant): if no filters, assume a forbidden is non-admin
|
||||||
data = identity_client.projects.list(user=user)
|
# wanting their own project list.
|
||||||
else:
|
if not kwargs:
|
||||||
raise
|
user = self.app.client_manager.auth_ref.user_id
|
||||||
|
data = identity_client.user_projects(user)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
if parsed_args.sort:
|
if parsed_args.sort:
|
||||||
data = utils.sort_items(data, parsed_args.sort)
|
data = utils.sort_items(data, parsed_args.sort)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
columns,
|
column_headers,
|
||||||
(
|
(utils.get_item_properties(s, columns) for s in data),
|
||||||
utils.get_item_properties(
|
|
||||||
s,
|
|
||||||
columns,
|
|
||||||
formatters={},
|
|
||||||
)
|
|
||||||
for s in data
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -392,11 +416,7 @@ class SetProject(command.Command):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
identity_client = self.app.client_manager.identity
|
identity_client = self.app.client_manager.sdk_connection.identity
|
||||||
|
|
||||||
project = common.find_project(
|
|
||||||
identity_client, parsed_args.project, parsed_args.domain
|
|
||||||
)
|
|
||||||
|
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if parsed_args.name:
|
if parsed_args.name:
|
||||||
@@ -409,9 +429,50 @@ class SetProject(command.Command):
|
|||||||
kwargs['options'] = {'immutable': parsed_args.immutable}
|
kwargs['options'] = {'immutable': parsed_args.immutable}
|
||||||
if parsed_args.properties:
|
if parsed_args.properties:
|
||||||
kwargs.update(parsed_args.properties)
|
kwargs.update(parsed_args.properties)
|
||||||
tag.update_tags_in_args(parsed_args, project, kwargs)
|
|
||||||
|
|
||||||
identity_client.projects.update(project.id, **kwargs)
|
if parsed_args.domain:
|
||||||
|
domain = common.find_domain_id_sdk(
|
||||||
|
identity_client,
|
||||||
|
parsed_args.domain,
|
||||||
|
validate_actor_existence=False,
|
||||||
|
)
|
||||||
|
project = identity_client.find_project(
|
||||||
|
parsed_args.project,
|
||||||
|
domain_id=domain,
|
||||||
|
ignore_missing=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
project = identity_client.find_project(
|
||||||
|
parsed_args.project,
|
||||||
|
ignore_missing=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
parsed_args.tags
|
||||||
|
or parsed_args.remove_tags
|
||||||
|
or parsed_args.clear_tags
|
||||||
|
):
|
||||||
|
existing_tags = []
|
||||||
|
if project:
|
||||||
|
existing_tags = project.tags
|
||||||
|
|
||||||
|
if parsed_args.clear_tags:
|
||||||
|
kwargs['tags'] = []
|
||||||
|
else:
|
||||||
|
existing_tags_set = set(existing_tags)
|
||||||
|
if parsed_args.remove_tags:
|
||||||
|
tags = sorted(
|
||||||
|
existing_tags_set - set(parsed_args.remove_tags)
|
||||||
|
)
|
||||||
|
if parsed_args.tags:
|
||||||
|
tags = sorted(
|
||||||
|
existing_tags_set.union(set(parsed_args.tags))
|
||||||
|
)
|
||||||
|
kwargs['tags'] = tags
|
||||||
|
|
||||||
|
project_id = project.id if project else parsed_args.project
|
||||||
|
|
||||||
|
identity_client.update_project(project_id, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ShowProject(command.ShowOne):
|
class ShowProject(command.ShowOne):
|
||||||
@@ -444,31 +505,36 @@ class ShowProject(command.ShowOne):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
identity_client = self.app.client_manager.identity
|
identity_client = self.app.client_manager.sdk_connection.identity
|
||||||
|
|
||||||
project_str = common._get_token_resource(
|
kwargs = {}
|
||||||
identity_client, 'project', parsed_args.project, parsed_args.domain
|
|
||||||
|
domain = None
|
||||||
|
if parsed_args.domain:
|
||||||
|
domain = common.find_domain_id_sdk(
|
||||||
|
identity_client, parsed_args.domain
|
||||||
|
)
|
||||||
|
|
||||||
|
kwargs['domain_id'] = domain
|
||||||
|
|
||||||
|
# Get project id first; otherwise, find_project() can't find
|
||||||
|
# parents/children if only project name was given
|
||||||
|
project = common.find_project_id_sdk(
|
||||||
|
identity_client,
|
||||||
|
parsed_args.project,
|
||||||
|
domain_name_or_id=domain,
|
||||||
|
validate_actor_existence=False,
|
||||||
|
validate_domain_actor_existence=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
if parsed_args.domain:
|
# Include these options as query parameters if they are provided
|
||||||
domain = common.find_domain(identity_client, parsed_args.domain)
|
if parsed_args.parents:
|
||||||
project = utils.find_resource(
|
kwargs['parents_as_ids'] = True
|
||||||
identity_client.projects, project_str, domain_id=domain.id
|
if parsed_args.children:
|
||||||
)
|
kwargs['subtree_as_ids'] = True
|
||||||
else:
|
|
||||||
project = utils.find_resource(
|
|
||||||
identity_client.projects, project_str
|
|
||||||
)
|
|
||||||
|
|
||||||
if parsed_args.parents or parsed_args.children:
|
project = identity_client.find_project(
|
||||||
# NOTE(RuiChen): utils.find_resource() can't pass kwargs,
|
project, **kwargs, ignore_missing=False
|
||||||
# if id query hit the result at first, so call
|
)
|
||||||
# identity manager.get() with kwargs directly.
|
|
||||||
project = identity_client.projects.get(
|
|
||||||
project.id,
|
|
||||||
parents_as_ids=parsed_args.parents,
|
|
||||||
subtree_as_ids=parsed_args.children,
|
|
||||||
)
|
|
||||||
|
|
||||||
project._info.pop('links')
|
return _format_project(project)
|
||||||
return zip(*sorted(project._info.items()))
|
|
||||||
|
|||||||
@@ -123,14 +123,3 @@ def add_tag_option_to_parser_for_set(parser, resource_name):
|
|||||||
)
|
)
|
||||||
% resource_name,
|
% resource_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_tags_in_args(parsed_args, obj, args):
|
|
||||||
if parsed_args.clear_tags:
|
|
||||||
args['tags'] = []
|
|
||||||
obj.tags = []
|
|
||||||
if parsed_args.remove_tags:
|
|
||||||
args['tags'] = sorted(set(obj.tags) - set(parsed_args.remove_tags))
|
|
||||||
return
|
|
||||||
if parsed_args.tags:
|
|
||||||
args['tags'] = sorted(set(obj.tags).union(set(parsed_args.tags)))
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Migrate ``project`` commands from keystoneclient to SDK.
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
Filtering in ``project`` commands is now case sensitive.
|
||||||
Reference in New Issue
Block a user