Add environment create/delete to openstack CLI

$ openstack environment create [--join-net-id <NET_ID>]
                               [--join-subnet-id <SUBNET_ID>]
                               [--region <REGION_NAME>]
                               <ENVIRONMENT_NAME>
$ openstack environment delete [--abandon] <NAME or ID>
                               [<NAME or ID> ...]

Partially implements: blueprint openstack-client-plugin-support

Change-Id: Ic8d97d8fb79ba5ce9e489b4083f26ef96f4e43e9
This commit is contained in:
enthurohini 2016-02-28 13:34:52 +05:30 committed by Kirill Zaitsev
parent 9a86110b6d
commit 844e8c7829
4 changed files with 328 additions and 25 deletions

View File

@ -12,19 +12,22 @@
"""Application-catalog v1 stack action implementation"""
import uuid
from cliff import lister
from cliff import show
from muranoclient.common import utils as murano_utils
from muranoclient.openstack.common.apiclient import exceptions
from openstackclient.common import utils
from oslo_log import log as logging
from oslo_serialization import jsonutils
LOG = logging.getLogger(__name__)
class ListEnvironments(lister.Lister):
"""Lists environments"""
log = logging.getLogger(__name__ + ".ListEnvironments")
def get_parser(self, prog_name):
parser = super(ListEnvironments, self).get_parser(prog_name)
parser.add_argument(
@ -37,13 +40,12 @@ class ListEnvironments(lister.Lister):
return parser
def take_action(self, parsed_args):
self.log.debug("take_action({0})".format(parsed_args))
LOG.debug("take_action({0})".format(parsed_args))
client = self.app.client_manager.application_catalog
data = client.environments.list(parsed_args.all_tenants)
columns = ('id', 'name', 'created', 'updated')
columns = ('id', 'name', 'status', 'created', 'updated')
column_headers = [c.capitalize() for c in columns]
return (
column_headers,
list(utils.get_item_properties(
@ -56,8 +58,6 @@ class ListEnvironments(lister.Lister):
class ShowEnvironment(show.ShowOne):
"""Display environment details"""
log = logging.getLogger(__name__ + ".ShowEnvironment")
def get_parser(self, prog_name):
parser = super(ShowEnvironment, self).get_parser(prog_name)
parser.add_argument(
@ -81,7 +81,7 @@ class ShowEnvironment(show.ShowOne):
return parser
def take_action(self, parsed_args):
self.log.debug("take_action({0})".format(parsed_args))
LOG.debug("take_action({0})".format(parsed_args))
client = self.app.client_manager.application_catalog
environment = utils.find_resource(client.environments,
@ -100,8 +100,6 @@ class ShowEnvironment(show.ShowOne):
class RenameEnvironment(lister.Lister):
"""Rename an environment."""
log = logging.getLogger(__name__ + ".RenameEnvironment")
def get_parser(self, prog_name):
parser = super(RenameEnvironment, self).get_parser(prog_name)
parser.add_argument(
@ -118,14 +116,14 @@ class RenameEnvironment(lister.Lister):
return parser
def take_action(self, parsed_args):
self.log.debug("take_action({0})".format(parsed_args))
LOG.debug("take_action({0})".format(parsed_args))
client = self.app.client_manager.application_catalog
environment = utils.find_resource(client.environments,
parsed_args.id)
data = client.environments.update(environment.id,
parsed_args.name)
columns = ('id', 'name', 'created', 'updated')
columns = ('id', 'name', 'status', 'created', 'updated')
column_headers = [c.capitalize() for c in columns]
return (
@ -140,8 +138,6 @@ class RenameEnvironment(lister.Lister):
class EnvironmentSessionCreate(show.ShowOne):
"""Creates a new configuration session for environment ID."""
log = logging.getLogger(__name__ + ".EnvironmentSessionCreate")
def get_parser(self, prog_name):
parser = super(EnvironmentSessionCreate, self).get_parser(prog_name)
parser.add_argument(
@ -153,7 +149,7 @@ class EnvironmentSessionCreate(show.ShowOne):
return parser
def take_action(self, parsed_args):
self.log.debug("take_action({0})".format(parsed_args))
LOG.debug("take_action({0})".format(parsed_args))
client = self.app.client_manager.application_catalog
environment_id = parsed_args.id
@ -161,3 +157,128 @@ class EnvironmentSessionCreate(show.ShowOne):
sessionid = murano_utils.text_wrap_formatter(session_id)
return (['id'], [sessionid])
class EnvironmentCreate(lister.Lister):
"""Create an environment."""
def get_parser(self, prog_name):
parser = super(EnvironmentCreate, self).get_parser(prog_name)
parser.add_argument(
'name',
metavar="<ENVIRONMENT_ID>",
help="Environment name.",
)
parser.add_argument(
'--region',
metavar="<REGION_NAME>",
help="Name of the target OpenStack region.",
)
parser.add_argument(
'--join-subnet-id',
metavar="<SUBNET_ID>",
help="Subnetwork id to join.",
)
parser.add_argument(
'--join-net-id',
metavar="<NET_ID>",
help="Network id to join.",
)
return parser
def take_action(self, parsed_args):
LOG.debug("take_action({0})".format(parsed_args))
client = self.app.client_manager.application_catalog
body = {"name": parsed_args.name, "region": parsed_args.region}
if parsed_args.join_net_id or parsed_args.join_subnet_id:
res = {
'defaultNetworks': {
'environment': {
'?': {
'id': uuid.uuid4().hex,
'type':
'io.murano.resources.ExistingNeutronNetwork'
},
},
'flat': None
}
}
if parsed_args.join_net_id:
res['defaultNetworks']['environment']['internalNetworkName'] \
= parsed_args.join_net_id
if parsed_args.join_subnet_id:
res['defaultNetworks']['environment']['internalSubnetworkName'
] = \
parsed_args.join_subnet_id
body.update(res)
data = client.environments.create(body)
columns = ('id', 'name', 'status', 'created', 'updated')
column_headers = [c.capitalize() for c in columns]
return (
column_headers,
[utils.get_item_properties(
data,
columns,
)]
)
class EnvironmentDelete(lister.Lister):
"""Delete an environment."""
def get_parser(self, prog_name):
parser = super(EnvironmentDelete, self).get_parser(prog_name)
parser.add_argument(
'id',
metavar="<NAME or ID>",
nargs="+",
help="Id or name of environment(s) to delete.",
)
parser.add_argument(
'--abandon',
action='store_true',
default=False,
help="If set will abandon environment without deleting any of its"
" resources.",
)
return parser
def take_action(self, parsed_args):
LOG.debug("take_action({0})".format(parsed_args))
client = self.app.client_manager.application_catalog
abandon = getattr(parsed_args, 'abandon', False)
failure_count = 0
for environment_id in parsed_args.id:
try:
environment = murano_utils.find_resource(client.environments,
environment_id)
client.environments.delete(environment.id, abandon)
except exceptions.NotFound:
failure_count += 1
print("Failed to delete '{0}'; environment not found".
format(environment_id))
if failure_count == len(parsed_args.id):
raise exceptions.CommandError("Unable to find and delete any of "
"the specified environments.")
data = client.environments.list()
columns = ('id', 'name', 'status', 'created', 'updated')
column_headers = [c.capitalize() for c in columns]
return (
column_headers,
list(utils.get_item_properties(
s,
columns,
) for s in data)
)

View File

@ -50,7 +50,8 @@ class TestListEnvironment(TestEnvironment):
verifylist = []
mock_util.return_value = ('1234', 'Environment of all tenants',
'2015-12-16T17:31:54', '2015-12-16T17:31:54'
'fake deployed', '2015-12-16T17:31:54',
'2015-12-16T17:31:54'
)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -58,12 +59,13 @@ class TestListEnvironment(TestEnvironment):
columns, data = self.cmd.take_action(parsed_args)
# Check that columns are correct
expected_columns = ['Id', 'Name', 'Created', 'Updated']
expected_columns = ['Id', 'Name', 'Status', 'Created', 'Updated']
self.assertEqual(expected_columns, columns)
# Check that data is correct
expected_data = [('1234', 'Environment of all tenants',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')]
'fake deployed', '2015-12-16T17:31:54',
'2015-12-16T17:31:54')]
self.assertEqual(expected_data, data)
@mock.patch('openstackclient.common.utils.get_item_properties')
@ -72,7 +74,8 @@ class TestListEnvironment(TestEnvironment):
verifylist = [('all_tenants', True)]
mock_util.return_value = ('1234', 'Environment of all tenants',
'2015-12-16T17:31:54', '2015-12-16T17:31:54'
'fake deployed', '2015-12-16T17:31:54',
'2015-12-16T17:31:54'
)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -80,12 +83,13 @@ class TestListEnvironment(TestEnvironment):
columns, data = self.cmd.take_action(parsed_args)
# Check that columns are correct
expected_columns = ['Id', 'Name', 'Created', 'Updated']
expected_columns = ['Id', 'Name', 'Status', 'Created', 'Updated']
self.assertEqual(expected_columns, columns)
# Check that data is correct
expected_data = [('1234', 'Environment of all tenants',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')]
'fake deployed', '2015-12-16T17:31:54',
'2015-12-16T17:31:54')]
self.assertEqual(expected_data, data)
@ -175,19 +179,20 @@ class TestRenameEnvironment(TestEnvironment):
arglist = ['1234', 'fake-1']
verifylist = [('id', '1234'), ('name', 'fake-1')]
mock_util.return_value = ('1234', 'fake-1', '2015-12-16T17:31:54',
'2015-12-16T17:31:54')
mock_util.return_value = ('1234', 'fake-1', 'fake deployed',
'2015-12-16T17:31:54', '2015-12-16T17:31:54'
)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
# Check that columns are correct
expected_columns = ['Id', 'Name', 'Created', 'Updated']
expected_columns = ['Id', 'Name', 'Status', 'Created', 'Updated']
self.assertEqual(expected_columns, columns)
# Check that data is correct
expected_data = [('1234', 'fake-1',
expected_data = [('1234', 'fake-1', 'fake deployed',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')]
self.assertEqual(expected_data, data)
@ -217,3 +222,172 @@ class TestEnvironmentSessionCreate(TestEnvironment):
# Check that data is correct
expected_data = ['1abc2xyz']
self.assertEqual(expected_data, data)
class TestEnvironmentCreate(TestEnvironment):
def setUp(self):
super(TestEnvironmentCreate, self).setUp()
self.environment_mock.create.return_value = [api_env.Environment(None,
ENV_INFO)]
# Command to test
self.cmd = osc_env.EnvironmentCreate(self.app, None)
@mock.patch('openstackclient.common.utils.get_item_properties')
def test_environment_create_with_no_option(self, mock_util):
arglist = ['fake']
verifylist = [('name', 'fake')]
mock_util.return_value = ('1234', 'fake', 'ready',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
# Check that columns are correct
expected_columns = ['Id', 'Name', 'Status', 'Created', 'Updated']
self.assertEqual(expected_columns, columns)
# Check that data is correct
expected_data = [('1234', 'fake', 'ready',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')]
self.assertEqual(expected_data, data)
@mock.patch('openstackclient.common.utils.get_item_properties')
def test_environment_create_with_region_option(self, mock_util):
arglist = ['fake', '--region', 'region_one']
verifylist = [('name', 'fake'), ('region', 'region_one')]
mock_util.return_value = ('1234', 'fake', 'ready',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
# Check that correct arguments are passed
self.environment_mock.create.assert_has_calls([mock.call(
{'name': 'fake', 'region': 'region_one'})])
# Check that columns are correct
expected_columns = ['Id', 'Name', 'Status', 'Created', 'Updated']
self.assertEqual(expected_columns, columns)
# Check that data is correct
expected_data = [('1234', 'fake', 'ready',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')]
self.assertEqual(expected_data, data)
@mock.patch('openstackclient.common.utils.get_item_properties')
def test_environment_create_with_net_option(self, mock_util):
arglist = ['fake', '--join-net-id', 'x1y2z3']
verifylist = [('name', 'fake'), ('join_net_id', 'x1y2z3')]
mock_util.return_value = ('1234', 'fake', 'ready',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
expected_call = {
'defaultNetworks': {
'environment': {
'internalNetworkName': 'x1y2z3',
'?': {
'type': 'io.murano.resources.ExistingNeutronNetwork',
'id': mock.ANY
}
},
'flat': None
},
'name': 'fake',
'region': None
}
# Check that correct arguments are passed
self.environment_mock.create.assert_called_with(expected_call)
# Check that columns are correct
expected_columns = ['Id', 'Name', 'Status', 'Created', 'Updated']
self.assertEqual(expected_columns, columns)
# Check that data is correct
expected_data = [('1234', 'fake', 'ready',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')]
self.assertEqual(expected_data, data)
@mock.patch('openstackclient.common.utils.get_item_properties')
def test_environment_create_with_subnet_option(self, mock_util):
arglist = ['fake', '--join-subnet-id', 'x1y2z3']
verifylist = [('name', 'fake'), ('join_subnet_id', 'x1y2z3')]
mock_util.return_value = ('1234', 'fake', 'ready',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
expected_call = {
'defaultNetworks': {
'environment': {
'internalSubnetworkName': 'x1y2z3',
'?': {
'type': 'io.murano.resources.ExistingNeutronNetwork',
'id': mock.ANY
}
},
'flat': None
},
'name': 'fake',
'region': None
}
# Check that correct arguments are passed
self.environment_mock.create.assert_called_with(expected_call)
# Check that columns are correct
expected_columns = ['Id', 'Name', 'Status', 'Created', 'Updated']
self.assertEqual(expected_columns, columns)
# Check that data is correct
expected_data = [('1234', 'fake', 'ready',
'2015-12-16T17:31:54', '2015-12-16T17:31:54')]
self.assertEqual(expected_data, data)
class TestEnvironmentDelete(TestEnvironment):
def setUp(self):
super(TestEnvironmentDelete, self).setUp()
self.environment_mock.delete.return_value = None
self.environment_mock.list.return_value = [api_env.Environment(None,
ENV_INFO)]
# Command to test
self.cmd = osc_env.EnvironmentDelete(self.app, None)
@mock.patch('openstackclient.common.utils.get_item_properties')
def test_environment_delete(self, mock_util):
arglist = ['fake1', 'fake2']
verifylist = [('id', ['fake1', 'fake2'])]
mock_util.return_value = ('1234', 'Environment of all tenants',
'fake deployed', '2015-12-16T17:31:54',
'2015-12-16T17:31:54'
)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
# Check that columns are correct
expected_columns = ['Id', 'Name', 'Status', 'Created', 'Updated']
self.assertEqual(expected_columns, columns)
# Check that data is correct
expected_data = [('1234', 'Environment of all tenants',
'fake deployed', '2015-12-16T17:31:54',
'2015-12-16T17:31:54')]
self.assertEqual(expected_data, data)

View File

@ -0,0 +1,6 @@
---
features:
- New OSC command ``environment create [--join-net-id <NET_ID>]
[--join-subnet-id <SUBNET_ID>] [--region <REGION_NAME>] <ENVIRONMENT_NAME>``
- New OSC command ``environment delete [--abandon] <NAME or ID>
[<NAME or ID> ...]``

View File

@ -38,6 +38,8 @@ openstack.application_catalog.v1 =
environment_show = muranoclient.osc.v1.environment:ShowEnvironment
environment_rename = muranoclient.osc.v1.environment:RenameEnvironment
environment_session_create = muranoclient.osc.v1.environment:EnvironmentSessionCreate
environment_create = muranoclient.osc.v1.environment:EnvironmentCreate
environment_delete = muranoclient.osc.v1.environment:EnvironmentDelete
[global]
setup-hooks =