diff --git a/magnumclient/common/utils.py b/magnumclient/common/utils.py index 34171315..d22ddaf8 100644 --- a/magnumclient/common/utils.py +++ b/magnumclient/common/utils.py @@ -107,3 +107,7 @@ def format_labels(lbls, parse_comma=True): labels[k].append(v) return labels + + +def print_list_field(field): + return lambda obj: ', '.join(getattr(obj, field)) diff --git a/magnumclient/shell.py b/magnumclient/shell.py index 6bd70819..7da226c0 100644 --- a/magnumclient/shell.py +++ b/magnumclient/shell.py @@ -52,7 +52,7 @@ except ImportError: from magnumclient.openstack.common.apiclient import auth from magnumclient.openstack.common.apiclient import exceptions as exc from magnumclient.openstack.common import cliutils -from magnumclient.v1 import client +from magnumclient.v1 import client as client_v1 from magnumclient.v1 import shell as shell_v1 from magnumclient import version @@ -335,13 +335,14 @@ class OpenStackMagnumShell(object): subparsers = parser.add_subparsers(metavar='') try: - actions_module = { - '1': shell_v1, + actions_modules = { + '1': shell_v1.COMMAND_MODULES, }[version] except KeyError: - actions_module = shell_v1 + actions_modules = shell_v1.COMMAND_MODULES - self._find_actions(subparsers, actions_module) + for actions_module in actions_modules: + self._find_actions(subparsers, actions_module) self._find_actions(subparsers, self) self._add_bash_completion_subparser(subparsers) @@ -508,6 +509,13 @@ class OpenStackMagnumShell(object): '--os-password, env[OS_PASSWORD], or ' 'prompted response') + try: + client = { + '1': client_v1, + }[options.magnum_api_version] + except KeyError: + client = client_v1 + self.cs = client.Client(username=os_username, api_key=os_password, project_id=os_tenant_id, diff --git a/magnumclient/tests/v1/shell_test_base.py b/magnumclient/tests/v1/shell_test_base.py new file mode 100644 index 00000000..ad29ae8f --- /dev/null +++ b/magnumclient/tests/v1/shell_test_base.py @@ -0,0 +1,71 @@ +# 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 re + +import mock +from testtools import matchers + +from magnumclient.tests import utils + +FAKE_ENV = {'OS_USERNAME': 'username', + 'OS_PASSWORD': 'password', + 'OS_TENANT_NAME': 'tenant_name', + 'OS_AUTH_URL': 'http://no.where/v2.0', + 'BYPASS_URL': 'http://magnum'} + + +class TestCommandLineArgument(utils.TestCase): + _unrecognized_arg_error = [ + '.*?^usage: ', + '.*?^error: unrecognized arguments:', + ".*?^Try 'magnum help ' for more information.", + ] + + _mandatory_arg_error = [ + '.*?^usage: ', + '.*?^error: (the following arguments|argument)', + ".*?^Try 'magnum help ", + ] + + _few_argument_error = [ + '.*?^usage: magnum ', + '.*?^error: (the following arguments|too few arguments)', + ".*?^Try" + ] + + def setUp(self): + super(TestCommandLineArgument, self).setUp() + self.make_env(fake_env=FAKE_ENV) + session_client = mock.patch( + 'magnumclient.common.httpclient.SessionClient') + session_client.start() + loader = mock.patch('keystoneauth1.loading.get_plugin_loader') + loader.start() + session = mock.patch('keystoneauth1.session.Session') + session.start() + + self.addCleanup(session_client.stop) + self.addCleanup(loader.stop) + self.addCleanup(session.stop) + + def _test_arg_success(self, command): + stdout, stderr = self.shell(command) + + def _test_arg_failure(self, command, error_msg): + stdout, stderr = self.shell(command, (2,)) + for line in error_msg: + self.assertThat((stdout + stderr), + matchers.MatchesRegex(line, + re.DOTALL | re.MULTILINE)) diff --git a/magnumclient/tests/v1/test_baymodels_shell.py b/magnumclient/tests/v1/test_baymodels_shell.py new file mode 100644 index 00000000..cf4367cb --- /dev/null +++ b/magnumclient/tests/v1/test_baymodels_shell.py @@ -0,0 +1,243 @@ +# 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.tests.v1 import shell_test_base + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test ' + '--image-id test_image ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--coe swarm ' + '--dns-nameserver test_dns ' + '--flavor-id test_flavor ' + '--fixed-network public ' + '--network-driver test_driver ' + '--labels key=val ' + '--master-flavor-id test_flavor ' + '--docker-volume-size 10' + '--public') + self.assertTrue(mock_create.called) + + self._test_arg_success('baymodel-create ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe kubernetes ' + '--name test ') + + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_public_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test --network-driver test_driver ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm' + '--public') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_success_with_master_flavor(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test ' + '--image-id test_image ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--coe swarm ' + '--dns-nameserver test_dns ' + '--master-flavor-id test_flavor') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_docker_vol_size_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test --docker-volume-size 4514 ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm' + ) + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_fixed_network_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test --fixed-network private ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_network_driver_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test --network-driver test_driver ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_ssh_authorized_key_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm ' + '--ssh-authorized-key test_key ' + ) + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_http_proxy_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test --fixed-network private ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm ' + '--http-proxy http_proxy ') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_https_proxy_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test --fixed-network private ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm ' + '--https-proxy https_proxy ') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_no_proxy_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test --fixed-network private ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm ' + '--no-proxy no_proxy ') + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_labels_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test ' + '--labels key=val ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_separate_labels_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test ' + '--labels key1=val1 ' + '--labels key2=val2 ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_combined_labels_success(self, mock_create): + self._test_arg_success('baymodel-create ' + '--name test ' + '--labels key1=val1,key2=val2 ' + '--keypair-id test_keypair ' + '--external-network-id test_net ' + '--image-id test_image ' + '--coe swarm') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.create') + def test_baymodel_create_failure_few_arg(self, mock_create): + self._test_arg_failure('baymodel-create ' + '--name test', self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + self._test_arg_failure('baymodel-create ' + '--image-id test', self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + self._test_arg_failure('baymodel-create ' + '--keypair-id test', self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + self._test_arg_failure('baymodel-create ' + '--external-network-id test', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + self._test_arg_failure('baymodel-create ' + '--coe test', self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + self._test_arg_failure('baymodel-create', self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.get') + def test_baymodel_show_success(self, mock_show): + self._test_arg_success('baymodel-show xxx') + self.assertTrue(mock_show.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.get') + def test_baymodel_show_failure_no_arg(self, mock_show): + self._test_arg_failure('baymodel-show', self._few_argument_error) + self.assertFalse(mock_show.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.delete') + def test_baymodel_delete_success(self, mock_delete): + self._test_arg_success('baymodel-delete xxx') + self.assertTrue(mock_delete.called) + self.assertEqual(1, mock_delete.call_count) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.delete') + def test_baymodel_delete_multiple_id_success(self, mock_delete): + self._test_arg_success('baymodel-delete xxx xyz') + self.assertTrue(mock_delete.called) + self.assertEqual(2, mock_delete.call_count) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.delete') + def test_baymodel_delete_failure_no_arg(self, mock_delete): + self._test_arg_failure('baymodel-delete', self._few_argument_error) + self.assertFalse(mock_delete.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.list') + def test_baymodel_list_success(self, mock_list): + self._test_arg_success('baymodel-list') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.list') + def test_baymodel_list_failure(self, mock_list): + self._test_arg_failure('baymodel-list --wrong', + self._unrecognized_arg_error) + self.assertFalse(mock_list.called) diff --git a/magnumclient/tests/v1/test_bays_shell.py b/magnumclient/tests/v1/test_bays_shell.py new file mode 100644 index 00000000..de3c6d60 --- /dev/null +++ b/magnumclient/tests/v1/test_bays_shell.py @@ -0,0 +1,158 @@ +# 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 import exceptions +from magnumclient.tests.v1 import shell_test_base + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.bays.BayManager.list') + def test_bay_list_success(self, mock_list): + self._test_arg_success('bay-list') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.bays.BayManager.list') + def test_bay_list_failure(self, mock_list): + self._test_arg_failure('bay-list --wrong', + self._unrecognized_arg_error) + self.assertFalse(mock_list.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.get') + @mock.patch('magnumclient.v1.bays.BayManager.create') + def test_bay_create_success(self, mock_create, mock_get): + self._test_arg_success('bay-create --name test --baymodel xxx ' + '--node-count 123 --timeout 15') + self.assertTrue(mock_create.called) + + self._test_arg_success('bay-create --baymodel xxx') + self.assertTrue(mock_create.called) + + self._test_arg_success('bay-create --name test --baymodel xxx') + self.assertTrue(mock_create.called) + + self._test_arg_success('bay-create --baymodel xxx --node-count 123') + self.assertTrue(mock_create.called) + + self._test_arg_success('bay-create --baymodel xxx --node-count 123 ' + '--master-count 123') + self.assertTrue(mock_create.called) + + self._test_arg_success('bay-create --baymodel xxx ' + '--timeout 15') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.baymodels.BayModelManager.get') + @mock.patch('magnumclient.v1.bays.BayManager.create') + def test_bay_create_success_only_baymodel_arg(self, mock_create, mock_get): + self._test_arg_success('bay-create --baymodel xxx') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.bays.BayManager.create') + def test_bay_create_failure_only_name(self, mock_create): + self._test_arg_failure('bay-create --name test', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + @mock.patch('magnumclient.v1.bays.BayManager.create') + def test_bay_create_failure_only_node_count(self, mock_create): + self._test_arg_failure('bay-create --node-count 1', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + @mock.patch('magnumclient.v1.bays.BayManager.create') + def test_bay_create_failure_only_bay_create_timeout(self, mock_create): + self._test_arg_failure('bay-create --timeout 15', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + @mock.patch('magnumclient.v1.bays.BayManager.create') + def test_bay_create_failure_no_arg(self, mock_create): + self._test_arg_failure('bay-create', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + @mock.patch('magnumclient.v1.bays.BayManager.delete') + def test_bay_delete_success(self, mock_delete): + self._test_arg_success('bay-delete xxx') + self.assertTrue(mock_delete.called) + self.assertEqual(1, mock_delete.call_count) + + @mock.patch('magnumclient.v1.bays.BayManager.delete') + def test_bay_delete_multiple_id_success(self, mock_delete): + self._test_arg_success('bay-delete xxx xyz') + self.assertTrue(mock_delete.called) + self.assertEqual(2, mock_delete.call_count) + + @mock.patch('magnumclient.v1.bays.BayManager.delete') + def test_bay_delete_failure_no_arg(self, mock_delete): + self._test_arg_failure('bay-delete', self._few_argument_error) + self.assertFalse(mock_delete.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + def test_bay_show_success(self, mock_show): + self._test_arg_success('bay-show xxx') + self.assertTrue(mock_show.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + def test_bay_show_failure_no_arg(self, mock_show): + self._test_arg_failure('bay-show', self._few_argument_error) + self.assertFalse(mock_show.called) + + @mock.patch('magnumclient.v1.bays.BayManager.update') + def test_bay_update_success(self, mock_update): + self._test_arg_success('bay-update test add test=test') + self.assertTrue(mock_update.called) + + @mock.patch('magnumclient.v1.bays.BayManager.update') + def test_bay_update_success_many_attribute(self, mock_update): + self._test_arg_success('bay-update test add test=test test1=test1') + self.assertTrue(mock_update.called) + + @mock.patch('magnumclient.v1.bays.BayManager.update') + def test_bay_update_failure_wrong_op(self, mock_update): + _error_msg = [ + '.*?^usage: magnum bay-update ', + '.*?^error: argument : invalid choice: ', + ".*?^Try 'magnum help bay-update' for more information." + ] + self._test_arg_failure('bay-update test wrong test=test', _error_msg) + self.assertFalse(mock_update.called) + + @mock.patch('magnumclient.v1.bays.BayManager.update') + def test_bay_update_failure_wrong_attribute(self, mock_update): + _error_msg = [ + '.*?^ERROR: Attributes must be a list of PATH=VALUE' + ] + self.assertRaises(exceptions.CommandError, self._test_arg_failure, + 'bay-update test add test', _error_msg) + self.assertFalse(mock_update.called) + + @mock.patch('magnumclient.v1.bays.BayManager.update') + def test_bay_update_failure_few_args(self, mock_update): + _error_msg = [ + '.*?^usage: magnum bay-update ', + '.*?^error: (the following arguments|too few arguments)', + ".*?^Try 'magnum help bay-update' for more information." + ] + self._test_arg_failure('bay-update', _error_msg) + self.assertFalse(mock_update.called) + + self._test_arg_failure('bay-update test', _error_msg) + self.assertFalse(mock_update.called) + + self._test_arg_failure('bay-update test add', _error_msg) + self.assertFalse(mock_update.called) diff --git a/magnumclient/tests/v1/test_certificates_shell.py b/magnumclient/tests/v1/test_certificates_shell.py new file mode 100644 index 00000000..8fc5ca6a --- /dev/null +++ b/magnumclient/tests/v1/test_certificates_shell.py @@ -0,0 +1,99 @@ +# 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.tests.v1 import shell_test_base +from magnumclient.v1 import certificates_shell + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.certificates.CertificateManager.get') + def test_ca_show_success(self, mock_cert_get, mock_bay_get): + mockbay = mock.MagicMock() + mockbay.status = "CREATE_COMPLETE" + mock_bay_get.return_value = mockbay + self._test_arg_success('ca-show ' + '--bay xxx') + self.assertTrue(mock_cert_get.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.certificates.CertificateManager.get') + def test_ca_show_with_wrong_status(self, mock_cert_get, mock_bay_get): + mockbay = mock.MagicMock() + mockbay.status = "FAILED" + mock_bay_get.return_value = mockbay + self._test_arg_success('ca-show ' + '--bay xxx') + self.assertFalse(mock_cert_get.called) + + @mock.patch('os.path.isfile') + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.certificates.CertificateManager.create') + def test_ca_sign_success( + self, mock_cert_create, mock_bay_get, mock_isfile): + mock_isfile.return_value = True + mockbay = mock.MagicMock() + mockbay.status = "CREATE_COMPLETE" + mock_bay_get.return_value = mockbay + + fake_csr = 'fake-csr' + file_mock = mock.mock_open(read_data=fake_csr) + with mock.patch.object(certificates_shell, 'open', file_mock): + self._test_arg_success('ca-sign ' + '--csr path/csr.pem ' + '--bay xxx') + self.assertTrue(mock_cert_create.called) + + @mock.patch('os.path.isfile') + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.certificates.CertificateManager.create') + def test_ca_sign_with_wrong_status( + self, mock_cert_create, mock_bay_get, mock_isfile): + mock_isfile.return_value = True + mockbay = mock.MagicMock() + mockbay.status = "FAILED" + mock_bay_get.return_value = mockbay + + fake_csr = 'fake-csr' + file_mock = mock.mock_open(read_data=fake_csr) + with mock.patch.object(certificates_shell, 'open', file_mock): + self._test_arg_success('ca-sign ' + '--csr path/csr.pem ' + '--bay xxx') + self.assertFalse(mock_isfile.called) + self.assertFalse(file_mock.called) + self.assertFalse(mock_cert_create.called) + + @mock.patch('os.path.isfile') + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.certificates.CertificateManager.create') + def test_ca_sign_with_not_csr( + self, mock_cert_create, mock_bay_get, mock_isfile): + mock_isfile.return_value = False + mockbay = mock.MagicMock() + mockbay.status = "CREATE_COMPLETE" + mock_bay_get.return_value = mockbay + + fake_csr = 'fake-csr' + file_mock = mock.mock_open(read_data=fake_csr) + with mock.patch.object(certificates_shell, 'open', file_mock): + self._test_arg_success('ca-sign ' + '--csr path/csr.pem ' + '--bay xxx') + mock_isfile.assert_called_once_with('path/csr.pem') + self.assertFalse(file_mock.called) + self.assertFalse(mock_cert_create.called) diff --git a/magnumclient/tests/v1/test_containers_shell.py b/magnumclient/tests/v1/test_containers_shell.py new file mode 100644 index 00000000..25bf45a1 --- /dev/null +++ b/magnumclient/tests/v1/test_containers_shell.py @@ -0,0 +1,197 @@ +# 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.tests.v1 import shell_test_base + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.containers.ContainerManager.list') + def test_container_list_success(self, mock_list): + self._test_arg_success('container-list') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.list') + def test_container_list_failure(self, mock_list): + self._test_arg_failure('container-list --wrong', + self._unrecognized_arg_error) + self.assertFalse(mock_list.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.containers.ContainerManager.create') + def test_container_create_success(self, mock_create, mock_bay_get): + mock_bay = mock.MagicMock() + mock_bay.status = "CREATE_COMPLETE" + mock_bay_get.return_value = mock_bay + self._test_arg_success('container-create ' + '--image test-image ' + '--bay test-bay') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.containers.ContainerManager.create') + def test_container_create_failure_without_image(self, mock_create, + mock_bay_get): + mock_bay = mock.MagicMock() + mock_bay.status = "CREATE_COMPLETE" + mock_bay_get.return_value = mock_bay + self._test_arg_failure('container-create ' + '--bay test-bay', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.delete') + def test_container_delete_success(self, mock_delete): + self._test_arg_success('container-delete xxx') + self.assertTrue(mock_delete.called) + self.assertEqual(1, mock_delete.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.delete') + def test_container_delete_multiple_id_success(self, mock_delete): + self._test_arg_success('container-delete xxx xyz') + self.assertTrue(mock_delete.called) + self.assertEqual(2, mock_delete.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.delete') + def test_container_delete_failure_no_arg(self, mock_delete): + self._test_arg_failure('container-delete', self._few_argument_error) + self.assertFalse(mock_delete.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.get') + def test_container_show_success(self, mock_show): + self._test_arg_success('container-show xxx') + self.assertTrue(mock_show.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.get') + def test_container_show_failure_no_arg(self, mock_show): + self._test_arg_failure('container-show', self._few_argument_error) + self.assertFalse(mock_show.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.reboot') + def test_container_reboot_success(self, mock_reboot): + self._test_arg_success('container-reboot xxx') + self.assertTrue(mock_reboot.called) + self.assertEqual(1, mock_reboot.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.reboot') + def test_container_reboot_multiple_id_success(self, mock_reboot): + self._test_arg_success('container-reboot xxx xyz') + self.assertTrue(mock_reboot.called) + self.assertEqual(2, mock_reboot.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.reboot') + def test_container_reboot_failure_no_arg(self, mock_reboot): + self._test_arg_failure('container-reboot', self._few_argument_error) + self.assertFalse(mock_reboot.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.stop') + def test_container_stop_success(self, mock_stop): + self._test_arg_success('container-stop xxx') + self.assertTrue(mock_stop.called) + self.assertEqual(1, mock_stop.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.stop') + def test_container_stop_multiple_id_success(self, mock_stop): + self._test_arg_success('container-stop xxx xyz') + self.assertTrue(mock_stop.called) + self.assertEqual(2, mock_stop.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.stop') + def test_container_stop_failure_no_arg(self, mock_stop): + self._test_arg_failure('container-stop', self._few_argument_error) + self.assertFalse(mock_stop.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.start') + def test_container_start_success(self, mock_start): + self._test_arg_success('container-start xxx') + self.assertTrue(mock_start.called) + self.assertEqual(1, mock_start.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.start') + def test_container_start_multiple_id_success(self, mock_start): + self._test_arg_success('container-start xxx xyz') + self.assertTrue(mock_start.called) + self.assertEqual(2, mock_start.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.start') + def test_container_start_failure_no_arg(self, mock_start): + self._test_arg_failure('container-start', self._few_argument_error) + self.assertFalse(mock_start.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.pause') + def test_container_pause_success(self, mock_pause): + self._test_arg_success('container-pause xxx') + self.assertTrue(mock_pause.called) + self.assertEqual(1, mock_pause.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.pause') + def test_container_multiple_id_pause_success(self, mock_pause): + self._test_arg_success('container-pause xxx xyz') + self.assertTrue(mock_pause.called) + self.assertEqual(2, mock_pause.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.pause') + def test_container_pause_failure_no_arg(self, mock_pause): + self._test_arg_failure('container-pause', self._few_argument_error) + self.assertFalse(mock_pause.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.unpause') + def test_container_unpause_success(self, mock_unpause): + self._test_arg_success('container-unpause xxx') + self.assertTrue(mock_unpause.called) + self.assertEqual(1, mock_unpause.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.unpause') + def test_container_unpause_multiple_id_success(self, mock_unpause): + self._test_arg_success('container-unpause xxx xyz') + self.assertTrue(mock_unpause.called) + self.assertEqual(2, mock_unpause.call_count) + + @mock.patch('magnumclient.v1.containers.ContainerManager.unpause') + def test_container_unpause_failure_no_arg(self, mock_unpause): + self._test_arg_failure('container-unpause', self._few_argument_error) + self.assertFalse(mock_unpause.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.logs') + def test_container_logs_success(self, mock_logs): + self._test_arg_success('container-logs xxx') + self.assertTrue(mock_logs.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.logs') + def test_container_logs_failure_no_arg(self, mock_logs): + self._test_arg_failure('container-logs', self._few_argument_error) + self.assertFalse(mock_logs.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.execute') + def test_container_execute_success(self, mock_execute): + self._test_arg_success('container-exec xxx ' + '--command ls') + self.assertTrue(mock_execute.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.execute') + def test_container_execute_failure_no_option(self, mock_execute): + self._test_arg_failure('container-exec xxx', + self._mandatory_arg_error) + self.assertFalse(mock_execute.called) + + self._test_arg_failure('container-exec --command ls', + self._few_argument_error) + self.assertFalse(mock_execute.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.execute') + def test_container_execute_failure_no_arg(self, mock_execute): + self._test_arg_failure('container-exec', self._few_argument_error) + self.assertFalse(mock_execute.called) diff --git a/magnumclient/tests/v1/test_mservices_shell.py b/magnumclient/tests/v1/test_mservices_shell.py new file mode 100644 index 00000000..c0d32a13 --- /dev/null +++ b/magnumclient/tests/v1/test_mservices_shell.py @@ -0,0 +1,31 @@ +# 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.tests.v1 import shell_test_base + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.mservices.MServiceManager.list') + def test_magnum_service_list_success(self, mock_list): + self._test_arg_success('service-list') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.mservices.MServiceManager.list') + def test_magnum_service_list_failure(self, mock_list): + self._test_arg_failure('service-list --wrong', + self._unrecognized_arg_error) + self.assertFalse(mock_list.called) diff --git a/magnumclient/tests/v1/test_nodes_shell.py b/magnumclient/tests/v1/test_nodes_shell.py new file mode 100644 index 00000000..795f657e --- /dev/null +++ b/magnumclient/tests/v1/test_nodes_shell.py @@ -0,0 +1,38 @@ +# 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.tests.v1 import shell_test_base + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.nodes.NodeManager.list') + def test_node_list_success(self, mock_list): + self._test_arg_success('node-list') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.nodes.NodeManager.list') + def test_node_list_failure(self, mock_list): + self._test_arg_failure('node-list --wrong', + self._unrecognized_arg_error) + self.assertFalse(mock_list.called) + + @mock.patch('magnumclient.v1.nodes.NodeManager.create') + def test_node_create_success(self, mock_create): + self._test_arg_success('node-create ' + '--type test ' + '--image-id test') + self.assertTrue(mock_create.called) diff --git a/magnumclient/tests/v1/test_pods_shell.py b/magnumclient/tests/v1/test_pods_shell.py new file mode 100644 index 00000000..84f93f92 --- /dev/null +++ b/magnumclient/tests/v1/test_pods_shell.py @@ -0,0 +1,96 @@ +# 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.tests.v1 import shell_test_base + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.pods.PodManager.list') + def test_pod_list_success(self, mock_list): + self._test_arg_success('pod-list bay_ident') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.pods.PodManager.list') + def test_pod_list_failure(self, mock_list): + self._test_arg_failure('pod-list bay_ident --wrong', + self._unrecognized_arg_error) + self.assertFalse(mock_list.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.pods.PodManager.create') + def test_pod_create_success(self, mock_list, mock_get): + mockbay = mock.MagicMock() + mockbay.status = "CREATE_COMPLETE" + mock_get.return_value = mockbay + self._test_arg_success('pod-create ' + '--bay xxx ' + '--manifest test ' + '--manifest-url test_url') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.pods.PodManager.create') + def test_pod_create_failure_few_arg(self, mock_list, mock_get): + self._test_arg_failure('pod-create ' + '--manifest test ' + '--manifest-url test_url', + self._mandatory_arg_error) + self.assertFalse(mock_list.called) + + self._test_arg_failure('pod-create ' + 'bay xxx ' + '--manifest-url test_url', + self._mandatory_arg_error) + self.assertFalse(mock_list.called) + + @mock.patch('magnumclient.v1.pods.PodManager.delete') + def test_pod_delete_success(self, mock_delete): + self._test_arg_success('pod-delete xxx zzz') + self.assertTrue(mock_delete.called) + self.assertEqual(1, mock_delete.call_count) + + @mock.patch('magnumclient.v1.pods.PodManager.delete') + def test_pod_delete_multiple_id_success(self, mock_delete): + self._test_arg_success('pod-delete xxx xyz zzz') + self.assertTrue(mock_delete.called) + self.assertEqual(2, mock_delete.call_count) + + @mock.patch('magnumclient.v1.pods.PodManager.delete') + def test_pod_delete_failure_no_arg(self, mock_delete): + self._test_arg_failure('pod-delete', self._few_argument_error) + self.assertFalse(mock_delete.called) + + @mock.patch('magnumclient.v1.pods.PodManager.update') + def test_pod_update_success(self, mock_update): + self._test_arg_success('pod-update xxx zzz replace xxx=xxx') + self.assertTrue(mock_update.called) + self.assertEqual(1, mock_update.call_count) + + @mock.patch('magnumclient.v1.pods.PodManager.update') + def test_pod_update_failure_no_arg(self, mock_update): + self._test_arg_failure('pod-update', self._few_argument_error) + self.assertFalse(mock_update.called) + + @mock.patch('magnumclient.v1.pods.PodManager.get') + def test_pod_show_success(self, mock_show): + self._test_arg_success('pod-show xxx zzz') + self.assertTrue(mock_show.called) + + @mock.patch('magnumclient.v1.pods.PodManager.get') + def test_pod_show_failure_no_arg(self, mock_show): + self._test_arg_failure('pod-show', self._few_argument_error) + self.assertFalse(mock_show.called) diff --git a/magnumclient/tests/v1/test_replicationcontrollers_shell.py b/magnumclient/tests/v1/test_replicationcontrollers_shell.py new file mode 100644 index 00000000..7ba3a77c --- /dev/null +++ b/magnumclient/tests/v1/test_replicationcontrollers_shell.py @@ -0,0 +1,107 @@ +# 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.tests.v1 import shell_test_base + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.list') + def test_rc_list_success(self, mock_list): + self._test_arg_success('rc-list bay_ident') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.list') + def test_rc_list_failure(self, mock_list): + self._test_arg_failure('rc-list bay_ident --wrong', + self._unrecognized_arg_error) + self.assertFalse(mock_list.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.create') + def test_rc_create_success(self, mock_create, mock_get): + mockbay = mock.MagicMock() + mockbay.status = "CREATE_COMPLETE" + mock_get.return_value = mockbay + + self._test_arg_success('rc-create ' + '--bay xxx ' + '--manifest test ' + '--manifest-url test_url') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.create') + def test_rc_create_failure_few_arg(self, mock_create, mock_get): + self._test_arg_failure('rc-create ' + '--manifest test ' + '--manifest-url test_url', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + self._test_arg_failure('rc-create ' + 'bay xxx ' + '--manifest-url test_url', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.delete') + def test_rc_delete_success(self, mock_delete): + self._test_arg_success('rc-delete xxx zzz') + self.assertTrue(mock_delete.called) + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.delete') + def test_rc_delete_multiple_id_success(self, mock_delete): + self._test_arg_success('rc-delete xxx xyz zzz') + self.assertTrue(mock_delete.called) + self.assertEqual(2, mock_delete.call_count) + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.delete') + def test_rc_delete_failure_no_arg(self, mock_delete): + self._test_arg_failure('rc-delete', self._few_argument_error) + self.assertFalse(mock_delete.called) + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.get') + def test_rc_show_success(self, mock_show): + self._test_arg_success('rc-show xxx zzz') + self.assertTrue(mock_show.called) + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.get') + def test_rc_show_failure_no_arg(self, mock_show): + self._test_arg_failure('rc-show', self._few_argument_error) + self.assertFalse(mock_show.called) + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.update') + def test_rc_update_success(self, mock_update): + self._test_arg_success('rc-update xxx zzz replace xxx=xxx') + self.assertTrue(mock_update.called) + self.assertEqual(1, mock_update.call_count) + + @mock.patch('magnumclient.v1.replicationcontrollers.' + 'ReplicationControllerManager.update') + def test_rc_update_failure_no_arg(self, mock_update): + self._test_arg_failure('rc-update', self._few_argument_error) + self.assertFalse(mock_update.called) diff --git a/magnumclient/tests/v1/test_services_shell.py b/magnumclient/tests/v1/test_services_shell.py new file mode 100644 index 00000000..6c52b1f3 --- /dev/null +++ b/magnumclient/tests/v1/test_services_shell.py @@ -0,0 +1,89 @@ +# 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.tests.v1 import shell_test_base + + +class ShellTest(shell_test_base.TestCommandLineArgument): + + @mock.patch('magnumclient.v1.services.ServiceManager.list') + def test_coe_service_list_success(self, mock_list): + self._test_arg_success('coe-service-list bay_ident') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.services.ServiceManager.list') + def test_coe_service_list_failure(self, mock_list): + self._test_arg_failure('coe-service-list bay_ident --wrong', + self._unrecognized_arg_error) + self.assertFalse(mock_list.called) + + @mock.patch('magnumclient.v1.bays.BayManager.get') + @mock.patch('magnumclient.v1.services.ServiceManager.create') + def test_coe_service_create_success(self, mock_create, mock_get): + mockbay = mock.MagicMock() + mockbay.status = "CREATE_COMPLETE" + mock_get.return_value = mockbay + self._test_arg_success('coe-service-create ' + '--bay xxx ' + '--manifest test ' + '--manifest-url test_url') + self.assertTrue(mock_create.called) + + @mock.patch('magnumclient.v1.services.ServiceManager.create') + def test_coe_service_create_failure_few_arg(self, mock_create): + self._test_arg_failure('coe-service-create ' + '--manifest test ' + '--manifest-url test_url', + self._mandatory_arg_error) + self.assertFalse(mock_create.called) + + @mock.patch('magnumclient.v1.services.ServiceManager.delete') + def test_coe_service_delete_success(self, mock_delete): + self._test_arg_success('coe-service-delete xxx zzz') + self.assertTrue(mock_delete.called) + self.assertEqual(1, mock_delete.call_count) + + @mock.patch('magnumclient.v1.services.ServiceManager.delete') + def test_coe_service_delete_multiple_id_success(self, mock_delete): + self._test_arg_success('coe-service-delete xxx xyz zzz') + self.assertTrue(mock_delete.called) + self.assertEqual(2, mock_delete.call_count) + + @mock.patch('magnumclient.v1.services.ServiceManager.delete') + def test_coe_service_delete_failure_no_arg(self, mock_delete): + self._test_arg_failure('coe-service-delete', self._few_argument_error) + self.assertFalse(mock_delete.called) + + @mock.patch('magnumclient.v1.services.ServiceManager.get') + def test_coe_service_show_success(self, mock_show): + self._test_arg_success('coe-service-show xxx zzz') + self.assertTrue(mock_show.called) + + @mock.patch('magnumclient.v1.services.ServiceManager.get') + def test_coe_service_show_failure_no_arg(self, mock_show): + self._test_arg_failure('coe-service-show', self._few_argument_error) + self.assertFalse(mock_show.called) + + @mock.patch('magnumclient.v1.services.ServiceManager.update') + def test_coe_service_update_success(self, mock_update): + self._test_arg_success('coe-service-update xxx zzz replace xxx=xxx') + self.assertTrue(mock_update.called) + self.assertEqual(1, mock_update.call_count) + + @mock.patch('magnumclient.v1.services.ServiceManager.update') + def test_coe_service_update_failure_no_arg(self, mock_update): + self._test_arg_failure('coe-service-update', self._few_argument_error) + self.assertFalse(mock_update.called) diff --git a/magnumclient/tests/v1/test_shell.py b/magnumclient/tests/v1/test_shell.py deleted file mode 100644 index 283eeed1..00000000 --- a/magnumclient/tests/v1/test_shell.py +++ /dev/null @@ -1,775 +0,0 @@ -# Copyright 2014 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 mock import mock_open - -from magnumclient.common import utils as magnum_utils -from magnumclient.tests import base -from magnumclient.v1 import shell - - -class ShellTest(base.TestCase): - - def setUp(self): - super(ShellTest, self).setUp() - - def test_do_bay_list(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - - shell.do_bay_list(client_mock, args) - client_mock.bays.list.assert_called_once_with() - - def test_do_bay_create(self): - client_mock = mock.MagicMock() - baymodel = mock.MagicMock() - baymodel.uuid = 'uuid' - client_mock.baymodels.get.return_value = baymodel - - args = mock.MagicMock() - node_count = 1 - args.node_count = node_count - args.master_count = None - args.discovery_url = None - name = "test_bay" - args.name = name - baymodel_id_or_name = "test_baymodel_id" - args.baymodel = baymodel_id_or_name - args.timeout = None - - shell.do_bay_create(client_mock, args) - client_mock.bays.create.assert_called_once_with( - name=name, node_count=node_count, baymodel_id=baymodel.uuid, - discovery_url=None, bay_create_timeout=None, master_count=None) - - def test_do_bay_create_with_discovery_url(self): - client_mock = mock.MagicMock() - baymodel = mock.MagicMock() - baymodel.uuid = 'uuid' - client_mock.baymodels.get.return_value = baymodel - - args = mock.MagicMock() - node_count = 1 - args.node_count = node_count - args.master_count = None - discovery_url = 'discovery_url' - args.discovery_url = discovery_url - name = "test_bay" - args.name = name - baymodel_id_or_name = "test_baymodel_id" - args.baymodel = baymodel_id_or_name - args.timeout = None - - shell.do_bay_create(client_mock, args) - client_mock.bays.create.assert_called_once_with( - name=name, node_count=node_count, baymodel_id=baymodel.uuid, - discovery_url=discovery_url, bay_create_timeout=None, - master_count=None) - - def test_do_bay_create_with_bay_create_timeout(self): - client_mock = mock.MagicMock() - baymodel = mock.MagicMock() - baymodel.uuid = 'uuid' - client_mock.baymodels.get.return_value = baymodel - - args = mock.MagicMock() - node_count = 1 - args.node_count = node_count - args.master_count = None - name = "test_bay" - args.name = name - baymodel_id_or_name = "test_baymodel_id" - args.baymodel = baymodel_id_or_name - bay_create_timeout = 15 - args.timeout = bay_create_timeout - args.discovery_url = None - - shell.do_bay_create(client_mock, args) - client_mock.bays.create.assert_called_once_with( - name=name, node_count=node_count, baymodel_id=baymodel.uuid, - discovery_url=None, bay_create_timeout=bay_create_timeout, - master_count=None) - - def test_do_bay_create_with_master_node_count(self): - client_mock = mock.MagicMock() - baymodel = mock.MagicMock() - baymodel.uuid = 'uuid' - client_mock.baymodels.get.return_value = baymodel - - args = mock.MagicMock() - node_count = 1 - args.node_count = node_count - master_count = 1 - args.master_count = master_count - args.discovery_url = None - name = "test_bay" - args.name = name - baymodel_id_or_name = "test_baymodel_id" - args.baymodel = baymodel_id_or_name - args.timeout = None - - shell.do_bay_create(client_mock, args) - client_mock.bays.create.assert_called_once_with( - name=name, node_count=node_count, baymodel_id=baymodel.uuid, - discovery_url=None, bay_create_timeout=None, master_count=1) - - def test_do_bay_delete(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - bay_id = 'id' - args.bay = [bay_id] - - shell.do_bay_delete(client_mock, args) - client_mock.bays.delete.assert_called_once_with(bay_id) - - def test_do_bay_show(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - bay_id = 'id' - args.bay = bay_id - - shell.do_bay_show(client_mock, args) - client_mock.bays.get.assert_called_once_with(bay_id) - - def test_do_bay_update(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - bay_id = 'id' - args.bay = bay_id - op = 'add' - args.op = op - attributes = 'node_count=2' - args.attributes = attributes - shell.magnum_utils.args_array_to_patch = mock.MagicMock() - patch = [{'path': '/node_count', 'value': 2, 'op': 'add'}] - shell.magnum_utils.args_array_to_patch.return_value = patch - - shell.do_bay_update(client_mock, args) - client_mock.bays.update.assert_called_once_with(bay_id, patch) - - @mock.patch('os.path.isfile') - def test_do_ca_show(self, mock_isfile): - mock_isfile.return_value = True - - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'CREATE_COMPLETE' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - bay_id_or_name = "xxx" - args.bay = bay_id_or_name - - shell.do_ca_show(client_mock, args) - - client_mock.certificates.get.assert_called_once_with( - bay_uuid=bay.uuid) - - @mock.patch('os.path.isfile') - def test_do_ca_show_wrong_status(self, mock_isfile): - mock_isfile.return_value = True - - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'XXX' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - bay_id_or_name = "xxx" - args.bay = bay_id_or_name - - shell.do_ca_show(client_mock, args) - - self.assertFalse(client_mock.certificates.get.called) - - @mock.patch('os.path.isfile') - def test_do_ca_sign(self, mock_isfile): - mock_isfile.return_value = True - - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'CREATE_COMPLETE' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - bay_id_or_name = "xxx" - args.bay = bay_id_or_name - csr = "test_csr" - args.csr = csr - - fake_csr = 'fake-csr' - mock_o = mock_open(read_data=fake_csr) - with mock.patch.object(shell, 'open', mock_o): - shell.do_ca_sign(client_mock, args) - - mock_isfile.assert_called_once_with(csr) - mock_o.assert_called_once_with(csr, 'r') - client_mock.certificates.create.assert_called_once_with( - csr=fake_csr, bay_uuid=bay.uuid) - - @mock.patch('os.path.isfile') - def test_do_ca_sign_wrong_status(self, mock_isfile): - mock_isfile.return_value = True - - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'XXX' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - bay_id_or_name = "xxx" - args.bay = bay_id_or_name - csr = "test_csr" - args.csr = csr - - fake_csr = 'fake-csr' - mock_o = mock_open(read_data=fake_csr) - with mock.patch.object(shell, 'open', mock_o): - shell.do_ca_sign(client_mock, args) - - self.assertFalse(mock_isfile.called) - self.assertFalse(mock_o.called) - self.assertFalse(client_mock.certificates.create.called) - - @mock.patch('os.path.isfile') - def test_do_ca_sign_not_file(self, mock_isfile): - mock_isfile.return_value = False - - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'CREATE_COMPLETE' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - bay_id_or_name = "xxx" - args.bay = bay_id_or_name - csr = "test_csr" - args.csr = csr - - fake_csr = 'fake-csr' - mock_o = mock_open(read_data=fake_csr) - with mock.patch.object(shell, 'open', mock_o): - shell.do_ca_sign(client_mock, args) - - mock_isfile.assert_called_once_with(csr) - self.assertFalse(mock_o.called) - self.assertFalse(client_mock.certificates.create.called) - - def test_do_baymodel_create(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - name = "test_baymodel" - args.name = name - image_id = "test_image" - args.image_id = image_id - flavor_id = "test_flavor" - args.flavor_id = flavor_id - master_flavor_id = "test_master_flavor" - args.master_flavor_id = master_flavor_id - keypair_id = "test_keypair" - args.keypair_id = keypair_id - external_network_id = "test_external_network_id" - args.external_network_id = external_network_id - dns_nameserver = "test_dns_nameserver" - args.dns_nameserver = dns_nameserver - docker_volume_size = "2051" - args.docker_volume_size = docker_volume_size - fixed_network = "private" - args.fixed_network = fixed_network - network_driver = "test_driver" - args.network_driver = network_driver - ssh_authorized_key = "test_key" - args.ssh_authorized_key = ssh_authorized_key - coe = 'swarm' - args.coe = coe - http_proxy = 'http_proxy' - args.http_proxy = http_proxy - https_proxy = 'https_proxy' - args.https_proxy = 'https_proxy' - no_proxy = 'no_proxy' - args.no_proxy = no_proxy - labels = ['key1=val1'] - args.labels = labels - tls_disabled = True - args.tls_disabled = tls_disabled - public = True - args.public = public - - shell.do_baymodel_create(client_mock, args) - client_mock.baymodels.create.assert_called_once_with( - name=name, image_id=image_id, flavor_id=flavor_id, - master_flavor_id=master_flavor_id, keypair_id=keypair_id, - external_network_id=external_network_id, - docker_volume_size=docker_volume_size, - fixed_network=fixed_network, dns_nameserver=dns_nameserver, - ssh_authorized_key=ssh_authorized_key, coe=coe, - http_proxy=http_proxy, https_proxy=https_proxy, - no_proxy=no_proxy, network_driver=network_driver, - labels=magnum_utils.format_labels(labels), - tls_disabled=tls_disabled, public=public) - - def test_do_baymodel_delete(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - baymodel_id = 'id' - args.baymodels = [baymodel_id] - - shell.do_baymodel_delete(client_mock, args) - client_mock.baymodels.delete.assert_called_once_with(baymodel_id) - - def test_do_baymodel_show(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - baymodel_id = 'id' - args.baymodel = baymodel_id - - shell.do_baymodel_show(client_mock, args) - client_mock.baymodels.get.assert_called_once_with(baymodel_id) - - def test_do_baymodel_list(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - - shell.do_baymodel_list(client_mock, args) - client_mock.baymodels.list.assert_called_once_with() - - def test_do_baymodel_update(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - baymodel_id = 'id' - args.baymodel = baymodel_id - op = 'add' - args.op = op - attributes = 'name=updated_name' - args.attributes = attributes - shell.magnum_utils.args_array_to_patch = mock.MagicMock() - patch = [{'path': '/name', 'value': 'updated_name', 'op': 'add'}] - shell.magnum_utils.args_array_to_patch.return_value = patch - - shell.do_baymodel_update(client_mock, args) - update = client_mock.baymodels.update - update.assert_called_once_with(baymodel_id, patch) - - def test_do_node_list(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - - shell.do_node_list(client_mock, args) - client_mock.nodes.list.assert_called_once_with() - - def test_do_node_create(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - type = "test_type" - args.type = type - image_id = "test_image" - args.image_id = image_id - - shell.do_node_create(client_mock, args) - client_mock.nodes.create.assert_called_once_with( - type=type, image_id=image_id) - - def test_do_pod_list(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - bay = 'id' - args.bay = bay - - shell.do_pod_list(client_mock, args) - client_mock.pods.list.assert_called_once_with(bay) - - def test_do_pod_create(self): - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'CREATE_COMPLETE' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - manifest_url = "test_url" - args.manifest_url = manifest_url - bay_id_or_name = "xxx" - args.bay = bay_id_or_name - manifest = "test_manifest" - args.manifest = manifest - - shell.do_pod_create(client_mock, args) - client_mock.pods.create.assert_called_once_with( - manifest_url=manifest_url, bay_uuid=bay.uuid) - - def test_do_pod_create_with_bay_in_wrong_status(self): - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'XXX' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - manifest_url = "test_url" - args.manifest_url = manifest_url - bay_id_or_name = "xxx" - args.bay = bay_id_or_name - manifest = "test_manifest" - args.manifest = manifest - - shell.do_pod_create(client_mock, args) - self.assertFalse(client_mock.pods.create.called) - - def test_do_pod_update(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - pod_id = 'id' - args.pod = pod_id - bay_uuid = 'uuid' - args.bay = bay_uuid - op = 'add' - args.op = op - attributes = "labels={'name': 'value'}" - args.attributes = attributes - shell.magnum_utils.args_array_to_patch = mock.MagicMock() - patch = [{'path': '/labels', 'value': {'name': 'value'}, 'op': 'add'}] - shell.magnum_utils.args_array_to_patch.return_value = patch - - shell.do_pod_update(client_mock, args) - client_mock.pods.update.assert_called_once_with(pod_id, - bay_uuid, - patch) - - def test_do_pod_delete(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - pod_id = 'id' - bay_uuid = 'uuid' - args.pods = [pod_id] - args.bay = bay_uuid - shell.do_pod_delete(client_mock, args) - client_mock.pods.delete.assert_called_once_with(pod_id, bay_uuid) - - def test_do_pod_show(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - pod_id = 'id' - args.pod = pod_id - bay_uuid = 'uuid' - args.bay = bay_uuid - - shell.do_pod_show(client_mock, args) - client_mock.pods.get.assert_called_once_with(pod_id, bay_uuid) - - def test_do_rc_list(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - bay = 'id' - args.bay = bay - - shell.do_rc_list(client_mock, args) - client_mock.rcs.list.assert_called_once_with(bay) - - def test_do_rc_create(self): - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'CREATE_COMPLETE' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - manifest_url = "test_url" - args.manifest_url = manifest_url - bay_id_or_name = "xxx" - args.bay_id = bay_id_or_name - manifest = "test_manifest" - args.manifest = manifest - - shell.do_rc_create(client_mock, args) - client_mock.rcs.create.assert_called_once_with( - manifest_url=manifest_url, bay_uuid=bay.uuid) - - def test_do_rc_create_with_bay_status_wrong(self): - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = 'XXX' - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - manifest_url = "test_url" - args.manifest_url = manifest_url - bay_id_or_name = "xxx" - args.bay_id = bay_id_or_name - manifest = "test_manifest" - args.manifest = manifest - - shell.do_rc_create(client_mock, args) - self.assertFalse(client_mock.rcs.create.called) - - def test_do_rc_update(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - rc_id = 'id' - bay_uuid = 'uuid' - args.rc = rc_id - args.bay = bay_uuid - op = 'replace' - args.op = op - attributes = 'manifest={}' - args.attributes = attributes - shell.magnum_utils.args_array_to_patch = mock.MagicMock() - patch = [{'path': '/manifest', 'value': '{}', 'op': 'replace'}] - shell.magnum_utils.args_array_to_patch.return_value = patch - - shell.do_rc_update(client_mock, args) - client_mock.rcs.update.assert_called_once_with(rc_id, - bay_uuid, - patch) - - def test_do_rc_delete(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - rc_id = 'id' - bay_uuid = 'uuid' - args.rcs = [rc_id] - args.bay = bay_uuid - - shell.do_rc_delete(client_mock, args) - client_mock.rcs.delete.assert_called_once_with(rc_id, bay_uuid) - - def test_do_rc_show(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - rc_id = 'id' - bay_uuid = 'uuid' - args.rc = rc_id - args.bay = bay_uuid - - shell.do_rc_show(client_mock, args) - client_mock.rcs.get.assert_called_once_with(rc_id, bay_uuid) - - def test_do_coe_service_list(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - bay = 'id' - args.bay = bay - - shell.do_coe_service_list(client_mock, args) - client_mock.services.list.assert_called_once_with(bay) - - def test_do_coe_service_create(self): - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = "CREATE_COMPLETE" - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - manifest_url = "test_url" - args.manifest_url = manifest_url - bay_id_or_name = "xxx" - args.bay_id = bay_id_or_name - manifest = "test_manifest" - args.manifest = manifest - - shell.do_coe_service_create(client_mock, args) - client_mock.services.create.assert_called_once_with( - manifest_url=manifest_url, bay_uuid=bay.uuid) - - def test_do_service_create_with_bay_status_wrong(self): - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = "XXX" - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - manifest_url = "test_url" - args.manifest_url = manifest_url - bay_id_or_name = "xxx" - args.bay_id = bay_id_or_name - manifest = "test_manifest" - args.manifest = manifest - - shell.do_coe_service_create(client_mock, args) - self.assertFalse(client_mock.services.create.called) - - def test_do_coe_service_update(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - service_id = 'id' - args.service = service_id - bay_uuid = 'uuid' - args.bay = bay_uuid - op = 'replace' - args.op = op - attributes = 'manifest={}' - args.attributes = attributes - shell.magnum_utils.args_array_to_patch = mock.MagicMock() - patch = [{'path': '/manifest', 'value': '{}', 'op': 'replace'}] - shell.magnum_utils.args_array_to_patch.return_value = patch - - shell.do_coe_service_update(client_mock, args) - client_mock.services.update.assert_called_once_with(service_id, - bay_uuid, - patch) - - def test_do_coe_service_delete(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - service_id = 'id' - bay_uuid = 'uuid' - args.services = [service_id] - args.bay = bay_uuid - - shell.do_coe_service_delete(client_mock, args) - client_mock.services.delete.assert_called_once_with(service_id, - bay_uuid) - - def test_do_coe_service_show(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - service_id = 'id' - bay_uuid = 'uuid' - args.service = service_id - args.bay = bay_uuid - - shell.do_coe_service_show(client_mock, args) - client_mock.services.get.assert_called_once_with(service_id, - bay_uuid) - - def test_do_container_create(self): - client_mock = mock.MagicMock() - bay = mock.MagicMock() - bay.uuid = 'uuid' - bay.status = "CREATE_COMPLETE" - client_mock.bays.get.return_value = bay - - args = mock.MagicMock() - name = "containe1" - args.name = name - image = "test_image" - args.image = image - bay_id_or_name = "xxx" - args.bay_id = bay_id_or_name - command = "test_command" - args.command = command - memory = "512m" - args.memory = memory - - shell.do_container_create(client_mock, args) - client_mock.containers.create.assert_called_once_with( - name=name, image=image, bay_uuid=bay.uuid, command=command, - memory=memory) - - def test_do_container_list(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - - shell.do_container_list(client_mock, args) - client_mock.containers.list.assert_called_once_with() - - def test_do_container_delete(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = "container_id" - args.containers = [container_id] - - shell.do_container_delete(client_mock, args) - client_mock.containers.delete.assert_called_once_with(container_id) - - def test_do_container_show(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = "container_id" - args.container = container_id - args.json = None - - shell.do_container_show(client_mock, args) - client_mock.containers.get.assert_called_once_with(container_id) - - def test_do_container_reboot(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = 'id' - args.containers = [container_id] - - shell.do_container_reboot(client_mock, args) - client_mock.containers.reboot.assert_called_once_with(container_id) - - def test_do_container_stop(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = 'id' - args.containers = [container_id] - - shell.do_container_stop(client_mock, args) - client_mock.containers.stop.assert_called_once_with(container_id) - - def test_do_container_start(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = 'id' - args.containers = [container_id] - - shell.do_container_start(client_mock, args) - client_mock.containers.start.assert_called_once_with(container_id) - - def test_do_container_pause(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = 'id' - args.containers = [container_id] - - shell.do_container_pause(client_mock, args) - client_mock.containers.pause.assert_called_once_with(container_id) - - def test_do_container_unpause(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = 'id' - args.containers = [container_id] - - shell.do_container_unpause(client_mock, args) - client_mock.containers.unpause.assert_called_once_with(container_id) - - def test_do_container_logs(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = 'id' - args.container = container_id - - shell.do_container_logs(client_mock, args) - client_mock.containers.logs.assert_called_once_with(container_id) - - def test_do_container_exec(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - container_id = 'id' - args.container = container_id - command = 'ls' - args.command = command - - shell.do_container_exec(client_mock, args) - client_mock.containers.execute.assert_called_once_with( - container_id, command) - - def test_do_service_list(self): - client_mock = mock.MagicMock() - args = mock.MagicMock() - - shell.do_service_list(client_mock, args) - client_mock.mservices.list.assert_called_once_with() diff --git a/magnumclient/v1/baymodels_shell.py b/magnumclient/v1/baymodels_shell.py new file mode 100644 index 00000000..a815ce9e --- /dev/null +++ b/magnumclient/v1/baymodels_shell.py @@ -0,0 +1,173 @@ +# 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.path + +from magnumclient.common import utils as magnum_utils +from magnumclient.openstack.common import cliutils as utils + + +def _show_baymodel(baymodel): + del baymodel._info['links'] + utils.print_dict(baymodel._info) + + +@utils.arg('--name', + metavar='', + help='Name of the bay to create.') +@utils.arg('--image-id', + required=True, + metavar='', + help='The name or UUID of the base image to customize for the bay.') +@utils.arg('--keypair-id', + required=True, + metavar='', + help='The name or UUID of the SSH keypair to load into the' + ' Bay nodes.') +@utils.arg('--external-network-id', + required=True, + metavar='', + help='The external Neutron network ID to connect to this bay' + ' model.') +@utils.arg('--coe', + required=True, + metavar='', + help='Specify the Container Orchestration Engine to use.') +@utils.arg('--fixed-network', + metavar='', + help='The private Neutron network name to connect to this bay' + ' model.') +@utils.arg('--network-driver', + metavar='', + help='The network driver name for instantiating container' + ' networks.') +@utils.arg('--ssh-authorized-key', + metavar='', + help='The SSH authorized key to use') +@utils.arg('--dns-nameserver', + metavar='', + default='8.8.8.8', + help='The DNS nameserver to use for this Bay.') +@utils.arg('--flavor-id', + metavar='', + default='m1.medium', + help='The nova flavor id to use when launching the bay.') +@utils.arg('--master-flavor-id', + metavar='', + help='The nova flavor id to use when launching the master node ' + 'of the bay.') +@utils.arg('--docker-volume-size', + metavar='', + help='Specify the size of the docker volume to use.') +@utils.arg('--http-proxy', + metavar='', + help='The http_proxy address to use for nodes in bay.') +@utils.arg('--https-proxy', + metavar='', + help='The https_proxy address to use for nodes in bay.') +@utils.arg('--no-proxy', + metavar='', + help='The no_proxy address to use for nodes in bay.') +@utils.arg('--labels', metavar='', + action='append', default=[], + help='Arbitrary labels in the form of key=value pairs ' + 'to associate with a baymodel. ' + 'May be used multiple times.') +@utils.arg('--tls-disabled', + action='store_true', default=False, + help='Disable TLS in the Bay.') +@utils.arg('--public', + action='store_true', default=False, + help='Make baymodel public.') +def do_baymodel_create(cs, args): + """Create a baymodel.""" + opts = {} + opts['name'] = args.name + opts['flavor_id'] = args.flavor_id + opts['master_flavor_id'] = args.master_flavor_id + opts['image_id'] = args.image_id + opts['keypair_id'] = args.keypair_id + opts['external_network_id'] = args.external_network_id + opts['fixed_network'] = args.fixed_network + opts['network_driver'] = args.network_driver + opts['dns_nameserver'] = args.dns_nameserver + opts['docker_volume_size'] = args.docker_volume_size + opts['ssh_authorized_key'] = args.ssh_authorized_key + opts['coe'] = args.coe + opts['http_proxy'] = args.http_proxy + opts['https_proxy'] = args.https_proxy + opts['no_proxy'] = args.no_proxy + opts['labels'] = magnum_utils.format_labels(args.labels) + opts['tls_disabled'] = args.tls_disabled + opts['public'] = args.public + + baymodel = cs.baymodels.create(**opts) + _show_baymodel(baymodel) + + +@utils.arg('baymodels', + metavar='', + nargs='+', + help='ID or name of the (baymodel)s to delete.') +def do_baymodel_delete(cs, args): + """Delete specified baymodel.""" + for baymodel in args.baymodels: + try: + cs.baymodels.delete(baymodel) + except Exception as e: + print("Delete for baymodel %(baymodel)s failed: %(e)s" % + {'baymodel': baymodel, 'e': e}) + + +@utils.arg('baymodel', + metavar='', + help='ID of the baymodel to show.') +def do_baymodel_show(cs, args): + """Show details about the given baymodel.""" + baymodel = cs.baymodels.get(args.baymodel) + _show_baymodel(baymodel) + + +def do_baymodel_list(cs, args): + """Print a list of bay models.""" + nodes = cs.baymodels.list() + columns = ('uuid', 'name') + utils.print_list(nodes, columns, + {'versions': magnum_utils.print_list_field('versions')}) + + +@utils.arg('baymodel', metavar='', help="UUID or name of baymodel") +@utils.arg( + 'op', + metavar='', + choices=['add', 'replace', 'remove'], + help="Operations: 'add', 'replace' or 'remove'") +@utils.arg( + 'attributes', + metavar='', + nargs='+', + action='append', + default=[], + help="Attributes to add/replace or remove " + "(only PATH is necessary on remove)") +def do_baymodel_update(cs, args): + """Updates one or more baymodel attributes.""" + patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) + p = patch[0] + if p['path'] == '/manifest' and os.path.isfile(p['value']): + with open(p['value'], 'r') as f: + p['value'] = f.read() + + baymodel = cs.baymodels.update(args.baymodel, patch) + _show_baymodel(baymodel) diff --git a/magnumclient/v1/bays_shell.py b/magnumclient/v1/bays_shell.py new file mode 100644 index 00000000..43facc9d --- /dev/null +++ b/magnumclient/v1/bays_shell.py @@ -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. + +from magnumclient.common import utils as magnum_utils +from magnumclient.openstack.common import cliutils as utils + + +def _show_bay(bay): + del bay._info['links'] + utils.print_dict(bay._info) + + +def do_bay_list(cs, args): + """Print a list of available bays.""" + bays = cs.bays.list() + columns = ('uuid', 'name', 'node_count', 'master_count', 'status') + utils.print_list(bays, columns, + {'versions': magnum_utils.print_list_field('versions')}) + + +@utils.arg('--name', + metavar='', + help='Name of the bay to create.') +@utils.arg('--baymodel', + required=True, + metavar='', + help='ID or name of the baymodel.') +@utils.arg('--node-count', + metavar='', + help='The bay node count.') +@utils.arg('--master-count', + metavar='', + default=1, + help='The number of master nodes for the bay.') +@utils.arg('--discovery-url', + metavar='', + help='Specifies custom discovery url for node discovery.') +@utils.arg('--timeout', + metavar='', + help='The timeout for bay creation in minutes. Set ' + 'to 0 for no timeout. The default is no timeout.') +def do_bay_create(cs, args): + """Create a bay.""" + baymodel = cs.baymodels.get(args.baymodel) + + opts = {} + opts['name'] = args.name + opts['baymodel_id'] = baymodel.uuid + opts['node_count'] = args.node_count + opts['master_count'] = args.master_count + opts['discovery_url'] = args.discovery_url + opts['bay_create_timeout'] = args.timeout + + bay = cs.bays.create(**opts) + _show_bay(bay) + + +@utils.arg('bay', + metavar='', + nargs='+', + help='ID or name of the (bay)s to delete.') +def do_bay_delete(cs, args): + """Delete specified bay.""" + for id in args.bay: + try: + cs.bays.delete(id) + except Exception as e: + print("Delete for bay %(bay)s failed: %(e)s" % + {'bay': id, 'e': e}) + + +@utils.arg('bay', + metavar='', + help='ID or name of the bay to show.') +def do_bay_show(cs, args): + """Show details about the given bay.""" + bay = cs.bays.get(args.bay) + _show_bay(bay) + + +@utils.arg('bay', metavar='', help="UUID or name of bay") +@utils.arg( + 'op', + metavar='', + choices=['add', 'replace', 'remove'], + help="Operations: 'add', 'replace' or 'remove'") +@utils.arg( + 'attributes', + metavar='', + nargs='+', + action='append', + default=[], + help="Attributes to add/replace or remove " + "(only PATH is necessary on remove)") +def do_bay_update(cs, args): + """Update information about the given bay.""" + patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) + bay = cs.bays.update(args.bay, patch) + _show_bay(bay) diff --git a/magnumclient/v1/certificates_shell.py b/magnumclient/v1/certificates_shell.py new file mode 100644 index 00000000..deb499c5 --- /dev/null +++ b/magnumclient/v1/certificates_shell.py @@ -0,0 +1,73 @@ +# 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.path + +from magnumclient.openstack.common import cliutils as utils + + +def _show_cert(certificate): + print(certificate.pem) + + +@utils.arg('--bay', + required=True, + metavar='', + help='ID or name of the bay.') +def do_ca_show(cs, args): + """Show details about the CA certificate for a bay.""" + bay = cs.bays.get(args.bay) + if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: + print('Bay status for %s is: %s. We can not create a %s there' + ' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % + (bay.uuid, bay.status, 'certificate')) + return + + opts = { + 'bay_uuid': bay.uuid + } + + cert = cs.certificates.get(**opts) + _show_cert(cert) + + +@utils.arg('--csr', + metavar='', + help='File path of the csr file to send to Magnum to get signed.') +@utils.arg('--bay', + required=True, + metavar='', + help='ID or name of the bay.') +def do_ca_sign(cs, args): + """Generate the CA certificate for a bay.""" + bay = cs.bays.get(args.bay) + if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: + print('Bay status for %s is: %s. We can not create a %s there' + ' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % + (bay.uuid, bay.status, 'certificate')) + return + + opts = { + 'bay_uuid': bay.uuid + } + + if args.csr is None or not os.path.isfile(args.csr): + print('A CSR must be provided.') + return + + with open(args.csr, 'r') as f: + opts['csr'] = f.read() + + cert = cs.certificates.create(**opts) + _show_cert(cert) diff --git a/magnumclient/v1/containers_shell.py b/magnumclient/v1/containers_shell.py new file mode 100644 index 00000000..f2bf39ce --- /dev/null +++ b/magnumclient/v1/containers_shell.py @@ -0,0 +1,187 @@ +# 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 json + +from magnumclient.common import utils as magnum_utils +from magnumclient.openstack.common import cliutils as utils + + +def _show_container(container): + utils.print_dict(container._info) + + +@utils.arg('--name', + metavar='', + help='name of the container') +@utils.arg('--image', + required=True, + metavar='', + help='name or ID of the image') +@utils.arg('--bay', + required=True, + metavar='', + help='ID or name of the bay.') +@utils.arg('--command', + metavar='', + help='Send command to the container') +@utils.arg('--memory', + metavar='', + help='The container memory size (format: , ' + 'where unit = b, k, m or g)') +def do_container_create(cs, args): + """Create a container.""" + bay = cs.bays.get(args.bay) + if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: + print('Bay status for %s is: %s. We can not create a %s there' + ' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % + (bay.uuid, bay.status, "pod")) + return + opts = {} + opts['name'] = args.name + opts['image'] = args.image + opts['bay_uuid'] = bay.uuid + opts['command'] = args.command + opts['memory'] = args.memory + _show_container(cs.containers.create(**opts)) + + +def do_container_list(cs, args): + """Print a list of available containers.""" + containers = cs.containers.list() + columns = ('uuid', 'name', 'status') + utils.print_list(containers, columns, + {'versions': magnum_utils.print_list_field('versions')}) + + +@utils.arg('containers', + metavar='', + nargs='+', + help='ID or name of the (container)s to delete.') +def do_container_delete(cs, args): + """Delete specified containers.""" + for container in args.containers: + try: + cs.containers.delete(container) + except Exception as e: + print("Delete for container %(container)s failed: %(e)s" % + {'container': container, 'e': e}) + + +@utils.arg('container', + metavar='', + help='ID or name of the container to show.') +@utils.arg('--json', + action='store_true', + default=False, + help='Print JSON representation of the container.') +def do_container_show(cs, args): + """Show details of a container.""" + container = cs.containers.get(args.container) + if args.json: + print(json.dumps(container._info)) + else: + _show_container(container) + + +@utils.arg('containers', + metavar='', + nargs='+', + help='ID or name of the (container)s to start.') +def do_container_reboot(cs, args): + """Reboot specified containers.""" + for container in args.containers: + try: + cs.containers.reboot(container) + except Exception as e: + print("Reboot for container %(container)s failed: %(e)s" % + {'container': container, 'e': e}) + + +@utils.arg('containers', + metavar='', + nargs='+', + help='ID or name of the (container)s to start.') +def do_container_stop(cs, args): + """Stop specified containers.""" + for container in args.containers: + try: + cs.containers.stop(container) + except Exception as e: + print("Stop for container %(container)s failed: %(e)s" % + {'container': container, 'e': e}) + + +@utils.arg('containers', + metavar='', + nargs='+', + help='ID of the (container)s to start.') +def do_container_start(cs, args): + """Start specified containers.""" + for container in args.containers: + try: + cs.containers.start(container) + except Exception as e: + print("Start for container %(container)s failed: %(e)s" % + {'container': container, 'e': e}) + + +@utils.arg('containers', + metavar='', + nargs='+', + help='ID or name of the (container)s to start.') +def do_container_pause(cs, args): + """Pause specified containers.""" + for container in args.containers: + try: + cs.containers.pause(container) + except Exception as e: + print("Pause for container %(container)s failed: %(e)s" % + {'container': container, 'e': e}) + + +@utils.arg('containers', + metavar='', + nargs='+', + help='ID or name of the (container)s to start.') +def do_container_unpause(cs, args): + """Unpause specified containers.""" + for container in args.containers: + try: + cs.containers.unpause(container) + except Exception as e: + print("Unpause for container %(container)s failed: %(e)s" % + {'container': container, 'e': e}) + + +@utils.arg('container', + metavar='', + help='ID or name of the container to start.') +def do_container_logs(cs, args): + """Get logs of a container.""" + logs = cs.containers.logs(args.container) + print(logs) + + +@utils.arg('container', + metavar='', + help='ID or name of the container to start.') +@utils.arg('--command', + required=True, + metavar='', + help='The command to execute') +def do_container_exec(cs, args): + """Execute command in a container.""" + output = cs.containers.execute(args.container, args.command) + print(output) diff --git a/magnumclient/v1/mservices_shell.py b/magnumclient/v1/mservices_shell.py new file mode 100644 index 00000000..f06064f2 --- /dev/null +++ b/magnumclient/v1/mservices_shell.py @@ -0,0 +1,25 @@ +# 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 utils as magnum_utils +from magnumclient.openstack.common import cliutils as utils + + +def do_service_list(cs, args): + """Print a list of magnum services.""" + mservices = cs.mservices.list() + columns = ('id', 'host', 'binary', 'state') + utils.print_list(mservices, columns, + {'versions': magnum_utils.print_list_field('versions')}) diff --git a/magnumclient/v1/nodes_shell.py b/magnumclient/v1/nodes_shell.py new file mode 100644 index 00000000..c4ecb1e8 --- /dev/null +++ b/magnumclient/v1/nodes_shell.py @@ -0,0 +1,44 @@ +# 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 utils as magnum_utils +from magnumclient.openstack.common import cliutils as utils + + +def _show_node(node): + utils.print_dict(node._info) + + +def do_node_list(cs, args): + """Print a list of configured nodes.""" + nodes = cs.nodes.list() + columns = ('uuid', 'type', 'image_id') + utils.print_list(nodes, columns, + {'versions': magnum_utils.print_list_field('versions')}) + + +@utils.arg('--type', + metavar='', + help='Type of node to create (virt or bare).') +@utils.arg('--image-id', + metavar='', + help='The name or UUID of the base image to use for the node.') +def do_node_create(cs, args): + """Create a node.""" + opts = {} + opts['type'] = args.type + opts['image_id'] = args.image_id + + node = cs.nodes.create(**opts) + _show_node(node) diff --git a/magnumclient/v1/pods_shell.py b/magnumclient/v1/pods_shell.py new file mode 100644 index 00000000..7a355613 --- /dev/null +++ b/magnumclient/v1/pods_shell.py @@ -0,0 +1,116 @@ +# 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.path + +from magnumclient.common import utils as magnum_utils +from magnumclient.openstack.common import cliutils as utils + + +def _show_pod(pod): + del pod._info['links'] + utils.print_dict(pod._info) + + +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_pod_list(cs, args): + """Print a list of registered pods.""" + pods = cs.pods.list(args.bay) + columns = ('uuid', 'name') + utils.print_list(pods, columns, + {'versions': magnum_utils.print_list_field('versions')}) + + +@utils.arg('--manifest-url', + metavar='', + help='Name/URL of the pod file to use for creating PODs.') +@utils.arg('--manifest', + metavar='', + help='File path of the pod file to use for creating PODs.') +@utils.arg('--bay', + required=True, + metavar='', + help='ID or name of the bay.') +def do_pod_create(cs, args): + """Create a pod.""" + bay = cs.bays.get(args.bay) + if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: + print('Bay status for %s is: %s. We can not create a %s there' + ' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % + (bay.uuid, bay.status, "pod")) + return + opts = {} + opts['manifest_url'] = args.manifest_url + opts['bay_uuid'] = bay.uuid + + if args.manifest is not None and os.path.isfile(args.manifest): + with open(args.manifest, 'r') as f: + opts['manifest'] = f.read() + + node = cs.pods.create(**opts) + _show_pod(node) + pass + + +@utils.arg('pod', metavar='', help="UUID or name of pod") +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +@utils.arg( + 'op', + metavar='', + choices=['add', 'replace', 'remove'], + help="Operations: 'add', 'replace' or 'remove'") +@utils.arg( + 'attributes', + metavar='', + nargs='+', + action='append', + default=[], + help="Attributes to add/replace or remove " + "(only PATH is necessary on remove)") +def do_pod_update(cs, args): + """Update information about the given pod.""" + patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) + p = patch[0] + if p['path'] == '/manifest' and os.path.isfile(p['value']): + with open(p['value'], 'r') as f: + p['value'] = f.read() + + pod = cs.pods.update(args.pod, args.bay, patch) + _show_pod(pod) + + +@utils.arg('pods', + metavar='', + nargs='+', + help='ID or name of the (pod)s to delete.') +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_pod_delete(cs, args): + """Delete specified pod.""" + for pod in args.pods: + try: + cs.pods.delete(pod, args.bay) + except Exception as e: + print("Delete for pod %(pod)s failed: %(e)s" % + {'pod': pod, 'e': e}) + pass + + +@utils.arg('pod', + metavar='', + help='ID or name of the pod to show.') +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_pod_show(cs, args): + """Show details about the given pod.""" + pod = cs.pods.get(args.pod, args.bay) + _show_pod(pod) diff --git a/magnumclient/v1/replicationcontrollers_shell.py b/magnumclient/v1/replicationcontrollers_shell.py new file mode 100644 index 00000000..639bcf72 --- /dev/null +++ b/magnumclient/v1/replicationcontrollers_shell.py @@ -0,0 +1,117 @@ +# 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.path + +from magnumclient.common import utils as magnum_utils +from magnumclient.openstack.common import cliutils as utils + + +def _show_rc(rc): + utils.print_dict(rc._info) + + +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_rc_list(cs, args): + """Print a list of registered replication controllers.""" + rcs = cs.rcs.list(args.bay) + columns = ('uuid', 'name') + utils.print_list(rcs, columns, + {'versions': magnum_utils.print_list_field('versions')}) + + +@utils.arg('--manifest-url', + metavar='', + help='Name/URL of the replication controller file to use for ' + 'creating replication controllers.') +@utils.arg('--manifest', + metavar='', + help='File path of the replication controller file to use for ' + 'creating replication controllers.') +@utils.arg('--bay', + required=True, + metavar='', + help='ID or name of the bay.') +def do_rc_create(cs, args): + """Create a replication controller.""" + bay = cs.bays.get(args.bay) + if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: + print('Bay status for %s is: %s. We can not create a ' + 'replication controller in bay until the status ' + 'is CREATE_COMPLETE or UPDATE_COMPLETE.' % + (args.bay, bay.status)) + return + + opts = {} + opts['manifest_url'] = args.manifest_url + opts['bay_uuid'] = bay.uuid + + if args.manifest is not None and os.path.isfile(args.manifest): + with open(args.manifest, 'r') as f: + opts['manifest'] = f.read() + + rc = cs.rcs.create(**opts) + _show_rc(rc) + + +@utils.arg('rc', metavar='', help="UUID or name of replication controller") +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +@utils.arg( + 'op', + metavar='', + choices=['add', 'replace', 'remove'], + help="Operations: 'add', 'replace' or 'remove'") +@utils.arg( + 'attributes', + metavar='', + nargs='+', + action='append', + default=[], + help="Attributes to add/replace or remove " + "(only PATH is necessary on remove)") +def do_rc_update(cs, args): + """Update information about the given replication controller.""" + patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) + p = patch[0] + if p['path'] == '/manifest' and os.path.isfile(p['value']): + with open(p['value'], 'r') as f: + p['value'] = f.read() + + rc = cs.rcs.update(args.rc, args.bay, patch) + _show_rc(rc) + + +@utils.arg('rcs', + metavar='', + nargs='+', + help='ID or name of the replication (controller)s to delete.') +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_rc_delete(cs, args): + """Delete specified replication controller.""" + for rc in args.rcs: + try: + cs.rcs.delete(rc, args.bay) + except Exception as e: + print("Delete for rc %(rc)s failed: %(e)s" % + {'rc': rc, 'e': e}) + + +@utils.arg('rc', + metavar='', + help='ID or name of the replication controller to show.') +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_rc_show(cs, args): + """Show details about the given replication controller.""" + rc = cs.rcs.get(args.rc, args.bay) + _show_rc(rc) diff --git a/magnumclient/v1/services_shell.py b/magnumclient/v1/services_shell.py new file mode 100644 index 00000000..8b3a1b90 --- /dev/null +++ b/magnumclient/v1/services_shell.py @@ -0,0 +1,114 @@ +# 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.path + +from magnumclient.common import utils as magnum_utils +from magnumclient.openstack.common import cliutils as utils + + +def _show_coe_service(service): + utils.print_dict(service._info) + + +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_coe_service_list(cs, args): + """Print a list of coe services.""" + services = cs.services.list(args.bay) + columns = ('uuid', 'name', 'bay_uuid') + utils.print_list(services, columns, + {'versions': magnum_utils.print_list_field('versions')}) + + +@utils.arg('--manifest-url', + metavar='', + help='Name/URL of the serivce file to use for creating services.') +@utils.arg('--manifest', + metavar='', + help='File path of the service file to use for creating services.') +@utils.arg('--bay', + required=True, + metavar='', + help='Id or name of the bay.') +def do_coe_service_create(cs, args): + """Create a coe service.""" + bay = cs.bays.get(args.bay) + if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: + print('Bay status for %s is: %s. We can not create a service in bay ' + 'until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % + (args.bay, bay.status)) + return + + opts = {} + opts['manifest_url'] = args.manifest_url + opts['bay_uuid'] = bay.uuid + + if args.manifest is not None and os.path.isfile(args.manifest): + with open(args.manifest, 'r') as f: + opts['manifest'] = f.read() + + service = cs.services.create(**opts) + _show_coe_service(service) + + +@utils.arg('service', metavar='', help="UUID or name of service") +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +@utils.arg( + 'op', + metavar='', + choices=['add', 'replace', 'remove'], + help="Operations: 'add', 'replace' or 'remove'") +@utils.arg( + 'attributes', + metavar='', + nargs='+', + action='append', + default=[], + help="Attributes to add/replace or remove " + "(only PATH is necessary on remove)") +def do_coe_service_update(cs, args): + """Update information about the given coe service.""" + patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) + p = patch[0] + if p['path'] == '/manifest' and os.path.isfile(p['value']): + with open(p['value'], 'r') as f: + p['value'] = f.read() + + service = cs.services.update(args.service, args.bay, patch) + _show_coe_service(service) + + +@utils.arg('services', + metavar='', + nargs='+', + help='ID or name of the (service)s to delete.') +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_coe_service_delete(cs, args): + """Delete specified coe service(s).""" + for service in args.services: + try: + cs.services.delete(service, args.bay) + except Exception as e: + print("Delete for service %(service)s failed: %(e)s" % + {'service': service, 'e': e}) + + +@utils.arg('service', + metavar='', + help='ID or name of the service to show.') +@utils.arg('bay', metavar='', help="UUID or Name of Bay") +def do_coe_service_show(cs, args): + """Show details about the given coe service.""" + service = cs.services.get(args.service, args.bay) + _show_coe_service(service) diff --git a/magnumclient/v1/shell.py b/magnumclient/v1/shell.py index c507216b..2f6cfb69 100644 --- a/magnumclient/v1/shell.py +++ b/magnumclient/v1/shell.py @@ -13,818 +13,24 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json -import os.path - -from magnumclient.common import utils as magnum_utils -from magnumclient.openstack.common import cliutils as utils - - -def _print_list_field(field): - return lambda obj: ', '.join(getattr(obj, field)) - - -def _show_container(container): - utils.print_dict(container._info) - - -def _show_bay(bay): - del bay._info['links'] - utils.print_dict(bay._info) - - -def _show_cert(certificate): - print(certificate.pem) - - -def _show_baymodel(baymodel): - del baymodel._info['links'] - utils.print_dict(baymodel._info) - - -def _show_node(node): - utils.print_dict(node._info) - - -def _show_pod(pod): - del pod._info['links'] - utils.print_dict(pod._info) - - -def _show_rc(rc): - utils.print_dict(rc._info) - - -def _show_coe_service(service): - utils.print_dict(service._info) - - -def do_bay_list(cs, args): - """Print a list of available bays.""" - bays = cs.bays.list() - columns = ('uuid', 'name', 'node_count', 'master_count', 'status') - utils.print_list(bays, columns, - {'versions': _print_list_field('versions')}) - - -@utils.arg('--name', - metavar='', - help='Name of the bay to create.') -@utils.arg('--baymodel', - required=True, - metavar='', - help='ID or name of the baymodel.') -@utils.arg('--node-count', - metavar='', - help='The bay node count.') -@utils.arg('--master-count', - metavar='', - default=1, - help='The number of master nodes for the bay.') -@utils.arg('--discovery-url', - metavar='', - help='Specifies custom discovery url for node discovery.') -@utils.arg('--timeout', - metavar='', - help='The timeout for bay creation in minutes. Set ' - 'to 0 for no timeout. The default is no timeout.') -def do_bay_create(cs, args): - """Create a bay.""" - baymodel = cs.baymodels.get(args.baymodel) - - opts = {} - opts['name'] = args.name - opts['baymodel_id'] = baymodel.uuid - opts['node_count'] = args.node_count - opts['master_count'] = args.master_count - opts['discovery_url'] = args.discovery_url - opts['bay_create_timeout'] = args.timeout - - bay = cs.bays.create(**opts) - _show_baymodel(bay) - - -@utils.arg('bay', - metavar='', - nargs='+', - help='ID or name of the (bay)s to delete.') -def do_bay_delete(cs, args): - """Delete specified bay.""" - for id in args.bay: - try: - cs.bays.delete(id) - except Exception as e: - print("Delete for bay %(bay)s failed: %(e)s" % - {'bay': id, 'e': e}) - - -@utils.arg('bay', - metavar='', - help='ID or name of the bay to show.') -def do_bay_show(cs, args): - """Show details about the given bay.""" - bay = cs.bays.get(args.bay) - _show_bay(bay) - - -@utils.arg('bay', metavar='', help="UUID or name of bay") -@utils.arg( - 'op', - metavar='', - choices=['add', 'replace', 'remove'], - help="Operations: 'add', 'replace' or 'remove'") -@utils.arg( - 'attributes', - metavar='', - nargs='+', - action='append', - default=[], - help="Attributes to add/replace or remove " - "(only PATH is necessary on remove)") -def do_bay_update(cs, args): - """Update information about the given bay.""" - patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) - bay = cs.bays.update(args.bay, patch) - _show_bay(bay) - - -@utils.arg('--name', - metavar='', - help='Name of the bay to create.') -@utils.arg('--image-id', - required=True, - metavar='', - help='The name or UUID of the base image to customize for the bay.') -@utils.arg('--keypair-id', - required=True, - metavar='', - help='The name or UUID of the SSH keypair to load into the' - ' Bay nodes.') -@utils.arg('--external-network-id', - required=True, - metavar='', - help='The external Neutron network ID to connect to this bay' - ' model.') -@utils.arg('--coe', - required=True, - metavar='', - help='Specify the Container Orchestration Engine to use.') -@utils.arg('--fixed-network', - metavar='', - help='The private Neutron network name to connect to this bay' - ' model.') -@utils.arg('--network-driver', - metavar='', - help='The network driver name for instantiating container' - ' networks.') -@utils.arg('--ssh-authorized-key', - metavar='', - help='The SSH authorized key to use') -@utils.arg('--dns-nameserver', - metavar='', - default='8.8.8.8', - help='The DNS nameserver to use for this Bay.') -@utils.arg('--flavor-id', - metavar='', - default='m1.medium', - help='The nova flavor id to use when launching the bay.') -@utils.arg('--master-flavor-id', - metavar='', - help='The nova flavor id to use when launching the master node ' - 'of the bay.') -@utils.arg('--docker-volume-size', - metavar='', - help='Specify the size of the docker volume to use.') -@utils.arg('--http-proxy', - metavar='', - help='The http_proxy address to use for nodes in bay.') -@utils.arg('--https-proxy', - metavar='', - help='The https_proxy address to use for nodes in bay.') -@utils.arg('--no-proxy', - metavar='', - help='The no_proxy address to use for nodes in bay.') -@utils.arg('--labels', metavar='', - action='append', default=[], - help='Arbitrary labels in the form of key=value pairs ' - 'to associate with a baymodel. ' - 'May be used multiple times.') -@utils.arg('--tls-disabled', - action='store_true', default=False, - help='Disable TLS in the Bay.') -@utils.arg('--public', - action='store_true', default=False, - help='Make baymodel public.') -def do_baymodel_create(cs, args): - """Create a baymodel.""" - opts = {} - opts['name'] = args.name - opts['flavor_id'] = args.flavor_id - opts['master_flavor_id'] = args.master_flavor_id - opts['image_id'] = args.image_id - opts['keypair_id'] = args.keypair_id - opts['external_network_id'] = args.external_network_id - opts['fixed_network'] = args.fixed_network - opts['network_driver'] = args.network_driver - opts['dns_nameserver'] = args.dns_nameserver - opts['docker_volume_size'] = args.docker_volume_size - opts['ssh_authorized_key'] = args.ssh_authorized_key - opts['coe'] = args.coe - opts['http_proxy'] = args.http_proxy - opts['https_proxy'] = args.https_proxy - opts['no_proxy'] = args.no_proxy - opts['labels'] = magnum_utils.format_labels(args.labels) - opts['tls_disabled'] = args.tls_disabled - opts['public'] = args.public - - baymodel = cs.baymodels.create(**opts) - _show_baymodel(baymodel) - - -@utils.arg('baymodels', - metavar='', - nargs='+', - help='ID or name of the (baymodel)s to delete.') -def do_baymodel_delete(cs, args): - """Delete specified baymodel.""" - for baymodel in args.baymodels: - try: - cs.baymodels.delete(baymodel) - except Exception as e: - print("Delete for baymodel %(baymodel)s failed: %(e)s" % - {'baymodel': baymodel, 'e': e}) - - -@utils.arg('baymodel', - metavar='', - help='ID of the baymodel to show.') -def do_baymodel_show(cs, args): - """Show details about the given baymodel.""" - baymodel = cs.baymodels.get(args.baymodel) - _show_baymodel(baymodel) - - -def do_baymodel_list(cs, args): - """Print a list of bay models.""" - nodes = cs.baymodels.list() - columns = ('uuid', 'name') - utils.print_list(nodes, columns, - {'versions': _print_list_field('versions')}) - - -@utils.arg('--bay', - required=True, - metavar='', - help='ID or name of the bay.') -def do_ca_show(cs, args): - """Show details about the CA certificate for a bay.""" - bay = cs.bays.get(args.bay) - if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: - print('Bay status for %s is: %s. We can not create a %s there' - ' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % - (bay.uuid, bay.status, 'certificate')) - return - - opts = { - 'bay_uuid': bay.uuid - } - - cert = cs.certificates.get(**opts) - _show_cert(cert) - - -@utils.arg('--csr', - metavar='', - help='File path of the csr file to send to Magnum to get signed.') -@utils.arg('--bay', - required=True, - metavar='', - help='ID or name of the bay.') -def do_ca_sign(cs, args): - """Generate the CA certificate for a bay.""" - bay = cs.bays.get(args.bay) - if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: - print('Bay status for %s is: %s. We can not create a %s there' - ' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % - (bay.uuid, bay.status, 'certificate')) - return - - opts = { - 'bay_uuid': bay.uuid - } - - if args.csr is None or not os.path.isfile(args.csr): - print('A CSR must be provided.') - return - - with open(args.csr, 'r') as f: - opts['csr'] = f.read() - - cert = cs.certificates.create(**opts) - _show_cert(cert) - - -@utils.arg('baymodel', metavar='', help="UUID or name of baymodel") -@utils.arg( - 'op', - metavar='', - choices=['add', 'replace', 'remove'], - help="Operations: 'add', 'replace' or 'remove'") -@utils.arg( - 'attributes', - metavar='', - nargs='+', - action='append', - default=[], - help="Attributes to add/replace or remove " - "(only PATH is necessary on remove)") -def do_baymodel_update(cs, args): - """Updates one or more baymodel attributes.""" - patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) - p = patch[0] - if p['path'] == '/manifest' and os.path.isfile(p['value']): - with open(p['value'], 'r') as f: - p['value'] = f.read() - - baymodel = cs.baymodels.update(args.baymodel, patch) - _show_baymodel(baymodel) - - -def do_node_list(cs, args): - """Print a list of configured nodes.""" - nodes = cs.nodes.list() - columns = ('uuid', 'type', 'image_id') - utils.print_list(nodes, columns, - {'versions': _print_list_field('versions')}) - - -@utils.arg('--type', - metavar='', - help='Type of node to create (virt or bare).') -@utils.arg('--image-id', - metavar='', - help='The name or UUID of the base image to use for the node.') -def do_node_create(cs, args): - """Create a node.""" - opts = {} - opts['type'] = args.type - opts['image_id'] = args.image_id - - node = cs.nodes.create(**opts) - _show_node(node) - - -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_pod_list(cs, args): - """Print a list of registered pods.""" - pods = cs.pods.list(args.bay) - columns = ('uuid', 'name') - utils.print_list(pods, columns, - {'versions': _print_list_field('versions')}) - - -@utils.arg('--manifest-url', - metavar='', - help='Name/URL of the pod file to use for creating PODs.') -@utils.arg('--manifest', - metavar='', - help='File path of the pod file to use for creating PODs.') -@utils.arg('--bay', - required=True, - metavar='', - help='ID or name of the bay.') -def do_pod_create(cs, args): - """Create a pod.""" - bay = cs.bays.get(args.bay) - if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: - print('Bay status for %s is: %s. We can not create a %s there' - ' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % - (bay.uuid, bay.status, "pod")) - return - opts = {} - opts['manifest_url'] = args.manifest_url - opts['bay_uuid'] = bay.uuid - - if args.manifest is not None and os.path.isfile(args.manifest): - with open(args.manifest, 'r') as f: - opts['manifest'] = f.read() - - node = cs.pods.create(**opts) - _show_pod(node) - pass - - -@utils.arg('pod', metavar='', help="UUID or name of pod") -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -@utils.arg( - 'op', - metavar='', - choices=['add', 'replace', 'remove'], - help="Operations: 'add', 'replace' or 'remove'") -@utils.arg( - 'attributes', - metavar='', - nargs='+', - action='append', - default=[], - help="Attributes to add/replace or remove " - "(only PATH is necessary on remove)") -def do_pod_update(cs, args): - """Update information about the given pod.""" - patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) - p = patch[0] - if p['path'] == '/manifest' and os.path.isfile(p['value']): - with open(p['value'], 'r') as f: - p['value'] = f.read() - - pod = cs.pods.update(args.pod, args.bay, patch) - _show_pod(pod) - - -@utils.arg('pods', - metavar='', - nargs='+', - help='ID or name of the (pod)s to delete.') -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_pod_delete(cs, args): - """Delete specified pod.""" - for pod in args.pods: - try: - cs.pods.delete(pod, args.bay) - except Exception as e: - print("Delete for pod %(pod)s failed: %(e)s" % - {'pod': pod, 'e': e}) - pass - - -@utils.arg('pod', - metavar='', - help='ID or name of the pod to show.') -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_pod_show(cs, args): - """Show details about the given pod.""" - pod = cs.pods.get(args.pod, args.bay) - _show_pod(pod) - - -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_rc_list(cs, args): - """Print a list of registered replication controllers.""" - rcs = cs.rcs.list(args.bay) - columns = ('uuid', 'name') - utils.print_list(rcs, columns, - {'versions': _print_list_field('versions')}) - - -@utils.arg('--manifest-url', - metavar='', - help='Name/URL of the replication controller file to use for ' - 'creating replication controllers.') -@utils.arg('--manifest', - metavar='', - help='File path of the replication controller file to use for ' - 'creating replication controllers.') -@utils.arg('--bay', - required=True, - metavar='', - help='ID or name of the bay.') -def do_rc_create(cs, args): - """Create a replication controller.""" - bay = cs.bays.get(args.bay) - if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: - print('Bay status for %s is: %s. We can not create a ' - 'replication controller in bay until the status ' - 'is CREATE_COMPLETE or UPDATE_COMPLETE.' % - (args.bay, bay.status)) - return - - opts = {} - opts['manifest_url'] = args.manifest_url - opts['bay_uuid'] = bay.uuid - - if args.manifest is not None and os.path.isfile(args.manifest): - with open(args.manifest, 'r') as f: - opts['manifest'] = f.read() - - rc = cs.rcs.create(**opts) - _show_rc(rc) - - -@utils.arg('rc', metavar='', help="UUID or name of replication controller") -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -@utils.arg( - 'op', - metavar='', - choices=['add', 'replace', 'remove'], - help="Operations: 'add', 'replace' or 'remove'") -@utils.arg( - 'attributes', - metavar='', - nargs='+', - action='append', - default=[], - help="Attributes to add/replace or remove " - "(only PATH is necessary on remove)") -def do_rc_update(cs, args): - """Update information about the given replication controller.""" - patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) - p = patch[0] - if p['path'] == '/manifest' and os.path.isfile(p['value']): - with open(p['value'], 'r') as f: - p['value'] = f.read() - - rc = cs.rcs.update(args.rc, args.bay, patch) - _show_rc(rc) - - -@utils.arg('rcs', - metavar='', - nargs='+', - help='ID or name of the replication (controller)s to delete.') -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_rc_delete(cs, args): - """Delete specified replication controller.""" - for rc in args.rcs: - try: - cs.rcs.delete(rc, args.bay) - except Exception as e: - print("Delete for rc %(rc)s failed: %(e)s" % - {'rc': rc, 'e': e}) - - -@utils.arg('rc', - metavar='', - help='ID or name of the replication controller to show.') -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_rc_show(cs, args): - """Show details about the given replication controller.""" - rc = cs.rcs.get(args.rc, args.bay) - _show_rc(rc) - - -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_coe_service_list(cs, args): - """Print a list of coe services.""" - services = cs.services.list(args.bay) - columns = ('uuid', 'name', 'bay_uuid') - utils.print_list(services, columns, - {'versions': _print_list_field('versions')}) - - -def do_service_list(cs, args): - """Print a list of magnum services.""" - mservices = cs.mservices.list() - columns = ('id', 'host', 'binary', 'state') - utils.print_list(mservices, columns, - {'versions': _print_list_field('versions')}) - - -@utils.arg('--manifest-url', - metavar='', - help='Name/URL of the serivce file to use for creating services.') -@utils.arg('--manifest', - metavar='', - help='File path of the service file to use for creating services.') -@utils.arg('--bay', - required=True, - metavar='', - help='Id or name of the bay.') -def do_coe_service_create(cs, args): - """Create a coe service.""" - bay = cs.bays.get(args.bay) - if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: - print('Bay status for %s is: %s. We can not create a service in bay ' - 'until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % - (args.bay, bay.status)) - return - - opts = {} - opts['manifest_url'] = args.manifest_url - opts['bay_uuid'] = bay.uuid - - if args.manifest is not None and os.path.isfile(args.manifest): - with open(args.manifest, 'r') as f: - opts['manifest'] = f.read() - - service = cs.services.create(**opts) - _show_coe_service(service) - - -@utils.arg('service', metavar='', help="UUID or name of service") -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -@utils.arg( - 'op', - metavar='', - choices=['add', 'replace', 'remove'], - help="Operations: 'add', 'replace' or 'remove'") -@utils.arg( - 'attributes', - metavar='', - nargs='+', - action='append', - default=[], - help="Attributes to add/replace or remove " - "(only PATH is necessary on remove)") -def do_coe_service_update(cs, args): - """Update information about the given coe service.""" - patch = magnum_utils.args_array_to_patch(args.op, args.attributes[0]) - p = patch[0] - if p['path'] == '/manifest' and os.path.isfile(p['value']): - with open(p['value'], 'r') as f: - p['value'] = f.read() - - service = cs.services.update(args.service, args.bay, patch) - _show_coe_service(service) - - -@utils.arg('services', - metavar='', - nargs='+', - help='ID or name of the (service)s to delete.') -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_coe_service_delete(cs, args): - """Delete specified coe service(s).""" - for service in args.services: - try: - cs.services.delete(service, args.bay) - except Exception as e: - print("Delete for service %(service)s failed: %(e)s" % - {'service': service, 'e': e}) - - -@utils.arg('service', - metavar='', - help='ID or name of the service to show.') -@utils.arg('bay', metavar='', help="UUID or Name of Bay") -def do_coe_service_show(cs, args): - """Show details about the given coe service.""" - service = cs.services.get(args.service, args.bay) - _show_coe_service(service) - - -# -# Containers - -@utils.arg('--name', - metavar='', - help='name of the container') -@utils.arg('--image', - required=True, - metavar='', - help='name or ID of the image') -@utils.arg('--bay', - required=True, - metavar='', - help='ID or name of the bay.') -@utils.arg('--command', - metavar='', - help='Send command to the container') -@utils.arg('--memory', - metavar='', - help='The container memory size (format: , ' - 'where unit = b, k, m or g)') -def do_container_create(cs, args): - """Create a container.""" - bay = cs.bays.get(args.bay) - if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']: - print('Bay status for %s is: %s. We can not create a %s there' - ' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' % - (bay.uuid, bay.status, "pod")) - return - opts = {} - opts['name'] = args.name - opts['image'] = args.image - opts['bay_uuid'] = bay.uuid - opts['command'] = args.command - opts['memory'] = args.memory - _show_container(cs.containers.create(**opts)) - - -def do_container_list(cs, args): - """Print a list of available containers.""" - containers = cs.containers.list() - columns = ('uuid', 'name', 'status') - utils.print_list(containers, columns, - {'versions': _print_list_field('versions')}) - - -@utils.arg('containers', - metavar='', - nargs='+', - help='ID or name of the (container)s to delete.') -def do_container_delete(cs, args): - """Delete specified containers.""" - for container in args.containers: - try: - cs.containers.delete(container) - except Exception as e: - print("Delete for container %(container)s failed: %(e)s" % - {'container': container, 'e': e}) - - -@utils.arg('container', - metavar='', - help='ID or name of the container to show.') -@utils.arg('--json', - action='store_true', - default=False, - help='Print JSON representation of the container.') -def do_container_show(cs, args): - """Show details of a container.""" - container = cs.containers.get(args.container) - if args.json: - print(json.dumps(container._info)) - else: - _show_container(container) - - -@utils.arg('containers', - metavar='', - nargs='+', - help='ID or name of the (container)s to start.') -def do_container_reboot(cs, args): - """Reboot specified containers.""" - for container in args.containers: - try: - cs.containers.reboot(container) - except Exception as e: - print("Reboot for container %(container)s failed: %(e)s" % - {'container': container, 'e': e}) - - -@utils.arg('containers', - metavar='', - nargs='+', - help='ID or name of the (container)s to start.') -def do_container_stop(cs, args): - """Stop specified containers.""" - for container in args.containers: - try: - cs.containers.stop(container) - except Exception as e: - print("Stop for container %(container)s failed: %(e)s" % - {'container': container, 'e': e}) - - -@utils.arg('containers', - metavar='', - nargs='+', - help='ID of the (container)s to start.') -def do_container_start(cs, args): - """Start specified containers.""" - for container in args.containers: - try: - cs.containers.start(container) - except Exception as e: - print("Start for container %(container)s failed: %(e)s" % - {'container': container, 'e': e}) - - -@utils.arg('containers', - metavar='', - nargs='+', - help='ID or name of the (container)s to start.') -def do_container_pause(cs, args): - """Pause specified containers.""" - for container in args.containers: - try: - cs.containers.pause(container) - except Exception as e: - print("Pause for container %(container)s failed: %(e)s" % - {'container': container, 'e': e}) - - -@utils.arg('containers', - metavar='', - nargs='+', - help='ID or name of the (container)s to start.') -def do_container_unpause(cs, args): - """Unpause specified containers.""" - for container in args.containers: - try: - cs.containers.unpause(container) - except Exception as e: - print("Unpause for container %(container)s failed: %(e)s" % - {'container': container, 'e': e}) - - -@utils.arg('container', - metavar='', - help='ID or name of the container to start.') -def do_container_logs(cs, args): - """Get logs of a container.""" - logs = cs.containers.logs(args.container) - print(logs) - - -@utils.arg('container', - metavar='', - help='ID or name of the container to start.') -@utils.arg('--command', - required=True, - metavar='', - help='The command to execute') -def do_container_exec(cs, args): - """Execute command in a container.""" - output = cs.containers.execute(args.container, args.command) - print(output) +from magnumclient.v1 import baymodels_shell +from magnumclient.v1 import bays_shell +from magnumclient.v1 import certificates_shell +from magnumclient.v1 import containers_shell +from magnumclient.v1 import mservices_shell +from magnumclient.v1 import nodes_shell +from magnumclient.v1 import pods_shell +from magnumclient.v1 import replicationcontrollers_shell +from magnumclient.v1 import services_shell + +COMMAND_MODULES = [ + baymodels_shell, + bays_shell, + certificates_shell, + containers_shell, + mservices_shell, + nodes_shell, + pods_shell, + replicationcontrollers_shell, + services_shell, +]