**** CubicPower OpenStack Study ****
def provide_ems(requester, server, stats, netapp_backend,
                server_type="cluster"):
    """Provide ems with volume stats for the requester.
    :param server_type: cluster or 7mode.
    """
    def _create_ems(stats, netapp_backend, server_type):
        """Create ems api request."""
        ems_log = NaElement('ems-autosupport-log')
        host = socket.getfqdn() or 'Cinder_node'
        dest = "cluster node" if server_type == "cluster"\
               else "7 mode controller"
        ems_log.add_new_child('computer-name', host)
        ems_log.add_new_child('event-id', '0')
        ems_log.add_new_child('event-source',
                              'Cinder driver %s' % netapp_backend)
        ems_log.add_new_child('app-version', stats.get('driver_version',
                              'Undefined'))
        ems_log.add_new_child('category', 'provisioning')
        ems_log.add_new_child('event-description',
                              'OpenStack volume created on %s' % dest)
        ems_log.add_new_child('log-level', '6')
        ems_log.add_new_child('auto-support', 'true')
        return ems_log
    def _create_vs_get():
        """Create vs_get api request."""
        vs_get = NaElement('vserver-get-iter')
        vs_get.add_new_child('max-records', '1')
        query = NaElement('query')
        query.add_node_with_children('vserver-info',
                                     **{'vserver-type': 'node'})
        vs_get.add_child_elem(query)
        desired = NaElement('desired-attributes')
        desired.add_node_with_children(
            'vserver-info', **{'vserver-name': '', 'vserver-type': ''})
        vs_get.add_child_elem(desired)
        return vs_get
    def _get_cluster_node(na_server):
        """Get the cluster node for ems."""
        na_server.set_vserver(None)
        vs_get = _create_vs_get()
        res = na_server.invoke_successfully(vs_get)
        if (res.get_child_content('num-records') and
           int(res.get_child_content('num-records')) > 0):
            attr_list = res.get_child_by_name('attributes-list')
            vs_info = attr_list.get_child_by_name('vserver-info')
            vs_name = vs_info.get_child_content('vserver-name')
            return vs_name
        return None
    do_ems = True
    if hasattr(requester, 'last_ems'):
        sec_limit = 604800
        if not (timeutils.is_older_than(requester.last_ems, sec_limit) or
                timeutils.is_older_than(requester.last_ems, sec_limit - 59)):
            do_ems = False
    if do_ems:
        na_server = copy.copy(server)
        na_server.set_timeout(25)
        ems = _create_ems(stats, netapp_backend, server_type)
        try:
            if server_type == "cluster":
                api_version = na_server.get_api_version()
                if api_version:
                    major, minor = api_version
                else:
                    raise NaApiError(code='Not found',
                                     message='No api version found')
                if major == 1 and minor > 15:
                    node = getattr(requester, 'vserver', None)
                else:
                    node = _get_cluster_node(na_server)
                if node is None:
                    raise NaApiError(code='Not found',
                                     message='No vserver found')
                na_server.set_vserver(node)
            else:
                na_server.set_vfiler(None)
            na_server.invoke_successfully(ems, True)
            LOG.debug(_("ems executed successfully."))
        except NaApiError as e:
            LOG.warn(_("Failed to invoke ems. Message : %s") % e)
        finally:
            requester.last_ems = timeutils.utcnow()
**** CubicPower OpenStack Study ****
def validate_instantiation(**kwargs):
    """Checks if a driver is instantiated other than by the unified driver.
    Helps check direct instantiation of netapp drivers.
    Call this function in every netapp block driver constructor.
    """
    if kwargs and kwargs.get('netapp_mode') == 'proxy':
        return
    LOG.warn(_("It is not the recommended way to use drivers by NetApp. "
               "Please use NetAppDriver to achieve the functionality."))
**** CubicPower OpenStack Study ****
def invoke_api(na_server, api_name, api_family='cm', query=None,
               des_result=None, additional_elems=None,
               is_iter=False, records=0, tag=None,
               timeout=0, tunnel=None):
    """Invokes any given api call to a NetApp server.
        :param na_server: na_server instance
        :param api_name: api name string
        :param api_family: cm or 7m
        :param query: api query as dict
        :param des_result: desired result as dict
        :param additional_elems: dict other than query and des_result
        :param is_iter: is iterator api
        :param records: limit for records, 0 for infinite
        :param timeout: timeout seconds
        :param tunnel: tunnel entity, vserver or vfiler name
    """
    record_step = 50
    if not (na_server or isinstance(na_server, NaServer)):
        msg = _("Requires an NaServer instance.")
        raise exception.InvalidInput(reason=msg)
    server = copy.copy(na_server)
    if api_family == 'cm':
        server.set_vserver(tunnel)
    else:
        server.set_vfiler(tunnel)
    if timeout > 0:
        server.set_timeout(timeout)
    iter_records = 0
    cond = True
    while cond:
        na_element = create_api_request(
            api_name, query, des_result, additional_elems,
            is_iter, record_step, tag)
        result = server.invoke_successfully(na_element, True)
        if is_iter:
            if records > 0:
                iter_records = iter_records + record_step
                if iter_records >= records:
                    cond = False
            tag_el = result.get_child_by_name('next-tag')
            tag = tag_el.get_content() if tag_el else None
            if not tag:
                cond = False
        else:
            cond = False
        yield result
