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

/collections/ansible_collections/community/general/plugins/modules/identity/ipa/ipa_subca.py

https://gitlab.com/cfernand/acm-aap-demo
Python | 212 lines | 196 code | 11 blank | 5 comment | 17 complexity | 2116e4888e4e8e939500aa0051c8a586 MD5 | raw file
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # Copyright (c) 2017, Abhijeet Kasurde (akasurde@redhat.com)
  4. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
  5. from __future__ import absolute_import, division, print_function
  6. __metaclass__ = type
  7. DOCUMENTATION = r'''
  8. ---
  9. module: ipa_subca
  10. author: Abhijeet Kasurde (@Akasurde)
  11. short_description: Manage FreeIPA Lightweight Sub Certificate Authorities.
  12. description:
  13. - Add, modify, enable, disable and delete an IPA Lightweight Sub Certificate Authorities using IPA API.
  14. options:
  15. subca_name:
  16. description:
  17. - The Sub Certificate Authority name which needs to be managed.
  18. required: true
  19. aliases: ["name"]
  20. type: str
  21. subca_subject:
  22. description:
  23. - The Sub Certificate Authority's Subject. e.g., 'CN=SampleSubCA1,O=testrelm.test'.
  24. required: true
  25. type: str
  26. subca_desc:
  27. description:
  28. - The Sub Certificate Authority's description.
  29. type: str
  30. state:
  31. description:
  32. - State to ensure.
  33. - State 'disable' and 'enable' is available for FreeIPA 4.4.2 version and onwards.
  34. required: false
  35. default: present
  36. choices: ["absent", "disabled", "enabled", "present"]
  37. type: str
  38. extends_documentation_fragment:
  39. - community.general.ipa.documentation
  40. '''
  41. EXAMPLES = '''
  42. - name: Ensure IPA Sub CA is present
  43. community.general.ipa_subca:
  44. ipa_host: spider.example.com
  45. ipa_pass: Passw0rd!
  46. state: present
  47. subca_name: AnsibleSubCA1
  48. subca_subject: 'CN=AnsibleSubCA1,O=example.com'
  49. subca_desc: Ansible Sub CA
  50. - name: Ensure that IPA Sub CA is removed
  51. community.general.ipa_subca:
  52. ipa_host: spider.example.com
  53. ipa_pass: Passw0rd!
  54. state: absent
  55. subca_name: AnsibleSubCA1
  56. - name: Ensure that IPA Sub CA is disabled
  57. community.general.ipa_subca:
  58. ipa_host: spider.example.com
  59. ipa_pass: Passw0rd!
  60. state: disable
  61. subca_name: AnsibleSubCA1
  62. '''
  63. RETURN = r'''
  64. subca:
  65. description: IPA Sub CA record as returned by IPA API.
  66. returned: always
  67. type: dict
  68. '''
  69. from ansible.module_utils.basic import AnsibleModule
  70. from ansible_collections.community.general.plugins.module_utils.ipa import IPAClient, ipa_argument_spec
  71. from ansible.module_utils.common.text.converters import to_native
  72. from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
  73. class SubCAIPAClient(IPAClient):
  74. def __init__(self, module, host, port, protocol):
  75. super(SubCAIPAClient, self).__init__(module, host, port, protocol)
  76. def subca_find(self, subca_name):
  77. return self._post_json(method='ca_find', name=subca_name, item=None)
  78. def subca_add(self, subca_name=None, subject_dn=None, details=None):
  79. item = dict(ipacasubjectdn=subject_dn)
  80. subca_desc = details.get('description', None)
  81. if subca_desc is not None:
  82. item.update(description=subca_desc)
  83. return self._post_json(method='ca_add', name=subca_name, item=item)
  84. def subca_mod(self, subca_name=None, diff=None, details=None):
  85. item = get_subca_dict(details)
  86. for change in diff:
  87. update_detail = dict()
  88. if item[change] is not None:
  89. update_detail.update(setattr="{0}={1}".format(change, item[change]))
  90. self._post_json(method='ca_mod', name=subca_name, item=update_detail)
  91. def subca_del(self, subca_name=None):
  92. return self._post_json(method='ca_del', name=subca_name)
  93. def subca_disable(self, subca_name=None):
  94. return self._post_json(method='ca_disable', name=subca_name)
  95. def subca_enable(self, subca_name=None):
  96. return self._post_json(method='ca_enable', name=subca_name)
  97. def get_subca_dict(details=None):
  98. module_subca = dict()
  99. if details['description'] is not None:
  100. module_subca['description'] = details['description']
  101. if details['subca_subject'] is not None:
  102. module_subca['ipacasubjectdn'] = details['subca_subject']
  103. return module_subca
  104. def get_subca_diff(client, ipa_subca, module_subca):
  105. details = get_subca_dict(module_subca)
  106. return client.get_diff(ipa_data=ipa_subca, module_data=details)
  107. def ensure(module, client):
  108. subca_name = module.params['subca_name']
  109. subca_subject_dn = module.params['subca_subject']
  110. subca_desc = module.params['subca_desc']
  111. state = module.params['state']
  112. ipa_subca = client.subca_find(subca_name)
  113. module_subca = dict(description=subca_desc,
  114. subca_subject=subca_subject_dn)
  115. changed = False
  116. if state == 'present':
  117. if not ipa_subca:
  118. changed = True
  119. if not module.check_mode:
  120. client.subca_add(subca_name=subca_name, subject_dn=subca_subject_dn, details=module_subca)
  121. else:
  122. diff = get_subca_diff(client, ipa_subca, module_subca)
  123. # IPA does not allow to modify Sub CA's subject DN
  124. # So skip it for now.
  125. if 'ipacasubjectdn' in diff:
  126. diff.remove('ipacasubjectdn')
  127. del module_subca['subca_subject']
  128. if len(diff) > 0:
  129. changed = True
  130. if not module.check_mode:
  131. client.subca_mod(subca_name=subca_name, diff=diff, details=module_subca)
  132. elif state == 'absent':
  133. if ipa_subca:
  134. changed = True
  135. if not module.check_mode:
  136. client.subca_del(subca_name=subca_name)
  137. elif state == 'disable':
  138. ipa_version = client.get_ipa_version()
  139. if LooseVersion(ipa_version) < LooseVersion('4.4.2'):
  140. module.fail_json(msg="Current version of IPA server [%s] does not support 'CA disable' option. Please upgrade to "
  141. "version greater than 4.4.2")
  142. if ipa_subca:
  143. changed = True
  144. if not module.check_mode:
  145. client.subca_disable(subca_name=subca_name)
  146. elif state == 'enable':
  147. ipa_version = client.get_ipa_version()
  148. if LooseVersion(ipa_version) < LooseVersion('4.4.2'):
  149. module.fail_json(msg="Current version of IPA server [%s] does not support 'CA enable' option. Please upgrade to "
  150. "version greater than 4.4.2")
  151. if ipa_subca:
  152. changed = True
  153. if not module.check_mode:
  154. client.subca_enable(subca_name=subca_name)
  155. return changed, client.subca_find(subca_name)
  156. def main():
  157. argument_spec = ipa_argument_spec()
  158. argument_spec.update(subca_name=dict(type='str', required=True, aliases=['name']),
  159. subca_subject=dict(type='str', required=True),
  160. subca_desc=dict(type='str'),
  161. state=dict(type='str', default='present',
  162. choices=['present', 'absent', 'enabled', 'disabled']),)
  163. module = AnsibleModule(argument_spec=argument_spec,
  164. supports_check_mode=True,)
  165. client = SubCAIPAClient(module=module,
  166. host=module.params['ipa_host'],
  167. port=module.params['ipa_port'],
  168. protocol=module.params['ipa_prot'])
  169. try:
  170. client.login(username=module.params['ipa_user'],
  171. password=module.params['ipa_pass'])
  172. changed, record = ensure(module, client)
  173. module.exit_json(changed=changed, record=record)
  174. except Exception as exc:
  175. module.fail_json(msg=to_native(exc))
  176. if __name__ == '__main__':
  177. main()