1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17from __future__ import absolute_import, division, print_function
18__metaclass__ = type
19
20
21DOCUMENTATION = '''
22---
23module: smart_proxy
24version_added: 1.4.0
25short_description: Manage Smart Proxies
26description:
27  - Create, update and delete Smart Proxies
28author:
29  - "James Stuart (@jstuart)"
30  - "Matthias M Dellweg (@mdellweg)"
31  - "Jeffrey van Pelt (@Thulium-Drake)"
32options:
33  name:
34    description:
35      - Name of the Smart Proxy
36    required: true
37    type: str
38  lifecycle_environments:
39    description:
40      - Lifecycle Environments synced to the Smart Proxy.
41      - Only available for Katello installations.
42    required: false
43    elements: str
44    type: list
45  url:
46    description:
47      - URL of the Smart Proxy
48    required: true
49    type: str
50  download_policy:
51    description:
52      - The download policy for the Smart Proxy
53      - Only available for Katello installations.
54    choices:
55      - background
56      - immediate
57      - on_demand
58    required: false
59    type: str
60notes:
61  - Even with I(state=present) this module does not install a new Smart Proxy.
62  - It can only associate an existing Smart Proxy listening at the specified I(url).
63  - Consider using I(foreman-installer) to create Smart Proxies.
64extends_documentation_fragment:
65  - theforeman.foreman.foreman
66  - theforeman.foreman.foreman.entity_state
67  - theforeman.foreman.foreman.taxonomy
68'''
69
70EXAMPLES = '''
71# Create a local Smart Proxy
72- name: "Create Smart Proxy"
73  theforeman.foreman.smart_proxy:
74    username: "admin"
75    password: "changeme"
76    server_url: "https://{{ ansible_fqdn }}"
77    name: "{{ ansible_fqdn }}"
78    url: "https://{{ ansible_fqdn }}:9090"
79    download_policy: "immediate"
80    lifecycle_environments:
81      - "Development"
82    organizations:
83      - "Default Organization"
84    locations:
85      - "Default Location"
86    state: present
87'''
88
89RETURN = '''
90entity:
91  description: Final state of the affected entities grouped by their type.
92  returned: success
93  type: dict
94  contains:
95    smart_proxies:
96      description: List of smart_proxies.
97      type: list
98      elements: dict
99'''
100
101
102from ansible_collections.theforeman.foreman.plugins.module_utils.foreman_helper import ForemanTaxonomicEntityAnsibleModule
103
104
105class ForemanSmartProxyModule(ForemanTaxonomicEntityAnsibleModule):
106    pass
107
108
109def main():
110    module = ForemanSmartProxyModule(
111        foreman_spec=dict(
112            name=dict(required=True),
113            url=dict(required=True),
114            lifecycle_environments=dict(required=False, type='entity_list'),
115            download_policy=dict(required=False, choices=['background', 'immediate', 'on_demand']),
116        ),
117        required_plugins=[('katello', ['lifecycle_environments', 'download_policy'])],
118    )
119
120    with module.api_connection():
121        handle_lifecycle_environments = not module.desired_absent and 'lifecycle_environments' in module.foreman_params
122        if handle_lifecycle_environments:
123            module.lookup_entity('lifecycle_environments')
124            lifecycle_environments = module.foreman_params.pop('lifecycle_environments', [])
125
126        smart_proxy = module.lookup_entity('entity')
127        new_smart_proxy = module.run()
128
129        if handle_lifecycle_environments:
130
131            if smart_proxy:
132                payload = {
133                    'id': new_smart_proxy['id'],
134                }
135                current_lces = module.resource_action('capsule_content', 'lifecycle_environments', payload, ignore_check_mode=True, record_change=False)
136            else:
137                current_lces = {'results': []}
138
139            desired_environment_ids = set(lifecycle_environment['id'] for lifecycle_environment in lifecycle_environments)
140            current_environment_ids = set(lifecycle_environment['id'] for lifecycle_environment in current_lces['results']) if current_lces else set()
141
142            module.record_before('smart_proxy_content/lifecycle_environment_ids', current_environment_ids)
143            module.record_after('smart_proxy_content/lifecycle_environment_ids', desired_environment_ids)
144            module.record_after_full('smart_proxy_content/lifecycle_environment_ids', desired_environment_ids)
145
146            if desired_environment_ids != current_environment_ids:
147                environment_ids_to_add = desired_environment_ids - current_environment_ids
148                if environment_ids_to_add:
149                    for environment_id_to_add in environment_ids_to_add:
150                        payload = {
151                            'id': new_smart_proxy['id'],
152                            'environment_id': environment_id_to_add,
153                        }
154                        module.resource_action('capsule_content', 'add_lifecycle_environment', payload)
155                environment_ids_to_remove = current_environment_ids - desired_environment_ids
156                if environment_ids_to_remove:
157                    for environment_id_to_remove in environment_ids_to_remove:
158                        payload = {
159                            'id': smart_proxy['id'],
160                            'environment_id': environment_id_to_remove,
161                        }
162                        module.resource_action('capsule_content', 'remove_lifecycle_environment', payload)
163
164
165if __name__ == '__main__':
166    main()
167