Skip to content

Commit

Permalink
Merge branch 'ldap'
Browse files Browse the repository at this point in the history
  • Loading branch information
brianveltman committed Nov 21, 2024
2 parents 19307eb + a362e1c commit 1fa0336
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 0 deletions.
2 changes: 2 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ nexus_enable_pro: false

nexus_ssl_truststore: []

ldap_connections: []

# Nexus Security Realms
#
# Each realm will be activated and configured in the same order as you listed.
Expand Down
62 changes: 62 additions & 0 deletions molecule/default/group_vars/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,68 @@ nexus_admin_username: admin
nexus_admin_password: changeme
nexus_enable_pro: true

ldap_connections:
- name: Mock ldap server STATIC # Required
protocol: LDAPS # Required. Values: "LDAP" or "LDAPS"
host: "{{ nexus_hostname }}" # Required
searchBase: dc=slapd-server-mock # Required
port: 389 # Required
groupType: STATIC # Required if ldapGroupsAsRoles is true. Values: "DYNAMIC" or "STATIC"
groupObjectClass: posixGroup # Required if groupType is static
groupIdAttribute: cn # Required if groupType is static
groupMemberAttribute: memberUID # Required if groupType is static
groupMemberFormat: ${username} # Required if groupType is static
#userMemberOfAttribute: memberOf # Required if groupType is dynamic
authScheme: "NONE" # Required. Values: "NONE","SIMPLE","DIGEST_MD5" or "CRAM_MD5"
#authRealm: # Required if authScheme is CRAM_MD5 or DIGEST_MD5
#authUsername: # Required if authScheme other than NONE
#authPassword: # Required if authScheme other than NONE
connectionTimeoutSeconds: 30 # Required
connectionRetryDelaySeconds: 300 # Required
maxIncidentsCount: 3 # Required
useTrustStore: true
userBaseDn: ou=people
userLdapFilter: (|(mail=*@example.com)(uid=dom*))
userIdAttribute: guid
userRealNameAttribute: usrPrincipalName
userEmailAddressAttribute: email
userPasswordAttribute: pswd
userObjectClass: person
ldapGroupsAsRoles: true
groupBaseDn: ou=groups
userSubtree: false
groupSubtree: false
- name: Mock ldap server DYNAMIC # Required
protocol: LDAP # Required. Values: "LDAP" or "LDAPS"
host: "{{ nexus_hostname }}" # Required
searchBase: dc=slapd-server-mock # Required
port: 389 # Required
groupType: DYNAMIC # Required if ldapGroupsAsRoles is true. Values: "DYNAMIC" or "STATIC"
#groupObjectClass: posixGroup # Required if groupType is static
#groupIdAttribute: cn # Required if groupType is static
#groupMemberAttribute: memberUID # Required if groupType is static
#groupMemberFormat: ${username} # Required if groupType is static
userMemberOfAttribute: memberOf # Required if groupType is dynamic
authScheme: "NONE" # Required. Values: "NONE","SIMPLE","DIGEST_MD5" or "CRAM_MD5"
#authRealm: # Required if authScheme is CRAM_MD5 or DIGEST_MD5
#authUsername: # Required if authScheme other than NONE
#authPassword: # Required if authScheme other than NONE
connectionTimeoutSeconds: 30 # Required
connectionRetryDelaySeconds: 300 # Required
maxIncidentsCount: 3 # Required
# useTrustStore: false
#userBaseDn: ou=people
#userLdapFilter: (|(mail=*@example.com)(uid=dom*))
userIdAttribute: guid # Required
userRealNameAttribute: usrPrincipalName # Required
userEmailAddressAttribute: email # Required
#userPasswordAttribute: pswd
userObjectClass: person # Required
ldapGroupsAsRoles: true
#groupBaseDn: "ou=devs"
#userSubtree: false
#groupSubtree: false

nexus_ssl_truststore:
certificates:
- name: |
Expand Down
12 changes: 12 additions & 0 deletions molecule/default/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ platforms:
- nexus
networks: *nexus_networks

- name: slapd-server-mock
hostname: slapd-server-mock
image: thoteam/slapd-server-mock:latest
override_command: false
pull: true
pre_build_image: true
env:
LDAP_DOMAIN: slapd-server-mock
groups:
- mockldap
networks: *nexus_networks

