Skip to content

Commit

Permalink
Release 0.2.16
Browse files Browse the repository at this point in the history
Merge commit for release 0.2.16
  • Loading branch information
Cedric Zhuang committed Jul 21, 2016
2 parents 3ea3171 + eeb14c0 commit 0dee4ce
Show file tree
Hide file tree
Showing 97 changed files with 1,242 additions and 2,864 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ StorOps: The Python Library for VNX & Unity
.. image:: https://img.shields.io/pypi/v/storops.svg
:target: https://pypi.python.org/pypi/storops

VERSION: 0.2.15
VERSION: 0.2.16

A minimalist Python library to manage VNX/Unity systems.
This document lies in the source code and go with the release.
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ requests!=2.9.0,>=2.8.1
retryz>=0.1.7
cachez>=0.1.0
six>=1.9.0
pywbemReq>=0.0.3
bitmath>=1.3.0
8 changes: 4 additions & 4 deletions storops/connection/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def request(self, full_url, method, **kwargs):
resp = self.session.request(method, full_url, headers=headers,
**options)

self.log_response(full_url, resp, start)
self.log_response(full_url, method, resp, start)

body = None
if resp.text:
Expand Down Expand Up @@ -152,11 +152,11 @@ def _debug_print_json(data, prefix=None):
log.debug('{}\n{}'.format(prefix, text))

@classmethod
def log_response(cls, full_url, resp, start_time):
def log_response(cls, full_url, method, resp, start_time):
if log.isEnabledFor(logging.DEBUG):
dt = time.time() - start_time
log.debug('REQ: {}, TIME: {} RESP CODE: {}'
.format(full_url, dt, resp.status_code))
log.debug('REQ URL: [{}] {}, TIME: {}, RESP CODE: {}'
.format(method, full_url, dt, resp.status_code))
cls._debug_print_json(resp.text, 'RESP BODY:')

def update_headers(self, headers):
Expand Down
83 changes: 0 additions & 83 deletions storops/connection/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import functools
import paramiko
from pywbemReq import WBEMConnection
from paramiko import ssh_exception
import six
from storops.connection import client
Expand Down Expand Up @@ -82,88 +81,6 @@ def _update_csrf_token(self):
self.http_client.update_headers(headers)


class UnityWbemConnector(object):
ns = 'root/emc/smis'

def __init__(self, host, user, password, namespace=None):
if namespace is None:
namespace = 'interop'
if user is not None and '/' not in user:
user = 'Local/{}'.format(user)
if host is not None and 'https' not in host:
host = 'https://{}:5989'.format(host)
self.conn = WBEMConnection(host, (user, password), namespace)

def ei(self, clz_name):
""" enumerate instance
:param clz_name: CIM class name
:return: instances of the class
"""
return self.conn.EnumerateInstances(clz_name, self.ns)

def gi(self, obj_name):
""" get instance
:param obj_name: instance name
:return: instance
"""
return self.conn.GetInstance(obj_name)

def im(self, method_name, instance_name, **kwargs):
""" invoke method
:param method_name: method name
:param instance_name: instance name
:param kwargs: method parameters
:return: method return
"""
return self.conn.InvokeMethod(
method_name, instance_name, kwargs.items())

def ai(self, from_inst_name, assoc_clz, result_clz):
""" associators
:param from_inst_name: from instance
:param assoc_clz: the associate class
:param result_clz: the result class
:return: associated instances
"""
return self.conn.Associators(from_inst_name,
AssocClass=assoc_clz,
ResultClass=result_clz)

def ei_first(self, clz_name):
""" enumerate first.
:param clz_name: class to enumerate
:return: first instance of the enumerate result
"""
instances = self.ei(clz_name)
if len(instances) > 0:
ret = instances[0]
else:
raise ValueError('instance of "{}" not found.'.format(clz_name))
return ret

def ref(self, obj_name, result_clz):
""" reference
:param obj_name: instance name
:param result_clz: result class name
:return: result instances
"""
return self.conn.References(obj_name, ResultClass=result_clz)

def di(self, obj_name):
""" delete instance
:param obj_name: instance name
:return: operation result
"""
return self.conn.DeleteInstance(obj_name)


