Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add hitachi vsp storage driver to community #388

Merged
merged 44 commits into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
bf50dc4
edit
jiangyutan Nov 2, 2020
770cc02
过滤rest警告
jiangyutan Nov 2, 2020
bc9b126
add vnx block driver
yuanyu-ghca Nov 6, 2020
72ebc49
111
jiangyutan Nov 6, 2020
747387d
11
jiangyutan Nov 6, 2020
b3890d5
11
jiangyutan Nov 6, 2020
b6a4761
hds vsp
jiangyutan Nov 6, 2020
2e63905
hitachi vsp do some optimize
jiangyutan Nov 21, 2020
54a5fc6
remove exception which for vnx
jiangyutan Nov 21, 2020
5a920e4
do some optimize
jiangyutan Nov 21, 2020
b32ae70
remove vsp info in setup
jiangyutan Nov 21, 2020
147f953
add hitachi vsp in setup
jiangyutan Nov 21, 2020
6458e05
do some optimize
jiangyutan Nov 21, 2020
77b4e34
remove change from the rest_client
jiangyutan Nov 21, 2020
0a9cfbf
change decode
jiangyutan Nov 21, 2020
a7e2af0
change the password in test
jiangyutan Nov 21, 2020
f938324
change the password in test
jiangyutan Nov 21, 2020
5089595
optimize rest
jiangyutan Nov 21, 2020
baf9c41
de some optimize
jiangyutan Nov 23, 2020
195a667
change for optimize
jiangyutan Nov 23, 2020
7b49efb
some optimize for pr
jiangyutan Nov 23, 2020
ff39e5e
optimezi for pr
jiangyutan Nov 23, 2020
32b4000
Merge pull request #1 from sodafoundation/v0.8.0-maint
jiangyutan Nov 23, 2020
4ec19dd
Merge remote-tracking branch 'origin/v0.8.0-maint' into hds_vsp
yuanyu-ghca Nov 23, 2020
484d20d
add vsp in setup and do some optimize
jiangyutan Nov 23, 2020
dc46038
do some change
jiangyutan Nov 23, 2020
4c664b0
do some change
jiangyutan Nov 23, 2020
ed3124b
change setup hitachi verdor
jiangyutan Nov 23, 2020
3e4ce27
add list alerts
jiangyutan Nov 24, 2020
56841dc
add list alerts
jiangyutan Nov 24, 2020
5f2ede7
change RestHandler inherit RestClient
jiangyutan Nov 24, 2020
875af48
change RestHandler inherit RestClient
jiangyutan Nov 24, 2020
057fe20
change RestHandler inherit RestClient
jiangyutan Nov 24, 2020
8595a5f
change test alert info
jiangyutan Nov 24, 2020
9cd4a91
add some comments and do some optimize
jiangyutan Nov 24, 2020
c466e23
fix line lenth longer than 79
jiangyutan Nov 24, 2020
ca19b2e
update verify before login
jiangyutan Nov 24, 2020
6aa6d3a
update verify before login
jiangyutan Nov 24, 2020
115776d
change tuple name in consts
jiangyutan Nov 24, 2020
be46db0
change tuple name in consts
jiangyutan Nov 24, 2020
d86f599
do some change for optimize
jiangyutan Nov 25, 2020
582e3ee
do some change for optimize
jiangyutan Nov 25, 2020
7d9d634
add test info for rest call
jiangyutan Nov 25, 2020
2f906a2
do some change for optimize
jiangyutan Nov 25, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
Empty file.
20 changes: 20 additions & 0 deletions delfin/drivers/hitachi/vsp/consts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2020 The SODA Authors.
#
# 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.
SOCKET_TIMEOUT = 52
ERROR_SESSION_INVALID_CODE = 403
ERROR_SESSION_IS_BEING_USED_CODE = 409
BLOCK_SIZE = 512

VSP_FXXX_GXXX_SERIES = ('VSP G350', 'VSP G370', 'VSP G700', 'VSP G900',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VSP_F_G_SERIES is better for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there also have like F200,G200 they are different

'VSP F350', 'VSP F370', 'VSP F700', 'VSP F900')
199 changes: 199 additions & 0 deletions delfin/drivers/hitachi/vsp/rest_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Copyright 2020 The SODA Authors.
# 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 threading

import requests
import six
from oslo_log import log as logging

from delfin import cryptor
from delfin import exception
from delfin.drivers.hitachi.vsp import consts
from delfin.drivers.utils.rest_client import RestClient

LOG = logging.getLogger(__name__)


class RestHandler(RestClient):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this new class and why can't the existing res_client util be used/enhanced?

SYSTEM_URL = '/ConfigurationManager/v1/objects/storages'
LOGOUT_URL = '/ConfigurationManager/v1/objects/sessions/'
COMM_URL = '/ConfigurationManager/v1/objects/storages/'
NajmudheenCT marked this conversation as resolved.
Show resolved Hide resolved

AUTH_KEY = 'Authorization'

