Implement CLI v2 for openstack configuration
* Add openstack-config commands for fuel2
* Add API facade for openstack configuration
Examples for fuel2:
fuel2 openstack-config list --env 1
fuel2 openstack-config upload --env 1 [--node 1 | --role controller]
--file config.yaml
fuel2 openstack-config download 1 --file config.yaml
fuel2 openstack-config execute --env 1 [--node 1 | --role controller]
Change-Id: I405d9e1f2d35406fe4c163a64b5cb7e2742b461b
Implements: blueprint openstack-config-change
This commit is contained in:
committed by
Sergey Slipushenko
parent
88274ba134
commit
38f75fc6e8
@@ -52,6 +52,7 @@ def get_client(resource, version='v1'):
|
||||
'fuel-version': v1.fuelversion,
|
||||
'network-group': v1.network_group,
|
||||
'node': v1.node,
|
||||
'openstack-config': v1.openstack_config,
|
||||
'plugins': v1.plugins,
|
||||
'task': v1.task,
|
||||
}
|
||||
|
||||
154
fuelclient/commands/openstack_config.py
Normal file
154
fuelclient/commands/openstack_config.py
Normal file
@@ -0,0 +1,154 @@
|
||||
# Copyright 2015 Mirantis, 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.
|
||||
|
||||
from fuelclient.commands import base
|
||||
from fuelclient.common import data_utils
|
||||
|
||||
|
||||
class OpenstackConfigMixin(object):
|
||||
|
||||
entity_name = 'openstack-config'
|
||||
|
||||
@staticmethod
|
||||
def add_env_arg(parser, required=False):
|
||||
parser.add_argument(
|
||||
'-e', '--env',
|
||||
type=int, required=required,
|
||||
help='Environment ID.')
|
||||
|
||||
@staticmethod
|
||||
def add_file_arg(parser):
|
||||
parser.add_argument(
|
||||
'-f', '--file',
|
||||
type=str, help='YAML file that contains openstack configuration.')
|
||||
|
||||
@staticmethod
|
||||
def add_config_id_arg(parser):
|
||||
parser.add_argument(
|
||||
'config',
|
||||
type=int, help='Openstack configuration ID.'
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def add_node_id_arg(parser):
|
||||
parser.add_argument(
|
||||
'-n', '--node',
|
||||
type=int, default=None, help='Node ID.'
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def add_node_role_arg(parser):
|
||||
parser.add_argument(
|
||||
'-r', '--role',
|
||||
type=str, default=None, help='Node role.'
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def add_deleted_arg(parser):
|
||||
parser.add_argument(
|
||||
'-D', '--deleted',
|
||||
type=bool, default=False, help='Show deleted configurations.'
|
||||
)
|
||||
|
||||
|
||||
class OpenstackConfigList(OpenstackConfigMixin, base.BaseCommand):
|
||||
"""List all openstack configurations.
|
||||
"""
|
||||
|
||||
columns = (
|
||||
'id', 'is_active', 'config_type',
|
||||
'cluster_id', 'node_id', 'node_role')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(OpenstackConfigList, self).get_parser(prog_name)
|
||||
|
||||
self.add_env_arg(parser)
|
||||
self.add_node_id_arg(parser)
|
||||
self.add_node_role_arg(parser)
|
||||
self.add_deleted_arg(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, args):
|
||||
data = self.client.get_filtered(
|
||||
cluster_id=args.env, node_id=args.node,
|
||||
node_role=args.role, is_active=(not args.deleted))
|
||||
data = data_utils.get_display_data_multi(self.columns, data)
|
||||
|
||||
return self.columns, data
|
||||
|
||||
|
||||
class OpenstackConfigDownload(OpenstackConfigMixin, base.BaseCommand):
|
||||
"""Download specified configuration file.
|
||||
"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(OpenstackConfigDownload, self).get_parser(prog_name)
|
||||
|
||||
self.add_config_id_arg(parser)
|
||||
self.add_file_arg(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, args):
|
||||
file_path = self.client.download(args.config, args.file)
|
||||
|
||||
msg = ("OpenStack configuration with id={0} "
|
||||
"downloaded to {1}\n").format(args.config, file_path)
|
||||
self.app.stdout.write(msg)
|
||||
|
||||
|
||||
class OpenstackConfigUpload(OpenstackConfigMixin, base.BaseCommand):
|
||||
"""Upload new opesntack configuration from file.
|
||||
"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(OpenstackConfigUpload, self).get_parser(prog_name)
|
||||
|
||||
self.add_env_arg(parser, required=True)
|
||||
self.add_node_id_arg(parser)
|
||||
self.add_node_role_arg(parser)
|
||||
self.add_file_arg(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, args):
|
||||
config = self.client.upload(
|
||||
path=args.file, cluster_id=args.env,
|
||||
node_id=args.node, node_role=args.role)
|
||||
|
||||
msg = "OpenStack configuration with id {0} " \
|
||||
"uploaded from file '{0}'\n".format(config.id, args.file)
|
||||
self.app.stdout.write(msg)
|
||||
|
||||
|
||||
class OpenstackConfigExecute(OpenstackConfigMixin, base.BaseCommand):
|
||||
"""Execute openstack configuration deployment.
|
||||
"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(OpenstackConfigExecute, self).get_parser(prog_name)
|
||||
|
||||
self.add_env_arg(parser, required=True)
|
||||
self.add_node_id_arg(parser)
|
||||
self.add_node_role_arg(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, args):
|
||||
self.client.execute(
|
||||
cluster_id=args.env, node_id=args.node, node_role=args.role)
|
||||
|
||||
msg = "OpenStack configuration execution started.\n"
|
||||
self.app.stdout.write(msg)
|
||||
85
fuelclient/tests/unit/v2/cli/test_openstack_config.py
Normal file
85
fuelclient/tests/unit/v2/cli/test_openstack_config.py
Normal file
@@ -0,0 +1,85 @@
|
||||
# Copyright 2015 Mirantis, 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 fuelclient.tests.unit.v2.cli import test_engine
|
||||
|
||||
|
||||
class TestOpenstackConfig(test_engine.BaseCLITest):
|
||||
|
||||
CLUSTER_ID = 42
|
||||
NODE_ID = 64
|
||||
|
||||
def _test_config_list(self, cmd_line, expected_kwargs):
|
||||
self.m_get_client.reset_mock()
|
||||
self.m_client.get_filtered.reset_mock()
|
||||
self.exec_command('openstack-config list {0}'.format(cmd_line))
|
||||
self.m_get_client.assert_called_once_with('openstack-config',
|
||||
mock.ANY)
|
||||
self.m_client.get_filtered.assert_called_once_with(
|
||||
**expected_kwargs)
|
||||
|
||||
def test_config_list_for_node(self):
|
||||
self._test_config_list(
|
||||
cmd_line='--env {0} --node {1}'.format(self.CLUSTER_ID,
|
||||
self.NODE_ID),
|
||||
expected_kwargs={'cluster_id': self.CLUSTER_ID,
|
||||
'node_id': self.NODE_ID, 'node_role': None,
|
||||
'is_active': True}
|
||||
)
|
||||
|
||||
def test_config_list_for_role(self):
|
||||
self._test_config_list(
|
||||
cmd_line='--env {0} --role compute'.format(self.CLUSTER_ID),
|
||||
expected_kwargs={'cluster_id': self.CLUSTER_ID, 'node_id': None,
|
||||
'node_role': 'compute', 'is_active': True}
|
||||
)
|
||||
|
||||
def test_config_list_for_cluster(self):
|
||||
self._test_config_list(
|
||||
cmd_line='--env {0}'.format(self.CLUSTER_ID),
|
||||
expected_kwargs={'cluster_id': self.CLUSTER_ID, 'node_id': None,
|
||||
'node_role': None, 'is_active': True}
|
||||
)
|
||||
|
||||
def test_config_upload(self):
|
||||
self.m_client.upload.return_value = 'config.yaml'
|
||||
|
||||
cmd = 'openstack-config upload --env {0} --node {1} --file ' \
|
||||
'config.yaml'.format(self.CLUSTER_ID, self.NODE_ID)
|
||||
self.exec_command(cmd)
|
||||
|
||||
self.m_get_client.assert_called_once_with('openstack-config', mock.ANY)
|
||||
self.m_client.upload.assert_called_once_with(
|
||||
path='config.yaml', cluster_id=self.CLUSTER_ID,
|
||||
node_id=self.NODE_ID, node_role=None)
|
||||
|
||||
def test_config_download(self):
|
||||
self.m_client.download.return_value = 'config.yaml'
|
||||
|
||||
cmd = 'openstack-config download 1 --file config.yaml'
|
||||
self.exec_command(cmd)
|
||||
|
||||
self.m_get_client.assert_called_once_with('openstack-config', mock.ANY)
|
||||
self.m_client.download.assert_called_once_with(1, 'config.yaml')
|
||||
|
||||
def test_config_execute(self):
|
||||
cmd = 'openstack-config execute --env {0} --node {1}' \
|
||||
''.format(self.CLUSTER_ID, self.NODE_ID)
|
||||
self.exec_command(cmd)
|
||||
|
||||
self.m_get_client.assert_called_once_with('openstack-config', mock.ANY)
|
||||
self.m_client.execute.assert_called_once_with(
|
||||
cluster_id=self.CLUSTER_ID, node_id=self.NODE_ID, node_role=None)
|
||||
@@ -16,6 +16,7 @@ from fuelclient.v1 import environment
|
||||
from fuelclient.v1 import fuelversion
|
||||
from fuelclient.v1 import network_group
|
||||
from fuelclient.v1 import node
|
||||
from fuelclient.v1 import openstack_config
|
||||
from fuelclient.v1 import task
|
||||
from fuelclient.v1 import plugins
|
||||
|
||||
@@ -24,5 +25,6 @@ __all__ = ('environment',
|
||||
'fuelversion',
|
||||
'network_group',
|
||||
'node',
|
||||
'openstack_config',
|
||||
'plugins',
|
||||
'task',)
|
||||
|
||||
44
fuelclient/v1/openstack_config.py
Normal file
44
fuelclient/v1/openstack_config.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# Copyright 2015 Mirantis, 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.
|
||||
|
||||
from fuelclient import objects
|
||||
from fuelclient.v1 import base_v1
|
||||
|
||||
|
||||
class OpenstackConfigClient(base_v1.BaseV1Client):
|
||||
|
||||
_entity_wrapper = objects.OpenstackConfig
|
||||
|
||||
def upload(self, path, cluster_id, node_id=None, node_role=None):
|
||||
data = self._entity_wrapper.read_file(path)
|
||||
return self._entity_wrapper.create(
|
||||
cluster_id=cluster_id, configuration=data['configuration'],
|
||||
node_id=node_id, node_role=node_role)
|
||||
|
||||
def download(self, config_id, path):
|
||||
config = self._entity_wrapper(config_id)
|
||||
config.write_file(path, {
|
||||
'configuration': config.data['configuration']})
|
||||
|
||||
return path
|
||||
|
||||
def execute(self, **kwargs):
|
||||
return self._entity_wrapper.execute(**kwargs)
|
||||
|
||||
def get_filtered(self, **kwargs):
|
||||
return self._entity_wrapper.get_filtered_data(**kwargs)
|
||||
|
||||
|
||||
def get_client():
|
||||
return OpenstackConfigClient()
|
||||
@@ -59,6 +59,10 @@ fuelclient =
|
||||
plugins_sync=fuelclient.commands.plugins:PluginsSync
|
||||
task_list=fuelclient.commands.task:TaskList
|
||||
task_show=fuelclient.commands.task:TaskShow
|
||||
openstack-config_list=fuelclient.commands.openstack_config:OpenstackConfigList
|
||||
openstack-config_upload=fuelclient.commands.openstack_config:OpenstackConfigUpload
|
||||
openstack-config_download=fuelclient.commands.openstack_config:OpenstackConfigDownload
|
||||
openstack-config_execute=fuelclient.commands.openstack_config:OpenstackConfigExecute
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
|
||||
Reference in New Issue
Block a user