From 862a6c8801f69fe58f84d58f508393a43104a802 Mon Sep 17 00:00:00 2001 From: liusheng Date: Tue, 18 Apr 2017 20:36:11 +0800 Subject: [PATCH] Add keypair support Change-Id: Iee1ddab7c5f2f21b453b69668554d8c1119d682d --- moganclient/osc/v1/keypair.py | 178 ++++++++++++++++++++++++++++++++++ moganclient/v1/client.py | 2 + moganclient/v1/keypair.py | 49 ++++++++++ setup.cfg | 4 + 4 files changed, 233 insertions(+) create mode 100644 moganclient/osc/v1/keypair.py create mode 100644 moganclient/v1/keypair.py diff --git a/moganclient/osc/v1/keypair.py b/moganclient/osc/v1/keypair.py new file mode 100644 index 0000000..7bb7abe --- /dev/null +++ b/moganclient/osc/v1/keypair.py @@ -0,0 +1,178 @@ +# Copyright 2016 Huawei, Inc. All rights reserved. +# +# 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. +# + + +"""Mogan v1 Baremetal keypair action implementations""" + +import copy +import logging +import os +import sys + +from osc_lib.command import command +from osc_lib import exceptions +from osc_lib import utils + +from moganclient.common.i18n import _ + +LOG = logging.getLogger(__name__) + + +class CreateKeyPair(command.ShowOne): + """Create new public or private key for baremetal server ssh access""" + + def get_parser(self, prog_name): + parser = super(CreateKeyPair, self).get_parser(prog_name) + parser.add_argument( + "name", + metavar="", + help=_("Name of key") + ) + parser.add_argument( + "--user", + metavar="", + help=_("ID of user to whom to add key-pair (Admin only)") + ) + parser.add_argument( + "--key-type", + metavar="", + help=_("Keypair type. Can be ssh or x509.") + ) + parser.add_argument( + "--public-key", + metavar="", + help=_("Filename for public key to add. If not used, " + "creates a private key.") + ) + return parser + + def take_action(self, parsed_args): + bc_client = self.app.client_manager.baremetal_compute + pub_key = parsed_args.public_key + if pub_key: + if pub_key == '-': + pub_key = sys.stdin.read() + else: + try: + with open(os.path.expanduser(pub_key)) as f: + pub_key = f.read() + except IOError as e: + raise exceptions.CommandError( + _("Can't open or read '%(key)s': %(exc)s") + % {'key': pub_key, 'exc': e} + ) + + data = bc_client.keypair.create(parsed_args.name, parsed_args.user, + pub_key, parsed_args.key_type) + info = copy.copy(data._info) + if not pub_key: + private_key = info.pop('private_key') + print(private_key) + return zip(*sorted(info.items())) + + +class DeleteKeyPair(command.Command): + """Delete baremetal server public or private key(s)""" + + def get_parser(self, prog_name): + parser = super(DeleteKeyPair, self).get_parser(prog_name) + parser.add_argument( + 'key', + metavar='', + nargs='+', + help=_("Name of key(s) to delete (name only)") + ) + parser.add_argument( + "--user", + metavar="", + help=_("ID of user to whom to add key-pair (Admin only)") + ) + return parser + + def take_action(self, parsed_args): + bc_client = self.app.client_manager.baremetal_compute + result = 0 + for one_key in parsed_args.key: + try: + bc_client.keypair.delete(one_key, parsed_args.user) + except Exception as e: + result += 1 + LOG.error(_("Failed to delete keypair with name " + "'%(key)s': %(e)s") % + {'key': one_key, 'e': e}) + + if result > 0: + total = len(parsed_args.key) + msg = (_("%(result)s of %(total)s keypairs failed " + "to delete.") % {'result': result, 'total': total}) + raise exceptions.CommandError(msg) + + +class ListKeyPair(command.Lister): + """List baremetal server key fingerprints""" + def get_parser(self, prog_name): + parser = super(ListKeyPair, self).get_parser(prog_name) + parser.add_argument( + "--user", + metavar="", + help=_("ID of user to whom to add key-pair (Admin only)") + ) + return parser + + def take_action(self, parsed_args): + bc_client = self.app.client_manager.baremetal_compute + + data = bc_client.keypair.list(parsed_args.user) + + column_headers = ( + "Name", + "Type", + "Fingerprint", + ) + columns = ( + "Name", + "Type", + "Fingerprint", + ) + + return (column_headers, + (utils.get_item_properties( + s, columns, + ) for s in data)) + + +class ShowKeyPair(command.ShowOne): + """Display baremetal server key details""" + + def get_parser(self, prog_name): + parser = super(ShowKeyPair, self).get_parser(prog_name) + parser.add_argument( + 'keypair', + metavar='', + help=_("Keypair to display (name only)") + ) + parser.add_argument( + "--user", + metavar="", + help=_("ID of user to whom to add key-pair (Admin only)") + ) + return parser + + def take_action(self, parsed_args): + bc_client = self.app.client_manager.baremetal_compute + data = bc_client.keypair.get(parsed_args.keypair, parsed_args.user) + info = {} + info.update(data._info) + return zip(*sorted(info.items())) diff --git a/moganclient/v1/client.py b/moganclient/v1/client.py index 5ba8865..c142bd1 100644 --- a/moganclient/v1/client.py +++ b/moganclient/v1/client.py @@ -16,6 +16,7 @@ from moganclient.common import http from moganclient.v1 import availability_zone from moganclient.v1 import flavor +from moganclient.v1 import keypair from moganclient.v1 import server @@ -31,3 +32,4 @@ class Client(object): self.server = server.ServerManager(self.http_client) self.availability_zone = availability_zone.AvailabilityZoneManager( self.http_client) + self.keypair = keypair.KeyPairManager(self.http_client) diff --git a/moganclient/v1/keypair.py b/moganclient/v1/keypair.py new file mode 100644 index 0000000..7239237 --- /dev/null +++ b/moganclient/v1/keypair.py @@ -0,0 +1,49 @@ +# Copyright 2016 Huawei, Inc. All rights reserved. +# +# 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. +# + +from moganclient.common import base + + +class KeyPair(base.Resource): + pass + + +class KeyPairManager(base.ManagerWithFind): + resource_class = KeyPair + + def create(self, name, user_id=None, public_key=None, keypair_type=None): + url = '/keypairs' + data = {'name': name} + if user_id: + data['user_id'] = user_id + if public_key: + data['public_key'] = public_key + if keypair_type: + data['type'] = keypair_type + return self._create(url, data=data) + + def delete(self, name, user_id=None): + url = '/keypairs/%s' % name + url = url + '?user_id=%s' % user_id if user_id else url + return self._delete(url) + + def get(self, name, user_id=None): + url = '/keypairs/%s' % name + url = url + '?user_id=%s' % user_id if user_id else url + return self._get(url) + + def list(self, user_id=None): + url = '/keypairs' if not user_id else '/keypairs?user_id=%s' % user_id + return self._list(url, response_key='keypairs') diff --git a/setup.cfg b/setup.cfg index 8990968..d2fa163 100644 --- a/setup.cfg +++ b/setup.cfg @@ -49,6 +49,10 @@ openstack.baremetal_compute.v1 = baremetal_server_unlock = moganclient.osc.v1.server:UnLockServer baremetal_server_netinfo = moganclient.osc.v1.server:ShowServerNetworkInfo baremetal_availability_zone_list = moganclient.osc.v1.availability_zone:ListAvailabilityZone + baremetal_keypair_create = moganclient.osc.v1.keypair:CreateKeyPair + baremetal_keypair_show = moganclient.osc.v1.keypair:ShowKeyPair + baremetal_keypair_list = moganclient.osc.v1.keypair:ListKeyPair + baremetal_keypair_delete = moganclient.osc.v1.keypair:DeleteKeyPair [build_sphinx]