blob: 964518ada502ac86e4728e6af748ab29f0d8ab44 [file] [log] [blame]
Oleksiy Petrenkoe2c8da22018-03-30 18:27:58 +03001# Copyright 2018 Mirantis Inc
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
Oleksiy Petrenko14384262018-04-12 13:59:04 +030015from oslo_utils.strutils import bool_from_string
Oleksiy Petrenkoe2c8da22018-03-30 18:27:58 +030016import logging
17log = logging.getLogger(__name__)
18
19
20def __virtual__():
21 '''
22 Only load if manila module is present in __salt__
23 '''
24 return 'manilang' if 'manilang.list_share_types' in __salt__ else False
25
26
27manilang_func = {
28 'list_types': 'manilang.list_share_types',
29 'create_type': 'manilang.create_share_type',
30 'set_type_specs': 'manilang.set_share_type_extra_specs',
31 'unset_type_specs': 'manilang.unset_share_type_extra_specs',
32 'delete_type': 'manilang.delete_share_type',
33}
34
35
Oleksiy Petrenko14384262018-04-12 13:59:04 +030036def share_type_present(name, extra_specs, cloud_name, microversion=None,
37 **kwargs):
Oleksiy Petrenkoe2c8da22018-03-30 18:27:58 +030038 """
39 Ensure that share_type is present and has desired parameters
40
41 This function will create the desired share type if one with the requested
42 name does not exist. If it does, it will be updated to correspond to
43 parameters passed to this function.
44
45 :param name: name of the share type.
46 :param extra_specs: dictionary of extra_specs that share type should have.
47 It contains one required parameter - driver_handles_share_servers.
48 :param kwargs: other arguments that will be pushed into share_type
49 dictionary to be POSTed, if specified.
50
51 """
Oleksiy Petrenko14384262018-04-12 13:59:04 +030052 for key in extra_specs:
53 try:
54 extra_specs[key] = str(
55 bool_from_string(extra_specs[key], strict=True)
56 )
57 except ValueError:
58 extra_specs[key] = str(extra_specs[key])
59
Oleksiy Petrenkoe2c8da22018-03-30 18:27:58 +030060 origin_share_types = __salt__[
61 manilang_func['list_types']
62 ](cloud_name=cloud_name)['share_types']
63 share_types = [
64 share_type
65 for share_type in origin_share_types if share_type['name'] == name
66 ]
67 if not share_types:
68 try:
69 res = __salt__[
70 manilang_func['create_type']
Oleksiy Petrenko14384262018-04-12 13:59:04 +030071 ](name, extra_specs, cloud_name=cloud_name,
72 microversion=microversion, **kwargs)
Oleksiy Petrenkoe2c8da22018-03-30 18:27:58 +030073 except Exception as e:
74 log.error('Manila share type create failed with {}'.format(e))
75 return _create_failed(name, 'resource')
76 return _created(name, 'share_type', res)
77
78 elif len(share_types) == 1:
79 exact_share_type = share_types[0]
80
81 api_extra_specs = exact_share_type['extra_specs']
82 api_keys = set(api_extra_specs)
83 sls_keys = set(extra_specs)
84
85 to_delete = api_keys - sls_keys
86 to_add = sls_keys - api_keys
87 to_update = sls_keys & api_keys
88 resp = {}
89
90 for key in to_delete:
91 try:
92 __salt__[
93 manilang_func['unset_type_specs']
Oleksiy Petrenko14384262018-04-12 13:59:04 +030094 ](exact_share_type['id'], key, cloud_name=cloud_name,
95 microversion=microversion)
Oleksiy Petrenkoe2c8da22018-03-30 18:27:58 +030096 except Exception as e:
97 log.error(
98 'Manila share type delete '
99 'extra specs failed with {}'.format(e)
100 )
101 return _update_failed(name, 'share_type_extra_specs')
Oleksiy Petrenko14384262018-04-12 13:59:04 +0300102 resp.update({'deleted_extra_specs': tuple(to_delete)})
Oleksiy Petrenkoe2c8da22018-03-30 18:27:58 +0300103
104 diff = {}
105
106 for key in to_add:
107 diff[key] = extra_specs[key]
108 for key in to_update:
109 if extra_specs[key] != api_extra_specs[key]:
110 diff[key] = extra_specs[key]
111 if diff:
112 try:
113 resp.update(
114 __salt__[
115 manilang_func['set_type_specs']
Oleksiy Petrenko14384262018-04-12 13:59:04 +0300116 ](exact_share_type['id'], diff,
117 cloud_name=cloud_name, microversion=microversion)
Oleksiy Petrenkoe2c8da22018-03-30 18:27:58 +0300118 )
119 except Exception as e:
120 log.error(
121 'Manila share type update '
122 'extra specs failed with {}'.format(e)
123 )
124 return _update_failed(name, 'share_type_extra_specs')
125 if to_delete or diff:
126 return _updated(name, 'share_type', resp)
127 return _no_changes(name, 'share_type')
128 else:
129 return _find_failed(name, 'share_type')
130
131
132def share_type_absent(name, cloud_name):
133 origin_share_types = __salt__[
134 manilang_func['list_types']
135 ](cloud_name=cloud_name)['share_types']
136 share_types = [
137 share_type
138 for share_type in origin_share_types if share_type['name'] == name
139 ]
140 if not share_types:
141 return _absent(name, 'share_type')
142 elif len(share_types) == 1:
143 try:
144 __salt__[manilang_func['delete_type']](share_types[0]['id'],
145 cloud_name=cloud_name)
146 except Exception as e:
147 log.error('Manila share type delete failed with {}'.format(e))
148 return _delete_failed(name, 'share_type')
149 return _deleted(name, 'share_type')
150 else:
151 return _find_failed(name, 'share_type')
152
153
154def _created(name, resource, resource_definition):
155 changes_dict = {
156 'name': name,
157 'changes': resource_definition,
158 'result': True,
159 'comment': '{}{} created'.format(resource, name)
160 }
161 return changes_dict
162
163
164def _updated(name, resource, resource_definition):
165 changes_dict = {
166 'name': name,
167 'changes': resource_definition,
168 'result': True,
169 'comment': '{}{} updated'.format(resource, name)
170 }
171 return changes_dict
172
173
174def _no_changes(name, resource):
175 changes_dict = {
176 'name': name,
177 'changes': {},
178 'result': True,
179 'comment': '{}{} is in desired state'.format(resource, name)
180 }
181 return changes_dict
182
183
184def _deleted(name, resource):
185 changes_dict = {
186 'name': name,
187 'changes': {},
188 'result': True,
189 'comment': '{}{} removed'.format(resource, name)
190 }
191 return changes_dict
192
193
194def _absent(name, resource):
195 changes_dict = {'name': name,
196 'changes': {},
197 'comment': '{0} {1} not present'.format(resource, name),
198 'result': True}
199 return changes_dict
200
201
202def _delete_failed(name, resource):
203 changes_dict = {'name': name,
204 'changes': {},
205 'comment': '{0} {1} failed to delete'.format(resource,
206 name),
207 'result': False}
208 return changes_dict
209
210
211def _create_failed(name, resource):
212 changes_dict = {'name': name,
213 'changes': {},
214 'comment': '{0} {1} failed to create'.format(resource,
215 name),
216 'result': False}
217 return changes_dict
218
219
220def _update_failed(name, resource):
221 changes_dict = {'name': name,
222 'changes': {},
223 'comment': '{0} {1} failed to update'.format(resource,
224 name),
225 'result': False}
226 return changes_dict
227
228
229def _find_failed(name, resource):
230 changes_dict = {
231 'name': name,
232 'changes': {},
233 'comment': '{0} {1} found multiple {0}'.format(resource, name),
234 'result': False,
235 }
236 return changes_dict