diff --git a/rdomanager_oscplugin/plugin.py b/rdomanager_oscplugin/plugin.py index cb858f465..0eae953e5 100644 --- a/rdomanager_oscplugin/plugin.py +++ b/rdomanager_oscplugin/plugin.py @@ -19,6 +19,7 @@ import logging from ironicclient import client as ironic_client from openstackclient.common import utils +from tuskarclient import client as tuskar_client LOG = logging.getLogger(__name__) @@ -66,6 +67,7 @@ class ClientWrapper(object): self._instance = instance self._baremetal = None self._orchestration = None + self._management = None def baremetal(self): """Returns an baremetal service client""" @@ -125,3 +127,18 @@ class ClientWrapper(object): self._orchestration = client return self._orchestration + + def management(self): + """Returns an management service client""" + + endpoint = self._instance.get_endpoint_for_service_type( + "management", + region_name=self._instance._region_name, + ) + + token = self._instance.auth.get_token(self._instance.session) + + self._management = tuskar_client.get_client( + 2, os_auth_token=token, tuskar_url=endpoint) + + return self._management diff --git a/rdomanager_oscplugin/tests/v1/overcloud_scale/__init__.py b/rdomanager_oscplugin/tests/v1/overcloud_scale/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/rdomanager_oscplugin/tests/v1/overcloud_scale/fakes.py b/rdomanager_oscplugin/tests/v1/overcloud_scale/fakes.py new file mode 100644 index 000000000..d1dd9d4af --- /dev/null +++ b/rdomanager_oscplugin/tests/v1/overcloud_scale/fakes.py @@ -0,0 +1,48 @@ +# Copyright 2015 Red Hat, Inc. +# +# 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 openstackclient.tests import utils + + +class FakeClientWrapper(object): + + def __init__(self): + self._instance = mock.Mock() + self._orchestration = None + self._management = None + + def orchestration(self): + + if self._orchestration is None: + self._orchestration = mock.Mock() + + return self._orchestration + + def management(self): + + if self._management is None: + self._management = mock.Mock() + + return self._management + + +class TestOvercloudScale(utils.TestCommand): + + def setUp(self): + super(TestOvercloudScale, self).setUp() + + self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN") + self.app.client_manager.rdomanager_oscplugin = FakeClientWrapper() diff --git a/rdomanager_oscplugin/tests/v1/overcloud_scale/test_overcloud_scale.py b/rdomanager_oscplugin/tests/v1/overcloud_scale/test_overcloud_scale.py new file mode 100644 index 000000000..a0634662c --- /dev/null +++ b/rdomanager_oscplugin/tests/v1/overcloud_scale/test_overcloud_scale.py @@ -0,0 +1,40 @@ +# Copyright 2015 Red Hat, Inc. +# +# 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 rdomanager_oscplugin.tests.v1.overcloud_scale import fakes +from rdomanager_oscplugin.v1 import overcloud_scale + + +class TestOvercloudScale(fakes.TestOvercloudScale): + + def setUp(self): + super(TestOvercloudScale, self).setUp() + + # Get the command object to test + self.cmd = overcloud_scale.ScaleOvercloud(self.app, None) + + @mock.patch('tripleo_common.scale.ScaleManager') + def test_scale_out(self, scale_manager): + argslist = ['-r', 'Compute-1', '-n', '2', 'overcloud', 'overcloud'] + verifylist = [ + ('role', 'Compute-1'), + ('num', '2') + ] + parsed_args = self.check_parser(self.cmd, argslist, verifylist) + self.cmd.take_action(parsed_args) + scale_manager.scaleup(parsed_args.role, parsed_args.num) + scale_manager.scaleup.called_once_with('Compute-1', '2') diff --git a/rdomanager_oscplugin/v1/overcloud_scale.py b/rdomanager_oscplugin/v1/overcloud_scale.py new file mode 100644 index 000000000..9423cb072 --- /dev/null +++ b/rdomanager_oscplugin/v1/overcloud_scale.py @@ -0,0 +1,58 @@ +# Copyright 2015 Red Hat, Inc. +# +# 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 logging + +from cliff import command +from openstackclient.common import utils +from tripleo_common import scale + + +class ScaleOvercloud(command.Command): + """Scale overcloud nodes + + Update role's count in tuskar overcloud plan and + trigger overcloud stack-update. Tuskar role is specified + with version, e.g.: + openstack overcloud scale stack overcloud overcloud -r Compute-1 -n 2 + """ + + log = logging.getLogger(__name__ + ".ScaleOvercloud") + + def get_parser(self, prog_name): + parser = super(ScaleOvercloud, self).get_parser(prog_name) + parser.add_argument('-r', '--role', dest='role', required=True) + parser.add_argument('-n', '--num', dest='num', required=True) + parser.add_argument('plan', nargs='?', + help='Name or ID of tuskar plan to scale ' + '(default=Env: OVERCLOUD_PLAN_NAME)', + default=utils.env('OVERCLOUD_PLAN_NAME')) + parser.add_argument('stack', nargs='?', + help='Name or ID of heat stack to scale ' + '(default=Env: OVERCLOUD_STACK_NAME)', + default=utils.env('OVERCLOUD_STACK_NAME')) + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)" % parsed_args) + management = self.app.client_manager.rdomanager_oscplugin.management() + orchestration = (self.app.client_manager.rdomanager_oscplugin. + orchestration()) + scale_manager = scale.ScaleManager( + tuskarclient=management, + heatclient=orchestration, + plan_id=parsed_args.plan, + stack_id=parsed_args.stack) + scale_manager.scaleup(parsed_args.role, parsed_args.num) diff --git a/requirements.txt b/requirements.txt index 91032c2de..b27b92520 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,5 @@ six>=1.9.0 # The ironic-discoverd OSC integration isn't yet on PyPI -e git://github.com/stackforge/ironic-discoverd.git#egg=ironic_discoverd +# tripleo-common lib is not yet on PyPi +-e git://github.com/rdo-management/tripleo-common.git#egg=tripleo_common diff --git a/setup.cfg b/setup.cfg index f5ea32e23..cb0763fb1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -61,4 +61,5 @@ openstack.rdomanager_oscplugin.v1 = overcloud_deploy = rdomanager_oscplugin.v1.overcloud_deploy:DeployPlugin overcloud_image_build = rdomanager_oscplugin.v1.overcloud_image:BuildPlugin overcloud_image_create = rdomanager_oscplugin.v1.overcloud_image:CreateOvercloud + overcloud_scale_stack = rdomanager_oscplugin.v1.overcloud_scale:ScaleOvercloud undercloud_install = rdomanager_oscplugin.v1.undercloud:InstallPlugin