def __init__(self, **kwargs):
super(RestHandler, self).__init__(**kwargs)
self.session_lock = threading.Lock()
self.session_id = None
self.storage_device_id = None
self.device_model = None
self.serial_number = None

def call(self, url, data=None, method=None):
try:
res = self.do_call(url, data, method,
calltimeout=consts.SOCKET_TIMEOUT)
if (res.status_code == consts.ERROR_SESSION_INVALID_CODE
or res.status_code ==
consts.ERROR_SESSION_IS_BEING_USED_CODE):
LOG.error("Failed to get token=={0}=={1},get token again"
.format(res.status_code, res.text))
# if method is logout,return immediately
if method == 'DELETE' and RestHandler. \
LOGOUT_URL in url:
return res
self.rest_auth_token = None
access_session = self.login()
if access_session is not None:
res = self. \
do_call(url, data, method,
calltimeout=consts.SOCKET_TIMEOUT)
else:
LOG.error('Login error,get access_session failed')
elif res.status_code == 503:
raise exception.InvalidResults(res.text)

return res

except Exception as e:
err_msg = "Get RestHandler.call failed: %s" % (six.text_type(e))
LOG.error(err_msg)
raise exception.InvalidResults(err_msg)

def get_resinfo_call(self, url, data=None):
NajmudheenCT marked this conversation as resolved.
Show resolved Hide resolved
result_json = None
res = self.call(url, data, 'GET')
if res.status_code == 200:
result_json = res.json()
return result_json

def login(self):
try:
self.get_device_id()
access_session = self.rest_auth_token
if self.san_address:
url = '%s%s/sessions' % \
(RestHandler.COMM_URL,
self.storage_device_id)
data = {}

with self.session_lock:
if self.session is None:
self.init_http_head()
self.session.auth = \
requests.auth.HTTPBasicAuth(
self.rest_username,
cryptor.decode(self.rest_password))
res = self. \
do_call(url, data, 'POST',
calltimeout=consts.SOCKET_TIMEOUT)
if res.status_code == 200:
result = res.json()
self.session_id = result.get('sessionId')
access_session = 'Session %s' % result.get('token')
self.rest_auth_token = access_session
self.session.headers[
RestHandler.AUTH_KEY] = access_session
else:
LOG.error("Login error. URL: %(url)s\n"
"Reason: %(reason)s.",
{"url": url, "reason": res.text})
if 'invalid username or password' in res.text:
raise exception.InvalidUsernameOrPassword()
else:
raise exception.BadResponse(res.text)
else:
LOG.error('Login Parameter error')

return access_session
except Exception as e:
LOG.error("Login error: %s", six.text_type(e))
raise e

def logout(self):
try:
url = RestHandler.LOGOUT_URL
if self.session_id is not None:
url = '%s%s/sessions/%s' % \
(RestHandler.COMM_URL,
self.storage_device_id,
self.session_id)
if self.san_address:
self.call(url, method='DELETE')
self.rest_auth_token = None
NajmudheenCT marked this conversation as resolved.
Show resolved Hide resolved
else:
LOG.error('logout error:session id not found')
except Exception as err:
LOG.error('logout error:{}'.format(err))
raise exception.StorageBackendException(
reason='Failed to Logout from restful')

def get_device_id(self):
try:
if self.session is None:
self.init_http_head()
storage_systems = self.get_system_info()
system_info = storage_systems.get('data')
for system in system_info:
if system.get('model') in consts.VSP_FXXX_GXXX_SERIES:
if system.get('ctl1Ip') == self.rest_host or \
system.get('ctl2Ip') == self.rest_host:
self.storage_device_id = system.get('storageDeviceId')
self.device_model = system.get('model')
self.serial_number = system.get('serialNumber')
break
elif system.get('svpIp') == self.rest_host:
self.storage_device_id = system.get('storageDeviceId')
self.device_model = system.get('model')
self.serial_number = system.get('serialNumber')
break
if self.storage_device_id is None:
LOG.error("Get device id fail,model or something is wrong")
except Exception as e:
LOG.error("Get device id error: %s", six.text_type(e))
raise e

def get_firmware_version(self):
url = '%s%s' % \
(RestHandler.COMM_URL, self.storage_device_id)
result_json = self.get_resinfo_call(url)
if result_json is None:
return None
firmware_version = result_json.get('dkcMicroVersion')

return firmware_version

def get_capacity(self):
url = '%s%s/total-capacities/instance' % \
(RestHandler.COMM_URL, self.storage_device_id)
result_json = self.get_resinfo_call(url)
return result_json

def get_all_pools(self):
url = '%s%s/pools' % \
(RestHandler.COMM_URL, self.storage_device_id)
result_json = self.get_resinfo_call(url)
return result_json

def get_all_volumes(self):
url = '%s%s/ldevs' % \
(RestHandler.COMM_URL, self.storage_device_id)
result_json = self.get_resinfo_call(url)
return result_json

def get_system_info(self):
result_json = self.get_resinfo_call(RestHandler.SYSTEM_URL)

return result_json
Loading