**** CubicPower OpenStack Study ****
def create_api_request(api_name, query=None, des_result=None,
                       additional_elems=None, is_iter=False,
                       record_step=50, tag=None):
        """Creates a NetApp api request.
            :param api_name: api name string
            :param query: api query as dict
            :param des_result: desired result as dict
            :param additional_elems: dict other than query and des_result
            :param is_iter: is iterator api
            :param record_step: records at a time for iter api
            :param tag: next tag for iter api
        """
        api_el = NaElement(api_name)
        if query:
            query_el = NaElement('query')
            query_el.translate_struct(query)
            api_el.add_child_elem(query_el)
        if des_result:
            res_el = NaElement('desired-attributes')
            res_el.translate_struct(des_result)
            api_el.add_child_elem(res_el)
        if additional_elems:
            api_el.translate_struct(additional_elems)
        if is_iter:
            api_el.add_new_child('max-records', str(record_step))
        if tag:
            api_el.add_new_child('tag', tag, True)
        return api_el
**** CubicPower OpenStack Study ****
def to_bool(val):
    """Converts true, yes, y, 1 to True, False otherwise."""
    if val:
        strg = str(val).lower()
        if (strg == 'true' or strg == 'y'
            or strg == 'yes' or strg == 'enabled'
                or strg == '1'):
                    return True
        else:
            return False
    else:
        return False
@utils.synchronized("safe_set_attr")
**** CubicPower OpenStack Study ****
def set_safe_attr(instance, attr, val):
    """Sets the attribute in a thread safe manner.
    Returns if new val was set on attribute.
    If attr already had the value then False.
    """
    if not instance or not attr:
        return False
    old_val = getattr(instance, attr, None)
    if val is None and old_val is None:
        return False
    elif val == old_val:
        return False
    else:
        setattr(instance, attr, val)
        return True
**** CubicPower OpenStack Study ****
def get_volume_extra_specs(volume):
    """Provides extra specs associated with volume."""
    ctxt = context.get_admin_context()
    type_id = volume.get('volume_type_id')
    specs = None
    if type_id is not None:
        volume_type = volume_types.get_volume_type(ctxt, type_id)
        specs = volume_type.get('extra_specs')
    return specs
**** CubicPower OpenStack Study ****
def check_apis_on_cluster(na_server, api_list=[]):
    """Checks api availability and permissions on cluster.
    Checks api availability and permissions for executing user.
    Returns a list of failed apis.
    """
    failed_apis = []
    if api_list:
        api_version = na_server.get_api_version()
        if api_version:
            major, minor = api_version
            if major == 1 and minor < 20:
                for api_name in api_list:
                    na_el = NaElement(api_name)
                    try:
                        na_server.invoke_successfully(na_el)
                    except Exception as e:
                        if isinstance(e, NaApiError):
                            if (e.code == NaErrors['API_NOT_FOUND'].code or
                                    e.code ==
                                    NaErrors['INSUFFICIENT_PRIVS'].code):
                                failed_apis.append(api_name)
            elif major == 1 and minor >= 20:
                failed_apis = copy.copy(api_list)
                result = invoke_api(
                    na_server,
                    api_name='system-user-capability-get-iter',
                    api_family='cm',
                    additional_elems=None,
                    is_iter=True)
                for res in result:
                    attr_list = res.get_child_by_name('attributes-list')
                    if attr_list:
                        capabilities = attr_list.get_children()
                        for capability in capabilities:
                            op_list = capability.get_child_by_name(
                                'operation-list')
                            if op_list:
                                ops = op_list.get_children()
                                for op in ops:
                                    apis = op.get_child_content('api-name')
                                    if apis:
                                        api_list = apis.split(',')
                                        for api_name in api_list:
                                            if (api_name and
                                                    api_name.strip()
                                                    in failed_apis):
                                                failed_apis.remove(api_name)
                                    else:
                                        continue
            else:
                msg = _("Unsupported Clustered Data ONTAP version.")
                raise exception.VolumeBackendAPIException(data=msg)
        else:
            msg = _("Api version could not be determined.")
            raise exception.VolumeBackendAPIException(data=msg)
    return failed_apis
**** CubicPower OpenStack Study ****
def resolve_hostname(hostname):
    """Resolves host name to IP address."""
    res = socket.getaddrinfo(hostname, None)[0]
    family, socktype, proto, canonname, sockaddr = res
    return sockaddr[0]
**** CubicPower OpenStack Study ****
def encode_hex_to_base32(hex_string):
    """Encodes hex to base32 bit as per RFC4648."""
    bin_form = binascii.unhexlify(hex_string)
    return base64.b32encode(bin_form)
**** CubicPower OpenStack Study ****
def decode_base32_to_hex(base32_string):
    """Decodes base32 string to hex string."""
    bin_form = base64.b32decode(base32_string)
    return binascii.hexlify(bin_form)
**** CubicPower OpenStack Study ****
def convert_uuid_to_es_fmt(uuid_str):
    """Converts uuid to e-series compatible name format."""
    uuid_base32 = encode_hex_to_base32(uuid.UUID(str(uuid_str)).hex)
    return uuid_base32.strip('=')
**** CubicPower OpenStack Study ****
def convert_es_fmt_to_uuid(es_label):
    """Converts e-series name format to uuid."""
    es_label_b32 = es_label.ljust(32, '=')
    return uuid.UUID(binascii.hexlify(base64.b32decode(es_label_b32)))