summaryrefslogtreecommitdiffstats
path: root/roles/openshift_storage_glusterfs/tasks/glusterfs_common.yml
blob: b8f3cab9d6603ee0dde8b437bacb3b8de97d1609 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
---
- name: Make sure heketi-client is installed
  package: name=heketi-client state=present
  when:
  - not openshift_is_atomic | bool
  - not glusterfs_heketi_is_native | bool
  register: result
  until: result is succeeded

- name: Verify heketi-cli is installed
  shell: "command -v {{ glusterfs_heketi_cli }} >/dev/null 2>&1 || { echo >&2 'ERROR: Make sure heketi-cli is available, then re-run the installer'; exit 1; }"
  changed_when: False
  when:
  - not glusterfs_heketi_is_native | bool

- name: Verify target namespace exists
  oc_project:
    state: present
    name: "{{ glusterfs_namespace }}"
    node_selector: "{% if glusterfs_use_default_selector %}{{ omit }}{% endif %}"
  when: glusterfs_is_native or glusterfs_heketi_is_native or glusterfs_storageclass

- name: Add namespace service accounts to privileged SCC
  oc_adm_policy_user:
    user: "system:serviceaccount:{{ glusterfs_namespace }}:{{ item }}"
    resource_kind: scc
    resource_name: privileged
    state: present
  with_items:
  - 'default'
  - 'router'
  when: glusterfs_is_native or glusterfs_heketi_is_native

- name: Delete pre-existing heketi resources
  oc_obj:
    namespace: "{{ glusterfs_namespace }}"
    kind: "{{ item.kind }}"
    name: "{{ item.name | default(omit) }}"
    selector: "{{ item.selector | default(omit) }}"
    state: absent
  with_items:
  - kind: "template,route,service,dc,jobs,secret"
    selector: "deploy-heketi"
  - kind: "svc"
    name: "heketi-storage-endpoints"
  - kind: "secret"
    name: "heketi-{{ glusterfs_name | default }}-topology-secret"
  - kind: "secret"
    name: "heketi-{{ glusterfs_name | default }}-config-secret"
  - kind: "template,route,service,dc"
    name: "heketi-{{ glusterfs_name | default }}"
  - kind: "svc"
    name: "heketi-db-{{ glusterfs_name | default }}-endpoints"
  - kind: "sa"
    name: "heketi-{{ glusterfs_name | default }}-service-account"
  - kind: "secret"
    name: "heketi-{{ glusterfs_name | default }}-admin-secret"
  failed_when: False
  when: glusterfs_heketi_wipe

- name: Wait for deploy-heketi pods to terminate
  oc_obj:
    namespace: "{{ glusterfs_namespace }}"
    kind: pod
    state: list
    selector: "glusterfs=deploy-heketi-{{ glusterfs_name }}-pod"
  register: deploy_heketi_pod
  until: "deploy_heketi_pod.results.results[0]['items'] | count == 0"
  delay: 10
  retries: "{{ (glusterfs_timeout | int / 10) | int }}"
  when: glusterfs_heketi_wipe

- name: Wait for heketi pods to terminate
  oc_obj:
    namespace: "{{ glusterfs_namespace }}"
    kind: pod
    state: list
    selector: "glusterfs=heketi-{{ glusterfs_name }}-pod"
  register: heketi_pod
  until: "heketi_pod.results.results[0]['items'] | count == 0"
  delay: 10
  retries: "{{ (glusterfs_timeout | int / 10) | int }}"
  when: glusterfs_heketi_wipe

- include_tasks: glusterfs_deploy.yml
  when: glusterfs_is_native

- name: Create heketi service account
  oc_serviceaccount:
    namespace: "{{ glusterfs_namespace }}"
    name: "heketi-{{ glusterfs_name }}-service-account"
    state: present
  when: glusterfs_heketi_is_native

