OSC command for ca-show, ca-sign, ca-roatate and stats-list
Implemented Openstack command for ca-show, ca-sign, ca-rotate and stats-list. Change-Id: Id9c21c3a603266d6bd32fd744cb3167b01473127 Partially-Implements: blueprint deprecate-magnum-client
This commit is contained in:
parent
c165071ff8
commit
ec33c56a23
110
magnumclient/osc/v1/certificates.py
Normal file
110
magnumclient/osc/v1/certificates.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
# Copyright 2015 NEC Corporation. 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.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from magnumclient.i18n import _
|
||||||
|
|
||||||
|
from osc_lib.command import command
|
||||||
|
|
||||||
|
|
||||||
|
def _show_cert(certificate):
|
||||||
|
try:
|
||||||
|
print(certificate.pem)
|
||||||
|
except AttributeError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _get_target_uuid(cs, args):
|
||||||
|
target = None
|
||||||
|
if args.cluster:
|
||||||
|
target = cs.clusters.get(args.cluster)
|
||||||
|
return target.uuid
|
||||||
|
|
||||||
|
|
||||||
|
class RotateCa(command.Command):
|
||||||
|
_description = _("Rotate the CA certificate for cluster to revoke access.")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(RotateCa, self).get_parser(prog_name)
|
||||||
|
parser.add_argument('cluster',
|
||||||
|
metavar='<cluster>',
|
||||||
|
help='ID or name of the cluster')
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
mag_client = self.app.client_manager.container_infra
|
||||||
|
cluster = mag_client.clusters.get(parsed_args.cluster)
|
||||||
|
opts = {
|
||||||
|
'cluster_uuid': cluster.uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
mag_client.certificates.rotate_ca(**opts)
|
||||||
|
|
||||||
|
|
||||||
|
class ShowCa(command.Command):
|
||||||
|
_description = _("Show details about the CA certificate for a cluster.")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(ShowCa, self).get_parser(prog_name)
|
||||||
|
# NOTE: All arguments are positional and, if not provided
|
||||||
|
# with a default, required.
|
||||||
|
parser.add_argument('cluster',
|
||||||
|
metavar='<cluster>',
|
||||||
|
help='ID or name of the cluster')
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug("take_action(%s)", parsed_args)
|
||||||
|
|
||||||
|
mag_client = self.app.client_manager.container_infra
|
||||||
|
cluster = mag_client.clusters.get(parsed_args.cluster)
|
||||||
|
cert = mag_client.certificates.get(cluster.uuid)
|
||||||
|
_show_cert(cert)
|
||||||
|
|
||||||
|
|
||||||
|
class SignCa(command.Command):
|
||||||
|
_description = _("Generate the CA certificate for a cluster.")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(SignCa, self).get_parser(prog_name)
|
||||||
|
# NOTE: All arguments are positional and, if not provided
|
||||||
|
# with a default, required.
|
||||||
|
parser.add_argument('cluster',
|
||||||
|
metavar='<cluster>',
|
||||||
|
help='ID or name of the cluster')
|
||||||
|
parser.add_argument('csr',
|
||||||
|
metavar='<csr>',
|
||||||
|
help='File path of csr file to send to Magnum'
|
||||||
|
' to get signed.')
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug("take_action(%s)", parsed_args)
|
||||||
|
|
||||||
|
mag_client = self.app.client_manager.container_infra
|
||||||
|
|
||||||
|
opts = {
|
||||||
|
'cluster_uuid': _get_target_uuid(mag_client, parsed_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
if parsed_args.csr is None or not os.path.isfile(parsed_args.csr):
|
||||||
|
print('A CSR must be provided.')
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(parsed_args.csr, 'r') as f:
|
||||||
|
opts['csr'] = f.read()
|
||||||
|
|
||||||
|
cert = mag_client.certificates.create(**opts)
|
||||||
|
_show_cert(cert)
|
41
magnumclient/osc/v1/stats.py
Normal file
41
magnumclient/osc/v1/stats.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# Copyright 2015 NEC Corporation. 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 magnumclient.common import cliutils as utils
|
||||||
|
from magnumclient.i18n import _
|
||||||
|
|
||||||
|
from osc_lib.command import command
|
||||||
|
|
||||||
|
|
||||||
|
class ListStats(command.Command):
|
||||||
|
_description = _("Show stats for the given project_id")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(ListStats, self).get_parser(prog_name)
|
||||||
|
parser.add_argument('project_id',
|
||||||
|
metavar='<project>',
|
||||||
|
help='Project ID')
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
mag_client = self.app.client_manager.container_infra
|
||||||
|
opts = {
|
||||||
|
'project_id': parsed_args.project_id
|
||||||
|
}
|
||||||
|
|
||||||
|
stats = mag_client.stats.list(**opts)
|
||||||
|
try:
|
||||||
|
utils.print_dict(stats._info)
|
||||||
|
except AttributeError:
|
||||||
|
return None
|
@ -42,12 +42,22 @@ class FakeBaseModelManager(object):
|
|||||||
def update(self, id, patch):
|
def update(self, id, patch):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def rotate_ca(self, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class FakeStatsModelManager(object):
|
||||||
|
def list(self, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MagnumFakeContainerInfra(object):
|
class MagnumFakeContainerInfra(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.cluster_templates = FakeBaseModelManager()
|
self.cluster_templates = FakeBaseModelManager()
|
||||||
self.clusters = FakeBaseModelManager()
|
self.clusters = FakeBaseModelManager()
|
||||||
self.mservices = FakeBaseModelManager()
|
self.mservices = FakeBaseModelManager()
|
||||||
|
self.certificates = FakeBaseModelManager()
|
||||||
|
self.stats = FakeStatsModelManager()
|
||||||
|
|
||||||
|
|
||||||
class MagnumFakeClientManager(osc_fakes.FakeClientManager):
|
class MagnumFakeClientManager(osc_fakes.FakeClientManager):
|
||||||
@ -204,6 +214,7 @@ class FakeCluster(object):
|
|||||||
'name': 'fake-cluster',
|
'name': 'fake-cluster',
|
||||||
'master_flavor_id': None,
|
'master_flavor_id': None,
|
||||||
'flavor_id': 'm1.medium',
|
'flavor_id': 'm1.medium',
|
||||||
|
'project_id': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Overwrite default attributes.
|
# Overwrite default attributes.
|
||||||
|
141
magnumclient/tests/osc/unit/v1/test_certificates.py
Normal file
141
magnumclient/tests/osc/unit/v1/test_certificates.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# Copyright 2015 NEC Corporation. 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.
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from magnumclient.osc.v1 import certificates as osc_certificates
|
||||||
|
from magnumclient.tests.osc.unit.v1 import fakes as magnum_fakes
|
||||||
|
|
||||||
|
|
||||||
|
class TestCertificate(magnum_fakes.TestMagnumClientOSCV1):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestCertificate, self).setUp()
|
||||||
|
|
||||||
|
self.clusters_mock = self.app.client_manager.container_infra.clusters
|
||||||
|
|
||||||
|
|
||||||
|
class TestRotateCa(TestCertificate):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestRotateCa, self).setUp()
|
||||||
|
|
||||||
|
attr = dict()
|
||||||
|
attr['name'] = 'fake-cluster-1'
|
||||||
|
self._cluster = magnum_fakes.FakeCluster.create_one_cluster(attr)
|
||||||
|
|
||||||
|
self.clusters_mock.get = mock.Mock()
|
||||||
|
self.clusters_mock.get.return_value = self._cluster
|
||||||
|
|
||||||
|
self.cmd = osc_certificates.RotateCa(self.app, None)
|
||||||
|
|
||||||
|
def test_rotate_ca(self):
|
||||||
|
arglist = ['fake-cluster']
|
||||||
|
verifylist = [
|
||||||
|
('cluster', 'fake-cluster')
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.get.assert_called_once_with('fake-cluster')
|
||||||
|
|
||||||
|
def test_rotate_ca_missing_args(self):
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
|
||||||
|
class TestShowCa(TestCertificate):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestShowCa, self).setUp()
|
||||||
|
|
||||||
|
attr = dict()
|
||||||
|
attr['name'] = 'fake-cluster-1'
|
||||||
|
self._cluster = magnum_fakes.FakeCluster.create_one_cluster(attr)
|
||||||
|
|
||||||
|
self.clusters_mock.get = mock.Mock()
|
||||||
|
self.clusters_mock.get.return_value = self._cluster
|
||||||
|
|
||||||
|
self.cmd = osc_certificates.ShowCa(self.app, None)
|
||||||
|
|
||||||
|
def test_show_ca(self):
|
||||||
|
arglist = ['fake-cluster']
|
||||||
|
verifylist = [
|
||||||
|
('cluster', 'fake-cluster')
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.get.assert_called_once_with('fake-cluster')
|
||||||
|
|
||||||
|
def test_show_ca_missing_args(self):
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
|
||||||
|
class TestSignCa(TestCertificate):
|
||||||
|
|
||||||
|
test_csr_path = 'magnumclient/tests/test_csr/test.csr'
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestSignCa, self).setUp()
|
||||||
|
|
||||||
|
attr = dict()
|
||||||
|
attr['name'] = 'fake-cluster-1'
|
||||||
|
self._cluster = magnum_fakes.FakeCluster.create_one_cluster(attr)
|
||||||
|
|
||||||
|
self.clusters_mock.get = mock.Mock()
|
||||||
|
self.clusters_mock.get.return_value = self._cluster
|
||||||
|
|
||||||
|
self.cmd = osc_certificates.SignCa(self.app, None)
|
||||||
|
|
||||||
|
def test_sign_ca(self):
|
||||||
|
arglist = ['fake-cluster', self.test_csr_path]
|
||||||
|
verifylist = [
|
||||||
|
('cluster', 'fake-cluster'),
|
||||||
|
('csr', self.test_csr_path)
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.get.assert_called_once_with('fake-cluster')
|
||||||
|
|
||||||
|
def test_sign_ca_without_csr(self):
|
||||||
|
arglist = ['fake-cluster']
|
||||||
|
verifylist = [
|
||||||
|
('cluster', 'fake-cluster')
|
||||||
|
]
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
def test_sign_ca_without_cluster(self):
|
||||||
|
arglist = [self.test_csr_path]
|
||||||
|
verifylist = [
|
||||||
|
('csr', self.test_csr_path)
|
||||||
|
]
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
def test_show_ca_missing_args(self):
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
72
magnumclient/tests/osc/unit/v1/test_stats.py
Normal file
72
magnumclient/tests/osc/unit/v1/test_stats.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# Copyright 2015 NEC Corporation. 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.
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from magnumclient.osc.v1 import stats as osc_stats
|
||||||
|
from magnumclient.tests.osc.unit.v1 import fakes as magnum_fakes
|
||||||
|
|
||||||
|
|
||||||
|
class TestStats(magnum_fakes.TestMagnumClientOSCV1):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestStats, self).setUp()
|
||||||
|
|
||||||
|
self.clusters_mock = self.app.client_manager.container_infra.stats
|
||||||
|
|
||||||
|
|
||||||
|
class TestStatsList(TestStats):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestStatsList, self).setUp()
|
||||||
|
|
||||||
|
attr = dict()
|
||||||
|
attr['name'] = 'fake-cluster-1'
|
||||||
|
attr['project_id'] = 'abc'
|
||||||
|
attr['node_count'] = 2
|
||||||
|
attr['master_count'] = 1
|
||||||
|
self._cluster = magnum_fakes.FakeCluster.create_one_cluster(attr)
|
||||||
|
|
||||||
|
self.clusters_mock.list = mock.Mock()
|
||||||
|
self.clusters_mock.list.return_value = self._cluster
|
||||||
|
|
||||||
|
self.cmd = osc_stats.ListStats(self.app, None)
|
||||||
|
|
||||||
|
def test_stats_list(self):
|
||||||
|
arglist = ['abc']
|
||||||
|
verifylist = [
|
||||||
|
('project_id', 'abc')
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.list.assert_called_once_with(project_id='abc')
|
||||||
|
|
||||||
|
def test_stats_list_wrong_projectid(self):
|
||||||
|
arglist = ['abcd']
|
||||||
|
verifylist = [
|
||||||
|
('project_id', 'abcd')
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.list.assert_called_once_with(project_id='abcd')
|
||||||
|
|
||||||
|
def test_stats_list_missing_args(self):
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
1
magnumclient/tests/test_csr/test.csr
Normal file
1
magnumclient/tests/test_csr/test.csr
Normal file
@ -0,0 +1 @@
|
|||||||
|
'fake-csr'
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Implemented Openstack command for ca-show, ca-sign,
|
||||||
|
ca-rotate and stats-list.
|
@ -42,6 +42,10 @@ openstack.container_infra.v1 =
|
|||||||
coe_cluster_show = magnumclient.osc.v1.clusters:ShowCluster
|
coe_cluster_show = magnumclient.osc.v1.clusters:ShowCluster
|
||||||
coe_cluster_update = magnumclient.osc.v1.clusters:UpdateCluster
|
coe_cluster_update = magnumclient.osc.v1.clusters:UpdateCluster
|
||||||
coe_cluster_config = magnumclient.osc.v1.clusters:ConfigCluster
|
coe_cluster_config = magnumclient.osc.v1.clusters:ConfigCluster
|
||||||
|
coe_ca_rotate = magnumclient.osc.v1.certificates:RotateCa
|
||||||
|
coe_ca_show = magnumclient.osc.v1.certificates:ShowCa
|
||||||
|
coe_ca_sign = magnumclient.osc.v1.certificates:SignCa
|
||||||
|
coe_stats_list = magnumclient.osc.v1.stats:ListStats
|
||||||
|
|
||||||
coe_service_list = magnumclient.osc.v1.mservices:ListService
|
coe_service_list = magnumclient.osc.v1.mservices:ListService
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user