6f5d350f3a
Since Trove now supports proprietary databases, a mechanism for handling licensing for said databases is needed. Other third-party 'modules' may also need configuration or activation. A proposal for allowing end users the ability to manage adding, deleting, listing, viewing and updating the corresponding module data file is included in this spec. Methods to apply, remove, query and retrieve the actual module data file on the Trove instance will also be provided. Change-Id: I3e8cc4548fe5b48cc53f4da55e4f1f40573fa057
836 lines
26 KiB
ReStructuredText
836 lines
26 KiB
ReStructuredText
..
|
|
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
|