provisioner:
name: ansible
options:
Expand Down
27 changes: 27 additions & 0 deletions tasks/ldap-api.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
- name: Construct API url
ansible.builtin.set_fact:
api_url: >
{% if method in ['POST'] %}
{{ nexus_protocol }}://{{ nexus_hostname }}:{{ nexus_port }}/service/rest/v1/security/ldap
{% elif method in ['PUT', 'DELETE'] %}
{{ nexus_protocol }}://{{ nexus_hostname }}:{{ nexus_port }}/service/rest/v1/security/ldap/{{ item.name | urlencode }}
{% endif %}
tags: ldap

- name: "{{ method }} {{ item.name }} LDAP connection"
ansible.builtin.uri:
url: "{{ api_url }}"
method: "{{ method }}"
validate_certs: false
user: "{{ nexus_admin_username }}"
password: "{{ nexus_admin_password }}"
force_basic_auth: true
body: "{{ item | combine({'id': item.id}) | to_json if method == 'PUT' else item | to_json }}"
status_code: "{{ '201' if method == 'POST' else '204' if method in ['PUT', 'DELETE'] else '200' }}"
headers:
Accept: "application/json"
Content-Type: "application/json"
register: __nexus_ldap_config_update__
changed_when: true
tags: ldap
141 changes: 141 additions & 0 deletions tasks/ldap-tasks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
- name: Get all LDAP configurations
ansible.builtin.uri:
url: "{{ nexus_protocol }}://{{ nexus_hostname }}:{{ nexus_port }}/service/rest/v1/security/ldap"
method: GET
validate_certs: false
user: "{{ nexus_admin_username }}"
password: "{{ nexus_admin_password }}"
force_basic_auth: true
headers:
Accept: "application/json"
status_code: 200
register: __nexus_ldap_config__
tags: ldap

- name: Set fact for current_nexus_ldap_config
ansible.builtin.set_fact:
current_nexus_ldap_config: "{{ __nexus_ldap_config__.json }}"
when: __nexus_ldap_config__.status == 200
tags: ldap

- name: Set fact for desired_nexus_ldap_config
ansible.builtin.set_fact:
desired_nexus_ldap_config: "{{ ldap_connections }}"
tags: ldap

- name: Determine LDAP connections to be created
ansible.builtin.set_fact:
nxs_create_ldap_connetions: "{{ ldap_connections | rejectattr('name', 'in', current_nexus_ldap_config | map(attribute='name') | list) | list }}"
tags: ldap

- name: Determine LDAP connections to be deleted
ansible.builtin.set_fact:
nxs_delete_ldap_connetions: "{{ current_nexus_ldap_config | rejectattr('name', 'in', ldap_connections | map(attribute='name') | list) | list }}"
tags: ldap

- name: Compare LDAP config for changes if ldap_connections is not empty
when: current_nexus_ldap_config | length > 0
block:
- name: Compare LDAP config for changes
ansible.builtin.set_fact:
nxs_update_ldap_connections: "{{ nxs_update_ldap_connections + [item | combine({'id': (current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).id})] }}"
loop: "{{ ldap_connections | list }}"
when: >
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first) is not defined or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).protocol | default(omit) != item.protocol | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).host | default(omit) != item.host | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).searchBase | default(omit) != item.searchBase | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).port | default(omit) != item.port | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).groupType | default(omit) != item.groupType | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).groupObjectClass | default(omit) != item.groupObjectClass | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).groupIdAttribute | default(omit) != item.groupIdAttribute | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).groupMemberAttribute | default(omit) != item.groupMemberAttribute | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).groupMemberFormat | default(omit) != item.groupMemberFormat | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userMemberOfAttribute | default(omit) != item.userMemberOfAttribute | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).authScheme | default(omit) != item.authScheme | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).authRealm | default(omit) != item.authRealm | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).authUsername | default(omit) != item.authUsername | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).authPassword | default(omit) != item.authPassword | default(omit) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).useTrustStore | default(false) != item.useTrustStore | default(false) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).connectionTimeoutSeconds | default(omit) != item.connectionTimeoutSeconds | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).connectionRetryDelaySeconds | default(omit) != item.connectionRetryDelaySeconds | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).maxIncidentsCount | default(omit) != item.maxIncidentsCount | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userBaseDn | default(omit) != item.userBaseDn | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userLdapFilter | default(omit) != item.userLdapFilter | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userIdAttribute | default(omit) != item.userIdAttribute | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userRealNameAttribute | default(omit) != item.userRealNameAttribute | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userEmailAddressAttribute | default(omit) != item.userEmailAddressAttribute | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userPasswordAttribute | default(omit) != item.userPasswordAttribute | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userObjectClass | default(omit) != item.userObjectClass | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).ldapGroupsAsRoles | default(false) != item.ldapGroupsAsRoles | default(false) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).groupBaseDn | default(omit) != item.groupBaseDn | default(None) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).userSubtree | default(false) != item.userSubtree | default(false) or
( current_nexus_ldap_config | selectattr('name', 'equalto', item.name) | first).groupSubtree | default(false) != item.groupSubtree | default(false)
tags: ldap