- name: Add heketi service account to privileged SCC
  oc_adm_policy_user:
    namespace: "{{ glusterfs_namespace }}"
    user: "system:serviceaccount:{{ glusterfs_namespace }}:heketi-{{ glusterfs_name }}-service-account"
    resource_kind: scc
    resource_name: privileged
    state: present
  when: glusterfs_heketi_is_native

- name: Allow heketi service account to view/edit pods
  oc_adm_policy_user:
    namespace: "{{ glusterfs_namespace }}"
    user: "system:serviceaccount:{{ glusterfs_namespace }}:heketi-{{ glusterfs_name }}-service-account"
    resource_kind: role
    resource_name: edit
    state: present
  when: glusterfs_heketi_is_native

- name: Check for existing deploy-heketi pod
  oc_obj:
    namespace: "{{ glusterfs_namespace }}"
    state: list
    kind: pod
    selector: "glusterfs=deploy-heketi-{{ glusterfs_name }}-pod"
  register: deploy_heketi_pod
  when: glusterfs_heketi_is_native

- name: Check if need to deploy deploy-heketi
  set_fact:
    glusterfs_heketi_deploy_is_missing: False
  when:
  - "glusterfs_heketi_is_native"
  - "deploy_heketi_pod.results.results[0]['items'] | count > 0"
  # deploy-heketi is not missing when there are one or more pods with matching labels whose 'Ready' status is True
  - "deploy_heketi_pod.results.results[0]['items'] | lib_utils_oo_collect(attribute='status.conditions') | lib_utils_oo_collect(attribute='status', filters={'type': 'Ready'}) | map('bool') | select | list | count > 0"

- name: Check for existing heketi pod
  oc_obj:
    namespace: "{{ glusterfs_namespace }}"
    state: list
    kind: pod
    selector: "glusterfs=heketi-{{ glusterfs_name }}-pod"
  register: heketi_pod
  when: glusterfs_heketi_is_native

- name: Check if need to deploy heketi
  set_fact:
    glusterfs_heketi_is_missing: False
  when:
  - "glusterfs_heketi_is_native"
  - "heketi_pod.results.results[0]['items'] | count > 0"
  # heketi is not missing when there are one or more pods with matching labels whose 'Ready' status is True
  - "heketi_pod.results.results[0]['items'] | lib_utils_oo_collect(attribute='status.conditions') | lib_utils_oo_collect(attribute='status', filters={'type': 'Ready'}) | map('bool') | select | list | count > 0"

- name: Generate topology file
  template:
    src: "{{ openshift.common.examples_content_version }}/topology.json.j2"
    dest: "{{ mktemp.stdout }}/topology.json"
  when:
  - glusterfs_heketi_topology_load

- name: Generate heketi config file
  template:
    src: "{{ openshift.common.examples_content_version }}/heketi.json.j2"
    dest: "{{ mktemp.stdout }}/heketi.json"
  when:
  - glusterfs_heketi_is_native

- name: Get heketi admin secret
  oc_secret:
    state: list
    namespace: "{{ glusterfs_namespace }}"
    name: "heketi-{{ glusterfs_name }}-admin-secret"
    decode: True
  register: glusterfs_heketi_admin_secret

- name: Set heketi admin key
  set_fact:
    glusterfs_heketi_admin_key: "{{ glusterfs_heketi_admin_secret.results.decoded.key }}"
  when:
  - glusterfs_is_native
  - glusterfs_heketi_admin_secret.results.results[0]

- name: Generate heketi admin key
  set_fact:
    glusterfs_heketi_admin_key: "{{ 32 | lib_utils_oo_generate_secret }}"
  when:
  - glusterfs_heketi_is_native
  - glusterfs_heketi_admin_key is undefined

- name: Generate heketi user key
  set_fact:
    glusterfs_heketi_user_key: "{{ 32 | lib_utils_oo_generate_secret }}"
  until: "glusterfs_heketi_user_key != glusterfs_heketi_admin_key"
  delay: 1
  retries: 10
  when:
  - glusterfs_heketi_is_native
  - glusterfs_heketi_user_key is undefined

