diff --git a/roles/opennebula/common/defaults/main.yml b/roles/opennebula/common/defaults/main.yml index 14bad7d1..42244c26 100644 --- a/roles/opennebula/common/defaults/main.yml +++ b/roles/opennebula/common/defaults/main.yml @@ -6,3 +6,4 @@ unsafe_migrations: true keep_empty_bridge: true admin_pubkey: "{{ _admin_pubkey_loaded }}" zone_name: "{{ ('OpenNebula' if (federation.role != 'SLAVE') else undef()) | mandatory('The zone_name var must be provided.') }}" +auth: { default: null } diff --git a/roles/opennebula/server/README.md b/roles/opennebula/server/README.md index 891d58a7..7c2c7835 100644 --- a/roles/opennebula/server/README.md +++ b/roles/opennebula/server/README.md @@ -28,6 +28,9 @@ Role Variables | `admin_pubkey` | `str` | loaded | (check below) | SSH pubkey loaded from `/var/lib/one/.ssh/id_rsa.pub`, provided by the user (as string) or ignored when `null`. | | `sched_rank` | `dict` | undefined | (check below) | Rank scheduler configuration. | | `sched_drs` | `dict` | undefined | (check below) | OpenNebula Distributed Resource Scheduler configuration. | +| `auth.default` | `str` | `null` | | Pick default auth mechanism (currently only `ldap` is supported in one-deploy). | +| `auth.ldap.config` | `dict` | `{}` | (check below) | LDAP authentication config (/etc/one/auth/ldap_auth.conf). | +| `auth.ldap.mapping` | `dict` | `{}` | (check below) | LDAP authentication group mapping (manually defined). | Dependencies ------------ @@ -42,6 +45,25 @@ Example Playbook gate_endpoint: "http://10.11.12.13:5030" admin_pubkey: null # ignore it + # LDAP authentication with manually defined group mappings. + auth: + default: ldap + ldap: + config: + :order: [dirsrv] + dirsrv: + :user: cn=admin,dc=sk4zuzu,dc=eu + :password: asd123 + :host: 10.3.10.1 + :base: dc=sk4zuzu,dc=eu + :rfc2307bis: true + :group_field: memberOf + :mapping_generate: false + :mapping_filename: dirsrv.yaml + mapping: + dirsrv: + cn=users,ou=groups,dc=sk4zuzu,dc=eu: 1 + sched_rank: DIFFERENT_VNETS: false diff --git a/roles/opennebula/server/tasks/config.yml b/roles/opennebula/server/tasks/config.yml index 76a9bf18..8643e6cb 100644 --- a/roles/opennebula/server/tasks/config.yml +++ b/roles/opennebula/server/tasks/config.yml @@ -51,6 +51,139 @@ notify: - Restart OpenNebula +- when: + - auth.ldap.config is defined + - auth.ldap.config is mapping + - _servers | count > 0 + vars: + _servers: >- + {{ auth.ldap.config.keys() | reject('in', [':order', ':match_user_regex']) }} + _has_order: >- + {{ auth.ldap.config is contains(':order') }} + _has_match_user_regex: >- + {{ auth.ldap.config is contains(':match_user_regex') }} + block: + - name: Configure LDAP authentication + opennebula.deploy.cfgtool: + dest: /etc/one/auth/ldap_auth.conf + parser: Yaml + actions: "{{ item.actions }}" + register: cfgtool_ldap_auth_conf + failed_when: + - item.ignore_errors | ternary(false, cfgtool_ldap_auth_conf.errors | count > 0) + loop: + - ignore_errors: false + actions: >- + {%- set output = [] -%} + {%- for k in _servers -%} + {{- + output.append({ + "put": { "path": [k], "value": {} }, + }) + -}} + {%- for x, y in auth.ldap.config[k].items() -%} + {{- + output.append({ + "put": { "path": [k, x], "value": y }, + }) + -}} + {%- endfor -%} + {%- endfor -%} + {{- output -}} + + - ignore_errors: true # TODO: Internal 'failed_when' for cfgtool. + actions: + - when: "{{ _has_order or _has_match_user_regex }}" + drop: + path: [':order'] + + - when: "{{ _has_order or _has_match_user_regex }}" + drop: + path: [':match_user_regex'] + + - ignore_errors: false + actions: + - when: "{{ _has_order }}" + put: + path: [':order'] + value: "{{ auth.ldap.config[':order'] | d() }}" + + - when: "{{ _has_match_user_regex }}" + put: + path: [':match_user_regex'] + value: "{{ auth.ldap.config[':match_user_regex'] | d() }}" + notify: + - Restart OpenNebula + + - when: + - auth.ldap.mapping is defined + - auth.ldap.mapping is mapping + - _mappings | count > 0 + vars: + _mappings: >- + {%- set output = [] -%} + {%- for k in auth.ldap.mapping.keys() | select('in', _servers) -%} + {%- if auth.ldap.config[k][':mapping_filename'] is defined -%} + {{- output.append(k) -}} + {%- endif -%} + {%- endfor -%} + {{- output -}} + block: + - name: Render LDAP group mapping (manual) + ansible.builtin.copy: + dest: "/var/lib/one/{{ auth.ldap.config[item][':mapping_filename'] }}" + content: | + # managed by one-deploy + {{ auth.ldap.mapping[item] | to_nice_yaml }} + owner: 9869 + group: 9869 + mode: u=rw,g=r,o= + loop: "{{ _mappings }}" + notify: + - Restart OpenNebula + + - when: + - auth.default is defined + - auth.default == 'ldap' + block: + - name: Read AUTH_MAD/AUTHN + opennebula.deploy.cfgtool: + dest: /etc/one/oned.conf + parser: One + actions: + - get: + path: [AUTH_MAD, AUTHN] + register: cfgtool_oned_conf_get + + - name: Make LDAP authentication default (AUTH_MAD/AUTHN) + opennebula.deploy.cfgtool: + dest: /etc/one/oned.conf + parser: One + actions: + - put: + path: [AUTH_MAD, AUTHN] + value: '"{{ _updated }}"' + vars: + _unquoted: >- + {{ cfgtool_oned_conf_get['values'].0.0[1:-1] }} + _cleaned: >- + {{ _unquoted | split(',') | reject('in', ['default']) }} + _updated: >- + {{ (['default'] + _cleaned) | join(',') }} + notify: + - Restart OpenNebula + + - name: Make LDAP authentication default (symlink) + ansible.builtin.file: + dest: /var/lib/one/remotes/auth/default + src: /var/lib/one/remotes/auth/ldap + state: link + owner: 9869 + group: 9869 + follow: false + notify: + - Restart OpenNebula + - name: Workaround potential Libvirt's NFS detection issues opennebula.deploy.cfgtool: dest: /var/lib/one/remotes/etc/vmm/kvm/kvmrc diff --git a/roles/precheck/pre_reboot/tasks/integrity.yml b/roles/precheck/pre_reboot/tasks/integrity.yml index d9cbce6b..0422ce9f 100644 --- a/roles/precheck/pre_reboot/tasks/integrity.yml +++ b/roles/precheck/pre_reboot/tasks/integrity.yml @@ -105,3 +105,17 @@ msg: | Please make sure each cluster member can resolve all Front-end hostnames (you could try enabling both ensure_hostname and ensure_hosts as a workaround). + +- name: Assert that :order and :match_user_regex are not used together + ansible.builtin.assert: + that: (auth.ldap.config is undefined) + or + ((_has_order and _has_match_user_regex) is false) + fail_msg: Options :order and :match_user_regex are mutually exclusive (LDAP). + vars: + _ldap_config: >- + {{ auth.ldap.config | d({}) }} + _has_order: >- + {{ _ldap_config is contains(':order') }} + _has_match_user_regex: >- + {{ _ldap_config is contains(':match_user_regex') }}