|
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