- name: Copy heketi private key
  copy:
    src: "{{ glusterfs_heketi_ssh_keyfile | default(omit)  }}"
    content: "{{ '' if glusterfs_heketi_ssh_keyfile is undefined else omit }}"
    dest: "{{ mktemp.stdout }}/private_key"

- name: Create heketi config secret
  oc_secret:
    namespace: "{{ glusterfs_namespace }}"
    state: present
    name: "heketi-{{ glusterfs_name }}-config-secret"
    force: True
    files:
    - name: heketi.json
      path: "{{ mktemp.stdout }}/heketi.json"
    - name: private_key
      path: "{{ mktemp.stdout }}/private_key"
  when:
  - glusterfs_heketi_is_native

- include_tasks: heketi_deploy_part1.yml
  when:
  - glusterfs_heketi_is_native
  - glusterfs_heketi_deploy_is_missing
  - glusterfs_heketi_is_missing

- name: Wait for deploy-heketi pod
  oc_obj:
    namespace: "{{ glusterfs_namespace }}"
    kind: pod
    state: list
    selector: "glusterfs=deploy-heketi-{{ glusterfs_name }}-pod"
  register: deploy_heketi_pod
  until:
  - "deploy_heketi_pod.results.results[0]['items'] | count > 0"
  # Pod's 'Ready' status must be True
  - "deploy_heketi_pod.results.results[0]['items'] | lib_utils_oo_collect(attribute='status.conditions') | lib_utils_oo_collect(attribute='status', filters={'type': 'Ready'}) | map('bool') | select | list | count == 1"
  delay: 10
  retries: "{{ (glusterfs_timeout | int / 10) | int }}"
  when:
  - glusterfs_heketi_is_native
  - not glusterfs_heketi_deploy_is_missing
  - glusterfs_heketi_is_missing

- name: Set heketi-cli command
  set_fact:
    glusterfs_heketi_client: "{% if glusterfs_heketi_is_native %}{{ openshift_client_binary }} rsh --namespace={{ glusterfs_namespace }} {%if not glusterfs_heketi_is_missing %}{{ heketi_pod.results.results[0]['items'][0]['metadata']['name'] }}{% else %}{{ deploy_heketi_pod.results.results[0]['items'][0]['metadata']['name'] }}{% endif %} {% endif %}{{ glusterfs_heketi_cli }} -s http://{% if glusterfs_heketi_is_native %}localhost:8080{% else %}{{ glusterfs_heketi_url }}:{{ glusterfs_heketi_port }}{% endif %} --user admin {% if glusterfs_heketi_admin_key is defined %}--secret '{{ glusterfs_heketi_admin_key }}'{% endif %}"

- name: Verify heketi service
  command: "{{ glusterfs_heketi_client }} cluster list"
  changed_when: False

- name: Place heketi topology on heketi Pod
  shell: "{{ openshift_client_binary }} exec --namespace={{ glusterfs_namespace }} -i {%if not glusterfs_heketi_is_missing %}{{ heketi_pod.results.results[0]['items'][0]['metadata']['name'] }}{% else %}{{ deploy_heketi_pod.results.results[0]['items'][0]['metadata']['name'] }}{% endif %} -- bash -c 'mkdir -p {{ mktemp.stdout }} && cat > {{ mktemp.stdout }}/topology.json' < {{ mktemp.stdout }}/topology.json"
  when:
  - glusterfs_heketi_is_native

- name: Load heketi topology
  command: "{{ glusterfs_heketi_client }} topology load --json={{ mktemp.stdout }}/topology.json 2>&1"
  register: topology_load
  failed_when: "topology_load.rc != 0 or 'Unable' in topology_load.stdout"
  when:
  - glusterfs_heketi_topology_load

