Add support for module ordering on apply

Client side of being able to specify 'priority' modules plus a
way to rank the order in which modules are applied.  Two new
attributes 'priority_apply' and 'apply_order' have been added
to the python API and are supported in the CLI by means of the
module-create and module-update commands.

Partially Implements: blueprint module-management-ordering

Change-Id: I2b871c7d1eab634174396bd0905329f3a66755f6
This commit is contained in:
Peter Stachowski 2016-07-13 11:37:34 -04:00
parent 2b8a3dc1c2
commit 8607ca8358
6 changed files with 99 additions and 23 deletions

@ -0,0 +1,7 @@
---
features:
- Modules can now be applied in a consistent order,
based on the new 'priority_apply' and 'apply_order'
attributes available to module-create and
module-update.
Blueprint module-management-ordering

@ -428,7 +428,10 @@ class FakeHTTPClient(base_client.HTTPClient):
"datastore_version": 'all',
"tenant": 'all',
"auto_apply": 0,
"visible": 1},
"visible": 1,
"priority_apply": 0,
"apply_order": 5,
"is_admin": 0},
{
"id": "8765",
"name": "mod2",
@ -437,7 +440,10 @@ class FakeHTTPClient(base_client.HTTPClient):
"datastore_version": 'all',
"tenant": 'all',
"auto_apply": 0,
"visible": 1}]})
"visible": 0,
"priority_apply": 0,
"apply_order": 5,
"is_admin": 1}]})
def get_modules_4321(self, **kw):
r = {'module': self.get_modules()[2]['modules'][0]}

@ -66,7 +66,10 @@ class TestModules(testtools.TestCase):
datastore_version="ds-version",
auto_apply=True,
visible=True,
live_update=False)
live_update=False,
priority_apply=False,
apply_order=5,
full_access=True)
self.assertEqual("/modules", path)
self.assertEqual("module", mod)
self.assertEqual(self.module_name, body["module"]["name"])
@ -77,6 +80,9 @@ class TestModules(testtools.TestCase):
self.assertTrue(body["module"]["auto_apply"])
self.assertTrue(body["module"]["visible"])
self.assertFalse(body["module"]["live_update"])
self.assertFalse(body["module"]["priority_apply"])
self.assertEqual(5, body["module"]["apply_order"])
self.assertTrue(body["module"]["full_access"])
def test_update(self):
resp = mock.Mock()

