.. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode ==================================== Manage / Unmanage with Share Servers ==================================== https://blueprints.launchpad.net/manila/+spec/manage-unmanage-with-share-servers This spec proposes enhancement to manila's Manage/Unmanage functionality so that drivers running in ``DHSS=True`` mode can: * import existing shares and snapshots, bringing them under manila's management. * release shares and their snapshots from manila's management without destroying them. Problem description =================== Cloud administrators cannot bring pre-existing shares under manila's management when those shares pertain to a back end driver operating in ``driver_handles_share_servers = True`` mode `[1]`_. For brevity, we will refer to this mode as ``DHSS = True`` in this document. Since ``DHSS = True`` is the mode in which manila guarantees secure multi-tenant isolation, cloud-users end up having to make an unfortunate tradeoff, using their imported shares in ``DHSS = False`` mode. We lack manage/unmanage for ``DHSS=True`` mode drivers today because of the following complexities: * **Share server setup and networking:** In ``DHSS = True`` mode, manila provisions and manages the lifecycle of share servers for each of the tenant's networks. When creating the share servers, manila has to allocate network ports (and later de-allocate them when share servers are deleted). However, in ``DHSS = False`` mode the concept of share servers do not apply, it is up to the administrator and the driver to do whatever is necessary for the back end's export locations to be accessible from the client hosts. * **Managing shares:** In ``DHSS = False``, manila requests the driver to find a pre-existing share in the configured back end based on an export location given at the API call. Shares being managed are expected to be accessible from client hosts as any share created from manila would. In ``DHSS = True`` mode, any existing share would be in a share server, therefore to manage a share, one would have to manage its share server first and then manage the share within the share server. * **Managing snapshots:** Since currently there is no way to manage a share in manila in ``DHSS = True`` mode, there is no way to manage snapshots as well. Additionally, unmanaging of snapshots is currently disallowed. * **Lifecycle of a share server:** In ``DHSS = True`` mode, manila provisions the share servers and network resources associated with it, therefore it also deletes them when appropriate (like when the share server is not serving any shares). In ``DHSS = False``, manila only manages the lifecycle of the resources it creates, such as shares, snapshots, replicas and access rules. As per the aspects mentioned previously, it becomes clear that to manage a share or snapshot in ``DHSS = True`` mode, one needs an API to manage a share server first. Use Cases ========= Cloud administrators that have been using storage devices to provision shares and their snapshots should have the ability to import the existing shares when migrating over to manila. Manila drivers that support ``DHSS = True`` mode could accomplish that if there was such API implemented in Manila. Similarly, manila shares and snapshots could be unmanaged in ``DHSS = True`` mode to be migrated to another system or to have maintenance performed, but this would only make sense if they could be managed back. Proposed change =============== The following changes are proposed: * **Add a Manage Share Server API:** Through this API, share servers shall be managed. Their state transitions will be similar to when managing shares. In other words, they will be created with the status ``manage_starting`` and transition either to ``available`` in case of success or to ``manage_error`` otherwise. The following parameters are expected to be supplied: * **Host:** back end name ("@"). * **Share Network:** share network associated with the neutron network the share server is connected to. * **Identifier:** a driver-specific share server identifier required by the driver to manage the share server. * **Driver Options:** optional list of driver-specific key-value pairs that may be necessary to assist the driver managing the share server. * **Network allocations pre-requisites:** Since connectivity is expected between an existing share server and the client hosts, the share server will already have interfaces with MAC and IP addresses but neutron and manila know nothing of them. Before taking the share server into manila's management, the cloud administrator must create neutron ports corresponding to these share server interfaces, allocate the proper addresses to these ports, and set each of the port's ``device_owner`` to ``manila:share``. When managing the share server, the share server IP addresses will be requested by the driver and once retrieved, matched with neutron ports owned by ``manila:share`` present in the neutron subnet associated with the share network provided or configured network plugin. If not all allocations are found, the operation is aborted with an error. When using the Standalone Network Plugin, this step is not required since Neutron is not involved. * **Security services pre-requisites:** Any pre-existing authentication services set up with share servers to be managed must be configured as security services associated with the share network before managing a share server. Manila offers no capability to update security services on existing manila provisioned share servers today. This specification does not add an ability to update security services on managed share servers. * **Implementation:** When a request to manage a share server is received, the API parameters are validated and then a share server model with the ``is_imported`` field set is created. The share service that runs the back end stanza specified in the host specified is invoked through RPC, and the driver method ``manage_server`` is invoked to obtain the back end details and network allocations of the share server to be managed. The back end details returned are saved in the database and the network allocations retrieved are then passed to the configured network plugins to validate the network allocations previously created by the admin. After the validation, the network allocation is saved in manila's ``network_allocations`` database table. * **Add a Unmanage Share Server API:** Through this API, share servers shall be unmanaged. No parameters are required beyond the ID of the share server to be unmanaged. The share server specified is removed from manila database. We are not going to remove the allocations, as for any existing untracked resource in a network, it will be bound to result in conflicts in the future if the ports are de-allocated. It will be up to the administrator to de-allocate the ports if desired. The state transitions will be similar to unmanaging a share, thus it would transition from ``available`` to ``unmanage_starting``, then either to ``deleted`` in case of success or to ``unmanage_error`` otherwise. * **Implementation:** When a request to unmanage a share server is received, the API parameters are validated and then the share service responsible by the given share server is invoked through RPC. The driver is then invoked to perform any operation that may be necessary to proceed with unmanaging, and finally the network allocations are deleted from manila's ``network_allocations`` database table. * **Add share_server_id parameter to Manage Share API:** Whenever managing a share and passing a share type defined with ``driver_handles_share_servers`` set to ``True``, the parameter share_server_id will be required, else the API will return ``400 BadRequest``. The Manage Snapshot API does not require this parameter since it will read it from the parent share's model. * **Allow unmanaging of shares and snapshots in ``DHSS = True`` mode:** Currently it is not allowed to unmanage shares and snapshots that were created in this mode. We will change the API to allow it (and thus no longer return an error) when the newer microversion is specified. There are no behavioral changes required other than this one at the API layer. * **Update driver interface of Manage/Unmanage Share and Snapshot to pass the share server:** Since the existing implementation has never expected to work in ``DHSS = True`` driver mode, the driver interfaces do not include a share server parameter. The driver interfaces will be updated to receive the share server model to perform for manage and unmanage operations of shares and snapshots. The parameter is optional, so it will not affect existing ``DHSS = False`` driver implementations in any way. * **Prevent automatic deletion of managed share servers:** As opposed to share servers created by manila, we will not attempt to automatically delete managed share servers that have no manila shares, as there may be existing shares unknown to manila within it. * **Manual deletion of managed share servers:** Share servers managed by manila may contain existing shares and not all of those shares may be managed by manila. If admins decide to delete the share server, it will be up to the admin to try to delete it along with any existing shares that are unknown to manila. However, it will be up to the driver to allow the operation to succeed, as some back ends do not allow the share server to be deleted if there are remaining shares. If that is the case, the share server will go to error state and the admin will have to either unmanage it, or delete the remaining shares (that are unknown to manila) either manually in the back end or by managing them. Alternatives ------------ Instead of adding the Manage Share Server API, a previously discussed approach was a Manage Share API that would have two phases in ``DHSS = True`` mode. Such approach presents the following characteristics: * Same complexity and amount of technical work as the proposed solution, but done by a single API. * Several additional parameters that make sense only for ``DHSS = True`` mode. * More complex error handling, as there would need to be statuses and errors specific to each phase (managing a share server or managing a share within). * The user experience degrades when we have a single API behaving so differently, as the user can get confused when using it on both driver modes. Alternatively to requiring the neutron ports to be created by the admin before managing a share server, we could have manila create the network allocations when managing the share servers, as this would be easier for the admin when doing a "bulk" manage of share servers. The downsides to this approach are: * It is reasonable to assume that the share servers we are managing are already connected to the share networks and accessible by hosts. Therefore, it is correct to also assume that a port in neutron should already exist to prevent the network allocations of those share servers from conflicting with other resources in the same subnet. * When unmanaging a share server, we would not remove the network allocations, since it is assumed these share servers may remain connected to the share networks and would need those network allocations to prevent conflicts with other resources in the same subnet. This behavior would be asymmetrical to creating the ports when managing share servers. If resorting to not change the APIs, there is no way to import existing resources to be managed by manila. If this is not implemented, the administrators would need to manage their storage devices outside of manila, or accept the limitation of using only ``DHSS = False`` mode, lacking the benefits present in the ``DHSS = True``. Data model impact ----------------- Since there is the need to distinguish share servers created by manila from managed ones, we proposed the addition of a boolean column in the ``ShareServer`` table named ``is_imported`` defaulting to ``False``. The database schema upgrade will add the column with the value ``False`` for all existing share servers, while the database schema downgrade will remove the column. REST API impact --------------- There are a couple of new APIs introduced and a few others changed. The policy for both new APIs are admin-only like the existing manage/unmanage APIs. There are no changes for the existing policies. The API microversion will be bumped to the next one for the listed changes. **Managing a share server**:: POST /v2/{tenant-id}/share-servers/manage Request parameters:: { "share_server": { "host": "host@backend", "share_network_id": "e76be4e9-4054-4df3-9e5c-178e68fb0949", "identifier": "0e73a5e1-e233-4635-b6df-db568307385f", "driver_options": { "key1": "value1", "key2": "value2", "key3": "value3" } } } Parameter ``driver_options`` is optional. If any of the other parameters is missing or invalid, the API will return ``400 BadRequest``. Response:: Code: 202 Accepted { "share_server": "status": "manage_starting", "created_at": 2018-09-17T18:05:34.000000, "updated_at": 2018-09-17T18:05:34.000000, "share_network_id": "e76be4e9-4054-4df3-9e5c-178e68fb0949", "share_network_name": "my_share_net", "host": "host@backend", "project_id": "0ebbe03068554da9b9d9ad11983bb08a", "id": "fa4e4d78-d3d9-46cf-8e61-514da5008cee", "is_imported": "True", "backend_details": { "key1": "value1", "key2": "value2", "key3": "value3" } } } **Unmanaging a share server**:: POST /v2/{tenant-id}/share-servers/{share_server_id}/action Request parameters:: { "unmanage": null } Response:: Code: 202 Accepted * If the share server does not exist the API will return ``404 NotFound``. * If the share server status is not in ``error``, ``active``, ``inactive``, ``manage_error`` or ``unmanage_error``, the API will return ``400 BadRequest``. * If the share server has shares registered in manila, it will return ``409 Conflict``. **Displaying a share server**: After the microversion bump, the share server view will include the field ``is_imported`` whenever a newer microversion is used. **Managing a share**:: POST /v2/{tenant-id}/shares/manage Request parameters:: { "share": { "protocol": "NFS", "name": "my_share", "share_type": "my_type", "description": null, "driver_options": {}, "is_public": false, "service_host": "host@backend#pool", "export_path": "192.168.10.100/my_export", "share_server_id": "fa4e4d78-d3d9-46cf-8e61-514da5008cee" } } The new parameter ``share_server_id`` is required if the share type given specifies ``DHSS = True`` mode. If ``share_server_id``is not given, or is given while the given share type specifies ``DHSS = False`` mode, the API will return ``400 BadRequest``. Response:: Code: 202 Accepted There are no changes proposed to the response body. **Unmanaging a share**:: POST /v2/{tenant-id}/shares/{share_id}/action Request parameters:: { "unmanage": null } Response:: Code: 202 Accepted This API will no longer return ``403 Forbiddden`` when attempting to unmanage a share that was created in ``DHSS = True`` mode. **Managing a snapshot**: No API changes are required. The API currently does not validate if the snapshot being managed is associated with a share that was created in ``DHSS = True`` mode. **Unmanaging a snapshot**:: POST /v2/{tenant-id}/snapshots/{snapshot_id}/action Request parameters:: { "unmanage": null } Response:: Code: 202 Accepted This API will no longer return ``403 Forbiddden`` when attempting to unmanage a snapshot of a share that was created in ``DHSS = True`` mode. Driver impact ------------- A new driver interface is introduced in order to get share server network allocation data. This data shall be used to validate the network allocations previously created by the admin. Drivers that support ``DHSS = True`` mode must implement this interface to support the Manage Share Servers functionality:: def manage_server(self, context, share_server, identifier, driver_options): """Return compiled back end details and network allocations. :param context: Current context. :param share_server: Share server model. :param identifier: A driver-specific share server identifier :param driver-options: Dictionary of driver options to assist managing the share server :return Dictionary with back end details to be saved in the database and a list containing IP addresses allocated in the back end. Example:: {'server_name': 'my_old_server'},['192.168.10.10', 'fd11::2000'] """ raise NotImplementedError() If the driver does not implement this interface, an exception will be raised and the operation will be aborted. The driver interfaces **manage_existing**, **unmanage**, **manage_existing_snapshot** and **unmanage_snapshot** will be updated to receive the share server model parameter. All drivers which implement those interface will have their method definition updated to avoid issues. In detail:: def manage_existing(self, share, driver_options, share_server=None): """Brings an existing share under Manila management. If the provided share is not valid, then raise a ManageInvalidShare exception, specifying a reason for the failure. If the provided share is not in a state that can be managed, such as being replicated on the backend, the driver *MUST* raise ManageInvalidShare exception with an appropriate message. The share has a share_type, and the driver can inspect that and compare against the properties of the referenced backend share. If they are incompatible, raise a ManageExistingShareTypeMismatch, specifying a reason for the failure. :param share: Share model :param driver_options: Driver-specific options provided by admin. :param share_server: Share server model or None. :return: share_update dictionary with required key 'size', which should contain size of the share. """ raise NotImplementedError() def unmanage(self, share, share_server=None): """Removes the specified share from Manila management. Does not delete the underlying backend share. For most drivers, this will not need to do anything. However, some drivers might use this call as an opportunity to clean up any Manila-specific configuration that they have associated with the backend share. If provided share cannot be unmanaged, then raise an UnmanageInvalidShare exception, specifying a reason for the failure. """ def manage_existing_snapshot(self, snapshot, driver_options, share_server=None): """Brings an existing snapshot under Manila management. If provided snapshot is not valid, then raise a ManageInvalidShareSnapshot exception, specifying a reason for the failure. :param snapshot: ShareSnapshotInstance model with ShareSnapshot data. Example:: { 'id': , 'snapshot_id': < snapshot id>, 'provider_location': , ... } :param driver_options: Optional driver-specific options provided by admin. Example:: { 'key': 'value', ... } :param share_server: Share server model or None. :return: model_update dictionary with required key 'size', which should contain size of the share snapshot, and key 'export_locations' containing a list of export locations, if snapshots can be mounted. """ raise NotImplementedError() def unmanage_snapshot(self, snapshot, share_server=None): """Removes the specified snapshot from Manila management. Does not delete the underlying backend share snapshot. For most drivers, this will not need to do anything. However, some drivers might use this call as an opportunity to clean up any Manila-specific configuration that they have associated with the backend share snapshot. If provided share snapshot cannot be unmanaged, then raise an UnmanageInvalidShareSnapshot exception, specifying a reason for the failure. """ Security impact --------------- As admin-only APIs, all the information necessary for managing share servers and the shares within is restricted to the admin by virtue of default policy. Notifications impact -------------------- Since the new API proposed is an admin-only API, there is no need for a user message notification. Other end user impact --------------------- New commands will be added to python-manilaclient:: manila share-server-manage [--driver_options key1=value1 [key2=value2] ...] manila share-server-unmanage One command will be updated:: manila manage [--name ] [--description ] [--share_type ] [--share_server_id ] [--driver_options [ [ ...]]] [--public] As for manila-ui, there will be a new button "Manage Share Server" and a context option "Unmanage Share Server" which will only be displayed if there are no manila shares associated with the given share server. Performance Impact ------------------ No significant performance impact is expected. Other deployer impact --------------------- None. Developer impact ---------------- The work proposed by this spec is impacted by [2]. The ``share_network_id`` parameter for the Manage Share Server will need to be replaced in favor of ``share_network_subnet_id``. Implementation ============== Assignee(s) ----------- Primary assignee: ganso Work Items ---------- * Implement main patch for manila that includes: * Database schema migration * Manage Share Server API * Unmanage Share Server API * Updates to Manage Share, Unmanage Share, Manage Snapshot and Unmanage Snapshot APIs * Add ``manage_server`` driver interface * Update existing affected driver interfaces * Share Manager adjustments to prevent automatic deletion of managed share servers * Adaptations to network plugins * Implementation in a First Party Driver * Functional Tests in manila-tempest-plugin * Python-manilaclient update * Docs update * Manila-UI update Dependencies ============ None. Testing ======= The functional tests of this change will consist of creating a share (which will create a regular share server), obtain its details, unmanage it, manage it, create another share in it, and then delete the share and the server. The existing config option "run_manage_unmanage_tests", now in combination with "multitenancy_enabled" will control whether those tests will run. If any of those are disabled the tests will be skipped. Documentation Impact ==================== The following documentation sections will be updated: * API reference: Will add the Manage Share Server API information and parameter details. The Manage Share API will be updated to include the ``share_server_id`` parameter as well. * Admin reference: Will add instructions on how about to manage shares in ``DHSS = True`` mode (including pre-requisite steps) and how to the use the new/updated CLI commands. * Developer reference: Will add information on how the functionality works and how to implement support for it in drivers. References ========== _`[1]` https://docs.openstack.org/manila/latest/contributor/driver_requirements.html#at-least-one-driver-mode-dhss-true-false _`[2]` https://blueprints.launchpad.net/manila/+spec/share-replication-enhancements-for-dhss _`[3]` https://etherpad.openstack.org/p/manila-ptg-planning-denver-2018