mirror of
https://github.com/ansible/awx.git
synced 2026-01-10 15:32:07 -03:30
Adding option to enable and configure an OpenLDAP server next to AWX (#11843)
This commit is contained in:
parent
49bcf2e211
commit
4de27117e8
5
Makefile
5
Makefile
@ -13,6 +13,8 @@ COMPOSE_TAG ?= $(GIT_BRANCH)
|
||||
MAIN_NODE_TYPE ?= hybrid
|
||||
# If set to true docker-compose will also start a keycloak instance
|
||||
KEYCLOAK ?= false
|
||||
# If set to true docker-compose will also start an ldap instance
|
||||
LDAP ?= false
|
||||
|
||||
VENV_BASE ?= /var/lib/awx/venv
|
||||
|
||||
@ -462,7 +464,8 @@ docker-compose-sources: .git/hooks/pre-commit
|
||||
-e control_plane_node_count=$(CONTROL_PLANE_NODE_COUNT) \
|
||||
-e execution_node_count=$(EXECUTION_NODE_COUNT) \
|
||||
-e minikube_container_group=$(MINIKUBE_CONTAINER_GROUP) \
|
||||
-e enable_keycloak=$(KEYCLOAK)
|
||||
-e enable_keycloak=$(KEYCLOAK) \
|
||||
-e enable_ldap=$(LDAP)
|
||||
|
||||
|
||||
docker-compose: awx/projects docker-compose-sources
|
||||
|
||||
@ -244,6 +244,7 @@ $ make docker-compose
|
||||
- [Start a Cluster](#start-a-cluster)
|
||||
- [Start with Minikube](#start-with-minikube)
|
||||
- [Keycloak Integration](#keycloak-integration)
|
||||
- [OpenLDAP Integration](#openldap-integration)
|
||||
|
||||
### Start a Shell
|
||||
|
||||
@ -390,3 +391,39 @@ Once the playbook is done running SAML should now be setup in your development e
|
||||
3. awx_auditor:audit123
|
||||
|
||||
The first account is a normal user. The second account has the attribute is_superuser set in Keycloak so will be a super user in AWX. The third account has the is_system_auditor attribute in Keycloak so it will be a system auditor in AWX. To log in with one of these Keycloak users go to the AWX login screen and click the small "Sign In With SAML Keycloak" button at the bottom of the login box.
|
||||
|
||||
### OpenLDAP Integration
|
||||
|
||||
OpenLDAP is an LDAP provider that can be used to test AWX with LDAP integration. This section describes how to build a reference OpenLDAP instance and plumb it with your AWX for testing purposes.
|
||||
|
||||
First, be sure that you have the awx.awx collection installed by running `make install_collection`.
|
||||
|
||||
Anytime you want to run an OpenLDAP instance alongside AWX we can start docker-compose with the LDAP option to get an LDAP instance with the command:
|
||||
```bash
|
||||
LDAP=true make docker-compose
|
||||
```
|
||||
|
||||
Once the containers come up two new ports (389, 636) should be exposed and the LDAP server should be running on those ports. The first port (389) is non-SSL and the second port (636) is SSL enabled.
|
||||
|
||||
Now we are ready to configure and plumb OpenLDAP with AWX. To do this we have provided a playbook which will:
|
||||
* Backup and configure the LDAP adapter in AWX. NOTE: this will back up your existing settings but the password fields can not be backuped through the API, you need a DB backup to recover this.
|
||||
|
||||
Note: The default configuration will utilize the non-tls connection. If you want to use the tls configuration you will need to work through TLS negotiation issues because the LDAP server is using a self signed certificate.
|
||||
|
||||
Before we can run the playbook we need to understand that LDAP will be communicated to from within the AWX container. Because of this, we have to tell AWX how to route traffic to the LDAP container through the `LDAP Server URI` settings. The playbook requires a variable called container_reference to be set. The container_reference variable needs to be how your AWX container will be able to talk to the LDAP container. See the SAML section for some examples for how to select a `container_reference`.
|
||||
|
||||
Once you have your container reference you can run the playbook like:
|
||||
```bash
|
||||
export CONTROLLER_USERNAME=<your username>
|
||||
export CONTROLLER_PASSWORD=<your password>
|
||||
ansible-playbook tools/docker-compose/ansible/plumb_ldap.yml -e container_reference=<your container_reference here>
|
||||
```
|
||||
|
||||
|
||||
Once the playbook is done running LDAP should now be setup in your development environment. This realm has four users with the following username/passwords:
|
||||
1. awx_ldap_unpriv:unpriv123
|
||||
2. awx_ldap_admin:admin123
|
||||
3. awx_ldap_auditor:audit123
|
||||
4. awx_ldap_org_admin:orgadmin123
|
||||
|
||||
The first account is a normal user. The second account will be a super user in AWX. The third account will be a system auditor in AWX. The fourth account is an org admin. All users belong to an org called "LDAP Organization". To log in with one of these users go to the AWX login screen enter the username/password.
|
||||
|
||||
32
tools/docker-compose/ansible/plumb_ldap.yml
Normal file
32
tools/docker-compose/ansible/plumb_ldap.yml
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
- name: Plumb an ldap instance
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: False
|
||||
vars:
|
||||
awx_host: "https://localhost:8043"
|
||||
tasks:
|
||||
- name: Load existing and new LDAP settings
|
||||
set_fact:
|
||||
existing_ldap: "{{ lookup('awx.awx.controller_api', 'settings/ldap', host=awx_host, verify_ssl=false) }}"
|
||||
new_ldap: "{{ lookup('template', 'ldap_settings.json.j2') }}"
|
||||
|
||||
- name: Display existing LDAP configuration
|
||||
debug:
|
||||
msg:
|
||||
- "Here is your existing LDAP configuration for reference:"
|
||||
- "{{ existing_ldap }}"
|
||||
|
||||
- pause:
|
||||
prompt: "Continuing to run this will replace your existing ldap settings (displayed above). They will all be captured. Be sure that is backed up before continuing"
|
||||
|
||||
- name: Write out the existing content
|
||||
copy:
|
||||
dest: "../_sources/existing_ldap_adapter_settings.json"
|
||||
content: "{{ existing_ldap }}"
|
||||
|
||||
- name: Configure AWX LDAP adapter
|
||||
awx.awx.settings:
|
||||
settings: "{{ new_ldap }}"
|
||||
controller_host: "{{ awx_host }}"
|
||||
validate_certs: False
|
||||
@ -18,3 +18,12 @@ work_sign_private_keyfile: "{{ work_sign_key_dir }}/work_private_key.pem"
|
||||
work_sign_public_keyfile: "{{ work_sign_key_dir }}/work_public_key.pem"
|
||||
|
||||
enable_keycloak: false
|
||||
|
||||
enable_ldap: false
|
||||
ldap_public_key_file_name: 'ldap.cert'
|
||||
ldap_private_key_file_name: 'ldap.key'
|
||||
ldap_cert_dir: '{{ sources_dest }}/ldap_certs'
|
||||
ldap_diff_dir: '{{ sources_dest }}/ldap_diffs'
|
||||
ldap_public_key_file: '{{ ldap_cert_dir }}/{{ ldap_public_key_file_name }}'
|
||||
ldap_private_key_file: '{{ ldap_cert_dir }}/{{ ldap_private_key_file_name }}'
|
||||
ldap_cert_subject: "/C=US/ST=NC/L=Durham/O=awx/CN="
|
||||
|
||||
86
tools/docker-compose/ansible/roles/sources/files/ldap.ldif
Normal file
86
tools/docker-compose/ansible/roles/sources/files/ldap.ldif
Normal file
@ -0,0 +1,86 @@
|
||||
dn: dc=example,dc=org
|
||||
objectClass: dcObject
|
||||
objectClass: organization
|
||||
dc: example
|
||||
o: example
|
||||
|
||||
dn: ou=users,dc=example,dc=org
|
||||
ou: users
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: cn=awx_ldap_admin,ou=users,dc=example,dc=org
|
||||
mail: admin@example.org
|
||||
sn: LdapAdmin
|
||||
cn: awx_ldap_admin
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: inetOrgPerson
|
||||
userPassword: admin123
|
||||
givenName: awx
|
||||
|
||||
dn: cn=awx_ldap_auditor,ou=users,dc=example,dc=org
|
||||
mail: auditor@example.org
|
||||
sn: LdapAuditor
|
||||
cn: awx_ldap_auditor
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: inetOrgPerson
|
||||
userPassword: audit123
|
||||
givenName: awx
|
||||
|
||||
dn: cn=awx_ldap_unpriv,ou=users,dc=example,dc=org
|
||||
mail: unpriv@example.org
|
||||
sn: LdapUnpriv
|
||||
cn: awx_ldap_unpriv
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: inetOrgPerson
|
||||
givenName: awx
|
||||
userPassword: unpriv123
|
||||
|
||||
dn: ou=groups,dc=example,dc=org
|
||||
ou: groups
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: cn=awx_users,ou=groups,dc=example,dc=org
|
||||
cn: awx_users
|
||||
objectClass: top
|
||||
objectClass: groupOfNames
|
||||
member: cn=awx_ldap_admin,ou=users,dc=example,dc=org
|
||||
member: cn=awx_ldap_auditor,ou=users,dc=example,dc=org
|
||||
member: cn=awx_ldap_unpriv,ou=users,dc=example,dc=org
|
||||
member: cn=awx_ldap_org_admin,ou=users,dc=example,dc=org
|
||||
|
||||
dn: cn=awx_admins,ou=groups,dc=example,dc=org
|
||||
cn: awx_admins
|
||||
objectClass: top
|
||||
objectClass: groupOfNames
|
||||
member: cn=awx_ldap_admin,ou=users,dc=example,dc=org
|
||||
|
||||
dn: cn=awx_auditors,ou=groups,dc=example,dc=org
|
||||
cn: awx_auditors
|
||||
objectClass: top
|
||||
objectClass: groupOfNames
|
||||
member: cn=awx_ldap_auditor,ou=users,dc=example,dc=org
|
||||
|
||||
dn: cn=awx_ldap_org_admin,ou=users,dc=example,dc=org
|
||||
mail: org.admin@example.org
|
||||
sn: LdapOrgAdmin
|
||||
cn: awx_ldap_org_admin
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: inetOrgPerson
|
||||
givenName: awx
|
||||
userPassword: orgadmin123
|
||||
|
||||
dn: cn=awx_org_admins,ou=groups,dc=example,dc=org
|
||||
cn: awx_org_admins
|
||||
objectClass: top
|
||||
objectClass: groupOfNames
|
||||
member: cn=awx_ldap_org_admin,ou=users,dc=example,dc=org
|
||||
|
||||
18
tools/docker-compose/ansible/roles/sources/tasks/ldap.yml
Normal file
18
tools/docker-compose/ansible/roles/sources/tasks/ldap.yml
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Create LDAP cert directory
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
loop:
|
||||
- "{{ ldap_cert_dir }}"
|
||||
- "{{ ldap_diff_dir }}"
|
||||
|
||||
- name: General LDAP cert
|
||||
command: 'openssl req -new -x509 -days 365 -nodes -out {{ ldap_public_key_file }} -keyout {{ ldap_private_key_file }} -subj "{{ ldap_cert_subject }}"'
|
||||
args:
|
||||
creates: "{{ ldap_public_key_file }}"
|
||||
|
||||
- name: Copy ldap.diff
|
||||
copy:
|
||||
src: "ldap.ldif"
|
||||
dest: "{{ ldap_diff_dir }}/ldap.ldif"
|
||||
@ -91,6 +91,10 @@
|
||||
args:
|
||||
creates: "{{ work_sign_public_keyfile }}"
|
||||
|
||||
- name: Include LDAP tasks if enabled
|
||||
include_tasks: ldap.yml
|
||||
when: enable_ldap | bool
|
||||
|
||||
- name: Render Docker-Compose
|
||||
template:
|
||||
src: docker-compose.yml.j2
|
||||
|
||||
@ -99,6 +99,29 @@ services:
|
||||
DB_PASSWORD: {{ pg_password }}
|
||||
depends_on:
|
||||
- postgres
|
||||
{% endif %}
|
||||
{% if enable_ldap|bool %}
|
||||
ldap:
|
||||
image: bitnami/openldap:2
|
||||
container_name: tools_ldap_1
|
||||
hostname: ldap
|
||||
user: "{{ ansible_user_uid }}"
|
||||
ports:
|
||||
- "389:1389"
|
||||
- "636:1636"
|
||||
environment:
|
||||
LDAP_ADMIN_USERNAME: admin
|
||||
LDAP_ADMIN_PASSWORD: admin
|
||||
LDAP_CUSTOM_LDIF_DIR: /opt/bitnami/openldap/ldiffs
|
||||
LDAP_ENABLE_TLS: "yes"
|
||||
LDAP_LDAPS_PORT_NUMBER: 1636
|
||||
LDAP_TLS_CERT_FILE: /opt/bitnami/openldap/certs/{{ ldap_public_key_file_name }}
|
||||
LDAP_TLS_CA_FILE: /opt/bitnami/openldap/certs/{{ ldap_public_key_file_name }}
|
||||
LDAP_TLS_KEY_FILE: /opt/bitnami/openldap/certs/{{ ldap_private_key_file_name }}
|
||||
volumes:
|
||||
- 'openldap_data:/bitnami/openldap'
|
||||
- '../../docker-compose/_sources/ldap_certs:/opt/bitnami/openldap/certs'
|
||||
- '../../docker-compose/_sources/ldap_diffs:/opt/bitnami/openldap/ldiffs'
|
||||
{% endif %}
|
||||
# A useful container that simply passes through log messages to the console
|
||||
# helpful for testing awx/tower logging
|
||||
@ -157,6 +180,11 @@ volumes:
|
||||
redis_socket_{{ container_postfix }}:
|
||||
name: tools_redis_socket_{{ container_postfix }}
|
||||
{% endfor -%}
|
||||
{% if enable_ldap %}
|
||||
openldap_data:
|
||||
name: tools_ldap_1
|
||||
driver: local
|
||||
{% endif %}
|
||||
{% if minikube_container_group|bool %}
|
||||
networks:
|
||||
default:
|
||||
|
||||
52
tools/docker-compose/ansible/templates/ldap_settings.json.j2
Normal file
52
tools/docker-compose/ansible/templates/ldap_settings.json.j2
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"AUTH_LDAP_1_SERVER_URI": "ldap://{{ container_reference }}:389",
|
||||
"AUTH_LDAP_1_BIND_DN": "cn=admin,dc=example,dc=org",
|
||||
"AUTH_LDAP_1_BIND_PASSWORD": "admin",
|
||||
"AUTH_LDAP_1_START_TLS": false,
|
||||
"AUTH_LDAP_1_CONNECTION_OPTIONS": {
|
||||
"OPT_REFERRALS": 0,
|
||||
"OPT_NETWORK_TIMEOUT": 30
|
||||
},
|
||||
"AUTH_LDAP_1_USER_SEARCH": [
|
||||
"ou=users,dc=example,dc=org",
|
||||
"SCOPE_SUBTREE",
|
||||
"(cn=%(user)s)"
|
||||
],
|
||||
"AUTH_LDAP_1_USER_DN_TEMPLATE": "cn=%(user)s,ou=users,dc=example,dc=org",
|
||||
"AUTH_LDAP_1_USER_ATTR_MAP": {
|
||||
"first_name": "givenName",
|
||||
"last_name": "sn",
|
||||
"email": "mail"
|
||||
},
|
||||
"AUTH_LDAP_1_GROUP_SEARCH": [
|
||||
"ou=groups,dc=example,dc=org",
|
||||
"SCOPE_SUBTREE",
|
||||
"(objectClass=groupOfNames)"
|
||||
],
|
||||
"AUTH_LDAP_1_GROUP_TYPE": "MemberDNGroupType",
|
||||
"AUTH_LDAP_1_GROUP_TYPE_PARAMS": {
|
||||
"member_attr": "member",
|
||||
"name_attr": "cn"
|
||||
},
|
||||
"AUTH_LDAP_1_REQUIRE_GROUP": "cn=awx_users,ou=groups,dc=example,dc=org",
|
||||
"AUTH_LDAP_1_DENY_GROUP": null,
|
||||
"AUTH_LDAP_1_USER_FLAGS_BY_GROUP": {
|
||||
"is_superuser": [
|
||||
"cn=awx_admins,ou=groups,dc=example,dc=org"
|
||||
],
|
||||
"is_system_auditor": [
|
||||
"cn=awx_auditors,ou=groups,dc=example,dc=org"
|
||||
]
|
||||
},
|
||||
"AUTH_LDAP_1_ORGANIZATION_MAP": {
|
||||
"LDAP Organization": {
|
||||
"users": true,
|
||||
"remove_admins": false,
|
||||
"remove_users": true,
|
||||
"admins": [
|
||||
"cn=awx_org_admins,ou=groups,dc=example,dc=org"
|
||||
]
|
||||
}
|
||||
},
|
||||
"AUTH_LDAP_1_TEAM_MAP": {}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user