Remove k8s pods, rcs, svc and container API calls
Magnum supports multiple COEs however it contains APIs that only work with Kubernetes. We will allow additional API extensions for specific bay drivers to allow access to the k8s APIs through Magnum. This will allow us to support multiple COEs without having to compromise the container API to the lowest common denominator between COEs. Change-Id: Ic6927f77f413f5202a3dd160ff809c7ec057d3b5
This commit is contained in:
@@ -88,7 +88,6 @@ class ShellTest(utils.TestCase):
|
||||
def test_help(self):
|
||||
required = [
|
||||
'.*?^usage: ',
|
||||
'.*?^\s+container-stop\s+Stop specified container.',
|
||||
'.*?^See "magnum help COMMAND" for help on a specific command',
|
||||
]
|
||||
stdout, stderr = self.shell('help')
|
||||
@@ -110,7 +109,6 @@ class ShellTest(utils.TestCase):
|
||||
def test_help_no_options(self):
|
||||
required = [
|
||||
'.*?^usage: ',
|
||||
'.*?^\s+container-stop\s+Stop specified container.',
|
||||
'.*?^See "magnum help COMMAND" for help on a specific command',
|
||||
]
|
||||
stdout, stderr = self.shell('')
|
||||
@@ -122,7 +120,6 @@ class ShellTest(utils.TestCase):
|
||||
stdout, stderr = self.shell('bash-completion')
|
||||
# just check we have some output
|
||||
required = [
|
||||
'.*--json',
|
||||
'.*help',
|
||||
'.*bay-show',
|
||||
'.*--bay']
|
||||
|
||||
@@ -32,9 +32,6 @@ CERT2 = {
|
||||
}
|
||||
CREATE_CERT = {'bay_uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a53',
|
||||
'csr': 'fake-csr'}
|
||||
UPDATED_POD = copy.deepcopy(CERT1)
|
||||
NEW_DESCR = 'new-description'
|
||||
UPDATED_POD['description'] = NEW_DESCR
|
||||
|
||||
fake_responses = {
|
||||
'/v1/certificates':
|
||||
@@ -80,7 +77,7 @@ class CertificateManagerTest(testtools.TestCase):
|
||||
self.assertEqual(CERT2['pem'], cert.pem)
|
||||
self.assertEqual(CERT2['csr'], cert.csr)
|
||||
|
||||
def test_pod_create_fail(self):
|
||||
def test_create_fail(self):
|
||||
create_cert_fail = copy.deepcopy(CREATE_CERT)
|
||||
create_cert_fail["wrong_key"] = "wrong"
|
||||
self.assertRaisesRegexp(exceptions.InvalidAttribute,
|
||||
|
||||
@@ -1,432 +0,0 @@
|
||||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# 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 copy
|
||||
|
||||
import testtools
|
||||
from testtools import matchers
|
||||
|
||||
from magnumclient import exceptions
|
||||
from magnumclient.tests import utils
|
||||
from magnumclient.v1 import containers
|
||||
|
||||
|
||||
CONTAINER1 = {'id': 123,
|
||||
'uuid': '66666666-7777-8888-9999-000000000001',
|
||||
'bay_uuid': '25d5d872-1f4e-4134-ae15-c5fa38cb09a3',
|
||||
'name': 'container1',
|
||||
'image': 'c-image1',
|
||||
'command': 'c-command1',
|
||||
'memory': '512m',
|
||||
}
|
||||
CONTAINER2 = {'id': 124,
|
||||
'uuid': '66666666-7777-8888-9999-000000000002',
|
||||
'bay_uuid': '25d5d872-1f4e-4134-ae15-c5fa38cb09a3',
|
||||
'name': 'container1',
|
||||
'image': 'c-image2',
|
||||
'command': 'c-command2',
|
||||
'memory': '2g',
|
||||
}
|
||||
|
||||
CREATE_CONTAINER = copy.deepcopy(CONTAINER1)
|
||||
del CREATE_CONTAINER['id']
|
||||
del CREATE_CONTAINER['uuid']
|
||||
|
||||
UPDATED_CONTAINER = copy.deepcopy(CONTAINER1)
|
||||
NEW_NAME = 'newcontainer'
|
||||
UPDATED_CONTAINER['name'] = NEW_NAME
|
||||
|
||||
fake_responses = {
|
||||
'/v1/containers':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'containers': [CONTAINER1, CONTAINER2]},
|
||||
),
|
||||
'POST': (
|
||||
{},
|
||||
CREATE_CONTAINER,
|
||||
),
|
||||
},
|
||||
'/v1/containers/?bay_ident=25d5d872-1f4e-4134-ae15-c5fa38cb09a3':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'containers': [CONTAINER1, CONTAINER2]},
|
||||
),
|
||||
'POST': (
|
||||
{},
|
||||
CREATE_CONTAINER,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s' % CONTAINER1['id']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
CONTAINER1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_CONTAINER,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s' % CONTAINER1['name']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
CONTAINER1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_CONTAINER,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/start' % CONTAINER1['id']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/start' % CONTAINER1['name']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/stop' % CONTAINER1['id']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/stop' % CONTAINER1['name']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/pause' % CONTAINER1['id']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/pause' % CONTAINER1['name']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/unpause' % CONTAINER1['id']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/unpause' % CONTAINER1['name']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/reboot' % CONTAINER1['id']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/reboot' % CONTAINER1['name']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
CONTAINER1,
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/logs' % CONTAINER1['id']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'output': 'login now'},
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/logs' % CONTAINER1['name']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'output': 'login now'},
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/execute?command=ls' % CONTAINER1['id']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
{'output': '/home'},
|
||||
),
|
||||
},
|
||||
'/v1/containers/%s/execute?command=ls' % CONTAINER1['name']:
|
||||
{
|
||||
'PUT': (
|
||||
{},
|
||||
{'output': '/home'},
|
||||
),
|
||||
},
|
||||
'/v1/containers/?limit=2':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'containers': [CONTAINER1, CONTAINER2]},
|
||||
),
|
||||
},
|
||||
'/v1/containers/?marker=%s' % CONTAINER2['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'containers': [CONTAINER1, CONTAINER2]},
|
||||
),
|
||||
},
|
||||
'/v1/containers/?limit=2&marker=%s' % CONTAINER2['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'containers': [CONTAINER1, CONTAINER2]},
|
||||
),
|
||||
},
|
||||
'/v1/containers/?sort_dir=asc':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'containers': [CONTAINER1, CONTAINER2]},
|
||||
),
|
||||
},
|
||||
'/v1/containers/?sort_key=uuid':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'containers': [CONTAINER1, CONTAINER2]},
|
||||
),
|
||||
},
|
||||
'/v1/containers/?sort_key=uuid&sort_dir=desc':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'containers': [CONTAINER2, CONTAINER1]},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class ContainerManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ContainerManagerTest, self).setUp()
|
||||
self.api = utils.FakeAPI(fake_responses)
|
||||
self.mgr = containers.ContainerManager(self.api)
|
||||
|
||||
def test_container_list(self):
|
||||
containers = self.mgr.list()
|
||||
expect = [
|
||||
('GET', '/v1/containers', {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertThat(containers, matchers.HasLength(2))
|
||||
|
||||
def test_container_list_with_bay(self):
|
||||
containers = self.mgr.list(
|
||||
bay_ident='25d5d872-1f4e-4134-ae15-c5fa38cb09a3')
|
||||
expect = [
|
||||
('GET', '/v1/containers/?bay_ident=25d5d872-1f4e-4134'
|
||||
'-ae15-c5fa38cb09a3', {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertThat(containers, matchers.HasLength(2))
|
||||
|
||||
def _test_container_list_with_filters(
|
||||
self, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None,
|
||||
detail=False, expect=[]):
|
||||
containers_filter = self.mgr.list(limit=limit, marker=marker,
|
||||
sort_key=sort_key,
|
||||
sort_dir=sort_dir,
|
||||
detail=detail)
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertThat(containers_filter, matchers.HasLength(2))
|
||||
|
||||
def test_container_list_with_limit(self):
|
||||
expect = [
|
||||
('GET', '/v1/containers/?limit=2', {}, None),
|
||||
]
|
||||
self._test_container_list_with_filters(
|
||||
limit=2,
|
||||
expect=expect)
|
||||
|
||||
def test_container_list_with_marker(self):
|
||||
expect = [
|
||||
('GET', '/v1/containers/?marker=%s' % CONTAINER2['uuid'],
|
||||
{}, None),
|
||||
]
|
||||
self._test_container_list_with_filters(
|
||||
marker=CONTAINER2['uuid'],
|
||||
expect=expect)
|
||||
|
||||
def test_container_list_with_marker_limit(self):
|
||||
expect = [
|
||||
('GET', '/v1/containers/?limit=2&marker=%s' % CONTAINER2['uuid'],
|
||||
{}, None),
|
||||
]
|
||||
self._test_container_list_with_filters(
|
||||
limit=2, marker=CONTAINER2['uuid'],
|
||||
expect=expect)
|
||||
|
||||
def test_container_list_with_sort_dir(self):
|
||||
expect = [
|
||||
('GET', '/v1/containers/?sort_dir=asc',
|
||||
{}, None),
|
||||
]
|
||||
self._test_container_list_with_filters(
|
||||
sort_dir='asc',
|
||||
expect=expect)
|
||||
|
||||
def test_container_list_with_sort_key(self):
|
||||
expect = [
|
||||
('GET', '/v1/containers/?sort_key=uuid',
|
||||
{}, None),
|
||||
]
|
||||
self._test_container_list_with_filters(
|
||||
sort_key='uuid',
|
||||
expect=expect)
|
||||
|
||||
def test_container_list_with_sort_key_dir(self):
|
||||
expect = [
|
||||
('GET', '/v1/containers/?sort_key=uuid&sort_dir=desc',
|
||||
{}, None),
|
||||
]
|
||||
self._test_container_list_with_filters(
|
||||
sort_key='uuid', sort_dir='desc',
|
||||
expect=expect)
|
||||
|
||||
def test_container_show(self):
|
||||
container = self.mgr.get(CONTAINER1['id'])
|
||||
expect = [
|
||||
('GET', '/v1/containers/%s' % CONTAINER1['id'], {}, None)
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(CONTAINER1['name'], container.name)
|
||||
self.assertEqual(CONTAINER1['image'], container.image)
|
||||
self.assertEqual(CONTAINER1['command'], container.command)
|
||||
self.assertEqual(CONTAINER1['memory'], container.memory)
|
||||
|
||||
def test_container_create(self):
|
||||
container = self.mgr.create(**CREATE_CONTAINER)
|
||||
expect = [
|
||||
('POST', '/v1/containers', {}, CREATE_CONTAINER),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(container)
|
||||
|
||||
def test_container_create_fail(self):
|
||||
CREATE_CONTAINER_FAIL = copy.deepcopy(CREATE_CONTAINER)
|
||||
CREATE_CONTAINER_FAIL["wrong_key"] = "wrong"
|
||||
self.assertRaisesRegexp(exceptions.InvalidAttribute,
|
||||
("Key must be in %s" %
|
||||
','.join(containers.CREATION_ATTRIBUTES)),
|
||||
self.mgr.create, **CREATE_CONTAINER_FAIL)
|
||||
self.assertEqual([], self.api.calls)
|
||||
|
||||
def test_container_delete(self):
|
||||
container = self.mgr.delete(CONTAINER1['id'])
|
||||
expect = [
|
||||
('DELETE', '/v1/containers/%s' % CONTAINER1['id'], {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(container)
|
||||
|
||||
def test_container_start(self):
|
||||
container = self.mgr.start(CONTAINER1['id'])
|
||||
expect = [
|
||||
('PUT', '/v1/containers/%s/start' % CONTAINER1['id'],
|
||||
{'Content-Length': '0'}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(container)
|
||||
|
||||
def test_container_stop(self):
|
||||
container = self.mgr.stop(CONTAINER1['id'])
|
||||
expect = [
|
||||
('PUT', '/v1/containers/%s/stop' % CONTAINER1['id'],
|
||||
{'Content-Length': '0'}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(container)
|
||||
|
||||
def test_container_reboot(self):
|
||||
container = self.mgr.reboot(CONTAINER1['id'])
|
||||
expect = [
|
||||
('PUT', '/v1/containers/%s/reboot' % CONTAINER1['id'],
|
||||
{'Content-Length': '0'}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(container)
|
||||
|
||||
def test_container_pause(self):
|
||||
container = self.mgr.pause(CONTAINER1['id'])
|
||||
expect = [
|
||||
('PUT', '/v1/containers/%s/pause' % CONTAINER1['id'],
|
||||
{'Content-Length': '0'}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(container)
|
||||
|
||||
def test_container_unpause(self):
|
||||
container = self.mgr.unpause(CONTAINER1['id'])
|
||||
expect = [
|
||||
('PUT', '/v1/containers/%s/unpause' % CONTAINER1['id'],
|
||||
{'Content-Length': '0'}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(container)
|
||||
|
||||
def test_container_logs(self):
|
||||
logs = self.mgr.logs(CONTAINER1['id'])
|
||||
expect = [
|
||||
('GET', '/v1/containers/%s/logs' % CONTAINER1['id'],
|
||||
{'Content-Length': '0'}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual('login now', logs)
|
||||
|
||||
def test_container_execute(self):
|
||||
output = self.mgr.execute(CONTAINER1['id'], 'ls')
|
||||
expect = [
|
||||
('PUT', '/v1/containers/%s/execute?command=ls' % CONTAINER1['id'],
|
||||
{'Content-Length': '0'}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual('/home', output)
|
||||
@@ -1,236 +0,0 @@
|
||||
# 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.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_success_with_arg(self, mock_list):
|
||||
self._test_arg_success('container-list '
|
||||
'--marker some_uuid '
|
||||
'--limit 1 '
|
||||
'--sort-dir asc '
|
||||
'--sort-key uuid')
|
||||
self.assertTrue(mock_list.called)
|
||||
|
||||
@mock.patch('magnumclient.v1.containers.ContainerManager.list')
|
||||
def test_container_list_failure_invalid_arg(self, mock_list):
|
||||
_error_msg = [
|
||||
'.*?^usage: magnum container-list ',
|
||||
'.*?^error: argument --sort-dir: invalid choice: ',
|
||||
".*?^Try 'magnum help container-list' for more information."
|
||||
]
|
||||
self._test_arg_failure('container-list --sort-dir aaa', _error_msg)
|
||||
self.assertFalse(mock_list.called)
|
||||
|
||||
@mock.patch('magnumclient.v1.containers.ContainerManager.list')
|
||||
def test_container_list_success_with_bay(self, mock_list):
|
||||
self._test_arg_success('container-list --bay bay_uuid')
|
||||
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.bays.BayManager.get')
|
||||
@mock.patch('magnumclient.v1.containers.ContainerManager.create')
|
||||
def test_container_create_failure_invalid_bay_status(self, mock_create,
|
||||
mock_bay_get):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay.status = "CREATE_IN_PROGRESS"
|
||||
mock_bay_get.return_value = mock_bay
|
||||
self.assertRaises(exceptions.InvalidAttribute, self._test_arg_failure,
|
||||
'container-create '
|
||||
'--image test-image '
|
||||
'--bay test-bay',
|
||||
self._bay_status_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)
|
||||
@@ -1,193 +0,0 @@
|
||||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# 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 copy
|
||||
|
||||
import testtools
|
||||
from testtools import matchers
|
||||
|
||||
from magnumclient import exceptions
|
||||
from magnumclient.tests import utils
|
||||
from magnumclient.v1 import pods
|
||||
|
||||
|
||||
POD1 = {'id': 123,
|
||||
'uuid': '66666666-7777-8888-9999-000000000000',
|
||||
'name': 'pod1',
|
||||
'desc': "desc",
|
||||
'bay_uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a52',
|
||||
'images': ['image1', 'image2'],
|
||||
'labels': {'foo': 'bar'},
|
||||
'status': 'Running'
|
||||
}
|
||||
POD2 = {'id': 124,
|
||||
'uuid': '66666666-7777-8888-9999-000000000001',
|
||||
'name': 'pod1',
|
||||
'desc': "desc",
|
||||
'bay_uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a53',
|
||||
'images': ['image1', 'image2'],
|
||||
'labels': {'foo': 'bar'},
|
||||
'status': 'Running'
|
||||
}
|
||||
CREATE_POD = {'manifest_url': 'file:///a/b.json'}
|
||||
UPDATED_POD = copy.deepcopy(POD1)
|
||||
NEW_DESCR = 'new-description'
|
||||
UPDATED_POD['description'] = NEW_DESCR
|
||||
|
||||
fake_responses = {
|
||||
'/v1/pods':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'pods': [POD1, POD2]},
|
||||
),
|
||||
'POST': (
|
||||
{},
|
||||
CREATE_POD,
|
||||
),
|
||||
},
|
||||
'/v1/pods/?bay_ident=%s' % (POD1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'pods': [POD1, POD2]},
|
||||
),
|
||||
'POST': (
|
||||
{},
|
||||
CREATE_POD,
|
||||
),
|
||||
},
|
||||
'/v1/pods/%s/?bay_ident=%s' % (POD1['id'], POD1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
POD1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_POD,
|
||||
),
|
||||
},
|
||||
'/v1/pods/%s/?bay_ident=%s' % (POD1['name'], POD1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
POD1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_POD,
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class PodManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PodManagerTest, self).setUp()
|
||||
self.api = utils.FakeAPI(fake_responses)
|
||||
self.mgr = pods.PodManager(self.api)
|
||||
|
||||
def test_pod_list(self):
|
||||
pods = self.mgr.list(POD1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/pods/?bay_ident=%s' % (POD1['bay_uuid']), {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertThat(pods, matchers.HasLength(2))
|
||||
|
||||
def test_pod_show_by_id(self):
|
||||
pod = self.mgr.get(POD1['id'], POD1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/pods/%s/?bay_ident=%s' % (POD1['id'],
|
||||
POD1['bay_uuid']), {},
|
||||
None)
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(POD1['name'], pod.name)
|
||||
self.assertEqual(POD1['bay_uuid'], pod.bay_uuid)
|
||||
self.assertEqual(POD1['desc'], pod.desc)
|
||||
|
||||
def test_pod_show_by_name(self):
|
||||
pod = self.mgr.get(POD1['name'], POD1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/pods/%s/?bay_ident=%s' % (POD1['name'],
|
||||
POD1['bay_uuid']),
|
||||
{}, None)
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(POD1['name'], pod.name)
|
||||
self.assertEqual(POD1['bay_uuid'], pod.bay_uuid)
|
||||
self.assertEqual(POD1['desc'], pod.desc)
|
||||
|
||||
def test_pod_create(self):
|
||||
pod = self.mgr.create(**CREATE_POD)
|
||||
expect = [
|
||||
('POST', '/v1/pods', {}, CREATE_POD),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(pod)
|
||||
|
||||
def test_pod_create_fail(self):
|
||||
CREATE_POD_FAIL = copy.deepcopy(CREATE_POD)
|
||||
CREATE_POD_FAIL["wrong_key"] = "wrong"
|
||||
self.assertRaisesRegexp(exceptions.InvalidAttribute,
|
||||
("Key must be in %s" %
|
||||
','.join(pods.CREATION_ATTRIBUTES)),
|
||||
self.mgr.create, **CREATE_POD_FAIL)
|
||||
self.assertEqual([], self.api.calls)
|
||||
|
||||
def test_pod_delete_by_id(self):
|
||||
pod = self.mgr.delete(POD1['id'], POD1['bay_uuid'])
|
||||
expect = [
|
||||
('DELETE', '/v1/pods/%s/?bay_ident=%s' % (POD1['id'],
|
||||
POD1['bay_uuid']),
|
||||
{}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(pod)
|
||||
|
||||
def test_pod_delete_by_name(self):
|
||||
pod = self.mgr.delete(POD1['name'], POD1['bay_uuid'])
|
||||
expect = [
|
||||
('DELETE', '/v1/pods/%s/?bay_ident=%s' % (POD1['name'],
|
||||
POD1['bay_uuid']),
|
||||
{}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(pod)
|
||||
|
||||
def test_pod_update(self):
|
||||
patch = {'op': 'replace',
|
||||
'value': NEW_DESCR,
|
||||
'path': '/description'}
|
||||
pod = self.mgr.update(id=POD1['id'],
|
||||
bay_ident=POD1['bay_uuid'],
|
||||
patch=patch)
|
||||
expect = [
|
||||
('PATCH', '/v1/pods/%s/?bay_ident=%s' % (POD1['id'],
|
||||
POD1['bay_uuid']),
|
||||
{}, patch),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(NEW_DESCR, pod.description)
|
||||
@@ -1,117 +0,0 @@
|
||||
# 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.get')
|
||||
@mock.patch('magnumclient.v1.pods.PodManager.list')
|
||||
def test_pod_list_success(self, mock_list, mock_get):
|
||||
mockbay = mock.MagicMock()
|
||||
mockbay.status = "CREATE_COMPLETE"
|
||||
mock_get.return_value = mockbay
|
||||
self._test_arg_success('pod-list --bay 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 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.list')
|
||||
def test_pod_list_failure_invalid_bay_status(self, mock_list, mock_get):
|
||||
mockbay = mock.MagicMock()
|
||||
mockbay.status = "CREATE_IN_PROGRESS"
|
||||
mock_get.return_value = mockbay
|
||||
self.assertRaises(exceptions.InvalidAttribute, self._test_arg_failure,
|
||||
'pod-list --bay bay_ident', self._bay_status_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.bays.BayManager.get')
|
||||
@mock.patch('magnumclient.v1.pods.PodManager.create')
|
||||
def test_pod_create_failure_invalid_bay_status(self, mock_list, mock_get):
|
||||
mockbay = mock.MagicMock()
|
||||
mockbay.status = "CREATE_IN_PROGRESS"
|
||||
mock_get.return_value = mockbay
|
||||
self.assertRaises(exceptions.InvalidAttribute, self._test_arg_failure,
|
||||
'pod-create --bay xxx '
|
||||
'--manifest test '
|
||||
'--manifest-url test_url',
|
||||
self._bay_status_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 --bay zzz')
|
||||
self.assertTrue(mock_delete.called)
|
||||
|
||||
@mock.patch('magnumclient.v1.pods.PodManager.delete')
|
||||
def test_pod_delete_failure_no_arg(self, mock_delete):
|
||||
self._test_arg_failure('pod-delete xxx', self._mandatory_arg_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 --bay 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 xxx', 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 --bay 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)
|
||||
@@ -1,185 +0,0 @@
|
||||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# 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 copy
|
||||
|
||||
import testtools
|
||||
from testtools import matchers
|
||||
|
||||
from magnumclient import exceptions
|
||||
from magnumclient.tests import utils
|
||||
from magnumclient.v1 import replicationcontrollers as rcs
|
||||
|
||||
|
||||
RC1 = {'id': 123,
|
||||
'uuid': '66666666-7777-8888-9999-000000000001',
|
||||
'name': 'rc1',
|
||||
'images': ['image1'],
|
||||
'bay_uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a51',
|
||||
'selector': {'name': 'bar1'},
|
||||
'replicas': 1
|
||||
}
|
||||
RC2 = {'id': 124,
|
||||
'uuid': '66666666-7777-8888-9999-000000000002',
|
||||
'name': 'rc2',
|
||||
'images': ['image2'],
|
||||
'bay_uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a52',
|
||||
'selector': {'name': 'bar2'},
|
||||
'replicas': 2
|
||||
}
|
||||
CREATE_RC = {'manifest_url': 'file:///a/b.json'}
|
||||
UPDATED_RC = copy.deepcopy(RC1)
|
||||
NEW_REPLICAS = 3
|
||||
UPDATED_RC['replicas'] = NEW_REPLICAS
|
||||
|
||||
fake_responses = {
|
||||
'/v1/rcs':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'rcs': [RC1, RC2]},
|
||||
),
|
||||
'POST': (
|
||||
{},
|
||||
CREATE_RC,
|
||||
),
|
||||
},
|
||||
'/v1/rcs/?bay_ident=%s' % (RC1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'rcs': [RC1, RC2]},
|
||||
),
|
||||
},
|
||||
'/v1/rcs/%s/?bay_ident=%s' % (RC1['id'], RC1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
RC1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_RC,
|
||||
),
|
||||
},
|
||||
'/v1/rcs/%s/?bay_ident=%s' % (RC1['name'], RC1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
RC1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_RC,
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class RCManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(RCManagerTest, self).setUp()
|
||||
self.api = utils.FakeAPI(fake_responses)
|
||||
self.mgr = rcs.ReplicationControllerManager(self.api)
|
||||
|
||||
def test_rc_list(self):
|
||||
rcs = self.mgr.list(RC1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/rcs/?bay_ident=%s' % (RC1['bay_uuid']), {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertThat(rcs, matchers.HasLength(2))
|
||||
|
||||
def test_rc_show_by_id(self):
|
||||
rc = self.mgr.get(RC1['id'], RC1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/rcs/%s/?bay_ident=%s' % (RC1['id'],
|
||||
RC1['bay_uuid']), {}, None)
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(RC1['name'], rc.name)
|
||||
self.assertEqual(RC1['bay_uuid'], rc.bay_uuid)
|
||||
self.assertEqual(RC1['replicas'], rc.replicas)
|
||||
|
||||
def test_rc_show_by_name(self):
|
||||
rc = self.mgr.get(RC1['name'], RC1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/rcs/%s/?bay_ident=%s' % (RC1['name'],
|
||||
RC1['bay_uuid']), {}, None)
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(RC1['name'], rc.name)
|
||||
self.assertEqual(RC1['bay_uuid'], rc.bay_uuid)
|
||||
self.assertEqual(RC1['replicas'], rc.replicas)
|
||||
|
||||
def test_rc_create(self):
|
||||
rc = self.mgr.create(**CREATE_RC)
|
||||
expect = [
|
||||
('POST', '/v1/rcs', {}, CREATE_RC),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(rc)
|
||||
|
||||
def test_rc_create_fail(self):
|
||||
CREATE_RC_FAIL = copy.deepcopy(CREATE_RC)
|
||||
CREATE_RC_FAIL["wrong_key"] = "wrong"
|
||||
self.assertRaisesRegexp(exceptions.InvalidAttribute,
|
||||
("Key must be in %s" %
|
||||
','.join(rcs.CREATION_ATTRIBUTES)),
|
||||
self.mgr.create, **CREATE_RC_FAIL)
|
||||
self.assertEqual([], self.api.calls)
|
||||
|
||||
def test_rc_delete_by_id(self):
|
||||
rc = self.mgr.delete(RC1['id'], RC1['bay_uuid'])
|
||||
expect = [
|
||||
('DELETE', '/v1/rcs/%s/?bay_ident=%s' % (RC1['id'],
|
||||
RC1['bay_uuid']),
|
||||
{}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(rc)
|
||||
|
||||
def test_rc_delete_by_name(self):
|
||||
rc = self.mgr.delete(RC1['name'], RC1['bay_uuid'])
|
||||
expect = [
|
||||
('DELETE', '/v1/rcs/%s/?bay_ident=%s' % (RC1['name'],
|
||||
RC1['bay_uuid']),
|
||||
{}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(rc)
|
||||
|
||||
def test_rc_update(self):
|
||||
patch = {'op': 'replace',
|
||||
'value': NEW_REPLICAS,
|
||||
'path': '/replicas'}
|
||||
rc = self.mgr.update(id=RC1['id'],
|
||||
bay_ident=RC1['bay_uuid'],
|
||||
patch=patch)
|
||||
expect = [
|
||||
('PATCH', '/v1/rcs/%s/?bay_ident=%s' % (RC1['id'],
|
||||
RC1['bay_uuid']), {},
|
||||
patch),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(NEW_REPLICAS, rc.replicas)
|
||||
@@ -1,132 +0,0 @@
|
||||
# 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.get')
|
||||
@mock.patch('magnumclient.v1.replicationcontrollers.'
|
||||
'ReplicationControllerManager.list')
|
||||
def test_rc_list_success(self, mock_list, mock_get):
|
||||
mockbay = mock.MagicMock()
|
||||
mockbay.status = "CREATE_COMPLETE"
|
||||
mock_get.return_value = mockbay
|
||||
self._test_arg_success('rc-list --bay 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 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.list')
|
||||
def test_rc_list_failure_invalid_bay_status(self, mock_list, mock_get):
|
||||
mockbay = mock.MagicMock()
|
||||
mockbay.status = "CREATE_IN_PROGRESS"
|
||||
mock_get.return_value = mockbay
|
||||
self.assertRaises(exceptions.InvalidAttribute, self._test_arg_failure,
|
||||
'rc-list --bay bay_ident', self._bay_status_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.bays.BayManager.get')
|
||||
@mock.patch('magnumclient.v1.replicationcontrollers.'
|
||||
'ReplicationControllerManager.create')
|
||||
def test_rc_create_failure_invalid_bay_status(self, mock_create, mock_get):
|
||||
mockbay = mock.MagicMock()
|
||||
mockbay.status = "CREATE_IN_PROGRESS"
|
||||
mock_get.return_value = mockbay
|
||||
self.assertRaises(exceptions.InvalidAttribute, self._test_arg_failure,
|
||||
'rc-create '
|
||||
'--bay xxx '
|
||||
'--manifest test '
|
||||
'--manifest-url test_url',
|
||||
self._bay_status_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 --bay zzz')
|
||||
self.assertTrue(mock_delete.called)
|
||||
|
||||
@mock.patch('magnumclient.v1.replicationcontrollers.'
|
||||
'ReplicationControllerManager.delete')
|
||||
def test_rc_delete_failure_no_arg(self, mock_delete):
|
||||
self._test_arg_failure('rc-delete xxx', self._mandatory_arg_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 --bay zzz')
|
||||
self.assertTrue(mock_show.called)
|
||||
self.assertEqual(1, mock_show.call_count)
|
||||
|
||||
@mock.patch('magnumclient.v1.replicationcontrollers.'
|
||||
'ReplicationControllerManager.get')
|
||||
def test_rc_show_failure_no_arg(self, mock_show):
|
||||
self._test_arg_failure('rc-show xxx', self._mandatory_arg_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 --bay 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 xxx', self._few_argument_error)
|
||||
self.assertFalse(mock_update.called)
|
||||
@@ -1,193 +0,0 @@
|
||||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# 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 copy
|
||||
|
||||
import testtools
|
||||
from testtools import matchers
|
||||
|
||||
from magnumclient import exceptions
|
||||
from magnumclient.tests import utils
|
||||
from magnumclient.v1 import services
|
||||
|
||||
|
||||
SERVICE1 = {'id': 123,
|
||||
'uuid': '66666666-7777-8888-9999-000000000001',
|
||||
'name': 'service1',
|
||||
'bay_uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a51',
|
||||
'selector': {'name': 'bar1'},
|
||||
'labels': {'name': 'foo1'},
|
||||
'ip': '10.0.0.3',
|
||||
'port': 8080
|
||||
}
|
||||
SERVICE2 = {'id': 124,
|
||||
'uuid': '66666666-7777-8888-9999-000000000002',
|
||||
'name': 'service2',
|
||||
'bay_uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a52',
|
||||
'selector': {'name': 'bar2'},
|
||||
'labels': {'name': 'foo2'},
|
||||
'ip': '10.0.0.4',
|
||||
'port': 8081
|
||||
}
|
||||
CREATE_SVC = {'manifest_url': 'file:///a/b.json'}
|
||||
UPDATED_SVC = copy.deepcopy(SERVICE1)
|
||||
NEW_SELECTOR = {'name': 'bar3'}
|
||||
UPDATED_SVC['selector'] = NEW_SELECTOR
|
||||
|
||||
fake_responses = {
|
||||
'/v1/services':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'services': [SERVICE1, SERVICE2]},
|
||||
),
|
||||
'POST': (
|
||||
{},
|
||||
CREATE_SVC,
|
||||
),
|
||||
},
|
||||
'/v1/services/?bay_ident=%s' % (SERVICE1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{'services': [SERVICE1, SERVICE2]},
|
||||
),
|
||||
'POST': (
|
||||
{},
|
||||
CREATE_SVC,
|
||||
),
|
||||
},
|
||||
'/v1/services/%s/?bay_ident=%s' % (SERVICE1['id'],
|
||||
SERVICE1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
SERVICE1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_SVC,
|
||||
),
|
||||
},
|
||||
'/v1/services/%s/?bay_ident=%s' % (SERVICE1['name'],
|
||||
SERVICE1['bay_uuid']):
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
SERVICE1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_SVC,
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class ServiceManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ServiceManagerTest, self).setUp()
|
||||
self.api = utils.FakeAPI(fake_responses)
|
||||
self.mgr = services.ServiceManager(self.api)
|
||||
|
||||
def test_coe_service_list(self):
|
||||
services = self.mgr.list(SERVICE1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/services/?bay_ident=%s' % (SERVICE1['bay_uuid']),
|
||||
{}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertThat(services, matchers.HasLength(2))
|
||||
|
||||
def test_coe_service_show_by_id(self):
|
||||
service = self.mgr.get(SERVICE1['id'], SERVICE1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/services/%s/?bay_ident=%s' % (SERVICE1['id'],
|
||||
SERVICE1['bay_uuid']),
|
||||
{}, None)
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(SERVICE1['name'], service.name)
|
||||
self.assertEqual(SERVICE1['bay_uuid'], service.bay_uuid)
|
||||
self.assertEqual(SERVICE1['ip'], service.ip)
|
||||
|
||||
def test_coe_service_show_by_name(self):
|
||||
service = self.mgr.get(SERVICE1['name'], SERVICE1['bay_uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/services/%s/?bay_ident=%s' % (SERVICE1['name'],
|
||||
SERVICE1['bay_uuid']),
|
||||
{}, None)
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(SERVICE1['name'], service.name)
|
||||
self.assertEqual(SERVICE1['bay_uuid'], service.bay_uuid)
|
||||
self.assertEqual(SERVICE1['ip'], service.ip)
|
||||
|
||||
def test_coe_service_create(self):
|
||||
service = self.mgr.create(**CREATE_SVC)
|
||||
expect = [
|
||||
('POST', '/v1/services', {}, CREATE_SVC),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(service)
|
||||
|
||||
def test_coe_service_create_fail(self):
|
||||
CREATE_SVC_FAIL = copy.deepcopy(CREATE_SVC)
|
||||
CREATE_SVC_FAIL["wrong_key"] = "wrong"
|
||||
self.assertRaisesRegexp(exceptions.InvalidAttribute,
|
||||
("Key must be in %s" %
|
||||
','.join(services.CREATION_ATTRIBUTES)),
|
||||
self.mgr.create, **CREATE_SVC_FAIL)
|
||||
self.assertEqual([], self.api.calls)
|
||||
|
||||
def test_coe_service_delete_by_id(self):
|
||||
service = self.mgr.delete(SERVICE1['id'], SERVICE1['bay_uuid'])
|
||||
expect = [
|
||||
('DELETE', '/v1/services/%s/?bay_ident=%s' % (
|
||||
SERVICE1['id'], SERVICE1['bay_uuid']), {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(service)
|
||||
|
||||
def test_coe_service_delete_by_name(self):
|
||||
service = self.mgr.delete(SERVICE1['name'], SERVICE1['bay_uuid'])
|
||||
expect = [
|
||||
('DELETE', '/v1/services/%s/?bay_ident=%s' % (
|
||||
SERVICE1['name'], SERVICE1['bay_uuid']), {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(service)
|
||||
|
||||
def test_coe_service_update(self):
|
||||
patch = {'op': 'replace',
|
||||
'value': NEW_SELECTOR,
|
||||
'path': '/selector'}
|
||||
service = self.mgr.update(service_id=SERVICE1['id'],
|
||||
bay_ident=SERVICE1['bay_uuid'],
|
||||
patch=patch)
|
||||
expect = [
|
||||
('PATCH', '/v1/services/%s/?bay_ident=%s' % (
|
||||
SERVICE1['id'], SERVICE1['bay_uuid']), {}, patch),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(NEW_SELECTOR, service.selector)
|
||||
@@ -1,87 +0,0 @@
|
||||
# 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 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 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 --bay zzz')
|
||||
self.assertTrue(mock_delete.called)
|
||||
|
||||
@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 xxx',
|
||||
self._mandatory_arg_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 --bay zzz')
|
||||
self.assertTrue(mock_show.called)
|
||||
self.assertEqual(1, mock_show.call_count)
|
||||
|
||||
@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 xxx',
|
||||
self._mandatory_arg_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 --bay 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 xxx',
|
||||
self._few_argument_error)
|
||||
self.assertFalse(mock_update.called)
|
||||
@@ -20,11 +20,7 @@ from magnumclient.common import httpclient
|
||||
from magnumclient.v1 import baymodels
|
||||
from magnumclient.v1 import bays
|
||||
from magnumclient.v1 import certificates
|
||||
from magnumclient.v1 import containers
|
||||
from magnumclient.v1 import mservices
|
||||
from magnumclient.v1 import pods
|
||||
from magnumclient.v1 import replicationcontrollers as rcs
|
||||
from magnumclient.v1 import services
|
||||
|
||||
|
||||
class Client(object):
|
||||
@@ -116,8 +112,4 @@ class Client(object):
|
||||
self.bays = bays.BayManager(self.http_client)
|
||||
self.certificates = certificates.CertificateManager(self.http_client)
|
||||
self.baymodels = baymodels.BayModelManager(self.http_client)
|
||||
self.containers = containers.ContainerManager(self.http_client)
|
||||
self.pods = pods.PodManager(self.http_client)
|
||||
self.rcs = rcs.ReplicationControllerManager(self.http_client)
|
||||
self.services = services.ServiceManager(self.http_client)
|
||||
self.mservices = mservices.MServiceManager(self.http_client)
|
||||
|
||||
@@ -1,144 +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.
|
||||
|
||||
from six.moves.urllib import parse
|
||||
|
||||
from magnumclient.common import base
|
||||
from magnumclient.common import utils
|
||||
from magnumclient import exceptions
|
||||
|
||||
|
||||
CREATION_ATTRIBUTES = ['name', 'image', 'command', 'bay_uuid', 'memory']
|
||||
|
||||
|
||||
class Container(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<Container %s>" % self._info
|
||||
|
||||
|
||||
class ContainerManager(base.Manager):
|
||||
resource_class = Container
|
||||
|
||||
@staticmethod
|
||||
def _path(id=None, bay_ident=None):
|
||||
|
||||
if id:
|
||||
return '/v1/containers/%s' % id
|
||||
elif bay_ident:
|
||||
return '/v1/containers/?bay_ident=%s' % (bay_ident)
|
||||
else:
|
||||
return '/v1/containers'
|
||||
|
||||
def list(self, marker=None, limit=None, sort_key=None,
|
||||
sort_dir=None, detail=False, bay_ident=None):
|
||||
"""Retrieve a list of containers.
|
||||
|
||||
:param marker: Optional, the UUID of a containers, eg the last
|
||||
containers from a previous result set. Return
|
||||
the next result set.
|
||||
:param limit: The maximum number of results to return per
|
||||
request, if:
|
||||
|
||||
1) limit > 0, the maximum number of containers to return.
|
||||
2) limit == 0, return the entire list of containers.
|
||||
3) limit param is NOT specified (None), the number of items
|
||||
returned respect the maximum imposed by the Magnum API
|
||||
(see Magnum's api.max_limit option).
|
||||
|
||||
:param sort_key: Optional, field used for sorting.
|
||||
|
||||
:param sort_dir: Optional, direction of sorting, either 'asc' (the
|
||||
default) or 'desc'.
|
||||
|
||||
:param detail: Optional, boolean whether to return detailed information
|
||||
about containers.
|
||||
|
||||
:returns: A list of containers.
|
||||
|
||||
"""
|
||||
if limit is not None:
|
||||
limit = int(limit)
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir)
|
||||
|
||||
path = ''
|
||||
if detail:
|
||||
path += 'detail'
|
||||
if filters:
|
||||
path += '?' + '&'.join(filters)
|
||||
|
||||
if limit is None:
|
||||
# TODO(yuanying): if endpoint returns "map",
|
||||
# change None to response_key
|
||||
return self._list(self._path(path, bay_ident=bay_ident),
|
||||
"containers")
|
||||
else:
|
||||
# TODO(yuanying): if endpoint returns "map",
|
||||
# change None to response_key
|
||||
return self._list_pagination(self._path(path,
|
||||
bay_ident=bay_ident),
|
||||
"containers",
|
||||
limit=limit)
|
||||
|
||||
def get(self, id):
|
||||
try:
|
||||
return self._list(self._path(id))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def create(self, **kwargs):
|
||||
new = {}
|
||||
for (key, value) in kwargs.items():
|
||||
if key in CREATION_ATTRIBUTES:
|
||||
new[key] = value
|
||||
else:
|
||||
raise exceptions.InvalidAttribute(
|
||||
"Key must be in %s" % ','.join(CREATION_ATTRIBUTES))
|
||||
return self._create(self._path(), new)
|
||||
|
||||
def delete(self, id):
|
||||
return self._delete(self._path(id))
|
||||
|
||||
def _action(self, id, action, method='PUT', qparams=None, **kwargs):
|
||||
if qparams:
|
||||
action = "%s?%s" % (action,
|
||||
parse.urlencode(qparams))
|
||||
kwargs.setdefault('headers', {})
|
||||
kwargs['headers'].setdefault('Content-Length', '0')
|
||||
resp, body = self.api.json_request(method,
|
||||
self._path(id) + action,
|
||||
**kwargs)
|
||||
return resp, body
|
||||
|
||||
def start(self, id):
|
||||
return self._action(id, '/start')
|
||||
|
||||
def stop(self, id):
|
||||
return self._action(id, '/stop')
|
||||
|
||||
def reboot(self, id):
|
||||
return self._action(id, '/reboot')
|
||||
|
||||
def pause(self, id):
|
||||
return self._action(id, '/pause')
|
||||
|
||||
def unpause(self, id):
|
||||
return self._action(id, '/unpause')
|
||||
|
||||
def logs(self, id):
|
||||
return self._action(id, '/logs', method='GET')[1]['output']
|
||||
|
||||
def execute(self, id, command):
|
||||
return self._action(id, '/execute',
|
||||
qparams={'command': command})[1]['output']
|
||||
@@ -1,217 +0,0 @@
|
||||
# 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 cliutils as utils
|
||||
from magnumclient.common import utils as magnum_utils
|
||||
from magnumclient import exceptions
|
||||
|
||||
|
||||
def _show_container(container):
|
||||
utils.print_dict(container._info)
|
||||
|
||||
|
||||
@utils.arg('--name',
|
||||
metavar='<name>',
|
||||
help='name of the container')
|
||||
@utils.arg('--image',
|
||||
required=True,
|
||||
metavar='<image>',
|
||||
help='name or ID of the image')
|
||||
@utils.arg('--bay',
|
||||
required=True,
|
||||
metavar='<bay>',
|
||||
help='ID or name of the bay.')
|
||||
@utils.arg('--command',
|
||||
metavar='<command>',
|
||||
help='Send command to the container')
|
||||
@utils.arg('--memory',
|
||||
metavar='<memory>',
|
||||
help='The container memory size (format: <number><optional unit>, '
|
||||
'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_IN_PROGRESS', 'UPDATE_COMPLETE']:
|
||||
raise exceptions.InvalidAttribute(
|
||||
'Bay status for %s is: %s. We cannot create a %s'
|
||||
' unless the status is CREATE_COMPLETE, UPDATE_IN_PROGRESS'
|
||||
' or UPDATE_COMPLETE.' % (bay.uuid, bay.status, "container"))
|
||||
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))
|
||||
|
||||
|
||||
@utils.arg('--marker',
|
||||
metavar='<marker>',
|
||||
default=None,
|
||||
help='The last bay UUID of the previous page; '
|
||||
'displays list of bays after "marker".')
|
||||
@utils.arg('--limit',
|
||||
metavar='<limit>',
|
||||
type=int,
|
||||
help='Maximum number of containers to return')
|
||||
@utils.arg('--sort-key',
|
||||
metavar='<sort-key>',
|
||||
help='Column to sort results by')
|
||||
@utils.arg('--sort-dir',
|
||||
metavar='<sort-dir>',
|
||||
choices=['desc', 'asc'],
|
||||
help='Direction to sort. "asc" or "desc".')
|
||||
@utils.arg('--bay',
|
||||
metavar='<bay>', help="UUID or Name of Bay")
|
||||
def do_container_list(cs, args):
|
||||
"""Print a list of available containers."""
|
||||
opts = {}
|
||||
opts['bay_ident'] = args.bay
|
||||
opts['marker'] = args.marker
|
||||
opts['limit'] = args.limit
|
||||
opts['sort_key'] = args.sort_key
|
||||
opts['sort_dir'] = args.sort_dir
|
||||
containers = cs.containers.list(**opts)
|
||||
columns = ('uuid', 'name', 'status', 'bay_uuid')
|
||||
utils.print_list(containers, columns,
|
||||
{'versions': magnum_utils.print_list_field('versions')},
|
||||
sortby_index=None)
|
||||
|
||||
|
||||
@utils.arg('containers',
|
||||
metavar='<container>',
|
||||
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)
|
||||
print("Request to delete container %s has been accepted." %
|
||||
container)
|
||||
except Exception as e:
|
||||
print("Delete for container %(container)s failed: %(e)s" %
|
||||
{'container': container, 'e': e})
|
||||
|
||||
|
||||
@utils.arg('container',
|
||||
metavar='<container>',
|
||||
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='<container>',
|
||||
nargs='+',
|
||||
help='ID or name of the (container)s to reboot.')
|
||||
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='<container>',
|
||||
nargs='+',
|
||||
help='ID or name of the (container)s to stop.')
|
||||
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='<container>',
|
||||
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='<container>',
|
||||
nargs='+',
|
||||
help='ID or name of the (container)s to pause.')
|
||||
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='<container>',
|
||||
nargs='+',
|
||||
help='ID or name of the (container)s to unpause.')
|
||||
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='<container>',
|
||||
help='ID or name of the container to get logs for.')
|
||||
def do_container_logs(cs, args):
|
||||
"""Get logs of a container."""
|
||||
logs = cs.containers.logs(args.container)
|
||||
print(logs)
|
||||
|
||||
|
||||
@utils.arg('container',
|
||||
metavar='<container>',
|
||||
help='ID or name of the container to execute command in.')
|
||||
@utils.arg('--command',
|
||||
required=True,
|
||||
metavar='<command>',
|
||||
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)
|
||||
@@ -1,106 +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.
|
||||
|
||||
from magnumclient.common import base
|
||||
from magnumclient.common import utils
|
||||
from magnumclient import exceptions
|
||||
|
||||
|
||||
CREATION_ATTRIBUTES = ['bay_uuid', 'manifest', 'manifest_url']
|
||||
|
||||
|
||||
class Pod(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<Pod %s>" % self._info
|
||||
|
||||
|
||||
class PodManager(base.Manager):
|
||||
resource_class = Pod
|
||||
|
||||
@staticmethod
|
||||
def _path(id=None, bay_ident=None):
|
||||
if id and bay_ident:
|
||||
return '/v1/pods/%s/?bay_ident=%s' % (id, bay_ident)
|
||||
elif bay_ident:
|
||||
return '/v1/pods/?bay_ident=%s' % (bay_ident)
|
||||
else:
|
||||
return '/v1/pods'
|
||||
|
||||
def list(self, bay_ident, limit=None, marker=None, sort_key=None,
|
||||
sort_dir=None, detail=False):
|
||||
"""Retrieve a list of pods.
|
||||
|
||||
:param bay_ident: UUID or Name of the Bay.
|
||||
:param marker: Optional, the UUID or Name of a pod, e.g. the last
|
||||
pod from a previous result set. Return the next
|
||||
result set.
|
||||
:param limit: The maximum number of results to return per
|
||||
request, if:
|
||||
|
||||
1) limit > 0, the maximum number of pods to return.
|
||||
2) limit == 0, return the entire list of pods.
|
||||
3) limit param is NOT specified (None), the number of items
|
||||
returned respect the maximum imposed by the Magnum API
|
||||
(see Magnum's api.max_limit option).
|
||||
|
||||
:param sort_key: Optional, field used for sorting.
|
||||
|
||||
:param sort_dir: Optional, direction of sorting, either 'asc' (the
|
||||
default) or 'desc'.
|
||||
|
||||
:param detail: Optional, boolean whether to return detailed
|
||||
information about pods.
|
||||
|
||||
:returns: A list of pods.
|
||||
|
||||
"""
|
||||
if limit is not None:
|
||||
limit = int(limit)
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir)
|
||||
filters.append('bay_ident=%s' % bay_ident)
|
||||
|
||||
path = ''
|
||||
if detail:
|
||||
path += 'detail'
|
||||
if filters:
|
||||
path += '?' + '&'.join(filters)
|
||||
|
||||
if limit is None:
|
||||
return self._list(self._path(bay_ident=bay_ident), "pods")
|
||||
else:
|
||||
return self._list_pagination(self._path(bay_ident=bay_ident),
|
||||
"pods", limit=limit)
|
||||
|
||||
def get(self, id, bay_ident):
|
||||
try:
|
||||
return self._list(self._path(id, bay_ident))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def create(self, **kwargs):
|
||||
new = {}
|
||||
for (key, value) in kwargs.items():
|
||||
if key in CREATION_ATTRIBUTES:
|
||||
new[key] = value
|
||||
else:
|
||||
raise exceptions.InvalidAttribute(
|
||||
"Key must be in %s" % ",".join(CREATION_ATTRIBUTES))
|
||||
return self._create(self._path(), new)
|
||||
|
||||
def delete(self, id, bay_ident):
|
||||
return self._delete(self._path(id, bay_ident))
|
||||
|
||||
def update(self, id, bay_ident, patch):
|
||||
return self._update(self._path(id, bay_ident), patch)
|
||||
@@ -1,128 +0,0 @@
|
||||
# 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 cliutils as utils
|
||||
from magnumclient.common import utils as magnum_utils
|
||||
from magnumclient import exceptions
|
||||
|
||||
|
||||
def _show_pod(pod):
|
||||
del pod._info['links']
|
||||
utils.print_dict(pod._info)
|
||||
|
||||
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', help="UUID or Name of Bay")
|
||||
def do_pod_list(cs, args):
|
||||
"""Print a list of registered pods."""
|
||||
bay = cs.bays.get(args.bay)
|
||||
if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']:
|
||||
raise exceptions.InvalidAttribute(
|
||||
'Bay status for %s is: %s. We can not list pods in there until'
|
||||
' the status is CREATE_COMPLETE or UPDATE_COMPLETE.' %
|
||||
(bay.uuid, bay.status))
|
||||
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='<manifest-url>',
|
||||
help='Name/URL of the pod file to use for creating PODs.')
|
||||
@utils.arg('--manifest',
|
||||
metavar='<manifest>',
|
||||
help='File path of the pod file to use for creating PODs.')
|
||||
@utils.arg('--bay',
|
||||
required=True,
|
||||
metavar='<bay>',
|
||||
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']:
|
||||
raise exceptions.InvalidAttribute(
|
||||
'Bay status for %s is: %s. We cannot create a %s'
|
||||
' until the status is CREATE_COMPLETE or UPDATE_COMPLETE.' %
|
||||
(bay.uuid, bay.status, "pod"))
|
||||
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='<pod-id>', help="UUID or name of pod")
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', help="UUID or Name of Bay")
|
||||
@utils.arg(
|
||||
'op',
|
||||
metavar='<op>',
|
||||
choices=['add', 'replace', 'remove'],
|
||||
help="Operations: 'add', 'replace' or 'remove'")
|
||||
@utils.arg(
|
||||
'attributes',
|
||||
metavar='<path=value>',
|
||||
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='<pods>', nargs='+',
|
||||
help='ID or name of the (pod)s to delete.')
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', 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)
|
||||
print("Request to delete pod %s has been accepted." %
|
||||
pod)
|
||||
except Exception as e:
|
||||
print("Delete for pod %(pod)s failed: %(e)s" %
|
||||
{'pod': pod, 'e': e})
|
||||
pass
|
||||
|
||||
|
||||
@utils.arg('pod',
|
||||
metavar='<pod>',
|
||||
help='ID or name of the pod to show.')
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', 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)
|
||||
@@ -1,106 +0,0 @@
|
||||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# 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 base
|
||||
from magnumclient.common import utils
|
||||
from magnumclient import exceptions
|
||||
|
||||
|
||||
CREATION_ATTRIBUTES = ['bay_uuid', 'manifest', 'manifest_url']
|
||||
|
||||
|
||||
class ReplicationController(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<ReplicationController %s>" % self._info
|
||||
|
||||
|
||||
class ReplicationControllerManager(base.Manager):
|
||||
resource_class = ReplicationController
|
||||
|
||||
@staticmethod
|
||||
def _path(id=None, bay_ident=None):
|
||||
if id and bay_ident:
|
||||
return '/v1/rcs/%s/?bay_ident=%s' % (id, bay_ident)
|
||||
elif bay_ident:
|
||||
return '/v1/rcs/?bay_ident=%s' % (bay_ident)
|
||||
else:
|
||||
return '/v1/rcs'
|
||||
|
||||
def list(self, bay_ident, limit=None, marker=None, sort_key=None,
|
||||
sort_dir=None, detail=False):
|
||||
"""Retrieve a list of ReplicationControllers.
|
||||
|
||||
:param bay_ident: UUID or Name of the Bay.
|
||||
:param marker: Optional, the UUID or Name of a rc, e.g. the last
|
||||
rc from a previous result set. Return
|
||||
the next result set.
|
||||
:param limit: The maximum number of results to return per
|
||||
request, if:
|
||||
|
||||
1) limit > 0, the maximum number of rcs to return.
|
||||
2) limit == 0, return the entire list of rcs.
|
||||
3) limit param is NOT specified (None), the number of items
|
||||
returned respect the maximum imposed by the Magnum API
|
||||
(see Magnum's api.max_limit option).
|
||||
|
||||
:param sort_key: Optional, field used for sorting.
|
||||
|
||||
:param sort_dir: Optional, direction of sorting, either 'asc' (the
|
||||
default) or 'desc'.
|
||||
|
||||
:param detail: Optional, boolean whether to return detailed
|
||||
information about ReplicationControllers.
|
||||
|
||||
:returns: A list of ReplicationControllers.
|
||||
|
||||
"""
|
||||
if limit is not None:
|
||||
limit = int(limit)
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir)
|
||||
filters.append('bay_ident=%s' % bay_ident)
|
||||
|
||||
path = ''
|
||||
if detail:
|
||||
path += 'detail'
|
||||
if filters:
|
||||
path += '?' + '&'.join(filters)
|
||||
|
||||
if limit is None:
|
||||
return self._list(self._path(bay_ident=bay_ident), "rcs")
|
||||
else:
|
||||
return self._list_pagination(self._path(bay_ident=bay_ident),
|
||||
"rcs", limit=limit)
|
||||
|
||||
def get(self, id, bay_ident):
|
||||
try:
|
||||
return self._list(self._path(id, bay_ident))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def create(self, **kwargs):
|
||||
new = {}
|
||||
for (key, value) in kwargs.items():
|
||||
if key in CREATION_ATTRIBUTES:
|
||||
new[key] = value
|
||||
else:
|
||||
raise exceptions.InvalidAttribute(
|
||||
"Key must be in %s" % ",".join(CREATION_ATTRIBUTES))
|
||||
return self._create(self._path(), new)
|
||||
|
||||
def delete(self, id, bay_ident):
|
||||
return self._delete(self._path(id, bay_ident))
|
||||
|
||||
def update(self, id, bay_ident, patch):
|
||||
return self._update(self._path(id, bay_ident), patch)
|
||||
@@ -1,132 +0,0 @@
|
||||
# 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 cliutils as utils
|
||||
from magnumclient.common import utils as magnum_utils
|
||||
from magnumclient import exceptions
|
||||
|
||||
|
||||
def _show_rc(rc):
|
||||
utils.print_dict(rc._info)
|
||||
|
||||
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', help="UUID or Name of Bay")
|
||||
def do_rc_list(cs, args):
|
||||
"""Print a list of registered replication controllers."""
|
||||
bay = cs.bays.get(args.bay)
|
||||
if bay.status not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']:
|
||||
raise exceptions.InvalidAttribute(
|
||||
'Bay status for %s is: %s. We cannot list '
|
||||
'replication controllers in bay until the bay status '
|
||||
'is CREATE_COMPLETE or UPDATE_COMPLETE.' %
|
||||
(args.bay, bay.status))
|
||||
|
||||
rcs = cs.rcs.list(args.bay)
|
||||
columns = ('uuid', 'name', 'bay_uuid')
|
||||
utils.print_list(rcs, columns,
|
||||
{'versions': magnum_utils.print_list_field('versions')})
|
||||
|
||||
|
||||
@utils.arg('--manifest-url',
|
||||
metavar='<manifest-url>',
|
||||
help='Name/URL of the replication controller file to use for '
|
||||
'creating replication controllers.')
|
||||
@utils.arg('--manifest',
|
||||
metavar='<manifest>',
|
||||
help='File path of the replication controller file to use for '
|
||||
'creating replication controllers.')
|
||||
@utils.arg('--bay',
|
||||
required=True,
|
||||
metavar='<bay>',
|
||||
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']:
|
||||
raise exceptions.InvalidAttribute(
|
||||
'Bay status for %s is: %s. We cannot create a '
|
||||
'replication controller in bay until the status '
|
||||
'is CREATE_COMPLETE or UPDATE_COMPLETE.' %
|
||||
(args.bay, bay.status))
|
||||
|
||||
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='<rc>', help="UUID or name of replication controller")
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', help="UUID or Name of Bay")
|
||||
@utils.arg(
|
||||
'op',
|
||||
metavar='<op>',
|
||||
choices=['add', 'replace', 'remove'],
|
||||
help="Operations: 'add', 'replace' or 'remove'")
|
||||
@utils.arg(
|
||||
'attributes',
|
||||
metavar='<path=value>',
|
||||
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='<rcs>',
|
||||
nargs='+',
|
||||
help='ID or name of the replication (controller)s to delete.')
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', 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)
|
||||
print("Request to delete rc %s has been accepted." %
|
||||
rc)
|
||||
except Exception as e:
|
||||
print("Delete for rc %(rc)s failed: %(e)s" %
|
||||
{'rc': rc, 'e': e})
|
||||
|
||||
|
||||
@utils.arg('rc',
|
||||
metavar='<rc>',
|
||||
help='ID or name of the replication controller to show.')
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', 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)
|
||||
@@ -1,105 +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.
|
||||
|
||||
from magnumclient.common import base
|
||||
from magnumclient.common import utils
|
||||
from magnumclient import exceptions
|
||||
|
||||
CREATION_ATTRIBUTES = ['bay_uuid', 'manifest', 'manifest_url']
|
||||
|
||||
|
||||
class Service(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<COE-Service %s>" % self._info
|
||||
|
||||
|
||||
class ServiceManager(base.Manager):
|
||||
resource_class = Service
|
||||
|
||||
@staticmethod
|
||||
def _path(id=None, bay_ident=None):
|
||||
if id and bay_ident:
|
||||
return '/v1/services/%s/?bay_ident=%s' % (id, bay_ident)
|
||||
elif bay_ident:
|
||||
return '/v1/services/?bay_ident=%s' % (bay_ident)
|
||||
else:
|
||||
return '/v1/services'
|
||||
|
||||
def list(self, bay_ident, marker=None, limit=None, sort_key=None,
|
||||
sort_dir=None, detail=False):
|
||||
"""Retrieve a list of services.
|
||||
|
||||
:param bay_ident: UUID or Name of the Bay.
|
||||
:param marker: Optional, the UUID or Name of a service, e.g. the
|
||||
last service from a previous result set. Return
|
||||
the next result set.
|
||||
:param limit: The maximum number of results to return per
|
||||
request, if:
|
||||
|
||||
1) limit > 0, the maximum number of services to return.
|
||||
2) limit == 0, return the entire list of services.
|
||||
3) limit param is NOT specified (None), the number of items
|
||||
returned respect the maximum imposed by the Magnum API
|
||||
(see Magnum's api.max_limit option).
|
||||
|
||||
:param sort_key: Optional, field used for sorting.
|
||||
|
||||
:param sort_dir: Optional, direction of sorting, either 'asc' (the
|
||||
default) or 'desc'.
|
||||
|
||||
:param detail: Optional, boolean whether to return detailed
|
||||
information about services.
|
||||
|
||||
:returns: A list of services.
|
||||
|
||||
"""
|
||||
if limit is not None:
|
||||
limit = int(limit)
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir)
|
||||
filters.append('bay_ident=%s' % bay_ident)
|
||||
|
||||
path = ''
|
||||
if detail:
|
||||
path += 'detail'
|
||||
if filters:
|
||||
path += '?' + '&'.join(filters)
|
||||
|
||||
if limit is None:
|
||||
return self._list(self._path(bay_ident=bay_ident), "services")
|
||||
else:
|
||||
return self._list_pagination(self._path(bay_ident=bay_ident),
|
||||
"services", limit=limit)
|
||||
|
||||
def get(self, service_id, bay_ident):
|
||||
try:
|
||||
return self._list(self._path(service_id, bay_ident))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def create(self, **kwargs):
|
||||
new = {}
|
||||
for (key, value) in kwargs.items():
|
||||
if key in CREATION_ATTRIBUTES:
|
||||
new[key] = value
|
||||
else:
|
||||
raise exceptions.InvalidAttribute(
|
||||
"Key must be in %s" % ",".join(CREATION_ATTRIBUTES))
|
||||
return self._create(self._path(), new)
|
||||
|
||||
def delete(self, service_id, bay_ident):
|
||||
return self._delete(self._path(service_id, bay_ident))
|
||||
|
||||
def update(self, service_id, bay_ident, patch):
|
||||
return self._update(self._path(service_id, bay_ident), patch)
|
||||
@@ -1,119 +0,0 @@
|
||||
# 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 cliutils as utils
|
||||
from magnumclient.common import utils as magnum_utils
|
||||
|
||||
|
||||
def _show_coe_service(service):
|
||||
utils.print_dict(service._info)
|
||||
|
||||
|
||||
@utils.arg('--bay',
|
||||
required=True,
|
||||
metavar='<bay>',
|
||||
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='<manifest-url>',
|
||||
help='Name/URL of the service file to use for creating services.')
|
||||
@utils.arg('--manifest',
|
||||
metavar='<manifest>',
|
||||
help='File path of the service file to use for creating services.')
|
||||
@utils.arg('--bay',
|
||||
required=True,
|
||||
metavar='<bay>',
|
||||
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('services', metavar='<services>', help="UUID or name of service")
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', help="UUID or Name of Bay")
|
||||
@utils.arg(
|
||||
'op',
|
||||
metavar='<op>',
|
||||
choices=['add', 'replace', 'remove'],
|
||||
help="Operations: 'add', 'replace' or 'remove'")
|
||||
@utils.arg(
|
||||
'attributes',
|
||||
metavar='<path=value>',
|
||||
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.services, args.bay, patch)
|
||||
_show_coe_service(service)
|
||||
|
||||
|
||||
@utils.arg('services', metavar='<services>', nargs='+',
|
||||
help='ID or name of the service to delete.')
|
||||
@utils.arg('--bay', required=True, metavar='<bay>',
|
||||
help="UUID or Name of Bay")
|
||||
def do_coe_service_delete(cs, args):
|
||||
"""Delete specified coe service."""
|
||||
for service in args.services:
|
||||
try:
|
||||
cs.services.delete(service, args.bay)
|
||||
print("Request to delete service %s has been accepted." %
|
||||
service)
|
||||
except Exception as e:
|
||||
print("Delete for service %(service)s failed: %(e)s" %
|
||||
{'service': service, 'e': e})
|
||||
|
||||
|
||||
@utils.arg('services', metavar='<services>',
|
||||
help='ID or name of the service to show.')
|
||||
@utils.arg('--bay', required=True,
|
||||
metavar='<bay>', 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.services, args.bay)
|
||||
_show_coe_service(service)
|
||||
@@ -16,19 +16,11 @@
|
||||
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 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,
|
||||
pods_shell,
|
||||
replicationcontrollers_shell,
|
||||
services_shell,
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user