diff --git a/bin/designate b/bin/designate deleted file mode 100755 index de73a36..0000000 --- a/bin/designate +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Managed I.T. -# -# Author: Kiall Mac Innes -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -import sys -from tatuclient.shell import TatuShell - -shell = TatuShell() -sys.exit(shell.run(sys.argv[1:])) diff --git a/setup.cfg b/setup.cfg index 35369a9..eda58d7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -42,18 +42,13 @@ openstack.ssh.v1 = usercert_list = tatuclient.v1.cli.usercert:ListUserCertsCommand usercert_show = tatuclient.v1.cli.usercert:ShowUserCertCommand usercert_revoke = tatuclient.v1.cli.usercert:RevokeUserCertCommand - usercert_delete = tatuclient.v1.cli.usercert:DeleteUserCertCommand - hostcert_create = tatuclient.v1.cli.hostcert:CreateHostCertCommand hostcert_list = tatuclient.v1.cli.hostcert:ListHostCertsCommand hostcert_show = tatuclient.v1.cli.hostcert:ShowHostCertCommand - hostcert_revoke = tatuclient.v1.cli.hostcert:RevokeHostCertCommand - hostcert_delete = tatuclient.v1.cli.hostcert:DeleteHostCertCommand sshca_create = tatuclient.v1.cli.ca:CreateCACommand sshca_list = tatuclient.v1.cli.ca:ListCAsCommand sshca_show = tatuclient.v1.cli.ca:ShowCACommand - sshca_delete = tatuclient.v1.cli.ca:DeleteCACommand [build_sphinx] builders = html,man diff --git a/tatuclient/client.py b/tatuclient/client.py index 6d099d5..300afb5 100644 --- a/tatuclient/client.py +++ b/tatuclient/client.py @@ -87,40 +87,6 @@ class Controller(object): return body -@six.add_metaclass(abc.ABCMeta) -class CrudController(Controller): - - @abc.abstractmethod - def list(self, *args, **kw): - """ - List a resource - """ - - @abc.abstractmethod - def get(self, *args, **kw): - """ - Get a resource - """ - - @abc.abstractmethod - def create(self, *args, **kw): - """ - Create a resource - """ - - @abc.abstractmethod - def update(self, *args, **kw): - """ - Update a resource - """ - - @abc.abstractmethod - def delete(self, *args, **kw): - """ - Delete a resource - """ - - def get_versions(): mgr = extension.ExtensionManager('tatuclient.versions') return dict([(ep.name, ep.plugin) for ep in mgr.extensions]) diff --git a/tatuclient/shell.py b/tatuclient/shell.py index da18d40..8b07483 100644 --- a/tatuclient/shell.py +++ b/tatuclient/shell.py @@ -36,213 +36,4 @@ def env(*vars, **kwargs): value = os.environ.get(v) if value: return value - return kwargs.get('default', '') - - -class TatuShell(App): - CONSOLE_MESSAGE_FORMAT = '%(levelname)s: %(message)s' - DEFAULT_VERBOSE_LEVEL = 0 - - def __init__(self): - super(TatuShell, self).__init__( - description='Tatu Client', - version=version.version_string(), - command_manager=CommandManager('tatuclient.cli'), - ) - - self.log = logging.getLogger(__name__) - - def build_option_parser(self, description, version): - parser = super(TatuShell, self).build_option_parser( - description, version) - - parser.add_argument('--os-username', - default=env('OS_USERNAME'), - help='Name used for authentication with the ' - 'OpenStack Identity service. ' - 'Defaults to env[OS_USERNAME].') - - parser.add_argument('--os-user-id', - default=env('OS_USER_ID'), - help='User ID used for authentication with the ' - 'OpenStack Identity service. ' - 'Defaults to env[OS_USER_ID].') - - parser.add_argument('--os-user-domain-id', - default=env('OS_USER_DOMAIN_ID'), - help='Defaults to env[OS_USER_DOMAIN_ID].') - - parser.add_argument('--os-user-domain-name', - default=env('OS_USER_DOMAIN_NAME'), - help='Defaults to env[OS_USER_DOMAIN_NAME].') - - parser.add_argument('--os-password', - default=env('OS_PASSWORD'), - help='Password used for authentication with the ' - 'OpenStack Identity service. ' - 'Defaults to env[OS_PASSWORD].') - - parser.add_argument('--os-tenant-name', - default=env('OS_TENANT_NAME'), - help='Tenant to request authorization on. ' - 'Defaults to env[OS_TENANT_NAME].') - - parser.add_argument('--os-tenant-id', - default=env('OS_TENANT_ID'), - help='Tenant to request authorization on. ' - 'Defaults to env[OS_TENANT_ID].') - - parser.add_argument('--os-project-name', - default=env('OS_PROJECT_NAME'), - help='Project to request authorization on. ' - 'Defaults to env[OS_PROJECT_NAME].') - - parser.add_argument('--os-domain-name', - default=env('OS_DOMAIN_NAME'), - help='Project to request authorization on. ' - 'Defaults to env[OS_DOMAIN_NAME].') - - parser.add_argument('--os-domain-id', - default=env('OS_DOMAIN_ID'), - help='Defaults to env[OS_DOMAIN_ID].') - - parser.add_argument('--os-project-id', - default=env('OS_PROJECT_ID'), - help='Project to request authorization on. ' - 'Defaults to env[OS_PROJECT_ID].') - - parser.add_argument('--os-project-domain-id', - default=env('OS_PROJECT_DOMAIN_ID'), - help='Defaults to env[OS_PROJECT_DOMAIN_ID].') - - parser.add_argument('--os-project-domain-name', - default=env('OS_PROJECT_DOMAIN_NAME'), - help='Defaults to env[OS_PROJECT_DOMAIN_NAME].') - - parser.add_argument('--os-auth-url', - default=env('OS_AUTH_URL'), - help='Specify the Identity endpoint to use for ' - 'authentication. ' - 'Defaults to env[OS_AUTH_URL].') - - parser.add_argument('--os-region-name', - default=env('OS_REGION_NAME'), - help='Specify the region to use. ' - 'Defaults to env[OS_REGION_NAME].') - - parser.add_argument('--os-token', - default=env('OS_SERVICE_TOKEN'), - help='Specify an existing token to use instead of ' - 'retrieving one via authentication (e.g. ' - 'with username & password). ' - 'Defaults to env[OS_SERVICE_TOKEN].') - - parser.add_argument('--os-endpoint', - default=env('OS_SSH_ENDPOINT', - 'OS_SERVICE_ENDPOINT'), - help='Specify an endpoint to use instead of ' - 'retrieving one from the service catalog ' - '(via authentication). ' - 'Defaults to env[OS_SSH_ENDPOINT].') - - parser.add_argument('--os-endpoint-type', - default=env('OS_ENDPOINT_TYPE', - default='publicURL'), - help='Defaults to env[OS_ENDPOINT_TYPE].') - - parser.add_argument('--os-service-type', - default=env('OS_SSH_SERVICE_TYPE', default='ssh'), - help=("Defaults to env[OS_SSH_SERVICE_TYPE], or " - "'ssh'.")) - - parser.add_argument('--os-cacert', - default=env('OS_CACERT'), - help=('CA certificate bundle file. Defaults to ' - 'env[OS_CACERT].')) - - parser.add_argument('--insecure', action='store_true', - help="Explicitly allow 'insecure' SSL requests.") - - parser.add_argument('--all-tenants', action='store_true', - help="Allows to list all domains from all " - "tenants.") - - return parser - - def configure_logging(self): - """Configure logging for the app - - Cliff sets some defaults we don't want so re-work it a bit - """ - - if self.options.debug: - # --debug forces verbose_level 3 - # Set this here so cliff.app.configure_logging() can work - self.options.verbose_level = 3 - - super(TatuShell, self).configure_logging() - root_logger = logging.getLogger('') - - # Requests logs some stuff at INFO that we don't want - # unless we have DEBUG - requests_log = logging.getLogger("requests") - requests_log.setLevel(logging.ERROR) - - # Other modules we don't want DEBUG output for so - # don't reset them below - iso8601_log = logging.getLogger("iso8601") - iso8601_log.setLevel(logging.ERROR) - - # Set logging to the requested level - self.dump_stack_trace = False - if self.options.verbose_level == 0: - # --quiet - root_logger.setLevel(logging.ERROR) - elif self.options.verbose_level == 1: - # This is the default case, no --debug, --verbose or --quiet - root_logger.setLevel(logging.WARNING) - elif self.options.verbose_level == 2: - # One --verbose - root_logger.setLevel(logging.INFO) - elif self.options.verbose_level >= 3: - # Two or more --verbose - root_logger.setLevel(logging.DEBUG) - requests_log.setLevel(logging.DEBUG) - - if self.options.debug: - # --debug forces traceback - self.dump_stack_trace = True - - def initialize_app(self, argv): - super(TatuShell, self).initialize_app(argv) - self.session = utils.get_session( - auth_url=self.options.os_auth_url, - endpoint=self.options.os_endpoint, - domain_id=self.options.os_domain_id, - domain_name=self.options.os_domain_name, - project_id=self.options.os_project_id or self.options.os_tenant_id, - project_name=(self.options.os_project_name or - self.options.os_tenant_name), - project_domain_name=self.options.os_project_domain_name, - project_domain_id=self.options.os_project_domain_id, - username=self.options.os_username, - user_id=self.options.os_user_id, - password=self.options.os_password, - user_domain_id=self.options.os_user_domain_id, - user_domain_name=self.options.os_user_domain_name, - token=self.options.os_token, - insecure=self.options.insecure, - cacert=self.options.os_cacert - ) - - def run(self, argv): - try: - return super(TatuShell, self).run(argv) - except Exception as e: - if not logging.getLogger('').handlers: - logging.basicConfig() - if self.dump_stack_trace: - self.log.error(traceback.format_exc(e)) - else: - self.log.error('Exception raised: ' + str(e)) - return 1 + return kwargs.get('default', '') \ No newline at end of file diff --git a/tatuclient/utils.py b/tatuclient/utils.py index f4fd5ad..7e177ec 100644 --- a/tatuclient/utils.py +++ b/tatuclient/utils.py @@ -101,15 +101,10 @@ def get_columns(data): return list(columns) -@removals.removed_kwarg('all_tenants', removal_version='1.3.0') -@removals.removed_kwarg('edit_managed', removal_version='1.3.0') def get_session(auth_url, endpoint, domain_id, domain_name, project_id, project_name, project_domain_name, project_domain_id, username, user_id, password, user_domain_id, user_domain_name, token, - insecure, cacert, all_tenants=False, edit_managed=False): - # NOTE: all_tenants and edit_managed are here for backwards compat - # reasons, do not add additional modifiers here. - + insecure, cacert): session = ks_session.Session() # Build + Attach Authentication Plugin @@ -148,11 +143,6 @@ def get_session(auth_url, endpoint, domain_id, domain_name, project_id, else: session.verify = cacert - # NOTE: all_tenants and edit_managed are here for backwards compat - # reasons, do not add additional modifiers here. - session.all_tenants = all_tenants - session.edit_managed = edit_managed - return session diff --git a/tatuclient/v1/cli/ca.py b/tatuclient/v1/cli/ca.py index da1da17..bb518fe 100644 --- a/tatuclient/v1/cli/ca.py +++ b/tatuclient/v1/cli/ca.py @@ -1,24 +1,21 @@ -# Copyright 2014 Hewlett-Packard Development Company, L.P. +# Copyright 2017 Huawei, Inc. All rights reserved. # -# Author: Endre Karlson +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 # -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. import argparse import logging from osc_lib.command import command -import six from tatuclient import utils from tatuclient.v1.cli import common @@ -28,233 +25,52 @@ from tatuclient.v1.utils import get_all LOG = logging.getLogger(__name__) -def _format_recordset(recordset): - # Remove unneeded fields for display output formatting - recordset['records'] = "\n".join(recordset['records']) - recordset.pop('links', None) - return recordset - - -def _has_project_id(data): - if len(data) < 1: - return False - if 'project_id' in data[0]: - return True - return False +_columns = ['auth_id', 'user_pub_key', 'host_pub_key'] +_names = ['Project/CA ID', 'User Public Key', 'Host Public Key'] class ListCACommand(command.Lister): - """List recordsets""" - - columns = ['id', 'name', 'type', 'records', 'status', 'action'] + """List CAs""" def get_parser(self, prog_name): - parser = super(ListRecordSetsCommand, self).get_parser(prog_name) - - parser.add_argument('--name', help="RecordSet Name", required=False) - parser.add_argument('--type', help="RecordSet Type", required=False) - parser.add_argument('--data', help="RecordSet Record Data", - required=False) - parser.add_argument('--ttl', help="Time To Live (Seconds)", - required=False) - parser.add_argument('--description', help="Description", - required=False) - parser.add_argument('--status', help="RecordSet Status", - required=False) - parser.add_argument('--action', help="RecordSet Action", - required=False) - - parser.add_argument('zone_id', help="Zone ID. To list all" - " recordsets specify 'all'") - + parser = super(ListCACommand, self).get_parser(prog_name) common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - - criterion = {} - if parsed_args.type is not None: - criterion["type"] = parsed_args.type - - if parsed_args.name is not None: - criterion["name"] = parsed_args.name - - if parsed_args.data is not None: - criterion["data"] = parsed_args.data - - if parsed_args.ttl is not None: - criterion["ttl"] = parsed_args.ttl - - if parsed_args.description is not None: - criterion["description"] = parsed_args.description - - if parsed_args.status is not None: - criterion["status"] = parsed_args.status - - if parsed_args.action is not None: - criterion["action"] = parsed_args.action - - cols = self.columns - - if parsed_args.zone_id == 'all': - data = get_all(client.recordsets.list_all_zones, - criterion=criterion) - cols.insert(2, 'zone_name') - else: - data = get_all(client.recordsets.list, args=[parsed_args.zone_id], - criterion=criterion) - - if client.session.all_projects and _has_project_id(data): - cols.insert(1, 'project_id') - - for i, rs in enumerate(data): - data[i] = _format_recordset(rs) - - return cols, (utils.get_item_properties(s, cols) for s in data) + data = get_all(client.ca.list) + return _names, (utils.get_item_properties(s, _columns) for s in data) -class ShowRecordSetCommand(command.ShowOne): - """Show recordset details""" +class ShowCACommand(command.ShowOne): + """Show CA details""" def get_parser(self, prog_name): - parser = super(ShowRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - + parser = super(ShowCACommand, self).get_parser(prog_name) + parser.add_argument('auth_id', help="Project/CA ID") common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - data = client.recordsets.get(parsed_args.zone_id, parsed_args.id) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) + data = client.ca.get(parsed_args.auth_id) + return _names, utils.get_item_properties(data, _columns) -class CreateRecordSetCommand(command.ShowOne): - """Create new recordset""" - - log = logging.getLogger('deprecated') +class CreateCACommand(command.ShowOne): + """Create new CA""" def get_parser(self, prog_name): - parser = super(CreateRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('name', help="RecordSet Name") - req_group = parser.add_mutually_exclusive_group(required=True) - req_group.add_argument( - '--records', - help=argparse.SUPPRESS, - nargs='+') - req_group.add_argument( - '--record', - help="RecordSet Record, repeat if necessary", - action='append') - parser.add_argument('--type', help="RecordSet Type", required=True) - parser.add_argument('--ttl', type=int, help="Time To Live (Seconds)") - parser.add_argument('--description', help="Description") - + parser = super(CreateCACommand, self).get_parser(prog_name) + parser.add_argument('auth_id', help="Project/CA ID") common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - - all_records = parsed_args.record or parsed_args.records - if parsed_args.records: - self.log.warning( - "Option --records is deprecated, use --record instead.") - data = client.recordsets.create( - parsed_args.zone_id, - parsed_args.name, - parsed_args.type, - all_records, - description=parsed_args.description, - ttl=parsed_args.ttl) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) - - -class SetRecordSetCommand(command.ShowOne): - """Set recordset properties""" - - def get_parser(self, prog_name): - parser = super(SetRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - parser.add_argument('--records', help="Records", nargs='+') - - description_group = parser.add_mutually_exclusive_group() - description_group.add_argument('--description', help="Description") - description_group.add_argument('--no-description', action='store_true') - - ttl_group = parser.add_mutually_exclusive_group() - ttl_group.add_argument('--ttl', type=int, help="TTL") - ttl_group.add_argument('--no-ttl', action='store_true') - - common.add_all_common_options(parser) - - return parser - - def take_action(self, parsed_args): - data = {} - - if parsed_args.no_description: - data['description'] = None - elif parsed_args.description: - data['description'] = parsed_args.description - - if parsed_args.no_ttl: - data['ttl'] = None - elif parsed_args.ttl: - data['ttl'] = parsed_args.ttl - - if parsed_args.records: - data['records'] = parsed_args.records - - client = self.app.client_manager.ssh - common.set_all_common_headers(client, parsed_args) - - updated = client.recordsets.update( - parsed_args.zone_id, - parsed_args.id, - data) - - _format_recordset(updated) - - return six.moves.zip(*sorted(six.iteritems(updated))) - - -class DeleteRecordSetCommand(command.ShowOne): - """Delete recordset""" - - def get_parser(self, prog_name): - parser = super(DeleteRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - - common.add_all_common_options(parser) - - return parser - - def take_action(self, parsed_args): - client = self.app.client_manager.ssh - common.set_all_common_headers(client, parsed_args) - data = client.recordsets.delete(parsed_args.zone_id, parsed_args.id) - - LOG.info('RecordSet %s was deleted', parsed_args.id) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) + data = client.ca.create(parsed_args.auth_id) + return _names, utils.get_item_properties(data, _columns) diff --git a/tatuclient/v1/cli/hostcert.py b/tatuclient/v1/cli/hostcert.py index 5813314..7428a80 100644 --- a/tatuclient/v1/cli/hostcert.py +++ b/tatuclient/v1/cli/hostcert.py @@ -1,24 +1,21 @@ -# Copyright 2014 Hewlett-Packard Development Company, L.P. +# Copyright 2017 Huawei, Inc. All rights reserved. # -# Author: Endre Karlson +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 # -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. import argparse import logging from osc_lib.command import command -import six from tatuclient import utils from tatuclient.v1.cli import common @@ -26,235 +23,53 @@ from tatuclient.v1.utils import get_all LOG = logging.getLogger(__name__) +'host_id': host.host_id, +'fingerprint': host.fingerprint, +'auth_id': host.auth_id, +'cert': host.cert, +item = { + 'host_id': host.host_id, + 'fingerprint': host.fingerprint, + 'auth_id': host.auth_id, + 'cert': host.cert, + 'hostname': host.hostname, +} +if CONF.tatu.use_pat_bastions: + item['pat_bastions'] = ','.join( + '{}:{}'.format(t[1], t[0]) for t in + get_port_ip_tuples(host.host_id, 22)) + item['srv_url'] = get_srv_url(host.hostname, host.auth_id) + +_columns = ['host_id', 'srv_url', 'pat_bastions', 'fingerprint', 'cert'] +_names = ['Instance ID', 'SRV URL', 'PAT Bastions', 'Fingerprint', 'SSH Certificate'] -def _format_recordset(recordset): - # Remove unneeded fields for display output formatting - recordset['records'] = "\n".join(recordset['records']) - recordset.pop('links', None) - return recordset - - -def _has_project_id(data): - if len(data) < 1: - return False - if 'project_id' in data[0]: - return True - return False - - -class ListRecordSetsCommand(command.Lister): - """List recordsets""" - - columns = ['id', 'name', 'type', 'records', 'status', 'action'] +class ListHostCertCommand(command.Lister): + """List HostCerts""" def get_parser(self, prog_name): - parser = super(ListRecordSetsCommand, self).get_parser(prog_name) - - parser.add_argument('--name', help="RecordSet Name", required=False) - parser.add_argument('--type', help="RecordSet Type", required=False) - parser.add_argument('--data', help="RecordSet Record Data", - required=False) - parser.add_argument('--ttl', help="Time To Live (Seconds)", - required=False) - parser.add_argument('--description', help="Description", - required=False) - parser.add_argument('--status', help="RecordSet Status", - required=False) - parser.add_argument('--action', help="RecordSet Action", - required=False) - - parser.add_argument('zone_id', help="Zone ID. To list all" - " recordsets specify 'all'") - + parser = super(ListHostCertCommand, self).get_parser(prog_name) common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - - criterion = {} - if parsed_args.type is not None: - criterion["type"] = parsed_args.type - - if parsed_args.name is not None: - criterion["name"] = parsed_args.name - - if parsed_args.data is not None: - criterion["data"] = parsed_args.data - - if parsed_args.ttl is not None: - criterion["ttl"] = parsed_args.ttl - - if parsed_args.description is not None: - criterion["description"] = parsed_args.description - - if parsed_args.status is not None: - criterion["status"] = parsed_args.status - - if parsed_args.action is not None: - criterion["action"] = parsed_args.action - - cols = self.columns - - if parsed_args.zone_id == 'all': - data = get_all(client.recordsets.list_all_zones, - criterion=criterion) - cols.insert(2, 'zone_name') - else: - data = get_all(client.recordsets.list, args=[parsed_args.zone_id], - criterion=criterion) - - if client.session.all_projects and _has_project_id(data): - cols.insert(1, 'project_id') - - for i, rs in enumerate(data): - data[i] = _format_recordset(rs) - - return cols, (utils.get_item_properties(s, cols) for s in data) + data = get_all(client.hostcert.list) + return _names, (utils.get_item_properties(s, _columns) for s in data) -class ShowRecordSetCommand(command.ShowOne): - """Show recordset details""" +class ShowHostCertCommand(command.ShowOne): + """Show HostCert details""" def get_parser(self, prog_name): - parser = super(ShowRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - + parser = super(ShowHostCertCommand, self).get_parser(prog_name) + parser.add_argument('serial', help="Serial Number") common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - data = client.recordsets.get(parsed_args.zone_id, parsed_args.id) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) - - -class CreateRecordSetCommand(command.ShowOne): - """Create new recordset""" - - log = logging.getLogger('deprecated') - - def get_parser(self, prog_name): - parser = super(CreateRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('name', help="RecordSet Name") - req_group = parser.add_mutually_exclusive_group(required=True) - req_group.add_argument( - '--records', - help=argparse.SUPPRESS, - nargs='+') - req_group.add_argument( - '--record', - help="RecordSet Record, repeat if necessary", - action='append') - parser.add_argument('--type', help="RecordSet Type", required=True) - parser.add_argument('--ttl', type=int, help="Time To Live (Seconds)") - parser.add_argument('--description', help="Description") - - common.add_all_common_options(parser) - - return parser - - def take_action(self, parsed_args): - client = self.app.client_manager.ssh - common.set_all_common_headers(client, parsed_args) - - all_records = parsed_args.record or parsed_args.records - if parsed_args.records: - self.log.warning( - "Option --records is deprecated, use --record instead.") - data = client.recordsets.create( - parsed_args.zone_id, - parsed_args.name, - parsed_args.type, - all_records, - description=parsed_args.description, - ttl=parsed_args.ttl) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) - - -class SetRecordSetCommand(command.ShowOne): - """Set recordset properties""" - - def get_parser(self, prog_name): - parser = super(SetRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - parser.add_argument('--records', help="Records", nargs='+') - - description_group = parser.add_mutually_exclusive_group() - description_group.add_argument('--description', help="Description") - description_group.add_argument('--no-description', action='store_true') - - ttl_group = parser.add_mutually_exclusive_group() - ttl_group.add_argument('--ttl', type=int, help="TTL") - ttl_group.add_argument('--no-ttl', action='store_true') - - common.add_all_common_options(parser) - - return parser - - def take_action(self, parsed_args): - data = {} - - if parsed_args.no_description: - data['description'] = None - elif parsed_args.description: - data['description'] = parsed_args.description - - if parsed_args.no_ttl: - data['ttl'] = None - elif parsed_args.ttl: - data['ttl'] = parsed_args.ttl - - if parsed_args.records: - data['records'] = parsed_args.records - - client = self.app.client_manager.ssh - common.set_all_common_headers(client, parsed_args) - - updated = client.recordsets.update( - parsed_args.zone_id, - parsed_args.id, - data) - - _format_recordset(updated) - - return six.moves.zip(*sorted(six.iteritems(updated))) - - -class DeleteRecordSetCommand(command.ShowOne): - """Delete recordset""" - - def get_parser(self, prog_name): - parser = super(DeleteRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - - common.add_all_common_options(parser) - - return parser - - def take_action(self, parsed_args): - client = self.app.client_manager.ssh - common.set_all_common_headers(client, parsed_args) - data = client.recordsets.delete(parsed_args.zone_id, parsed_args.id) - - LOG.info('RecordSet %s was deleted', parsed_args.id) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) + data = client.hostcert.get(parsed_args.serial) + return _names, utils.get_item_properties(data, _columns) diff --git a/tatuclient/v1/cli/usercert.py b/tatuclient/v1/cli/usercert.py index 5813314..161e53e 100644 --- a/tatuclient/v1/cli/usercert.py +++ b/tatuclient/v1/cli/usercert.py @@ -1,24 +1,21 @@ -# Copyright 2014 Hewlett-Packard Development Company, L.P. +# Copyright 2017 Huawei, Inc. All rights reserved. # -# Author: Endre Karlson +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 # -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. import argparse import logging from osc_lib.command import command -import six from tatuclient import utils from tatuclient.v1.cli import common @@ -27,234 +24,70 @@ from tatuclient.v1.utils import get_all LOG = logging.getLogger(__name__) - -def _format_recordset(recordset): - # Remove unneeded fields for display output formatting - recordset['records'] = "\n".join(recordset['records']) - recordset.pop('links', None) - return recordset +_columns = ['serial', 'revoked', 'user_id', 'auth_id', 'fingerprint', 'cert'] +_names = ['Serial Number', 'Revoked', 'User ID', 'Project/CA ID', 'Fingerprint', 'SSH Certificate'] -def _has_project_id(data): - if len(data) < 1: - return False - if 'project_id' in data[0]: - return True - return False - - -class ListRecordSetsCommand(command.Lister): - """List recordsets""" - - columns = ['id', 'name', 'type', 'records', 'status', 'action'] +class ListUserCertCommand(command.Lister): + """List UserCerts""" def get_parser(self, prog_name): - parser = super(ListRecordSetsCommand, self).get_parser(prog_name) - - parser.add_argument('--name', help="RecordSet Name", required=False) - parser.add_argument('--type', help="RecordSet Type", required=False) - parser.add_argument('--data', help="RecordSet Record Data", - required=False) - parser.add_argument('--ttl', help="Time To Live (Seconds)", - required=False) - parser.add_argument('--description', help="Description", - required=False) - parser.add_argument('--status', help="RecordSet Status", - required=False) - parser.add_argument('--action', help="RecordSet Action", - required=False) - - parser.add_argument('zone_id', help="Zone ID. To list all" - " recordsets specify 'all'") - + parser = super(ListUserCertCommand, self).get_parser(prog_name) common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - - criterion = {} - if parsed_args.type is not None: - criterion["type"] = parsed_args.type - - if parsed_args.name is not None: - criterion["name"] = parsed_args.name - - if parsed_args.data is not None: - criterion["data"] = parsed_args.data - - if parsed_args.ttl is not None: - criterion["ttl"] = parsed_args.ttl - - if parsed_args.description is not None: - criterion["description"] = parsed_args.description - - if parsed_args.status is not None: - criterion["status"] = parsed_args.status - - if parsed_args.action is not None: - criterion["action"] = parsed_args.action - - cols = self.columns - - if parsed_args.zone_id == 'all': - data = get_all(client.recordsets.list_all_zones, - criterion=criterion) - cols.insert(2, 'zone_name') - else: - data = get_all(client.recordsets.list, args=[parsed_args.zone_id], - criterion=criterion) - - if client.session.all_projects and _has_project_id(data): - cols.insert(1, 'project_id') - - for i, rs in enumerate(data): - data[i] = _format_recordset(rs) - - return cols, (utils.get_item_properties(s, cols) for s in data) + data = get_all(client.usercert.list) + return _names, (utils.get_item_properties(s, _columns) for s in data) -class ShowRecordSetCommand(command.ShowOne): - """Show recordset details""" +class ShowUserCertCommand(command.ShowOne): + """Show UserCert details""" def get_parser(self, prog_name): - parser = super(ShowRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - + parser = super(ShowUserCertCommand, self).get_parser(prog_name) + parser.add_argument('serial', help="Serial Number") common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - data = client.recordsets.get(parsed_args.zone_id, parsed_args.id) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) + data = client.usercert.get(parsed_args.serial) + return _names, utils.get_item_properties(data, _columns) -class CreateRecordSetCommand(command.ShowOne): - """Create new recordset""" - - log = logging.getLogger('deprecated') +class CreateUserCertCommand(command.ShowOne): + """Create new UserCert""" def get_parser(self, prog_name): - parser = super(CreateRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('name', help="RecordSet Name") - req_group = parser.add_mutually_exclusive_group(required=True) - req_group.add_argument( - '--records', - help=argparse.SUPPRESS, - nargs='+') - req_group.add_argument( - '--record', - help="RecordSet Record, repeat if necessary", - action='append') - parser.add_argument('--type', help="RecordSet Type", required=True) - parser.add_argument('--ttl', type=int, help="Time To Live (Seconds)") - parser.add_argument('--description', help="Description") - + parser = super(CreateUserCertCommand, self).get_parser(prog_name) + parser.add_argument('user_id', help="User ID") + parser.add_argument('auth_id', help="Project/CA ID") + parser.add_argument('pub_key', help="Public Key") common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - - all_records = parsed_args.record or parsed_args.records - if parsed_args.records: - self.log.warning( - "Option --records is deprecated, use --record instead.") - data = client.recordsets.create( - parsed_args.zone_id, - parsed_args.name, - parsed_args.type, - all_records, - description=parsed_args.description, - ttl=parsed_args.ttl) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) + data = client.usercert.create(parsed_args) + return _names, utils.get_item_properties(data, _columns) -class SetRecordSetCommand(command.ShowOne): - """Set recordset properties""" +class RevokeUserCertCommand(command.ShowOne): + """Create new UserCert""" def get_parser(self, prog_name): - parser = super(SetRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - parser.add_argument('--records', help="Records", nargs='+') - - description_group = parser.add_mutually_exclusive_group() - description_group.add_argument('--description', help="Description") - description_group.add_argument('--no-description', action='store_true') - - ttl_group = parser.add_mutually_exclusive_group() - ttl_group.add_argument('--ttl', type=int, help="TTL") - ttl_group.add_argument('--no-ttl', action='store_true') - + parser = super(RevokeUserCertCommand, self).get_parser(prog_name) + parser.add_argument('serial', help="Serial Number") common.add_all_common_options(parser) - - return parser - - def take_action(self, parsed_args): - data = {} - - if parsed_args.no_description: - data['description'] = None - elif parsed_args.description: - data['description'] = parsed_args.description - - if parsed_args.no_ttl: - data['ttl'] = None - elif parsed_args.ttl: - data['ttl'] = parsed_args.ttl - - if parsed_args.records: - data['records'] = parsed_args.records - - client = self.app.client_manager.ssh - common.set_all_common_headers(client, parsed_args) - - updated = client.recordsets.update( - parsed_args.zone_id, - parsed_args.id, - data) - - _format_recordset(updated) - - return six.moves.zip(*sorted(six.iteritems(updated))) - - -class DeleteRecordSetCommand(command.ShowOne): - """Delete recordset""" - - def get_parser(self, prog_name): - parser = super(DeleteRecordSetCommand, self).get_parser(prog_name) - - parser.add_argument('zone_id', help="Zone ID") - parser.add_argument('id', help="RecordSet ID") - - common.add_all_common_options(parser) - return parser def take_action(self, parsed_args): client = self.app.client_manager.ssh common.set_all_common_headers(client, parsed_args) - data = client.recordsets.delete(parsed_args.zone_id, parsed_args.id) - - LOG.info('RecordSet %s was deleted', parsed_args.id) - - _format_recordset(data) - return six.moves.zip(*sorted(six.iteritems(data))) + data = client.usercert.create(parsed_args.serial) + return _names, utils.get_item_properties(data, _columns) diff --git a/tatuclient/v1/client.py b/tatuclient/v1/client.py index 8a0963c..60921e1 100644 --- a/tatuclient/v1/client.py +++ b/tatuclient/v1/client.py @@ -34,7 +34,6 @@ class TatuAdapter(adapter.LegacyJsonAdapter): def __init__(self, *args, **kwargs): self.timeout = kwargs.pop('timeout', None) self.all_projects = kwargs.pop('all_projects', False) - self.edit_managed = kwargs.pop('edit_managed', False) self.sudo_project_id = kwargs.pop('sudo_project_id', None) super(self.__class__, self).__init__(*args, **kwargs) @@ -109,5 +108,5 @@ class Client(object): ) self.ca = CAController(self) - self.hostcert = HostCeretController(self) + self.hostcert = HostCertController(self) self.usercert = UserCertController(self)