- name: Show LDAP connections to be created
ansible.builtin.debug:
var: nxs_create_ldap_connetions | length
tags: ldap

- name: Show LDAP connections to be updated
ansible.builtin.debug:
var: nxs_update_ldap_connections
tags: ldap

- name: Show LDAP connections to be deleted
ansible.builtin.debug:
var: nxs_delete_ldap_connetions | length
tags: ldap

- name: Create configured LDAP connections using Nexus API
ansible.builtin.include_tasks: ldap-api.yml
vars:
ldap_connections: "{{ item | default([]) }}"
method: POST
with_items:
- "{{ nxs_create_ldap_connetions | default([]) }}"
when: nxs_create_ldap_connetions | length > 0
tags: ldap

- name: Update configured LDAP connections using Nexus API
ansible.builtin.include_tasks: ldap-api.yml
vars:
ldap_connections: "{{ item | default([]) }}"
method: PUT
with_items:
- "{{ nxs_update_ldap_connections | default([]) }}"
when: nxs_update_ldap_connections | length > 0
tags: ldap

- name: Delete unconfigured LDAP connections using Nexus API
ansible.builtin.include_tasks: ldap-api.yml
vars:
ldap_connections: "{{ item | default([]) }}"
method: DELETE
with_items:
- "{{ nxs_delete_ldap_connetions | default([]) }}"
when: nxs_delete_ldap_connetions | length > 0
tags: ldap

- name: Ensure LDAP connections are in desired order
ansible.builtin.uri:
url: "{{ nexus_protocol }}://{{ nexus_hostname }}:{{ nexus_port }}/service/rest/v1/security/ldap/change-order"
method: POST
validate_certs: false
user: "{{ nexus_admin_username }}"
password: "{{ nexus_admin_password }}"
force_basic_auth: true
headers:
Accept: "application/json"
Content-Type: "application/json"
status_code: 204
body: "{{ ldap_connections | map(attribute='name') | to_json }}"
register: __nexus_ldap_order__
# The API always returns 204, even if the order is not changed
# So we need to check if the order is changed to be idempotent
changed_when: >
ldap_connections | map(attribute='name') | list != current_nexus_ldap_config | map(attribute='name') | list
when: ldap_connections | length > 0
tags: ldap
4 changes: 4 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
ansible.builtin.include_tasks: ssl-truststore-api.yml
tags: ssl-truststore

- name: Include LDAP configuration
ansible.builtin.include_tasks: ldap-tasks.yml
tags: ldap

- name: Include security-realms-api
ansible.builtin.include_tasks: security-realms-api.yml
tags: security-realms
Expand Down
1 change: 1 addition & 0 deletions vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ nxs_update_conan_proxy_repos: []
nxs_update_conan_hosted_repos: []
nxs_update_go_proxy_repos: []
nxs_update_go_group_repos: []
nxs_update_ldap_connections: []
nxs_update_cleanuppolicies: []
nxs_update_routingrules: []
nxs_update_users: []
Expand Down

0 comments on commit 1fa0336

Please sign in to comment.