class XMLAPIConnector(object):
HEADERS = {
'Content-Type': 'application/x-www-form-urlencoded',
Expand Down
28 changes: 0 additions & 28 deletions storops/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,14 +266,6 @@ class UnityCifsServiceNotEnabledError(UnityException):
pass


class UnityCimException(UnityException):
pass


class UnityCimResourceNotFoundError(UnityCimException):
pass


class UnityHostInitiatorNotFoundError(UnityException):
pass

Expand Down Expand Up @@ -305,18 +297,6 @@ class UnityAluAlreadyAttachedError(UnityAttachAluError):
message = 'Requested LUN has already been added to this host'


class UnityAddCifsAceError(UnityCimException):
message = 'failed to add ace for cifs share.'


class UnityDeleteCifsAceError(UnityCimException):
message = 'failed to remove ace for cifs share.'


class UnityAceNotFoundError(UnityCimException):
message = 'specified ace not found.'


@rest_exception
class UnityResourceNotFoundError(UnityException):
error_code = 131149829
Expand Down Expand Up @@ -411,18 +391,10 @@ class UnityFileSystemSizeTooSmallError(UnityException):
error_code = 108008449


class UnityImportCifsUserError(UnityException):
message = 'failed to import cifs user.'


class UnityShareTypeNotSupportAccessControlError(UnityException):
message = 'share type does not support access control.'


class UnityCreateCifsUserError(UnityImportCifsUserError):
message = 'failed to import cifs user. please make sure this user exists.'


class UnityHostNotFoundException(UnityException):
message = 'specified host not found.'

Expand Down
31 changes: 24 additions & 7 deletions storops/lib/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@
# under the License.
from __future__ import unicode_literals

from enum import Enum as _Enum
import errno
from functools import partial
import functools
import inspect
import json
import logging
from os import path, makedirs
import six
import sys
import threading
from functools import partial
from os import path, makedirs

from retryz import retry
import cachez
import six
from enum import Enum as _Enum
from retryz import retry

import storops.exception

Expand Down Expand Up @@ -427,13 +428,29 @@ def get_lock_file(name):
return path.join(lock_folder, name)


def round_it(ndigits=3):
def round_it(n_digits=3):
def inner(func):
@six.wraps(func)
def _inner(*args, **kwargs):
value = func(*args, **kwargs)
return round(value, ndigits)
return round(value, n_digits)

return _inner

return inner


round_3 = round_it(3)


def allow_omit_parentheses(func):
@six.wraps(func)
def inner(*args, **kwargs):
if len(args) == 1 and inspect.isfunction(args[0]):
# Decorator are used without parentheses, this
# decorator add the the parentheses
return func()(*args, **kwargs)
else:
return func(*args, **kwargs)

return inner
67 changes: 2 additions & 65 deletions storops/unity/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@

import six

from storops.connection.connector import UnityRESTConnector, UnityWbemConnector
from storops.connection.connector import UnityRESTConnector
import storops.unity.resource.type_resource
from storops.exception import UnityException
from storops.lib.common import instance_cache, EnumList
from storops.unity.enums import UnityEnum, UnityEnumList, SmisReturnValueEnum
from storops.unity.enums import UnityEnum, UnityEnumList
from storops.unity.resource import UnityResource, UnityResourceList
from storops.unity.resp import RestResponse

Expand All @@ -36,7 +35,6 @@ class UnityClient(object):
def __init__(self, ip, username, password, port=443):
self._rest = UnityRESTConnector(ip, port=port, user=username,
password=password)
self._smis = UnityWbemConnector(ip, user=username, password=password)

def get_all(self, type_name, fields=None, the_filter=None):
"""Get the resource by resource id.
Expand Down Expand Up @@ -210,67 +208,6 @@ def make_body(cls, value=None, allow_empty=False, **kwargs):
ret = value
return ret

@property
@instance_cache
def account_management_service(self):
return self.ei_first('CIM_AccountManagementService')

@property
@instance_cache
def system(self):
return self.ei_first('EMC_VNXe_StorageSystemLeaf')

def ei(self, clz_name):
return self._smis.ei(clz_name)

def ai(self, from_inst_name, assoc_clz, result_clz):
return self._smis.ai(from_inst_name, assoc_clz, result_clz)

def ei_first(self, clz_name):
return self._smis.ei_first(clz_name)

def im(self, method_name, instance_name, **kwargs):
ret = self._smis.im(method_name, instance_name, **kwargs)
return CimResponse(ret)

def ref(self, obj_name, result_clz):
return self._smis.ref(obj_name, result_clz)

def di(self, obj_name):
return CimResponse(self._smis.di(obj_name))

def gi(self, obj_name):
return self._smis.gi(obj_name)


class CimResponse(object):
def __init__(self, inputs):
if inputs is None:
inputs = [0, None]
self._error_code = inputs[0]
self._value = inputs[1]

@property
@instance_cache
def error_code(self):
return SmisReturnValueEnum.parse(self._error_code)

@property
def value(self):
return self._value

def raise_if_err(self, default=None):
if default is not None:
ex_clz = default
else:
ex_clz = UnityException

if self.error_code != SmisReturnValueEnum.OK:
raise ex_clz()

def is_ok(self):
return self.error_code == SmisReturnValueEnum.OK


class UnityDoc(object):
def __init__(self, cli, clz):
Expand Down
33 changes: 0 additions & 33 deletions storops/unity/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,36 +670,3 @@ class ACEAccessLevelEnum(UnityEnum):
READ = (1, 'Read')
WRITE = (2, 'Write')
FULL = (4, 'Full')

def to_smis_activity_value(self):
if self == self.READ:
ret = SmisActivityEnum.READ
elif self == self.WRITE:
ret = SmisActivityEnum.WRITE
else:
ret = SmisActivityEnum.FULL
return ret.index

@classmethod
def from_list(cls, values):
if SmisActivityEnum.FULL.index in values:
ret = cls.FULL
elif SmisActivityEnum.WRITE.index in values:
ret = cls.WRITE
elif SmisActivityEnum.READ.index in values:
ret = cls.READ
else:
ret = None
return ret


class SmisReturnValueEnum(UnityEnum):
OK = (0, 'Ok')
NOT_SUPPORTED = (1, 'Not Supported')
FAILED = (2, 'Failed')


class SmisActivityEnum(UnityEnum):
READ = (5, 'Read')
WRITE = (6, 'Write')
FULL = (14, 'Full Control')
1 change: 1 addition & 0 deletions storops/unity/parser_configs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ UnityCifsShareAce:
name: cifsShareACE
properties:
- label: sid
is_index: True
- label: accessType
converter: ACEAccessTypeEnum
- label: accessLevel
Expand Down
Loading

0 comments on commit 0dee4ce

Please sign in to comment.