- include_tasks: heketi_deploy_part2.yml
  when:
  - glusterfs_heketi_is_native
  - glusterfs_heketi_is_missing

- name: Check if gluster-s3 can't be deployed
  set_fact:
    glusterfs_s3_deploy: False
  when:
  - "glusterfs_s3_account is not defined or glusterfs_s3_user is not defined or glusterfs_s3_password is not defined"

- block:
  - name: Create heketi secret
    oc_secret:
      namespace: "{{ glusterfs_namespace }}"
      state: present
      name: "heketi-{{ glusterfs_name }}-admin-secret"
      type: "kubernetes.io/glusterfs"
      force: True
      contents:
      - path: key
        data: "{{ glusterfs_heketi_admin_key }}"
    when:
    - glusterfs_heketi_admin_key is defined

  - name: Get heketi route
    oc_obj:
      namespace: "{{ glusterfs_namespace }}"
      kind: route
      state: list
      name: "heketi-{{ glusterfs_name }}"
    register: heketi_route
    when:
    - glusterfs_heketi_is_native

  - name: Determine StorageClass heketi URL
    set_fact:
      glusterfs_heketi_route: "heketi-{{ glusterfs_name }}.{{ glusterfs_namespace }}.svc.cluster.local:8080"
#      glusterfs_heketi_route: "{{ heketi_route.results.results[0]['spec']['host'] }}"
    when:
    - glusterfs_heketi_is_native

  - name: Generate GlusterFS StorageClass file
    template:
      src: "{{ openshift.common.examples_content_version }}/glusterfs-storageclass.yml.j2"
      dest: "{{ mktemp.stdout }}/glusterfs-storageclass.yml"

  - name: Create GlusterFS StorageClass
    oc_obj:
      state: present
      kind: storageclass
      name: "glusterfs-{{ glusterfs_name }}"
      files:
      - "{{ mktemp.stdout }}/glusterfs-storageclass.yml"
  when:
  - glusterfs_storageclass or glusterfs_s3_deploy

- include_tasks: glusterblock_deploy.yml
  when:
  - glusterfs_block_deploy
  #TODO: Remove this when multipathd will be available on atomic
  - not openshift_is_atomic | bool

- block:
  - name: Create heketi block secret
    oc_secret:
      namespace: "{{ glusterfs_namespace }}"
      state: present
      name: "heketi-{{ glusterfs_name }}-admin-secret-block"
      type: "gluster.org/glusterblock"
      force: True
      contents:
      - path: key
        data: "{{ glusterfs_heketi_admin_key }}"
    when: glusterfs_heketi_admin_key is defined

  - name: Get heketi route
    oc_obj:
      namespace: "{{ glusterfs_namespace }}"
      kind: route
      state: list
      name: "heketi-{{ glusterfs_name }}"
    register: heketi_route
    when:
    - glusterfs_heketi_is_native
    - glusterfs_heketi_route is not defined

  - name: Determine StorageClass heketi URL
    set_fact:
      glusterfs_heketi_route: "heketi-{{ glusterfs_name }}.{{ glusterfs_namespace }}.svc.cluster.local:8080"
#      glusterfs_heketi_route: "{{ heketi_route.results.results[0]['spec']['host'] }}"
    when:
    - glusterfs_heketi_is_native
    - glusterfs_heketi_route is not defined

  - name: Generate Gluster Block StorageClass file
    template:
      src: "{{ openshift.common.examples_content_version }}/gluster-block-storageclass.yml.j2"
      dest: "{{ mktemp.stdout }}/gluster-block-storageclass.yml"

  - name: Create Gluster Block StorageClass
    oc_obj:
      state: present
      kind: storageclass
      name: "glusterfs-{{ glusterfs_name }}-block"
      files:
      - "{{ mktemp.stdout }}/gluster-block-storageclass.yml"
  when: glusterfs_block_storageclass

- include_tasks: gluster_s3_deploy.yml
  when: glusterfs_s3_deploy