blob: 97609c12addfa7788b9fcacdeaa28ba90337729b [file] [log] [blame]
# Copyright 2018 Mirantis Inc
# 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.
from oslo_utils.strutils import bool_from_string
import logging
log = logging.getLogger(__name__)
def __virtual__():
'''
Only load if manila module is present in __salt__
'''
return 'manilang' if 'manilang.list_share_types' in __salt__ else False
manilang_func = {
'list_types': 'manilang.list_share_types',
'create_type': 'manilang.create_share_type',
'set_type_specs': 'manilang.set_share_type_extra_specs',
'unset_type_specs': 'manilang.unset_share_type_extra_specs',
'delete_type': 'manilang.delete_share_type',
'service_list': 'manilang.service_list',
'service_update': 'manilang.service_update',
}
def share_type_present(name, extra_specs, cloud_name, microversion=None,
**kwargs):
"""
Ensure that share_type is present and has desired parameters
This function will create the desired share type if one with the requested
name does not exist. If it does, it will be updated to correspond to
parameters passed to this function.
:param name: name of the share type.
:param extra_specs: dictionary of extra_specs that share type should have.
It contains one required parameter - driver_handles_share_servers.
:param kwargs: other arguments that will be pushed into share_type
dictionary to be POSTed, if specified.
"""
for key in extra_specs:
try:
extra_specs[key] = str(
bool_from_string(extra_specs[key], strict=True)
)
except ValueError:
extra_specs[key] = str(extra_specs[key])
origin_share_types = __salt__[
manilang_func['list_types']
](cloud_name=cloud_name)['share_types']
share_types = [
share_type
for share_type in origin_share_types if share_type['name'] == name
]
if not share_types:
try:
res = __salt__[
manilang_func['create_type']
](name, extra_specs, cloud_name=cloud_name,
microversion=microversion, **kwargs)
except Exception as e:
log.error('Manila share type create failed with {}'.format(e))
return _create_failed(name, 'resource')
return _created(name, 'share_type', res)
elif len(share_types) == 1:
exact_share_type = share_types[0]
api_extra_specs = exact_share_type['extra_specs']
api_keys = set(api_extra_specs)
sls_keys = set(extra_specs)
to_delete = api_keys - sls_keys
to_add = sls_keys - api_keys
to_update = sls_keys & api_keys
resp = {}
for key in to_delete:
try:
__salt__[
manilang_func['unset_type_specs']
](exact_share_type['id'], key, cloud_name=cloud_name,
microversion=microversion)
except Exception as e:
log.error(
'Manila share type delete '
'extra specs failed with {}'.format(e)
)
return _update_failed(name, 'share_type_extra_specs')
resp.update({'deleted_extra_specs': tuple(to_delete)})
diff = {}
for key in to_add:
diff[key] = extra_specs[key]
for key in to_update:
if extra_specs[key] != api_extra_specs[key]:
diff[key] = extra_specs[key]
if diff:
try:
resp.update(
__salt__[
manilang_func['set_type_specs']
](exact_share_type['id'], diff,
cloud_name=cloud_name, microversion=microversion)
)
except Exception as e:
log.error(
'Manila share type update '
'extra specs failed with {}'.format(e)
)
return _update_failed(name, 'share_type_extra_specs')
if to_delete or diff:
return _updated(name, 'share_type', resp)
return _no_changes(name, 'share_type')
else:
return _find_failed(name, 'share_type')
def share_type_absent(name, cloud_name):
origin_share_types = __salt__[
manilang_func['list_types']
](cloud_name=cloud_name)['share_types']
share_types = [
share_type
for share_type in origin_share_types if share_type['name'] == name
]
if not share_types:
return _absent(name, 'share_type')
elif len(share_types) == 1:
try:
__salt__[manilang_func['delete_type']](share_types[0]['id'],
cloud_name=cloud_name)
except Exception as e:
log.error('Manila share type delete failed with {}'.format(e))
return _delete_failed(name, 'share_type')
return _deleted(name, 'share_type')
else:
return _find_failed(name, 'share_type')
def service_enabled(name, binary, cloud_name, microversion=None):
"""
Method allows enable service by binary and name.
:param name: name of a host where service is running
:param binary: name of the service have to be run
"""
ret = {}
services = __salt__[manilang_func['service_list']](binary=binary, cloud_name=cloud_name)['services']
# You are able to either enable certain manila-share instance by name@driver
# or all existed instances on a node by name
if '@' in name:
disabled_services = [s for s in services if name == s['host'] and s['status'] == 'disabled']
else:
disabled_services = [s for s in services if name == s['host'].split('@')[0] and s['status'] == 'disabled']
if len(disabled_services):
for service in disabled_services:
changes = __salt__[manilang_func['service_update']](service['host'], binary, 'enable', cloud_name=cloud_name, microversion=microversion)
ret[service['host']] = {'disabled': changes['disabled']}
return _updated(name, binary, ret)
return _no_changes(name, binary)
def service_disabled(name, binary, cloud_name, microversion=None):
"""
Method allows disable service by binary and name.
:param name: name of a host where service is running
:param binary: name of the service have to be disabled
"""
ret = {}
services = __salt__[manilang_func['service_list']](binary=binary, cloud_name=cloud_name)['services']
# You are able to either disable certain manila-share instance by name@driver
# or all existed instances on a node by name
if '@' in name:
enabled_services = [s for s in services if name == s['host'] and s['status'] == 'enabled']
else:
enabled_services = [s for s in services if name == s['host'].split('@')[0] and s['status'] == 'enabled']
if len(enabled_services):
for service in enabled_services:
changes = __salt__[manilang_func['service_update']](service['host'], binary, 'disable', cloud_name=cloud_name, microversion=microversion)
ret[service['host']] = {'disabled': changes['disabled']}
return _updated(name, binary, ret)
return _no_changes(name, binary)
def _created(name, resource, resource_definition):
changes_dict = {
'name': name,
'changes': resource_definition,
'result': True,
'comment': '{}{} created'.format(resource, name)
}
return changes_dict
def _updated(name, resource, resource_definition):
changes_dict = {
'name': name,
'changes': resource_definition,
'result': True,
'comment': '{}{} updated'.format(resource, name)
}
return changes_dict
def _no_changes(name, resource):
changes_dict = {
'name': name,
'changes': {},
'result': True,
'comment': '{}{} is in desired state'.format(resource, name)
}
return changes_dict
def _deleted(name, resource):
changes_dict = {
'name': name,
'changes': {},
'result': True,
'comment': '{}{} removed'.format(resource, name)
}
return changes_dict
def _absent(name, resource):
changes_dict = {'name': name,
'changes': {},
'comment': '{0} {1} not present'.format(resource, name),
'result': True}
return changes_dict
def _delete_failed(name, resource):
changes_dict = {'name': name,
'changes': {},
'comment': '{0} {1} failed to delete'.format(resource,
name),
'result': False}
return changes_dict
def _create_failed(name, resource):
changes_dict = {'name': name,
'changes': {},
'comment': '{0} {1} failed to create'.format(resource,
name),
'result': False}
return changes_dict
def _update_failed(name, resource):
changes_dict = {'name': name,
'changes': {},
'comment': '{0} {1} failed to update'.format(resource,
name),
'result': False}
return changes_dict
def _find_failed(name, resource):
changes_dict = {
'name': name,
'changes': {},
'comment': '{0} {1} found multiple {0}'.format(resource, name),
'result': False,
}
return changes_dict