Merge "Add module mangement to Trove"
This commit is contained in:
commit
ac1d0a3324
835
specs/mitaka/module-management.rst
Normal file
835
specs/mitaka/module-management.rst
Normal file
@ -0,0 +1,835 @@
|
||||
..
|
||||
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||
License.
|
||||
|
||||
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||
|
||||
Sections of this template were taken directly from the Nova spec
|
||||
template at:
|
||||
https://github.com/openstack/nova-specs/blob/master/specs/template.rst
|
||||
|
||||
..
|
||||
This template should be in ReSTructured text. The filename in the git
|
||||
repository should match the launchpad URL, for example a URL of
|
||||
https://blueprints.launchpad.net/trove/+spec/awesome-thing should be named
|
||||
awesome-thing.rst.
|
||||
|
||||
Please do not delete any of the sections in this template. If you
|
||||
have nothing to say for a whole section, just write: None
|
||||
|
||||
Note: This comment may be removed if desired, however the license notice
|
||||
above should remain.
|
||||
|
||||
|
||||
=================
|
||||
Module Management
|
||||
=================
|
||||
|
||||
.. If section numbers are desired, unindent this
|
||||
.. sectnum::
|
||||
|
||||
.. If a TOC is desired, unindent this
|
||||
.. contents::
|
||||
|
||||
Historically, Trove has supported open source databases. As more datastores
|
||||
were added it was inevitable that this would eventually change to include
|
||||
proprietary databases as well. Starting with the Liberty release this is the
|
||||
case (support for Vertica and DB2 now being available) and with this comes the
|
||||
issue of managing the licenses of said databases. In addition, operators may
|
||||
find it useful to include other software on their images that may require
|
||||
'activation' by end-users (for example New Relic's analytical suite). A method
|
||||
of activating this software is also needed.
|
||||
|
||||
The concept of applying a 'license' or 'activation' or 'configuration' of this
|
||||
third-party software is what is referred to herein as 'module' management.
|
||||
|
||||
Launchpad Blueprint:
|
||||
https://blueprints.launchpad.net/trove/+spec/module-management
|
||||
|
||||
|
||||
Problem Description
|
||||
===================
|
||||
|
||||
Users of a particular cloud may be willing to purchase a license to use a
|
||||
datastore from the cloud vendor on a pay-as-you-go based model, and this is the
|
||||
model assumed at the moment (as both Vertica and DB2 redstack images include a
|
||||
fully-functional and licensed database). It is also desirable, however, that
|
||||
users be allowed to 'bring their own license.' In this scenario the user
|
||||
provides a license file that the database requires, and as such a mechanism
|
||||
needs to be in place to 'activate' and/or 'renew' the license through the use
|
||||
of the user provided file.
|
||||
|
||||
This same problem exists for any other proprietary software that an operator
|
||||
may wish to include in their Trove images. These software packages also
|
||||
typically require activation through the use of a license key or file (such as
|
||||
New Relic [1]_) or configuration of some kind.
|
||||
|
||||
|
||||
Proposed Change
|
||||
===============
|
||||
|
||||
Trove's responsiblity towards module management will be restricted to the scope
|
||||
of encrypting and storing the required data file (for example, a license file)
|
||||
and providing a way to apply this data to a new or existing Trove instance or
|
||||
cluster. A mechanism will be put in place to allow end users the ability to
|
||||
manage adding, deleting, listing, viewing and updating these module data files.
|
||||
|
||||
Methods to apply, remove, query and retrieve the actual 'module' data file on
|
||||
the Trove instance will also be provided.
|
||||
|
||||
A repeatable option (--module) will be added to the create and cluster-create
|
||||
commands to allow adhoc module selection. In addition, modules can be set to
|
||||
auto-apply, which will have the effect of the Guest Agent installing that
|
||||
module on any instance created with the relevant datastore combination.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The following configuration changes are anticipated.
|
||||
|
||||
A way of specifying valid module 'types' will be needed for proper validation
|
||||
on module create:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
cfg.StrOpt('module_types', default=None,
|
||||
help='A list of module types supported.'),
|
||||
|
||||
A key will be needed in order to be able to encrypt the module data file before
|
||||
storing it in the database:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
cfg.StrOpt('module_aes_cbc_key', default='module_aes_cbc_key',
|
||||
help='OpenSSL aes_cbc key for module encryption.'),
|
||||
|
||||
Database
|
||||
--------
|
||||
|
||||
A new table (modules) will be added to the Trove schema:
|
||||
|
||||
================= ============ =========== ==============================
|
||||
Column Type Allow Nulls Description
|
||||
================= ============ =========== ==============================
|
||||
id varchar(36) No ID of module (autogenerated)
|
||||
type varchar(255) No Type of module. This will
|
||||
correlate directly to the
|
||||
required plugin (i.e. a
|
||||
plugin must exist of this
|
||||
'type')
|
||||
tenant_id varchar(36) No ID of tenant to apply
|
||||
module to. 'all' means module
|
||||
applies to all tenants
|
||||
datastore varchar(36) No Name of datastore to apply
|
||||
module to. 'all' means module
|
||||
applies to all datastores
|
||||
datastore_version varchar(36) No Name of datastore version to
|
||||
apply module to. 'all' means
|
||||
module applies to all
|
||||
datastores
|
||||
name varchar(255) No Name of module
|
||||
description varchar(512) Yes Description of module
|
||||
auto_apply tinyint(1) No Should this module be
|
||||
automatically applied during
|
||||
instance/cluster create. Will
|
||||
default to 'no' if not
|
||||
provided
|
||||
visible tinyint(1) No Should this module be
|
||||
visible to non-admin users.
|
||||
Will default to 'yes' if not
|
||||
provided
|
||||
live_update tinyint(1) No Can this module be updated
|
||||
while applied-to instances
|
||||
still exist. If set to 'no'
|
||||
all instances must have the
|
||||
corresponding module removed
|
||||
before it can be updated.
|
||||
Defaults to 'no'
|
||||
contents blob No Encrypted module contents
|
||||
md5 varchar(32) No MD5 hash of module contents
|
||||
created DateTime No Created date
|
||||
updated DateTime No Updated date
|
||||
deleted tinyint(1) Yes Deleted flag
|
||||
deleted_at DateTime Yes Deleted date
|
||||
================= ============ =========== ==============================
|
||||
|
||||
A unique index will be created from the (datastore, datastore_version, name)
|
||||
fields, to allow easy determination of the correct module to apply to a
|
||||
specific instance.
|
||||
|
||||
An MD5 hash of the module contents will be stored in the module record as
|
||||
well. This hash will be reported back when querying the module from a
|
||||
running instance, as the original module record could have been modified with
|
||||
new contents after it was initially applied.
|
||||
|
||||
On installing the module contents on a given instance, a file will be created
|
||||
in a know location using <datastore>-<datastore_version>-<name>.lic as a
|
||||
pattern.
|
||||
|
||||
Creating modules that apply to 'all' tenants or 'all' datastores and ones that
|
||||
are auto-applied will require admin credentials.
|
||||
|
||||
Setting a module to 'not' visible is also an admin-only option. This will
|
||||
allow administrators to 'hide' modules from users if they so desire. Modules
|
||||
that are marked visible=False will not be returned in commands such as list or
|
||||
show unless requested by an admin user. Non-admin users won't be able to apply
|
||||
a non-visible module, however they will still be auto-applied if so designated.
|
||||
|
||||
A new table (instance_modules) will be added to the Trove schema to track which
|
||||
modules have been applied to each instance:
|
||||
|
||||
================= ============ =========== ==============================
|
||||
Column Type Allow Nulls Description
|
||||
================= ============ =========== ==============================
|
||||
id varchar(36) No ID of association
|
||||
(autogenerated)
|
||||
instance_id varchar(36) No ID of instance
|
||||
module_id varchar(36) No ID of module
|
||||
md5 varchar(32) No MD5 hash of module contents
|
||||
created DateTime No Created date
|
||||
updated DateTime No Updated date
|
||||
deleted tinyint(1) Yes Deleted flag
|
||||
deleted_at DateTime Yes Deleted date
|
||||
================= ============ =========== ==============================
|
||||
|
||||
Public API
|
||||
----------
|
||||
|
||||
New ReST API calls will be added to the Trove infrastructure. These fall into
|
||||
two categories - ones to manage the maintenance of the actual modules, and
|
||||
ones to handle the instance interactions.
|
||||
|
||||
In addition, the create and cluster-create calls will be enhanced.
|
||||
|
||||
Module Maintenance
|
||||
..................
|
||||
|
||||
To retrieve a list of all modules that can be applied, the following request
|
||||
would be made:
|
||||
|
||||
Request::
|
||||
|
||||
GET v1/modules
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
'modules' : [
|
||||
{
|
||||
'id': <id>,
|
||||
'type': 'vertica_license',
|
||||
'tenant': <id>,
|
||||
'datastore': 'vertica',
|
||||
'datastore_version': 'all',
|
||||
'name': '100GB',
|
||||
'description': 'Vertica license for 100GB',
|
||||
'auto_apply': False,
|
||||
'visible': True, # returned for admin only
|
||||
'live_update': False,
|
||||
'md5': <md5>,
|
||||
'created': <date>,
|
||||
'updated': <date>,
|
||||
},
|
||||
{
|
||||
'id': <id>,
|
||||
'type': 'new_relic_activation',
|
||||
'tenant': <id>,
|
||||
'datastore': 'all',
|
||||
'datastore_version': 'all',
|
||||
'name': 'new_relic',
|
||||
'description': 'New Relic activation',
|
||||
'auto_apply': True,
|
||||
'visible': True, # returned for admin only
|
||||
'live_update': True,
|
||||
'md5': <md5>,
|
||||
'created': <date>,
|
||||
'updated': <date>,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
|
||||
Note that an admin user will receive the modules for all tenants, whereas
|
||||
regular users will see modules for their tenant only.
|
||||
|
||||
To retrieve a list of valid modules that can be applied to a specific
|
||||
datastore, the following request would be made:
|
||||
|
||||
Request::
|
||||
|
||||
GET v1/datastores/{datastore_id}/modules
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
'modules' : [
|
||||
{
|
||||
'id': <id>,
|
||||
'type': 'new_relic_activation',
|
||||
'tenant': <id>,
|
||||
'datastore': 'all',
|
||||
'datastore_version': 'all',
|
||||
'name': 'new_relic',
|
||||
'description': 'New Relic activation',
|
||||
'auto_apply': True,
|
||||
'visible': True, # returned for admin only
|
||||
'live_update': True,
|
||||
'md5': <md5>,
|
||||
'updated': <date>,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
|
||||
To show the details of a particular module, the following request would be
|
||||
made:
|
||||
|
||||
Request::
|
||||
|
||||
GET v1/modules/<id>
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
'id': <id>,
|
||||
'type': 'new_relic_activation',
|
||||
'tenant': <id>,
|
||||
'datastore': 'all',
|
||||
'datastore_version': 'all',
|
||||
'name': 'new_relic',
|
||||
'description': 'New Relic activation',
|
||||
'auto_apply': True,
|
||||
'visible': True, # returned for admin only
|
||||
'live_update': True,
|
||||
'md5': <md5>,
|
||||
'created': <date>,
|
||||
'updated': <date>,
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
404 Not Found
|
||||
|
||||
To create a module, the following request would be made:
|
||||
|
||||
Request::
|
||||
|
||||
POST /v1.0/modules
|
||||
{
|
||||
'type': 'vertica_license',
|
||||
'tenant': <id>,
|
||||
'datastore': 'vertica',
|
||||
'datastore_version': 'all',
|
||||
'name': '100GB',
|
||||
'description': 'Vertica license for 100GB',
|
||||
'auto_apply': False,
|
||||
'visible': False, # admin-only option
|
||||
'live_update': True,
|
||||
'contents': <module_contents>,
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
"module": {
|
||||
'id': <id>,
|
||||
'type': 'vertica_license',
|
||||
'tenant': <id>,
|
||||
'datastore': 'vertica',
|
||||
'datastore_version': 'all',
|
||||
'name': '100GB',
|
||||
'description': 'Vertica license for 100GB',
|
||||
'auto_apply': False,
|
||||
'visible': False, # returned for admin only
|
||||
'live_update': True,
|
||||
'md5': <md5>,
|
||||
'created': <date>,
|
||||
'updated': <date>,
|
||||
}
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
400 Bad Request
|
||||
|
||||
To update a module, the following request would be made:
|
||||
|
||||
Request::
|
||||
|
||||
PATCH /v1.0/modules/{module_id}
|
||||
{
|
||||
'type': 'new_type',
|
||||
'tenant': <id>,
|
||||
'datastore': 'new_datastore',
|
||||
'datastore_version': 'new_datastore_version',
|
||||
'name': 'new_name',
|
||||
'description': 'new_description',
|
||||
'auto_apply': True,
|
||||
'visible': False, # admin-only option
|
||||
'live_update': True,
|
||||
'contents': <module_contents>,
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
"module": {
|
||||
'id': <id>,
|
||||
'type': 'new_type',
|
||||
'tenant': <id>,
|
||||
'datastore': 'new_datastore',
|
||||
'datastore_version': 'new_datastore_version',
|
||||
'name': 'new_name',
|
||||
'description': 'new_description',
|
||||
'auto_apply': True,
|
||||
'visible': False, # returned for admin only
|
||||
'live_update': True,
|
||||
'md5': <new_md5>,
|
||||
'created': <date>,
|
||||
'updated': <date>,
|
||||
}
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
400 Bad Request
|
||||
404 Not Found
|
||||
|
||||
To delete a module, the following request would be made:
|
||||
|
||||
Request::
|
||||
|
||||
DELETE /v1.0/modules/{module_id}
|
||||
{
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
This operation has no response body
|
||||
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
404 Not Found
|
||||
|
||||
To query which instances have a particular module applied, the following
|
||||
request would be made:
|
||||
|
||||
Request::
|
||||
|
||||
GET v1/modules/{module_id}/instances
|
||||
{
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
'instance': <id>,
|
||||
'modules' : [
|
||||
{
|
||||
'name': '100GB',
|
||||
'id': <id>,
|
||||
'md5': <md5>,
|
||||
'installed': <date>,
|
||||
},
|
||||
{
|
||||
'name': 'new_relic',
|
||||
'id': <id>,
|
||||
'md5': <md5>,
|
||||
'installed': <date>,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
404 Not Found
|
||||
|
||||
Instance Interaction
|
||||
....................
|
||||
|
||||
To apply modules to an instance, the following request would be made:
|
||||
|
||||
Request::
|
||||
|
||||
POST v1/{tenant_id}/instances/{instance_id}/modules
|
||||
{
|
||||
'modules' : [
|
||||
{
|
||||
"id": <id>,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
'type': 'vertica_license',
|
||||
'datastore': 'vertica',
|
||||
'datastore_version': 'all',
|
||||
'name': '100GB',
|
||||
'md5': <md5>,
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
202 Success
|
||||
400 Bad Request
|
||||
404 Not Found
|
||||
|
||||
To query an instance about installed modules, the following request would be
|
||||
made:
|
||||
|
||||
Request::
|
||||
|
||||
GET v1/{tenant_id}/instances/{instance_id}/modules
|
||||
{
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
'modules' : [
|
||||
{
|
||||
'type': 'vertica_license',
|
||||
'datastore': 'vertica',
|
||||
'datastore_version': 'all',
|
||||
'name': '100GB',
|
||||
'filename': 'vertica-all-100GB.lic',
|
||||
'md5': <md5>,
|
||||
'installed': <date>,
|
||||
'status': 'OK',
|
||||
'error_message': None,
|
||||
},
|
||||
{
|
||||
'type': 'new_relic_activation',
|
||||
'datastore': 'all',
|
||||
'datastore_version': 'all',
|
||||
'name': 'new_relic',
|
||||
'filename': 'all-all-new_relic.lic',
|
||||
'md5': <md5>,
|
||||
'installed': <date>,
|
||||
'status': 'FAILED',
|
||||
'error_message': 'New Relic binaries not found',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
404 Not Found
|
||||
|
||||
To retrieve a module from an instance, the following request would be made:
|
||||
|
||||
Request::
|
||||
|
||||
GET v1/{tenant_id}/instances/{instance_id}/modules/{module_id}
|
||||
{
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
'filename': 'vertica-all-100GB.lic',
|
||||
'contents': <module_contents>,
|
||||
'md5': <md5>,
|
||||
}
|
||||
|
||||
Response Codes::
|
||||
|
||||
200 Success
|
||||
404 Not Found
|
||||
|
||||
To delete a module from an instance, the following request would be made:
|
||||
|
||||
Request::
|
||||
|
||||
DELETE v1/{tenant_id}/instances/{instance_id}/modules/{module_id}
|
||||
{
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
This operation has no response body
|
||||
|
||||
Response Codes::
|
||||
|
||||
202 Success
|
||||
404 Not Found
|
||||
|
||||
Creation Enhancements
|
||||
.....................
|
||||
|
||||
The instance create API will be enhanced to include a module field, containing
|
||||
a list of modules to apply. These will be sent down during the normal
|
||||
'prepare' call and the appropriate plugin called once this instance has been
|
||||
provisioned correctly.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
'modules' : [
|
||||
{
|
||||
"id": <id>,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
In a similar manner, the cluster create API will also be enhanced to include
|
||||
module information in the instances field, as is currently done with flavors,
|
||||
AZs, etc.
|
||||
|
||||
|
||||
Public API Security
|
||||
-------------------
|
||||
|
||||
Since the file will be transmitted clear text across the management
|
||||
network, there is a chance that the module can be intercepted if the network
|
||||
is compromised.
|
||||
|
||||
It should be ensured that each plugin created does not 'execute' the contents
|
||||
of the supplied module data file, as this would present the opportunity for a
|
||||
security breach. This seems unlikely though (and will not be the case for the
|
||||
proposed implementations) as most module data files will be passed to another
|
||||
process for validation, and it is up to that process to ensure proper security
|
||||
is maintained. Code reviews will be vital to make sure no plugin accidentally
|
||||
executes this data.
|
||||
|
||||
Python API
|
||||
----------
|
||||
|
||||
New methods will be added to the Python API to facilitate the licensing.
|
||||
A few existing methods will need to be extended as well.
|
||||
|
||||
Module Maintenance
|
||||
..................
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def module_list(self, datastore=None):
|
||||
"""Get a list of all modules that can be applied. Return only
|
||||
those that apply to the datastore if it is passed in.
|
||||
"""
|
||||
|
||||
def module_list_instances(self, module):
|
||||
"""Get a list of all instances that have a given module applied."""
|
||||
|
||||
def module_show(self, module):
|
||||
"""Show the details of the module."""
|
||||
|
||||
def module_create(self, module_type, name, description, contents,
|
||||
datastore, datastore_version='all', auto_apply=False,
|
||||
all_tenants=False, visible=True, live_update=False):
|
||||
"""Create a new module."""
|
||||
|
||||
def module_update(self, module, module_type=None, name=None,
|
||||
description=None, contents=None, datastore=None,
|
||||
datastore_version=None, auto_apply=None,
|
||||
all_tenants=None, visible=None, live_update=None):
|
||||
"""Update an existing module."""
|
||||
|
||||
def module_delete(self, module):
|
||||
"""Delete a module."""
|
||||
|
||||
Instance Interaction
|
||||
....................
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def module_apply(self, instance, modules):
|
||||
"""Apply modules to an instance."""
|
||||
|
||||
def module_query(self, instance):
|
||||
"""Query an instance about installed modules."""
|
||||
|
||||
def module_retrieve(self, instance, module=None, filename=None):
|
||||
"""Retrieve the module data file from an instance and save it in
|
||||
filename. If module is not supplied, retrieve all the modules.
|
||||
If filename is not supplied, use the generated filename found
|
||||
on the instance.
|
||||
"""
|
||||
|
||||
def module_remove(self, instance, module):
|
||||
"""Remove a module from an instance."""
|
||||
|
||||
Creation Enhancements
|
||||
.....................
|
||||
|
||||
For instance.create, the modules field will be added to the call:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def create(self, name, flavor_id, volume=None, databases=None, users=None,
|
||||
restorePoint=None, availability_zone=None, datastore=None,
|
||||
datastore_version=None, nics=None, configuration=None,
|
||||
replica_of=None, slave_of=None, replica_count=None,
|
||||
modules=None):
|
||||
"""Create (boot) a new instance."""
|
||||
|
||||
For cluster.create, the modules field will be added to the
|
||||
['cluster']['instances'] data structure that is already being passed in.
|
||||
|
||||
CLI (python-troveclient)
|
||||
------------------------
|
||||
|
||||
The following Trove CLI commands (upon completion) will be fully functional
|
||||
|
||||
- module-list Displays all modules for the tenant.
|
||||
- module-show Shows details for a particular module resource.
|
||||
- module-create Creates a new module resource.
|
||||
- module-update Updates module details for a particular module
|
||||
resource.
|
||||
- module-delete Delete a module resource.
|
||||
|
||||
- module-apply Apply the given modules to a Trove instance.
|
||||
- module-query Query the given Trove instance for any installed
|
||||
modules.
|
||||
- module-retrieve Retrieves the current modules from a Trove instance.
|
||||
- module-remove Remove a module from a Trove instance.
|
||||
|
||||
- create --module [--module]
|
||||
Creates a new instance and applies the given modules.
|
||||
|
||||
- cluster-create --instance=module=<id>[,module=<id>]
|
||||
Creates a new cluster and applies the given modules to
|
||||
each instance.
|
||||
|
||||
Internal API
|
||||
------------
|
||||
|
||||
Changes also need to be made to the internal API to include any module IDs as
|
||||
a part of the message body that is sent to the task manager.
|
||||
|
||||
The API server will need to make calls to the Guest Agent for the instance
|
||||
interaction type commands.
|
||||
|
||||
Guest Agent
|
||||
-----------
|
||||
|
||||
In the Guest Agent, the modules will be managed with a plugin style
|
||||
architecture based on the stevedore.driver.DriverManager paradym. Each plugin
|
||||
will need to implement 'apply', 'query' and 'remove' actions. The 'query'
|
||||
action will need to report the status of the module 'apply' action. This
|
||||
would report (at a minimum) 'OK' or 'FAILED' plus any other state that seems
|
||||
reasonable for users of the relevant software. If possible, the
|
||||
'error_message' field should be filled with useful information if an error
|
||||
occurs.
|
||||
|
||||
A simple plugin 'base class' that defines the contract will be provided. It
|
||||
will also provide functionality such as placing the file contents into a
|
||||
specified location and retrieving the file will be added. This can be used
|
||||
as the basis for all other plugins.
|
||||
|
||||
The Guest Agent code will use the module 'type' to determine if a plugin exists
|
||||
for the given module. If no plugin can be found, then an error will be written
|
||||
to the log and processing stopped.
|
||||
|
||||
To provide a concrete, real-world plugin implementation, a Vertica license
|
||||
module plugin will be created to allow licenses to be applied to a Vertica
|
||||
datastore. A New Relic plugin will also be created to illustrate activation of
|
||||
other third party software on a guest image.
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
|
||||
None
|
||||
|
||||
|
||||
Dashboard Impact (UX)
|
||||
=====================
|
||||
|
||||
A multi-dropdown will need to be added to the instance create dialog that
|
||||
contains all modules for the selected datastore. These modules, along with
|
||||
any auto-apply ones, will need to be sent along on the create call. The same
|
||||
will be needed for the cluster create dialog.
|
||||
|
||||
A module detail panel will need to be created. This panel will have fields
|
||||
representing the attributes of a module (see module-create command).
|
||||
|
||||
A 'modules' list panel will need to be created. This will have buttons for
|
||||
'delete' and 'update' and will have a link to the detail page for each listed
|
||||
module. This will be a high-level panel, similar to 'Instances.'
|
||||
|
||||
The instance list panel will need to have a new action added: 'apply module.'
|
||||
This will cause a pop-up where the available modules are displayed. The
|
||||
selected module will then be passed in to the module-apply command.
|
||||
|
||||
The instance detail panel will need to run 'module-query' and display the
|
||||
results in a new section 'modules.' Alternately, a link could be placed here
|
||||
that would open a module list panel with the results of the 'module-query'
|
||||
call. Here, buttons for 'module-remove' and 'module-retrieve' would be
|
||||
needed.
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Assignee(s)
|
||||
-----------
|
||||
|
||||
Primary assignee:
|
||||
[peterstac]
|
||||
|
||||
Milestones
|
||||
----------
|
||||
|
||||
Mitaka
|
||||
|
||||
Work Items
|
||||
----------
|
||||
|
||||
The work will be undertaken with the following tasks:
|
||||
|
||||
* Client (Python and CLI) changes
|
||||
* Server (API) changes
|
||||
* Guest Agent module plugin infrastructure
|
||||
* Vertica/New Relic plugin implementation
|
||||
|
||||
|
||||
Upgrade Implications
|
||||
====================
|
||||
|
||||
Since this change is net-new, no upgrade issues are expected.
|
||||
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
None.
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
Generic int-tests will be written, however these will not be run under MySQL
|
||||
testing as it requires no module-based handling.
|
||||
|
||||
|
||||
Documentation Impact
|
||||
====================
|
||||
|
||||
This is a net-new feature, and as such will require documentation.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] nrsysmond-config --set license_key=<new_relic_key>.
|
||||
|
||||
|
||||
Appendix
|
||||
========
|
||||
|
||||
None
|
Loading…
Reference in New Issue
Block a user