cinder-fusioncompute/cinder/volume/drivers/huawei/fusioncompute/vrm_commands.py

442 lines
19 KiB
Python

# Copyright 2016 Huawei Technologies Co.,LTD.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import urlparse
from oslo_config import cfg
from oslo_log import log as logging
from cinder import exception as cinder_exception
from cinder.i18n import _
from cinder.volume.drivers.huawei.vrm.conf import FC_DRIVER_CONF
from cinder.volume.drivers.huawei.vrm import exception as driver_exception
TASK_WAITING = 'waiting'
TASK_RUNNING = 'running'
TASK_SUCCESS = 'success'
TASK_FAILED = 'failed'
TASK_CANCELLING = 'cancelling'
TASK_UNKNOWN = 'unknown'
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class VRM_COMMANDS(object):
USER_AGENT = 'VRM-HTTP-Client for OpenStack'
RESOURCE_URI = 'uri'
TASK_URI = 'taskUri'
BASIC_URI = '/service'
glanceServer_host = ''
glanceServer_port = ''
version = CONF.vrm_version
site_uri = ''
def __init__(self):
self.site_urn = None
self.site_uri = None
glanceServer_Info = str(CONF.glance_api_servers).split(':')
LOG.info("glance_api_servers is [%s]", CONF.glance_api_servers)
LOG.info("sxmatch glanceServer_Info is %s", glanceServer_Info)
self.glanceServer_host =\
glanceServer_Info[0] + ":" + glanceServer_Info[1]
self.glanceServer_host = self.glanceServer_host.replace("['", '')
LOG.info("sxmatch glanceServer_host is %s", self.glanceServer_host)
self.glanceServer_port = glanceServer_Info[1].replace("']", '')
LOG.info("sxmatch glanceServer_port is %s", self.glanceServer_port)
"""Generate command to be sent to VRM."""
def _joined_params(self, params):
param_str = []
for k, v in params.items():
if (k is None) or (v is None) or len(k) == 0:
continue
if k == 'scope' and v == self.site_urn:
continue
param_str.append("%s=%s" % (k, str(v)))
return '&'.join(param_str)
def _joined_body(self, params):
param_str = []
for k, v in params.items():
if k is None or v is None or \
len(k) == 0:
continue
if type(v) in [int]:
param_str.append('"%s":%s' % (k, str(v)))
elif type(v) in [str, unicode]:
param_str.append('"%s":"%s"' % (k, str(v)))
elif type(v) in [bool]:
param_str.append('"%s":%s' % (k, str(v).lower()))
elif type(v) in [dict]:
param_str1 = json.dumps(v)
param_str.append('"%s":%s' % (k, param_str1))
else:
pass
if len(param_str) > 0:
return '{' + ','.join(param_str) + '}'
else:
return None
def _combine_vmConfig(self, **kwargs):
cpu_quantity = 1
mem_quantityMB = 1024
datastoreUrn = CONF.vrm_sm_datastoreurn
disk_quantityGB = 10
image_size = 10
if image_size > disk_quantityGB:
LOG.error(_("image is larger than sys-vol."))
raise cinder_exception.ImageTooLarge
cpu = {'quantity': cpu_quantity}
memory = {'quantityMB': mem_quantityMB}
disks = [
{
'datastoreUrn': datastoreUrn,
'quantityGB': disk_quantityGB,
'volType': 0,
'sequenceNum': 1,
}
]
properties = {
'isEnableHa': True,
'reoverByHost': False,
'isEnableFt': False
}
vmConfigBody = {
'cpu': cpu,
'memory': memory,
'disks': disks,
'properties': properties,
}
return vmConfigBody
def _combine_os_options(self, **kwargs):
osOptions = {
'osType': 'Windows',
'osVersion': 26
}
return osOptions
def init_site(self, uri, urn):
self.site_uri = uri
self.site_urn = urn
return
def _generate_url(self, path, query=None, frag=None):
LOG.info(_("[BRM-DRIVER] call _generate_url() "))
if CONF.vrm_ssl:
scheme = 'https'
else:
scheme = 'http'
fc_ip = FC_DRIVER_CONF.fc_ip
netloc = str(fc_ip) + ':' + str(CONF.vrm_port)
if path.startswith(self.BASIC_URI):
url = urlparse.urlunsplit((scheme, netloc, path, query, frag))
else:
url = urlparse.urlunsplit(
(scheme, netloc, self.BASIC_URI + str(path), query, frag))
return url
def generate_vrm_cmd(self, cmd, **kwargs):
COMMANDS = {
'v5.1': {
'list_tasks': ('GET',
('/tasks', kwargs.get(self.RESOURCE_URI), None,
None),
{},
{},
False),
'list_hosts': ('GET',
('/hosts', kwargs.get(self.RESOURCE_URI), None,
None),
{'limit': kwargs.get('limit'),
'offset': kwargs.get('offset'),
'scope': kwargs.get('scope')},
{},
False),
'list_datastores': ('GET',
('/datastores',
kwargs.get(self.RESOURCE_URI), None,
None),
{'limit': kwargs.get('limit'),
'offset': kwargs.get('offset'),
'scope': kwargs.get('scope')},
{},
False),
'list_volumes': ('GET',
('/volumes', kwargs.get(self.RESOURCE_URI),
None, kwargs.get('id')),
{'limit': kwargs.get('limit'),
'offset': kwargs.get('offset'),
'scope': kwargs.get('scope')},
{},
False),
'create_volume': ('POST',
('/volumes', None, None, None),
{},
{'name': kwargs.get('name'),
'quantityGB': kwargs.get('quantityGB'),
'datastoreUrn': kwargs.get('datastoreUrn'),
'uuid': kwargs.get('uuid'),
'isThin': kwargs.get('isThin'),
'type': kwargs.get('type'),
'indepDisk': kwargs.get('indepDisk'),
'persistentDisk': kwargs.get(
'persistentDisk'),
'volumeId': kwargs.get('volumeId')},
True),
'delete_volume': ('DELETE',
('/volumes', kwargs.get(self.RESOURCE_URI),
None, None),
{},
{},
True),
'list_volumesnapshot': ('GET',
('/volumesnapshots', None,
kwargs.get('uuid'), None),
{'limit': kwargs.get('limit'),
'offset': kwargs.get('offset'),
'scope': kwargs.get('scope')},
{},
False),
'create_volumesnapshot': ('POST',
('/volumesnapshots', None, None,
None),
{},
{'volumeUrn': kwargs.get('vol_urn'),
'snapshotUuid': kwargs.get('uuid')},
False),
'delete_volumesnapshot': ('DELETE',
('/volumesnapshots', None, None,
kwargs.get('id')),
{},
{
'snapshotUuid': kwargs.get(
'snapshotUuid')
},
True),
'createvolumefromsnapshot': ('POST',
('/volumesnapshots', None,
"createvol", None),
{},
{'snapshotUuid': kwargs.get(
'uuid'),
'volumeName':
kwargs.get('name')},
True),
'clone_volume': ('POST',
('/volumes', None, kwargs.get('src_name'),
'action/copyVol'),
{},
{'destinationVolumeID': kwargs.get(
'dest_name')},
True),
'copy_image_to_volume': ('POST',
('/volumes/imagetovolume', None, None,
None),
{},
{
'volumePara': {
'quantityGB': kwargs.get(
'volume_size'),
'urn': kwargs.get(
'volume_urn')
},
'imagePara': {
'id': kwargs.get('image_id'),
'url': kwargs.get(
'image_location')
},
'location': kwargs.get(
'host_urn'),
'needCreateVolume': False
},
True),
'copy_volume_to_image': ('POST',
('/volumes/volumetoimage', None, None,
None),
{},
{
'volumePara': {'urn': kwargs.get(
'volume_urn'),
'quantityGB': kwargs.get(
'volume_size')},
'imagePara': {
'id': kwargs.get('image_id'),
'url': kwargs.get(
'image_url')}
},
True),
'import_vm_from_image': ('POST',
('/vms/action/import', None, None,
None),
{},
dict({
'name': 'name',
'location': kwargs.get(
'host_urn'),
'autoBoot': 'false',
'url': kwargs.get('url'),
'protocol': 'nfs',
'vmConfig': {
'cpu': {
'quantity': 1
},
'memory': {
'quantityMB': 1024
},
'disks': [
{
'pciType': 'IDE',
'datastoreUrn':
kwargs.get(
'ds_urn'),
'quantityGB':
kwargs.get(
'vol_size'),
'volType': 0,
'sequenceNum': 1},
]
},
'osOptions': {
'osType': 'Windows',
'osVersion': 32
}
}),
True),
'detach_vol_from_vm': ('POST',
('/vms', None, kwargs.get('vm_id'),
'action/detachvol'),
{},
{'volUrn': kwargs.get('volUrn')},
True),
'stop_vm': ('POST',
('/vms', None, kwargs.get('vm_id'), 'action/stop'),
{},
{'mode': kwargs.get('mode')},
True),
'delete_vm': ('DELETE',
('/vms', None, kwargs.get('vm_id'), None),
{},
{},
True),
'query_vm': ('GET',
('/vms', None, kwargs.get('vm_id'), None),
{},
{},
False),
'list_templates': ('GET',
('/vms', None, None, None),
{'limit': kwargs.get('limit'),
'offset': kwargs.get('offset'),
'scope': kwargs.get('scope'),
'isTemplate': 'true'},
{},
False),
'clone_vm': ('POST',
('/vms', None, kwargs.get('template_id'),
'action/clone'),
{},
dict({
"name": "cinder-plugin-temp-vm",
"description": "cinder-plugin-temp-vm",
"isLinkClone": kwargs.get('linked_clone'),
'location': kwargs.get('host_urn'),
'autoBoot': 'false',
'vmConfig':
{
'cpu': {
'quantity': 2
},
'memory':
{
'quantityMB': 1024
},
'disks':
[{
'pciType': 'IDE',
'datastoreUrn': kwargs.get('ds_urn'),
'quantityGB': kwargs.get(
'volume_size'),
'volType': 0,
'sequenceNum': 1,
'isThin': kwargs.get('is_thin')
}]
},
}),
True),
},
'v2.0': {}
}
path = query = body = None
LOG.info("[BRM-DRIVER] version is [%s]", self.version)
if self.version not in COMMANDS.keys():
raise driver_exception.UnsupportedVersion()
else:
commands = COMMANDS[self.version]
if cmd not in commands.keys():
raise driver_exception.UnsupportedCommand()
else:
(method, pathparams, queryparams, bodyparams, hastask) = commands[
cmd]
resource, resource_uri, tag1, tag2 = pathparams
if resource_uri:
path = resource_uri
LOG.info(_("[VRM-CINDER] [%s]"), path)
else:
path = self.site_uri + resource
LOG.info(_("[VRM-CINDER] [%s]"), path)
if tag1:
path += ('/' + str(tag1))
LOG.info(_("[VRM-CINDER] [%s]"), path)
if tag2:
path += ('/' + str(tag2))
LOG.info(_("[VRM-CINDER] [%s]"), path)
if method == 'GET':
query = self._joined_params(queryparams)
elif method == 'DELETE':
query = self._joined_params(queryparams)
elif method == 'POST':
query = self._joined_params(queryparams)
LOG.info("[BRM-DRIVER] _generate_vrm_cmd bodyparams is [%s]",
bodyparams)
body = json.dumps(bodyparams)
LOG.info("[BRM-DRIVER] _generate_vrm_cmd body is [%s]", body)
else:
raise cinder_exception.UnknownCmd(cmd=method)
url = self._generate_url(path, query)
LOG.info("[BRM-DRIVER] _generate_vrm_cmd url is [%s]", url)
return (method, url, body, hastask)