|
3 | 3 | ansible.builtin.set_fact: |
4 | 4 | old_ansible_python_interpreter: "{{ ansible_python_interpreter | default('/usr/bin/python3') }}" |
5 | 5 |
|
6 | | -- name: Set a fact to ensure Ansible uses the python interpreter in the virtualenv |
7 | | - ansible.builtin.set_fact: |
8 | | - ansible_python_interpreter: "{{ os_projects_venv }}/bin/python" |
9 | | - when: os_projects_venv != None |
10 | | - |
11 | | -- name: Ensure the domain exists |
12 | | - openstack.cloud.identity_domain: |
13 | | - auth_type: "{{ os_projects_auth_type }}" |
14 | | - auth: "{{ os_projects_admin_auth }}" |
15 | | - cacert: "{{ os_projects_cacert | default(omit) }}" |
16 | | - cloud: "{{ os_projects_cloud | default(omit) }}" |
17 | | - interface: "{{ os_projects_interface | default(omit, true) }}" |
18 | | - name: "{{ item.name }}" |
19 | | - description: "{{ item.description | default(omit) }}" |
20 | | - state: present |
21 | | - enabled: true |
22 | | - wait: true |
23 | | - with_items: "{{ os_projects_domains }}" |
24 | | - environment: "{{ os_projects_environment }}" |
25 | | - |
26 | | -# Domains must be specified by UUID in API calls (with the exception of the |
27 | | -# default domain), so build a domain name -> UUID map that allows users to pass |
28 | | -# in domains by name. We might have the information already, but in case any |
29 | | -# domains weren't created by the previous task, let's just grab the whole lot. |
30 | | - |
31 | | -# NOTE: We can't use the os_keystone_domain_facts module because ansible |
32 | | -# sanitises variables matching anything found in the auth parameter of os_* |
33 | | -# modules. This will include the name of the domain used to authenticate |
34 | | -# against. Use the openstack CLI directly instead. |
35 | | - |
36 | | -- name: List OpenStack domains |
37 | | - ansible.builtin.shell: > |
38 | | - . {{ os_projects_venv }}/bin/activate && |
39 | | - openstack |
40 | | - {% for auth_name, auth_value in os_projects_admin_auth.items() %} |
41 | | - --os-{{ auth_name | replace('_', '-') }}='{{ auth_value }}' |
42 | | - {% endfor %} |
43 | | - {% if os_projects_cacert is defined %} |
44 | | - --os-cacert='{{ os_projects_cacert }}' |
45 | | - {% endif %} |
46 | | - {% if os_projects_cloud is defined %} |
47 | | - --os-cloud='{{ os_projects_cloud }}' |
48 | | - {% endif %} |
49 | | - --os-interface={{ os_projects_interface | default('public', true) }} |
50 | | - domain list -f json -c Name -c ID |
51 | | - changed_when: false |
52 | | - environment: "{{ os_projects_environment }}" |
53 | | - register: domain_list |
54 | | - check_mode: false |
55 | | - |
56 | | -- name: Initialise a fact mapping domain names to IDs |
57 | | - ansible.builtin.set_fact: |
58 | | - os_projects_domain_to_id: {} |
59 | | - |
60 | | -- name: Update a fact mapping domain names to IDs |
61 | | - ansible.builtin.set_fact: |
62 | | - os_projects_domain_to_id: > |
63 | | - {{ os_projects_domain_to_id | combine({item.Name: item.ID}) }} |
64 | | - with_items: "{{ domain_list.stdout | from_json }}" |
65 | | - loop_control: |
66 | | - label: "{{ item.Name }}" |
67 | | - |
68 | | -- name: Fail if the project's domain was not found |
69 | | - ansible.builtin.fail: |
70 | | - msg: > |
71 | | - OpenStack domain {{ item.project_domain }} for project {{ item.name }} |
72 | | - was not found. |
73 | | - when: |
74 | | - - item.project_domain not in os_projects_domain_to_id |
75 | | - - item.project_domain not in os_projects_domain_to_id.values() |
76 | | - with_items: "{{ os_projects }}" |
77 | | - loop_control: |
78 | | - label: "{{ item.name }}" |
79 | | - |
80 | | -- name: Fail if the project's user domain was not found |
81 | | - ansible.builtin.fail: |
82 | | - msg: > |
83 | | - OpenStack domain {{ item.user_domain }} for project {{ item.name }} |
84 | | - was not found. |
85 | | - when: |
86 | | - - item.user_domain is defined |
87 | | - - item.user_domain not in os_projects_domain_to_id |
88 | | - - item.user_domain not in os_projects_domain_to_id.values() |
89 | | - with_items: "{{ os_projects }}" |
90 | | - loop_control: |
91 | | - label: "{{ item.name }}" |
92 | | - |
93 | | -- name: Ensure the project exists |
94 | | - openstack.cloud.project: |
95 | | - auth_type: "{{ os_projects_auth_type }}" |
96 | | - auth: "{{ os_projects_admin_auth }}" |
97 | | - cacert: "{{ os_projects_cacert | default(omit) }}" |
98 | | - cloud: "{{ os_projects_cloud | default(omit) }}" |
99 | | - interface: "{{ os_projects_interface | default(omit, true) }}" |
100 | | - name: "{{ item.name }}" |
101 | | - description: "{{ item.description }}" |
102 | | - domain_id: "{{ domain_is_id | ternary(item.project_domain, os_projects_domain_to_id[item.project_domain]) }}" |
103 | | - state: present |
104 | | - enabled: true |
105 | | - wait: true |
106 | | - with_items: "{{ os_projects }}" |
107 | | - environment: "{{ os_projects_environment }}" |
108 | | - vars: |
109 | | - domain_is_id: "{{ item.project_domain in os_projects_domain_to_id.values() }}" |
110 | | - loop_control: |
111 | | - label: "{{ item.name }}" |
112 | | - |
113 | | -- name: Ensure the role exists |
114 | | - openstack.cloud.identity_role: |
115 | | - auth_type: "{{ os_projects_auth_type }}" |
116 | | - auth: "{{ os_projects_admin_auth }}" |
117 | | - cacert: "{{ os_projects_cacert | default(omit) }}" |
118 | | - cloud: "{{ os_projects_cloud | default(omit) }}" |
119 | | - interface: "{{ os_projects_interface | default(omit, true) }}" |
120 | | - name: "{{ item }}" |
121 | | - with_items: "{{ all_roles }}" |
122 | | - environment: "{{ os_projects_environment }}" |
123 | | - vars: |
124 | | - users: > |
125 | | - {{ os_projects | |
126 | | - selectattr('users', 'defined') | |
127 | | - map(attribute='users') | |
128 | | - sum(start=[]) | |
129 | | - list }} |
130 | | - project_roles: > |
131 | | - {{ users | |
132 | | - selectattr('roles', 'defined') | |
133 | | - map(attribute='roles') | |
134 | | - sum(start=[]) | |
135 | | - unique | |
136 | | - list }} |
137 | | - domain_roles: > |
138 | | - {{ users | |
139 | | - selectattr('domain_roles', 'defined') | |
140 | | - map(attribute='domain_roles') | |
141 | | - sum(start=[]) | |
142 | | - unique | |
143 | | - list }} |
144 | | - all_roles: "{{ project_roles + domain_roles }}" |
145 | | - |
146 | | -- name: Include users.yml |
147 | | - ansible.builtin.include_tasks: users.yml |
148 | | - with_items: "{{ os_projects }}" |
149 | | - when: project.users is defined |
150 | | - loop_control: |
151 | | - loop_var: project |
152 | | - |
153 | | -- name: Ensure SSH keypairs are registered |
154 | | - openstack.cloud.keypair: |
155 | | - auth_type: "{{ os_projects_auth_type }}" |
156 | | - auth: "{{ os_projects_admin_auth | combine(os_projects_user_auth_overrides) }}" |
157 | | - cacert: "{{ os_projects_cacert | default(omit) }}" |
158 | | - cloud: "{{ os_projects_cloud | default(omit) }}" |
159 | | - interface: "{{ os_projects_interface | default(omit, true) }}" |
160 | | - name: "{{ item.1.name }}" |
161 | | - public_key_file: "{{ item.1.public_key_file | default(omit) }}" |
162 | | - public_key: "{{ item.1.public_key | default(omit) }}" |
163 | | - state: present |
164 | | - with_subelements: |
165 | | - - "{{ os_projects }}" |
166 | | - - keypairs |
167 | | - - skip_missing: true |
168 | | - environment: "{{ os_projects_environment }}" |
| 6 | +- name: Import projects.yml |
| 7 | + ansible.builtin.import_tasks: projects.yml |
169 | 8 | vars: |
170 | | - # Authentication option overrides for non-admin user as used by os_* |
171 | | - # modules' 'auth' argument. |
172 | | - os_projects_user_auth_overrides: |
173 | | - project_domain_name: "{{ item.0.project_domain }}" |
174 | | - user_domain_name: "{{ item.0.user_domain }}" |
175 | | - project_name: "{{ item.0.name }}" |
176 | | - username: "{{ item.0.users[0].name }}" |
177 | | - password: "{{ item.0.users[0].password }}" |
178 | | - loop_control: |
179 | | - label: |
180 | | - project: "{{ item.0.name }}" |
181 | | - keypair: "{{ item.1.name }}" |
182 | | - |
183 | | -- name: Ensure quotas are set |
184 | | - openstack.cloud.quota: |
185 | | - auth_type: "{{ os_projects_auth_type }}" |
186 | | - auth: "{{ os_projects_admin_auth }}" |
187 | | - cacert: "{{ os_projects_cacert | default(omit) }}" |
188 | | - cloud: "{{ os_projects_cloud | default(omit) }}" |
189 | | - interface: "{{ os_projects_interface | default(omit, true) }}" |
190 | | - name: "{{ item.name }}" |
191 | | - state: present |
192 | | - # Quotas: |
193 | | - backup_gigabytes: "{{ quotas.backup_gigabytes | default(omit) }}" |
194 | | - backups: "{{ quotas.backups | default(omit) }}" |
195 | | - cores: "{{ quotas.cores | default(omit) }}" |
196 | | - fixed_ips: "{{ quotas.fixed_ips | default(omit) }}" |
197 | | - floating_ips: "{{ quotas.floating_ips | default(omit) }}" |
198 | | - floatingip: "{{ quotas.floatingip | default(omit) }}" |
199 | | - gigabytes: "{{ quotas.gigabytes | default(omit) }}" |
200 | | - gigabytes_lvm: "{{ quotas.gigabytes_lvm | default(omit) }}" |
201 | | - injected_file_size: "{{ quotas.injected_file_size | default(omit) }}" |
202 | | - injected_files: "{{ quotas.injected_files | default(omit) }}" |
203 | | - injected_path_size: "{{ quotas.injected_path_size | default(omit) }}" |
204 | | - instances: "{{ quotas.instances | default(omit) }}" |
205 | | - key_pairs: "{{ quotas.key_pairs | default(omit) }}" |
206 | | - loadbalancer: "{{ quotas.loadbalancer | default(omit) }}" |
207 | | - network: "{{ quotas.network | default(omit) }}" |
208 | | - per_volume_gigabytes: "{{ quotas.per_volume_gigabytes | default(omit) }}" |
209 | | - pool: "{{ quotas.pool | default(omit) }}" |
210 | | - port: "{{ quotas.port | default(omit) }}" |
211 | | - properties: "{{ quotas.properties | default(omit) }}" |
212 | | - ram: "{{ quotas.ram | default(omit) }}" |
213 | | - rbac_policy: "{{ quotas.rbac_policy | default(omit) }}" |
214 | | - router: "{{ quotas.router | default(omit) }}" |
215 | | - security_group: "{{ quotas.security_group | default(omit) }}" |
216 | | - security_group_rule: "{{ quotas.security_group_rule | default(omit) }}" |
217 | | - server_group_members: "{{ quotas.server_group_members | default(omit) }}" |
218 | | - server_groups: "{{ quotas.server_groups | default(omit) }}" |
219 | | - snapshots: "{{ quotas.snapshots | default(omit) }}" |
220 | | - snapshots_lvm: "{{ quotas.snapshots_lvm | default(omit) }}" |
221 | | - subnet: "{{ quotas.subnet | default(omit) }}" |
222 | | - subnetpool: "{{ quotas.subnetpool | default(omit) }}" |
223 | | - volumes: "{{ quotas.volumes | default(omit) }}" |
224 | | - volumes_lvm: "{{ quotas.volumes_lvm | default(omit) }}" |
225 | | - when: |
226 | | - - item.quotas is defined |
227 | | - with_items: "{{ os_projects }}" |
228 | | - environment: "{{ os_projects_environment }}" |
229 | | - vars: |
230 | | - quotas: "{{ item.quotas }}" |
231 | | - loop_control: |
232 | | - label: "{{ item.name }}" |
233 | | - |
234 | | -# This variable is unset before we set it, and it does not appear to be |
235 | | -# possible to unset a variable in Ansible. |
236 | | -- name: Set a fact to reset the Ansible python interpreter |
237 | | - ansible.builtin.set_fact: |
238 | | - ansible_python_interpreter: "{{ old_ansible_python_interpreter }}" |
239 | | - when: os_projects_venv != None |
240 | | - |
241 | | -- name: Ensure openrc environment file exists |
242 | | - ansible.builtin.template: |
243 | | - src: openrc.j2 |
244 | | - dest: "{{ item.1.openrc_file }}" |
245 | | - mode: "0600" |
246 | | - with_subelements: |
247 | | - - "{{ os_projects }}" |
248 | | - - users |
249 | | - - skip_missing: true |
250 | | - when: item.1.openrc_file is defined |
251 | | - loop_control: |
252 | | - label: |
253 | | - project: "{{ item.0.name }}" |
254 | | - user: "{{ item.1.name }}" |
255 | | - delegate_to: localhost |
| 9 | + ansible_python_interpreter: "{{ os_projects_venv ~ '/bin/python' if os_projects_venv != None else old_ansible_python_interpreter }}" |
0 commit comments