@ -679,7 +679,8 @@ class ShellTest(utils.TestCase):
'all_tenants': 0,
'module_type': 'type', 'visible': 1,
'auto_apply': 0, 'live_update': 0,
'name': 'mod1'}})
'name': 'mod1', 'priority_apply': 0,
'apply_order': 5}})
def test_module_update(self):
with mock.patch.object(troveclient.v1.modules.Module, '__repr__',

@ -43,7 +43,9 @@ class Modules(base.ManagerWithFind):
def create(self, name, module_type, contents, description=None,
all_tenants=None, datastore=None,
datastore_version=None, auto_apply=None,
visible=None, live_update=None):
visible=None, live_update=None,
priority_apply=None, apply_order=None,
full_access=None):
"""Create a new module."""
contents = utils.encode_data(contents)
@ -69,6 +71,12 @@ class Modules(base.ManagerWithFind):
body["module"]["visible"] = int(visible)
if live_update is not None:
body["module"]["live_update"] = int(live_update)
if priority_apply is not None:
body["module"]["priority_apply"] = int(priority_apply)
if apply_order is not None:
body["module"]["apply_order"] = apply_order
if full_access is not None:
body["module"]["full_access"] = int(full_access)
return self._create("/modules", body, "module")
@ -77,7 +85,9 @@ class Modules(base.ManagerWithFind):
all_tenants=None, datastore=None,
datastore_version=None, auto_apply=None,
visible=None, live_update=None,
all_datastores=None, all_datastore_versions=None):
all_datastores=None, all_datastore_versions=None,
priority_apply=None, apply_order=None,
full_access=None):
"""Update an existing module. Passing in
datastore=None or datastore_version=None has the effect of
making it available for all datastores/versions.
@ -115,6 +125,12 @@ class Modules(base.ManagerWithFind):
body["module"]["visible"] = int(visible)
if live_update is not None:
body["module"]["live_update"] = int(live_update)
if priority_apply is not None:
body["module"]["priority_apply"] = int(priority_apply)
if apply_order is not None:
body["module"]["apply_order"] = apply_order
if full_access is not None:
body["module"]["full_access"] = int(full_access)
url = "/modules/%s" % base.getid(module)
resp, body = self.api.client.put(url, body=body)

@ -1599,7 +1599,9 @@ def do_module_list(cs, args):
datastore = _find_datastore(cs, args.datastore)
module_list = cs.modules.list(datastore=datastore)
field_list = ['id', 'name', 'type', 'datastore',
'datastore_version', 'auto_apply', 'tenant', 'visible']
'datastore_version', 'auto_apply',
'priority_apply', 'apply_order', 'is_admin',
'tenant', 'visible']
is_admin = False
try:
try:
@ -1616,7 +1618,10 @@ def do_module_list(cs, args):
field_list = field_list[:-2]
utils.print_list(
module_list, field_list,
labels={'datastore_version': 'Version'})
labels={'datastore_version': 'Version',
'priority_apply': 'Priority',
'apply_order': 'Order',
'is_admin': 'Admin'})
@utils.arg('module', metavar='<module>',
@ -1646,16 +1651,29 @@ def do_module_show(cs, args):
'to. If not specified, module can be applied to all versions.')
@utils.arg('--auto_apply', action='store_true', default=False,
help='Automatically apply this module when creating an instance '
'or cluster.')
'or cluster. Admin only.')
@utils.arg('--all_tenants', action='store_true', default=False,
help='Module is valid for all tenants (Admin only).')
# This option is to suppress the module from module-list for non-admin
help='Module is valid for all tenants. Admin only.')
@utils.arg('--hidden', action='store_true', default=False,
help=argparse.SUPPRESS)
help='Hide this module from non-Admin. Useful in creating '
'auto-apply modules without cluttering up module lists. '
'Admin only.')
@utils.arg('--live_update', action='store_true', default=False,
help='Allow module to be updated even if it is already applied '
'to a current instance or cluster. Automatically attempt to '
'reapply this module if the contents change.')
@utils.arg('--priority_apply', action='store_true', default=False,
help='Sets a priority for applying the module. All priority '
'modules will be applied before non-priority ones. '
'Admin only.')
@utils.arg('--apply_order', type=int, default=5, choices=range(0, 10),
help='Sets an order for applying the module. Modules with a lower '
'value will be applied before modules with a higher '
'value. Modules having the same value may be '
'applied in any order (default %(default)s).')
@utils.arg('--full_access', action='store_true', default=None,
help="Marks a module as 'non-admin', unless an admin-only "
"option was specified. Admin only.")
@utils.service_type('database')
def do_module_create(cs, args):
"""Create a module."""
@ -1670,7 +1688,8 @@ def do_module_create(cs, args):
all_tenants=args.all_tenants, datastore=args.datastore,
datastore_version=args.datastore_version,
auto_apply=args.auto_apply, visible=not args.hidden,
live_update=args.live_update)
live_update=args.live_update, priority_apply=args.priority_apply,
apply_order=args.apply_order, full_access=args.full_access)
_print_object(module)
@ -1680,7 +1699,7 @@ def do_module_create(cs, args):
help='Name of the module.')
@utils.arg('--type', metavar='<type>', type=str, default=None,
help='Type of the module. The type must be supported by a '
'corresponding module plugin on the datastore it is '
'corresponding module driver plugin on the datastore it is '
'applied to.')
@utils.arg('--file', metavar='<filename>', type=argparse.FileType('rb', 0),
default=None,
@ -1702,22 +1721,22 @@ def do_module_create(cs, args):
help='Module is valid for all datastore versions.')
@utils.arg('--auto_apply', action='store_true', default=None,
help='Automatically apply this module when creating an instance '
'or cluster.')
'or cluster. Admin only.')
@utils.arg('--no_auto_apply', dest='auto_apply', action='store_false',
default=None,
help='Do not automatically apply this module when creating an '
'instance or cluster.')
'instance or cluster. Admin only.')
@utils.arg('--all_tenants', action='store_true', default=None,
help='Module is valid for all tenants (Admin only).')
help='Module is valid for all tenants. Admin only.')
@utils.arg('--no_all_tenants', dest='all_tenants', action='store_false',
default=None,
help='Module is valid for current tenant only (Admin only).')
# This option is to suppress the module from module-list for non-admin
help='Module is valid for current tenant only. Admin only.')
@utils.arg('--hidden', action='store_true', default=None,
help=argparse.SUPPRESS)
# This option is to allow the module to be seen from module-list for non-admin
help='Hide this module from non-admin users. Useful in creating '
'auto-apply modules without cluttering up module lists. '
'Admin only.')
@utils.arg('--no_hidden', dest='hidden', action='store_false', default=None,
help=argparse.SUPPRESS)
help='Allow all users to see this module. Admin only.')
@utils.arg('--live_update', action='store_true', default=None,
help='Allow module to be updated or deleted even if it is already '
'applied to a current instance or cluster. Automatically '
@ -1726,6 +1745,24 @@ def do_module_create(cs, args):
default=None,
help='Restricts a module from being updated or deleted if it is '
'already applied to a current instance or cluster.')
@utils.arg('--priority_apply', action='store_true', default=None,
help='Sets a priority for applying the module. All priority '
'modules will be applied before non-priority ones. '
'Admin only.')
@utils.arg('--no_priority_apply', dest='priority_apply', action='store_false',
default=None,
help='Removes apply priority from the module. Admin only.')
@utils.arg('--apply_order', type=int, default=None, choices=range(0, 10),
help='Sets an order for applying the module. Modules with a lower '
'value will be applied before modules with a higher '
'value. Modules having the same value may be '
'applied in any order (default %(default)s).')
@utils.arg('--full_access', action='store_true', default=None,
help="Marks a module as 'non-admin', unless an admin-only "
"option was specified. Admin only.")
@utils.arg('--no_full_access', dest='full_access', action='store_false',
default=None,
help='Restricts modification access for non-admin. Admin only.')
@utils.service_type('database')
def do_module_update(cs, args):
"""Update a module."""
@ -1739,7 +1776,10 @@ def do_module_update(cs, args):
description=args.description, all_tenants=args.all_tenants,
auto_apply=args.auto_apply, visible=visible,
live_update=args.live_update, all_datastores=args.all_datastores,
all_datastore_versions=args.all_datastore_versions, **datastore_args)
all_datastore_versions=args.all_datastore_versions,
priority_apply=args.priority_apply,
apply_order=args.apply_order, full_access=args.full_access,
**datastore_args)
_print_object(updated_module)