This patch is primarily a refactor to make the validate-modules arg-spec
no longer generate a traceback. It additionally includes removal of deprecated
code in the virtual server module.
... | ... |
@@ -30,7 +30,6 @@ options: |
30 | 30 |
that an existing variable is set to C(value). When C(reset) sets the |
31 | 31 |
variable back to the default value. At least one of value and state |
32 | 32 |
C(reset) are required. |
33 |
- required: False |
|
34 | 33 |
default: present |
35 | 34 |
choices: |
36 | 35 |
- present |
... | ... |
@@ -39,14 +38,9 @@ options: |
39 | 39 |
description: |
40 | 40 |
- The value to set the key to. At least one of value and state C(reset) |
41 | 41 |
are required. |
42 |
- required: False |
|
43 | 42 |
notes: |
44 |
- - Requires the f5-sdk Python package on the host. This is as easy as pip |
|
45 |
- install f5-sdk. |
|
46 | 43 |
- Requires BIG-IP version 12.0.0 or greater |
47 | 44 |
extends_documentation_fragment: f5 |
48 |
-requirements: |
|
49 |
- - f5-sdk |
|
50 | 45 |
author: |
51 | 46 |
- Tim Rupp (@caphrim007) |
52 | 47 |
''' |
... | ... |
@@ -98,15 +92,37 @@ value: |
98 | 98 |
sample: false |
99 | 99 |
''' |
100 | 100 |
|
101 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
102 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
103 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
104 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
101 |
+from ansible.module_utils.basic import AnsibleModule |
|
102 |
+ |
|
103 |
+HAS_DEVEL_IMPORTS = False |
|
105 | 104 |
|
106 | 105 |
try: |
107 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
106 |
+ # Sideband repository used for dev |
|
107 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
108 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
109 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
110 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
111 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
112 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
113 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
114 |
+ try: |
|
115 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
116 |
+ except ImportError: |
|
117 |
+ HAS_F5SDK = False |
|
118 |
+ HAS_DEVEL_IMPORTS = True |
|
108 | 119 |
except ImportError: |
109 |
- HAS_F5SDK = False |
|
120 |
+ # Upstream Ansible |
|
121 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
122 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
123 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
124 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
125 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
126 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
127 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
128 |
+ try: |
|
129 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
130 |
+ except ImportError: |
|
131 |
+ HAS_F5SDK = False |
|
110 | 132 |
|
111 | 133 |
|
112 | 134 |
class Parameters(AnsibleF5Parameters): |
... | ... |
@@ -124,16 +140,6 @@ class Parameters(AnsibleF5Parameters): |
124 | 124 |
result = self._filter_params(result) |
125 | 125 |
return result |
126 | 126 |
|
127 |
- def api_params(self): |
|
128 |
- result = {} |
|
129 |
- for api_attribute in self.api_attributes: |
|
130 |
- if self.api_map is not None and api_attribute in self.api_map: |
|
131 |
- result[api_attribute] = getattr(self, self.api_map[api_attribute]) |
|
132 |
- else: |
|
133 |
- result[api_attribute] = getattr(self, api_attribute) |
|
134 |
- result = self._filter_params(result) |
|
135 |
- return result |
|
136 |
- |
|
137 | 127 |
@property |
138 | 128 |
def name(self): |
139 | 129 |
return self._values['key'] |
... | ... |
@@ -143,12 +149,17 @@ class Parameters(AnsibleF5Parameters): |
143 | 143 |
self._values['key'] = value |
144 | 144 |
|
145 | 145 |
|
146 |
+class Changes(Parameters): |
|
147 |
+ pass |
|
148 |
+ |
|
149 |
+ |
|
146 | 150 |
class ModuleManager(object): |
147 |
- def __init__(self, client): |
|
148 |
- self.client = client |
|
151 |
+ def __init__(self, *args, **kwargs): |
|
152 |
+ self.module = kwargs.get('module', None) |
|
153 |
+ self.client = kwargs.get('client', None) |
|
149 | 154 |
self.have = None |
150 |
- self.want = Parameters(self.client.module.params) |
|
151 |
- self.changes = Parameters() |
|
155 |
+ self.want = Parameters(params=self.module.params) |
|
156 |
+ self.changes = Changes() |
|
152 | 157 |
|
153 | 158 |
def _update_changed_options(self): |
154 | 159 |
changed = {} |
... | ... |
@@ -159,10 +170,10 @@ class ModuleManager(object): |
159 | 159 |
if attr1 != attr2: |
160 | 160 |
changed[key] = attr1 |
161 | 161 |
if self.want.state == 'reset': |
162 |
- if str(self.want.value) == str(self.want.default_value): |
|
163 |
- changed[self.want.key] = self.want.value |
|
162 |
+ if str(self.have.value) != str(self.have.default_value): |
|
163 |
+ changed[self.want.key] = self.have.default_value |
|
164 | 164 |
if changed: |
165 |
- self.changes = Parameters(changed) |
|
165 |
+ self.changes = Changes(params=changed) |
|
166 | 166 |
return True |
167 | 167 |
return False |
168 | 168 |
|
... | ... |
@@ -189,7 +200,7 @@ class ModuleManager(object): |
189 | 189 |
name=self.want.key |
190 | 190 |
) |
191 | 191 |
result = resource.attrs |
192 |
- return Parameters(result) |
|
192 |
+ return Parameters(params=result) |
|
193 | 193 |
|
194 | 194 |
def exists(self): |
195 | 195 |
resource = self.client.api.tm.sys.dbs.db.load( |
... | ... |
@@ -213,7 +224,7 @@ class ModuleManager(object): |
213 | 213 |
self.have = self.read_current_from_device() |
214 | 214 |
if not self.should_update(): |
215 | 215 |
return False |
216 |
- if self.client.check_mode: |
|
216 |
+ if self.module.check_mode: |
|
217 | 217 |
return True |
218 | 218 |
self.update_on_device() |
219 | 219 |
return True |
... | ... |
@@ -235,9 +246,11 @@ class ModuleManager(object): |
235 | 235 |
self.have = self.read_current_from_device() |
236 | 236 |
if not self.should_update(): |
237 | 237 |
return False |
238 |
- if self.client.check_mode: |
|
238 |
+ if self.module.check_mode: |
|
239 | 239 |
return True |
240 |
- self.update_on_device() |
|
240 |
+ self.reset_on_device() |
|
241 |
+ self.want.update({'key': self.want.key}) |
|
242 |
+ self.want.update({'value': self.have.default_value}) |
|
241 | 243 |
if self.exists(): |
242 | 244 |
return True |
243 | 245 |
else: |
... | ... |
@@ -249,13 +262,13 @@ class ModuleManager(object): |
249 | 249 |
resource = self.client.api.tm.sys.dbs.db.load( |
250 | 250 |
name=self.want.key |
251 | 251 |
) |
252 |
- resource.update(value=self.want.default_value) |
|
252 |
+ resource.update(value=self.have.default_value) |
|
253 | 253 |
|
254 | 254 |
|
255 | 255 |
class ArgumentSpec(object): |
256 | 256 |
def __init__(self): |
257 | 257 |
self.supports_check_mode = True |
258 |
- self.argument_spec = dict( |
|
258 |
+ argument_spec = dict( |
|
259 | 259 |
key=dict(required=True), |
260 | 260 |
state=dict( |
261 | 261 |
default='present', |
... | ... |
@@ -263,27 +276,30 @@ class ArgumentSpec(object): |
263 | 263 |
), |
264 | 264 |
value=dict() |
265 | 265 |
) |
266 |
- self.f5_product_name = 'bigip' |
|
266 |
+ self.argument_spec = {} |
|
267 |
+ self.argument_spec.update(f5_argument_spec) |
|
268 |
+ self.argument_spec.update(argument_spec) |
|
267 | 269 |
|
268 | 270 |
|
269 | 271 |
def main(): |
270 |
- if not HAS_F5SDK: |
|
271 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
272 |
- |
|
273 | 272 |
spec = ArgumentSpec() |
274 | 273 |
|
275 |
- client = AnsibleF5Client( |
|
274 |
+ module = AnsibleModule( |
|
276 | 275 |
argument_spec=spec.argument_spec, |
277 |
- supports_check_mode=spec.supports_check_mode, |
|
278 |
- f5_product_name=spec.f5_product_name |
|
276 |
+ supports_check_mode=spec.supports_check_mode |
|
279 | 277 |
) |
278 |
+ if not HAS_F5SDK: |
|
279 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
280 | 280 |
|
281 | 281 |
try: |
282 |
- mm = ModuleManager(client) |
|
282 |
+ client = F5Client(**module.params) |
|
283 |
+ mm = ModuleManager(module=module, client=client) |
|
283 | 284 |
results = mm.exec_module() |
284 |
- client.module.exit_json(**results) |
|
285 |
- except F5ModuleError as e: |
|
286 |
- client.module.fail_json(msg=str(e)) |
|
285 |
+ cleanup_tokens(client) |
|
286 |
+ module.exit_json(**results) |
|
287 |
+ except F5ModuleError as ex: |
|
288 |
+ cleanup_tokens(client) |
|
289 |
+ module.fail_json(msg=str(ex)) |
|
287 | 290 |
|
288 | 291 |
|
289 | 292 |
if __name__ == '__main__': |
... | ... |
@@ -30,48 +30,44 @@ options: |
30 | 30 |
gui_setup: |
31 | 31 |
description: |
32 | 32 |
- C(enable) or C(disabled) the Setup utility in the browser-based |
33 |
- Configuration utility |
|
34 |
- choices: ['yes', 'no'] |
|
33 |
+ Configuration utility. |
|
34 |
+ type: bool |
|
35 | 35 |
lcd_display: |
36 | 36 |
description: |
37 | 37 |
- Specifies, when C(enabled), that the system menu displays on the |
38 | 38 |
LCD screen on the front of the unit. This setting has no effect |
39 | 39 |
when used on the VE platform. |
40 |
- choices: ['yes', 'no'] |
|
40 |
+ type: bool |
|
41 | 41 |
mgmt_dhcp: |
42 | 42 |
description: |
43 | 43 |
- Specifies whether or not to enable DHCP client on the management |
44 | 44 |
interface |
45 |
- choices: ['yes', 'no'] |
|
45 |
+ type: bool |
|
46 | 46 |
net_reboot: |
47 | 47 |
description: |
48 | 48 |
- Specifies, when C(enabled), that the next time you reboot the system, |
49 | 49 |
the system boots to an ISO image on the network, rather than an |
50 | 50 |
internal media drive. |
51 |
- choices: ['yes', 'no'] |
|
51 |
+ type: bool |
|
52 | 52 |
quiet_boot: |
53 | 53 |
description: |
54 | 54 |
- Specifies, when C(enabled), that the system suppresses informational |
55 | 55 |
text on the console during the boot cycle. When C(disabled), the |
56 | 56 |
system presents messages and informational text on the console during |
57 | 57 |
the boot cycle. |
58 |
- choices: ['yes', 'no'] |
|
58 |
+ type: bool |
|
59 | 59 |
security_banner: |
60 | 60 |
description: |
61 | 61 |
- Specifies whether the system displays an advisory message on the |
62 | 62 |
login screen. |
63 |
- choices: ['yes', 'no'] |
|
63 |
+ type: bool |
|
64 | 64 |
state: |
65 | 65 |
description: |
66 | 66 |
- The state of the variable on the system. When C(present), guarantees |
67 | 67 |
that an existing variable is set to C(value). |
68 |
- required: false |
|
69 | 68 |
default: present |
70 | 69 |
choices: |
71 | 70 |
- present |
72 |
-notes: |
|
73 |
- - Requires the f5-sdk Python package on the host. This is as easy as pip |
|
74 |
- install f5-sdk. |
|
75 | 71 |
extends_documentation_fragment: f5 |
76 | 72 |
requirements: |
77 | 73 |
- f5-sdk |
... | ... |
@@ -139,20 +135,40 @@ security_banner: |
139 | 139 |
sample: enabled |
140 | 140 |
''' |
141 | 141 |
|
142 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
143 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
144 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
145 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
142 |
+from ansible.module_utils.basic import AnsibleModule |
|
146 | 143 |
from ansible.module_utils.parsing.convert_bool import BOOLEANS |
147 | 144 |
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE |
148 | 145 |
from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE |
149 |
-from ansible.module_utils.six import iteritems |
|
150 |
-from collections import defaultdict |
|
146 |
+ |
|
147 |
+HAS_DEVEL_IMPORTS = False |
|
151 | 148 |
|
152 | 149 |
try: |
153 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
150 |
+ # Sideband repository used for dev |
|
151 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
152 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
153 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
154 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
155 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
156 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
157 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
158 |
+ try: |
|
159 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
160 |
+ except ImportError: |
|
161 |
+ HAS_F5SDK = False |
|
162 |
+ HAS_DEVEL_IMPORTS = True |
|
154 | 163 |
except ImportError: |
155 |
- HAS_F5SDK = False |
|
164 |
+ # Upstream Ansible |
|
165 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
166 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
167 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
168 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
169 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
170 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
171 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
172 |
+ try: |
|
173 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
174 |
+ except ImportError: |
|
175 |
+ HAS_F5SDK = False |
|
156 | 176 |
|
157 | 177 |
|
158 | 178 |
class Parameters(AnsibleF5Parameters): |
... | ... |
@@ -182,46 +198,6 @@ class Parameters(AnsibleF5Parameters): |
182 | 182 |
'mgmt_dhcp', 'net_reboot', 'quiet_boot', 'console_timeout' |
183 | 183 |
] |
184 | 184 |
|
185 |
- def __init__(self, params=None): |
|
186 |
- self._values = defaultdict(lambda: None) |
|
187 |
- self._values['__warnings'] = [] |
|
188 |
- if params: |
|
189 |
- self.update(params=params) |
|
190 |
- |
|
191 |
- def update(self, params=None): |
|
192 |
- if params: |
|
193 |
- for k, v in iteritems(params): |
|
194 |
- if self.api_map is not None and k in self.api_map: |
|
195 |
- map_key = self.api_map[k] |
|
196 |
- else: |
|
197 |
- map_key = k |
|
198 |
- |
|
199 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
200 |
- # using a map provided by the module developer |
|
201 |
- class_attr = getattr(type(self), map_key, None) |
|
202 |
- if isinstance(class_attr, property): |
|
203 |
- # There is a mapped value for the api_map key |
|
204 |
- if class_attr.fset is None: |
|
205 |
- # If the mapped value does not have |
|
206 |
- # an associated setter |
|
207 |
- self._values[map_key] = v |
|
208 |
- else: |
|
209 |
- # The mapped value has a setter |
|
210 |
- setattr(self, map_key, v) |
|
211 |
- else: |
|
212 |
- # If the mapped value is not a @property |
|
213 |
- self._values[map_key] = v |
|
214 |
- |
|
215 |
- def api_params(self): |
|
216 |
- result = {} |
|
217 |
- for api_attribute in self.api_attributes: |
|
218 |
- if self.api_map is not None and api_attribute in self.api_map: |
|
219 |
- result[api_attribute] = getattr(self, self.api_map[api_attribute]) |
|
220 |
- else: |
|
221 |
- result[api_attribute] = getattr(self, api_attribute) |
|
222 |
- result = self._filter_params(result) |
|
223 |
- return result |
|
224 |
- |
|
225 | 185 |
|
226 | 186 |
class ApiParameters(Parameters): |
227 | 187 |
pass |
... | ... |
@@ -323,9 +299,10 @@ class Difference(object): |
323 | 323 |
|
324 | 324 |
|
325 | 325 |
class ModuleManager(object): |
326 |
- def __init__(self, client): |
|
327 |
- self.client = client |
|
328 |
- self.want = ModuleParameters(params=self.client.module.params) |
|
326 |
+ def __init__(self, *args, **kwargs): |
|
327 |
+ self.module = kwargs.get('module', None) |
|
328 |
+ self.client = kwargs.get('client', None) |
|
329 |
+ self.want = ModuleParameters(params=self.module.params) |
|
329 | 330 |
self.have = ApiParameters() |
330 | 331 |
self.changes = UsableChanges() |
331 | 332 |
|
... | ... |
@@ -335,7 +312,7 @@ class ModuleManager(object): |
335 | 335 |
if getattr(self.want, key) is not None: |
336 | 336 |
changed[key] = getattr(self.want, key) |
337 | 337 |
if changed: |
338 |
- self.changes = UsableChanges(changed) |
|
338 |
+ self.changes = UsableChanges(params=changed) |
|
339 | 339 |
|
340 | 340 |
def _update_changed_options(self): |
341 | 341 |
diff = Difference(self.want, self.have) |
... | ... |
@@ -351,7 +328,7 @@ class ModuleManager(object): |
351 | 351 |
else: |
352 | 352 |
changed[k] = change |
353 | 353 |
if changed: |
354 |
- self.changes = UsableChanges(changed) |
|
354 |
+ self.changes = UsableChanges(params=changed) |
|
355 | 355 |
return True |
356 | 356 |
return False |
357 | 357 |
|
... | ... |
@@ -369,7 +346,7 @@ class ModuleManager(object): |
369 | 369 |
except iControlUnexpectedHTTPError as e: |
370 | 370 |
raise F5ModuleError(str(e)) |
371 | 371 |
|
372 |
- reportable = ReportableChanges(self.changes.to_return()) |
|
372 |
+ reportable = ReportableChanges(params=self.changes.to_return()) |
|
373 | 373 |
changes = reportable.to_return() |
374 | 374 |
result.update(**changes) |
375 | 375 |
result.update(dict(changed=changed)) |
... | ... |
@@ -379,7 +356,7 @@ class ModuleManager(object): |
379 | 379 |
def _announce_deprecations(self, result): |
380 | 380 |
warnings = result.pop('__warnings', []) |
381 | 381 |
for warning in warnings: |
382 |
- self.client.module.deprecate( |
|
382 |
+ self.module.deprecate( |
|
383 | 383 |
msg=warning['msg'], |
384 | 384 |
version=warning['version'] |
385 | 385 |
) |
... | ... |
@@ -390,13 +367,13 @@ class ModuleManager(object): |
390 | 390 |
def read_current_from_device(self): |
391 | 391 |
resource = self.client.api.tm.sys.global_settings.load() |
392 | 392 |
result = resource.attrs |
393 |
- return ApiParameters(result) |
|
393 |
+ return ApiParameters(params=result) |
|
394 | 394 |
|
395 | 395 |
def update(self): |
396 | 396 |
self.have = self.read_current_from_device() |
397 | 397 |
if not self.should_update(): |
398 | 398 |
return False |
399 |
- if self.client.check_mode: |
|
399 |
+ if self.module.check_mode: |
|
400 | 400 |
return True |
401 | 401 |
self.update_on_device() |
402 | 402 |
return True |
... | ... |
@@ -412,7 +389,7 @@ class ArgumentSpec(object): |
412 | 412 |
self.supports_check_mode = True |
413 | 413 |
self.states = ['present'] |
414 | 414 |
self.on_off_choices = ['enabled', 'disabled', 'True', 'False'] + list(BOOLEANS) |
415 |
- self.argument_spec = dict( |
|
415 |
+ argument_spec = dict( |
|
416 | 416 |
security_banner=dict( |
417 | 417 |
choices=self.on_off_choices |
418 | 418 |
), |
... | ... |
@@ -435,39 +412,30 @@ class ArgumentSpec(object): |
435 | 435 |
console_timeout=dict(required=False, type='int', default=None), |
436 | 436 |
state=dict(default='present', choices=['present']) |
437 | 437 |
) |
438 |
- self.f5_product_name = 'bigip' |
|
439 |
- |
|
440 |
- |
|
441 |
-def cleanup_tokens(client): |
|
442 |
- try: |
|
443 |
- resource = client.api.shared.authz.tokens_s.token.load( |
|
444 |
- name=client.api.icrs.token |
|
445 |
- ) |
|
446 |
- resource.delete() |
|
447 |
- except Exception: |
|
448 |
- pass |
|
438 |
+ self.argument_spec = {} |
|
439 |
+ self.argument_spec.update(f5_argument_spec) |
|
440 |
+ self.argument_spec.update(argument_spec) |
|
449 | 441 |
|
450 | 442 |
|
451 | 443 |
def main(): |
452 |
- if not HAS_F5SDK: |
|
453 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
454 |
- |
|
455 | 444 |
spec = ArgumentSpec() |
456 | 445 |
|
457 |
- client = AnsibleF5Client( |
|
446 |
+ module = AnsibleModule( |
|
458 | 447 |
argument_spec=spec.argument_spec, |
459 |
- supports_check_mode=spec.supports_check_mode, |
|
460 |
- f5_product_name=spec.f5_product_name |
|
448 |
+ supports_check_mode=spec.supports_check_mode |
|
461 | 449 |
) |
450 |
+ if not HAS_F5SDK: |
|
451 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
462 | 452 |
|
463 | 453 |
try: |
464 |
- mm = ModuleManager(client) |
|
454 |
+ client = F5Client(**module.params) |
|
455 |
+ mm = ModuleManager(module=module, client=client) |
|
465 | 456 |
results = mm.exec_module() |
466 | 457 |
cleanup_tokens(client) |
467 |
- client.module.exit_json(**results) |
|
468 |
- except F5ModuleError as e: |
|
458 |
+ module.exit_json(**results) |
|
459 |
+ except F5ModuleError as ex: |
|
469 | 460 |
cleanup_tokens(client) |
470 |
- client.module.fail_json(msg=str(e)) |
|
461 |
+ module.fail_json(msg=str(ex)) |
|
471 | 462 |
|
472 | 463 |
|
473 | 464 |
if __name__ == '__main__': |
... | ... |
@@ -24,11 +24,20 @@ options: |
24 | 24 |
description: |
25 | 25 |
- The name of the traffic group. |
26 | 26 |
required: True |
27 |
-notes: |
|
28 |
- - Requires the f5-sdk Python package on the host. This is as easy as |
|
29 |
- C(pip install f5-sdk). |
|
30 |
-requirements: |
|
31 |
- - f5-sdk >= 3.0.5 |
|
27 |
+ partition: |
|
28 |
+ description: |
|
29 |
+ - Device partition to manage resources on. |
|
30 |
+ default: Common |
|
31 |
+ version_added: 2.5 |
|
32 |
+ state: |
|
33 |
+ description: |
|
34 |
+ - When C(present), ensures that the traffic group exists. |
|
35 |
+ - When C(absent), ensures the traffic group is removed. |
|
36 |
+ default: present |
|
37 |
+ choices: |
|
38 |
+ - present |
|
39 |
+ - absent |
|
40 |
+ version_added: 2.5 |
|
32 | 41 |
extends_documentation_fragment: f5 |
33 | 42 |
author: |
34 | 43 |
- Tim Rupp (@caphrim007) |
... | ... |
@@ -49,18 +58,38 @@ RETURN = r''' |
49 | 49 |
# only common fields returned |
50 | 50 |
''' |
51 | 51 |
|
52 |
+from ansible.module_utils.basic import AnsibleModule |
|
53 |
+from ansible.module_utils.basic import env_fallback |
|
52 | 54 |
|
53 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
54 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
55 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
56 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
57 |
-from ansible.module_utils.six import iteritems |
|
58 |
-from collections import defaultdict |
|
55 |
+HAS_DEVEL_IMPORTS = False |
|
59 | 56 |
|
60 | 57 |
try: |
61 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
58 |
+ # Sideband repository used for dev |
|
59 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
60 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
61 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
62 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
63 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
64 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
65 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
66 |
+ try: |
|
67 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
68 |
+ except ImportError: |
|
69 |
+ HAS_F5SDK = False |
|
70 |
+ HAS_DEVEL_IMPORTS = True |
|
62 | 71 |
except ImportError: |
63 |
- HAS_F5SDK = False |
|
72 |
+ # Upstream Ansible |
|
73 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
74 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
75 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
76 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
77 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
78 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
79 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
80 |
+ try: |
|
81 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
82 |
+ except ImportError: |
|
83 |
+ HAS_F5SDK = False |
|
64 | 84 |
|
65 | 85 |
|
66 | 86 |
class Parameters(AnsibleF5Parameters): |
... | ... |
@@ -80,36 +109,6 @@ class Parameters(AnsibleF5Parameters): |
80 | 80 |
|
81 | 81 |
] |
82 | 82 |
|
83 |
- def __init__(self, params=None): |
|
84 |
- self._values = defaultdict(lambda: None) |
|
85 |
- self._values['__warnings'] = [] |
|
86 |
- if params: |
|
87 |
- self.update(params=params) |
|
88 |
- |
|
89 |
- def update(self, params=None): |
|
90 |
- if params: |
|
91 |
- for k, v in iteritems(params): |
|
92 |
- if self.api_map is not None and k in self.api_map: |
|
93 |
- map_key = self.api_map[k] |
|
94 |
- else: |
|
95 |
- map_key = k |
|
96 |
- |
|
97 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
98 |
- # using a map provided by the module developer |
|
99 |
- class_attr = getattr(type(self), map_key, None) |
|
100 |
- if isinstance(class_attr, property): |
|
101 |
- # There is a mapped value for the api_map key |
|
102 |
- if class_attr.fset is None: |
|
103 |
- # If the mapped value does not have |
|
104 |
- # an associated setter |
|
105 |
- self._values[map_key] = v |
|
106 |
- else: |
|
107 |
- # The mapped value has a setter |
|
108 |
- setattr(self, map_key, v) |
|
109 |
- else: |
|
110 |
- # If the mapped value is not a @property |
|
111 |
- self._values[map_key] = v |
|
112 |
- |
|
113 | 83 |
def to_return(self): |
114 | 84 |
result = {} |
115 | 85 |
try: |
... | ... |
@@ -120,16 +119,6 @@ class Parameters(AnsibleF5Parameters): |
120 | 120 |
pass |
121 | 121 |
return result |
122 | 122 |
|
123 |
- def api_params(self): |
|
124 |
- result = {} |
|
125 |
- for api_attribute in self.api_attributes: |
|
126 |
- if self.api_map is not None and api_attribute in self.api_map: |
|
127 |
- result[api_attribute] = getattr(self, self.api_map[api_attribute]) |
|
128 |
- else: |
|
129 |
- result[api_attribute] = getattr(self, api_attribute) |
|
130 |
- result = self._filter_params(result) |
|
131 |
- return result |
|
132 |
- |
|
133 | 123 |
|
134 | 124 |
class Changes(Parameters): |
135 | 125 |
pass |
... | ... |
@@ -164,9 +153,10 @@ class Difference(object): |
164 | 164 |
|
165 | 165 |
|
166 | 166 |
class ModuleManager(object): |
167 |
- def __init__(self, client): |
|
168 |
- self.client = client |
|
169 |
- self.want = Parameters(self.client.module.params) |
|
167 |
+ def __init__(self, *args, **kwargs): |
|
168 |
+ self.module = kwargs.get('module', None) |
|
169 |
+ self.client = kwargs.get('client', None) |
|
170 |
+ self.want = Parameters(params=self.module.params) |
|
170 | 171 |
self.changes = Changes() |
171 | 172 |
|
172 | 173 |
def _set_changed_options(self): |
... | ... |
@@ -175,38 +165,9 @@ class ModuleManager(object): |
175 | 175 |
if getattr(self.want, key) is not None: |
176 | 176 |
changed[key] = getattr(self.want, key) |
177 | 177 |
if changed: |
178 |
- self.changes = Changes(changed) |
|
178 |
+ self.changes = Changes(params=changed) |
|
179 | 179 |
|
180 | 180 |
def _update_changed_options(self): |
181 |
- """Sets the changed updatables when updating a resource |
|
182 |
- |
|
183 |
- A module needs to know what changed to determine whether to update |
|
184 |
- a resource (or set of resources). This method accomplishes this by |
|
185 |
- invoking the Difference engine code. |
|
186 |
- |
|
187 |
- Each parameter in the `Parameter` class' `updatables` array will be |
|
188 |
- given to the Difference engine's `compare` method. This is done in the |
|
189 |
- order the updatables are listed in the array. |
|
190 |
- |
|
191 |
- The `compare` method updates the `changes` dictionary if the following |
|
192 |
- way, |
|
193 |
- |
|
194 |
- * If `None` is returned, a change will not be registered. |
|
195 |
- * If a dictionary is returned, the `changes` dictionary will be updated |
|
196 |
- with the values in what was returned. |
|
197 |
- * Otherwise, the `changes` dictionary's key (the parameter being |
|
198 |
- compared) will be set to the value that is returned by `compare` |
|
199 |
- |
|
200 |
- The dictionary behavior is in place to allow you to change the key |
|
201 |
- that is set in the `changes` dictionary. There are frequently cases |
|
202 |
- where there is not a clean API map that can be set, nor a way to |
|
203 |
- otherwise allow you to change the attribute name of the resource being |
|
204 |
- updated before it is sent off to the remote device. Using a dictionary |
|
205 |
- return value of `compare` allows you to do this. |
|
206 |
- |
|
207 |
- Returns: |
|
208 |
- bool: True when changes are present. False otherwise. |
|
209 |
- """ |
|
210 | 181 |
diff = Difference(self.want, self.have) |
211 | 182 |
updatables = Parameters.updatables |
212 | 183 |
changed = dict() |
... | ... |
@@ -220,7 +181,7 @@ class ModuleManager(object): |
220 | 220 |
else: |
221 | 221 |
changed[k] = change |
222 | 222 |
if changed: |
223 |
- self.changes = Changes(changed) |
|
223 |
+ self.changes = Changes(params=changed) |
|
224 | 224 |
return True |
225 | 225 |
return False |
226 | 226 |
|
... | ... |
@@ -252,7 +213,7 @@ class ModuleManager(object): |
252 | 252 |
def _announce_deprecations(self, result): |
253 | 253 |
warnings = result.pop('__warnings', []) |
254 | 254 |
for warning in warnings: |
255 |
- self.client.module.deprecate( |
|
255 |
+ self.module.deprecate( |
|
256 | 256 |
msg=warning['msg'], |
257 | 257 |
version=warning['version'] |
258 | 258 |
) |
... | ... |
@@ -274,13 +235,13 @@ class ModuleManager(object): |
274 | 274 |
self.have = self.read_current_from_device() |
275 | 275 |
if not self.should_update(): |
276 | 276 |
return False |
277 |
- if self.client.check_mode: |
|
277 |
+ if self.module.check_mode: |
|
278 | 278 |
return True |
279 | 279 |
self.update_on_device() |
280 | 280 |
return True |
281 | 281 |
|
282 | 282 |
def remove(self): |
283 |
- if self.client.check_mode: |
|
283 |
+ if self.module.check_mode: |
|
284 | 284 |
return True |
285 | 285 |
self.remove_from_device() |
286 | 286 |
if self.exists(): |
... | ... |
@@ -293,7 +254,7 @@ class ModuleManager(object): |
293 | 293 |
raise F5ModuleError( |
294 | 294 |
"Traffic groups can only be created in the /Common partition" |
295 | 295 |
) |
296 |
- if self.client.check_mode: |
|
296 |
+ if self.module.check_mode: |
|
297 | 297 |
return True |
298 | 298 |
self.create_on_device() |
299 | 299 |
return True |
... | ... |
@@ -333,49 +294,44 @@ class ModuleManager(object): |
333 | 333 |
partition=self.want.partition |
334 | 334 |
) |
335 | 335 |
result = resource.attrs |
336 |
- return Parameters(result) |
|
336 |
+ return Parameters(params=result) |
|
337 | 337 |
|
338 | 338 |
|
339 | 339 |
class ArgumentSpec(object): |
340 | 340 |
def __init__(self): |
341 | 341 |
self.supports_check_mode = True |
342 |
- self.argument_spec = dict( |
|
342 |
+ argument_spec = dict( |
|
343 | 343 |
name=dict(required=True), |
344 |
- state=dict(default='present', choices=['absent', 'present']) |
|
345 |
- ) |
|
346 |
- self.f5_product_name = 'bigip' |
|
347 |
- |
|
348 |
- |
|
349 |
-def cleanup_tokens(client): |
|
350 |
- try: |
|
351 |
- resource = client.api.shared.authz.tokens_s.token.load( |
|
352 |
- name=client.api.icrs.token |
|
344 |
+ state=dict(default='present', choices=['absent', 'present']), |
|
345 |
+ partition=dict( |
|
346 |
+ default='Common', |
|
347 |
+ fallback=(env_fallback, ['F5_PARTITION']) |
|
348 |
+ ) |
|
353 | 349 |
) |
354 |
- resource.delete() |
|
355 |
- except Exception: |
|
356 |
- pass |
|
350 |
+ self.argument_spec = {} |
|
351 |
+ self.argument_spec.update(f5_argument_spec) |
|
352 |
+ self.argument_spec.update(argument_spec) |
|
357 | 353 |
|
358 | 354 |
|
359 | 355 |
def main(): |
360 |
- if not HAS_F5SDK: |
|
361 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
362 |
- |
|
363 | 356 |
spec = ArgumentSpec() |
364 | 357 |
|
365 |
- client = AnsibleF5Client( |
|
358 |
+ module = AnsibleModule( |
|
366 | 359 |
argument_spec=spec.argument_spec, |
367 |
- supports_check_mode=spec.supports_check_mode, |
|
368 |
- f5_product_name=spec.f5_product_name |
|
360 |
+ supports_check_mode=spec.supports_check_mode |
|
369 | 361 |
) |
362 |
+ if not HAS_F5SDK: |
|
363 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
370 | 364 |
|
371 | 365 |
try: |
372 |
- mm = ModuleManager(client) |
|
366 |
+ client = F5Client(**module.params) |
|
367 |
+ mm = ModuleManager(module=module, client=client) |
|
373 | 368 |
results = mm.exec_module() |
374 | 369 |
cleanup_tokens(client) |
375 |
- client.module.exit_json(**results) |
|
376 |
- except F5ModuleError as e: |
|
370 |
+ module.exit_json(**results) |
|
371 |
+ except F5ModuleError as ex: |
|
377 | 372 |
cleanup_tokens(client) |
378 |
- client.module.fail_json(msg=str(e)) |
|
373 |
+ module.fail_json(msg=str(ex)) |
|
379 | 374 |
|
380 | 375 |
|
381 | 376 |
if __name__ == '__main__': |
... | ... |
@@ -87,8 +87,6 @@ options: |
87 | 87 |
- installed |
88 | 88 |
- present |
89 | 89 |
notes: |
90 |
- - Requires the f5-sdk Python package on the host. This is as easy as |
|
91 |
- pip install f5-sdk. |
|
92 | 90 |
- Only the most basic checks are performed by this module. Other checks and |
93 | 91 |
considerations need to be taken into account. See the following URL. |
94 | 92 |
https://support.f5.com/kb/en-us/solutions/public/11000/300/sol11318.html |
... | ... |
@@ -110,8 +108,6 @@ notes: |
110 | 110 |
- This module does not support restoring encrypted archives on replacement |
111 | 111 |
RMA units. |
112 | 112 |
extends_documentation_fragment: f5 |
113 |
-requirements: |
|
114 |
- - f5-sdk |
|
115 | 113 |
author: |
116 | 114 |
- Tim Rupp (@caphrim007) |
117 | 115 |
''' |
... | ... |
@@ -182,28 +178,49 @@ RETURN = r''' |
182 | 182 |
|
183 | 183 |
import os |
184 | 184 |
import re |
185 |
-import sys |
|
186 | 185 |
import time |
187 | 186 |
|
188 |
-from distutils.version import LooseVersion |
|
189 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
190 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
191 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
192 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
187 |
+from ansible.module_utils.basic import AnsibleModule |
|
193 | 188 |
from ansible.module_utils.six import iteritems |
189 |
+from distutils.version import LooseVersion |
|
190 |
+ |
|
191 |
+HAS_DEVEL_IMPORTS = False |
|
194 | 192 |
|
195 | 193 |
try: |
196 |
- from collections import OrderedDict |
|
194 |
+ # Sideband repository used for dev |
|
195 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
196 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
197 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
198 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
199 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
200 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
201 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
202 |
+ try: |
|
203 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
204 |
+ except ImportError: |
|
205 |
+ HAS_F5SDK = False |
|
206 |
+ HAS_DEVEL_IMPORTS = True |
|
197 | 207 |
except ImportError: |
208 |
+ # Upstream Ansible |
|
209 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
210 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
211 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
212 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
213 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
214 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
215 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
198 | 216 |
try: |
199 |
- from ordereddict import OrderedDict |
|
217 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
200 | 218 |
except ImportError: |
201 |
- pass |
|
219 |
+ HAS_F5SDK = False |
|
202 | 220 |
|
203 | 221 |
try: |
204 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
222 |
+ from collections import OrderedDict |
|
205 | 223 |
except ImportError: |
206 |
- HAS_F5SDK = False |
|
224 |
+ try: |
|
225 |
+ from ordereddict import OrderedDict |
|
226 |
+ except ImportError: |
|
227 |
+ pass |
|
207 | 228 |
|
208 | 229 |
|
209 | 230 |
class Parameters(AnsibleF5Parameters): |
... | ... |
@@ -292,14 +309,15 @@ class Parameters(AnsibleF5Parameters): |
292 | 292 |
|
293 | 293 |
|
294 | 294 |
class ModuleManager(object): |
295 |
- def __init__(self, client): |
|
296 |
- self.client = client |
|
295 |
+ def __init__(self, *args, **kwargs): |
|
296 |
+ self.client = kwargs.get('client', None) |
|
297 |
+ self.kwargs = kwargs |
|
297 | 298 |
|
298 | 299 |
def exec_module(self): |
299 | 300 |
if self.is_version_v1(): |
300 |
- manager = V1Manager(self.client) |
|
301 |
+ manager = V1Manager(**self.kwargs) |
|
301 | 302 |
else: |
302 |
- manager = V2Manager(self.client) |
|
303 |
+ manager = V2Manager(**self.kwargs) |
|
303 | 304 |
|
304 | 305 |
return manager.exec_module() |
305 | 306 |
|
... | ... |
@@ -321,10 +339,10 @@ class ModuleManager(object): |
321 | 321 |
|
322 | 322 |
|
323 | 323 |
class BaseManager(object): |
324 |
- def __init__(self, client): |
|
325 |
- self.client = client |
|
326 |
- self.have = None |
|
327 |
- self.want = Parameters(self.client.module.params) |
|
324 |
+ def __init__(self, *args, **kwargs): |
|
325 |
+ self.module = kwargs.get('module', None) |
|
326 |
+ self.client = kwargs.get('client', None) |
|
327 |
+ self.want = Parameters(params=self.module.params) |
|
328 | 328 |
self.changes = Parameters() |
329 | 329 |
|
330 | 330 |
def exec_module(self): |
... | ... |
@@ -352,7 +370,7 @@ class BaseManager(object): |
352 | 352 |
return self.create() |
353 | 353 |
|
354 | 354 |
def update(self): |
355 |
- if self.client.check_mode: |
|
355 |
+ if self.module.check_mode: |
|
356 | 356 |
if self.want.force: |
357 | 357 |
return True |
358 | 358 |
return False |
... | ... |
@@ -365,7 +383,7 @@ class BaseManager(object): |
365 | 365 |
return False |
366 | 366 |
|
367 | 367 |
def create(self): |
368 |
- if self.client.check_mode: |
|
368 |
+ if self.module.check_mode: |
|
369 | 369 |
return True |
370 | 370 |
self.create_on_device() |
371 | 371 |
if not self.exists(): |
... | ... |
@@ -386,7 +404,7 @@ class BaseManager(object): |
386 | 386 |
return False |
387 | 387 |
|
388 | 388 |
def remove(self): |
389 |
- if self.client.check_mode: |
|
389 |
+ if self.module.check_mode: |
|
390 | 390 |
return True |
391 | 391 |
self.remove_from_device() |
392 | 392 |
if self.exists(): |
... | ... |
@@ -466,7 +484,6 @@ class V1Manager(BaseManager): |
466 | 466 |
* No API to upload UCS files |
467 | 467 |
|
468 | 468 |
""" |
469 |
- |
|
470 | 469 |
def create_on_device(self): |
471 | 470 |
remote_path = "/var/local/ucs" |
472 | 471 |
tpath_name = '/var/config/rest/downloads' |
... | ... |
@@ -563,7 +580,7 @@ class V2Manager(V1Manager): |
563 | 563 |
class ArgumentSpec(object): |
564 | 564 |
def __init__(self): |
565 | 565 |
self.supports_check_mode = True |
566 |
- self.argument_spec = dict( |
|
566 |
+ argument_spec = dict( |
|
567 | 567 |
force=dict( |
568 | 568 |
type='bool', |
569 | 569 |
default='no' |
... | ... |
@@ -585,30 +602,30 @@ class ArgumentSpec(object): |
585 | 585 |
), |
586 | 586 |
ucs=dict(required=True) |
587 | 587 |
) |
588 |
- self.f5_product_name = 'bigip' |
|
588 |
+ self.argument_spec = {} |
|
589 |
+ self.argument_spec.update(f5_argument_spec) |
|
590 |
+ self.argument_spec.update(argument_spec) |
|
589 | 591 |
|
590 | 592 |
|
591 | 593 |
def main(): |
592 |
- if not HAS_F5SDK: |
|
593 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
594 |
- |
|
595 |
- if sys.version_info < (2, 7): |
|
596 |
- raise F5ModuleError("F5 Ansible modules require Python >= 2.7") |
|
597 |
- |
|
598 | 594 |
spec = ArgumentSpec() |
599 | 595 |
|
600 |
- client = AnsibleF5Client( |
|
596 |
+ module = AnsibleModule( |
|
601 | 597 |
argument_spec=spec.argument_spec, |
602 |
- supports_check_mode=spec.supports_check_mode, |
|
603 |
- f5_product_name=spec.f5_product_name |
|
598 |
+ supports_check_mode=spec.supports_check_mode |
|
604 | 599 |
) |
600 |
+ if not HAS_F5SDK: |
|
601 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
605 | 602 |
|
606 | 603 |
try: |
607 |
- mm = ModuleManager(client) |
|
604 |
+ client = F5Client(**module.params) |
|
605 |
+ mm = ModuleManager(module=module, client=client) |
|
608 | 606 |
results = mm.exec_module() |
609 |
- client.module.exit_json(**results) |
|
610 |
- except F5ModuleError as e: |
|
611 |
- client.module.fail_json(msg=str(e)) |
|
607 |
+ cleanup_tokens(client) |
|
608 |
+ module.exit_json(**results) |
|
609 |
+ except F5ModuleError as ex: |
|
610 |
+ cleanup_tokens(client) |
|
611 |
+ module.fail_json(msg=str(ex)) |
|
612 | 612 |
|
613 | 613 |
|
614 | 614 |
if __name__ == '__main__': |
... | ... |
@@ -74,13 +74,14 @@ options: |
74 | 74 |
choices: |
75 | 75 |
- always |
76 | 76 |
- on_create |
77 |
+ partition: |
|
78 |
+ description: |
|
79 |
+ - Device partition to manage resources on. |
|
80 |
+ default: Common |
|
81 |
+ version_added: 2.5 |
|
77 | 82 |
notes: |
78 |
- - Requires the f5-sdk Python package on the host. This is as easy as |
|
79 |
- pip install f5-sdk. |
|
80 | 83 |
- Requires BIG-IP versions >= 12.0.0 |
81 | 84 |
extends_documentation_fragment: f5 |
82 |
-requirements: |
|
83 |
- - f5-sdk |
|
84 | 85 |
author: |
85 | 86 |
- Tim Rupp (@caphrim007) |
86 | 87 |
- Wojciech Wypior (@wojtek0806) |
... | ... |
@@ -191,23 +192,44 @@ shell: |
191 | 191 |
|
192 | 192 |
import re |
193 | 193 |
|
194 |
+from ansible.module_utils.basic import AnsibleModule |
|
195 |
+from ansible.module_utils.basic import env_fallback |
|
194 | 196 |
from distutils.version import LooseVersion |
195 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
196 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
197 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
198 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
199 |
-from ansible.module_utils.six import iteritems |
|
200 |
-from collections import defaultdict |
|
197 |
+ |
|
198 |
+HAS_DEVEL_IMPORTS = False |
|
201 | 199 |
|
202 | 200 |
try: |
203 |
- from StringIO import StringIO |
|
201 |
+ # Sideband repository used for dev |
|
202 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
203 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
204 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
205 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
206 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
207 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
208 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
209 |
+ try: |
|
210 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
211 |
+ except ImportError: |
|
212 |
+ HAS_F5SDK = False |
|
213 |
+ HAS_DEVEL_IMPORTS = True |
|
204 | 214 |
except ImportError: |
205 |
- from io import StringIO |
|
215 |
+ # Upstream Ansible |
|
216 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
217 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
218 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
219 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
220 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
221 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
222 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
223 |
+ try: |
|
224 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
225 |
+ except ImportError: |
|
226 |
+ HAS_F5SDK = False |
|
206 | 227 |
|
207 | 228 |
try: |
208 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
229 |
+ from StringIO import StringIO |
|
209 | 230 |
except ImportError: |
210 |
- HAS_F5SDK = False |
|
231 |
+ from io import StringIO |
|
211 | 232 |
|
212 | 233 |
|
213 | 234 |
class Parameters(AnsibleF5Parameters): |
... | ... |
@@ -228,36 +250,6 @@ class Parameters(AnsibleF5Parameters): |
228 | 228 |
'shell', 'partitionAccess', 'description', 'name', 'password' |
229 | 229 |
] |
230 | 230 |
|
231 |
- def __init__(self, params=None): |
|
232 |
- self._values = defaultdict(lambda: None) |
|
233 |
- self._values['__warnings'] = [] |
|
234 |
- if params: |
|
235 |
- self.update(params=params) |
|
236 |
- |
|
237 |
- def update(self, params=None): |
|
238 |
- if params: |
|
239 |
- for k, v in iteritems(params): |
|
240 |
- if self.api_map is not None and k in self.api_map: |
|
241 |
- map_key = self.api_map[k] |
|
242 |
- else: |
|
243 |
- map_key = k |
|
244 |
- |
|
245 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
246 |
- # using a map provided by the module developer |
|
247 |
- class_attr = getattr(type(self), map_key, None) |
|
248 |
- if isinstance(class_attr, property): |
|
249 |
- # There is a mapped value for the api_map key |
|
250 |
- if class_attr.fset is None: |
|
251 |
- # If the mapped value does not have |
|
252 |
- # an associated setter |
|
253 |
- self._values[map_key] = v |
|
254 |
- else: |
|
255 |
- # The mapped value has a setter |
|
256 |
- setattr(self, map_key, v) |
|
257 |
- else: |
|
258 |
- # If the mapped value is not a @property |
|
259 |
- self._values[map_key] = v |
|
260 |
- |
|
261 | 231 |
@property |
262 | 232 |
def partition_access(self): |
263 | 233 |
"""Partition access values will require some transformation. |
... | ... |
@@ -324,18 +316,28 @@ class Parameters(AnsibleF5Parameters): |
324 | 324 |
|
325 | 325 |
|
326 | 326 |
class ModuleManager(object): |
327 |
- def __init__(self, client): |
|
328 |
- self.client = client |
|
327 |
+ def __init__(self, *args, **kwargs): |
|
328 |
+ self.module = kwargs.get('module', None) |
|
329 |
+ self.client = kwargs.get('client', None) |
|
330 |
+ self.kwargs = kwargs |
|
329 | 331 |
|
330 | 332 |
def exec_module(self): |
331 | 333 |
if self.is_root_username_credential(): |
332 |
- manager = RootUserManager(self.client) |
|
334 |
+ manager = self.get_manager('root') |
|
333 | 335 |
elif self.is_version_less_than_13(): |
334 |
- manager = UnparitionedManager(self.client) |
|
336 |
+ manager = self.get_manager('v1') |
|
335 | 337 |
else: |
336 |
- manager = PartitionedManager(self.client) |
|
338 |
+ manager = self.get_manager('v2') |
|
337 | 339 |
return manager.exec_module() |
338 | 340 |
|
341 |
+ def get_manager(self, type): |
|
342 |
+ if type == 'root': |
|
343 |
+ return RootUserManager(**self.kwargs) |
|
344 |
+ elif type == 'v1': |
|
345 |
+ return UnparitionedManager(**self.kwargs) |
|
346 |
+ elif type == 'v2': |
|
347 |
+ return PartitionedManager(**self.kwargs) |
|
348 |
+ |
|
339 | 349 |
def is_version_less_than_13(self): |
340 | 350 |
"""Checks to see if the TMOS version is less than 13 |
341 | 351 |
|
... | ... |
@@ -351,17 +353,18 @@ class ModuleManager(object): |
351 | 351 |
return False |
352 | 352 |
|
353 | 353 |
def is_root_username_credential(self): |
354 |
- user = self.client.module.params.get('username_credential', None) |
|
354 |
+ user = self.module.params.get('username_credential', None) |
|
355 | 355 |
if user == 'root': |
356 | 356 |
return True |
357 | 357 |
return False |
358 | 358 |
|
359 | 359 |
|
360 | 360 |
class BaseManager(object): |
361 |
- def __init__(self, client): |
|
362 |
- self.client = client |
|
361 |
+ def __init__(self, *args, **kwargs): |
|
362 |
+ self.module = kwargs.get('module', None) |
|
363 |
+ self.client = kwargs.get('client', None) |
|
363 | 364 |
self.have = None |
364 |
- self.want = Parameters(self.client.module.params) |
|
365 |
+ self.want = Parameters(params=self.module.params) |
|
365 | 366 |
self.changes = Parameters() |
366 | 367 |
|
367 | 368 |
def exec_module(self): |
... | ... |
@@ -388,7 +391,7 @@ class BaseManager(object): |
388 | 388 |
if getattr(self.want, key) is not None: |
389 | 389 |
changed[key] = getattr(self.want, key) |
390 | 390 |
if changed: |
391 |
- self.changes = Parameters(changed) |
|
391 |
+ self.changes = Parameters(params=changed) |
|
392 | 392 |
|
393 | 393 |
def _update_changed_options(self): |
394 | 394 |
changed = {} |
... | ... |
@@ -411,7 +414,7 @@ class BaseManager(object): |
411 | 411 |
changed[key] = attr1 |
412 | 412 |
|
413 | 413 |
if changed: |
414 |
- self.changes = Parameters(changed) |
|
414 |
+ self.changes = Parameters(params=changed) |
|
415 | 415 |
return True |
416 | 416 |
return False |
417 | 417 |
|
... | ... |
@@ -481,13 +484,13 @@ class BaseManager(object): |
481 | 481 |
self.have = self.read_current_from_device() |
482 | 482 |
if not self.should_update(): |
483 | 483 |
return False |
484 |
- if self.client.check_mode: |
|
484 |
+ if self.module.check_mode: |
|
485 | 485 |
return True |
486 | 486 |
self.update_on_device() |
487 | 487 |
return True |
488 | 488 |
|
489 | 489 |
def remove(self): |
490 |
- if self.client.check_mode: |
|
490 |
+ if self.module.check_mode: |
|
491 | 491 |
return True |
492 | 492 |
self.remove_from_device() |
493 | 493 |
if self.exists(): |
... | ... |
@@ -499,7 +502,7 @@ class BaseManager(object): |
499 | 499 |
if self.want.shell == 'bash': |
500 | 500 |
self.validate_shell_parameter() |
501 | 501 |
self._set_changed_options() |
502 |
- if self.client.check_mode: |
|
502 |
+ if self.module.check_mode: |
|
503 | 503 |
return True |
504 | 504 |
self.create_on_device() |
505 | 505 |
return True |
... | ... |
@@ -518,7 +521,7 @@ class UnparitionedManager(BaseManager): |
518 | 518 |
def read_current_from_device(self): |
519 | 519 |
tmp_res = self.client.api.tm.auth.users.user.load(name=self.want.name) |
520 | 520 |
result = tmp_res.attrs |
521 |
- return Parameters(result) |
|
521 |
+ return Parameters(params=result) |
|
522 | 522 |
|
523 | 523 |
def exists(self): |
524 | 524 |
return self.client.api.tm.auth.users.user.exists(name=self.want.name) |
... | ... |
@@ -570,7 +573,7 @@ class PartitionedManager(BaseManager): |
570 | 570 |
def read_current_from_device(self): |
571 | 571 |
resource = self._read_one_resource_from_collection() |
572 | 572 |
result = resource.attrs |
573 |
- return Parameters(result) |
|
573 |
+ return Parameters(params=result) |
|
574 | 574 |
|
575 | 575 |
def exists(self): |
576 | 576 |
collection = self.client.api.tm.auth.users.get_collection( |
... | ... |
@@ -646,7 +649,7 @@ class RootUserManager(BaseManager): |
646 | 646 |
class ArgumentSpec(object): |
647 | 647 |
def __init__(self): |
648 | 648 |
self.supports_check_mode = True |
649 |
- self.argument_spec = dict( |
|
649 |
+ argument_spec = dict( |
|
650 | 650 |
name=dict( |
651 | 651 |
required=True, |
652 | 652 |
aliases=['username_credential'] |
... | ... |
@@ -664,41 +667,37 @@ class ArgumentSpec(object): |
664 | 664 |
update_password=dict( |
665 | 665 |
default='always', |
666 | 666 |
choices=['always', 'on_create'] |
667 |
+ ), |
|
668 |
+ state=dict(default='present', choices=['absent', 'present']), |
|
669 |
+ partition=dict( |
|
670 |
+ default='Common', |
|
671 |
+ fallback=(env_fallback, ['F5_PARTITION']) |
|
667 | 672 |
) |
668 | 673 |
) |
669 |
- self.f5_product_name = 'bigip' |
|
670 |
- |
|
671 |
- |
|
672 |
-def cleanup_tokens(client): |
|
673 |
- try: |
|
674 |
- resource = client.api.shared.authz.tokens_s.token.load( |
|
675 |
- name=client.api.icrs.token |
|
676 |
- ) |
|
677 |
- resource.delete() |
|
678 |
- except Exception: |
|
679 |
- pass |
|
674 |
+ self.argument_spec = {} |
|
675 |
+ self.argument_spec.update(f5_argument_spec) |
|
676 |
+ self.argument_spec.update(argument_spec) |
|
680 | 677 |
|
681 | 678 |
|
682 | 679 |
def main(): |
683 |
- if not HAS_F5SDK: |
|
684 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
685 |
- |
|
686 | 680 |
spec = ArgumentSpec() |
687 | 681 |
|
688 |
- client = AnsibleF5Client( |
|
682 |
+ module = AnsibleModule( |
|
689 | 683 |
argument_spec=spec.argument_spec, |
690 |
- supports_check_mode=spec.supports_check_mode, |
|
691 |
- f5_product_name=spec.f5_product_name |
|
684 |
+ supports_check_mode=spec.supports_check_mode |
|
692 | 685 |
) |
686 |
+ if not HAS_F5SDK: |
|
687 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
693 | 688 |
|
694 | 689 |
try: |
695 |
- mm = ModuleManager(client) |
|
690 |
+ client = F5Client(**module.params) |
|
691 |
+ mm = ModuleManager(module=module, client=client) |
|
696 | 692 |
results = mm.exec_module() |
697 | 693 |
cleanup_tokens(client) |
698 |
- client.module.exit_json(**results) |
|
699 |
- except F5ModuleError as e: |
|
694 |
+ module.exit_json(**results) |
|
695 |
+ except F5ModuleError as ex: |
|
700 | 696 |
cleanup_tokens(client) |
701 |
- client.module.fail_json(msg=str(e)) |
|
697 |
+ module.fail_json(msg=str(ex)) |
|
702 | 698 |
|
703 | 699 |
|
704 | 700 |
if __name__ == '__main__': |
... | ... |
@@ -112,9 +112,11 @@ options: |
112 | 112 |
- The number you can specify depends on the type of hardware you have. |
113 | 113 |
- In the event of a reboot, the system persists the guest to the same slot on |
114 | 114 |
which it ran prior to the reboot. |
115 |
+ partition: |
|
116 |
+ description: |
|
117 |
+ - Device partition to manage resources on. |
|
118 |
+ default: Common |
|
115 | 119 |
notes: |
116 |
- - Requires the f5-sdk Python package on the host. This is as easy as pip |
|
117 |
- install f5-sdk. |
|
118 | 120 |
- This module can take a lot of time to deploy vCMP guests. This is an intrinsic |
119 | 121 |
limitation of the vCMP system because it is booting real VMs on the BIG-IP |
120 | 122 |
device. This boot time is very similar in length to the time it takes to |
... | ... |
@@ -123,8 +125,6 @@ notes: |
123 | 123 |
means that it is not unusual for a vCMP host with many guests to take a |
124 | 124 |
long time (60+ minutes) to reboot and bring all the guests online. The |
125 | 125 |
BIG-IP chassis will be available before all vCMP guests are online. |
126 |
-requirements: |
|
127 |
- - f5-sdk >= 3.0.3 |
|
128 | 126 |
- netaddr |
129 | 127 |
extends_documentation_fragment: f5 |
130 | 128 |
author: |
... | ... |
@@ -173,16 +173,41 @@ vlans: |
173 | 173 |
sample: ['/Common/vlan1', '/Common/vlan2'] |
174 | 174 |
''' |
175 | 175 |
|
176 |
+import time |
|
176 | 177 |
|
177 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
178 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
179 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
180 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
181 |
-from ansible.module_utils.six import iteritems |
|
182 |
-from collections import defaultdict |
|
178 |
+from ansible.module_utils.basic import AnsibleModule |
|
179 |
+from ansible.module_utils.basic import env_fallback |
|
183 | 180 |
from collections import namedtuple |
184 | 181 |
|
185 |
-import time |
|
182 |
+HAS_DEVEL_IMPORTS = False |
|
183 |
+ |
|
184 |
+try: |
|
185 |
+ # Sideband repository used for dev |
|
186 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
187 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
188 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
189 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
190 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
191 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
192 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
193 |
+ try: |
|
194 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
195 |
+ except ImportError: |
|
196 |
+ HAS_F5SDK = False |
|
197 |
+ HAS_DEVEL_IMPORTS = True |
|
198 |
+except ImportError: |
|
199 |
+ # Upstream Ansible |
|
200 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
201 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
202 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
203 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
204 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
205 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
206 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
207 |
+ try: |
|
208 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
209 |
+ except ImportError: |
|
210 |
+ HAS_F5SDK = False |
|
186 | 211 |
|
187 | 212 |
try: |
188 | 213 |
from netaddr import IPAddress, AddrFormatError, IPNetwork |
... | ... |
@@ -192,7 +217,6 @@ except ImportError: |
192 | 192 |
|
193 | 193 |
try: |
194 | 194 |
from f5.utils.responses.handlers import Stats |
195 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
196 | 195 |
except ImportError: |
197 | 196 |
HAS_F5SDK = False |
198 | 197 |
|
... | ... |
@@ -222,37 +246,6 @@ class Parameters(AnsibleF5Parameters): |
222 | 222 |
'state' |
223 | 223 |
] |
224 | 224 |
|
225 |
- def __init__(self, params=None, client=None): |
|
226 |
- self._values = defaultdict(lambda: None) |
|
227 |
- self._values['__warnings'] = [] |
|
228 |
- if params: |
|
229 |
- self.update(params=params) |
|
230 |
- self.client = client |
|
231 |
- |
|
232 |
- def update(self, params=None): |
|
233 |
- if params: |
|
234 |
- for k, v in iteritems(params): |
|
235 |
- if self.api_map is not None and k in self.api_map: |
|
236 |
- map_key = self.api_map[k] |
|
237 |
- else: |
|
238 |
- map_key = k |
|
239 |
- |
|
240 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
241 |
- # using a map provided by the module developer |
|
242 |
- class_attr = getattr(type(self), map_key, None) |
|
243 |
- if isinstance(class_attr, property): |
|
244 |
- # There is a mapped value for the api_map key |
|
245 |
- if class_attr.fset is None: |
|
246 |
- # If the mapped value does not have |
|
247 |
- # an associated setter |
|
248 |
- self._values[map_key] = v |
|
249 |
- else: |
|
250 |
- # The mapped value has a setter |
|
251 |
- setattr(self, map_key, v) |
|
252 |
- else: |
|
253 |
- # If the mapped value is not a @property |
|
254 |
- self._values[map_key] = v |
|
255 |
- |
|
256 | 225 |
def _fqdn_name(self, value): |
257 | 226 |
if value is not None and not value.startswith('/'): |
258 | 227 |
return '/{0}/{1}'.format(self.partition, value) |
... | ... |
@@ -268,16 +261,6 @@ class Parameters(AnsibleF5Parameters): |
268 | 268 |
pass |
269 | 269 |
return result |
270 | 270 |
|
271 |
- def api_params(self): |
|
272 |
- result = {} |
|
273 |
- for api_attribute in self.api_attributes: |
|
274 |
- if self.api_map is not None and api_attribute in self.api_map: |
|
275 |
- result[api_attribute] = getattr(self, self.api_map[api_attribute]) |
|
276 |
- else: |
|
277 |
- result[api_attribute] = getattr(self, api_attribute) |
|
278 |
- result = self._filter_params(result) |
|
279 |
- return result |
|
280 |
- |
|
281 | 271 |
@property |
282 | 272 |
def mgmt_route(self): |
283 | 273 |
if self._values['mgmt_route'] is None: |
... | ... |
@@ -394,9 +377,10 @@ class Difference(object): |
394 | 394 |
|
395 | 395 |
|
396 | 396 |
class ModuleManager(object): |
397 |
- def __init__(self, client): |
|
398 |
- self.client = client |
|
399 |
- self.want = Parameters(client=client, params=self.client.module.params) |
|
397 |
+ def __init__(self, *args, **kwargs): |
|
398 |
+ self.module = kwargs.get('module', None) |
|
399 |
+ self.client = kwargs.get('client', None) |
|
400 |
+ self.want = Parameters(client=self.client, params=self.module.params) |
|
400 | 401 |
self.changes = Changes() |
401 | 402 |
|
402 | 403 |
def _set_changed_options(self): |
... | ... |
@@ -405,7 +389,7 @@ class ModuleManager(object): |
405 | 405 |
if getattr(self.want, key) is not None: |
406 | 406 |
changed[key] = getattr(self.want, key) |
407 | 407 |
if changed: |
408 |
- self.changes = Changes(changed) |
|
408 |
+ self.changes = Changes(params=changed) |
|
409 | 409 |
|
410 | 410 |
def _update_changed_options(self): |
411 | 411 |
diff = Difference(self.want, self.have) |
... | ... |
@@ -418,7 +402,7 @@ class ModuleManager(object): |
418 | 418 |
else: |
419 | 419 |
changed[k] = change |
420 | 420 |
if changed: |
421 |
- self.changes = Parameters(changed) |
|
421 |
+ self.changes = Parameters(params=changed) |
|
422 | 422 |
return True |
423 | 423 |
return False |
424 | 424 |
|
... | ... |
@@ -450,7 +434,7 @@ class ModuleManager(object): |
450 | 450 |
def _announce_deprecations(self, result): |
451 | 451 |
warnings = result.pop('__warnings', []) |
452 | 452 |
for warning in warnings: |
453 |
- self.client.module.deprecate( |
|
453 |
+ self.module.deprecate( |
|
454 | 454 |
msg=warning['msg'], |
455 | 455 |
version=warning['version'] |
456 | 456 |
) |
... | ... |
@@ -476,7 +460,7 @@ class ModuleManager(object): |
476 | 476 |
self.have = self.read_current_from_device() |
477 | 477 |
if not self.should_update(): |
478 | 478 |
return False |
479 |
- if self.client.check_mode: |
|
479 |
+ if self.module.check_mode: |
|
480 | 480 |
return True |
481 | 481 |
self.update_on_device() |
482 | 482 |
if self.want.state == 'provisioned': |
... | ... |
@@ -488,7 +472,7 @@ class ModuleManager(object): |
488 | 488 |
return True |
489 | 489 |
|
490 | 490 |
def remove(self): |
491 |
- if self.client.check_mode: |
|
491 |
+ if self.module.check_mode: |
|
492 | 492 |
return True |
493 | 493 |
if self.want.delete_virtual_disk: |
494 | 494 |
self.have = self.read_current_from_device() |
... | ... |
@@ -501,7 +485,7 @@ class ModuleManager(object): |
501 | 501 |
|
502 | 502 |
def create(self): |
503 | 503 |
self._set_changed_options() |
504 |
- if self.client.check_mode: |
|
504 |
+ if self.module.check_mode: |
|
505 | 505 |
return True |
506 | 506 |
if self.want.mgmt_tuple.subnet is None: |
507 | 507 |
self.want.update(dict( |
... | ... |
@@ -547,7 +531,7 @@ class ModuleManager(object): |
547 | 547 |
name=self.want.name |
548 | 548 |
) |
549 | 549 |
result = resource.attrs |
550 |
- return Parameters(result) |
|
550 |
+ return Parameters(params=result) |
|
551 | 551 |
|
552 | 552 |
def remove_virtual_disk(self): |
553 | 553 |
if self.virtual_disk_exists(): |
... | ... |
@@ -666,7 +650,7 @@ class ModuleManager(object): |
666 | 666 |
class ArgumentSpec(object): |
667 | 667 |
def __init__(self): |
668 | 668 |
self.supports_check_mode = True |
669 |
- self.argument_spec = dict( |
|
669 |
+ argument_spec = dict( |
|
670 | 670 |
name=dict(required=True), |
671 | 671 |
vlans=dict(type='list'), |
672 | 672 |
mgmt_network=dict(choices=['bridged', 'isolated', 'host only']), |
... | ... |
@@ -680,47 +664,41 @@ class ArgumentSpec(object): |
680 | 680 |
delete_virtual_disk=dict( |
681 | 681 |
type='bool', default='no' |
682 | 682 |
), |
683 |
- cores_per_slot=dict(type='int') |
|
683 |
+ cores_per_slot=dict(type='int'), |
|
684 |
+ partition=dict( |
|
685 |
+ default='Common', |
|
686 |
+ fallback=(env_fallback, ['F5_PARTITION']) |
|
687 |
+ ) |
|
684 | 688 |
) |
685 |
- self.f5_product_name = 'bigip' |
|
689 |
+ self.argument_spec = {} |
|
690 |
+ self.argument_spec.update(f5_argument_spec) |
|
691 |
+ self.argument_spec.update(argument_spec) |
|
686 | 692 |
self.required_if = [ |
687 | 693 |
['mgmt_network', 'bridged', ['mgmt_address']] |
688 | 694 |
] |
689 | 695 |
|
690 | 696 |
|
691 |
-def cleanup_tokens(client): |
|
692 |
- try: |
|
693 |
- resource = client.api.shared.authz.tokens_s.token.load( |
|
694 |
- name=client.api.icrs.token |
|
695 |
- ) |
|
696 |
- resource.delete() |
|
697 |
- except Exception: |
|
698 |
- pass |
|
699 |
- |
|
700 |
- |
|
701 | 697 |
def main(): |
702 |
- if not HAS_F5SDK: |
|
703 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
704 |
- |
|
705 |
- if not HAS_NETADDR: |
|
706 |
- raise F5ModuleError("The python netaddr module is required") |
|
707 |
- |
|
708 | 698 |
spec = ArgumentSpec() |
709 | 699 |
|
710 |
- client = AnsibleF5Client( |
|
700 |
+ module = AnsibleModule( |
|
711 | 701 |
argument_spec=spec.argument_spec, |
712 |
- supports_check_mode=spec.supports_check_mode, |
|
713 |
- f5_product_name=spec.f5_product_name |
|
702 |
+ supports_check_mode=spec.supports_check_mode |
|
714 | 703 |
) |
704 |
+ if not HAS_F5SDK: |
|
705 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
706 |
+ if not HAS_NETADDR: |
|
707 |
+ module.fail_json(msg="The python netaddr module is required") |
|
715 | 708 |
|
716 | 709 |
try: |
717 |
- mm = ModuleManager(client) |
|
710 |
+ client = F5Client(**module.params) |
|
711 |
+ mm = ModuleManager(module=module, client=client) |
|
718 | 712 |
results = mm.exec_module() |
719 | 713 |
cleanup_tokens(client) |
720 |
- client.module.exit_json(**results) |
|
721 |
- except F5ModuleError as e: |
|
714 |
+ module.exit_json(**results) |
|
715 |
+ except F5ModuleError as ex: |
|
722 | 716 |
cleanup_tokens(client) |
723 |
- client.module.fail_json(msg=str(e)) |
|
717 |
+ module.fail_json(msg=str(ex)) |
|
724 | 718 |
|
725 | 719 |
|
726 | 720 |
if __name__ == '__main__': |
... | ... |
@@ -100,14 +100,11 @@ options: |
100 | 100 |
- Specifies whether the system uses route advertisement for this |
101 | 101 |
virtual address. When disabled, the system does not advertise |
102 | 102 |
routes for this virtual address. |
103 |
- choices: |
|
104 |
- - yes |
|
105 |
- - no |
|
103 |
+ type: bool |
|
106 | 104 |
partition: |
107 | 105 |
description: |
108 | 106 |
- Device partition to manage resources on. |
109 |
- required: False |
|
110 |
- default: 'Common' |
|
107 |
+ default: Common |
|
111 | 108 |
version_added: 2.5 |
112 | 109 |
traffic_group: |
113 | 110 |
description: |
... | ... |
@@ -116,13 +113,10 @@ options: |
116 | 116 |
will be used. |
117 | 117 |
version_added: 2.5 |
118 | 118 |
notes: |
119 |
- - Requires the f5-sdk Python package on the host. This is as easy as pip |
|
120 |
- install f5-sdk. |
|
121 | 119 |
- Requires the netaddr Python package on the host. This is as easy as pip |
122 | 120 |
install netaddr. |
123 | 121 |
extends_documentation_fragment: f5 |
124 | 122 |
requirements: |
125 |
- - f5-sdk |
|
126 | 123 |
- netaddr |
127 | 124 |
author: |
128 | 125 |
- Tim Rupp (@caphrim007) |
... | ... |
@@ -193,23 +187,46 @@ state: |
193 | 193 |
sample: disabled |
194 | 194 |
''' |
195 | 195 |
|
196 |
-try: |
|
197 |
- import netaddr |
|
198 |
- HAS_NETADDR = True |
|
199 |
-except ImportError: |
|
200 |
- HAS_NETADDR = False |
|
201 |
- |
|
202 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
203 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
204 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
205 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
196 |
+from ansible.module_utils.basic import AnsibleModule |
|
197 |
+from ansible.module_utils.basic import env_fallback |
|
206 | 198 |
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE |
207 | 199 |
from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE |
208 | 200 |
|
201 |
+HAS_DEVEL_IMPORTS = False |
|
202 |
+ |
|
209 | 203 |
try: |
210 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
204 |
+ # Sideband repository used for dev |
|
205 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
206 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
207 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
208 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
209 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
210 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
211 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
212 |
+ try: |
|
213 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
214 |
+ except ImportError: |
|
215 |
+ HAS_F5SDK = False |
|
216 |
+ HAS_DEVEL_IMPORTS = True |
|
211 | 217 |
except ImportError: |
212 |
- HAS_F5SDK = False |
|
218 |
+ # Upstream Ansible |
|
219 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
220 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
221 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
222 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
223 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
224 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
225 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
226 |
+ try: |
|
227 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
228 |
+ except ImportError: |
|
229 |
+ HAS_F5SDK = False |
|
230 |
+ |
|
231 |
+try: |
|
232 |
+ import netaddr |
|
233 |
+ HAS_NETADDR = True |
|
234 |
+except ImportError: |
|
235 |
+ HAS_NETADDR = False |
|
213 | 236 |
|
214 | 237 |
|
215 | 238 |
class Parameters(AnsibleF5Parameters): |
... | ... |
@@ -349,17 +366,6 @@ class Parameters(AnsibleF5Parameters): |
349 | 349 |
result = self._filter_params(result) |
350 | 350 |
return result |
351 | 351 |
|
352 |
- def api_params(self): |
|
353 |
- result = {} |
|
354 |
- for api_attribute in self.api_attributes: |
|
355 |
- if api_attribute in self.api_map: |
|
356 |
- result[api_attribute] = getattr( |
|
357 |
- self, self.api_map[api_attribute]) |
|
358 |
- else: |
|
359 |
- result[api_attribute] = getattr(self, api_attribute) |
|
360 |
- result = self._filter_params(result) |
|
361 |
- return result |
|
362 |
- |
|
363 | 352 |
|
364 | 353 |
class Changes(Parameters): |
365 | 354 |
pass |
... | ... |
@@ -393,10 +399,11 @@ class Difference(object): |
393 | 393 |
|
394 | 394 |
|
395 | 395 |
class ModuleManager(object): |
396 |
- def __init__(self, client): |
|
397 |
- self.client = client |
|
396 |
+ def __init__(self, *args, **kwargs): |
|
397 |
+ self.module = kwargs.get('module', None) |
|
398 |
+ self.client = kwargs.get('client', None) |
|
398 | 399 |
self.have = None |
399 |
- self.want = Parameters(self.client.module.params) |
|
400 |
+ self.want = Parameters(client=self.client, params=self.module.params) |
|
400 | 401 |
self.changes = Changes() |
401 | 402 |
|
402 | 403 |
def _set_changed_options(self): |
... | ... |
@@ -405,7 +412,7 @@ class ModuleManager(object): |
405 | 405 |
if getattr(self.want, key) is not None: |
406 | 406 |
changed[key] = getattr(self.want, key) |
407 | 407 |
if changed: |
408 |
- self.changes = Changes(changed) |
|
408 |
+ self.changes = Changes(params=changed) |
|
409 | 409 |
|
410 | 410 |
def _update_changed_options(self): |
411 | 411 |
diff = Difference(self.want, self.have) |
... | ... |
@@ -421,7 +428,7 @@ class ModuleManager(object): |
421 | 421 |
else: |
422 | 422 |
changed[k] = change |
423 | 423 |
if changed: |
424 |
- self.changes = Changes(changed) |
|
424 |
+ self.changes = Changes(params=changed) |
|
425 | 425 |
return True |
426 | 426 |
return False |
427 | 427 |
|
... | ... |
@@ -467,7 +474,7 @@ class ModuleManager(object): |
467 | 467 |
partition=self.want.partition |
468 | 468 |
) |
469 | 469 |
result = resource.attrs |
470 |
- return Parameters(result) |
|
470 |
+ return Parameters(params=result) |
|
471 | 471 |
|
472 | 472 |
def exists(self): |
473 | 473 |
result = self.client.api.tm.ltm.virtual_address_s.virtual_address.exists( |
... | ... |
@@ -481,18 +488,18 @@ class ModuleManager(object): |
481 | 481 |
if self.want.netmask is not None: |
482 | 482 |
if self.have.netmask != self.want.netmask: |
483 | 483 |
raise F5ModuleError( |
484 |
- "The netmask cannot be changed. Delete and recreate" |
|
484 |
+ "The netmask cannot be changed. Delete and recreate " |
|
485 | 485 |
"the virtual address if you need to do this." |
486 | 486 |
) |
487 | 487 |
if self.want.address is not None: |
488 | 488 |
if self.have.address != self.want.address: |
489 | 489 |
raise F5ModuleError( |
490 |
- "The address cannot be changed. Delete and recreate" |
|
490 |
+ "The address cannot be changed. Delete and recreate " |
|
491 | 491 |
"the virtual address if you need to do this." |
492 | 492 |
) |
493 | 493 |
if not self.should_update(): |
494 | 494 |
return False |
495 |
- if self.client.check_mode: |
|
495 |
+ if self.module.check_mode: |
|
496 | 496 |
return True |
497 | 497 |
self.update_on_device() |
498 | 498 |
return True |
... | ... |
@@ -509,7 +516,7 @@ class ModuleManager(object): |
509 | 509 |
self._set_changed_options() |
510 | 510 |
if self.want.traffic_group is None: |
511 | 511 |
self.want.update({'traffic_group': '/Common/traffic-group-1'}) |
512 |
- if self.client.check_mode: |
|
512 |
+ if self.module.check_mode: |
|
513 | 513 |
return True |
514 | 514 |
self.create_on_device() |
515 | 515 |
if self.exists(): |
... | ... |
@@ -527,7 +534,7 @@ class ModuleManager(object): |
527 | 527 |
) |
528 | 528 |
|
529 | 529 |
def remove(self): |
530 |
- if self.client.check_mode: |
|
530 |
+ if self.module.check_mode: |
|
531 | 531 |
return True |
532 | 532 |
self.remove_from_device() |
533 | 533 |
if self.exists(): |
... | ... |
@@ -545,7 +552,7 @@ class ModuleManager(object): |
545 | 545 |
class ArgumentSpec(object): |
546 | 546 |
def __init__(self): |
547 | 547 |
self.supports_check_mode = True |
548 |
- self.argument_spec = dict( |
|
548 |
+ argument_spec = dict( |
|
549 | 549 |
state=dict( |
550 | 550 |
default='present', |
551 | 551 |
choices=['present', 'absent', 'disabled', 'enabled'] |
... | ... |
@@ -577,29 +584,38 @@ class ArgumentSpec(object): |
577 | 577 |
use_route_advertisement=dict( |
578 | 578 |
type='bool' |
579 | 579 |
), |
580 |
- traffic_group=dict() |
|
580 |
+ traffic_group=dict(), |
|
581 |
+ partition=dict( |
|
582 |
+ default='Common', |
|
583 |
+ fallback=(env_fallback, ['F5_PARTITION']) |
|
584 |
+ ) |
|
581 | 585 |
) |
582 |
- self.f5_product_name = 'bigip' |
|
586 |
+ self.argument_spec = {} |
|
587 |
+ self.argument_spec.update(f5_argument_spec) |
|
588 |
+ self.argument_spec.update(argument_spec) |
|
583 | 589 |
|
584 | 590 |
|
585 | 591 |
def main(): |
586 |
- if not HAS_F5SDK: |
|
587 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
588 |
- |
|
589 | 592 |
spec = ArgumentSpec() |
590 | 593 |
|
591 |
- client = AnsibleF5Client( |
|
594 |
+ module = AnsibleModule( |
|
592 | 595 |
argument_spec=spec.argument_spec, |
593 |
- supports_check_mode=spec.supports_check_mode, |
|
594 |
- f5_product_name=spec.f5_product_name |
|
596 |
+ supports_check_mode=spec.supports_check_mode |
|
595 | 597 |
) |
598 |
+ if not HAS_F5SDK: |
|
599 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
600 |
+ if not HAS_NETADDR: |
|
601 |
+ module.fail_json(msg="The python netaddr module is required") |
|
596 | 602 |
|
597 | 603 |
try: |
598 |
- mm = ModuleManager(client) |
|
604 |
+ client = F5Client(**module.params) |
|
605 |
+ mm = ModuleManager(module=module, client=client) |
|
599 | 606 |
results = mm.exec_module() |
600 |
- client.module.exit_json(**results) |
|
601 |
- except F5ModuleError as e: |
|
602 |
- client.module.fail_json(msg=str(e)) |
|
607 |
+ cleanup_tokens(client) |
|
608 |
+ module.exit_json(**results) |
|
609 |
+ except F5ModuleError as ex: |
|
610 |
+ cleanup_tokens(client) |
|
611 |
+ module.fail_json(msg=str(ex)) |
|
603 | 612 |
|
604 | 613 |
|
605 | 614 |
if __name__ == '__main__': |
... | ... |
@@ -137,14 +137,6 @@ options: |
137 | 137 |
- Default Profile which manages the session persistence. |
138 | 138 |
- If you want to remove the existing default persistence profile, specify an |
139 | 139 |
empty value; C(""). See the documentation for an example. |
140 |
- route_advertisement_state: |
|
141 |
- description: |
|
142 |
- - Enable route advertisement for destination. |
|
143 |
- - Deprecated in 2.4. Use the C(bigip_virtual_address) module instead. |
|
144 |
- choices: |
|
145 |
- - enabled |
|
146 |
- - disabled |
|
147 |
- version_added: "2.3" |
|
148 | 140 |
description: |
149 | 141 |
description: |
150 | 142 |
- Virtual server description. |
... | ... |
@@ -171,12 +163,9 @@ options: |
171 | 171 |
version_added: 2.5 |
172 | 172 |
notes: |
173 | 173 |
- Requires BIG-IP software version >= 11 |
174 |
- - Requires the f5-sdk Python package on the host. This is as easy as pip |
|
175 |
- install f5-sdk. |
|
176 | 174 |
- Requires the netaddr Python package on the host. This is as easy as pip |
177 | 175 |
install netaddr. |
178 | 176 |
requirements: |
179 |
- - f5-sdk |
|
180 | 177 |
- netaddr |
181 | 178 |
extends_documentation_fragment: f5 |
182 | 179 |
author: |
... | ... |
@@ -381,18 +370,38 @@ metadata: |
381 | 381 |
|
382 | 382 |
import re |
383 | 383 |
|
384 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
385 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
386 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
387 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
384 |
+from ansible.module_utils.basic import AnsibleModule |
|
385 |
+from ansible.module_utils.basic import env_fallback |
|
388 | 386 |
from ansible.module_utils.six import iteritems |
389 |
-from collections import defaultdict |
|
390 | 387 |
from collections import namedtuple |
391 | 388 |
|
392 | 389 |
try: |
393 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
390 |
+ # Sideband repository used for dev |
|
391 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
392 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
393 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
394 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
395 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
396 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
397 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
398 |
+ try: |
|
399 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
400 |
+ except ImportError: |
|
401 |
+ HAS_F5SDK = False |
|
402 |
+ HAS_DEVEL_IMPORTS = True |
|
394 | 403 |
except ImportError: |
395 |
- HAS_F5SDK = False |
|
404 |
+ # Upstream Ansible |
|
405 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
406 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
407 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
408 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
409 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
410 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
411 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
412 |
+ try: |
|
413 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
414 |
+ except ImportError: |
|
415 |
+ HAS_F5SDK = False |
|
396 | 416 |
|
397 | 417 |
try: |
398 | 418 |
import netaddr |
... | ... |
@@ -402,100 +411,6 @@ except ImportError: |
402 | 402 |
|
403 | 403 |
|
404 | 404 |
class Parameters(AnsibleF5Parameters): |
405 |
- def __init__(self, params=None): |
|
406 |
- self._values = defaultdict(lambda: None) |
|
407 |
- if params: |
|
408 |
- self.update(params=params) |
|
409 |
- |
|
410 |
- def update(self, params=None): |
|
411 |
- if params: |
|
412 |
- for k, v in iteritems(params): |
|
413 |
- if self.api_map is not None and k in self.api_map: |
|
414 |
- map_key = self.api_map[k] |
|
415 |
- else: |
|
416 |
- map_key = k |
|
417 |
- |
|
418 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
419 |
- # using a map provided by the module developer |
|
420 |
- class_attr = getattr(type(self), map_key, None) |
|
421 |
- if isinstance(class_attr, property): |
|
422 |
- # There is a mapped value for the api_map key |
|
423 |
- if class_attr.fset is None: |
|
424 |
- # If the mapped value does not have |
|
425 |
- # an associated setter |
|
426 |
- self._values[map_key] = v |
|
427 |
- else: |
|
428 |
- # The mapped value has a setter |
|
429 |
- setattr(self, map_key, v) |
|
430 |
- else: |
|
431 |
- # If the mapped value is not a @property |
|
432 |
- self._values[map_key] = v |
|
433 |
- |
|
434 |
- def to_return(self): |
|
435 |
- result = {} |
|
436 |
- for returnable in self.returnables: |
|
437 |
- try: |
|
438 |
- result[returnable] = getattr(self, returnable) |
|
439 |
- except Exception as ex: |
|
440 |
- pass |
|
441 |
- result = self._filter_params(result) |
|
442 |
- return result |
|
443 |
- |
|
444 |
- def _fqdn_name(self, value): |
|
445 |
- if value is not None and not value.startswith('/'): |
|
446 |
- return '/{0}/{1}'.format(self.partition, value) |
|
447 |
- return value |
|
448 |
- |
|
449 |
- def api_params(self): |
|
450 |
- result = {} |
|
451 |
- for api_attribute in self.api_attributes: |
|
452 |
- if self.api_map is not None and api_attribute in self.api_map: |
|
453 |
- result[api_attribute] = getattr(self, self.api_map[api_attribute]) |
|
454 |
- else: |
|
455 |
- result[api_attribute] = getattr(self, api_attribute) |
|
456 |
- result = self._filter_params(result) |
|
457 |
- return result |
|
458 |
- |
|
459 |
- |
|
460 |
-class VirtualAddressParameters(Parameters): |
|
461 |
- api_map = { |
|
462 |
- 'routeAdvertisement': 'route_advertisement_state' |
|
463 |
- } |
|
464 |
- returnables = [ |
|
465 |
- 'route_advertisement_state' |
|
466 |
- ] |
|
467 |
- |
|
468 |
- updatables = [ |
|
469 |
- 'route_advertisement_state' |
|
470 |
- ] |
|
471 |
- |
|
472 |
- api_attributes = [ |
|
473 |
- 'routeAdvertisement' |
|
474 |
- ] |
|
475 |
- |
|
476 |
- |
|
477 |
-class VirtualAddressModuleParameters(VirtualAddressParameters): |
|
478 |
- @property |
|
479 |
- def route_advertisement_state(self): |
|
480 |
- # TODO: Remove in 2.5 |
|
481 |
- if self._values['route_advertisement_state'] is None: |
|
482 |
- return None |
|
483 |
- if self._values['__warnings'] is None: |
|
484 |
- self._values['__warnings'] = [] |
|
485 |
- self._values['__warnings'].append( |
|
486 |
- dict( |
|
487 |
- msg="Usage of the 'route_advertisement_state' parameter is deprecated. Use the bigip_virtual_address module instead", |
|
488 |
- version='2.4' |
|
489 |
- ) |
|
490 |
- ) |
|
491 |
- return str(self._values['route_advertisement_state']) |
|
492 |
- |
|
493 |
- |
|
494 |
-class VirtualAddressApiParameters(VirtualAddressParameters): |
|
495 |
- pass |
|
496 |
- |
|
497 |
- |
|
498 |
-class VirtualServerParameters(Parameters): |
|
499 | 405 |
api_map = { |
500 | 406 |
'sourceAddressTranslation': 'snat', |
501 | 407 |
'fallbackPersistence': 'fallback_persistence_profile', |
... | ... |
@@ -566,12 +481,25 @@ class VirtualServerParameters(Parameters): |
566 | 566 |
'vlans_disabled' |
567 | 567 |
] |
568 | 568 |
|
569 |
- def __init__(self, params=None): |
|
570 |
- super(VirtualServerParameters, self).__init__(params) |
|
571 |
- self.profiles_mutex = [ |
|
572 |
- 'sip', 'sipsession', 'iiop', 'rtsp', 'http', 'diameter', |
|
573 |
- 'diametersession', 'radius', 'ftp', 'tftp', 'dns', 'pptp', 'fix' |
|
574 |
- ] |
|
569 |
+ profiles_mutex = [ |
|
570 |
+ 'sip', 'sipsession', 'iiop', 'rtsp', 'http', 'diameter', |
|
571 |
+ 'diametersession', 'radius', 'ftp', 'tftp', 'dns', 'pptp', 'fix' |
|
572 |
+ ] |
|
573 |
+ |
|
574 |
+ def to_return(self): |
|
575 |
+ result = {} |
|
576 |
+ for returnable in self.returnables: |
|
577 |
+ try: |
|
578 |
+ result[returnable] = getattr(self, returnable) |
|
579 |
+ except Exception as ex: |
|
580 |
+ pass |
|
581 |
+ result = self._filter_params(result) |
|
582 |
+ return result |
|
583 |
+ |
|
584 |
+ def _fqdn_name(self, value): |
|
585 |
+ if value is not None and not value.startswith('/'): |
|
586 |
+ return '/{0}/{1}'.format(self.partition, value) |
|
587 |
+ return value |
|
575 | 588 |
|
576 | 589 |
def is_valid_ip(self, value): |
577 | 590 |
try: |
... | ... |
@@ -618,7 +546,7 @@ class VirtualServerParameters(Parameters): |
618 | 618 |
return result |
619 | 619 |
|
620 | 620 |
|
621 |
-class VirtualServerApiParameters(VirtualServerParameters): |
|
621 |
+class ApiParameters(Parameters): |
|
622 | 622 |
@property |
623 | 623 |
def destination(self): |
624 | 624 |
if self._values['destination'] is None: |
... | ... |
@@ -648,7 +576,7 @@ class VirtualServerApiParameters(VirtualServerParameters): |
648 | 648 |
if self._values['destination'] is None: |
649 | 649 |
result = Destination(ip=None, port=None, route_domain=None) |
650 | 650 |
return result |
651 |
- destination = re.sub(r'^/[a-zA-Z_.-]+/', '', self._values['destination']) |
|
651 |
+ destination = re.sub(r'^/[a-zA-Z0-9_.-]+/', '', self._values['destination']) |
|
652 | 652 |
|
653 | 653 |
if self.is_valid_ip(destination): |
654 | 654 |
result = Destination( |
... | ... |
@@ -816,7 +744,7 @@ class VirtualServerApiParameters(VirtualServerParameters): |
816 | 816 |
return result |
817 | 817 |
|
818 | 818 |
|
819 |
-class VirtualServerModuleParameters(VirtualServerParameters): |
|
819 |
+class ModuleParameters(Parameters): |
|
820 | 820 |
def _handle_profile_context(self, tmp): |
821 | 821 |
if 'context' not in tmp: |
822 | 822 |
tmp['context'] = 'all' |
... | ... |
@@ -1106,7 +1034,11 @@ class VirtualServerModuleParameters(VirtualServerParameters): |
1106 | 1106 |
return result |
1107 | 1107 |
|
1108 | 1108 |
|
1109 |
-class VirtualServerUsableChanges(VirtualServerParameters): |
|
1109 |
+class Changes(Parameters): |
|
1110 |
+ pass |
|
1111 |
+ |
|
1112 |
+ |
|
1113 |
+class UsableChanges(Changes): |
|
1110 | 1114 |
@property |
1111 | 1115 |
def vlans(self): |
1112 | 1116 |
if self._values['vlans'] is None: |
... | ... |
@@ -1118,11 +1050,7 @@ class VirtualServerUsableChanges(VirtualServerParameters): |
1118 | 1118 |
return self._values['vlans'] |
1119 | 1119 |
|
1120 | 1120 |
|
1121 |
-class VirtualAddressUsableChanges(VirtualAddressParameters): |
|
1122 |
- pass |
|
1123 |
- |
|
1124 |
- |
|
1125 |
-class VirtualServerReportableChanges(VirtualServerParameters): |
|
1121 |
+class ReportableChanges(Changes): |
|
1126 | 1122 |
@property |
1127 | 1123 |
def snat(self): |
1128 | 1124 |
if self._values['snat'] is None: |
... | ... |
@@ -1137,13 +1065,13 @@ class VirtualServerReportableChanges(VirtualServerParameters): |
1137 | 1137 |
|
1138 | 1138 |
@property |
1139 | 1139 |
def destination(self): |
1140 |
- params = VirtualServerApiParameters(dict(destination=self._values['destination'])) |
|
1140 |
+ params = ApiParameters(params=dict(destination=self._values['destination'])) |
|
1141 | 1141 |
result = params.destination_tuple.ip |
1142 | 1142 |
return result |
1143 | 1143 |
|
1144 | 1144 |
@property |
1145 | 1145 |
def port(self): |
1146 |
- params = VirtualServerApiParameters(dict(destination=self._values['destination'])) |
|
1146 |
+ params = ApiParameters(params=dict(destination=self._values['destination'])) |
|
1147 | 1147 |
result = params.destination_tuple.port |
1148 | 1148 |
return result |
1149 | 1149 |
|
... | ... |
@@ -1175,10 +1103,6 @@ class VirtualServerReportableChanges(VirtualServerParameters): |
1175 | 1175 |
return self._values['vlans'] |
1176 | 1176 |
|
1177 | 1177 |
|
1178 |
-class VirtualAddressReportableChanges(VirtualAddressParameters): |
|
1179 |
- pass |
|
1180 |
- |
|
1181 |
- |
|
1182 | 1178 |
class Difference(object): |
1183 | 1179 |
def __init__(self, want, have=None): |
1184 | 1180 |
self.have = have |
... | ... |
@@ -1461,49 +1385,12 @@ class Difference(object): |
1461 | 1461 |
|
1462 | 1462 |
|
1463 | 1463 |
class ModuleManager(object): |
1464 |
- def __init__(self, client): |
|
1465 |
- self.client = client |
|
1466 |
- |
|
1467 |
- def exec_module(self): |
|
1468 |
- managers = list() |
|
1469 |
- managers.append(self.get_manager('virtual_server')) |
|
1470 |
- if self.client.module.params['route_advertisement_state'] is not None: |
|
1471 |
- managers.append(self.get_manager('virtual_address')) |
|
1472 |
- result = self.execute_managers(managers) |
|
1473 |
- return result |
|
1474 |
- |
|
1475 |
- def execute_managers(self, managers): |
|
1476 |
- results = dict(changed=False) |
|
1477 |
- for manager in managers: |
|
1478 |
- result = manager.exec_module() |
|
1479 |
- for k, v in iteritems(result): |
|
1480 |
- if k == 'changed': |
|
1481 |
- if v is True: |
|
1482 |
- results['changed'] = True |
|
1483 |
- else: |
|
1484 |
- results[k] = v |
|
1485 |
- return results |
|
1486 |
- |
|
1487 |
- def get_manager(self, type): |
|
1488 |
- vsm = VirtualServerManager(self.client) |
|
1489 |
- if type == 'virtual_server': |
|
1490 |
- return vsm |
|
1491 |
- elif type == 'virtual_address': |
|
1492 |
- self.set_name_of_virtual_address() |
|
1493 |
- result = VirtualAddressManager(self.client) |
|
1494 |
- return result |
|
1495 |
- |
|
1496 |
- def set_name_of_virtual_address(self): |
|
1497 |
- mgr = VirtualServerManager(self.client) |
|
1498 |
- params = mgr.read_current_from_device() |
|
1499 |
- destination = params.destination_tuple |
|
1500 |
- self.client.module.params['name'] = destination.ip |
|
1501 |
- |
|
1502 |
- |
|
1503 |
-class BaseManager(object): |
|
1504 |
- def __init__(self, client): |
|
1505 |
- self.client = client |
|
1506 |
- self.have = None |
|
1464 |
+ def __init__(self, *args, **kwargs): |
|
1465 |
+ self.module = kwargs.get('module', None) |
|
1466 |
+ self.client = kwargs.get('client', None) |
|
1467 |
+ self.have = ApiParameters() |
|
1468 |
+ self.want = ModuleParameters(client=self.client, params=self.module.params) |
|
1469 |
+ self.changes = UsableChanges() |
|
1507 | 1470 |
|
1508 | 1471 |
def exec_module(self): |
1509 | 1472 |
changed = False |
... | ... |
@@ -1518,7 +1405,7 @@ class BaseManager(object): |
1518 | 1518 |
except iControlUnexpectedHTTPError as e: |
1519 | 1519 |
raise F5ModuleError(str(e)) |
1520 | 1520 |
|
1521 |
- reportable = self.get_reportable_changes() |
|
1521 |
+ reportable = ReportableChanges(params=self.changes.to_return()) |
|
1522 | 1522 |
changes = reportable.to_return() |
1523 | 1523 |
result.update(**changes) |
1524 | 1524 |
result.update(dict(changed=changed)) |
... | ... |
@@ -1528,7 +1415,7 @@ class BaseManager(object): |
1528 | 1528 |
def _announce_deprecations(self, result): |
1529 | 1529 |
warnings = result.pop('__warnings', []) |
1530 | 1530 |
for warning in warnings: |
1531 |
- self.client.module.deprecate( |
|
1531 |
+ self.module.deprecate( |
|
1532 | 1532 |
msg=warning['msg'], |
1533 | 1533 |
version=warning['version'] |
1534 | 1534 |
) |
... | ... |
@@ -1548,23 +1435,11 @@ class BaseManager(object): |
1548 | 1548 |
self.have = self.read_current_from_device() |
1549 | 1549 |
if not self.should_update(): |
1550 | 1550 |
return False |
1551 |
- if self.client.check_mode: |
|
1551 |
+ if self.module.check_mode: |
|
1552 | 1552 |
return True |
1553 | 1553 |
self.update_on_device() |
1554 | 1554 |
return True |
1555 | 1555 |
|
1556 |
- def create(self): |
|
1557 |
- if self.client.check_mode: |
|
1558 |
- return True |
|
1559 |
- |
|
1560 |
- # This must be changed back to a list to make a valid REST API |
|
1561 |
- # value. The module manipulates this as a normal dictionary |
|
1562 |
- if self.want.default_persistence_profile is not None: |
|
1563 |
- self.want.update({'default_persistence_profile': [self.want.default_persistence_profile]}) |
|
1564 |
- |
|
1565 |
- self.create_on_device() |
|
1566 |
- return True |
|
1567 |
- |
|
1568 | 1556 |
def should_update(self): |
1569 | 1557 |
result = self._update_changed_options() |
1570 | 1558 |
if result: |
... | ... |
@@ -1572,36 +1447,28 @@ class BaseManager(object): |
1572 | 1572 |
return False |
1573 | 1573 |
|
1574 | 1574 |
def remove(self): |
1575 |
- if self.client.check_mode: |
|
1575 |
+ if self.module.check_mode: |
|
1576 | 1576 |
return True |
1577 | 1577 |
self.remove_from_device() |
1578 | 1578 |
if self.exists(): |
1579 | 1579 |
raise F5ModuleError("Failed to delete the resource") |
1580 | 1580 |
return True |
1581 | 1581 |
|
1582 |
- |
|
1583 |
-class VirtualServerManager(BaseManager): |
|
1584 |
- def __init__(self, client): |
|
1585 |
- super(VirtualServerManager, self).__init__(client) |
|
1586 |
- self.have = None |
|
1587 |
- self.want = VirtualServerModuleParameters(self.client.module.params) |
|
1588 |
- self.changes = VirtualServerUsableChanges() |
|
1589 |
- |
|
1590 | 1582 |
def get_reportable_changes(self): |
1591 |
- result = VirtualServerReportableChanges(self.changes.to_return()) |
|
1583 |
+ result = ReportableChanges(params=self.changes.to_return()) |
|
1592 | 1584 |
return result |
1593 | 1585 |
|
1594 | 1586 |
def _set_changed_options(self): |
1595 | 1587 |
changed = {} |
1596 |
- for key in VirtualServerParameters.returnables: |
|
1588 |
+ for key in Parameters.returnables: |
|
1597 | 1589 |
if getattr(self.want, key) is not None: |
1598 | 1590 |
changed[key] = getattr(self.want, key) |
1599 | 1591 |
if changed: |
1600 |
- self.changes = VirtualServerUsableChanges(changed) |
|
1592 |
+ self.changes = UsableChanges(params=changed) |
|
1601 | 1593 |
|
1602 | 1594 |
def _update_changed_options(self): |
1603 | 1595 |
diff = Difference(self.want, self.have) |
1604 |
- updatables = VirtualServerParameters.updatables |
|
1596 |
+ updatables = Parameters.updatables |
|
1605 | 1597 |
changed = dict() |
1606 | 1598 |
for k in updatables: |
1607 | 1599 |
change = diff.compare(k) |
... | ... |
@@ -1613,7 +1480,7 @@ class VirtualServerManager(BaseManager): |
1613 | 1613 |
else: |
1614 | 1614 |
changed[k] = change |
1615 | 1615 |
if changed: |
1616 |
- self.changes = VirtualServerUsableChanges(changed) |
|
1616 |
+ self.changes = UsableChanges(params=changed) |
|
1617 | 1617 |
return True |
1618 | 1618 |
return False |
1619 | 1619 |
|
... | ... |
@@ -1628,6 +1495,11 @@ class VirtualServerManager(BaseManager): |
1628 | 1628 |
required_resources = ['destination', 'port'] |
1629 | 1629 |
|
1630 | 1630 |
self._set_changed_options() |
1631 |
+ # This must be changed back to a list to make a valid REST API |
|
1632 |
+ # value. The module manipulates this as a normal dictionary |
|
1633 |
+ if self.want.default_persistence_profile is not None: |
|
1634 |
+ self.want.update({'default_persistence_profile': [self.want.default_persistence_profile]}) |
|
1635 |
+ |
|
1631 | 1636 |
if self.want.destination is None: |
1632 | 1637 |
raise F5ModuleError( |
1633 | 1638 |
"'destination' must be specified when creating a virtual server" |
... | ... |
@@ -1652,7 +1524,10 @@ class VirtualServerManager(BaseManager): |
1652 | 1652 |
raise F5ModuleError( |
1653 | 1653 |
"The source and destination addresses for the virtual server must be be the same type (IPv4 or IPv6)." |
1654 | 1654 |
) |
1655 |
- return super(VirtualServerManager, self).create() |
|
1655 |
+ if self.module.check_mode: |
|
1656 |
+ return True |
|
1657 |
+ self.create_on_device() |
|
1658 |
+ return True |
|
1656 | 1659 |
|
1657 | 1660 |
def update_on_device(self): |
1658 | 1661 |
params = self.changes.api_params() |
... | ... |
@@ -1674,7 +1549,7 @@ class VirtualServerManager(BaseManager): |
1674 | 1674 |
) |
1675 | 1675 |
params = result.attrs |
1676 | 1676 |
params.update(dict(kind=result.to_dict().get('kind', None))) |
1677 |
- result = VirtualServerApiParameters(params) |
|
1677 |
+ result = ApiParameters(params=params) |
|
1678 | 1678 |
return result |
1679 | 1679 |
|
1680 | 1680 |
def create_on_device(self): |
... | ... |
@@ -1694,71 +1569,10 @@ class VirtualServerManager(BaseManager): |
1694 | 1694 |
resource.delete() |
1695 | 1695 |
|
1696 | 1696 |
|
1697 |
-class VirtualAddressManager(BaseManager): |
|
1698 |
- def __init__(self, client): |
|
1699 |
- super(VirtualAddressManager, self).__init__(client) |
|
1700 |
- self.want = VirtualAddressModuleParameters(self.client.module.params) |
|
1701 |
- self.have = VirtualAddressApiParameters() |
|
1702 |
- self.changes = VirtualAddressUsableChanges() |
|
1703 |
- |
|
1704 |
- def get_reportable_changes(self): |
|
1705 |
- result = VirtualAddressReportableChanges(self.changes.to_return()) |
|
1706 |
- return result |
|
1707 |
- |
|
1708 |
- def _set_changed_options(self): |
|
1709 |
- changed = {} |
|
1710 |
- for key in VirtualAddressParameters.returnables: |
|
1711 |
- if getattr(self.want, key) is not None: |
|
1712 |
- changed[key] = getattr(self.want, key) |
|
1713 |
- if changed: |
|
1714 |
- self.changes = VirtualAddressUsableChanges(changed) |
|
1715 |
- |
|
1716 |
- def _update_changed_options(self): |
|
1717 |
- diff = Difference(self.want, self.have) |
|
1718 |
- updatables = VirtualAddressParameters.updatables |
|
1719 |
- changed = dict() |
|
1720 |
- for k in updatables: |
|
1721 |
- change = diff.compare(k) |
|
1722 |
- if change is None: |
|
1723 |
- continue |
|
1724 |
- else: |
|
1725 |
- if isinstance(change, dict): |
|
1726 |
- changed.update(change) |
|
1727 |
- else: |
|
1728 |
- changed[k] = change |
|
1729 |
- if changed: |
|
1730 |
- self.changes = VirtualAddressUsableChanges(changed) |
|
1731 |
- return True |
|
1732 |
- return False |
|
1733 |
- |
|
1734 |
- def read_current_from_device(self): |
|
1735 |
- result = self.client.api.tm.ltm.virtual_address_s.virtual_address.load( |
|
1736 |
- name=self.want.name, |
|
1737 |
- partition=self.want.partition |
|
1738 |
- ) |
|
1739 |
- result = VirtualAddressParameters(result.attrs) |
|
1740 |
- return result |
|
1741 |
- |
|
1742 |
- def update_on_device(self): |
|
1743 |
- params = self.want.api_params() |
|
1744 |
- resource = self.client.api.tm.ltm.virtual_address_s.virtual_address.load( |
|
1745 |
- name=self.want.name, |
|
1746 |
- partition=self.want.partition |
|
1747 |
- ) |
|
1748 |
- resource.modify(**params) |
|
1749 |
- |
|
1750 |
- def exists(self): |
|
1751 |
- result = self.client.api.tm.ltm.virtual_address_s.virtual_address.exists( |
|
1752 |
- name=self.want.name, |
|
1753 |
- partition=self.want.partition |
|
1754 |
- ) |
|
1755 |
- return result |
|
1756 |
- |
|
1757 |
- |
|
1758 | 1697 |
class ArgumentSpec(object): |
1759 | 1698 |
def __init__(self): |
1760 | 1699 |
self.supports_check_mode = True |
1761 |
- self.argument_spec = dict( |
|
1700 |
+ argument_spec = dict( |
|
1762 | 1701 |
state=dict( |
1763 | 1702 |
default='present', |
1764 | 1703 |
choices=['present', 'absent', 'disabled', 'enabled'] |
... | ... |
@@ -1798,54 +1612,45 @@ class ArgumentSpec(object): |
1798 | 1798 |
pool=dict(), |
1799 | 1799 |
description=dict(), |
1800 | 1800 |
snat=dict(), |
1801 |
- route_advertisement_state=dict( |
|
1802 |
- choices=['enabled', 'disabled'] |
|
1803 |
- ), |
|
1804 | 1801 |
default_persistence_profile=dict(), |
1805 | 1802 |
fallback_persistence_profile=dict(), |
1806 | 1803 |
source=dict(), |
1807 |
- metadata=dict(type='raw') |
|
1804 |
+ metadata=dict(type='raw'), |
|
1805 |
+ partition=dict( |
|
1806 |
+ default='Common', |
|
1807 |
+ fallback=(env_fallback, ['F5_PARTITION']) |
|
1808 |
+ ) |
|
1808 | 1809 |
) |
1809 |
- self.f5_product_name = 'bigip' |
|
1810 |
+ self.argument_spec = {} |
|
1811 |
+ self.argument_spec.update(f5_argument_spec) |
|
1812 |
+ self.argument_spec.update(argument_spec) |
|
1810 | 1813 |
self.mutually_exclusive = [ |
1811 | 1814 |
['enabled_vlans', 'disabled_vlans'] |
1812 | 1815 |
] |
1813 | 1816 |
|
1814 | 1817 |
|
1815 |
-def cleanup_tokens(client): |
|
1816 |
- try: |
|
1817 |
- resource = client.api.shared.authz.tokens_s.token.load( |
|
1818 |
- name=client.api.icrs.token |
|
1819 |
- ) |
|
1820 |
- resource.delete() |
|
1821 |
- except Exception: |
|
1822 |
- pass |
|
1823 |
- |
|
1824 |
- |
|
1825 | 1818 |
def main(): |
1826 |
- if not HAS_F5SDK: |
|
1827 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
1828 |
- |
|
1829 |
- if not HAS_NETADDR: |
|
1830 |
- raise F5ModuleError("The python netaddr module is required") |
|
1831 |
- |
|
1832 | 1819 |
spec = ArgumentSpec() |
1833 | 1820 |
|
1834 |
- client = AnsibleF5Client( |
|
1821 |
+ module = AnsibleModule( |
|
1835 | 1822 |
argument_spec=spec.argument_spec, |
1836 | 1823 |
supports_check_mode=spec.supports_check_mode, |
1837 |
- f5_product_name=spec.f5_product_name, |
|
1838 | 1824 |
mutually_exclusive=spec.mutually_exclusive |
1839 | 1825 |
) |
1826 |
+ if not HAS_F5SDK: |
|
1827 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
1828 |
+ if not HAS_NETADDR: |
|
1829 |
+ module.fail_json(msg="The python netaddr module is required") |
|
1840 | 1830 |
|
1841 | 1831 |
try: |
1842 |
- mm = ModuleManager(client) |
|
1832 |
+ client = F5Client(**module.params) |
|
1833 |
+ mm = ModuleManager(module=module, client=client) |
|
1843 | 1834 |
results = mm.exec_module() |
1844 | 1835 |
cleanup_tokens(client) |
1845 |
- client.module.exit_json(**results) |
|
1846 |
- except F5ModuleError as e: |
|
1836 |
+ module.exit_json(**results) |
|
1837 |
+ except F5ModuleError as ex: |
|
1847 | 1838 |
cleanup_tokens(client) |
1848 |
- client.module.fail_json(msg=str(e)) |
|
1839 |
+ module.fail_json(msg=str(ex)) |
|
1849 | 1840 |
|
1850 | 1841 |
|
1851 | 1842 |
if __name__ == '__main__': |
... | ... |
@@ -55,13 +55,46 @@ options: |
55 | 55 |
- Tag number for the VLAN. The tag number can be any integer between 1 |
56 | 56 |
and 4094. The system automatically assigns a tag number if you do not |
57 | 57 |
specify a value. |
58 |
+ mtu: |
|
59 |
+ description: |
|
60 |
+ - Specifies the maximum transmission unit (MTU) for traffic on this VLAN. |
|
61 |
+ When creating a new VLAN, if this parameter is not specified, the default |
|
62 |
+ value used will be C(1500). |
|
63 |
+ - This number must be between 576 to 9198. |
|
64 |
+ version_added: 2.5 |
|
65 |
+ cmp_hash: |
|
66 |
+ description: |
|
67 |
+ - Specifies how the traffic on the VLAN will be disaggregated. The value |
|
68 |
+ selected determines the traffic disaggregation method. You can choose to |
|
69 |
+ disaggregate traffic based on C(source-address) (the source IP address), |
|
70 |
+ C(destination-address) (destination IP address), or C(default), which |
|
71 |
+ specifies that the default CMP hash uses L4 ports. |
|
72 |
+ - When creating a new VLAN, if this parameter is not specified, the default |
|
73 |
+ of C(default) is used. |
|
74 |
+ version_added: 2.5 |
|
75 |
+ dag_tunnel: |
|
76 |
+ description: |
|
77 |
+ - Specifies how the disaggregator (DAG) distributes received tunnel-encapsulated |
|
78 |
+ packets to TMM instances. Select C(inner) to distribute packets based on information |
|
79 |
+ in inner headers. Select C(outer) to distribute packets based on information in |
|
80 |
+ outer headers without inspecting inner headers. |
|
81 |
+ - When creating a new VLAN, if this parameter is not specified, the default |
|
82 |
+ of C(outer) is used. |
|
83 |
+ - This parameter is not supported on Virtual Editions of BIG-IP. |
|
84 |
+ version_added: 2.5 |
|
85 |
+ dag_round_robin: |
|
86 |
+ description: |
|
87 |
+ - Specifies whether some of the stateless traffic on the VLAN should be |
|
88 |
+ disaggregated in a round-robin order instead of using a static hash. The |
|
89 |
+ stateless traffic includes non-IP L2 traffic, ICMP, some UDP protocols, |
|
90 |
+ and so on. |
|
91 |
+ - When creating a new VLAN, if this parameter is not specified, the default |
|
92 |
+ of (no) is used. |
|
93 |
+ version_added: 2.5 |
|
94 |
+ choices: [yes, no] |
|
58 | 95 |
notes: |
59 |
- - Requires the f5-sdk Python package on the host. This is as easy as pip |
|
60 |
- install f5-sdk. |
|
61 | 96 |
- Requires BIG-IP versions >= 12.0.0 |
62 | 97 |
extends_documentation_fragment: f5 |
63 |
-requirements: |
|
64 |
- - f5-sdk |
|
65 | 98 |
author: |
66 | 99 |
- Tim Rupp (@caphrim007) |
67 | 100 |
- Wojciech Wypior (@wojtek0806) |
... | ... |
@@ -114,162 +147,296 @@ EXAMPLES = r''' |
114 | 114 |
|
115 | 115 |
RETURN = r''' |
116 | 116 |
description: |
117 |
- description: The description set on the VLAN |
|
118 |
- returned: changed |
|
119 |
- type: string |
|
120 |
- sample: foo VLAN |
|
117 |
+ description: The description set on the VLAN. |
|
118 |
+ returned: changed |
|
119 |
+ type: string |
|
120 |
+ sample: foo VLAN |
|
121 | 121 |
interfaces: |
122 |
- description: Interfaces that the VLAN is assigned to |
|
123 |
- returned: changed |
|
124 |
- type: list |
|
125 |
- sample: ['1.1','1.2'] |
|
126 |
-name: |
|
127 |
- description: The name of the VLAN |
|
128 |
- returned: changed |
|
129 |
- type: string |
|
130 |
- sample: net1 |
|
122 |
+ description: Interfaces that the VLAN is assigned to. |
|
123 |
+ returned: changed |
|
124 |
+ type: list |
|
125 |
+ sample: ['1.1','1.2'] |
|
131 | 126 |
partition: |
132 |
- description: The partition that the VLAN was created on |
|
133 |
- returned: changed |
|
134 |
- type: string |
|
135 |
- sample: Common |
|
127 |
+ description: The partition that the VLAN was created on. |
|
128 |
+ returned: changed |
|
129 |
+ type: string |
|
130 |
+ sample: Common |
|
136 | 131 |
tag: |
137 |
- description: The ID of the VLAN |
|
138 |
- returned: changed |
|
139 |
- type: int |
|
140 |
- sample: 2345 |
|
132 |
+ description: The ID of the VLAN. |
|
133 |
+ returned: changed |
|
134 |
+ type: int |
|
135 |
+ sample: 2345 |
|
136 |
+cmp_hash: |
|
137 |
+ description: New traffic disaggregation method. |
|
138 |
+ returned: changed |
|
139 |
+ type: string |
|
140 |
+ sample: source-address |
|
141 |
+dag_tunnel: |
|
142 |
+ description: The new DAG tunnel setting. |
|
143 |
+ returned: changed |
|
144 |
+ type: string |
|
145 |
+ sample: outer |
|
141 | 146 |
''' |
142 | 147 |
|
143 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
144 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
145 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
146 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
147 |
-from ansible.module_utils.six import iteritems |
|
148 |
-from collections import defaultdict |
|
148 |
+from ansible.module_utils.basic import AnsibleModule |
|
149 |
+from ansible.module_utils.basic import env_fallback |
|
149 | 150 |
|
150 | 151 |
try: |
151 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
152 |
+ # Sideband repository used for dev |
|
153 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
154 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
155 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
156 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
157 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
158 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
159 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
160 |
+ try: |
|
161 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
162 |
+ except ImportError: |
|
163 |
+ HAS_F5SDK = False |
|
164 |
+ HAS_DEVEL_IMPORTS = True |
|
152 | 165 |
except ImportError: |
153 |
- HAS_F5SDK = False |
|
166 |
+ # Upstream Ansible |
|
167 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
168 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
169 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
170 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
171 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
172 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
173 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
174 |
+ try: |
|
175 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
176 |
+ except ImportError: |
|
177 |
+ HAS_F5SDK = False |
|
154 | 178 |
|
155 | 179 |
|
156 | 180 |
class Parameters(AnsibleF5Parameters): |
157 |
- def __init__(self, params=None): |
|
158 |
- self._values = defaultdict(lambda: None) |
|
159 |
- if params: |
|
160 |
- self.update(params=params) |
|
161 |
- |
|
162 |
- def update(self, params=None): |
|
163 |
- if params: |
|
164 |
- for k, v in iteritems(params): |
|
165 |
- if self.api_map is not None and k in self.api_map: |
|
166 |
- map_key = self.api_map[k] |
|
167 |
- else: |
|
168 |
- map_key = k |
|
169 |
- |
|
170 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
171 |
- # using a map provided by the module developer |
|
172 |
- class_attr = getattr(type(self), map_key, None) |
|
173 |
- if isinstance(class_attr, property): |
|
174 |
- # There is a mapped value for the api_map key |
|
175 |
- if class_attr.fset is None: |
|
176 |
- # If the mapped value does not have |
|
177 |
- # an associated setter |
|
178 |
- self._values[map_key] = v |
|
179 |
- else: |
|
180 |
- # The mapped value has a setter |
|
181 |
- setattr(self, map_key, v) |
|
182 |
- else: |
|
183 |
- # If the mapped value is not a @property |
|
184 |
- self._values[map_key] = v |
|
181 |
+ api_map = { |
|
182 |
+ 'cmpHash': 'cmp_hash', |
|
183 |
+ 'dagTunnel': 'dag_tunnel', |
|
184 |
+ 'dagRoundRobin': 'dag_round_robin' |
|
185 |
+ } |
|
185 | 186 |
|
186 | 187 |
updatables = [ |
187 | 188 |
'tagged_interfaces', 'untagged_interfaces', 'tag', |
188 |
- 'description' |
|
189 |
+ 'description', 'mtu', 'cmp_hash', 'dag_tunnel', |
|
190 |
+ 'dag_round_robin' |
|
189 | 191 |
] |
190 | 192 |
|
191 | 193 |
returnables = [ |
192 |
- 'description', 'partition', 'name', 'tag', 'interfaces', |
|
193 |
- 'tagged_interfaces', 'untagged_interfaces' |
|
194 |
+ 'description', 'partition', 'tag', 'interfaces', |
|
195 |
+ 'tagged_interfaces', 'untagged_interfaces', 'mtu', |
|
196 |
+ 'cmp_hash', 'dag_tunnel', 'dag_round_robin' |
|
194 | 197 |
] |
195 | 198 |
|
196 | 199 |
api_attributes = [ |
197 |
- 'description', 'interfaces', 'partition', 'name', 'tag' |
|
200 |
+ 'description', 'interfaces', 'tag', 'mtu', 'cmpHash', |
|
201 |
+ 'dagTunnel', 'dagRoundRobin' |
|
198 | 202 |
] |
199 |
- api_map = {} |
|
200 | 203 |
|
201 |
- @property |
|
202 |
- def interfaces(self): |
|
203 |
- tagged = self._values['tagged_interfaces'] |
|
204 |
- untagged = self._values['untagged_interfaces'] |
|
205 |
- if tagged: |
|
206 |
- return [dict(name=x, tagged=True) for x in tagged] |
|
207 |
- if untagged: |
|
208 |
- return [dict(name=x, untagged=True) for x in untagged] |
|
204 |
+ def to_return(self): |
|
205 |
+ result = {} |
|
206 |
+ for returnable in self.returnables: |
|
207 |
+ result[returnable] = getattr(self, returnable) |
|
208 |
+ result = self._filter_params(result) |
|
209 |
+ return result |
|
209 | 210 |
|
211 |
+ |
|
212 |
+class ApiParameters(Parameters): |
|
210 | 213 |
@property |
211 | 214 |
def tagged_interfaces(self): |
212 |
- value = self._values['tagged_interfaces'] |
|
213 |
- if value is None: |
|
215 |
+ if self._values['interfaces'] is None: |
|
216 |
+ return None |
|
217 |
+ result = [str(x.name) for x in self._values['interfaces'] if x.tagged is True] |
|
218 |
+ result = sorted(result) |
|
219 |
+ return result |
|
220 |
+ |
|
221 |
+ @property |
|
222 |
+ def untagged_interfaces(self): |
|
223 |
+ if self._values['interfaces'] is None: |
|
214 | 224 |
return None |
215 |
- ifcs = self._parse_return_ifcs() |
|
216 |
- for ifc in value: |
|
217 |
- if ifc not in ifcs: |
|
218 |
- err = 'The specified interface "%s" was not found' % ifc |
|
219 |
- raise F5ModuleError(err) |
|
220 |
- return value |
|
225 |
+ result = [str(x.name) for x in self._values['interfaces'] if x.untagged is True] |
|
226 |
+ result = sorted(result) |
|
227 |
+ return result |
|
228 |
+ |
|
221 | 229 |
|
230 |
+class ModuleParameters(Parameters): |
|
222 | 231 |
@property |
223 | 232 |
def untagged_interfaces(self): |
224 |
- value = self._values['untagged_interfaces'] |
|
225 |
- if value is None: |
|
233 |
+ if self._values['untagged_interfaces'] is None: |
|
234 |
+ return None |
|
235 |
+ if self._values['untagged_interfaces'] is None: |
|
236 |
+ return None |
|
237 |
+ if len(self._values['untagged_interfaces']) == 1 and self._values['untagged_interfaces'][0] == '': |
|
238 |
+ return '' |
|
239 |
+ result = sorted([str(x) for x in self._values['untagged_interfaces']]) |
|
240 |
+ return result |
|
241 |
+ |
|
242 |
+ @property |
|
243 |
+ def tagged_interfaces(self): |
|
244 |
+ if self._values['tagged_interfaces'] is None: |
|
245 |
+ return None |
|
246 |
+ if self._values['tagged_interfaces'] is None: |
|
226 | 247 |
return None |
227 |
- ifcs = self._parse_return_ifcs() |
|
228 |
- for ifc in value: |
|
229 |
- if ifc not in ifcs: |
|
230 |
- err = 'The specified interface "%s" was not found' % ifc |
|
231 |
- raise F5ModuleError(err) |
|
232 |
- return value |
|
233 |
- |
|
234 |
- def _get_interfaces_from_device(self): |
|
235 |
- lst = self.client.api.tm.net.interfaces.get_collection() |
|
236 |
- return lst |
|
237 |
- |
|
238 |
- def _parse_return_ifcs(self): |
|
239 |
- ifclst = self._get_interfaces_from_device() |
|
240 |
- ifcs = [str(x.name) for x in ifclst] |
|
241 |
- if not ifcs: |
|
242 |
- err = 'No interfaces were found' |
|
243 |
- raise F5ModuleError(err) |
|
244 |
- return ifcs |
|
248 |
+ if len(self._values['tagged_interfaces']) == 1 and self._values['tagged_interfaces'][0] == '': |
|
249 |
+ return '' |
|
250 |
+ result = sorted([str(x) for x in self._values['tagged_interfaces']]) |
|
251 |
+ return result |
|
252 |
+ |
|
253 |
+ @property |
|
254 |
+ def mtu(self): |
|
255 |
+ if self._values['mtu'] is None: |
|
256 |
+ return None |
|
257 |
+ if int(self._values['mtu']) < 576 or int(self._values['mtu']) > 9198: |
|
258 |
+ raise F5ModuleError( |
|
259 |
+ "The mtu value must be between 576 - 9198" |
|
260 |
+ ) |
|
261 |
+ return int(self._values['mtu']) |
|
245 | 262 |
|
263 |
+ @property |
|
264 |
+ def cmp_hash(self): |
|
265 |
+ if self._values['cmp_hash'] is None: |
|
266 |
+ return None |
|
267 |
+ if self._values['cmp_hash'] in ['source-address', 'src', 'src-ip', 'source']: |
|
268 |
+ return 'src-ip' |
|
269 |
+ if self._values['cmp_hash'] in ['destination-address', 'dest', 'dst-ip', 'destination', 'dst']: |
|
270 |
+ return 'dst-ip' |
|
271 |
+ else: |
|
272 |
+ return 'default' |
|
273 |
+ |
|
274 |
+ @property |
|
275 |
+ def dag_round_robin(self): |
|
276 |
+ if self._values['dag_round_robin'] is None: |
|
277 |
+ return None |
|
278 |
+ if self._values['dag_round_robin'] is True: |
|
279 |
+ return 'enabled' |
|
280 |
+ else: |
|
281 |
+ return 'disabled' |
|
282 |
+ |
|
283 |
+ |
|
284 |
+class Changes(Parameters): |
|
246 | 285 |
def to_return(self): |
247 | 286 |
result = {} |
248 |
- for returnable in self.returnables: |
|
249 |
- result[returnable] = getattr(self, returnable) |
|
250 |
- result = self._filter_params(result) |
|
287 |
+ try: |
|
288 |
+ for returnable in self.returnables: |
|
289 |
+ result[returnable] = getattr(self, returnable) |
|
290 |
+ result = self._filter_params(result) |
|
291 |
+ except Exception: |
|
292 |
+ pass |
|
251 | 293 |
return result |
252 | 294 |
|
253 |
- def api_params(self): |
|
254 |
- result = {} |
|
255 |
- for api_attribute in self.api_attributes: |
|
256 |
- if api_attribute in self.api_map: |
|
257 |
- result[api_attribute] = getattr( |
|
258 |
- self, self.api_map[api_attribute]) |
|
259 |
- else: |
|
260 |
- result[api_attribute] = getattr(self, api_attribute) |
|
261 |
- result = self._filter_params(result) |
|
295 |
+ |
|
296 |
+class UsableChanges(Changes): |
|
297 |
+ pass |
|
298 |
+ |
|
299 |
+ |
|
300 |
+class ReportableChanges(Changes): |
|
301 |
+ @property |
|
302 |
+ def tagged_interfaces(self): |
|
303 |
+ if self._values['interfaces'] is None: |
|
304 |
+ return None |
|
305 |
+ result = [str(x['name']) for x in self._values['interfaces'] if 'tagged' in x and x['tagged'] is True] |
|
306 |
+ result = sorted(result) |
|
307 |
+ return result |
|
308 |
+ |
|
309 |
+ @property |
|
310 |
+ def untagged_interfaces(self): |
|
311 |
+ if self._values['interfaces'] is None: |
|
312 |
+ return None |
|
313 |
+ result = [str(x['name']) for x in self._values['interfaces'] if 'untagged' in x and x['untagged'] is True] |
|
314 |
+ result = sorted(result) |
|
315 |
+ return result |
|
316 |
+ |
|
317 |
+ |
|
318 |
+class Difference(object): |
|
319 |
+ def __init__(self, want, have=None): |
|
320 |
+ self.want = want |
|
321 |
+ self.have = have |
|
322 |
+ |
|
323 |
+ def compare(self, param): |
|
324 |
+ try: |
|
325 |
+ result = getattr(self, param) |
|
326 |
+ return result |
|
327 |
+ except AttributeError: |
|
328 |
+ return self.__default(param) |
|
329 |
+ |
|
330 |
+ def __default(self, param): |
|
331 |
+ attr1 = getattr(self.want, param) |
|
332 |
+ try: |
|
333 |
+ attr2 = getattr(self.have, param) |
|
334 |
+ if attr1 != attr2: |
|
335 |
+ return attr1 |
|
336 |
+ except AttributeError: |
|
337 |
+ return attr1 |
|
338 |
+ |
|
339 |
+ @property |
|
340 |
+ def untagged_interfaces(self): |
|
341 |
+ result = [] |
|
342 |
+ if self.want.untagged_interfaces is None: |
|
343 |
+ return None |
|
344 |
+ elif self.want.untagged_interfaces == '' and self.have.untagged_interfaces is None: |
|
345 |
+ return None |
|
346 |
+ elif self.want.untagged_interfaces == '' and len(self.have.untagged_interfaces) > 0: |
|
347 |
+ pass |
|
348 |
+ elif not self.have.untagged_interfaces: |
|
349 |
+ result = dict( |
|
350 |
+ interfaces=[dict(name=x, untagged=True) for x in self.want.untagged_interfaces] |
|
351 |
+ ) |
|
352 |
+ elif set(self.want.untagged_interfaces) != set(self.have.untagged_interfaces): |
|
353 |
+ result = dict( |
|
354 |
+ interfaces=[dict(name=x, untagged=True) for x in self.want.untagged_interfaces] |
|
355 |
+ ) |
|
356 |
+ else: |
|
357 |
+ return None |
|
358 |
+ return result |
|
359 |
+ |
|
360 |
+ @property |
|
361 |
+ def tagged_interfaces(self): |
|
362 |
+ result = [] |
|
363 |
+ if self.want.tagged_interfaces is None: |
|
364 |
+ return None |
|
365 |
+ elif self.want.tagged_interfaces == '' and self.have.tagged_interfaces is None: |
|
366 |
+ return None |
|
367 |
+ elif self.want.tagged_interfaces == '' and len(self.have.tagged_interfaces) > 0: |
|
368 |
+ pass |
|
369 |
+ elif not self.have.tagged_interfaces: |
|
370 |
+ result = dict( |
|
371 |
+ interfaces=[dict(name=x, tagged=True) for x in self.want.tagged_interfaces] |
|
372 |
+ ) |
|
373 |
+ elif set(self.want.tagged_interfaces) != set(self.have.tagged_interfaces): |
|
374 |
+ result = dict( |
|
375 |
+ interfaces=[dict(name=x, tagged=True) for x in self.want.tagged_interfaces] |
|
376 |
+ ) |
|
377 |
+ else: |
|
378 |
+ return None |
|
262 | 379 |
return result |
263 | 380 |
|
264 | 381 |
|
265 | 382 |
class ModuleManager(object): |
266 |
- def __init__(self, client): |
|
267 |
- self.client = client |
|
268 |
- self.have = None |
|
269 |
- self.want = Parameters() |
|
270 |
- self.want.client = self.client |
|
271 |
- self.want.update(self.client.module.params) |
|
272 |
- self.changes = Parameters() |
|
383 |
+ def __init__(self, *args, **kwargs): |
|
384 |
+ self.module = kwargs.get('module', None) |
|
385 |
+ self.client = kwargs.get('client', None) |
|
386 |
+ self.want = ModuleParameters(params=self.module.params) |
|
387 |
+ self.have = ApiParameters() |
|
388 |
+ self.changes = UsableChanges() |
|
389 |
+ |
|
390 |
+ def _update_changed_options(self): |
|
391 |
+ diff = Difference(self.want, self.have) |
|
392 |
+ updatables = Parameters.updatables |
|
393 |
+ changed = dict() |
|
394 |
+ for k in updatables: |
|
395 |
+ change = diff.compare(k) |
|
396 |
+ if change is None: |
|
397 |
+ continue |
|
398 |
+ else: |
|
399 |
+ if isinstance(change, dict): |
|
400 |
+ changed.update(change) |
|
401 |
+ else: |
|
402 |
+ changed[k] = change |
|
403 |
+ if changed: |
|
404 |
+ self.changes = UsableChanges(params=changed) |
|
405 |
+ return True |
|
406 |
+ return False |
|
273 | 407 |
|
274 | 408 |
def exec_module(self): |
275 | 409 |
changed = False |
... | ... |
@@ -284,39 +451,20 @@ class ModuleManager(object): |
284 | 284 |
except iControlUnexpectedHTTPError as e: |
285 | 285 |
raise F5ModuleError(str(e)) |
286 | 286 |
|
287 |
- changes = self.changes.to_return() |
|
287 |
+ reportable = ReportableChanges(params=self.changes.to_return()) |
|
288 |
+ changes = reportable.to_return() |
|
288 | 289 |
result.update(**changes) |
289 | 290 |
result.update(dict(changed=changed)) |
291 |
+ self._announce_deprecations(result) |
|
290 | 292 |
return result |
291 | 293 |
|
292 |
- def _set_changed_options(self): |
|
293 |
- changed = {} |
|
294 |
- for key in Parameters.returnables: |
|
295 |
- if getattr(self.want, key) is not None: |
|
296 |
- changed[key] = getattr(self.want, key) |
|
297 |
- if changed: |
|
298 |
- self.changes = Parameters(changed) |
|
299 |
- |
|
300 |
- def _update_changed_options(self): |
|
301 |
- changed = {} |
|
302 |
- for key in Parameters.updatables: |
|
303 |
- if getattr(self.want, key) is not None: |
|
304 |
- attr1 = getattr(self.want, key) |
|
305 |
- attr2 = getattr(self.have, key) |
|
306 |
- if attr1 != attr2: |
|
307 |
- changed[key] = attr1 |
|
308 |
- if changed: |
|
309 |
- self.changes = Parameters(changed) |
|
310 |
- return True |
|
311 |
- return False |
|
312 |
- |
|
313 |
- def _have_interfaces(self, ifcs): |
|
314 |
- untagged = [str(x.name) for x in ifcs if hasattr(x, 'untagged')] |
|
315 |
- tagged = [str(x.name) for x in ifcs if hasattr(x, 'tagged')] |
|
316 |
- if untagged: |
|
317 |
- self.have.update({'untagged_interfaces': untagged}) |
|
318 |
- if tagged: |
|
319 |
- self.have.update({'tagged_interfaces': tagged}) |
|
294 |
+ def _announce_deprecations(self, result): |
|
295 |
+ warnings = result.pop('__warnings', []) |
|
296 |
+ for warning in warnings: |
|
297 |
+ self.module.deprecate( |
|
298 |
+ msg=warning['msg'], |
|
299 |
+ version=warning['version'] |
|
300 |
+ ) |
|
320 | 301 |
|
321 | 302 |
def present(self): |
322 | 303 |
if self.exists(): |
... | ... |
@@ -336,18 +484,16 @@ class ModuleManager(object): |
336 | 336 |
return False |
337 | 337 |
|
338 | 338 |
def update(self): |
339 |
- self.have, ifcs = self.read_current_from_device() |
|
340 |
- if ifcs: |
|
341 |
- self._have_interfaces(ifcs) |
|
339 |
+ self.have = self.read_current_from_device() |
|
342 | 340 |
if not self.should_update(): |
343 | 341 |
return False |
344 |
- if self.client.check_mode: |
|
342 |
+ if self.module.check_mode: |
|
345 | 343 |
return True |
346 | 344 |
self.update_on_device() |
347 | 345 |
return True |
348 | 346 |
|
349 | 347 |
def remove(self): |
350 |
- if self.client.check_mode: |
|
348 |
+ if self.module.check_mode: |
|
351 | 349 |
return True |
352 | 350 |
self.remove_from_device() |
353 | 351 |
if self.exists(): |
... | ... |
@@ -355,49 +501,59 @@ class ModuleManager(object): |
355 | 355 |
return True |
356 | 356 |
|
357 | 357 |
def create(self): |
358 |
- self._set_changed_options() |
|
359 |
- if self.client.check_mode: |
|
358 |
+ self.have = ApiParameters() |
|
359 |
+ if self.want.mtu is None: |
|
360 |
+ self.want.update({'mtu': 1500}) |
|
361 |
+ self._update_changed_options() |
|
362 |
+ if self.module.check_mode: |
|
360 | 363 |
return True |
361 | 364 |
self.create_on_device() |
362 | 365 |
return True |
363 | 366 |
|
364 | 367 |
def create_on_device(self): |
365 |
- params = self.want.api_params() |
|
366 |
- self.client.api.tm.net.vlans.vlan.create(**params) |
|
368 |
+ params = self.changes.api_params() |
|
369 |
+ self.client.api.tm.net.vlans.vlan.create( |
|
370 |
+ name=self.want.name, |
|
371 |
+ partition=self.want.partition, |
|
372 |
+ **params |
|
373 |
+ ) |
|
367 | 374 |
|
368 | 375 |
def update_on_device(self): |
369 |
- params = self.want.api_params() |
|
370 |
- result = self.client.api.tm.net.vlans.vlan.load( |
|
371 |
- name=self.want.name, partition=self.want.partition |
|
376 |
+ params = self.changes.api_params() |
|
377 |
+ resource = self.client.api.tm.net.vlans.vlan.load( |
|
378 |
+ name=self.want.name, |
|
379 |
+ partition=self.want.partition |
|
372 | 380 |
) |
373 |
- result.modify(**params) |
|
381 |
+ resource.modify(**params) |
|
374 | 382 |
|
375 | 383 |
def exists(self): |
376 | 384 |
return self.client.api.tm.net.vlans.vlan.exists( |
377 |
- name=self.want.name, partition=self.want.partition |
|
385 |
+ name=self.want.name, |
|
386 |
+ partition=self.want.partition |
|
378 | 387 |
) |
379 | 388 |
|
380 | 389 |
def remove_from_device(self): |
381 |
- result = self.client.api.tm.net.vlans.vlan.load( |
|
382 |
- name=self.want.name, partition=self.want.partition |
|
390 |
+ resource = self.client.api.tm.net.vlans.vlan.load( |
|
391 |
+ name=self.want.name, |
|
392 |
+ partition=self.want.partition |
|
383 | 393 |
) |
384 |
- if result: |
|
385 |
- result.delete() |
|
394 |
+ if resource: |
|
395 |
+ resource.delete() |
|
386 | 396 |
|
387 | 397 |
def read_current_from_device(self): |
388 |
- tmp_res = self.client.api.tm.net.vlans.vlan.load( |
|
398 |
+ resource = self.client.api.tm.net.vlans.vlan.load( |
|
389 | 399 |
name=self.want.name, partition=self.want.partition |
390 | 400 |
) |
391 |
- ifcs = tmp_res.interfaces_s.get_collection() |
|
392 |
- |
|
393 |
- result = tmp_res.attrs |
|
394 |
- return Parameters(result), ifcs |
|
401 |
+ interfaces = resource.interfaces_s.get_collection() |
|
402 |
+ result = resource.attrs |
|
403 |
+ result['interfaces'] = interfaces |
|
404 |
+ return ApiParameters(params=result) |
|
395 | 405 |
|
396 | 406 |
|
397 | 407 |
class ArgumentSpec(object): |
398 | 408 |
def __init__(self): |
399 | 409 |
self.supports_check_mode = True |
400 |
- self.argument_spec = dict( |
|
410 |
+ argument_spec = dict( |
|
401 | 411 |
name=dict( |
402 | 412 |
required=True, |
403 | 413 |
), |
... | ... |
@@ -412,32 +568,56 @@ class ArgumentSpec(object): |
412 | 412 |
description=dict(), |
413 | 413 |
tag=dict( |
414 | 414 |
type='int' |
415 |
+ ), |
|
416 |
+ mtu=dict(type='int'), |
|
417 |
+ cmp_hash=dict( |
|
418 |
+ choices=[ |
|
419 |
+ 'default', |
|
420 |
+ 'destination-address', 'dest', 'dst-ip', 'destination', 'dst', |
|
421 |
+ 'source-address', 'src', 'src-ip', 'source' |
|
422 |
+ ] |
|
423 |
+ ), |
|
424 |
+ dag_tunnel=dict( |
|
425 |
+ choices=['inner', 'outer'] |
|
426 |
+ ), |
|
427 |
+ dag_round_robin=dict(type='bool'), |
|
428 |
+ state=dict( |
|
429 |
+ default='present', |
|
430 |
+ choices=['present', 'absent'] |
|
431 |
+ ), |
|
432 |
+ partition=dict( |
|
433 |
+ default='Common', |
|
434 |
+ fallback=(env_fallback, ['F5_PARTITION']) |
|
415 | 435 |
) |
416 | 436 |
) |
417 |
- self.f5_product_name = 'bigip' |
|
437 |
+ self.argument_spec = {} |
|
438 |
+ self.argument_spec.update(f5_argument_spec) |
|
439 |
+ self.argument_spec.update(argument_spec) |
|
440 |
+ self.mutually_exclusive = [ |
|
441 |
+ ['tagged_interfaces', 'untagged_interfaces'] |
|
442 |
+ ] |
|
418 | 443 |
|
419 | 444 |
|
420 | 445 |
def main(): |
421 |
- if not HAS_F5SDK: |
|
422 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
423 |
- |
|
424 | 446 |
spec = ArgumentSpec() |
425 | 447 |
|
426 |
- client = AnsibleF5Client( |
|
448 |
+ module = AnsibleModule( |
|
427 | 449 |
argument_spec=spec.argument_spec, |
428 | 450 |
supports_check_mode=spec.supports_check_mode, |
429 |
- f5_product_name=spec.f5_product_name, |
|
430 |
- mutually_exclusive=[ |
|
431 |
- ['tagged_interfaces', 'untagged_interfaces'] |
|
432 |
- ] |
|
451 |
+ mutually_exclusive=spec.mutually_exclusive |
|
433 | 452 |
) |
453 |
+ if not HAS_F5SDK: |
|
454 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
434 | 455 |
|
435 | 456 |
try: |
436 |
- mm = ModuleManager(client) |
|
457 |
+ client = F5Client(**module.params) |
|
458 |
+ mm = ModuleManager(module=module, client=client) |
|
437 | 459 |
results = mm.exec_module() |
438 |
- client.module.exit_json(**results) |
|
460 |
+ cleanup_tokens(client) |
|
461 |
+ module.exit_json(**results) |
|
439 | 462 |
except F5ModuleError as e: |
440 |
- client.module.fail_json(msg=str(e)) |
|
463 |
+ cleanup_tokens(client) |
|
464 |
+ module.fail_json(msg=str(e)) |
|
441 | 465 |
|
442 | 466 |
|
443 | 467 |
if __name__ == '__main__': |
... | ... |
@@ -40,11 +40,6 @@ options: |
40 | 40 |
msg: |
41 | 41 |
description: |
42 | 42 |
- This overrides the normal error message from a failure to meet the required conditions. |
43 |
-notes: |
|
44 |
- - Requires the f5-sdk Python package on the host. This is as easy as pip |
|
45 |
- install f5-sdk. |
|
46 |
-requirements: |
|
47 |
- - f5-sdk >= 2.2.3 |
|
48 | 43 |
extends_documentation_fragment: f5 |
49 | 44 |
author: |
50 | 45 |
- Tim Rupp (@caphrim007) |
... | ... |
@@ -84,133 +79,50 @@ import signal |
84 | 84 |
import time |
85 | 85 |
|
86 | 86 |
from ansible.module_utils.basic import AnsibleModule |
87 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
88 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
89 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
90 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
91 |
-from ansible.module_utils.f5_utils import F5_COMMON_ARGS |
|
92 |
-from ansible.module_utils.six import iteritems |
|
93 |
-from collections import defaultdict |
|
87 |
+ |
|
88 |
+HAS_DEVEL_IMPORTS = False |
|
94 | 89 |
|
95 | 90 |
try: |
96 |
- from f5.bigip import ManagementRoot as BigIpMgmt |
|
97 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
91 |
+ # Sideband repository used for dev |
|
92 |
+ from library.module_utils.network.f5.bigip import HAS_F5SDK |
|
93 |
+ from library.module_utils.network.f5.bigip import F5Client |
|
94 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
95 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
96 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
97 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
98 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
99 |
+ try: |
|
100 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
101 |
+ except ImportError: |
|
102 |
+ HAS_F5SDK = False |
|
103 |
+ HAS_DEVEL_IMPORTS = True |
|
98 | 104 |
except ImportError: |
99 |
- HAS_F5SDK = False |
|
105 |
+ # Upstream Ansible |
|
106 |
+ from ansible.module_utils.network.f5.bigip import HAS_F5SDK |
|
107 |
+ from ansible.module_utils.network.f5.bigip import F5Client |
|
108 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
109 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
110 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
111 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
112 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
113 |
+ try: |
|
114 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
115 |
+ except ImportError: |
|
116 |
+ HAS_F5SDK = False |
|
100 | 117 |
|
101 | 118 |
|
102 |
-def hard_timeout(client, want, start): |
|
119 |
+def hard_timeout(module, want, start): |
|
103 | 120 |
elapsed = datetime.datetime.utcnow() - start |
104 |
- client.module.fail_json( |
|
121 |
+ module.fail_json( |
|
105 | 122 |
want.msg or "Timeout when waiting for BIG-IP", elapsed=elapsed.seconds |
106 | 123 |
) |
107 | 124 |
|
108 | 125 |
|
109 |
-class AnsibleF5ClientStub(AnsibleF5Client): |
|
110 |
- """Interim class to disconnect Params from connection |
|
111 |
- |
|
112 |
- This module is an interim class that was made to separate the Ansible Module |
|
113 |
- Parameters from the connection to BIG-IP. |
|
114 |
- |
|
115 |
- Since this module needs to be able to control the connection process, the default |
|
116 |
- class is not appropriate. Therefore, we overload it and re-define out the |
|
117 |
- connection related work to a separate method. |
|
118 |
- |
|
119 |
- This class should serve as a reason to break apart this work itself into separate |
|
120 |
- classes in module_utils. There will be on-going work to do this and, when done, |
|
121 |
- the result will replace this work here. |
|
122 |
- |
|
123 |
- """ |
|
124 |
- def __init__(self, argument_spec=None, supports_check_mode=False, |
|
125 |
- mutually_exclusive=None, required_together=None, |
|
126 |
- required_if=None, required_one_of=None, add_file_common_args=False, |
|
127 |
- f5_product_name='bigip'): |
|
128 |
- self.f5_product_name = f5_product_name |
|
129 |
- |
|
130 |
- merged_arg_spec = dict() |
|
131 |
- merged_arg_spec.update(F5_COMMON_ARGS) |
|
132 |
- if argument_spec: |
|
133 |
- merged_arg_spec.update(argument_spec) |
|
134 |
- self.arg_spec = merged_arg_spec |
|
135 |
- |
|
136 |
- mutually_exclusive_params = [] |
|
137 |
- if mutually_exclusive: |
|
138 |
- mutually_exclusive_params += mutually_exclusive |
|
139 |
- |
|
140 |
- required_together_params = [] |
|
141 |
- if required_together: |
|
142 |
- required_together_params += required_together |
|
143 |
- |
|
144 |
- self.module = AnsibleModule( |
|
145 |
- argument_spec=merged_arg_spec, |
|
146 |
- supports_check_mode=supports_check_mode, |
|
147 |
- mutually_exclusive=mutually_exclusive_params, |
|
148 |
- required_together=required_together_params, |
|
149 |
- required_if=required_if, |
|
150 |
- required_one_of=required_one_of, |
|
151 |
- add_file_common_args=add_file_common_args |
|
152 |
- ) |
|
153 |
- |
|
154 |
- self.check_mode = self.module.check_mode |
|
155 |
- self._connect_params = self._get_connect_params() |
|
156 |
- |
|
157 |
- def connect(self): |
|
158 |
- try: |
|
159 |
- if 'transport' not in self.module.params or self.module.params['transport'] != 'cli': |
|
160 |
- self.api = self._get_mgmt_root( |
|
161 |
- self.f5_product_name, **self._connect_params |
|
162 |
- ) |
|
163 |
- return True |
|
164 |
- except Exception: |
|
165 |
- return False |
|
166 |
- |
|
167 |
- def _get_mgmt_root(self, type, **kwargs): |
|
168 |
- if type == 'bigip': |
|
169 |
- result = BigIpMgmt( |
|
170 |
- kwargs['server'], |
|
171 |
- kwargs['user'], |
|
172 |
- kwargs['password'], |
|
173 |
- port=kwargs['server_port'], |
|
174 |
- timeout=1, |
|
175 |
- token='tmos' |
|
176 |
- ) |
|
177 |
- return result |
|
178 |
- |
|
179 |
- |
|
180 | 126 |
class Parameters(AnsibleF5Parameters): |
181 | 127 |
returnables = [ |
182 | 128 |
'elapsed' |
183 | 129 |
] |
184 | 130 |
|
185 |
- def __init__(self, params=None): |
|
186 |
- self._values = defaultdict(lambda: None) |
|
187 |
- if params: |
|
188 |
- self.update(params=params) |
|
189 |
- self._values['__warnings'] = [] |
|
190 |
- |
|
191 |
- def update(self, params=None): |
|
192 |
- if params: |
|
193 |
- for k, v in iteritems(params): |
|
194 |
- if self.api_map is not None and k in self.api_map: |
|
195 |
- map_key = self.api_map[k] |
|
196 |
- else: |
|
197 |
- map_key = k |
|
198 |
- |
|
199 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
200 |
- # using a map provided by the module developer |
|
201 |
- class_attr = getattr(type(self), map_key, None) |
|
202 |
- if isinstance(class_attr, property): |
|
203 |
- # There is a mapped value for the api_map key |
|
204 |
- if class_attr.fset is None: |
|
205 |
- # If the mapped value does not have an associated setter |
|
206 |
- self._values[map_key] = v |
|
207 |
- else: |
|
208 |
- # The mapped value has a setter |
|
209 |
- setattr(self, map_key, v) |
|
210 |
- else: |
|
211 |
- # If the mapped value is not a @property |
|
212 |
- self._values[map_key] = v |
|
213 |
- |
|
214 | 131 |
def to_return(self): |
215 | 132 |
result = {} |
216 | 133 |
try: |
... | ... |
@@ -245,10 +157,11 @@ class Changes(Parameters): |
245 | 245 |
|
246 | 246 |
|
247 | 247 |
class ModuleManager(object): |
248 |
- def __init__(self, client): |
|
249 |
- self.client = client |
|
248 |
+ def __init__(self, *args, **kwargs): |
|
249 |
+ self.module = kwargs.get('module', None) |
|
250 |
+ self.client = kwargs.get('client', None) |
|
250 | 251 |
self.have = None |
251 |
- self.want = Parameters(self.client.module.params) |
|
252 |
+ self.want = Parameters(params=self.module.params) |
|
252 | 253 |
self.changes = Parameters() |
253 | 254 |
|
254 | 255 |
def exec_module(self): |
... | ... |
@@ -268,7 +181,7 @@ class ModuleManager(object): |
268 | 268 |
def _announce_deprecations(self, result): |
269 | 269 |
warnings = result.pop('__warnings', []) |
270 | 270 |
for warning in warnings: |
271 |
- self.client.module.deprecate( |
|
271 |
+ self.module.deprecate( |
|
272 | 272 |
msg=warning['msg'], |
273 | 273 |
version=warning['version'] |
274 | 274 |
) |
... | ... |
@@ -276,7 +189,7 @@ class ModuleManager(object): |
276 | 276 |
def execute(self): |
277 | 277 |
signal.signal( |
278 | 278 |
signal.SIGALRM, |
279 |
- lambda sig, frame: hard_timeout(self.client, self.want, start) |
|
279 |
+ lambda sig, frame: hard_timeout(self.module, self.want, start) |
|
280 | 280 |
) |
281 | 281 |
|
282 | 282 |
# setup handler before scheduling signal, to eliminate a race |
... | ... |
@@ -291,8 +204,8 @@ class ModuleManager(object): |
291 | 291 |
try: |
292 | 292 |
# The first test verifies that the REST API is available; this is done |
293 | 293 |
# by repeatedly trying to login to it. |
294 |
- connected = self._connect_to_device() |
|
295 |
- if not connected: |
|
294 |
+ self.client = F5Client(**self.module.params) |
|
295 |
+ if not self.client: |
|
296 | 296 |
continue |
297 | 297 |
|
298 | 298 |
if self._device_is_rebooting(): |
... | ... |
@@ -333,17 +246,13 @@ class ModuleManager(object): |
333 | 333 |
continue |
334 | 334 |
else: |
335 | 335 |
elapsed = datetime.datetime.utcnow() - start |
336 |
- self.client.module.fail_json( |
|
336 |
+ self.module.fail_json( |
|
337 | 337 |
msg=self.want.msg or "Timeout when waiting for BIG-IP", elapsed=elapsed.seconds |
338 | 338 |
) |
339 | 339 |
elapsed = datetime.datetime.utcnow() - start |
340 | 340 |
self.changes.update({'elapsed': elapsed.seconds}) |
341 | 341 |
return False |
342 | 342 |
|
343 |
- def _connect_to_device(self): |
|
344 |
- result = self.client.connect() |
|
345 |
- return result |
|
346 |
- |
|
347 | 343 |
def _device_is_rebooting(self): |
348 | 344 |
output = self.client.api.tm.util.bash.exec_cmd( |
349 | 345 |
'run', |
... | ... |
@@ -386,45 +295,33 @@ class ModuleManager(object): |
386 | 386 |
class ArgumentSpec(object): |
387 | 387 |
def __init__(self): |
388 | 388 |
self.supports_check_mode = True |
389 |
- self.argument_spec = dict( |
|
389 |
+ argument_spec = dict( |
|
390 | 390 |
timeout=dict(default=7200, type='int'), |
391 | 391 |
delay=dict(default=0, type='int'), |
392 | 392 |
sleep=dict(default=1, type='int'), |
393 | 393 |
msg=dict() |
394 | 394 |
) |
395 |
- self.f5_product_name = 'bigip' |
|
396 |
- |
|
397 |
- |
|
398 |
-def cleanup_tokens(client): |
|
399 |
- try: |
|
400 |
- resource = client.api.shared.authz.tokens_s.token.load( |
|
401 |
- name=client.api.icrs.token |
|
402 |
- ) |
|
403 |
- resource.delete() |
|
404 |
- except Exception: |
|
405 |
- pass |
|
395 |
+ self.argument_spec = {} |
|
396 |
+ self.argument_spec.update(f5_argument_spec) |
|
397 |
+ self.argument_spec.update(argument_spec) |
|
406 | 398 |
|
407 | 399 |
|
408 | 400 |
def main(): |
409 |
- if not HAS_F5SDK: |
|
410 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
411 |
- |
|
412 | 401 |
spec = ArgumentSpec() |
413 | 402 |
|
414 |
- client = AnsibleF5ClientStub( |
|
403 |
+ module = AnsibleModule( |
|
415 | 404 |
argument_spec=spec.argument_spec, |
416 |
- supports_check_mode=spec.supports_check_mode, |
|
417 |
- f5_product_name=spec.f5_product_name, |
|
405 |
+ supports_check_mode=spec.supports_check_mode |
|
418 | 406 |
) |
407 |
+ if not HAS_F5SDK: |
|
408 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
419 | 409 |
|
420 | 410 |
try: |
421 |
- mm = ModuleManager(client) |
|
411 |
+ mm = ModuleManager(module=module) |
|
422 | 412 |
results = mm.exec_module() |
423 |
- cleanup_tokens(client) |
|
424 |
- client.module.exit_json(**results) |
|
413 |
+ module.exit_json(**results) |
|
425 | 414 |
except F5ModuleError as e: |
426 |
- cleanup_tokens(client) |
|
427 |
- client.module.fail_json(msg=str(e)) |
|
415 |
+ module.fail_json(msg=str(e)) |
|
428 | 416 |
|
429 | 417 |
|
430 | 418 |
if __name__ == '__main__': |
... | ... |
@@ -89,17 +89,37 @@ description: |
89 | 89 |
|
90 | 90 |
import time |
91 | 91 |
|
92 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
93 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
94 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
95 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
96 |
-from ansible.module_utils.six import iteritems |
|
97 |
-from collections import defaultdict |
|
92 |
+from ansible.module_utils.basic import AnsibleModule |
|
93 |
+ |
|
94 |
+HAS_DEVEL_IMPORTS = False |
|
98 | 95 |
|
99 | 96 |
try: |
100 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
97 |
+ # Sideband repository used for dev |
|
98 |
+ from library.module_utils.network.f5.bigiq import HAS_F5SDK |
|
99 |
+ from library.module_utils.network.f5.bigiq import F5Client |
|
100 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
101 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
102 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
103 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
104 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
105 |
+ try: |
|
106 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
107 |
+ except ImportError: |
|
108 |
+ HAS_F5SDK = False |
|
109 |
+ HAS_DEVEL_IMPORTS = True |
|
101 | 110 |
except ImportError: |
102 |
- HAS_F5SDK = False |
|
111 |
+ # Upstream Ansible |
|
112 |
+ from ansible.module_utils.network.f5.bigiq import HAS_F5SDK |
|
113 |
+ from ansible.module_utils.network.f5.bigiq import F5Client |
|
114 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
115 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
116 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
117 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
118 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
119 |
+ try: |
|
120 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
121 |
+ except ImportError: |
|
122 |
+ HAS_F5SDK = False |
|
103 | 123 |
|
104 | 124 |
|
105 | 125 |
class Parameters(AnsibleF5Parameters): |
... | ... |
@@ -119,36 +139,6 @@ class Parameters(AnsibleF5Parameters): |
119 | 119 |
'description' |
120 | 120 |
] |
121 | 121 |
|
122 |
- def __init__(self, params=None): |
|
123 |
- self._values = defaultdict(lambda: None) |
|
124 |
- self._values['__warnings'] = [] |
|
125 |
- if params: |
|
126 |
- self.update(params=params) |
|
127 |
- |
|
128 |
- def update(self, params=None): |
|
129 |
- if params: |
|
130 |
- for k, v in iteritems(params): |
|
131 |
- if self.api_map is not None and k in self.api_map: |
|
132 |
- map_key = self.api_map[k] |
|
133 |
- else: |
|
134 |
- map_key = k |
|
135 |
- |
|
136 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
137 |
- # using a map provided by the module developer |
|
138 |
- class_attr = getattr(type(self), map_key, None) |
|
139 |
- if isinstance(class_attr, property): |
|
140 |
- # There is a mapped value for the api_map key |
|
141 |
- if class_attr.fset is None: |
|
142 |
- # If the mapped value does not have |
|
143 |
- # an associated setter |
|
144 |
- self._values[map_key] = v |
|
145 |
- else: |
|
146 |
- # The mapped value has a setter |
|
147 |
- setattr(self, map_key, v) |
|
148 |
- else: |
|
149 |
- # If the mapped value is not a @property |
|
150 |
- self._values[map_key] = v |
|
151 |
- |
|
152 | 122 |
def to_return(self): |
153 | 123 |
result = {} |
154 | 124 |
try: |
... | ... |
@@ -159,16 +149,6 @@ class Parameters(AnsibleF5Parameters): |
159 | 159 |
pass |
160 | 160 |
return result |
161 | 161 |
|
162 |
- def api_params(self): |
|
163 |
- result = {} |
|
164 |
- for api_attribute in self.api_attributes: |
|
165 |
- if self.api_map is not None and api_attribute in self.api_map: |
|
166 |
- result[api_attribute] = getattr(self, self.api_map[api_attribute]) |
|
167 |
- else: |
|
168 |
- result[api_attribute] = getattr(self, api_attribute) |
|
169 |
- result = self._filter_params(result) |
|
170 |
- return result |
|
171 |
- |
|
172 | 162 |
|
173 | 163 |
class ApiParameters(Parameters): |
174 | 164 |
pass |
... | ... |
@@ -230,10 +210,10 @@ class Difference(object): |
230 | 230 |
|
231 | 231 |
|
232 | 232 |
class ModuleManager(object): |
233 |
- def __init__(self, client): |
|
234 |
- self.client = client |
|
235 |
- self.want = ModuleParameters(params=self.client.module.params) |
|
236 |
- self.want.update(dict(client=client)) |
|
233 |
+ def __init__(self, *args, **kwargs): |
|
234 |
+ self.module = kwargs.get('module', None) |
|
235 |
+ self.client = kwargs.get('client', None) |
|
236 |
+ self.want = ModuleParameters(client=self.client, params=self.module.params) |
|
237 | 237 |
self.have = ApiParameters() |
238 | 238 |
self.changes = UsableChanges() |
239 | 239 |
|
... | ... |
@@ -243,7 +223,7 @@ class ModuleManager(object): |
243 | 243 |
if getattr(self.want, key) is not None: |
244 | 244 |
changed[key] = getattr(self.want, key) |
245 | 245 |
if changed: |
246 |
- self.changes = UsableChanges(changed) |
|
246 |
+ self.changes = UsableChanges(params=changed) |
|
247 | 247 |
|
248 | 248 |
def _update_changed_options(self): |
249 | 249 |
diff = Difference(self.want, self.have) |
... | ... |
@@ -259,7 +239,7 @@ class ModuleManager(object): |
259 | 259 |
else: |
260 | 260 |
changed[k] = change |
261 | 261 |
if changed: |
262 |
- self.changes = UsableChanges(changed) |
|
262 |
+ self.changes = UsableChanges(params=changed) |
|
263 | 263 |
return True |
264 | 264 |
return False |
265 | 265 |
|
... | ... |
@@ -282,7 +262,7 @@ class ModuleManager(object): |
282 | 282 |
except iControlUnexpectedHTTPError as e: |
283 | 283 |
raise F5ModuleError(str(e)) |
284 | 284 |
|
285 |
- reportable = ReportableChanges(self.changes.to_return()) |
|
285 |
+ reportable = ReportableChanges(params=self.changes.to_return()) |
|
286 | 286 |
changes = reportable.to_return() |
287 | 287 |
result.update(**changes) |
288 | 288 |
result.update(dict(changed=changed)) |
... | ... |
@@ -292,7 +272,7 @@ class ModuleManager(object): |
292 | 292 |
def _announce_deprecations(self, result): |
293 | 293 |
warnings = result.pop('__warnings', []) |
294 | 294 |
for warning in warnings: |
295 |
- self.client.module.deprecate( |
|
295 |
+ self.module.deprecate( |
|
296 | 296 |
msg=warning['msg'], |
297 | 297 |
version=warning['version'] |
298 | 298 |
) |
... | ... |
@@ -316,13 +296,13 @@ class ModuleManager(object): |
316 | 316 |
self.have = self.read_current_from_device() |
317 | 317 |
if not self.should_update(): |
318 | 318 |
return False |
319 |
- if self.client.check_mode: |
|
319 |
+ if self.module.check_mode: |
|
320 | 320 |
return True |
321 | 321 |
self.update_on_device() |
322 | 322 |
return True |
323 | 323 |
|
324 | 324 |
def remove(self): |
325 |
- if self.client.check_mode: |
|
325 |
+ if self.module.check_mode: |
|
326 | 326 |
return True |
327 | 327 |
self.remove_from_device() |
328 | 328 |
if self.exists(): |
... | ... |
@@ -331,7 +311,7 @@ class ModuleManager(object): |
331 | 331 |
|
332 | 332 |
def create(self): |
333 | 333 |
self._set_changed_options() |
334 |
- if self.client.check_mode: |
|
334 |
+ if self.module.check_mode: |
|
335 | 335 |
return True |
336 | 336 |
if self.want.accept_eula is False: |
337 | 337 |
raise F5ModuleError( |
... | ... |
@@ -401,42 +381,48 @@ class ModuleManager(object): |
401 | 401 |
if resource is None: |
402 | 402 |
return False |
403 | 403 |
result = resource.attrs |
404 |
- return ApiParameters(result) |
|
404 |
+ return ApiParameters(params=result) |
|
405 | 405 |
|
406 | 406 |
|
407 | 407 |
class ArgumentSpec(object): |
408 | 408 |
def __init__(self): |
409 | 409 |
self.supports_check_mode = True |
410 |
- self.argument_spec = dict( |
|
410 |
+ argument_spec = dict( |
|
411 | 411 |
regkey_pool=dict(required=True), |
412 | 412 |
license_key=dict(required=True, no_log=True), |
413 | 413 |
description=dict(), |
414 |
- accept_eula=dict(type='bool') |
|
414 |
+ accept_eula=dict(type='bool'), |
|
415 |
+ state=dict( |
|
416 |
+ default='present', |
|
417 |
+ choices=['present', 'absent'] |
|
418 |
+ ), |
|
415 | 419 |
) |
416 |
- self.f5_product_name = 'bigiq' |
|
420 |
+ self.argument_spec = {} |
|
421 |
+ self.argument_spec.update(f5_argument_spec) |
|
422 |
+ self.argument_spec.update(argument_spec) |
|
417 | 423 |
self.required_if = [ |
418 | 424 |
['state', 'present', ['accept_eula']] |
419 | 425 |
] |
420 | 426 |
|
421 | 427 |
|
422 | 428 |
def main(): |
423 |
- if not HAS_F5SDK: |
|
424 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
425 |
- |
|
426 | 429 |
spec = ArgumentSpec() |
427 | 430 |
|
428 |
- client = AnsibleF5Client( |
|
431 |
+ module = AnsibleModule( |
|
429 | 432 |
argument_spec=spec.argument_spec, |
430 | 433 |
supports_check_mode=spec.supports_check_mode, |
431 |
- f5_product_name=spec.f5_product_name |
|
434 |
+ required_if=spec.required_if |
|
432 | 435 |
) |
436 |
+ if not HAS_F5SDK: |
|
437 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
433 | 438 |
|
434 | 439 |
try: |
435 |
- mm = ModuleManager(client) |
|
440 |
+ client = F5Client(**module.params) |
|
441 |
+ mm = ModuleManager(module=module, client=client) |
|
436 | 442 |
results = mm.exec_module() |
437 |
- client.module.exit_json(**results) |
|
443 |
+ module.exit_json(**results) |
|
438 | 444 |
except F5ModuleError as e: |
439 |
- client.module.fail_json(msg=str(e)) |
|
445 |
+ module.fail_json(msg=str(e)) |
|
440 | 446 |
|
441 | 447 |
|
442 | 448 |
if __name__ == '__main__': |
... | ... |
@@ -69,18 +69,37 @@ description: |
69 | 69 |
sample: My description |
70 | 70 |
''' |
71 | 71 |
|
72 |
+from ansible.module_utils.basic import AnsibleModule |
|
72 | 73 |
|
73 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
74 |
-from ansible.module_utils.f5_utils import AnsibleF5Parameters |
|
75 |
-from ansible.module_utils.f5_utils import HAS_F5SDK |
|
76 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
77 |
-from ansible.module_utils.six import iteritems |
|
78 |
-from collections import defaultdict |
|
74 |
+HAS_DEVEL_IMPORTS = False |
|
79 | 75 |
|
80 | 76 |
try: |
81 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
77 |
+ # Sideband repository used for dev |
|
78 |
+ from library.module_utils.network.f5.bigiq import HAS_F5SDK |
|
79 |
+ from library.module_utils.network.f5.bigiq import F5Client |
|
80 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
81 |
+ from library.module_utils.network.f5.common import AnsibleF5Parameters |
|
82 |
+ from library.module_utils.network.f5.common import cleanup_tokens |
|
83 |
+ from library.module_utils.network.f5.common import fqdn_name |
|
84 |
+ from library.module_utils.network.f5.common import f5_argument_spec |
|
85 |
+ try: |
|
86 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
87 |
+ except ImportError: |
|
88 |
+ HAS_F5SDK = False |
|
89 |
+ HAS_DEVEL_IMPORTS = True |
|
82 | 90 |
except ImportError: |
83 |
- HAS_F5SDK = False |
|
91 |
+ # Upstream Ansible |
|
92 |
+ from ansible.module_utils.network.f5.bigiq import HAS_F5SDK |
|
93 |
+ from ansible.module_utils.network.f5.bigiq import F5Client |
|
94 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
95 |
+ from ansible.module_utils.network.f5.common import AnsibleF5Parameters |
|
96 |
+ from ansible.module_utils.network.f5.common import cleanup_tokens |
|
97 |
+ from ansible.module_utils.network.f5.common import fqdn_name |
|
98 |
+ from ansible.module_utils.network.f5.common import f5_argument_spec |
|
99 |
+ try: |
|
100 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
101 |
+ except ImportError: |
|
102 |
+ HAS_F5SDK = False |
|
84 | 103 |
|
85 | 104 |
|
86 | 105 |
class Parameters(AnsibleF5Parameters): |
... | ... |
@@ -100,36 +119,6 @@ class Parameters(AnsibleF5Parameters): |
100 | 100 |
'description' |
101 | 101 |
] |
102 | 102 |
|
103 |
- def __init__(self, params=None): |
|
104 |
- self._values = defaultdict(lambda: None) |
|
105 |
- self._values['__warnings'] = [] |
|
106 |
- if params: |
|
107 |
- self.update(params=params) |
|
108 |
- |
|
109 |
- def update(self, params=None): |
|
110 |
- if params: |
|
111 |
- for k, v in iteritems(params): |
|
112 |
- if self.api_map is not None and k in self.api_map: |
|
113 |
- map_key = self.api_map[k] |
|
114 |
- else: |
|
115 |
- map_key = k |
|
116 |
- |
|
117 |
- # Handle weird API parameters like `dns.proxy.__iter__` by |
|
118 |
- # using a map provided by the module developer |
|
119 |
- class_attr = getattr(type(self), map_key, None) |
|
120 |
- if isinstance(class_attr, property): |
|
121 |
- # There is a mapped value for the api_map key |
|
122 |
- if class_attr.fset is None: |
|
123 |
- # If the mapped value does not have |
|
124 |
- # an associated setter |
|
125 |
- self._values[map_key] = v |
|
126 |
- else: |
|
127 |
- # The mapped value has a setter |
|
128 |
- setattr(self, map_key, v) |
|
129 |
- else: |
|
130 |
- # If the mapped value is not a @property |
|
131 |
- self._values[map_key] = v |
|
132 |
- |
|
133 | 103 |
def to_return(self): |
134 | 104 |
result = {} |
135 | 105 |
try: |
... | ... |
@@ -140,16 +129,6 @@ class Parameters(AnsibleF5Parameters): |
140 | 140 |
pass |
141 | 141 |
return result |
142 | 142 |
|
143 |
- def api_params(self): |
|
144 |
- result = {} |
|
145 |
- for api_attribute in self.api_attributes: |
|
146 |
- if self.api_map is not None and api_attribute in self.api_map: |
|
147 |
- result[api_attribute] = getattr(self, self.api_map[api_attribute]) |
|
148 |
- else: |
|
149 |
- result[api_attribute] = getattr(self, api_attribute) |
|
150 |
- result = self._filter_params(result) |
|
151 |
- return result |
|
152 |
- |
|
153 | 143 |
|
154 | 144 |
class ModuleParameters(Parameters): |
155 | 145 |
@property |
... | ... |
@@ -214,10 +193,10 @@ class Difference(object): |
214 | 214 |
|
215 | 215 |
|
216 | 216 |
class ModuleManager(object): |
217 |
- def __init__(self, client): |
|
218 |
- self.client = client |
|
219 |
- self.want = ModuleParameters(self.client.module.params) |
|
220 |
- self.want.update({'client': client}) |
|
217 |
+ def __init__(self, *args, **kwargs): |
|
218 |
+ self.module = kwargs.get('module', None) |
|
219 |
+ self.client = kwargs.get('client', None) |
|
220 |
+ self.want = ModuleParameters(client=self.client, params=self.module.params) |
|
221 | 221 |
self.have = ApiParameters() |
222 | 222 |
self.changes = UsableChanges() |
223 | 223 |
|
... | ... |
@@ -227,7 +206,7 @@ class ModuleManager(object): |
227 | 227 |
if getattr(self.want, key) is not None: |
228 | 228 |
changed[key] = getattr(self.want, key) |
229 | 229 |
if changed: |
230 |
- self.changes = UsableChanges(changed) |
|
230 |
+ self.changes = UsableChanges(params=changed) |
|
231 | 231 |
|
232 | 232 |
def _update_changed_options(self): |
233 | 233 |
diff = Difference(self.want, self.have) |
... | ... |
@@ -243,7 +222,7 @@ class ModuleManager(object): |
243 | 243 |
else: |
244 | 244 |
changed[k] = change |
245 | 245 |
if changed: |
246 |
- self.changes = Changes(changed) |
|
246 |
+ self.changes = Changes(params=changed) |
|
247 | 247 |
return True |
248 | 248 |
return False |
249 | 249 |
|
... | ... |
@@ -266,7 +245,7 @@ class ModuleManager(object): |
266 | 266 |
except iControlUnexpectedHTTPError as e: |
267 | 267 |
raise F5ModuleError(str(e)) |
268 | 268 |
|
269 |
- reportable = ReportableChanges(self.changes.to_return()) |
|
269 |
+ reportable = ReportableChanges(params=self.changes.to_return()) |
|
270 | 270 |
changes = reportable.to_return() |
271 | 271 |
result.update(**changes) |
272 | 272 |
result.update(dict(changed=changed)) |
... | ... |
@@ -276,7 +255,7 @@ class ModuleManager(object): |
276 | 276 |
def _announce_deprecations(self, result): |
277 | 277 |
warnings = result.pop('__warnings', []) |
278 | 278 |
for warning in warnings: |
279 |
- self.client.module.deprecate( |
|
279 |
+ self.module.deprecate( |
|
280 | 280 |
msg=warning['msg'], |
281 | 281 |
version=warning['version'] |
282 | 282 |
) |
... | ... |
@@ -297,13 +276,13 @@ class ModuleManager(object): |
297 | 297 |
self.have = self.read_current_from_device() |
298 | 298 |
if not self.should_update(): |
299 | 299 |
return False |
300 |
- if self.client.check_mode: |
|
300 |
+ if self.module.check_mode: |
|
301 | 301 |
return True |
302 | 302 |
self.update_on_device() |
303 | 303 |
return True |
304 | 304 |
|
305 | 305 |
def remove(self): |
306 |
- if self.client.check_mode: |
|
306 |
+ if self.module.check_mode: |
|
307 | 307 |
return True |
308 | 308 |
self.remove_from_device() |
309 | 309 |
if self.exists(): |
... | ... |
@@ -312,7 +291,7 @@ class ModuleManager(object): |
312 | 312 |
|
313 | 313 |
def create(self): |
314 | 314 |
self._set_changed_options() |
315 |
- if self.client.check_mode: |
|
315 |
+ if self.module.check_mode: |
|
316 | 316 |
return True |
317 | 317 |
self.create_on_device() |
318 | 318 |
return True |
... | ... |
@@ -348,13 +327,13 @@ class ModuleManager(object): |
348 | 348 |
id=self.want.uuid |
349 | 349 |
) |
350 | 350 |
result = resource.attrs |
351 |
- return ApiParameters(result) |
|
351 |
+ return ApiParameters(params=result) |
|
352 | 352 |
|
353 | 353 |
|
354 | 354 |
class ArgumentSpec(object): |
355 | 355 |
def __init__(self): |
356 | 356 |
self.supports_check_mode = True |
357 |
- self.argument_spec = dict( |
|
357 |
+ argument_spec = dict( |
|
358 | 358 |
name=dict(required=True), |
359 | 359 |
description=dict(), |
360 | 360 |
state=dict( |
... | ... |
@@ -362,27 +341,28 @@ class ArgumentSpec(object): |
362 | 362 |
choices=['absent', 'present'] |
363 | 363 |
) |
364 | 364 |
) |
365 |
- self.f5_product_name = 'bigiq' |
|
365 |
+ self.argument_spec = {} |
|
366 |
+ self.argument_spec.update(f5_argument_spec) |
|
367 |
+ self.argument_spec.update(argument_spec) |
|
366 | 368 |
|
367 | 369 |
|
368 | 370 |
def main(): |
369 |
- if not HAS_F5SDK: |
|
370 |
- raise F5ModuleError("The python f5-sdk module is required") |
|
371 |
- |
|
372 | 371 |
spec = ArgumentSpec() |
373 | 372 |
|
374 |
- client = AnsibleF5Client( |
|
373 |
+ module = AnsibleModule( |
|
375 | 374 |
argument_spec=spec.argument_spec, |
376 |
- supports_check_mode=spec.supports_check_mode, |
|
377 |
- f5_product_name=spec.f5_product_name |
|
375 |
+ supports_check_mode=spec.supports_check_mode |
|
378 | 376 |
) |
377 |
+ if not HAS_F5SDK: |
|
378 |
+ module.fail_json(msg="The python f5-sdk module is required") |
|
379 | 379 |
|
380 | 380 |
try: |
381 |
- mm = ModuleManager(client) |
|
381 |
+ client = F5Client(**module.params) |
|
382 |
+ mm = ModuleManager(module=module, client=client) |
|
382 | 383 |
results = mm.exec_module() |
383 |
- client.module.exit_json(**results) |
|
384 |
+ module.exit_json(**results) |
|
384 | 385 |
except F5ModuleError as e: |
385 |
- client.module.fail_json(msg=str(e)) |
|
386 |
+ module.fail_json(msg=str(e)) |
|
386 | 387 |
|
387 | 388 |
|
388 | 389 |
if __name__ == '__main__': |
... | ... |
@@ -41,18 +41,6 @@ lib/ansible/modules/net_tools/cloudflare_dns.py E317 |
41 | 41 |
lib/ansible/modules/net_tools/haproxy.py E317 |
42 | 42 |
lib/ansible/modules/net_tools/omapi_host.py E317 |
43 | 43 |
lib/ansible/modules/network/cloudengine/ce_reboot.py E317 |
44 |
-lib/ansible/modules/network/f5/bigip_sys_db.py E321 |
|
45 |
-lib/ansible/modules/network/f5/bigip_sys_global.py E321 |
|
46 |
-lib/ansible/modules/network/f5/bigip_traffic_group.py E321 |
|
47 |
-lib/ansible/modules/network/f5/bigip_ucs.py E321 |
|
48 |
-lib/ansible/modules/network/f5/bigip_user.py E321 |
|
49 |
-lib/ansible/modules/network/f5/bigip_vcmp_guest.py E321 |
|
50 |
-lib/ansible/modules/network/f5/bigip_virtual_address.py E321 |
|
51 |
-lib/ansible/modules/network/f5/bigip_virtual_server.py E321 |
|
52 |
-lib/ansible/modules/network/f5/bigip_vlan.py E321 |
|
53 |
-lib/ansible/modules/network/f5/bigip_wait.py E321 |
|
54 |
-lib/ansible/modules/network/f5/bigiq_regkey_license.py E321 |
|
55 |
-lib/ansible/modules/network/f5/bigiq_regkey_pool.py E321 |
|
56 | 44 |
lib/ansible/modules/network/illumos/dladm_linkprop.py E317 |
57 | 45 |
lib/ansible/modules/network/illumos/ipadm_addrprop.py E317 |
58 | 46 |
lib/ansible/modules/network/illumos/ipadm_ifprop.py E317 |
59 | 47 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,15 @@ |
0 |
+{ |
|
1 |
+ "kind": "tm:net:vlan:interfaces:interfacescollectionstate", |
|
2 |
+ "selfLink": "https://localhost/mgmt/tm/net/vlan/~Common~vlan1/interfaces?ver=13.0.0", |
|
3 |
+ "items": [ |
|
4 |
+ { |
|
5 |
+ "kind": "tm:net:vlan:interfaces:interfacesstate", |
|
6 |
+ "name": "1.2", |
|
7 |
+ "fullPath": "1.2", |
|
8 |
+ "generation": 105, |
|
9 |
+ "selfLink": "https://localhost/mgmt/tm/net/vlan/~Common~vlan1/interfaces/1.2?ver=13.0.0", |
|
10 |
+ "tagMode": "none", |
|
11 |
+ "tagged": true |
|
12 |
+ } |
|
13 |
+ ] |
|
14 |
+} |
... | ... |
@@ -17,20 +17,22 @@ if sys.version_info < (2, 7): |
17 | 17 |
from ansible.compat.tests import unittest |
18 | 18 |
from ansible.compat.tests.mock import Mock |
19 | 19 |
from ansible.compat.tests.mock import patch |
20 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
20 |
+from ansible.module_utils.basic import AnsibleModule |
|
21 | 21 |
|
22 | 22 |
try: |
23 | 23 |
from library.bigip_sys_db import Parameters |
24 | 24 |
from library.bigip_sys_db import ModuleManager |
25 | 25 |
from library.bigip_sys_db import ArgumentSpec |
26 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
26 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
27 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
27 | 28 |
from test.unit.modules.utils import set_module_args |
28 | 29 |
except ImportError: |
29 | 30 |
try: |
30 | 31 |
from ansible.modules.network.f5.bigip_sys_db import Parameters |
31 | 32 |
from ansible.modules.network.f5.bigip_sys_db import ModuleManager |
32 | 33 |
from ansible.modules.network.f5.bigip_sys_db import ArgumentSpec |
33 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
34 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
35 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
34 | 36 |
from units.modules.utils import set_module_args |
35 | 37 |
except ImportError: |
36 | 38 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -66,7 +68,7 @@ class TestParameters(unittest.TestCase): |
66 | 66 |
server='localhost', |
67 | 67 |
user='admin' |
68 | 68 |
) |
69 |
- p = Parameters(args) |
|
69 |
+ p = Parameters(params=args) |
|
70 | 70 |
assert p.key == 'foo' |
71 | 71 |
assert p.value == 'bar' |
72 | 72 |
|
... | ... |
@@ -80,13 +82,11 @@ class TestParameters(unittest.TestCase): |
80 | 80 |
user='admin' |
81 | 81 |
|
82 | 82 |
) |
83 |
- p = Parameters(args) |
|
83 |
+ p = Parameters(params=args) |
|
84 | 84 |
assert p.key == 'foo' |
85 | 85 |
assert p.value == 'bar' |
86 | 86 |
|
87 | 87 |
|
88 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
89 |
- return_value=True) |
|
90 | 88 |
class TestManager(unittest.TestCase): |
91 | 89 |
|
92 | 90 |
def setUp(self): |
... | ... |
@@ -118,12 +118,11 @@ class TestManager(unittest.TestCase): |
118 | 118 |
) |
119 | 119 |
) |
120 | 120 |
|
121 |
- client = AnsibleF5Client( |
|
121 |
+ module = AnsibleModule( |
|
122 | 122 |
argument_spec=self.spec.argument_spec, |
123 |
- supports_check_mode=self.spec.supports_check_mode, |
|
124 |
- f5_product_name=self.spec.f5_product_name |
|
123 |
+ supports_check_mode=self.spec.supports_check_mode |
|
125 | 124 |
) |
126 |
- mm = ModuleManager(client) |
|
125 |
+ mm = ModuleManager(module=module) |
|
127 | 126 |
|
128 | 127 |
# Override methods to force specific logic in the module to happen |
129 | 128 |
mm.exists = Mock(return_value=False) |
... | ... |
@@ -17,14 +17,15 @@ if sys.version_info < (2, 7): |
17 | 17 |
from ansible.compat.tests import unittest |
18 | 18 |
from ansible.compat.tests.mock import Mock |
19 | 19 |
from ansible.compat.tests.mock import patch |
20 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
20 |
+from ansible.module_utils.basic import AnsibleModule |
|
21 | 21 |
|
22 | 22 |
try: |
23 | 23 |
from library.bigip_sys_global import ApiParameters |
24 | 24 |
from library.bigip_sys_global import ModuleParameters |
25 | 25 |
from library.bigip_sys_global import ModuleManager |
26 | 26 |
from library.bigip_sys_global import ArgumentSpec |
27 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
27 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
28 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
28 | 29 |
from test.unit.modules.utils import set_module_args |
29 | 30 |
except ImportError: |
30 | 31 |
try: |
... | ... |
@@ -32,7 +33,8 @@ except ImportError: |
32 | 32 |
from ansible.modules.network.f5.bigip_sys_global import ModuleParameters |
33 | 33 |
from ansible.modules.network.f5.bigip_sys_global import ModuleManager |
34 | 34 |
from ansible.modules.network.f5.bigip_sys_global import ArgumentSpec |
35 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
35 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
36 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
36 | 37 |
from units.modules.utils import set_module_args |
37 | 38 |
except ImportError: |
38 | 39 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -71,7 +73,7 @@ class TestParameters(unittest.TestCase): |
71 | 71 |
quiet_boot='yes', |
72 | 72 |
security_banner='yes', |
73 | 73 |
) |
74 |
- p = ModuleParameters(args) |
|
74 |
+ p = ModuleParameters(params=args) |
|
75 | 75 |
assert p.banner_text == 'this is a banner' |
76 | 76 |
assert p.console_timeout == 100 |
77 | 77 |
assert p.gui_setup == 'enabled' |
... | ... |
@@ -83,7 +85,7 @@ class TestParameters(unittest.TestCase): |
83 | 83 |
|
84 | 84 |
def test_api_parameters(self): |
85 | 85 |
args = load_fixture('load_sys_global_settings.json') |
86 |
- p = ApiParameters(args) |
|
86 |
+ p = ApiParameters(params=args) |
|
87 | 87 |
assert 'Welcome to the BIG-IP Configuration Utility' in p.banner_text |
88 | 88 |
assert p.console_timeout == 0 |
89 | 89 |
assert p.gui_setup == 'disabled' |
... | ... |
@@ -94,8 +96,6 @@ class TestParameters(unittest.TestCase): |
94 | 94 |
assert p.security_banner == 'enabled' |
95 | 95 |
|
96 | 96 |
|
97 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
98 |
- return_value=True) |
|
99 | 97 |
class TestManager(unittest.TestCase): |
100 | 98 |
|
101 | 99 |
def setUp(self): |
... | ... |
@@ -113,14 +113,13 @@ class TestManager(unittest.TestCase): |
113 | 113 |
|
114 | 114 |
# Configure the parameters that would be returned by querying the |
115 | 115 |
# remote device |
116 |
- current = ApiParameters(load_fixture('load_sys_global_settings.json')) |
|
116 |
+ current = ApiParameters(params=load_fixture('load_sys_global_settings.json')) |
|
117 | 117 |
|
118 |
- client = AnsibleF5Client( |
|
118 |
+ module = AnsibleModule( |
|
119 | 119 |
argument_spec=self.spec.argument_spec, |
120 |
- supports_check_mode=self.spec.supports_check_mode, |
|
121 |
- f5_product_name=self.spec.f5_product_name |
|
120 |
+ supports_check_mode=self.spec.supports_check_mode |
|
122 | 121 |
) |
123 |
- mm = ModuleManager(client) |
|
122 |
+ mm = ModuleManager(module=module) |
|
124 | 123 |
|
125 | 124 |
# Override methods to force specific logic in the module to happen |
126 | 125 |
mm.exists = Mock(return_value=False) |
... | ... |
@@ -18,21 +18,22 @@ if sys.version_info < (2, 7): |
18 | 18 |
from ansible.compat.tests import unittest |
19 | 19 |
from ansible.compat.tests.mock import Mock |
20 | 20 |
from ansible.compat.tests.mock import patch |
21 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
22 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
21 |
+from ansible.module_utils.basic import AnsibleModule |
|
23 | 22 |
|
24 | 23 |
try: |
25 | 24 |
from library.bigip_traffic_group import Parameters |
26 | 25 |
from library.bigip_traffic_group import ModuleManager |
27 | 26 |
from library.bigip_traffic_group import ArgumentSpec |
28 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
27 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
28 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
29 | 29 |
from test.unit.modules.utils import set_module_args |
30 | 30 |
except ImportError: |
31 | 31 |
try: |
32 | 32 |
from ansible.modules.network.f5.bigip_traffic_group import Parameters |
33 | 33 |
from ansible.modules.network.f5.bigip_traffic_group import ModuleManager |
34 | 34 |
from ansible.modules.network.f5.bigip_traffic_group import ArgumentSpec |
35 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
35 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
36 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
36 | 37 |
from units.modules.utils import set_module_args |
37 | 38 |
except ImportError: |
38 | 39 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -65,12 +66,10 @@ class TestParameters(unittest.TestCase): |
65 | 65 |
name='foo' |
66 | 66 |
) |
67 | 67 |
|
68 |
- p = Parameters(args) |
|
68 |
+ p = Parameters(params=args) |
|
69 | 69 |
assert p.name == 'foo' |
70 | 70 |
|
71 | 71 |
|
72 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
73 |
- return_value=True) |
|
74 | 72 |
class TestManager(unittest.TestCase): |
75 | 73 |
|
76 | 74 |
def setUp(self): |
... | ... |
@@ -84,13 +83,12 @@ class TestManager(unittest.TestCase): |
84 | 84 |
user='admin' |
85 | 85 |
)) |
86 | 86 |
|
87 |
- client = AnsibleF5Client( |
|
87 |
+ module = AnsibleModule( |
|
88 | 88 |
argument_spec=self.spec.argument_spec, |
89 |
- supports_check_mode=self.spec.supports_check_mode, |
|
90 |
- f5_product_name=self.spec.f5_product_name |
|
89 |
+ supports_check_mode=self.spec.supports_check_mode |
|
91 | 90 |
) |
92 | 91 |
|
93 |
- mm = ModuleManager(client) |
|
92 |
+ mm = ModuleManager(module=module) |
|
94 | 93 |
mm.create_on_device = Mock(return_value=True) |
95 | 94 |
mm.exists = Mock(return_value=False) |
96 | 95 |
|
... | ... |
@@ -18,8 +18,7 @@ if sys.version_info < (2, 7): |
18 | 18 |
from ansible.compat.tests import unittest |
19 | 19 |
from ansible.compat.tests.mock import Mock |
20 | 20 |
from ansible.compat.tests.mock import patch |
21 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
22 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
21 |
+from ansible.module_utils.basic import AnsibleModule |
|
23 | 22 |
|
24 | 23 |
try: |
25 | 24 |
from library.bigip_ucs import Parameters |
... | ... |
@@ -27,7 +26,8 @@ try: |
27 | 27 |
from library.bigip_ucs import ArgumentSpec |
28 | 28 |
from library.bigip_ucs import V1Manager |
29 | 29 |
from library.bigip_ucs import V2Manager |
30 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
30 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
31 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
31 | 32 |
from test.unit.modules.utils import set_module_args |
32 | 33 |
except ImportError: |
33 | 34 |
try: |
... | ... |
@@ -36,7 +36,8 @@ except ImportError: |
36 | 36 |
from ansible.modules.network.f5.bigip_ucs import ArgumentSpec |
37 | 37 |
from ansible.modules.network.f5.bigip_ucs import V1Manager |
38 | 38 |
from ansible.modules.network.f5.bigip_ucs import V2Manager |
39 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
39 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
40 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
40 | 41 |
from units.modules.utils import set_module_args |
41 | 42 |
except ImportError: |
42 | 43 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -76,7 +77,7 @@ class TestParameters(unittest.TestCase): |
76 | 76 |
state='installed' |
77 | 77 |
) |
78 | 78 |
|
79 |
- p = Parameters(args) |
|
79 |
+ p = Parameters(params=args) |
|
80 | 80 |
assert p.ucs == '/root/bigip.localhost.localdomain.ucs' |
81 | 81 |
assert p.force is True |
82 | 82 |
assert p.include_chassis_level_config is True |
... | ... |
@@ -98,7 +99,7 @@ class TestParameters(unittest.TestCase): |
98 | 98 |
reset_trust=False |
99 | 99 |
) |
100 | 100 |
|
101 |
- p = Parameters(args) |
|
101 |
+ p = Parameters(params=args) |
|
102 | 102 |
assert p.ucs == '/root/bigip.localhost.localdomain.ucs' |
103 | 103 |
assert p.include_chassis_level_config is False |
104 | 104 |
assert p.no_license is False |
... | ... |
@@ -107,8 +108,6 @@ class TestParameters(unittest.TestCase): |
107 | 107 |
assert p.install_command == "tmsh load sys ucs /var/local/ucs/bigip.localhost.localdomain.ucs" |
108 | 108 |
|
109 | 109 |
|
110 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
111 |
- return_value=True) |
|
112 | 110 |
class TestV1Manager(unittest.TestCase): |
113 | 111 |
|
114 | 112 |
def setUp(self): |
... | ... |
@@ -122,17 +121,16 @@ class TestV1Manager(unittest.TestCase): |
122 | 122 |
user='admin' |
123 | 123 |
)) |
124 | 124 |
|
125 |
- client = AnsibleF5Client( |
|
125 |
+ module = AnsibleModule( |
|
126 | 126 |
argument_spec=self.spec.argument_spec, |
127 |
- supports_check_mode=self.spec.supports_check_mode, |
|
128 |
- f5_product_name=self.spec.f5_product_name |
|
127 |
+ supports_check_mode=self.spec.supports_check_mode |
|
129 | 128 |
) |
130 | 129 |
|
131 | 130 |
# Override methods to force specific logic in the module to happen |
132 |
- mm = ModuleManager(client) |
|
131 |
+ mm = ModuleManager(module=module) |
|
133 | 132 |
mm.is_version_v1 = Mock(return_value=True) |
134 | 133 |
|
135 |
- vm = V1Manager(client) |
|
134 |
+ vm = V1Manager(module=module) |
|
136 | 135 |
vm.create_on_device = Mock(return_value=True) |
137 | 136 |
vm.exists = Mock(side_effect=[False, True]) |
138 | 137 |
|
... | ... |
@@ -149,17 +147,16 @@ class TestV1Manager(unittest.TestCase): |
149 | 149 |
state='present' |
150 | 150 |
)) |
151 | 151 |
|
152 |
- client = AnsibleF5Client( |
|
152 |
+ module = AnsibleModule( |
|
153 | 153 |
argument_spec=self.spec.argument_spec, |
154 |
- supports_check_mode=self.spec.supports_check_mode, |
|
155 |
- f5_product_name=self.spec.f5_product_name |
|
154 |
+ supports_check_mode=self.spec.supports_check_mode |
|
156 | 155 |
) |
157 | 156 |
|
158 | 157 |
# Override methods to force specific logic in the module to happen |
159 |
- mm = ModuleManager(client) |
|
158 |
+ mm = ModuleManager(module=module) |
|
160 | 159 |
mm.is_version_v1 = Mock(return_value=True) |
161 | 160 |
|
162 |
- vm = V1Manager(client) |
|
161 |
+ vm = V1Manager(module=module) |
|
163 | 162 |
vm.create_on_device = Mock(return_value=True) |
164 | 163 |
vm.exists = Mock(side_effect=[False, True]) |
165 | 164 |
|
... | ... |
@@ -176,17 +173,16 @@ class TestV1Manager(unittest.TestCase): |
176 | 176 |
state='installed' |
177 | 177 |
)) |
178 | 178 |
|
179 |
- client = AnsibleF5Client( |
|
179 |
+ module = AnsibleModule( |
|
180 | 180 |
argument_spec=self.spec.argument_spec, |
181 |
- supports_check_mode=self.spec.supports_check_mode, |
|
182 |
- f5_product_name=self.spec.f5_product_name |
|
181 |
+ supports_check_mode=self.spec.supports_check_mode |
|
183 | 182 |
) |
184 | 183 |
|
185 | 184 |
# Override methods to force specific logic in the module to happen |
186 |
- mm = ModuleManager(client) |
|
185 |
+ mm = ModuleManager(module=module) |
|
187 | 186 |
mm.is_version_v1 = Mock(return_value=True) |
188 | 187 |
|
189 |
- vm = V1Manager(client) |
|
188 |
+ vm = V1Manager(module=module) |
|
190 | 189 |
vm.create_on_device = Mock(return_value=True) |
191 | 190 |
vm.exists = Mock(return_value=True) |
192 | 191 |
vm.install_on_device = Mock(return_value=True) |
... | ... |
@@ -204,17 +200,16 @@ class TestV1Manager(unittest.TestCase): |
204 | 204 |
state='absent' |
205 | 205 |
)) |
206 | 206 |
|
207 |
- client = AnsibleF5Client( |
|
207 |
+ module = AnsibleModule( |
|
208 | 208 |
argument_spec=self.spec.argument_spec, |
209 |
- supports_check_mode=self.spec.supports_check_mode, |
|
210 |
- f5_product_name=self.spec.f5_product_name |
|
209 |
+ supports_check_mode=self.spec.supports_check_mode |
|
211 | 210 |
) |
212 | 211 |
|
213 | 212 |
# Override methods to force specific logic in the module to happen |
214 |
- mm = ModuleManager(client) |
|
213 |
+ mm = ModuleManager(module=module) |
|
215 | 214 |
mm.is_version_v1 = Mock(return_value=True) |
216 | 215 |
|
217 |
- vm = V1Manager(client) |
|
216 |
+ vm = V1Manager(module=module) |
|
218 | 217 |
vm.remove_from_device = Mock(return_value=True) |
219 | 218 |
vm.exists = Mock(side_effect=[True, False]) |
220 | 219 |
|
... | ... |
@@ -231,17 +226,16 @@ class TestV1Manager(unittest.TestCase): |
231 | 231 |
state='absent' |
232 | 232 |
)) |
233 | 233 |
|
234 |
- client = AnsibleF5Client( |
|
234 |
+ module = AnsibleModule( |
|
235 | 235 |
argument_spec=self.spec.argument_spec, |
236 |
- supports_check_mode=self.spec.supports_check_mode, |
|
237 |
- f5_product_name=self.spec.f5_product_name |
|
236 |
+ supports_check_mode=self.spec.supports_check_mode |
|
238 | 237 |
) |
239 | 238 |
|
240 | 239 |
# Override methods to force specific logic in the module to happen |
241 |
- mm = ModuleManager(client) |
|
240 |
+ mm = ModuleManager(module=module) |
|
242 | 241 |
mm.is_version_v1 = Mock(return_value=True) |
243 | 242 |
|
244 |
- vm = V1Manager(client) |
|
243 |
+ vm = V1Manager(module=module) |
|
245 | 244 |
vm.remove_from_device = Mock(return_value=True) |
246 | 245 |
vm.exists = Mock(side_effect=[True, True]) |
247 | 246 |
|
... | ... |
@@ -250,8 +244,6 @@ class TestV1Manager(unittest.TestCase): |
250 | 250 |
assert 'Failed to delete' in str(ex.value) |
251 | 251 |
|
252 | 252 |
|
253 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
254 |
- return_value=True) |
|
255 | 253 |
class TestV2Manager(unittest.TestCase): |
256 | 254 |
|
257 | 255 |
def setUp(self): |
... | ... |
@@ -265,17 +257,16 @@ class TestV2Manager(unittest.TestCase): |
265 | 265 |
user='admin' |
266 | 266 |
)) |
267 | 267 |
|
268 |
- client = AnsibleF5Client( |
|
268 |
+ module = AnsibleModule( |
|
269 | 269 |
argument_spec=self.spec.argument_spec, |
270 |
- supports_check_mode=self.spec.supports_check_mode, |
|
271 |
- f5_product_name=self.spec.f5_product_name |
|
270 |
+ supports_check_mode=self.spec.supports_check_mode |
|
272 | 271 |
) |
273 | 272 |
|
274 | 273 |
# Override methods to force specific logic in the module to happen |
275 |
- mm = ModuleManager(client) |
|
274 |
+ mm = ModuleManager(module=module) |
|
276 | 275 |
mm.is_version_v1 = Mock(return_value=False) |
277 | 276 |
|
278 |
- vm = V2Manager(client) |
|
277 |
+ vm = V2Manager(module=module) |
|
279 | 278 |
vm.create_on_device = Mock(return_value=True) |
280 | 279 |
vm.exists = Mock(side_effect=[False, True]) |
281 | 280 |
|
... | ... |
@@ -292,17 +283,16 @@ class TestV2Manager(unittest.TestCase): |
292 | 292 |
state='present' |
293 | 293 |
)) |
294 | 294 |
|
295 |
- client = AnsibleF5Client( |
|
295 |
+ module = AnsibleModule( |
|
296 | 296 |
argument_spec=self.spec.argument_spec, |
297 |
- supports_check_mode=self.spec.supports_check_mode, |
|
298 |
- f5_product_name=self.spec.f5_product_name |
|
297 |
+ supports_check_mode=self.spec.supports_check_mode |
|
299 | 298 |
) |
300 | 299 |
|
301 | 300 |
# Override methods to force specific logic in the module to happen |
302 |
- mm = ModuleManager(client) |
|
301 |
+ mm = ModuleManager(module=module) |
|
303 | 302 |
mm.is_version_v1 = Mock(return_value=False) |
304 | 303 |
|
305 |
- vm = V2Manager(client) |
|
304 |
+ vm = V2Manager(module=module) |
|
306 | 305 |
vm.create_on_device = Mock(return_value=True) |
307 | 306 |
vm.exists = Mock(side_effect=[False, True]) |
308 | 307 |
|
... | ... |
@@ -319,17 +309,16 @@ class TestV2Manager(unittest.TestCase): |
319 | 319 |
state='installed' |
320 | 320 |
)) |
321 | 321 |
|
322 |
- client = AnsibleF5Client( |
|
322 |
+ module = AnsibleModule( |
|
323 | 323 |
argument_spec=self.spec.argument_spec, |
324 |
- supports_check_mode=self.spec.supports_check_mode, |
|
325 |
- f5_product_name=self.spec.f5_product_name |
|
324 |
+ supports_check_mode=self.spec.supports_check_mode |
|
326 | 325 |
) |
327 | 326 |
|
328 | 327 |
# Override methods to force specific logic in the module to happen |
329 |
- mm = ModuleManager(client) |
|
328 |
+ mm = ModuleManager(module=module) |
|
330 | 329 |
mm.is_version_v1 = Mock(return_value=False) |
331 | 330 |
|
332 |
- vm = V2Manager(client) |
|
331 |
+ vm = V2Manager(module=module) |
|
333 | 332 |
vm.create_on_device = Mock(return_value=True) |
334 | 333 |
vm.exists = Mock(return_value=True) |
335 | 334 |
vm.install_on_device = Mock(return_value=True) |
... | ... |
@@ -347,17 +336,16 @@ class TestV2Manager(unittest.TestCase): |
347 | 347 |
state='absent' |
348 | 348 |
)) |
349 | 349 |
|
350 |
- client = AnsibleF5Client( |
|
350 |
+ module = AnsibleModule( |
|
351 | 351 |
argument_spec=self.spec.argument_spec, |
352 |
- supports_check_mode=self.spec.supports_check_mode, |
|
353 |
- f5_product_name=self.spec.f5_product_name |
|
352 |
+ supports_check_mode=self.spec.supports_check_mode |
|
354 | 353 |
) |
355 | 354 |
|
356 | 355 |
# Override methods to force specific logic in the module to happen |
357 |
- mm = ModuleManager(client) |
|
356 |
+ mm = ModuleManager(module=module) |
|
358 | 357 |
mm.is_version_v1 = Mock(return_value=False) |
359 | 358 |
|
360 |
- vm = V1Manager(client) |
|
359 |
+ vm = V1Manager(module=module) |
|
361 | 360 |
vm.remove_from_device = Mock(return_value=True) |
362 | 361 |
vm.exists = Mock(side_effect=[True, False]) |
363 | 362 |
|
... | ... |
@@ -374,17 +362,16 @@ class TestV2Manager(unittest.TestCase): |
374 | 374 |
state='absent' |
375 | 375 |
)) |
376 | 376 |
|
377 |
- client = AnsibleF5Client( |
|
377 |
+ module = AnsibleModule( |
|
378 | 378 |
argument_spec=self.spec.argument_spec, |
379 |
- supports_check_mode=self.spec.supports_check_mode, |
|
380 |
- f5_product_name=self.spec.f5_product_name |
|
379 |
+ supports_check_mode=self.spec.supports_check_mode |
|
381 | 380 |
) |
382 | 381 |
|
383 | 382 |
# Override methods to force specific logic in the module to happen |
384 |
- mm = ModuleManager(client) |
|
383 |
+ mm = ModuleManager(module=module) |
|
385 | 384 |
mm.is_version_v1 = Mock(return_value=False) |
386 | 385 |
|
387 |
- vm = V1Manager(client) |
|
386 |
+ vm = V1Manager(module=module) |
|
388 | 387 |
vm.remove_from_device = Mock(return_value=True) |
389 | 388 |
vm.exists = Mock(side_effect=[True, True]) |
390 | 389 |
|
... | ... |
@@ -18,8 +18,7 @@ if sys.version_info < (2, 7): |
18 | 18 |
from ansible.compat.tests import unittest |
19 | 19 |
from ansible.compat.tests.mock import Mock |
20 | 20 |
from ansible.compat.tests.mock import patch |
21 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
22 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
21 |
+from ansible.module_utils.basic import AnsibleModule |
|
23 | 22 |
|
24 | 23 |
try: |
25 | 24 |
from library.bigip_user import Parameters |
... | ... |
@@ -27,7 +26,8 @@ try: |
27 | 27 |
from library.bigip_user import ArgumentSpec |
28 | 28 |
from library.bigip_user import UnparitionedManager |
29 | 29 |
from library.bigip_user import PartitionedManager |
30 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
30 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
31 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
31 | 32 |
from test.unit.modules.utils import set_module_args |
32 | 33 |
except ImportError: |
33 | 34 |
try: |
... | ... |
@@ -36,7 +36,8 @@ except ImportError: |
36 | 36 |
from ansible.modules.network.f5.bigip_user import ArgumentSpec |
37 | 37 |
from ansible.modules.network.f5.bigip_user import UnparitionedManager |
38 | 38 |
from ansible.modules.network.f5.bigip_user import PartitionedManager |
39 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
39 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
40 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
40 | 41 |
from units.modules.utils import set_module_args |
41 | 42 |
except ImportError: |
42 | 43 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -74,7 +75,7 @@ class TestParameters(unittest.TestCase): |
74 | 74 |
update_password='always' |
75 | 75 |
) |
76 | 76 |
|
77 |
- p = Parameters(args) |
|
77 |
+ p = Parameters(params=args) |
|
78 | 78 |
assert p.username_credential == 'someuser' |
79 | 79 |
assert p.password_credential == 'testpass' |
80 | 80 |
assert p.full_name == 'Fake Person' |
... | ... |
@@ -91,7 +92,7 @@ class TestParameters(unittest.TestCase): |
91 | 91 |
shell='none' |
92 | 92 |
) |
93 | 93 |
|
94 |
- p = Parameters(args) |
|
94 |
+ p = Parameters(params=args) |
|
95 | 95 |
assert p.name == 'someuser' |
96 | 96 |
assert p.password == 'testpass' |
97 | 97 |
assert p.full_name == 'Fake Person' |
... | ... |
@@ -99,8 +100,6 @@ class TestParameters(unittest.TestCase): |
99 | 99 |
assert p.shell == 'none' |
100 | 100 |
|
101 | 101 |
|
102 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
103 |
- return_value=True) |
|
104 | 102 |
class TestManager(unittest.TestCase): |
105 | 103 |
|
106 | 104 |
def setUp(self): |
... | ... |
@@ -118,21 +117,21 @@ class TestManager(unittest.TestCase): |
118 | 118 |
update_password='on_create' |
119 | 119 |
)) |
120 | 120 |
|
121 |
- client = AnsibleF5Client( |
|
121 |
+ module = AnsibleModule( |
|
122 | 122 |
argument_spec=self.spec.argument_spec, |
123 |
- supports_check_mode=self.spec.supports_check_mode, |
|
124 |
- f5_product_name=self.spec.f5_product_name |
|
123 |
+ supports_check_mode=self.spec.supports_check_mode |
|
125 | 124 |
) |
126 | 125 |
|
127 | 126 |
# Override methods to force specific logic in the module to happen |
128 |
- mm = ModuleManager(client) |
|
129 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
130 |
- |
|
131 |
- pm = PartitionedManager(client) |
|
127 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
132 | 128 |
pm.create_on_device = Mock(return_value=True) |
133 | 129 |
pm.exists = Mock(return_value=False) |
134 | 130 |
|
135 |
- results = pm.exec_module() |
|
131 |
+ mm = ModuleManager(module=module) |
|
132 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
133 |
+ mm.get_manager = Mock(return_value=pm) |
|
134 |
+ |
|
135 |
+ results = mm.exec_module() |
|
136 | 136 |
|
137 | 137 |
assert results['changed'] is True |
138 | 138 |
assert results['partition_access'] == access |
... | ... |
@@ -147,21 +146,21 @@ class TestManager(unittest.TestCase): |
147 | 147 |
user='admin' |
148 | 148 |
)) |
149 | 149 |
|
150 |
- client = AnsibleF5Client( |
|
150 |
+ module = AnsibleModule( |
|
151 | 151 |
argument_spec=self.spec.argument_spec, |
152 |
- supports_check_mode=self.spec.supports_check_mode, |
|
153 |
- f5_product_name=self.spec.f5_product_name |
|
152 |
+ supports_check_mode=self.spec.supports_check_mode |
|
154 | 153 |
) |
155 | 154 |
|
156 | 155 |
# Override methods to force specific logic in the module to happen |
157 |
- mm = ModuleManager(client) |
|
158 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
159 |
- |
|
160 |
- pm = PartitionedManager(client) |
|
156 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
161 | 157 |
pm.create_on_device = Mock(return_value=True) |
162 | 158 |
pm.exists = Mock(return_value=False) |
163 | 159 |
|
164 |
- results = pm.exec_module() |
|
160 |
+ mm = ModuleManager(module=module) |
|
161 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
162 |
+ mm.get_manager = Mock(return_value=pm) |
|
163 |
+ |
|
164 |
+ results = mm.exec_module() |
|
165 | 165 |
|
166 | 166 |
assert results['changed'] is True |
167 | 167 |
assert results['partition_access'] == access |
... | ... |
@@ -177,26 +176,26 @@ class TestManager(unittest.TestCase): |
177 | 177 |
user='admin' |
178 | 178 |
)) |
179 | 179 |
|
180 |
- client = AnsibleF5Client( |
|
180 |
+ module = AnsibleModule( |
|
181 | 181 |
argument_spec=self.spec.argument_spec, |
182 |
- supports_check_mode=self.spec.supports_check_mode, |
|
183 |
- f5_product_name=self.spec.f5_product_name |
|
182 |
+ supports_check_mode=self.spec.supports_check_mode |
|
184 | 183 |
) |
185 | 184 |
|
186 | 185 |
# Override methods to force specific logic in the module to happen |
187 |
- mm = ModuleManager(client) |
|
188 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
189 |
- |
|
190 |
- pm = PartitionedManager(client) |
|
186 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
191 | 187 |
pm.create_on_device = Mock(return_value=True) |
192 | 188 |
pm.exists = Mock(return_value=False) |
193 | 189 |
|
190 |
+ mm = ModuleManager(module=module) |
|
191 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
192 |
+ mm.get_manager = Mock(return_value=pm) |
|
193 |
+ |
|
194 | 194 |
msg = "The 'update_password' option " \ |
195 | 195 |
"needs to be set to 'on_create' when creating " \ |
196 | 196 |
"a resource with a password." |
197 | 197 |
|
198 | 198 |
with pytest.raises(F5ModuleError) as ex: |
199 |
- pm.exec_module() |
|
199 |
+ mm.exec_module() |
|
200 | 200 |
assert str(ex.value) == msg |
201 | 201 |
|
202 | 202 |
def test_create_user_partition_access_raises(self, *args): |
... | ... |
@@ -207,25 +206,25 @@ class TestManager(unittest.TestCase): |
207 | 207 |
user='admin' |
208 | 208 |
)) |
209 | 209 |
|
210 |
- client = AnsibleF5Client( |
|
210 |
+ module = AnsibleModule( |
|
211 | 211 |
argument_spec=self.spec.argument_spec, |
212 |
- supports_check_mode=self.spec.supports_check_mode, |
|
213 |
- f5_product_name=self.spec.f5_product_name |
|
212 |
+ supports_check_mode=self.spec.supports_check_mode |
|
214 | 213 |
) |
215 | 214 |
|
216 | 215 |
# Override methods to force specific logic in the module to happen |
217 |
- mm = ModuleManager(client) |
|
218 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
219 |
- |
|
220 |
- pm = PartitionedManager(client) |
|
216 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
221 | 217 |
pm.create_on_device = Mock(return_value=True) |
222 | 218 |
pm.exists = Mock(return_value=False) |
223 | 219 |
|
220 |
+ mm = ModuleManager(module=module) |
|
221 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
222 |
+ mm.get_manager = Mock(return_value=pm) |
|
223 |
+ |
|
224 | 224 |
msg = "The 'partition_access' option " \ |
225 | 225 |
"is required when creating a resource." |
226 | 226 |
|
227 | 227 |
with pytest.raises(F5ModuleError) as ex: |
228 |
- pm.exec_module() |
|
228 |
+ mm.exec_module() |
|
229 | 229 |
assert str(ex.value) == msg |
230 | 230 |
|
231 | 231 |
def test_create_user_shell_bash(self, *args): |
... | ... |
@@ -241,21 +240,21 @@ class TestManager(unittest.TestCase): |
241 | 241 |
shell='bash' |
242 | 242 |
)) |
243 | 243 |
|
244 |
- client = AnsibleF5Client( |
|
244 |
+ module = AnsibleModule( |
|
245 | 245 |
argument_spec=self.spec.argument_spec, |
246 |
- supports_check_mode=self.spec.supports_check_mode, |
|
247 |
- f5_product_name=self.spec.f5_product_name |
|
246 |
+ supports_check_mode=self.spec.supports_check_mode |
|
248 | 247 |
) |
249 | 248 |
|
250 | 249 |
# Override methods to force specific logic in the module to happen |
251 |
- mm = ModuleManager(client) |
|
252 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
253 |
- |
|
254 |
- pm = PartitionedManager(client) |
|
250 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
255 | 251 |
pm.create_on_device = Mock(return_value=True) |
256 | 252 |
pm.exists = Mock(return_value=False) |
257 | 253 |
|
258 |
- results = pm.exec_module() |
|
254 |
+ mm = ModuleManager(module=module) |
|
255 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
256 |
+ mm.get_manager = Mock(return_value=pm) |
|
257 |
+ |
|
258 |
+ results = mm.exec_module() |
|
259 | 259 |
|
260 | 260 |
assert results['changed'] is True |
261 | 261 |
assert results['partition_access'] == access |
... | ... |
@@ -273,25 +272,25 @@ class TestManager(unittest.TestCase): |
273 | 273 |
shell='bash' |
274 | 274 |
)) |
275 | 275 |
|
276 |
- client = AnsibleF5Client( |
|
276 |
+ module = AnsibleModule( |
|
277 | 277 |
argument_spec=self.spec.argument_spec, |
278 |
- supports_check_mode=self.spec.supports_check_mode, |
|
279 |
- f5_product_name=self.spec.f5_product_name |
|
278 |
+ supports_check_mode=self.spec.supports_check_mode |
|
280 | 279 |
) |
281 | 280 |
|
282 | 281 |
# Override methods to force specific logic in the module to happen |
283 |
- mm = ModuleManager(client) |
|
284 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
285 |
- |
|
286 |
- pm = PartitionedManager(client) |
|
282 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
287 | 283 |
pm.create_on_device = Mock(return_value=True) |
288 | 284 |
pm.exists = Mock(return_value=False) |
289 | 285 |
|
286 |
+ mm = ModuleManager(module=module) |
|
287 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
288 |
+ mm.get_manager = Mock(return_value=pm) |
|
289 |
+ |
|
290 | 290 |
msg = "Shell access is only available to 'admin' or " \ |
291 | 291 |
"'resource-admin' roles" |
292 | 292 |
|
293 | 293 |
with pytest.raises(F5ModuleError) as ex: |
294 |
- pm.exec_module() |
|
294 |
+ mm.exec_module() |
|
295 | 295 |
assert str(ex.value) == msg |
296 | 296 |
|
297 | 297 |
def test_update_user_password_no_pass(self, *args): |
... | ... |
@@ -303,26 +302,26 @@ class TestManager(unittest.TestCase): |
303 | 303 |
user='admin' |
304 | 304 |
)) |
305 | 305 |
|
306 |
- client = AnsibleF5Client( |
|
306 |
+ module = AnsibleModule( |
|
307 | 307 |
argument_spec=self.spec.argument_spec, |
308 |
- supports_check_mode=self.spec.supports_check_mode, |
|
309 |
- f5_product_name=self.spec.f5_product_name |
|
308 |
+ supports_check_mode=self.spec.supports_check_mode |
|
310 | 309 |
) |
311 | 310 |
|
312 | 311 |
# Configure the parameters that would be returned by querying the |
313 | 312 |
# remote device |
314 |
- current = Parameters(load_fixture('load_auth_user_no_pass.json')) |
|
313 |
+ current = Parameters(params=load_fixture('load_auth_user_no_pass.json')) |
|
315 | 314 |
|
316 | 315 |
# Override methods to force specific logic in the module to happen |
317 |
- mm = ModuleManager(client) |
|
318 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
319 |
- |
|
320 |
- pm = PartitionedManager(client) |
|
316 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
321 | 317 |
pm.exists = Mock(return_value=True) |
322 | 318 |
pm.update_on_device = Mock(return_value=True) |
323 | 319 |
pm.read_current_from_device = Mock(return_value=current) |
324 | 320 |
|
325 |
- results = pm.exec_module() |
|
321 |
+ mm = ModuleManager(module=module) |
|
322 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
323 |
+ mm.get_manager = Mock(return_value=pm) |
|
324 |
+ |
|
325 |
+ results = mm.exec_module() |
|
326 | 326 |
|
327 | 327 |
assert results['changed'] is True |
328 | 328 |
|
... | ... |
@@ -335,26 +334,26 @@ class TestManager(unittest.TestCase): |
335 | 335 |
user='admin' |
336 | 336 |
)) |
337 | 337 |
|
338 |
- client = AnsibleF5Client( |
|
338 |
+ module = AnsibleModule( |
|
339 | 339 |
argument_spec=self.spec.argument_spec, |
340 |
- supports_check_mode=self.spec.supports_check_mode, |
|
341 |
- f5_product_name=self.spec.f5_product_name |
|
340 |
+ supports_check_mode=self.spec.supports_check_mode |
|
342 | 341 |
) |
343 | 342 |
|
344 | 343 |
# Configure the parameters that would be returned by querying the |
345 | 344 |
# remote device |
346 |
- current = Parameters(load_fixture('load_auth_user_with_pass.json')) |
|
345 |
+ current = Parameters(params=load_fixture('load_auth_user_with_pass.json')) |
|
347 | 346 |
|
348 | 347 |
# Override methods to force specific logic in the module to happen |
349 |
- mm = ModuleManager(client) |
|
350 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
351 |
- |
|
352 |
- pm = PartitionedManager(client) |
|
348 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
353 | 349 |
pm.exists = Mock(return_value=True) |
354 | 350 |
pm.update_on_device = Mock(return_value=True) |
355 | 351 |
pm.read_current_from_device = Mock(return_value=current) |
356 | 352 |
|
357 |
- results = pm.exec_module() |
|
353 |
+ mm = ModuleManager(module=module) |
|
354 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
355 |
+ mm.get_manager = Mock(return_value=pm) |
|
356 |
+ |
|
357 |
+ results = mm.exec_module() |
|
358 | 358 |
|
359 | 359 |
assert results['changed'] is True |
360 | 360 |
|
... | ... |
@@ -367,31 +366,31 @@ class TestManager(unittest.TestCase): |
367 | 367 |
shell='none' |
368 | 368 |
)) |
369 | 369 |
|
370 |
- client = AnsibleF5Client( |
|
370 |
+ module = AnsibleModule( |
|
371 | 371 |
argument_spec=self.spec.argument_spec, |
372 |
- supports_check_mode=self.spec.supports_check_mode, |
|
373 |
- f5_product_name=self.spec.f5_product_name |
|
372 |
+ supports_check_mode=self.spec.supports_check_mode |
|
374 | 373 |
) |
375 | 374 |
|
376 | 375 |
# Configure the parameters that would be returned by querying the |
377 | 376 |
# remote device |
378 | 377 |
current = Parameters( |
379 |
- dict( |
|
378 |
+ params=dict( |
|
380 | 379 |
user='admin', |
381 | 380 |
shell='tmsh' |
382 | 381 |
) |
383 | 382 |
) |
384 | 383 |
|
385 | 384 |
# Override methods to force specific logic in the module to happen |
386 |
- mm = ModuleManager(client) |
|
387 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
388 |
- |
|
389 |
- pm = PartitionedManager(client) |
|
385 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
390 | 386 |
pm.exists = Mock(return_value=True) |
391 | 387 |
pm.update_on_device = Mock(return_value=True) |
392 | 388 |
pm.read_current_from_device = Mock(return_value=current) |
393 | 389 |
|
394 |
- results = pm.exec_module() |
|
390 |
+ mm = ModuleManager(module=module) |
|
391 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
392 |
+ mm.get_manager = Mock(return_value=pm) |
|
393 |
+ |
|
394 |
+ results = mm.exec_module() |
|
395 | 395 |
|
396 | 396 |
assert results['changed'] is True |
397 | 397 |
assert results['shell'] == 'none' |
... | ... |
@@ -405,32 +404,32 @@ class TestManager(unittest.TestCase): |
405 | 405 |
shell='none' |
406 | 406 |
)) |
407 | 407 |
|
408 |
- client = AnsibleF5Client( |
|
408 |
+ module = AnsibleModule( |
|
409 | 409 |
argument_spec=self.spec.argument_spec, |
410 |
- supports_check_mode=self.spec.supports_check_mode, |
|
411 |
- f5_product_name=self.spec.f5_product_name |
|
410 |
+ supports_check_mode=self.spec.supports_check_mode |
|
412 | 411 |
) |
413 | 412 |
|
414 | 413 |
# Configure the parameters that would be returned by querying the |
415 | 414 |
# remote device |
416 | 415 |
access = [{'name': 'Common', 'role': 'guest'}] |
417 | 416 |
current = Parameters( |
418 |
- dict( |
|
417 |
+ params=dict( |
|
419 | 418 |
user='admin', |
420 | 419 |
partition_access=access |
421 | 420 |
) |
422 | 421 |
) |
423 | 422 |
|
424 | 423 |
# Override methods to force specific logic in the module to happen |
425 |
- mm = ModuleManager(client) |
|
426 |
- mm.is_version_less_than_13 = Mock(return_value=False) |
|
427 |
- |
|
428 |
- pm = PartitionedManager(client) |
|
424 |
+ pm = PartitionedManager(module=module, params=module.params) |
|
429 | 425 |
pm.exists = Mock(return_value=True) |
430 | 426 |
pm.update_on_device = Mock(return_value=True) |
431 | 427 |
pm.read_current_from_device = Mock(return_value=current) |
432 | 428 |
|
433 |
- results = pm.exec_module() |
|
429 |
+ mm = ModuleManager(module=module) |
|
430 |
+ mm.is_version_less_than_13 = Mock(return_value=False) |
|
431 |
+ mm.get_manager = Mock(return_value=pm) |
|
432 |
+ |
|
433 |
+ results = mm.exec_module() |
|
434 | 434 |
|
435 | 435 |
assert results['changed'] is False |
436 | 436 |
assert not hasattr(results, 'shell') |
... | ... |
@@ -444,17 +443,16 @@ class TestManager(unittest.TestCase): |
444 | 444 |
shell='bash' |
445 | 445 |
)) |
446 | 446 |
|
447 |
- client = AnsibleF5Client( |
|
447 |
+ module = AnsibleModule( |
|
448 | 448 |
argument_spec=self.spec.argument_spec, |
449 |
- supports_check_mode=self.spec.supports_check_mode, |
|
450 |
- f5_product_name=self.spec.f5_product_name |
|
449 |
+ supports_check_mode=self.spec.supports_check_mode |
|
451 | 450 |
) |
452 | 451 |
|
453 | 452 |
# Configure the parameters that would be returned by querying the |
454 | 453 |
# remote device |
455 | 454 |
access = [{'name': 'all', 'role': 'admin'}] |
456 | 455 |
current = Parameters( |
457 |
- dict( |
|
456 |
+ params=dict( |
|
458 | 457 |
user='admin', |
459 | 458 |
shell='tmsh', |
460 | 459 |
partition_access=access |
... | ... |
@@ -462,15 +460,16 @@ class TestManager(unittest.TestCase): |
462 | 462 |
) |
463 | 463 |
|
464 | 464 |
# Override methods to force specific logic in the module to happen |
465 |
- mm = ModuleManager(client) |
|
466 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
467 |
- |
|
468 |
- upm = UnparitionedManager(client) |
|
465 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
469 | 466 |
upm.exists = Mock(return_value=True) |
470 | 467 |
upm.update_on_device = Mock(return_value=True) |
471 | 468 |
upm.read_current_from_device = Mock(return_value=current) |
472 | 469 |
|
473 |
- results = upm.exec_module() |
|
470 |
+ mm = ModuleManager(module=module) |
|
471 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
472 |
+ mm.get_manager = Mock(return_value=upm) |
|
473 |
+ |
|
474 |
+ results = mm.exec_module() |
|
474 | 475 |
|
475 | 476 |
assert results['changed'] is True |
476 | 477 |
assert results['shell'] == 'bash' |
... | ... |
@@ -484,10 +483,9 @@ class TestManager(unittest.TestCase): |
484 | 484 |
shell='bash' |
485 | 485 |
)) |
486 | 486 |
|
487 |
- client = AnsibleF5Client( |
|
487 |
+ module = AnsibleModule( |
|
488 | 488 |
argument_spec=self.spec.argument_spec, |
489 |
- supports_check_mode=self.spec.supports_check_mode, |
|
490 |
- f5_product_name=self.spec.f5_product_name |
|
489 |
+ supports_check_mode=self.spec.supports_check_mode |
|
491 | 490 |
) |
492 | 491 |
|
493 | 492 |
# Configure the parameters that would be returned by querying the |
... | ... |
@@ -497,7 +495,7 @@ class TestManager(unittest.TestCase): |
497 | 497 |
{'name': 'all', 'role': 'guest'} |
498 | 498 |
] |
499 | 499 |
current = Parameters( |
500 |
- dict( |
|
500 |
+ params=dict( |
|
501 | 501 |
user='admin', |
502 | 502 |
shell='tmsh', |
503 | 503 |
partition_access=access |
... | ... |
@@ -505,24 +503,23 @@ class TestManager(unittest.TestCase): |
505 | 505 |
) |
506 | 506 |
|
507 | 507 |
# Override methods to force specific logic in the module to happen |
508 |
- mm = ModuleManager(client) |
|
509 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
510 |
- |
|
511 |
- upm = UnparitionedManager(client) |
|
508 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
512 | 509 |
upm.exists = Mock(return_value=True) |
513 | 510 |
upm.update_on_device = Mock(return_value=True) |
514 | 511 |
upm.read_current_from_device = Mock(return_value=current) |
515 | 512 |
|
513 |
+ mm = ModuleManager(module=module) |
|
514 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
515 |
+ mm.get_manager = Mock(return_value=upm) |
|
516 |
+ |
|
516 | 517 |
msg = "Shell access is only available to 'admin' or " \ |
517 | 518 |
"'resource-admin' roles" |
518 | 519 |
|
519 | 520 |
with pytest.raises(F5ModuleError) as ex: |
520 |
- upm.exec_module() |
|
521 |
+ mm.exec_module() |
|
521 | 522 |
assert str(ex.value) == msg |
522 | 523 |
|
523 | 524 |
|
524 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
525 |
- return_value=True) |
|
526 | 525 |
class TestLegacyManager(unittest.TestCase): |
527 | 526 |
|
528 | 527 |
def setUp(self): |
... | ... |
@@ -540,21 +537,21 @@ class TestLegacyManager(unittest.TestCase): |
540 | 540 |
update_password='on_create' |
541 | 541 |
)) |
542 | 542 |
|
543 |
- client = AnsibleF5Client( |
|
543 |
+ module = AnsibleModule( |
|
544 | 544 |
argument_spec=self.spec.argument_spec, |
545 |
- supports_check_mode=self.spec.supports_check_mode, |
|
546 |
- f5_product_name=self.spec.f5_product_name |
|
545 |
+ supports_check_mode=self.spec.supports_check_mode |
|
547 | 546 |
) |
548 | 547 |
|
549 | 548 |
# Override methods to force specific logic in the module to happen |
550 |
- mm = ModuleManager(client) |
|
551 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
552 |
- |
|
553 |
- upm = UnparitionedManager(client) |
|
549 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
554 | 550 |
upm.create_on_device = Mock(return_value=True) |
555 | 551 |
upm.exists = Mock(return_value=False) |
556 | 552 |
|
557 |
- results = upm.exec_module() |
|
553 |
+ mm = ModuleManager(module=module) |
|
554 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
555 |
+ mm.get_manager = Mock(return_value=upm) |
|
556 |
+ |
|
557 |
+ results = mm.exec_module() |
|
558 | 558 |
|
559 | 559 |
assert results['changed'] is True |
560 | 560 |
assert results['partition_access'] == access |
... | ... |
@@ -569,21 +566,21 @@ class TestLegacyManager(unittest.TestCase): |
569 | 569 |
user='admin' |
570 | 570 |
)) |
571 | 571 |
|
572 |
- client = AnsibleF5Client( |
|
572 |
+ module = AnsibleModule( |
|
573 | 573 |
argument_spec=self.spec.argument_spec, |
574 |
- supports_check_mode=self.spec.supports_check_mode, |
|
575 |
- f5_product_name=self.spec.f5_product_name |
|
574 |
+ supports_check_mode=self.spec.supports_check_mode |
|
576 | 575 |
) |
577 | 576 |
|
578 | 577 |
# Override methods to force specific logic in the module to happen |
579 |
- mm = ModuleManager(client) |
|
580 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
581 |
- |
|
582 |
- upm = UnparitionedManager(client) |
|
578 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
583 | 579 |
upm.create_on_device = Mock(return_value=True) |
584 | 580 |
upm.exists = Mock(return_value=False) |
585 | 581 |
|
586 |
- results = upm.exec_module() |
|
582 |
+ mm = ModuleManager(module=module) |
|
583 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
584 |
+ mm.get_manager = Mock(return_value=upm) |
|
585 |
+ |
|
586 |
+ results = mm.exec_module() |
|
587 | 587 |
|
588 | 588 |
assert results['changed'] is True |
589 | 589 |
assert results['partition_access'] == access |
... | ... |
@@ -599,26 +596,26 @@ class TestLegacyManager(unittest.TestCase): |
599 | 599 |
user='admin' |
600 | 600 |
)) |
601 | 601 |
|
602 |
- client = AnsibleF5Client( |
|
602 |
+ module = AnsibleModule( |
|
603 | 603 |
argument_spec=self.spec.argument_spec, |
604 |
- supports_check_mode=self.spec.supports_check_mode, |
|
605 |
- f5_product_name=self.spec.f5_product_name |
|
604 |
+ supports_check_mode=self.spec.supports_check_mode |
|
606 | 605 |
) |
607 | 606 |
|
608 | 607 |
# Override methods to force specific logic in the module to happen |
609 |
- mm = ModuleManager(client) |
|
610 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
611 |
- |
|
612 |
- upm = UnparitionedManager(client) |
|
608 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
613 | 609 |
upm.create_on_device = Mock(return_value=True) |
614 | 610 |
upm.exists = Mock(return_value=False) |
615 | 611 |
|
612 |
+ mm = ModuleManager(module=module) |
|
613 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
614 |
+ mm.get_manager = Mock(return_value=upm) |
|
615 |
+ |
|
616 | 616 |
msg = "The 'update_password' option " \ |
617 | 617 |
"needs to be set to 'on_create' when creating " \ |
618 | 618 |
"a resource with a password." |
619 | 619 |
|
620 | 620 |
with pytest.raises(F5ModuleError) as ex: |
621 |
- upm.exec_module() |
|
621 |
+ mm.exec_module() |
|
622 | 622 |
assert str(ex.value) == msg |
623 | 623 |
|
624 | 624 |
def test_create_user_partition_access_raises(self, *args): |
... | ... |
@@ -629,25 +626,25 @@ class TestLegacyManager(unittest.TestCase): |
629 | 629 |
user='admin' |
630 | 630 |
)) |
631 | 631 |
|
632 |
- client = AnsibleF5Client( |
|
632 |
+ module = AnsibleModule( |
|
633 | 633 |
argument_spec=self.spec.argument_spec, |
634 |
- supports_check_mode=self.spec.supports_check_mode, |
|
635 |
- f5_product_name=self.spec.f5_product_name |
|
634 |
+ supports_check_mode=self.spec.supports_check_mode |
|
636 | 635 |
) |
637 | 636 |
|
638 | 637 |
# Override methods to force specific logic in the module to happen |
639 |
- mm = ModuleManager(client) |
|
640 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
641 |
- |
|
642 |
- upm = UnparitionedManager(client) |
|
638 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
643 | 639 |
upm.create_on_device = Mock(return_value=True) |
644 | 640 |
upm.exists = Mock(return_value=False) |
645 | 641 |
|
642 |
+ mm = ModuleManager(module=module) |
|
643 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
644 |
+ mm.get_manager = Mock(return_value=upm) |
|
645 |
+ |
|
646 | 646 |
msg = "The 'partition_access' option " \ |
647 | 647 |
"is required when creating a resource." |
648 | 648 |
|
649 | 649 |
with pytest.raises(F5ModuleError) as ex: |
650 |
- upm.exec_module() |
|
650 |
+ mm.exec_module() |
|
651 | 651 |
assert str(ex.value) == msg |
652 | 652 |
|
653 | 653 |
def test_create_user_shell_bash(self, *args): |
... | ... |
@@ -663,21 +660,21 @@ class TestLegacyManager(unittest.TestCase): |
663 | 663 |
shell='bash' |
664 | 664 |
)) |
665 | 665 |
|
666 |
- client = AnsibleF5Client( |
|
666 |
+ module = AnsibleModule( |
|
667 | 667 |
argument_spec=self.spec.argument_spec, |
668 |
- supports_check_mode=self.spec.supports_check_mode, |
|
669 |
- f5_product_name=self.spec.f5_product_name |
|
668 |
+ supports_check_mode=self.spec.supports_check_mode |
|
670 | 669 |
) |
671 | 670 |
|
672 | 671 |
# Override methods to force specific logic in the module to happen |
673 |
- mm = ModuleManager(client) |
|
674 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
675 |
- |
|
676 |
- upm = UnparitionedManager(client) |
|
672 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
677 | 673 |
upm.create_on_device = Mock(return_value=True) |
678 | 674 |
upm.exists = Mock(return_value=False) |
679 | 675 |
|
680 |
- results = upm.exec_module() |
|
676 |
+ mm = ModuleManager(module=module) |
|
677 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
678 |
+ mm.get_manager = Mock(return_value=upm) |
|
679 |
+ |
|
680 |
+ results = mm.exec_module() |
|
681 | 681 |
|
682 | 682 |
assert results['changed'] is True |
683 | 683 |
assert results['partition_access'] == access |
... | ... |
@@ -695,25 +692,25 @@ class TestLegacyManager(unittest.TestCase): |
695 | 695 |
shell='bash' |
696 | 696 |
)) |
697 | 697 |
|
698 |
- client = AnsibleF5Client( |
|
698 |
+ module = AnsibleModule( |
|
699 | 699 |
argument_spec=self.spec.argument_spec, |
700 |
- supports_check_mode=self.spec.supports_check_mode, |
|
701 |
- f5_product_name=self.spec.f5_product_name |
|
700 |
+ supports_check_mode=self.spec.supports_check_mode |
|
702 | 701 |
) |
703 | 702 |
|
704 | 703 |
# Override methods to force specific logic in the module to happen |
705 |
- mm = ModuleManager(client) |
|
706 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
707 |
- |
|
708 |
- upm = UnparitionedManager(client) |
|
704 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
709 | 705 |
upm.create_on_device = Mock(return_value=True) |
710 | 706 |
upm.exists = Mock(return_value=False) |
711 | 707 |
|
708 |
+ mm = ModuleManager(module=module) |
|
709 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
710 |
+ mm.get_manager = Mock(return_value=upm) |
|
711 |
+ |
|
712 | 712 |
msg = "Shell access is only available to 'admin' or " \ |
713 | 713 |
"'resource-admin' roles" |
714 | 714 |
|
715 | 715 |
with pytest.raises(F5ModuleError) as ex: |
716 |
- upm.exec_module() |
|
716 |
+ mm.exec_module() |
|
717 | 717 |
assert str(ex.value) == msg |
718 | 718 |
|
719 | 719 |
def test_update_user_password(self, *args): |
... | ... |
@@ -725,32 +722,32 @@ class TestLegacyManager(unittest.TestCase): |
725 | 725 |
user='admin' |
726 | 726 |
)) |
727 | 727 |
|
728 |
- client = AnsibleF5Client( |
|
728 |
+ module = AnsibleModule( |
|
729 | 729 |
argument_spec=self.spec.argument_spec, |
730 |
- supports_check_mode=self.spec.supports_check_mode, |
|
731 |
- f5_product_name=self.spec.f5_product_name |
|
730 |
+ supports_check_mode=self.spec.supports_check_mode |
|
732 | 731 |
) |
733 | 732 |
|
734 | 733 |
# Configure the parameters that would be returned by querying the |
735 | 734 |
# remote device |
736 | 735 |
access = [{'name': 'Common', 'role': 'guest'}] |
737 | 736 |
current = Parameters( |
738 |
- dict( |
|
737 |
+ params=dict( |
|
739 | 738 |
shell='tmsh', |
740 | 739 |
partition_access=access |
741 | 740 |
) |
742 | 741 |
) |
743 | 742 |
|
744 | 743 |
# Override methods to force specific logic in the module to happen |
745 |
- mm = ModuleManager(client) |
|
746 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
747 |
- |
|
748 |
- upm = UnparitionedManager(client) |
|
744 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
749 | 745 |
upm.exists = Mock(return_value=True) |
750 | 746 |
upm.update_on_device = Mock(return_value=True) |
751 | 747 |
upm.read_current_from_device = Mock(return_value=current) |
752 | 748 |
|
753 |
- results = upm.exec_module() |
|
749 |
+ mm = ModuleManager(module=module) |
|
750 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
751 |
+ mm.get_manager = Mock(return_value=upm) |
|
752 |
+ |
|
753 |
+ results = mm.exec_module() |
|
754 | 754 |
|
755 | 755 |
assert results['changed'] is True |
756 | 756 |
|
... | ... |
@@ -763,31 +760,31 @@ class TestLegacyManager(unittest.TestCase): |
763 | 763 |
shell='none' |
764 | 764 |
)) |
765 | 765 |
|
766 |
- client = AnsibleF5Client( |
|
766 |
+ module = AnsibleModule( |
|
767 | 767 |
argument_spec=self.spec.argument_spec, |
768 |
- supports_check_mode=self.spec.supports_check_mode, |
|
769 |
- f5_product_name=self.spec.f5_product_name |
|
768 |
+ supports_check_mode=self.spec.supports_check_mode |
|
770 | 769 |
) |
771 | 770 |
|
772 | 771 |
# Configure the parameters that would be returned by querying the |
773 | 772 |
# remote device |
774 | 773 |
current = Parameters( |
775 |
- dict( |
|
774 |
+ params=dict( |
|
776 | 775 |
user='admin', |
777 | 776 |
shell='tmsh' |
778 | 777 |
) |
779 | 778 |
) |
780 | 779 |
|
781 | 780 |
# Override methods to force specific logic in the module to happen |
782 |
- mm = ModuleManager(client) |
|
783 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
784 |
- |
|
785 |
- upm = UnparitionedManager(client) |
|
781 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
786 | 782 |
upm.exists = Mock(return_value=True) |
787 | 783 |
upm.update_on_device = Mock(return_value=True) |
788 | 784 |
upm.read_current_from_device = Mock(return_value=current) |
789 | 785 |
|
790 |
- results = upm.exec_module() |
|
786 |
+ mm = ModuleManager(module=module) |
|
787 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
788 |
+ mm.get_manager = Mock(return_value=upm) |
|
789 |
+ |
|
790 |
+ results = mm.exec_module() |
|
791 | 791 |
|
792 | 792 |
assert results['changed'] is True |
793 | 793 |
assert results['shell'] == 'none' |
... | ... |
@@ -801,32 +798,32 @@ class TestLegacyManager(unittest.TestCase): |
801 | 801 |
shell='none' |
802 | 802 |
)) |
803 | 803 |
|
804 |
- client = AnsibleF5Client( |
|
804 |
+ module = AnsibleModule( |
|
805 | 805 |
argument_spec=self.spec.argument_spec, |
806 |
- supports_check_mode=self.spec.supports_check_mode, |
|
807 |
- f5_product_name=self.spec.f5_product_name |
|
806 |
+ supports_check_mode=self.spec.supports_check_mode |
|
808 | 807 |
) |
809 | 808 |
|
810 | 809 |
# Configure the parameters that would be returned by querying the |
811 | 810 |
# remote device |
812 | 811 |
access = [{'name': 'Common', 'role': 'guest'}] |
813 | 812 |
current = Parameters( |
814 |
- dict( |
|
813 |
+ params=dict( |
|
815 | 814 |
user='admin', |
816 | 815 |
partition_access=access |
817 | 816 |
) |
818 | 817 |
) |
819 | 818 |
|
820 | 819 |
# Override methods to force specific logic in the module to happen |
821 |
- mm = ModuleManager(client) |
|
822 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
823 |
- |
|
824 |
- upm = UnparitionedManager(client) |
|
820 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
825 | 821 |
upm.exists = Mock(return_value=True) |
826 | 822 |
upm.update_on_device = Mock(return_value=True) |
827 | 823 |
upm.read_current_from_device = Mock(return_value=current) |
828 | 824 |
|
829 |
- results = upm.exec_module() |
|
825 |
+ mm = ModuleManager(module=module) |
|
826 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
827 |
+ mm.get_manager = Mock(return_value=upm) |
|
828 |
+ |
|
829 |
+ results = mm.exec_module() |
|
830 | 830 |
|
831 | 831 |
assert results['changed'] is False |
832 | 832 |
assert not hasattr(results, 'shell') |
... | ... |
@@ -840,17 +837,16 @@ class TestLegacyManager(unittest.TestCase): |
840 | 840 |
shell='bash' |
841 | 841 |
)) |
842 | 842 |
|
843 |
- client = AnsibleF5Client( |
|
843 |
+ module = AnsibleModule( |
|
844 | 844 |
argument_spec=self.spec.argument_spec, |
845 |
- supports_check_mode=self.spec.supports_check_mode, |
|
846 |
- f5_product_name=self.spec.f5_product_name |
|
845 |
+ supports_check_mode=self.spec.supports_check_mode |
|
847 | 846 |
) |
848 | 847 |
|
849 | 848 |
# Configure the parameters that would be returned by querying the |
850 | 849 |
# remote device |
851 | 850 |
access = [{'name': 'all', 'role': 'admin'}] |
852 | 851 |
current = Parameters( |
853 |
- dict( |
|
852 |
+ params=dict( |
|
854 | 853 |
user='admin', |
855 | 854 |
shell='tmsh', |
856 | 855 |
partition_access=access |
... | ... |
@@ -858,15 +854,16 @@ class TestLegacyManager(unittest.TestCase): |
858 | 858 |
) |
859 | 859 |
|
860 | 860 |
# Override methods to force specific logic in the module to happen |
861 |
- mm = ModuleManager(client) |
|
862 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
863 |
- |
|
864 |
- upm = UnparitionedManager(client) |
|
861 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
865 | 862 |
upm.exists = Mock(return_value=True) |
866 | 863 |
upm.update_on_device = Mock(return_value=True) |
867 | 864 |
upm.read_current_from_device = Mock(return_value=current) |
868 | 865 |
|
869 |
- results = upm.exec_module() |
|
866 |
+ mm = ModuleManager(module=module) |
|
867 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
868 |
+ mm.get_manager = Mock(return_value=upm) |
|
869 |
+ |
|
870 |
+ results = mm.exec_module() |
|
870 | 871 |
|
871 | 872 |
assert results['changed'] is True |
872 | 873 |
assert results['shell'] == 'bash' |
... | ... |
@@ -880,10 +877,9 @@ class TestLegacyManager(unittest.TestCase): |
880 | 880 |
shell='bash' |
881 | 881 |
)) |
882 | 882 |
|
883 |
- client = AnsibleF5Client( |
|
883 |
+ module = AnsibleModule( |
|
884 | 884 |
argument_spec=self.spec.argument_spec, |
885 |
- supports_check_mode=self.spec.supports_check_mode, |
|
886 |
- f5_product_name=self.spec.f5_product_name |
|
885 |
+ supports_check_mode=self.spec.supports_check_mode |
|
887 | 886 |
) |
888 | 887 |
|
889 | 888 |
# Configure the parameters that would be returned by querying the |
... | ... |
@@ -893,7 +889,7 @@ class TestLegacyManager(unittest.TestCase): |
893 | 893 |
{'name': 'all', 'role': 'guest'} |
894 | 894 |
] |
895 | 895 |
current = Parameters( |
896 |
- dict( |
|
896 |
+ params=dict( |
|
897 | 897 |
user='admin', |
898 | 898 |
shell='tmsh', |
899 | 899 |
partition_access=access |
... | ... |
@@ -901,17 +897,18 @@ class TestLegacyManager(unittest.TestCase): |
901 | 901 |
) |
902 | 902 |
|
903 | 903 |
# Override methods to force specific logic in the module to happen |
904 |
- mm = ModuleManager(client) |
|
905 |
- mm.is_version_less_than_13 = Mock(return_value=True) |
|
906 |
- |
|
907 |
- upm = UnparitionedManager(client) |
|
904 |
+ upm = UnparitionedManager(module=module, params=module.params) |
|
908 | 905 |
upm.exists = Mock(return_value=True) |
909 | 906 |
upm.update_on_device = Mock(return_value=True) |
910 | 907 |
upm.read_current_from_device = Mock(return_value=current) |
911 | 908 |
|
909 |
+ mm = ModuleManager(module=module) |
|
910 |
+ mm.is_version_less_than_13 = Mock(return_value=True) |
|
911 |
+ mm.get_manager = Mock(return_value=upm) |
|
912 |
+ |
|
912 | 913 |
msg = "Shell access is only available to 'admin' or " \ |
913 | 914 |
"'resource-admin' roles" |
914 | 915 |
|
915 | 916 |
with pytest.raises(F5ModuleError) as ex: |
916 |
- upm.exec_module() |
|
917 |
+ mm.exec_module() |
|
917 | 918 |
assert str(ex.value) == msg |
... | ... |
@@ -18,20 +18,22 @@ if sys.version_info < (2, 7): |
18 | 18 |
from ansible.compat.tests import unittest |
19 | 19 |
from ansible.compat.tests.mock import Mock |
20 | 20 |
from ansible.compat.tests.mock import patch |
21 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
21 |
+from ansible.module_utils.basic import AnsibleModule |
|
22 | 22 |
|
23 | 23 |
try: |
24 | 24 |
from library.bigip_vcmp_guest import Parameters |
25 | 25 |
from library.bigip_vcmp_guest import ModuleManager |
26 | 26 |
from library.bigip_vcmp_guest import ArgumentSpec |
27 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
27 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
28 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
28 | 29 |
from test.unit.modules.utils import set_module_args |
29 | 30 |
except ImportError: |
30 | 31 |
try: |
31 | 32 |
from ansible.modules.network.f5.bigip_vcmp_guest import Parameters |
32 | 33 |
from ansible.modules.network.f5.bigip_vcmp_guest import ModuleManager |
33 | 34 |
from ansible.modules.network.f5.bigip_vcmp_guest import ArgumentSpec |
34 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
35 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
36 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
35 | 37 |
from units.modules.utils import set_module_args |
36 | 38 |
except ImportError: |
37 | 39 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -70,7 +72,7 @@ class TestParameters(unittest.TestCase): |
70 | 70 |
] |
71 | 71 |
) |
72 | 72 |
|
73 |
- p = Parameters(args) |
|
73 |
+ p = Parameters(params=args) |
|
74 | 74 |
assert p.initial_image == 'BIGIP-12.1.0.1.0.1447-HF1.iso' |
75 | 75 |
assert p.mgmt_network == 'bridged' |
76 | 76 |
|
... | ... |
@@ -80,7 +82,7 @@ class TestParameters(unittest.TestCase): |
80 | 80 |
mgmt_address='1.2.3.4' |
81 | 81 |
) |
82 | 82 |
|
83 |
- p = Parameters(args) |
|
83 |
+ p = Parameters(params=args) |
|
84 | 84 |
assert p.mgmt_network == 'bridged' |
85 | 85 |
assert p.mgmt_address == '1.2.3.4/32' |
86 | 86 |
|
... | ... |
@@ -90,7 +92,7 @@ class TestParameters(unittest.TestCase): |
90 | 90 |
mgmt_address='1.2.3.4/24' |
91 | 91 |
) |
92 | 92 |
|
93 |
- p = Parameters(args) |
|
93 |
+ p = Parameters(params=args) |
|
94 | 94 |
assert p.mgmt_network == 'bridged' |
95 | 95 |
assert p.mgmt_address == '1.2.3.4/24' |
96 | 96 |
|
... | ... |
@@ -100,7 +102,7 @@ class TestParameters(unittest.TestCase): |
100 | 100 |
mgmt_address='1.2.3.4/255.255.255.0' |
101 | 101 |
) |
102 | 102 |
|
103 |
- p = Parameters(args) |
|
103 |
+ p = Parameters(params=args) |
|
104 | 104 |
assert p.mgmt_network == 'bridged' |
105 | 105 |
assert p.mgmt_address == '1.2.3.4/24' |
106 | 106 |
|
... | ... |
@@ -109,7 +111,7 @@ class TestParameters(unittest.TestCase): |
109 | 109 |
mgmt_route='1.2.3.4' |
110 | 110 |
) |
111 | 111 |
|
112 |
- p = Parameters(args) |
|
112 |
+ p = Parameters(params=args) |
|
113 | 113 |
assert p.mgmt_route == '1.2.3.4' |
114 | 114 |
|
115 | 115 |
def test_module_parameters_vcmp_software_image_facts(self): |
... | ... |
@@ -120,7 +122,7 @@ class TestParameters(unittest.TestCase): |
120 | 120 |
initial_image='BIGIP-12.1.0.1.0.1447-HF1.iso/1', |
121 | 121 |
) |
122 | 122 |
|
123 |
- p = Parameters(args) |
|
123 |
+ p = Parameters(params=args) |
|
124 | 124 |
assert p.initial_image == 'BIGIP-12.1.0.1.0.1447-HF1.iso/1' |
125 | 125 |
|
126 | 126 |
def test_api_parameters(self): |
... | ... |
@@ -136,7 +138,7 @@ class TestParameters(unittest.TestCase): |
136 | 136 |
] |
137 | 137 |
) |
138 | 138 |
|
139 |
- p = Parameters(args) |
|
139 |
+ p = Parameters(params=args) |
|
140 | 140 |
assert p.initial_image == 'BIGIP-tmos-tier2-13.1.0.0.0.931.iso' |
141 | 141 |
assert p.mgmt_route == '2.2.2.2' |
142 | 142 |
assert p.mgmt_address == '1.1.1.1/24' |
... | ... |
@@ -144,8 +146,6 @@ class TestParameters(unittest.TestCase): |
144 | 144 |
assert '/Common/vlan2' in p.vlans |
145 | 145 |
|
146 | 146 |
|
147 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
148 |
- return_value=True) |
|
149 | 147 |
class TestManager(unittest.TestCase): |
150 | 148 |
def setUp(self): |
151 | 149 |
self.spec = ArgumentSpec() |
... | ... |
@@ -161,14 +161,13 @@ class TestManager(unittest.TestCase): |
161 | 161 |
user='admin' |
162 | 162 |
)) |
163 | 163 |
|
164 |
- client = AnsibleF5Client( |
|
164 |
+ module = AnsibleModule( |
|
165 | 165 |
argument_spec=self.spec.argument_spec, |
166 |
- supports_check_mode=self.spec.supports_check_mode, |
|
167 |
- f5_product_name=self.spec.f5_product_name |
|
166 |
+ supports_check_mode=self.spec.supports_check_mode |
|
168 | 167 |
) |
169 | 168 |
|
170 | 169 |
# Override methods to force specific logic in the module to happen |
171 |
- mm = ModuleManager(client) |
|
170 |
+ mm = ModuleManager(module=module) |
|
172 | 171 |
mm.create_on_device = Mock(return_value=True) |
173 | 172 |
mm.exists = Mock(return_value=False) |
174 | 173 |
mm.is_deployed = Mock(side_effect=[False, True, True, True, True]) |
... | ... |
@@ -17,20 +17,22 @@ if sys.version_info < (2, 7): |
17 | 17 |
from ansible.compat.tests import unittest |
18 | 18 |
from ansible.compat.tests.mock import Mock |
19 | 19 |
from ansible.compat.tests.mock import patch |
20 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
20 |
+from ansible.module_utils.basic import AnsibleModule |
|
21 | 21 |
|
22 | 22 |
try: |
23 | 23 |
from library.bigip_virtual_address import Parameters |
24 | 24 |
from library.bigip_virtual_address import ModuleManager |
25 | 25 |
from library.bigip_virtual_address import ArgumentSpec |
26 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
26 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
27 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
27 | 28 |
from test.unit.modules.utils import set_module_args |
28 | 29 |
except ImportError: |
29 | 30 |
try: |
30 | 31 |
from ansible.modules.network.f5.bigip_virtual_address import Parameters |
31 | 32 |
from ansible.modules.network.f5.bigip_virtual_address import ModuleManager |
32 | 33 |
from ansible.modules.network.f5.bigip_virtual_address import ArgumentSpec |
33 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
34 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
35 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
34 | 36 |
from units.modules.utils import set_module_args |
35 | 37 |
except ImportError: |
36 | 38 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -70,7 +72,7 @@ class TestParameters(unittest.TestCase): |
70 | 70 |
advertise_route='always', |
71 | 71 |
use_route_advertisement='yes' |
72 | 72 |
) |
73 |
- p = Parameters(args) |
|
73 |
+ p = Parameters(params=args) |
|
74 | 74 |
assert p.state == 'present' |
75 | 75 |
assert p.address == '1.1.1.1' |
76 | 76 |
assert p.netmask == '2.2.2.2' |
... | ... |
@@ -83,7 +85,7 @@ class TestParameters(unittest.TestCase): |
83 | 83 |
|
84 | 84 |
def test_api_parameters(self): |
85 | 85 |
args = load_fixture('load_ltm_virtual_address_default.json') |
86 |
- p = Parameters(args) |
|
86 |
+ p = Parameters(params=args) |
|
87 | 87 |
assert p.name == '1.1.1.1' |
88 | 88 |
assert p.address == '1.1.1.1' |
89 | 89 |
assert p.arp_state == 'enabled' |
... | ... |
@@ -99,56 +101,56 @@ class TestParameters(unittest.TestCase): |
99 | 99 |
args = dict( |
100 | 100 |
advertise_route='when_all_available' |
101 | 101 |
) |
102 |
- p = Parameters(args) |
|
102 |
+ p = Parameters(params=args) |
|
103 | 103 |
assert p.advertise_route == 'all' |
104 | 104 |
|
105 | 105 |
def test_module_parameters_advertise_route_any(self): |
106 | 106 |
args = dict( |
107 | 107 |
advertise_route='when_any_available' |
108 | 108 |
) |
109 |
- p = Parameters(args) |
|
109 |
+ p = Parameters(params=args) |
|
110 | 110 |
assert p.advertise_route == 'any' |
111 | 111 |
|
112 | 112 |
def test_module_parameters_icmp_echo_disabled(self): |
113 | 113 |
args = dict( |
114 | 114 |
icmp_echo='disabled' |
115 | 115 |
) |
116 |
- p = Parameters(args) |
|
116 |
+ p = Parameters(params=args) |
|
117 | 117 |
assert p.icmp_echo == 'disabled' |
118 | 118 |
|
119 | 119 |
def test_module_parameters_icmp_echo_selective(self): |
120 | 120 |
args = dict( |
121 | 121 |
icmp_echo='selective' |
122 | 122 |
) |
123 |
- p = Parameters(args) |
|
123 |
+ p = Parameters(params=args) |
|
124 | 124 |
assert p.icmp_echo == 'selective' |
125 | 125 |
|
126 | 126 |
def test_module_parameters_auto_delete_disabled(self): |
127 | 127 |
args = dict( |
128 | 128 |
auto_delete='disabled' |
129 | 129 |
) |
130 |
- p = Parameters(args) |
|
130 |
+ p = Parameters(params=args) |
|
131 | 131 |
assert p.auto_delete is False |
132 | 132 |
|
133 | 133 |
def test_module_parameters_arp_state_disabled(self): |
134 | 134 |
args = dict( |
135 | 135 |
arp_state='disabled' |
136 | 136 |
) |
137 |
- p = Parameters(args) |
|
137 |
+ p = Parameters(params=args) |
|
138 | 138 |
assert p.arp_state == 'disabled' |
139 | 139 |
|
140 | 140 |
def test_module_parameters_use_route_advert_disabled(self): |
141 | 141 |
args = dict( |
142 | 142 |
use_route_advertisement='no' |
143 | 143 |
) |
144 |
- p = Parameters(args) |
|
144 |
+ p = Parameters(params=args) |
|
145 | 145 |
assert p.use_route_advertisement == 'disabled' |
146 | 146 |
|
147 | 147 |
def test_module_parameters_state_present(self): |
148 | 148 |
args = dict( |
149 | 149 |
state='present' |
150 | 150 |
) |
151 |
- p = Parameters(args) |
|
151 |
+ p = Parameters(params=args) |
|
152 | 152 |
assert p.state == 'present' |
153 | 153 |
assert p.enabled == 'yes' |
154 | 154 |
|
... | ... |
@@ -156,14 +158,14 @@ class TestParameters(unittest.TestCase): |
156 | 156 |
args = dict( |
157 | 157 |
state='absent' |
158 | 158 |
) |
159 |
- p = Parameters(args) |
|
159 |
+ p = Parameters(params=args) |
|
160 | 160 |
assert p.state == 'absent' |
161 | 161 |
|
162 | 162 |
def test_module_parameters_state_enabled(self): |
163 | 163 |
args = dict( |
164 | 164 |
state='enabled' |
165 | 165 |
) |
166 |
- p = Parameters(args) |
|
166 |
+ p = Parameters(params=args) |
|
167 | 167 |
assert p.state == 'enabled' |
168 | 168 |
assert p.enabled == 'yes' |
169 | 169 |
|
... | ... |
@@ -171,13 +173,11 @@ class TestParameters(unittest.TestCase): |
171 | 171 |
args = dict( |
172 | 172 |
state='disabled' |
173 | 173 |
) |
174 |
- p = Parameters(args) |
|
174 |
+ p = Parameters(params=args) |
|
175 | 175 |
assert p.state == 'disabled' |
176 | 176 |
assert p.enabled == 'no' |
177 | 177 |
|
178 | 178 |
|
179 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
180 |
- return_value=True) |
|
181 | 179 |
class TestManager(unittest.TestCase): |
182 | 180 |
|
183 | 181 |
def setUp(self): |
... | ... |
@@ -199,12 +199,11 @@ class TestManager(unittest.TestCase): |
199 | 199 |
user='admin', |
200 | 200 |
)) |
201 | 201 |
|
202 |
- client = AnsibleF5Client( |
|
202 |
+ module = AnsibleModule( |
|
203 | 203 |
argument_spec=self.spec.argument_spec, |
204 |
- supports_check_mode=self.spec.supports_check_mode, |
|
205 |
- f5_product_name=self.spec.f5_product_name |
|
204 |
+ supports_check_mode=self.spec.supports_check_mode |
|
206 | 205 |
) |
207 |
- mm = ModuleManager(client) |
|
206 |
+ mm = ModuleManager(module=module) |
|
208 | 207 |
|
209 | 208 |
# Override methods to force specific logic in the module to happen |
210 | 209 |
mm.exists = Mock(side_effect=[False, True]) |
... | ... |
@@ -222,12 +221,11 @@ class TestManager(unittest.TestCase): |
222 | 222 |
user='admin', |
223 | 223 |
)) |
224 | 224 |
|
225 |
- client = AnsibleF5Client( |
|
225 |
+ module = AnsibleModule( |
|
226 | 226 |
argument_spec=self.spec.argument_spec, |
227 |
- supports_check_mode=self.spec.supports_check_mode, |
|
228 |
- f5_product_name=self.spec.f5_product_name |
|
227 |
+ supports_check_mode=self.spec.supports_check_mode |
|
229 | 228 |
) |
230 |
- mm = ModuleManager(client) |
|
229 |
+ mm = ModuleManager(module=module) |
|
231 | 230 |
|
232 | 231 |
# Override methods to force specific logic in the module to happen |
233 | 232 |
mm.exists = Mock(side_effect=[True, False]) |
... | ... |
@@ -17,28 +17,24 @@ if sys.version_info < (2, 7): |
17 | 17 |
from ansible.compat.tests import unittest |
18 | 18 |
from ansible.compat.tests.mock import Mock |
19 | 19 |
from ansible.compat.tests.mock import patch |
20 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
20 |
+from ansible.module_utils.basic import AnsibleModule |
|
21 | 21 |
|
22 | 22 |
try: |
23 |
- from library.bigip_virtual_server import VirtualAddressParameters |
|
24 |
- from library.bigip_virtual_server import VirtualServerModuleParameters |
|
25 |
- from library.bigip_virtual_server import VirtualServerApiParameters |
|
23 |
+ from library.bigip_virtual_server import ModuleParameters |
|
24 |
+ from library.bigip_virtual_server import ApiParameters |
|
26 | 25 |
from library.bigip_virtual_server import ModuleManager |
27 |
- from library.bigip_virtual_server import VirtualServerManager |
|
28 |
- from library.bigip_virtual_server import VirtualAddressManager |
|
29 | 26 |
from library.bigip_virtual_server import ArgumentSpec |
30 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
27 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
28 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
31 | 29 |
from test.unit.modules.utils import set_module_args |
32 | 30 |
except ImportError: |
33 | 31 |
try: |
34 |
- from ansible.modules.network.f5.bigip_virtual_server import VirtualAddressParameters |
|
35 |
- from ansible.modules.network.f5.bigip_virtual_server import VirtualServerApiParameters |
|
36 |
- from ansible.modules.network.f5.bigip_virtual_server import VirtualServerModuleParameters |
|
32 |
+ from ansible.modules.network.f5.bigip_virtual_server import ApiParameters |
|
33 |
+ from ansible.modules.network.f5.bigip_virtual_server import ModuleParameters |
|
37 | 34 |
from ansible.modules.network.f5.bigip_virtual_server import ModuleManager |
38 |
- from ansible.modules.network.f5.bigip_virtual_server import VirtualServerManager |
|
39 |
- from ansible.modules.network.f5.bigip_virtual_server import VirtualAddressManager |
|
40 | 35 |
from ansible.modules.network.f5.bigip_virtual_server import ArgumentSpec |
41 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
36 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
37 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
42 | 38 |
from units.modules.utils import set_module_args |
43 | 39 |
except ImportError: |
44 | 40 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -70,14 +66,14 @@ class TestParameters(unittest.TestCase): |
70 | 70 |
args = dict( |
71 | 71 |
destination='1.1.1.1' |
72 | 72 |
) |
73 |
- p = VirtualServerApiParameters(args) |
|
73 |
+ p = ApiParameters(params=args) |
|
74 | 74 |
assert p.destination_tuple.ip == '1.1.1.1' |
75 | 75 |
|
76 | 76 |
def test_destination_mutex_2(self): |
77 | 77 |
args = dict( |
78 | 78 |
destination='1.1.1.1%2' |
79 | 79 |
) |
80 |
- p = VirtualServerApiParameters(args) |
|
80 |
+ p = ApiParameters(params=args) |
|
81 | 81 |
assert p.destination_tuple.ip == '1.1.1.1' |
82 | 82 |
assert p.destination_tuple.route_domain == 2 |
83 | 83 |
|
... | ... |
@@ -85,7 +81,7 @@ class TestParameters(unittest.TestCase): |
85 | 85 |
args = dict( |
86 | 86 |
destination='1.1.1.1:80' |
87 | 87 |
) |
88 |
- p = VirtualServerApiParameters(args) |
|
88 |
+ p = ApiParameters(params=args) |
|
89 | 89 |
assert p.destination_tuple.ip == '1.1.1.1' |
90 | 90 |
assert p.destination_tuple.port == 80 |
91 | 91 |
|
... | ... |
@@ -93,7 +89,7 @@ class TestParameters(unittest.TestCase): |
93 | 93 |
args = dict( |
94 | 94 |
destination='1.1.1.1%2:80' |
95 | 95 |
) |
96 |
- p = VirtualServerApiParameters(args) |
|
96 |
+ p = ApiParameters(params=args) |
|
97 | 97 |
assert p.destination_tuple.ip == '1.1.1.1' |
98 | 98 |
assert p.destination_tuple.port == 80 |
99 | 99 |
assert p.destination_tuple.route_domain == 2 |
... | ... |
@@ -102,14 +98,14 @@ class TestParameters(unittest.TestCase): |
102 | 102 |
args = dict( |
103 | 103 |
destination='/Common/1.1.1.1' |
104 | 104 |
) |
105 |
- p = VirtualServerApiParameters(args) |
|
105 |
+ p = ApiParameters(params=args) |
|
106 | 106 |
assert p.destination_tuple.ip == '1.1.1.1' |
107 | 107 |
|
108 | 108 |
def test_api_destination_mutex_6(self): |
109 | 109 |
args = dict( |
110 | 110 |
destination='/Common/1.1.1.1%2' |
111 | 111 |
) |
112 |
- p = VirtualServerApiParameters(args) |
|
112 |
+ p = ApiParameters(params=args) |
|
113 | 113 |
assert p.destination_tuple.ip == '1.1.1.1' |
114 | 114 |
assert p.destination_tuple.route_domain == 2 |
115 | 115 |
|
... | ... |
@@ -117,7 +113,7 @@ class TestParameters(unittest.TestCase): |
117 | 117 |
args = dict( |
118 | 118 |
destination='/Common/1.1.1.1:80' |
119 | 119 |
) |
120 |
- p = VirtualServerApiParameters(args) |
|
120 |
+ p = ApiParameters(params=args) |
|
121 | 121 |
assert p.destination_tuple.ip == '1.1.1.1' |
122 | 122 |
assert p.destination_tuple.port == 80 |
123 | 123 |
|
... | ... |
@@ -125,7 +121,7 @@ class TestParameters(unittest.TestCase): |
125 | 125 |
args = dict( |
126 | 126 |
destination='/Common/1.1.1.1%2:80' |
127 | 127 |
) |
128 |
- p = VirtualServerApiParameters(args) |
|
128 |
+ p = ApiParameters(params=args) |
|
129 | 129 |
assert p.destination_tuple.ip == '1.1.1.1' |
130 | 130 |
assert p.destination_tuple.port == 80 |
131 | 131 |
assert p.destination_tuple.route_domain == 2 |
... | ... |
@@ -134,14 +130,14 @@ class TestParameters(unittest.TestCase): |
134 | 134 |
args = dict( |
135 | 135 |
destination='2700:bc00:1f10:101::6' |
136 | 136 |
) |
137 |
- p = VirtualServerApiParameters(args) |
|
137 |
+ p = ApiParameters(params=args) |
|
138 | 138 |
assert p.destination_tuple.ip == '2700:bc00:1f10:101::6' |
139 | 139 |
|
140 | 140 |
def test_destination_mutex_10(self): |
141 | 141 |
args = dict( |
142 | 142 |
destination='2700:bc00:1f10:101::6%2' |
143 | 143 |
) |
144 |
- p = VirtualServerApiParameters(args) |
|
144 |
+ p = ApiParameters(params=args) |
|
145 | 145 |
assert p.destination_tuple.ip == '2700:bc00:1f10:101::6' |
146 | 146 |
assert p.destination_tuple.route_domain == 2 |
147 | 147 |
|
... | ... |
@@ -149,7 +145,7 @@ class TestParameters(unittest.TestCase): |
149 | 149 |
args = dict( |
150 | 150 |
destination='2700:bc00:1f10:101::6.80' |
151 | 151 |
) |
152 |
- p = VirtualServerApiParameters(args) |
|
152 |
+ p = ApiParameters(params=args) |
|
153 | 153 |
assert p.destination_tuple.ip == '2700:bc00:1f10:101::6' |
154 | 154 |
assert p.destination_tuple.port == 80 |
155 | 155 |
|
... | ... |
@@ -157,26 +153,11 @@ class TestParameters(unittest.TestCase): |
157 | 157 |
args = dict( |
158 | 158 |
destination='2700:bc00:1f10:101::6%2.80' |
159 | 159 |
) |
160 |
- p = VirtualServerApiParameters(args) |
|
160 |
+ p = ApiParameters(params=args) |
|
161 | 161 |
assert p.destination_tuple.ip == '2700:bc00:1f10:101::6' |
162 | 162 |
assert p.destination_tuple.port == 80 |
163 | 163 |
assert p.destination_tuple.route_domain == 2 |
164 | 164 |
|
165 |
-# |
|
166 |
-# def test_destination_mutex_6(self): |
|
167 |
-# args = dict( |
|
168 |
-# destination='/Common/2700:bc00:1f10:101::6' |
|
169 |
-# ) |
|
170 |
-# p = VirtualServerParameters(args) |
|
171 |
-# assert p.destination_tuple.ip == '2700:bc00:1f10:101::6' |
|
172 |
-# |
|
173 |
-# def test_destination_mutex_5(self): |
|
174 |
-# args = dict( |
|
175 |
-# destination='/Common/2700:bc00:1f10:101::6' |
|
176 |
-# ) |
|
177 |
-# p = VirtualServerParameters(args) |
|
178 |
-# assert p.destination_tuple.ip == '2700:bc00:1f10:101::6' |
|
179 |
- |
|
180 | 165 |
def test_module_no_partition_prefix_parameters(self): |
181 | 166 |
args = dict( |
182 | 167 |
server='localhost', |
... | ... |
@@ -198,7 +179,7 @@ class TestParameters(unittest.TestCase): |
198 | 198 |
], |
199 | 199 |
enabled_vlans=['vlan2'] |
200 | 200 |
) |
201 |
- p = VirtualServerModuleParameters(args) |
|
201 |
+ p = ModuleParameters(params=args) |
|
202 | 202 |
assert p.name == 'my-virtual-server' |
203 | 203 |
assert p.partition == 'Common' |
204 | 204 |
assert p.port == 443 |
... | ... |
@@ -235,7 +216,7 @@ class TestParameters(unittest.TestCase): |
235 | 235 |
], |
236 | 236 |
enabled_vlans=['/Common/vlan2'] |
237 | 237 |
) |
238 |
- p = VirtualServerModuleParameters(args) |
|
238 |
+ p = ModuleParameters(params=args) |
|
239 | 239 |
assert p.name == 'my-virtual-server' |
240 | 240 |
assert p.partition == 'Common' |
241 | 241 |
assert p.port == 443 |
... | ... |
@@ -342,7 +323,7 @@ class TestParameters(unittest.TestCase): |
342 | 342 |
] |
343 | 343 |
} |
344 | 344 |
} |
345 |
- p = VirtualServerApiParameters(args) |
|
345 |
+ p = ApiParameters(params=args) |
|
346 | 346 |
assert p.name == 'my-virtual-server' |
347 | 347 |
assert p.partition == 'Common' |
348 | 348 |
assert p.port == 443 |
... | ... |
@@ -358,8 +339,6 @@ class TestParameters(unittest.TestCase): |
358 | 358 |
assert '/Common/net1' in p.vlans |
359 | 359 |
|
360 | 360 |
|
361 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
362 |
- return_value=True) |
|
363 | 361 |
class TestManager(unittest.TestCase): |
364 | 362 |
|
365 | 363 |
def setUp(self): |
... | ... |
@@ -388,19 +367,15 @@ class TestManager(unittest.TestCase): |
388 | 388 |
validate_certs="no" |
389 | 389 |
)) |
390 | 390 |
|
391 |
- client = AnsibleF5Client( |
|
391 |
+ module = AnsibleModule( |
|
392 | 392 |
argument_spec=self.spec.argument_spec, |
393 |
- supports_check_mode=self.spec.supports_check_mode, |
|
394 |
- f5_product_name=self.spec.f5_product_name |
|
393 |
+ supports_check_mode=self.spec.supports_check_mode |
|
395 | 394 |
) |
396 | 395 |
|
397 | 396 |
# Override methods to force specific logic in the module to happen |
398 |
- vsm = VirtualServerManager(client) |
|
399 |
- vsm.exists = Mock(return_value=False) |
|
400 |
- vsm.create_on_device = Mock(return_value=True) |
|
401 |
- |
|
402 |
- mm = ModuleManager(client) |
|
403 |
- mm.get_manager = Mock(return_value=vsm) |
|
397 |
+ mm = ModuleManager(module=module) |
|
398 |
+ mm.exists = Mock(return_value=False) |
|
399 |
+ mm.create_on_device = Mock(return_value=True) |
|
404 | 400 |
results = mm.exec_module() |
405 | 401 |
|
406 | 402 |
assert results['changed'] is True |
... | ... |
@@ -423,18 +398,14 @@ class TestManager(unittest.TestCase): |
423 | 423 |
validate_certs="no" |
424 | 424 |
)) |
425 | 425 |
|
426 |
- client = AnsibleF5Client( |
|
426 |
+ module = AnsibleModule( |
|
427 | 427 |
argument_spec=self.spec.argument_spec, |
428 |
- supports_check_mode=self.spec.supports_check_mode, |
|
429 |
- f5_product_name=self.spec.f5_product_name |
|
428 |
+ supports_check_mode=self.spec.supports_check_mode |
|
430 | 429 |
) |
431 | 430 |
|
432 | 431 |
# Override methods to force specific logic in the module to happen |
433 |
- vsm = VirtualServerManager(client) |
|
434 |
- vsm.exists = Mock(return_value=False) |
|
435 |
- |
|
436 |
- mm = ModuleManager(client) |
|
437 |
- mm.get_manager = Mock(return_value=vsm) |
|
432 |
+ mm = ModuleManager(module=module) |
|
433 |
+ mm.exists = Mock(return_value=False) |
|
438 | 434 |
|
439 | 435 |
results = mm.exec_module() |
440 | 436 |
|
... | ... |
@@ -460,26 +431,22 @@ class TestManager(unittest.TestCase): |
460 | 460 |
|
461 | 461 |
# Configure the parameters that would be returned by querying the |
462 | 462 |
# remote device |
463 |
- current = VirtualServerApiParameters( |
|
463 |
+ current = ApiParameters( |
|
464 | 464 |
dict( |
465 | 465 |
agent_status_traps='disabled' |
466 | 466 |
) |
467 | 467 |
) |
468 | 468 |
|
469 |
- client = AnsibleF5Client( |
|
469 |
+ module = AnsibleModule( |
|
470 | 470 |
argument_spec=self.spec.argument_spec, |
471 |
- supports_check_mode=self.spec.supports_check_mode, |
|
472 |
- f5_product_name=self.spec.f5_product_name |
|
471 |
+ supports_check_mode=self.spec.supports_check_mode |
|
473 | 472 |
) |
474 | 473 |
|
475 | 474 |
# Override methods to force specific logic in the module to happen |
476 |
- vsm = VirtualServerManager(client) |
|
477 |
- vsm.exists = Mock(return_value=False) |
|
478 |
- vsm.update_on_device = Mock(return_value=True) |
|
479 |
- vsm.read_current_from_device = Mock(return_value=current) |
|
480 |
- |
|
481 |
- mm = ModuleManager(client) |
|
482 |
- mm.get_manager = Mock(return_value=vsm) |
|
475 |
+ mm = ModuleManager(module=module) |
|
476 |
+ mm.exists = Mock(return_value=False) |
|
477 |
+ mm.update_on_device = Mock(return_value=True) |
|
478 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
483 | 479 |
results = mm.exec_module() |
484 | 480 |
|
485 | 481 |
assert results['changed'] is False |
... | ... |
@@ -498,22 +465,18 @@ class TestManager(unittest.TestCase): |
498 | 498 |
|
499 | 499 |
# Configure the parameters that would be returned by querying the |
500 | 500 |
# remote device |
501 |
- current = VirtualServerApiParameters(load_fixture('load_ltm_virtual_1.json')) |
|
501 |
+ current = ApiParameters(params=load_fixture('load_ltm_virtual_1.json')) |
|
502 | 502 |
|
503 |
- client = AnsibleF5Client( |
|
503 |
+ module = AnsibleModule( |
|
504 | 504 |
argument_spec=self.spec.argument_spec, |
505 |
- supports_check_mode=self.spec.supports_check_mode, |
|
506 |
- f5_product_name=self.spec.f5_product_name |
|
505 |
+ supports_check_mode=self.spec.supports_check_mode |
|
507 | 506 |
) |
508 | 507 |
|
509 | 508 |
# Override methods to force specific logic in the module to happen |
510 |
- vsm = VirtualServerManager(client) |
|
511 |
- vsm.exists = Mock(return_value=True) |
|
512 |
- vsm.read_current_from_device = Mock(return_value=current) |
|
513 |
- vsm.update_on_device = Mock(return_value=True) |
|
514 |
- |
|
515 |
- mm = ModuleManager(client) |
|
516 |
- mm.get_manager = Mock(return_value=vsm) |
|
509 |
+ mm = ModuleManager(module=module) |
|
510 |
+ mm.exists = Mock(return_value=True) |
|
511 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
512 |
+ mm.update_on_device = Mock(return_value=True) |
|
517 | 513 |
results = mm.exec_module() |
518 | 514 |
|
519 | 515 |
assert results['changed'] is True |
... | ... |
@@ -532,21 +495,17 @@ class TestManager(unittest.TestCase): |
532 | 532 |
|
533 | 533 |
# Configure the parameters that would be returned by querying the |
534 | 534 |
# remote device |
535 |
- current = VirtualServerApiParameters(load_fixture('load_ltm_virtual_1.json')) |
|
535 |
+ current = ApiParameters(params=load_fixture('load_ltm_virtual_1.json')) |
|
536 | 536 |
|
537 |
- client = AnsibleF5Client( |
|
537 |
+ module = AnsibleModule( |
|
538 | 538 |
argument_spec=self.spec.argument_spec, |
539 |
- supports_check_mode=self.spec.supports_check_mode, |
|
540 |
- f5_product_name=self.spec.f5_product_name |
|
539 |
+ supports_check_mode=self.spec.supports_check_mode |
|
541 | 540 |
) |
542 | 541 |
|
543 | 542 |
# Override methods to force specific logic in the module to happen |
544 |
- vsm = VirtualServerManager(client) |
|
545 |
- vsm.exists = Mock(return_value=True) |
|
546 |
- vsm.read_current_from_device = Mock(return_value=current) |
|
547 |
- |
|
548 |
- mm = ModuleManager(client) |
|
549 |
- mm.get_manager = Mock(return_value=vsm) |
|
543 |
+ mm = ModuleManager(module=module) |
|
544 |
+ mm.exists = Mock(return_value=True) |
|
545 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
550 | 546 |
results = mm.exec_module() |
551 | 547 |
|
552 | 548 |
assert results['changed'] is False |
... | ... |
@@ -567,21 +526,17 @@ class TestManager(unittest.TestCase): |
567 | 567 |
|
568 | 568 |
# Configure the parameters that would be returned by querying the |
569 | 569 |
# remote device |
570 |
- current = VirtualServerApiParameters(load_fixture('load_ltm_virtual_2.json')) |
|
570 |
+ current = ApiParameters(params=load_fixture('load_ltm_virtual_2.json')) |
|
571 | 571 |
|
572 |
- client = AnsibleF5Client( |
|
572 |
+ module = AnsibleModule( |
|
573 | 573 |
argument_spec=self.spec.argument_spec, |
574 |
- supports_check_mode=self.spec.supports_check_mode, |
|
575 |
- f5_product_name=self.spec.f5_product_name |
|
574 |
+ supports_check_mode=self.spec.supports_check_mode |
|
576 | 575 |
) |
577 | 576 |
|
578 | 577 |
# Override methods to force specific logic in the module to happen |
579 |
- vsm = VirtualServerManager(client) |
|
580 |
- vsm.exists = Mock(return_value=True) |
|
581 |
- vsm.read_current_from_device = Mock(return_value=current) |
|
582 |
- |
|
583 |
- mm = ModuleManager(client) |
|
584 |
- mm.get_manager = Mock(return_value=vsm) |
|
578 |
+ mm = ModuleManager(module=module) |
|
579 |
+ mm.exists = Mock(return_value=True) |
|
580 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
585 | 581 |
|
586 | 582 |
results = mm.exec_module() |
587 | 583 |
|
... | ... |
@@ -603,22 +558,18 @@ class TestManager(unittest.TestCase): |
603 | 603 |
|
604 | 604 |
# Configure the parameters that would be returned by querying the |
605 | 605 |
# remote device |
606 |
- current = VirtualServerApiParameters(load_fixture('load_ltm_virtual_2.json')) |
|
606 |
+ current = ApiParameters(params=load_fixture('load_ltm_virtual_2.json')) |
|
607 | 607 |
|
608 |
- client = AnsibleF5Client( |
|
608 |
+ module = AnsibleModule( |
|
609 | 609 |
argument_spec=self.spec.argument_spec, |
610 |
- supports_check_mode=self.spec.supports_check_mode, |
|
611 |
- f5_product_name=self.spec.f5_product_name |
|
610 |
+ supports_check_mode=self.spec.supports_check_mode |
|
612 | 611 |
) |
613 | 612 |
|
614 | 613 |
# Override methods to force specific logic in the module to happen |
615 |
- vsm = VirtualServerManager(client) |
|
616 |
- vsm.exists = Mock(return_value=True) |
|
617 |
- vsm.read_current_from_device = Mock(return_value=current) |
|
618 |
- vsm.update_on_device = Mock(return_value=True) |
|
619 |
- |
|
620 |
- mm = ModuleManager(client) |
|
621 |
- mm.get_manager = Mock(return_value=vsm) |
|
614 |
+ mm = ModuleManager(module=module) |
|
615 |
+ mm.exists = Mock(return_value=True) |
|
616 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
617 |
+ mm.update_on_device = Mock(return_value=True) |
|
622 | 618 |
|
623 | 619 |
results = mm.exec_module() |
624 | 620 |
|
... | ... |
@@ -674,22 +625,18 @@ class TestManager(unittest.TestCase): |
674 | 674 |
|
675 | 675 |
# Configure the parameters that would be returned by querying the |
676 | 676 |
# remote device |
677 |
- current = VirtualServerApiParameters(load_fixture('load_ltm_virtual_3.json')) |
|
677 |
+ current = ApiParameters(params=load_fixture('load_ltm_virtual_3.json')) |
|
678 | 678 |
|
679 |
- client = AnsibleF5Client( |
|
679 |
+ module = AnsibleModule( |
|
680 | 680 |
argument_spec=self.spec.argument_spec, |
681 |
- supports_check_mode=self.spec.supports_check_mode, |
|
682 |
- f5_product_name=self.spec.f5_product_name |
|
681 |
+ supports_check_mode=self.spec.supports_check_mode |
|
683 | 682 |
) |
684 | 683 |
|
685 | 684 |
# Override methods to force specific logic in the module to happen |
686 |
- vsm = VirtualServerManager(client) |
|
687 |
- vsm.exists = Mock(return_value=True) |
|
688 |
- vsm.read_current_from_device = Mock(return_value=current) |
|
689 |
- vsm.update_on_device = Mock(return_value=True) |
|
690 |
- |
|
691 |
- mm = ModuleManager(client) |
|
692 |
- mm.get_manager = Mock(return_value=vsm) |
|
685 |
+ mm = ModuleManager(module=module) |
|
686 |
+ mm.exists = Mock(return_value=True) |
|
687 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
688 |
+ mm.update_on_device = Mock(return_value=True) |
|
693 | 689 |
|
694 | 690 |
results = mm.exec_module() |
695 | 691 |
|
... | ... |
@@ -727,47 +674,3 @@ class TestManager(unittest.TestCase): |
727 | 727 |
assert 'context' in results['profiles'][1] |
728 | 728 |
assert results['profiles'][1]['name'] == 'clientssl' |
729 | 729 |
assert results['profiles'][1]['context'] == 'clientside' |
730 |
- |
|
731 |
- |
|
732 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
733 |
- return_value=True) |
|
734 |
-class TestDeprecatedAnsible24Manager(unittest.TestCase): |
|
735 |
- def setUp(self): |
|
736 |
- self.spec = ArgumentSpec() |
|
737 |
- |
|
738 |
- def test_modify_port_idempotent(self, *args): |
|
739 |
- set_module_args(dict( |
|
740 |
- destination="10.10.10.10", |
|
741 |
- name="my-virtual-server", |
|
742 |
- route_advertisement_state="enabled", |
|
743 |
- partition="Common", |
|
744 |
- password="secret", |
|
745 |
- port="443", |
|
746 |
- server="localhost", |
|
747 |
- state="present", |
|
748 |
- user="admin", |
|
749 |
- validate_certs="no" |
|
750 |
- )) |
|
751 |
- |
|
752 |
- client = AnsibleF5Client( |
|
753 |
- argument_spec=self.spec.argument_spec, |
|
754 |
- supports_check_mode=self.spec.supports_check_mode, |
|
755 |
- f5_product_name=self.spec.f5_product_name |
|
756 |
- ) |
|
757 |
- |
|
758 |
- vsm_current = VirtualServerApiParameters(load_fixture('load_ltm_virtual_1.json')) |
|
759 |
- vam_current = VirtualAddressParameters(load_fixture('load_ltm_virtual_1_address.json')) |
|
760 |
- |
|
761 |
- vsm = VirtualServerManager(client) |
|
762 |
- vsm.exists = Mock(return_value=True) |
|
763 |
- vsm.read_current_from_device = Mock(return_value=vsm_current) |
|
764 |
- vam = VirtualAddressManager(client) |
|
765 |
- vam.exists = Mock(return_value=True) |
|
766 |
- vam.read_current_from_device = Mock(return_value=vam_current) |
|
767 |
- |
|
768 |
- mm = ModuleManager(client) |
|
769 |
- mm.get_manager = Mock(side_effect=[vsm, vam]) |
|
770 |
- |
|
771 |
- results = mm.exec_module() |
|
772 |
- |
|
773 |
- assert results['changed'] is False |
... | ... |
@@ -8,7 +8,6 @@ __metaclass__ = type |
8 | 8 |
|
9 | 9 |
import os |
10 | 10 |
import json |
11 |
-import pytest |
|
12 | 11 |
import sys |
13 | 12 |
|
14 | 13 |
from nose.plugins.skip import SkipTest |
... | ... |
@@ -18,21 +17,24 @@ if sys.version_info < (2, 7): |
18 | 18 |
from ansible.compat.tests import unittest |
19 | 19 |
from ansible.compat.tests.mock import Mock |
20 | 20 |
from ansible.compat.tests.mock import patch |
21 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
22 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
21 |
+from ansible.module_utils.basic import AnsibleModule |
|
23 | 22 |
|
24 | 23 |
try: |
25 |
- from library.bigip_vlan import Parameters |
|
24 |
+ from library.bigip_vlan import ApiParameters |
|
25 |
+ from library.bigip_vlan import ModuleParameters |
|
26 | 26 |
from library.bigip_vlan import ModuleManager |
27 | 27 |
from library.bigip_vlan import ArgumentSpec |
28 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
28 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
29 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
29 | 30 |
from test.unit.modules.utils import set_module_args |
30 | 31 |
except ImportError: |
31 | 32 |
try: |
32 |
- from ansible.modules.network.f5.bigip_vlan import Parameters |
|
33 |
+ from ansible.modules.network.f5.bigip_vlan import ApiParameters |
|
34 |
+ from ansible.modules.network.f5.bigip_vlan import ModuleParameters |
|
33 | 35 |
from ansible.modules.network.f5.bigip_vlan import ModuleManager |
34 | 36 |
from ansible.modules.network.f5.bigip_vlan import ArgumentSpec |
35 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
37 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
38 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
36 | 39 |
from units.modules.utils import set_module_args |
37 | 40 |
except ImportError: |
38 | 41 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -65,13 +67,6 @@ class BigIpObj(object): |
65 | 65 |
|
66 | 66 |
|
67 | 67 |
class TestParameters(unittest.TestCase): |
68 |
- |
|
69 |
- def setUp(self): |
|
70 |
- self.loaded_ifcs = [] |
|
71 |
- ifcs_json = load_fixture('load_net_interfaces.json') |
|
72 |
- for item in ifcs_json: |
|
73 |
- self.loaded_ifcs.append(BigIpObj(**item)) |
|
74 |
- |
|
75 | 68 |
def test_module_parameters(self): |
76 | 69 |
args = dict( |
77 | 70 |
name='somevlan', |
... | ... |
@@ -79,9 +74,7 @@ class TestParameters(unittest.TestCase): |
79 | 79 |
description='fakevlan', |
80 | 80 |
untagged_interfaces=['1.1'], |
81 | 81 |
) |
82 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
83 |
- obj.return_value = self.loaded_ifcs |
|
84 |
- p = Parameters(args) |
|
82 |
+ p = ModuleParameters(params=args) |
|
85 | 83 |
|
86 | 84 |
assert p.name == 'somevlan' |
87 | 85 |
assert p.tag == 213 |
... | ... |
@@ -92,38 +85,20 @@ class TestParameters(unittest.TestCase): |
92 | 92 |
args = dict( |
93 | 93 |
name='somevlan', |
94 | 94 |
description='fakevlan', |
95 |
- tag=213, |
|
96 |
- tagged_interfaces=['1.2'] |
|
95 |
+ tag=213 |
|
97 | 96 |
) |
98 | 97 |
|
99 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
100 |
- obj.return_value = self.loaded_ifcs |
|
101 |
- p = Parameters(args) |
|
98 |
+ p = ApiParameters(params=args) |
|
102 | 99 |
|
103 | 100 |
assert p.name == 'somevlan' |
104 | 101 |
assert p.tag == 213 |
105 |
- assert p.interfaces == [{'tagged': True, 'name': '1.2'}] |
|
106 | 102 |
assert p.description == 'fakevlan' |
107 | 103 |
|
108 | 104 |
|
109 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
110 |
- return_value=True) |
|
111 | 105 |
class TestManager(unittest.TestCase): |
112 | 106 |
|
113 | 107 |
def setUp(self): |
114 | 108 |
self.spec = ArgumentSpec() |
115 |
- self.loaded_ifcs = [] |
|
116 |
- self.loaded_vlan_ifc_tag = [] |
|
117 |
- self.loaded_vlan_ifc_untag = [] |
|
118 |
- ifcs_tag = load_fixture('load_vlan_tagged_ifcs.json') |
|
119 |
- ifcs_untag = load_fixture('load_vlan_untag_ifcs.json') |
|
120 |
- ifcs_json = load_fixture('load_net_interfaces.json') |
|
121 |
- for item in ifcs_json: |
|
122 |
- self.loaded_ifcs.append(BigIpObj(**item)) |
|
123 |
- for item in ifcs_tag: |
|
124 |
- self.loaded_vlan_ifc_tag.append(BigIpObj(**item)) |
|
125 |
- for item in ifcs_untag: |
|
126 |
- self.loaded_vlan_ifc_untag.append(BigIpObj(**item)) |
|
127 | 109 |
|
128 | 110 |
def test_create_vlan(self, *args): |
129 | 111 |
set_module_args(dict( |
... | ... |
@@ -135,24 +110,19 @@ class TestManager(unittest.TestCase): |
135 | 135 |
partition='Common' |
136 | 136 |
)) |
137 | 137 |
|
138 |
- client = AnsibleF5Client( |
|
138 |
+ module = AnsibleModule( |
|
139 | 139 |
argument_spec=self.spec.argument_spec, |
140 |
- supports_check_mode=self.spec.supports_check_mode, |
|
141 |
- f5_product_name=self.spec.f5_product_name |
|
140 |
+ supports_check_mode=self.spec.supports_check_mode |
|
142 | 141 |
) |
143 | 142 |
|
144 | 143 |
# Override methods to force specific logic in the module to happen |
145 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
146 |
- obj.return_value = self.loaded_ifcs |
|
144 |
+ mm = ModuleManager(module=module) |
|
145 |
+ mm.create_on_device = Mock(return_value=True) |
|
146 |
+ mm.exists = Mock(return_value=False) |
|
147 | 147 |
|
148 |
- mm = ModuleManager(client) |
|
149 |
- mm.create_on_device = Mock(return_value=True) |
|
150 |
- mm.exists = Mock(return_value=False) |
|
151 |
- |
|
152 |
- results = mm.exec_module() |
|
148 |
+ results = mm.exec_module() |
|
153 | 149 |
|
154 | 150 |
assert results['changed'] is True |
155 |
- assert results['name'] == 'somevlan' |
|
156 | 151 |
assert results['description'] == 'fakevlan' |
157 | 152 |
|
158 | 153 |
def test_create_vlan_tagged_interface(self, *args): |
... | ... |
@@ -166,26 +136,21 @@ class TestManager(unittest.TestCase): |
166 | 166 |
partition='Common' |
167 | 167 |
)) |
168 | 168 |
|
169 |
- client = AnsibleF5Client( |
|
169 |
+ module = AnsibleModule( |
|
170 | 170 |
argument_spec=self.spec.argument_spec, |
171 |
- supports_check_mode=self.spec.supports_check_mode, |
|
172 |
- f5_product_name=self.spec.f5_product_name |
|
171 |
+ supports_check_mode=self.spec.supports_check_mode |
|
173 | 172 |
) |
174 | 173 |
|
175 | 174 |
# Override methods to force specific logic in the module to happen |
176 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
177 |
- obj.return_value = self.loaded_ifcs |
|
178 |
- |
|
179 |
- mm = ModuleManager(client) |
|
180 |
- mm.create_on_device = Mock(return_value=True) |
|
181 |
- mm.exists = Mock(return_value=False) |
|
175 |
+ mm = ModuleManager(module=module) |
|
176 |
+ mm.create_on_device = Mock(return_value=True) |
|
177 |
+ mm.exists = Mock(return_value=False) |
|
182 | 178 |
|
183 |
- results = mm.exec_module() |
|
179 |
+ results = mm.exec_module() |
|
184 | 180 |
|
185 | 181 |
assert results['changed'] is True |
186 |
- assert results['interfaces'] == [{'tagged': True, 'name': '2.1'}] |
|
182 |
+ assert results['tagged_interfaces'] == ['2.1'] |
|
187 | 183 |
assert results['tag'] == 213 |
188 |
- assert results['name'] == 'somevlan' |
|
189 | 184 |
|
190 | 185 |
def test_create_vlan_untagged_interface(self, *args): |
191 | 186 |
set_module_args(dict( |
... | ... |
@@ -197,25 +162,20 @@ class TestManager(unittest.TestCase): |
197 | 197 |
partition='Common' |
198 | 198 |
)) |
199 | 199 |
|
200 |
- client = AnsibleF5Client( |
|
200 |
+ module = AnsibleModule( |
|
201 | 201 |
argument_spec=self.spec.argument_spec, |
202 |
- supports_check_mode=self.spec.supports_check_mode, |
|
203 |
- f5_product_name=self.spec.f5_product_name |
|
202 |
+ supports_check_mode=self.spec.supports_check_mode |
|
204 | 203 |
) |
205 | 204 |
|
206 | 205 |
# Override methods to force specific logic in the module to happen |
207 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
208 |
- obj.return_value = self.loaded_ifcs |
|
206 |
+ mm = ModuleManager(module=module) |
|
207 |
+ mm.create_on_device = Mock(return_value=True) |
|
208 |
+ mm.exists = Mock(return_value=False) |
|
209 | 209 |
|
210 |
- mm = ModuleManager(client) |
|
211 |
- mm.create_on_device = Mock(return_value=True) |
|
212 |
- mm.exists = Mock(return_value=False) |
|
213 |
- |
|
214 |
- results = mm.exec_module() |
|
210 |
+ results = mm.exec_module() |
|
215 | 211 |
|
216 | 212 |
assert results['changed'] is True |
217 |
- assert results['interfaces'] == [{'untagged': True, 'name': '2.1'}] |
|
218 |
- assert results['name'] == 'somevlan' |
|
213 |
+ assert results['untagged_interfaces'] == ['2.1'] |
|
219 | 214 |
|
220 | 215 |
def test_create_vlan_tagged_interfaces(self, *args): |
221 | 216 |
set_module_args(dict( |
... | ... |
@@ -228,27 +188,21 @@ class TestManager(unittest.TestCase): |
228 | 228 |
partition='Common' |
229 | 229 |
)) |
230 | 230 |
|
231 |
- client = AnsibleF5Client( |
|
231 |
+ module = AnsibleModule( |
|
232 | 232 |
argument_spec=self.spec.argument_spec, |
233 |
- supports_check_mode=self.spec.supports_check_mode, |
|
234 |
- f5_product_name=self.spec.f5_product_name |
|
233 |
+ supports_check_mode=self.spec.supports_check_mode |
|
235 | 234 |
) |
236 | 235 |
|
237 | 236 |
# Override methods to force specific logic in the module to happen |
238 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
239 |
- obj.return_value = self.loaded_ifcs |
|
240 |
- |
|
241 |
- mm = ModuleManager(client) |
|
242 |
- mm.create_on_device = Mock(return_value=True) |
|
243 |
- mm.exists = Mock(return_value=False) |
|
237 |
+ mm = ModuleManager(module=module) |
|
238 |
+ mm.create_on_device = Mock(return_value=True) |
|
239 |
+ mm.exists = Mock(return_value=False) |
|
244 | 240 |
|
245 |
- results = mm.exec_module() |
|
241 |
+ results = mm.exec_module() |
|
246 | 242 |
|
247 | 243 |
assert results['changed'] is True |
248 |
- assert results['interfaces'] == [{'tagged': True, 'name': '2.1'}, |
|
249 |
- {'tagged': True, 'name': '1.1'}] |
|
244 |
+ assert results['tagged_interfaces'] == ['1.1', '2.1'] |
|
250 | 245 |
assert results['tag'] == 213 |
251 |
- assert results['name'] == 'somevlan' |
|
252 | 246 |
|
253 | 247 |
def test_create_vlan_untagged_interfaces(self, *args): |
254 | 248 |
set_module_args(dict( |
... | ... |
@@ -260,26 +214,20 @@ class TestManager(unittest.TestCase): |
260 | 260 |
partition='Common', |
261 | 261 |
)) |
262 | 262 |
|
263 |
- client = AnsibleF5Client( |
|
263 |
+ module = AnsibleModule( |
|
264 | 264 |
argument_spec=self.spec.argument_spec, |
265 |
- supports_check_mode=self.spec.supports_check_mode, |
|
266 |
- f5_product_name=self.spec.f5_product_name |
|
265 |
+ supports_check_mode=self.spec.supports_check_mode |
|
267 | 266 |
) |
268 | 267 |
|
269 | 268 |
# Override methods to force specific logic in the module to happen |
270 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
271 |
- obj.return_value = self.loaded_ifcs |
|
269 |
+ mm = ModuleManager(module=module) |
|
270 |
+ mm.create_on_device = Mock(return_value=True) |
|
271 |
+ mm.exists = Mock(return_value=False) |
|
272 | 272 |
|
273 |
- mm = ModuleManager(client) |
|
274 |
- mm.create_on_device = Mock(return_value=True) |
|
275 |
- mm.exists = Mock(return_value=False) |
|
276 |
- |
|
277 |
- results = mm.exec_module() |
|
273 |
+ results = mm.exec_module() |
|
278 | 274 |
|
279 | 275 |
assert results['changed'] is True |
280 |
- assert results['interfaces'] == [{'untagged': True, 'name': '2.1'}, |
|
281 |
- {'untagged': True, 'name': '1.1'}] |
|
282 |
- assert results['name'] == 'somevlan' |
|
276 |
+ assert results['untagged_interfaces'] == ['1.1', '2.1'] |
|
283 | 277 |
|
284 | 278 |
def test_update_vlan_untag_interface(self, *args): |
285 | 279 |
set_module_args(dict( |
... | ... |
@@ -291,32 +239,26 @@ class TestManager(unittest.TestCase): |
291 | 291 |
partition='Common', |
292 | 292 |
)) |
293 | 293 |
|
294 |
- client = AnsibleF5Client( |
|
294 |
+ module = AnsibleModule( |
|
295 | 295 |
argument_spec=self.spec.argument_spec, |
296 |
- supports_check_mode=self.spec.supports_check_mode, |
|
297 |
- f5_product_name=self.spec.f5_product_name |
|
296 |
+ supports_check_mode=self.spec.supports_check_mode |
|
298 | 297 |
) |
299 |
- ifcs = self.loaded_vlan_ifc_untag |
|
298 |
+ |
|
300 | 299 |
# Override methods to force specific logic in the module to happen |
301 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
302 |
- obj.return_value = self.loaded_ifcs |
|
303 |
- mm = ModuleManager(client) |
|
300 |
+ mm = ModuleManager(module=module) |
|
304 | 301 |
|
305 |
- current = ( |
|
306 |
- Parameters( |
|
307 |
- load_fixture('load_vlan.json') |
|
308 |
- ), |
|
309 |
- ifcs |
|
310 |
- ) |
|
302 |
+ current = ApiParameters(params=load_fixture('load_vlan.json')) |
|
303 |
+ interfaces = load_fixture('load_vlan_interfaces.json') |
|
304 |
+ current.update({'interfaces': interfaces}) |
|
311 | 305 |
|
312 |
- mm.update_on_device = Mock(return_value=True) |
|
313 |
- mm.exists = Mock(return_value=True) |
|
314 |
- mm.read_current_from_device = Mock(return_value=current) |
|
306 |
+ mm.update_on_device = Mock(return_value=True) |
|
307 |
+ mm.exists = Mock(return_value=True) |
|
308 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
315 | 309 |
|
316 |
- results = mm.exec_module() |
|
310 |
+ results = mm.exec_module() |
|
317 | 311 |
|
318 | 312 |
assert results['changed'] is True |
319 |
- assert results['interfaces'] == [{'untagged': True, 'name': '2.1'}] |
|
313 |
+ assert results['untagged_interfaces'] == ['2.1'] |
|
320 | 314 |
|
321 | 315 |
def test_update_vlan_tag_interface(self, *args): |
322 | 316 |
set_module_args(dict( |
... | ... |
@@ -328,32 +270,24 @@ class TestManager(unittest.TestCase): |
328 | 328 |
partition='Common', |
329 | 329 |
)) |
330 | 330 |
|
331 |
- client = AnsibleF5Client( |
|
331 |
+ module = AnsibleModule( |
|
332 | 332 |
argument_spec=self.spec.argument_spec, |
333 |
- supports_check_mode=self.spec.supports_check_mode, |
|
334 |
- f5_product_name=self.spec.f5_product_name |
|
333 |
+ supports_check_mode=self.spec.supports_check_mode |
|
335 | 334 |
) |
336 |
- ifcs = self.loaded_vlan_ifc_tag |
|
335 |
+ |
|
337 | 336 |
# Override methods to force specific logic in the module to happen |
338 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
339 |
- obj.return_value = self.loaded_ifcs |
|
340 |
- mm = ModuleManager(client) |
|
337 |
+ mm = ModuleManager(module=module) |
|
341 | 338 |
|
342 |
- current = ( |
|
343 |
- Parameters( |
|
344 |
- load_fixture('load_vlan.json') |
|
345 |
- ), |
|
346 |
- ifcs |
|
347 |
- ) |
|
339 |
+ current = ApiParameters(params=load_fixture('load_vlan.json')) |
|
348 | 340 |
|
349 |
- mm.update_on_device = Mock(return_value=True) |
|
350 |
- mm.exists = Mock(return_value=True) |
|
351 |
- mm.read_current_from_device = Mock(return_value=current) |
|
341 |
+ mm.update_on_device = Mock(return_value=True) |
|
342 |
+ mm.exists = Mock(return_value=True) |
|
343 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
352 | 344 |
|
353 |
- results = mm.exec_module() |
|
345 |
+ results = mm.exec_module() |
|
354 | 346 |
|
355 | 347 |
assert results['changed'] is True |
356 |
- assert results['interfaces'] == [{'tagged': True, 'name': '2.1'}] |
|
348 |
+ assert results['tagged_interfaces'] == ['2.1'] |
|
357 | 349 |
|
358 | 350 |
def test_update_vlan_description(self, *args): |
359 | 351 |
set_module_args(dict( |
... | ... |
@@ -365,117 +299,21 @@ class TestManager(unittest.TestCase): |
365 | 365 |
partition='Common', |
366 | 366 |
)) |
367 | 367 |
|
368 |
- client = AnsibleF5Client( |
|
368 |
+ module = AnsibleModule( |
|
369 | 369 |
argument_spec=self.spec.argument_spec, |
370 |
- supports_check_mode=self.spec.supports_check_mode, |
|
371 |
- f5_product_name=self.spec.f5_product_name |
|
370 |
+ supports_check_mode=self.spec.supports_check_mode |
|
372 | 371 |
) |
373 |
- ifcs = self.loaded_vlan_ifc_tag |
|
372 |
+ |
|
374 | 373 |
# Override methods to force specific logic in the module to happen |
375 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
376 |
- obj.return_value = self.loaded_ifcs |
|
377 |
- mm = ModuleManager(client) |
|
374 |
+ mm = ModuleManager(module=module) |
|
378 | 375 |
|
379 |
- current = ( |
|
380 |
- Parameters( |
|
381 |
- load_fixture('update_vlan_description.json') |
|
382 |
- ), |
|
383 |
- ifcs |
|
384 |
- ) |
|
376 |
+ current = ApiParameters(params=load_fixture('update_vlan_description.json')) |
|
385 | 377 |
|
386 |
- mm.update_on_device = Mock(return_value=True) |
|
387 |
- mm.exists = Mock(return_value=True) |
|
388 |
- mm.read_current_from_device = Mock(return_value=current) |
|
378 |
+ mm.update_on_device = Mock(return_value=True) |
|
379 |
+ mm.exists = Mock(return_value=True) |
|
380 |
+ mm.read_current_from_device = Mock(return_value=current) |
|
389 | 381 |
|
390 |
- results = mm.exec_module() |
|
382 |
+ results = mm.exec_module() |
|
391 | 383 |
|
392 | 384 |
assert results['changed'] is True |
393 | 385 |
assert results['description'] == 'changed_that' |
394 |
- |
|
395 |
- def test_untagged_ifc_raises(self, *args): |
|
396 |
- set_module_args(dict( |
|
397 |
- name='somevlan', |
|
398 |
- untagged_interface=['10.2'], |
|
399 |
- server='localhost', |
|
400 |
- password='password', |
|
401 |
- user='admin', |
|
402 |
- partition='Common' |
|
403 |
- )) |
|
404 |
- |
|
405 |
- client = AnsibleF5Client( |
|
406 |
- argument_spec=self.spec.argument_spec, |
|
407 |
- supports_check_mode=self.spec.supports_check_mode, |
|
408 |
- f5_product_name=self.spec.f5_product_name |
|
409 |
- ) |
|
410 |
- msg = 'The specified interface "10.2" was not found' |
|
411 |
- # Override methods to force specific logic in the module to happen |
|
412 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
413 |
- obj.return_value = self.loaded_ifcs |
|
414 |
- |
|
415 |
- mm = ModuleManager(client) |
|
416 |
- mm.create_on_device = Mock(return_value=True) |
|
417 |
- mm.exists = Mock(return_value=False) |
|
418 |
- |
|
419 |
- with pytest.raises(F5ModuleError) as err: |
|
420 |
- mm.exec_module() |
|
421 |
- |
|
422 |
- assert str(err.value) == msg |
|
423 |
- |
|
424 |
- def test_tagged_ifc_raises(self, *args): |
|
425 |
- set_module_args(dict( |
|
426 |
- name='somevlan', |
|
427 |
- tagged_interface=['10.2'], |
|
428 |
- tag=213, |
|
429 |
- server='localhost', |
|
430 |
- password='password', |
|
431 |
- user='admin', |
|
432 |
- partition='Common' |
|
433 |
- )) |
|
434 |
- |
|
435 |
- client = AnsibleF5Client( |
|
436 |
- argument_spec=self.spec.argument_spec, |
|
437 |
- supports_check_mode=self.spec.supports_check_mode, |
|
438 |
- f5_product_name=self.spec.f5_product_name |
|
439 |
- ) |
|
440 |
- msg = 'The specified interface "10.2" was not found' |
|
441 |
- # Override methods to force specific logic in the module to happen |
|
442 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
443 |
- obj.return_value = self.loaded_ifcs |
|
444 |
- |
|
445 |
- mm = ModuleManager(client) |
|
446 |
- mm.create_on_device = Mock(return_value=True) |
|
447 |
- mm.exists = Mock(return_value=False) |
|
448 |
- |
|
449 |
- with pytest.raises(F5ModuleError) as err: |
|
450 |
- mm.exec_module() |
|
451 |
- |
|
452 |
- assert str(err.value) == msg |
|
453 |
- |
|
454 |
- def test_parse_return_ifcs_raises(self, *args): |
|
455 |
- set_module_args(dict( |
|
456 |
- name='somevlan', |
|
457 |
- untagged_interface=['1.2'], |
|
458 |
- server='localhost', |
|
459 |
- password='password', |
|
460 |
- user='admin', |
|
461 |
- partition='Common' |
|
462 |
- )) |
|
463 |
- |
|
464 |
- client = AnsibleF5Client( |
|
465 |
- argument_spec=self.spec.argument_spec, |
|
466 |
- supports_check_mode=self.spec.supports_check_mode, |
|
467 |
- f5_product_name=self.spec.f5_product_name |
|
468 |
- ) |
|
469 |
- msg = 'No interfaces were found' |
|
470 |
- # Override methods to force specific logic in the module to happen |
|
471 |
- with patch.object(Parameters, '_get_interfaces_from_device') as obj: |
|
472 |
- obj.return_value = [] |
|
473 |
- |
|
474 |
- mm = ModuleManager(client) |
|
475 |
- mm.create_on_device = Mock(return_value=True) |
|
476 |
- mm.exists = Mock(return_value=False) |
|
477 |
- |
|
478 |
- with pytest.raises(F5ModuleError) as err: |
|
479 |
- mm.exec_module() |
|
480 |
- |
|
481 |
- assert str(err.value) == msg |
... | ... |
@@ -18,23 +18,22 @@ if sys.version_info < (2, 7): |
18 | 18 |
from ansible.compat.tests import unittest |
19 | 19 |
from ansible.compat.tests.mock import Mock |
20 | 20 |
from ansible.compat.tests.mock import patch |
21 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
22 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
21 |
+from ansible.module_utils.basic import AnsibleModule |
|
23 | 22 |
|
24 | 23 |
try: |
25 | 24 |
from library.bigip_wait import Parameters |
26 | 25 |
from library.bigip_wait import ModuleManager |
27 | 26 |
from library.bigip_wait import ArgumentSpec |
28 |
- from library.bigip_wait import AnsibleF5ClientStub |
|
29 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
27 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
28 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
30 | 29 |
from test.unit.modules.utils import set_module_args |
31 | 30 |
except ImportError: |
32 | 31 |
try: |
33 | 32 |
from ansible.modules.network.f5.bigip_wait import Parameters |
34 | 33 |
from ansible.modules.network.f5.bigip_wait import ModuleManager |
35 | 34 |
from ansible.modules.network.f5.bigip_wait import ArgumentSpec |
36 |
- from ansible.modules.network.f5.bigip_wait import AnsibleF5ClientStub |
|
37 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
35 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
36 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
38 | 37 |
from units.modules.utils import set_module_args |
39 | 38 |
except ImportError: |
40 | 39 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -70,7 +69,7 @@ class TestParameters(unittest.TestCase): |
70 | 70 |
msg='We timed out during waiting for BIG-IP :-(' |
71 | 71 |
) |
72 | 72 |
|
73 |
- p = Parameters(args) |
|
73 |
+ p = Parameters(params=args) |
|
74 | 74 |
assert p.delay == 3 |
75 | 75 |
assert p.timeout == 500 |
76 | 76 |
assert p.sleep == 10 |
... | ... |
@@ -84,15 +83,13 @@ class TestParameters(unittest.TestCase): |
84 | 84 |
msg='We timed out during waiting for BIG-IP :-(' |
85 | 85 |
) |
86 | 86 |
|
87 |
- p = Parameters(args) |
|
87 |
+ p = Parameters(params=args) |
|
88 | 88 |
assert p.delay == 3 |
89 | 89 |
assert p.timeout == 500 |
90 | 90 |
assert p.sleep == 10 |
91 | 91 |
assert p.msg == 'We timed out during waiting for BIG-IP :-(' |
92 | 92 |
|
93 | 93 |
|
94 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
95 |
- return_value=True) |
|
96 | 94 |
class TestManager(unittest.TestCase): |
97 | 95 |
def setUp(self): |
98 | 96 |
self.spec = ArgumentSpec() |
... | ... |
@@ -104,14 +101,13 @@ class TestManager(unittest.TestCase): |
104 | 104 |
user='admin' |
105 | 105 |
)) |
106 | 106 |
|
107 |
- client = AnsibleF5ClientStub( |
|
107 |
+ module = AnsibleModule( |
|
108 | 108 |
argument_spec=self.spec.argument_spec, |
109 |
- supports_check_mode=self.spec.supports_check_mode, |
|
110 |
- f5_product_name=self.spec.f5_product_name |
|
109 |
+ supports_check_mode=self.spec.supports_check_mode |
|
111 | 110 |
) |
112 | 111 |
|
113 | 112 |
# Override methods to force specific logic in the module to happen |
114 |
- mm = ModuleManager(client) |
|
113 |
+ mm = ModuleManager(module=module) |
|
115 | 114 |
mm._connect_to_device = Mock(return_value=True) |
116 | 115 |
mm._device_is_rebooting = Mock(return_value=False) |
117 | 116 |
mm._is_mprov_running_on_device = Mock(return_value=False) |
... | ... |
@@ -18,15 +18,15 @@ if sys.version_info < (2, 7): |
18 | 18 |
from ansible.compat.tests import unittest |
19 | 19 |
from ansible.compat.tests.mock import Mock |
20 | 20 |
from ansible.compat.tests.mock import patch |
21 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
22 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
21 |
+from ansible.module_utils.basic import AnsibleModule |
|
23 | 22 |
|
24 | 23 |
try: |
25 | 24 |
from library.bigiq_regkey_license import ModuleParameters |
26 | 25 |
from library.bigiq_regkey_license import ApiParameters |
27 | 26 |
from library.bigiq_regkey_license import ModuleManager |
28 | 27 |
from library.bigiq_regkey_license import ArgumentSpec |
29 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
28 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
29 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
30 | 30 |
from test.unit.modules.utils import set_module_args |
31 | 31 |
except ImportError: |
32 | 32 |
try: |
... | ... |
@@ -34,7 +34,8 @@ except ImportError: |
34 | 34 |
from ansible.modules.network.f5.bigiq_regkey_license import ApiParameters |
35 | 35 |
from ansible.modules.network.f5.bigiq_regkey_license import ModuleManager |
36 | 36 |
from ansible.modules.network.f5.bigiq_regkey_license import ArgumentSpec |
37 |
- from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError |
|
37 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
38 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
38 | 39 |
from units.modules.utils import set_module_args |
39 | 40 |
except ImportError: |
40 | 41 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -70,7 +71,7 @@ class TestParameters(unittest.TestCase): |
70 | 70 |
description='this is a description' |
71 | 71 |
) |
72 | 72 |
|
73 |
- p = ModuleParameters(args) |
|
73 |
+ p = ModuleParameters(params=args) |
|
74 | 74 |
assert p.regkey_pool == 'foo' |
75 | 75 |
assert p.license_key == 'XXXX-XXXX-XXXX-XXXX-XXXX' |
76 | 76 |
assert p.accept_eula is True |
... | ... |
@@ -79,12 +80,10 @@ class TestParameters(unittest.TestCase): |
79 | 79 |
def test_api_parameters(self): |
80 | 80 |
args = load_fixture('load_regkey_license_key.json') |
81 | 81 |
|
82 |
- p = ApiParameters(args) |
|
82 |
+ p = ApiParameters(params=args) |
|
83 | 83 |
assert p.description == 'foo bar baz' |
84 | 84 |
|
85 | 85 |
|
86 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
87 |
- return_value=True) |
|
88 | 86 |
class TestManager(unittest.TestCase): |
89 | 87 |
|
90 | 88 |
def setUp(self): |
... | ... |
@@ -101,12 +100,11 @@ class TestManager(unittest.TestCase): |
101 | 101 |
user='admin' |
102 | 102 |
)) |
103 | 103 |
|
104 |
- client = AnsibleF5Client( |
|
104 |
+ module = AnsibleModule( |
|
105 | 105 |
argument_spec=self.spec.argument_spec, |
106 |
- supports_check_mode=self.spec.supports_check_mode, |
|
107 |
- f5_product_name=self.spec.f5_product_name |
|
106 |
+ supports_check_mode=self.spec.supports_check_mode |
|
108 | 107 |
) |
109 |
- mm = ModuleManager(client) |
|
108 |
+ mm = ModuleManager(module=module) |
|
110 | 109 |
|
111 | 110 |
# Override methods to force specific logic in the module to happen |
112 | 111 |
mm.exists = Mock(side_effect=[False, True]) |
... | ... |
@@ -18,14 +18,15 @@ if sys.version_info < (2, 7): |
18 | 18 |
from ansible.compat.tests import unittest |
19 | 19 |
from ansible.compat.tests.mock import Mock |
20 | 20 |
from ansible.compat.tests.mock import patch |
21 |
-from ansible.module_utils.f5_utils import AnsibleF5Client |
|
22 |
-from ansible.module_utils.f5_utils import F5ModuleError |
|
21 |
+from ansible.module_utils.basic import AnsibleModule |
|
23 | 22 |
|
24 | 23 |
try: |
25 | 24 |
from library.bigiq_regkey_pool import ModuleParameters |
26 | 25 |
from library.bigiq_regkey_pool import ApiParameters |
27 | 26 |
from library.bigiq_regkey_pool import ModuleManager |
28 | 27 |
from library.bigiq_regkey_pool import ArgumentSpec |
28 |
+ from library.module_utils.network.f5.common import F5ModuleError |
|
29 |
+ from library.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
29 | 30 |
from test.unit.modules.utils import set_module_args |
30 | 31 |
except ImportError: |
31 | 32 |
try: |
... | ... |
@@ -33,6 +34,8 @@ except ImportError: |
33 | 33 |
from ansible.modules.network.f5.bigiq_regkey_pool import ApiParameters |
34 | 34 |
from ansible.modules.network.f5.bigiq_regkey_pool import ModuleManager |
35 | 35 |
from ansible.modules.network.f5.bigiq_regkey_pool import ArgumentSpec |
36 |
+ from ansible.module_utils.network.f5.common import F5ModuleError |
|
37 |
+ from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError |
|
36 | 38 |
from units.modules.utils import set_module_args |
37 | 39 |
except ImportError: |
38 | 40 |
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") |
... | ... |
@@ -65,18 +68,16 @@ class TestParameters(unittest.TestCase): |
65 | 65 |
description='this is a description' |
66 | 66 |
) |
67 | 67 |
|
68 |
- p = ModuleParameters(args) |
|
68 |
+ p = ModuleParameters(params=args) |
|
69 | 69 |
assert p.description == 'this is a description' |
70 | 70 |
|
71 | 71 |
def test_api_parameters(self): |
72 | 72 |
args = load_fixture('load_regkey_license_pool.json') |
73 | 73 |
|
74 |
- p = ApiParameters(args) |
|
74 |
+ p = ApiParameters(params=args) |
|
75 | 75 |
assert p.description == 'this is a description' |
76 | 76 |
|
77 | 77 |
|
78 |
-@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root', |
|
79 |
- return_value=True) |
|
80 | 78 |
class TestManager(unittest.TestCase): |
81 | 79 |
|
82 | 80 |
def setUp(self): |
... | ... |
@@ -91,14 +92,13 @@ class TestManager(unittest.TestCase): |
91 | 91 |
user='admin' |
92 | 92 |
)) |
93 | 93 |
|
94 |
- client = AnsibleF5Client( |
|
94 |
+ module = AnsibleModule( |
|
95 | 95 |
argument_spec=self.spec.argument_spec, |
96 |
- supports_check_mode=self.spec.supports_check_mode, |
|
97 |
- f5_product_name=self.spec.f5_product_name |
|
96 |
+ supports_check_mode=self.spec.supports_check_mode |
|
98 | 97 |
) |
99 | 98 |
|
100 | 99 |
# Override methods in the specific type of manager |
101 |
- mm = ModuleManager(client) |
|
100 |
+ mm = ModuleManager(module=module) |
|
102 | 101 |
mm.exists = Mock(return_value=False) |
103 | 102 |
mm.create_on_device = Mock(return_value=True) |
104 | 103 |
|