PageRenderTime 35ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/salt/states/bigip.py

https://bitbucket.org/bhuvanchandradv/salt
Python | 3087 lines | 2508 code | 111 blank | 468 comment | 87 complexity | 45e814e162e0688a772174baa1053801 MD5 | raw file
Possible License(s): Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. # -*- coding: utf-8 -*-
  2. '''
  3. A state module designed to enforce load-balancing configurations for F5 Big-IP entities.
  4. :maturity: develop
  5. :platform: f5_bigip_11.6
  6. '''
  7. # Import Python libs
  8. from __future__ import absolute_import
  9. import json
  10. # Import 3rd-party libs
  11. import salt.ext.six as six
  12. #set up virtual function
  13. def __virtual__():
  14. '''
  15. Only load if the bigip exec module is available in __salt__
  16. '''
  17. return 'bigip' if 'bigip.list_transaction' in __salt__ else False
  18. def _load_result(response, ret):
  19. '''
  20. format the results of listing functions
  21. '''
  22. #were we able to connect?
  23. if response['code'] is None:
  24. ret['comment'] = response['content']
  25. #forbidden?
  26. elif response['code'] == 401:
  27. ret['comment'] = '401 Forbidden: Authentication required!'
  28. #Not found?
  29. elif response['code'] == 404:
  30. ret['comment'] = response['content']['message']
  31. #200?
  32. elif response['code'] == 200:
  33. ret['result'] = True
  34. ret['comment'] = 'Listing Current Configuration Only. ' \
  35. 'Not action or changes occurred during the execution of this state.'
  36. ret['changes'] = response['content']
  37. #something bad
  38. else:
  39. ret['comment'] = response['content']['message']
  40. return ret
  41. def _strip_key(dictionary, keyword):
  42. '''
  43. look for a certain key within a dictionary and nullify ti's contents, check within nested
  44. dictionaries and lists as well. Certain attributes such as "generation" will change even
  45. when there were no changes made to the entity.
  46. '''
  47. for key, value in six.iteritems(dictionary):
  48. if key == keyword:
  49. dictionary[key] = None
  50. elif isinstance(value, dict):
  51. _strip_key(value, keyword)
  52. elif isinstance(value, list):
  53. for item in value:
  54. if isinstance(item, dict):
  55. _strip_key(item, keyword)
  56. return dictionary
  57. def _check_for_changes(entity_type, ret, existing, modified):
  58. '''
  59. take an existing entity and a modified entity and check for changes.
  60. '''
  61. ret['result'] = True
  62. #were there any changes? generation always changes, remove it.
  63. if isinstance(existing, dict) and isinstance(modified, dict):
  64. if 'generation' in modified['content'].keys():
  65. del modified['content']['generation']
  66. if 'generation' in existing['content'].keys():
  67. del existing['content']['generation']
  68. if cmp(modified['content'], existing['content']) == 0:
  69. ret['comment'] = '{entity_type} is currently enforced to the desired state. No changes made.'.format(entity_type=entity_type)
  70. else:
  71. ret['comment'] = '{entity_type} was enforced to the desired state. Note: Only parameters specified ' \
  72. 'were enforced. See changes for details.'.format(entity_type=entity_type)
  73. ret['changes']['old'] = existing['content']
  74. ret['changes']['new'] = modified['content']
  75. else:
  76. if cmp(modified, existing) == 0:
  77. ret['comment'] = '{entity_type} is currently enforced to the desired state. No changes made.'.format(entity_type=entity_type)
  78. else:
  79. ret['comment'] = '{entity_type} was enforced to the desired state. Note: Only parameters specified ' \
  80. 'were enforced. See changes for details.'.format(entity_type=entity_type)
  81. ret['changes']['old'] = existing
  82. ret['changes']['new'] = modified
  83. return ret
  84. def _test_output(ret, action, params):
  85. '''
  86. For testing just output what the state will attempt to do without actually doing it.
  87. '''
  88. if action == 'list':
  89. ret['comment'] += 'The list action will just list an entity and will make no changes.\n'
  90. elif action == 'create' or action == 'add':
  91. ret['comment'] += 'The create action will attempt to create an entity if it does not already exist.\n'
  92. elif action == 'delete':
  93. ret['comment'] += 'The delete action will attempt to delete an existing entity if it exists.\n'
  94. elif action == 'manage':
  95. ret['comment'] += 'The manage action will create a new entity if it does not exist. If it does exist, it will be enforced' \
  96. 'to the desired state.\n'
  97. elif action == 'modify':
  98. ret['comment'] += 'The modify action will attempt to modify an existing entity only if it exists.\n'
  99. ret['comment'] += 'An iControl REST Request will be made using the parameters:\n'
  100. ret['comment'] += json.dumps(params, indent=4)
  101. ret['changes'] = {}
  102. # Return ``None`` when running with ``test=true``.
  103. ret['result'] = None
  104. return ret
  105. def list_node(hostname, username, password, name):
  106. '''
  107. A function to connect to a bigip device and list a specific node.
  108. hostname
  109. The host/address of the bigip device
  110. username
  111. The iControl REST username
  112. password
  113. The iControl REST password
  114. name
  115. The name of the node to list.
  116. '''
  117. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  118. if __opts__['test']:
  119. return _test_output(ret, 'list', params={
  120. 'hostname': hostname,
  121. 'username': username,
  122. 'password': password,
  123. 'name': name
  124. }
  125. )
  126. response = __salt__['bigip.list_node'](hostname, username, password, name)
  127. return _load_result(response, ret)
  128. def create_node(hostname, username, password, name, address):
  129. '''
  130. Create a new node if it does not already exist.
  131. hostname
  132. The host/address of the bigip device
  133. username
  134. The iControl REST username
  135. password
  136. The iControl REST password
  137. name
  138. The name of the node to create
  139. address
  140. The address of the node
  141. '''
  142. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  143. if __opts__['test']:
  144. return _test_output(ret, 'create', params={
  145. 'hostname': hostname,
  146. 'username': username,
  147. 'password': password,
  148. 'name': name,
  149. 'address': address
  150. }
  151. )
  152. #is this node currently configured?
  153. existing = __salt__['bigip.list_node'](hostname, username, password, name)
  154. # if it exists
  155. if existing['code'] == 200:
  156. ret['result'] = True
  157. ret['comment'] = 'A node by this name currently exists. No change made.'
  158. # if it doesn't exist
  159. elif existing['code'] == 404:
  160. response = __salt__['bigip.create_node'](hostname, username, password, name, address)
  161. ret['result'] = True
  162. ret['changes']['old'] = {}
  163. ret['changes']['new'] = response['content']
  164. ret['comment'] = 'Node was successfully created.'
  165. # else something else was returned
  166. else:
  167. ret = _load_result(existing, ret)
  168. return ret
  169. def manage_node(hostname, username, password, name, address,
  170. connection_limit=None,
  171. description=None,
  172. dynamic_ratio=None,
  173. logging=None,
  174. monitor=None,
  175. rate_limit=None,
  176. ratio=None,
  177. session=None,
  178. node_state=None):
  179. '''
  180. Manages a node of a given bigip device. If the node does not exist it will be created, otherwise,
  181. only the properties which are different than the existing will be updated.
  182. hostname
  183. The host/address of the bigip device
  184. username
  185. The iControl REST username
  186. password
  187. The iControl REST password
  188. name
  189. The name of the node to manage.
  190. address
  191. The address of the node
  192. connection_limit
  193. [integer]
  194. description
  195. [string]
  196. dynam
  197. c_ratio: [integer]
  198. logging
  199. [enabled | disabled]
  200. monitor
  201. [[name] | none | default]
  202. rate_limit
  203. [integer]
  204. ratio
  205. [integer]
  206. session
  207. [user-enabled | user-disabled]
  208. node_state (state)
  209. [user-down | user-up ]
  210. '''
  211. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  212. if __opts__['test']:
  213. return _test_output(ret, 'manage', params={
  214. 'hostname': hostname,
  215. 'username': username,
  216. 'password': password,
  217. 'name': name,
  218. 'address': address,
  219. 'connection_limit': connection_limit,
  220. 'description': description,
  221. 'dynamic_ratio': dynamic_ratio,
  222. 'logging': logging,
  223. 'monitor': monitor,
  224. 'rate_limit': rate_limit,
  225. 'ratio': ratio,
  226. 'session': session,
  227. 'state:': node_state
  228. }
  229. )
  230. #is this node currently configured?
  231. existing = __salt__['bigip.list_node'](hostname, username, password, name)
  232. # if it exists by name
  233. if existing['code'] == 200:
  234. # ensure the address is the same, we don't want to modify a different node than what
  235. # we think we are managing
  236. if existing['content']['address'] != address:
  237. ret['result'] = False
  238. ret['comment'] = 'A node with this name exists but the address does not match.'
  239. modified = __salt__['bigip.modify_node'](hostname=hostname,
  240. username=username,
  241. password=password,
  242. name=name,
  243. connection_limit=connection_limit,
  244. description=description,
  245. dynamic_ratio=dynamic_ratio,
  246. logging=logging,
  247. monitor=monitor,
  248. rate_limit=rate_limit,
  249. ratio=ratio,
  250. session=session,
  251. state=node_state)
  252. #was the modification successful?
  253. if modified['code'] == 200:
  254. ret = _check_for_changes('Node', ret, existing, modified)
  255. else:
  256. ret = _load_result(modified, ret)
  257. # not found, attempt to create it
  258. elif existing['code'] == 404:
  259. new = __salt__['bigip.create_node'](hostname, username, password, name, address)
  260. # were we able to create it?
  261. if new['code'] == 200:
  262. # try modification
  263. modified = __salt__['bigip.modify_node'](hostname=hostname,
  264. username=username,
  265. password=password,
  266. name=name,
  267. connection_limit=connection_limit,
  268. description=description,
  269. dynamic_ratio=dynamic_ratio,
  270. logging=logging,
  271. monitor=monitor,
  272. rate_limit=rate_limit,
  273. ratio=ratio,
  274. session=session,
  275. state=node_state)
  276. #was the modification successful?
  277. if modified['code'] == 200:
  278. ret['result'] = True
  279. ret['comment'] = 'Node was created and enforced to the desired state. Note: Only parameters specified ' \
  280. 'were enforced. See changes for details.'
  281. ret['changes']['old'] = {}
  282. ret['changes']['new'] = modified['content']
  283. # roll it back
  284. else:
  285. deleted = __salt__['bigip.delete_node'](hostname, username, password, name)
  286. # did we get rid of it?
  287. if deleted['code'] == 200:
  288. ret['comment'] = 'Node was successfully created but an error occurred during modification. ' \
  289. 'The creation of the node has been rolled back. Message is as follows:\n' \
  290. '{message}'.format(message=modified['content']['message'])
  291. # something bad happened
  292. else:
  293. ret['comment'] = 'Node was successfully created but an error occurred during modification. ' \
  294. 'The creation of the node was not able to be rolled back. Message is as follows:' \
  295. '\n {message}\n{message_two}'.format(message=modified['content']['message'],
  296. message_two=deleted['content']['message'])
  297. # unable to create it
  298. else:
  299. ret = _load_result(new, ret)
  300. # an error occurred
  301. else:
  302. ret = _load_result(existing, ret)
  303. return ret
  304. def modify_node(hostname, username, password, name,
  305. connection_limit=None,
  306. description=None,
  307. dynamic_ratio=None,
  308. logging=None,
  309. monitor=None,
  310. rate_limit=None,
  311. ratio=None,
  312. session=None,
  313. node_state=None):
  314. '''
  315. Modify an existing node. Only a node which already exists will be modified and
  316. only the parameters specified will be enforced.
  317. hostname
  318. The host/address of the bigip device
  319. username
  320. The iControl REST username
  321. password
  322. The iControl REST password
  323. name
  324. The name of the node to modify
  325. connection_limit
  326. [integer]
  327. description
  328. [string]
  329. dynamic_ratio
  330. [integer]
  331. logging
  332. [enabled | disabled]
  333. monitor
  334. [[name] | none | default]
  335. rate_limit
  336. [integer]
  337. ratio
  338. [integer]
  339. session
  340. [user-enabled | user-disabled]
  341. node_state (state)
  342. [user-down | user-up ]
  343. '''
  344. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  345. if __opts__['test']:
  346. return _test_output(ret, 'modify', params={
  347. 'hostname': hostname,
  348. 'username': username,
  349. 'password': password,
  350. 'name': name,
  351. 'connection_limit': connection_limit,
  352. 'description': description,
  353. 'dynamic_ratio': dynamic_ratio,
  354. 'logging': logging,
  355. 'monitor': monitor,
  356. 'rate_limit': rate_limit,
  357. 'ratio': ratio,
  358. 'session': session,
  359. 'state:': node_state
  360. }
  361. )
  362. #is this node currently configured?
  363. existing = __salt__['bigip.list_node'](hostname, username, password, name)
  364. # if it exists by name
  365. if existing['code'] == 200:
  366. modified = __salt__['bigip.modify_node'](hostname=hostname,
  367. username=username,
  368. password=password,
  369. name=name,
  370. connection_limit=connection_limit,
  371. description=description,
  372. dynamic_ratio=dynamic_ratio,
  373. logging=logging,
  374. monitor=monitor,
  375. rate_limit=rate_limit,
  376. ratio=ratio,
  377. session=session,
  378. state=node_state)
  379. #was the modification successful?
  380. if modified['code'] == 200:
  381. ret = _check_for_changes('Node', ret, existing, modified)
  382. else:
  383. ret = _load_result(modified, ret)
  384. # not found, attempt to create it
  385. elif existing['code'] == 404:
  386. ret['comment'] = 'A node with this name was not found.'
  387. # an error occurred
  388. else:
  389. ret = _load_result(existing, ret)
  390. return ret
  391. def delete_node(hostname, username, password, name):
  392. '''
  393. Delete an existing node.
  394. hostname
  395. The host/address of the bigip device
  396. username
  397. The iControl REST username
  398. password
  399. The iControl REST password
  400. name
  401. The name of the node which will be deleted.
  402. '''
  403. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  404. if __opts__['test']:
  405. return _test_output(ret, 'delete', params={
  406. 'hostname': hostname,
  407. 'username': username,
  408. 'password': password,
  409. 'name': name,
  410. }
  411. )
  412. #is this node currently configured?
  413. existing = __salt__['bigip.list_node'](hostname, username, password, name)
  414. # if it exists by name
  415. if existing['code'] == 200:
  416. deleted = __salt__['bigip.delete_node'](hostname, username, password, name)
  417. # did we get rid of it?
  418. if deleted['code'] == 200:
  419. ret['result'] = True
  420. ret['comment'] = 'Node was successfully deleted.'
  421. ret['changes']['old'] = existing['content']
  422. ret['changes']['new'] = {}
  423. # something bad happened
  424. else:
  425. ret = _load_result(existing, ret)
  426. # not found
  427. elif existing['code'] == 404:
  428. ret['result'] = True
  429. ret['comment'] = 'This node already does not exist. No changes made.'
  430. ret['changes']['old'] = {}
  431. ret['changes']['new'] = {}
  432. else:
  433. ret = _load_result(existing, ret)
  434. return ret
  435. def list_pool(hostname, username, password, name):
  436. '''
  437. A function to connect to a bigip device and list a specific pool.
  438. hostname
  439. The host/address of the bigip device
  440. username
  441. The iControl REST username
  442. password
  443. The iControl REST password
  444. name
  445. The name of the pool to list.
  446. '''
  447. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  448. if __opts__['test']:
  449. return _test_output(ret, 'list', params={
  450. 'hostname': hostname,
  451. 'username': username,
  452. 'password': password,
  453. 'name': name,
  454. }
  455. )
  456. response = __salt__['bigip.list_pool'](hostname, username, password, name)
  457. return _load_result(response, ret)
  458. def create_pool(hostname, username, password, name, members=None,
  459. allow_nat=None,
  460. allow_snat=None,
  461. description=None,
  462. gateway_failsafe_device=None,
  463. ignore_persisted_weight=None,
  464. ip_tos_to_client=None,
  465. ip_tos_to_server=None,
  466. link_qos_to_client=None,
  467. link_qos_to_server=None,
  468. load_balancing_mode=None,
  469. min_active_members=None,
  470. min_up_members=None,
  471. min_up_members_action=None,
  472. min_up_members_checking=None,
  473. monitor=None,
  474. profiles=None,
  475. queue_depth_limit=None,
  476. queue_on_connection_limit=None,
  477. queue_time_limit=None,
  478. reselect_tries=None,
  479. service_down_action=None,
  480. slow_ramp_time=None):
  481. '''
  482. Create a new node if it does not already exist.
  483. hostname
  484. The host/address of the bigip device
  485. username
  486. The iControl REST username
  487. password
  488. The iControl REST password
  489. name
  490. The name of the pool to create
  491. members
  492. List of members to be added to the pool
  493. allow_nat
  494. [yes | no]
  495. allow_snat
  496. [yes | no]
  497. description
  498. [string]
  499. gateway_failsafe_device
  500. [string]
  501. ignore_persisted_weight
  502. [enabled | disabled]
  503. ip_tos_to_client
  504. [pass-through | [integer]]
  505. ip_tos_to_server
  506. [pass-through | [integer]]
  507. link_qos_to_client
  508. [pass-through | [integer]]
  509. link_qos_to_server
  510. [pass-through | [integer]]
  511. load_balancing_mode
  512. [dynamic-ratio-member | dynamic-ratio-node |
  513. fastest-app-response | fastest-node |
  514. least-connections-members |
  515. least-connections-node |
  516. least-sessions |
  517. observed-member | observed-node |
  518. predictive-member | predictive-node |
  519. ratio-least-connections-member |
  520. ratio-least-connections-node |
  521. ratio-member | ratio-node | ratio-session |
  522. round-robin | weighted-least-connections-member |
  523. weighted-least-connections-node]
  524. min_active_members
  525. [integer]
  526. min_up_members
  527. [integer]
  528. min_up_members_action
  529. [failover | reboot | restart-all]
  530. min_up_members_checking
  531. [enabled | disabled]
  532. monitor
  533. [name]
  534. profiles
  535. [none | profile_name]
  536. queue_depth_limit
  537. [integer]
  538. queue_on_connection_limit
  539. [enabled | disabled]
  540. queue_time_limit
  541. [integer]
  542. reselect_tries
  543. [integer]
  544. service_down_action
  545. [drop | none | reselect | reset]
  546. slow_ramp_time
  547. [integer]
  548. '''
  549. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  550. if __opts__['test']:
  551. return _test_output(ret, 'create', params={
  552. 'hostname': hostname,
  553. 'username': username,
  554. 'password': password,
  555. 'name': name,
  556. 'members': members,
  557. 'allow_nat': allow_nat,
  558. 'allow_snat': allow_snat,
  559. 'description': description,
  560. 'gateway_failsafe_device': gateway_failsafe_device,
  561. 'ignore_persisted_weight': ignore_persisted_weight,
  562. 'ip_tos_client:': ip_tos_to_client,
  563. 'ip_tos_server': ip_tos_to_server,
  564. 'link_qos_to_client': link_qos_to_client,
  565. 'link_qos_to_server': link_qos_to_server,
  566. 'load_balancing_mode': load_balancing_mode,
  567. 'min_active_members': min_active_members,
  568. 'min_up_members': min_up_members,
  569. 'min_up_members_checking': min_up_members_checking,
  570. 'monitor': monitor,
  571. 'profiles': profiles,
  572. 'queue_depth_limit': queue_depth_limit,
  573. 'queue_on_connection_limit': queue_on_connection_limit,
  574. 'queue_time_limit': queue_time_limit,
  575. 'reselect_tries': reselect_tries,
  576. 'service_down_action': service_down_action,
  577. 'slow_ramp_time': slow_ramp_time
  578. }
  579. )
  580. #is this pool currently configured?
  581. existing = __salt__['bigip.list_pool'](hostname, username, password, name)
  582. # if it exists
  583. if existing['code'] == 200:
  584. ret['result'] = True
  585. ret['comment'] = 'A pool by this name currently exists. No change made.'
  586. # if it doesn't exist
  587. elif existing['code'] == 404:
  588. response = __salt__['bigip.create_pool'](hostname=hostname,
  589. username=username,
  590. password=password,
  591. name=name,
  592. members=members,
  593. allow_nat=allow_nat,
  594. allow_snat=allow_snat,
  595. description=description,
  596. gateway_failsafe_device=gateway_failsafe_device,
  597. ignore_persisted_weight=ignore_persisted_weight,
  598. ip_tos_to_client=ip_tos_to_client,
  599. ip_tos_to_server=ip_tos_to_server,
  600. link_qos_to_client=link_qos_to_client,
  601. link_qos_to_server=link_qos_to_server,
  602. load_balancing_mode=load_balancing_mode,
  603. min_active_members=min_active_members,
  604. min_up_members=min_up_members,
  605. min_up_members_action=min_up_members_action,
  606. min_up_members_checking=min_up_members_checking,
  607. monitor=monitor,
  608. profiles=profiles,
  609. queue_depth_limit=queue_depth_limit,
  610. queue_on_connection_limit=queue_on_connection_limit,
  611. queue_time_limit=queue_time_limit,
  612. reselect_tries=reselect_tries,
  613. service_down_action=service_down_action,
  614. slow_ramp_time=slow_ramp_time)
  615. if response['code'] == 200:
  616. ret['result'] = True
  617. ret['changes']['old'] = {}
  618. ret['changes']['new'] = response['content']
  619. ret['comment'] = 'Pool was successfully created.'
  620. else:
  621. ret = _load_result(existing, ret)
  622. # else something else was returned
  623. else:
  624. ret = _load_result(existing, ret)
  625. return ret
  626. def manage_pool(hostname, username, password, name,
  627. allow_nat=None,
  628. allow_snat=None,
  629. description=None,
  630. gateway_failsafe_device=None,
  631. ignore_persisted_weight=None,
  632. ip_tos_to_client=None,
  633. ip_tos_to_server=None,
  634. link_qos_to_client=None,
  635. link_qos_to_server=None,
  636. load_balancing_mode=None,
  637. min_active_members=None,
  638. min_up_members=None,
  639. min_up_members_action=None,
  640. min_up_members_checking=None,
  641. monitor=None,
  642. profiles=None,
  643. queue_depth_limit=None,
  644. queue_on_connection_limit=None,
  645. queue_time_limit=None,
  646. reselect_tries=None,
  647. service_down_action=None,
  648. slow_ramp_time=None):
  649. '''
  650. Create a new pool if it does not already exist. Pool members are managed separately. Only the
  651. parameters specified are enforced.
  652. hostname
  653. The host/address of the bigip device
  654. username
  655. The iControl REST username
  656. password
  657. The iControl REST password
  658. name
  659. The name of the pool to create
  660. allow_nat
  661. [yes | no]
  662. allow_snat
  663. [yes | no]
  664. description
  665. [string]
  666. gateway_failsafe_device
  667. [string]
  668. ignore_persisted_weight
  669. [enabled | disabled]
  670. ip_tos_to_client
  671. [pass-through | [integer]]
  672. ip_tos_to_server
  673. [pass-through | [integer]]
  674. link_qos_to_client
  675. [pass-through | [integer]]
  676. link_qos_to_server
  677. [pass-through | [integer]]
  678. load_balancing_mode
  679. [dynamic-ratio-member | dynamic-ratio-node |
  680. fastest-app-response | fastest-node |
  681. least-connections-members |
  682. least-connections-node |
  683. least-sessions |
  684. observed-member | observed-node |
  685. predictive-member | predictive-node |
  686. ratio-least-connections-member |
  687. ratio-least-connections-node |
  688. ratio-member | ratio-node | ratio-session |
  689. round-robin | weighted-least-connections-member |
  690. weighted-least-connections-node]
  691. min_active_members
  692. [integer]
  693. min_up_members
  694. [integer]
  695. min_up_members_action
  696. [failover | reboot | restart-all]
  697. min_up_members_checking
  698. [enabled | disabled]
  699. monitor
  700. [name]
  701. profiles
  702. [none | profile_name]
  703. queue_depth_limit
  704. [integer]
  705. queue_on_connection_limit
  706. [enabled | disabled]
  707. queue_time_limit
  708. [integer]
  709. reselect_tries
  710. [integer]
  711. service_down_action
  712. [drop | none | reselect | reset]
  713. slow_ramp_time
  714. [integer]
  715. '''
  716. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  717. if __opts__['test']:
  718. return _test_output(ret, 'manage', params={
  719. 'hostname': hostname,
  720. 'username': username,
  721. 'password': password,
  722. 'name': name,
  723. 'allow_nat': allow_nat,
  724. 'allow_snat': allow_snat,
  725. 'description': description,
  726. 'gateway_failsafe_device': gateway_failsafe_device,
  727. 'ignore_persisted_weight': ignore_persisted_weight,
  728. 'ip_tos_client:': ip_tos_to_client,
  729. 'ip_tos_server': ip_tos_to_server,
  730. 'link_qos_to_client': link_qos_to_client,
  731. 'link_qos_to_server': link_qos_to_server,
  732. 'load_balancing_mode': load_balancing_mode,
  733. 'min_active_members': min_active_members,
  734. 'min_up_members': min_up_members,
  735. 'min_up_members_checking': min_up_members_checking,
  736. 'monitor': monitor,
  737. 'profiles': profiles,
  738. 'queue_depth_limit': queue_depth_limit,
  739. 'queue_on_connection_limit': queue_on_connection_limit,
  740. 'queue_time_limit': queue_time_limit,
  741. 'reselect_tries': reselect_tries,
  742. 'service_down_action': service_down_action,
  743. 'slow_ramp_time': slow_ramp_time
  744. }
  745. )
  746. #is this pool currently configured?
  747. existing = __salt__['bigip.list_pool'](hostname, username, password, name)
  748. # if it exists
  749. if existing['code'] == 200:
  750. modified = __salt__['bigip.modify_pool'](hostname=hostname,
  751. username=username,
  752. password=password,
  753. name=name,
  754. allow_nat=allow_nat,
  755. allow_snat=allow_snat,
  756. description=description,
  757. gateway_failsafe_device=gateway_failsafe_device,
  758. ignore_persisted_weight=ignore_persisted_weight,
  759. ip_tos_to_client=ip_tos_to_client,
  760. ip_tos_to_server=ip_tos_to_server,
  761. link_qos_to_client=link_qos_to_client,
  762. link_qos_to_server=link_qos_to_server,
  763. load_balancing_mode=load_balancing_mode,
  764. min_active_members=min_active_members,
  765. min_up_members=min_up_members,
  766. min_up_members_action=min_up_members_action,
  767. min_up_members_checking=min_up_members_checking,
  768. monitor=monitor,
  769. profiles=profiles,
  770. queue_depth_limit=queue_depth_limit,
  771. queue_on_connection_limit=queue_on_connection_limit,
  772. queue_time_limit=queue_time_limit,
  773. reselect_tries=reselect_tries,
  774. service_down_action=service_down_action,
  775. slow_ramp_time=slow_ramp_time)
  776. #was the modification successful?
  777. if modified['code'] == 200:
  778. #remove member listings and self-links
  779. del existing['content']['membersReference']
  780. del modified['content']['membersReference']
  781. del existing['content']['selfLink']
  782. del modified['content']['selfLink']
  783. ret = _check_for_changes('Pool', ret, existing, modified)
  784. else:
  785. ret = _load_result(modified, ret)
  786. # if it doesn't exist
  787. elif existing['code'] == 404:
  788. new = __salt__['bigip.create_pool'](hostname=hostname,
  789. username=username,
  790. password=password,
  791. name=name,
  792. allow_nat=allow_nat,
  793. allow_snat=allow_snat,
  794. description=description,
  795. gateway_failsafe_device=gateway_failsafe_device,
  796. ignore_persisted_weight=ignore_persisted_weight,
  797. ip_tos_to_client=ip_tos_to_client,
  798. ip_tos_to_server=ip_tos_to_server,
  799. link_qos_to_client=link_qos_to_client,
  800. link_qos_to_server=link_qos_to_server,
  801. load_balancing_mode=load_balancing_mode,
  802. min_active_members=min_active_members,
  803. min_up_members=min_up_members,
  804. min_up_members_action=min_up_members_action,
  805. min_up_members_checking=min_up_members_checking,
  806. monitor=monitor,
  807. profiles=profiles,
  808. queue_depth_limit=queue_depth_limit,
  809. queue_on_connection_limit=queue_on_connection_limit,
  810. queue_time_limit=queue_time_limit,
  811. reselect_tries=reselect_tries,
  812. service_down_action=service_down_action,
  813. slow_ramp_time=slow_ramp_time)
  814. # were we able to create it?
  815. if new['code'] == 200:
  816. ret['result'] = True
  817. ret['comment'] = 'Pool was created and enforced to the desired state. Note: Only parameters specified ' \
  818. 'were enforced. See changes for details.'
  819. ret['changes']['old'] = {}
  820. ret['changes']['new'] = new['content']
  821. # unable to create it
  822. else:
  823. ret = _load_result(new, ret)
  824. # else something else was returned
  825. else:
  826. ret = _load_result(existing, ret)
  827. return ret
  828. def modify_pool(hostname, username, password, name,
  829. allow_nat=None,
  830. allow_snat=None,
  831. description=None,
  832. gateway_failsafe_device=None,
  833. ignore_persisted_weight=None,
  834. ip_tos_to_client=None,
  835. ip_tos_to_server=None,
  836. link_qos_to_client=None,
  837. link_qos_to_server=None,
  838. load_balancing_mode=None,
  839. min_active_members=None,
  840. min_up_members=None,
  841. min_up_members_action=None,
  842. min_up_members_checking=None,
  843. monitor=None,
  844. profiles=None,
  845. queue_depth_limit=None,
  846. queue_on_connection_limit=None,
  847. queue_time_limit=None,
  848. reselect_tries=None,
  849. service_down_action=None,
  850. slow_ramp_time=None):
  851. '''
  852. Modify an existing pool. Pool members are managed separately. Only the
  853. parameters specified are enforced.
  854. hostname
  855. The host/address of the bigip device
  856. username
  857. The iControl REST username
  858. password
  859. The iControl REST password
  860. name
  861. The name of the pool to create
  862. allow_nat
  863. [yes | no]
  864. allow_snat
  865. [yes | no]
  866. description
  867. [string]
  868. gateway_failsafe_device
  869. [string]
  870. ignore_persisted_weight
  871. [enabled | disabled]
  872. ip_tos_to_client
  873. [pass-through | [integer]]
  874. ip_tos_to_server
  875. [pass-through | [integer]]
  876. link_qos_to_client
  877. [pass-through | [integer]]
  878. link_qos_to_server
  879. [pass-through | [integer]]
  880. load_balancing_mode
  881. [dynamic-ratio-member | dynamic-ratio-node |
  882. fastest-app-response | fastest-node |
  883. least-connections-members |
  884. least-connections-node |
  885. least-sessions |
  886. observed-member | observed-node |
  887. predictive-member | predictive-node |
  888. ratio-least-connections-member |
  889. ratio-least-connections-node |
  890. ratio-member | ratio-node | ratio-session |
  891. round-robin | weighted-least-connections-member |
  892. weighted-least-connections-node]
  893. min_active_members
  894. [integer]
  895. min_up_members
  896. [integer]
  897. min_up_members_action
  898. [failover | reboot | restart-all]
  899. min_up_members_checking
  900. [enabled | disabled]
  901. monitor
  902. [name]
  903. profiles
  904. [none | profile_name]
  905. queue_depth_limit
  906. [integer]
  907. queue_on_connection_limit
  908. [enabled | disabled]
  909. queue_time_limit
  910. [integer]
  911. reselect_tries
  912. [integer]
  913. service_down_action
  914. [drop | none | reselect | reset]
  915. slow_ramp_time
  916. [integer]
  917. '''
  918. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  919. if __opts__['test']:
  920. return _test_output(ret, 'modify', params={
  921. 'hostname': hostname,
  922. 'username': username,
  923. 'password': password,
  924. 'name': name,
  925. 'allow_nat': allow_nat,
  926. 'allow_snat': allow_snat,
  927. 'description': description,
  928. 'gateway_failsafe_device': gateway_failsafe_device,
  929. 'ignore_persisted_weight': ignore_persisted_weight,
  930. 'ip_tos_client:': ip_tos_to_client,
  931. 'ip_tos_server': ip_tos_to_server,
  932. 'link_qos_to_client': link_qos_to_client,
  933. 'link_qos_to_server': link_qos_to_server,
  934. 'load_balancing_mode': load_balancing_mode,
  935. 'min_active_members': min_active_members,
  936. 'min_up_members': min_up_members,
  937. 'min_up_members_checking': min_up_members_checking,
  938. 'monitor': monitor,
  939. 'profiles': profiles,
  940. 'queue_depth_limit': queue_depth_limit,
  941. 'queue_on_connection_limit': queue_on_connection_limit,
  942. 'queue_time_limit': queue_time_limit,
  943. 'reselect_tries': reselect_tries,
  944. 'service_down_action': service_down_action,
  945. 'slow_ramp_time': slow_ramp_time
  946. }
  947. )
  948. #is this pool currently configured?
  949. existing = __salt__['bigip.list_pool'](hostname, username, password, name)
  950. # if it exists
  951. if existing['code'] == 200:
  952. modified = __salt__['bigip.modify_pool'](hostname=hostname,
  953. username=username,
  954. password=password,
  955. name=name,
  956. allow_nat=allow_nat,
  957. allow_snat=allow_snat,
  958. description=description,
  959. gateway_failsafe_device=gateway_failsafe_device,
  960. ignore_persisted_weight=ignore_persisted_weight,
  961. ip_tos_to_client=ip_tos_to_client,
  962. ip_tos_to_server=ip_tos_to_server,
  963. link_qos_to_client=link_qos_to_client,
  964. link_qos_to_server=link_qos_to_server,
  965. load_balancing_mode=load_balancing_mode,
  966. min_active_members=min_active_members,
  967. min_up_members=min_up_members,
  968. min_up_members_action=min_up_members_action,
  969. min_up_members_checking=min_up_members_checking,
  970. monitor=monitor,
  971. profiles=profiles,
  972. queue_depth_limit=queue_depth_limit,
  973. queue_on_connection_limit=queue_on_connection_limit,
  974. queue_time_limit=queue_time_limit,
  975. reselect_tries=reselect_tries,
  976. service_down_action=service_down_action,
  977. slow_ramp_time=slow_ramp_time)
  978. #was the modification successful?
  979. if modified['code'] == 200:
  980. #remove member listings and self-links
  981. del existing['content']['membersReference']
  982. del modified['content']['membersReference']
  983. del existing['content']['selfLink']
  984. del modified['content']['selfLink']
  985. ret = _check_for_changes('Pool', ret, existing, modified)
  986. else:
  987. ret = _load_result(modified, ret)
  988. # if it doesn't exist
  989. elif existing['code'] == 404:
  990. ret['comment'] = 'A pool with this name was not found.'
  991. # else something else was returned
  992. else:
  993. ret = _load_result(existing, ret)
  994. return ret
  995. def delete_pool(hostname, username, password, name):
  996. '''
  997. Delete an existing pool.
  998. hostname
  999. The host/address of the bigip device
  1000. username
  1001. The iControl REST username
  1002. password
  1003. The iControl REST password
  1004. name
  1005. The name of the pool which will be deleted
  1006. '''
  1007. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  1008. if __opts__['test']:
  1009. return _test_output(ret, 'delete', params={
  1010. 'hostname': hostname,
  1011. 'username': username,
  1012. 'password': password,
  1013. 'name': name,
  1014. }
  1015. )
  1016. #is this pool currently configured?
  1017. existing = __salt__['bigip.list_pool'](hostname, username, password, name)
  1018. # if it exists by name
  1019. if existing['code'] == 200:
  1020. deleted = __salt__['bigip.delete_pool'](hostname, username, password, name)
  1021. # did we get rid of it?
  1022. if deleted['code'] == 200:
  1023. ret['result'] = True
  1024. ret['comment'] = 'Pool was successfully deleted.'
  1025. ret['changes']['old'] = existing['content']
  1026. ret['changes']['new'] = {}
  1027. # something bad happened
  1028. else:
  1029. ret = _load_result(deleted, ret)
  1030. # not found
  1031. elif existing['code'] == 404:
  1032. ret['result'] = True
  1033. ret['comment'] = 'This pool already does not exist. No changes made.'
  1034. ret['changes']['old'] = {}
  1035. ret['changes']['new'] = {}
  1036. else:
  1037. ret = _load_result(existing, ret)
  1038. return ret
  1039. def manage_pool_members(hostname, username, password, name, members):
  1040. '''
  1041. Manage the members of an existing pool. This function replaces all current pool members.
  1042. Only the parameters specified are enforced.
  1043. hostname
  1044. The host/address of the bigip device
  1045. username
  1046. The iControl REST username
  1047. password
  1048. The iControl REST password
  1049. name
  1050. The name of the pool to modify
  1051. members
  1052. list of pool members to manage.
  1053. '''
  1054. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  1055. if __opts__['test']:
  1056. return _test_output(ret, 'manage', params={
  1057. 'hostname': hostname,
  1058. 'username': username,
  1059. 'password': password,
  1060. 'name': name,
  1061. 'members': members
  1062. }
  1063. )
  1064. #is this pool currently configured?
  1065. existing = __salt__['bigip.list_pool'](hostname, username, password, name)
  1066. # if it exists
  1067. if existing['code'] == 200:
  1068. #what are the current members?
  1069. current_members = existing['content']['membersReference']['items']
  1070. modified = __salt__['bigip.replace_pool_members'](hostname, username, password, name, members)
  1071. #was the modification successful?
  1072. if modified['code'] == 200:
  1073. #re-list the pool with new membership
  1074. new_listing = __salt__['bigip.list_pool'](hostname, username, password, name)
  1075. #just in case something happened...
  1076. if new_listing['code'] != 200:
  1077. ret = _load_result(new_listing, ret)
  1078. ret['comment'] = 'modification of the pool was successful but an error occurred upon retrieving new' \
  1079. ' listing.'
  1080. return ret
  1081. new_members = new_listing['content']['membersReference']['items']
  1082. #remove generation keys and create new lists indexed by integers
  1083. for current_member in current_members:
  1084. del current_member['generation']
  1085. for new_member in new_members:
  1086. del new_member['generation']
  1087. #anything changed?
  1088. ret = _check_for_changes('Pool Membership', ret, current_members, new_members)
  1089. else:
  1090. ret = _load_result(modified, ret)
  1091. #pool does not exists
  1092. elif existing['code'] == 404:
  1093. ret['comment'] = 'A pool with this name was not found.'
  1094. else:
  1095. ret = _load_result(existing, ret)
  1096. return ret
  1097. def add_pool_member(hostname, username, password, name, member):
  1098. '''
  1099. A function to connect to a bigip device and add a new member to an existing pool.
  1100. hostname
  1101. The host/address of the bigip device
  1102. username
  1103. The iControl REST username
  1104. password
  1105. The iControl REST password
  1106. name
  1107. The name of the pool to modify
  1108. member
  1109. The member to add to the pool
  1110. '''
  1111. ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
  1112. if __opts__['test']:
  1113. return _test_output(ret, 'add', params={
  1114. 'hostname': hostname,
  1115. 'username': username,
  1116. 'password': password,
  1117. 'name': name,
  1118. 'members': member
  1119. }
  1120. )
  1121. #is this pool member currently configured?
  1122. existing_pool = __salt__['bigip.list_pool'](hostname, username, password, name)
  1123. if existing_pool['code'] == 200:
  1124. # for some reason iControl REST doesn't support listing a single pool member.
  1125. # the response from GET for listing a member will return 200 even if it doesn't exists.
  1126. # because of this we have to do some rather "unnecessary" searching within a pool.
  1127. #what are the current members?
  1128. current_members = existing_pool['content']['membersReference']['items']
  1129. #loop through them
  1130. exists = False
  1131. for current_member in current_members:
  1132. if current_member['name'] == member['name']:
  1133. exists = True
  1134. break
  1135. if exists:
  1136. ret['result'] = True
  1137. ret['comment'] = 'Member: {name} already exists within this pool. No changes made.'.format(name=member['name'])
  1138. ret['changes']['old'] = {}
  1139. ret['changes']['new'] = {}
  1140. else:
  1141. new_member = __salt__['bigip.add_pool_member'](hostname, username, password, name, member)
  1142. if new_member['code'] == 200:
  1143. ret['result'] = True
  1144. ret['comment'] = 'Member: {name} has been successfully added to the pool.'.format(name=member['name'])
  1145. ret['changes']['old'] = {}
  1146. #look up the member again...
  1147. pool_listing = __salt__['bigip.list_pool'](hostname, username, password, name)
  1148. if pool_listing['code'] != 200:
  1149. ret = _load_result(new_member, ret)
  1150. return ret
  1151. members = pool_listing['content']['membersReference']['items']
  1152. #loop through them
  1153. for current_member in members:
  1154. if current_member['name'] == member['name']:
  1155. added_member = current_member
  1156. break
  1157. ret['changes']['new'] = added_member
  1158. # member wasn't added
  1159. else:
  1160. ret = _load_result(new_member, ret)
  1161. #pool does not exists
  1162. elif existing_pool['code'] == 404:
  1163. ret['comment'] = 'A pool with this name was not found.'
  1164. else:
  1165. ret = _load_result(existing_pool, ret)
  1166. return ret
  1167. def modify_pool_member(hostname, username, password, name, member,
  1168. connection_limit=None,
  1169. description=None,
  1170. dynamic_ratio=None,
  1171. inherit_profile=None,
  1172. logging=None,
  1173. monitor=None,
  1174. priority_group=None,
  1175. prof

Large files files are truncated, but you can click here to view the full file