├── doc ├── source │ ├── _static │ │ └── .gitkeep │ ├── configure-federation.rst │ ├── index.rst │ ├── configure-federation-wrapper.rst │ ├── configure-keystone.rst │ ├── configure-federation-idp.rst │ ├── configure-federation-mapping.rst │ └── conf.py ├── requirements.txt └── Makefile ├── releasenotes ├── notes │ ├── .placeholder │ ├── os_keystone-centos7-support-0a5d97f81ac42e44.yaml │ ├── shibboleth_mirror_el-89e41075a1ee8fbf.yaml │ ├── keystone_ssl-4dc7676a36831f85.yaml │ ├── keystone-endpoints-urls-679748dec6ee6dd7.yaml │ ├── remove_rpc_backend-187132a35223d295.yaml │ ├── os-keystone-apache-log-format-support-7232177f835222ee.yaml │ ├── keystone-oidc-forwarded-proto-92471121e3949428.yaml │ ├── sso-callback-template-cf720ab7f6fc2461.yaml │ ├── os-keystone-only-install-venv-b766568ee8d40354.yaml │ ├── tls_variables-5d7db8f80f158f0d.yaml │ ├── primary-container-rebuild-a2f4d7f33d66c843.yaml │ ├── deprecated-memcached-and-backend-caching-vars-88c48117b232b37e.yaml │ ├── tls12-only-75222cbe8c32ad57.yaml │ ├── capping_keystone_workers-e284a47fc4dcea38.yaml │ ├── os-keystone-remove-service-user-f2100fa3127c7c2e.yaml │ ├── os-keystone-zero-downtime-upgrade-5f19ab84183490b9.yaml │ ├── keystone_uwsgi_role-b61179e170401e21.yaml │ ├── remove-requirements-git-bdf5691b8390ed7c.yaml │ ├── openstack-distribution-packages-d42a426bb57f76b1.yaml │ ├── os-keystone-oidc-scope-spelling-fix-3051b95adeb37901.yaml │ ├── db-pooling-old-vars-6ad7284cd8583218.yaml │ ├── app-credentials-709e7ae0573b4955.yaml │ ├── keystone_external_ssl-removal-5d972299f98dcc32.yaml │ ├── cache_backend-3ac67f78fa111445.yaml │ ├── add-security-headers-e46c205b42b9598b.yaml │ ├── journal-log-ccbb504642b49611.yaml │ ├── package-list-name-changes-007cacee4faf8ee6.yaml │ ├── keystone-upstream-config-files-d16f27fc1332ed83.yaml │ ├── keystone-init-config-overrides-1857d5e5bc5a905f.yaml │ ├── extra-headers-e54a672d3a78dd89.yaml │ ├── keystone-nginx-default-e9d91affd646f379.yaml │ ├── db-pooling-f078d5d7668377b2.yaml │ ├── oidc-fix-redirect-uri-5909172a1db5457f.yaml │ ├── keystone-service-setup-host-cd3ee3346af823e6.yaml │ ├── keystone_drop_nginx-5e7791d22f0be48a.yaml │ ├── federated_domain_names-4e169b8b9a947940.yaml │ ├── os-keystone-apache-mpm-tunable-support-1c72f2f99cd502bc.yaml │ ├── package-state-711a1eb4814311cc.yaml │ ├── keystone_uwsgi-86116742b67bb944.yaml │ ├── keystone-use-pki-role-d0e905887a5f5bd1.yaml │ ├── git-sourced-config-change-5b445d3ce26d29c1.yaml │ ├── os-keystone-admin-token-auth-deprecation-24e84a18f8a56814.yaml │ ├── mod-auth-openidc-102bd253b677f3fc.yaml │ ├── oslo-messaging-separate-backends-e68c98d4f9d9a79c.yaml │ ├── os-keystone-uwsgi-and-nginx-options-2157f8e40a7a8156.yaml │ └── keystone_init_time_settings-62a1aab4bcfc9779.yaml └── source │ ├── _static │ └── .placeholder │ ├── _templates │ └── .placeholder │ ├── unreleased.rst │ ├── zed.rst │ ├── train.rst │ ├── ussuri.rst │ ├── mitaka.rst │ ├── pike.rst │ ├── rocky.rst │ ├── stein.rst │ ├── queens.rst │ ├── newton.rst │ ├── ocata.rst │ ├── index.rst │ └── conf.py ├── .gitreview ├── templates ├── keystone.domain.conf.j2 ├── keystone-fernet-rotate.sh.j2 ├── shibboleth-attribute-map.xml.j2 ├── keystone-credential-rotate.sh.j2 ├── shibboleth2.xml.j2 └── keystone.conf.j2 ├── tasks ├── main_keystone_federation_sp_idp_setup.yml ├── keystone_credential.yml ├── keystone_fernet.yml ├── keystone_credential_distribute.yml ├── keystone_fernet_keys_distribute.yml ├── keystone_key_setup.yml ├── keystone_idp_setup.yml ├── keystone_service_bootstrap.yml ├── keystone_ldap_setup.yml ├── keystone_fernet_keys_autorotate.yml ├── keystone_credential_autorotate.yml ├── keystone_fernet_keys_create.yml ├── keystone_db_sync.yml ├── keystone_apache.yml ├── keystone_post_install.yml ├── keystone_federation_sp_shib_setup.yml ├── main_pre.yml ├── keystone_federation_sp_idp_setup.yml ├── keystone_install.yml ├── keystone_credential_create.yml └── main.yml ├── tests ├── inventory ├── host_vars │ ├── localhost.yml │ ├── infra1.yml │ ├── keystone1.yml │ └── keystone2.yml ├── group_vars │ └── all_containers.yml ├── test.yml ├── ansible-role-requirements.yml ├── os_keystone-overrides.yml └── test-keystone-functional.yml ├── CONTRIBUTING.rst ├── meta ├── openstack-ansible.yml └── main.yml ├── README.rst ├── zuul.d └── project.yaml ├── vars ├── distro_install.yml ├── source_install.yml ├── redhat.yml ├── debian.yml └── main.yml ├── examples └── playbook.yml ├── .gitignore ├── tox.ini ├── bindep.txt └── handlers └── main.yml /doc/source/_static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /releasenotes/notes/.placeholder: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /releasenotes/source/_static/.placeholder: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /releasenotes/source/_templates/.placeholder: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=review.opendev.org 3 | port=29418 4 | project=openstack/openstack-ansible-os_keystone.git 5 | -------------------------------------------------------------------------------- /releasenotes/notes/os_keystone-centos7-support-0a5d97f81ac42e44.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - CentOS7/RHEL support has been added to the os_keystone 4 | role. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/shibboleth_mirror_el-89e41075a1ee8fbf.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | URI to Shibboleth mirror has been fixed for EL-based distributions. 5 | -------------------------------------------------------------------------------- /releasenotes/source/unreleased.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | Current Series Release Notes 3 | ============================== 4 | 5 | .. release-notes:: 6 | -------------------------------------------------------------------------------- /releasenotes/source/zed.rst: -------------------------------------------------------------------------------- 1 | ======================== 2 | Zed Series Release Notes 3 | ======================== 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/zed 7 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone_ssl-4dc7676a36831f85.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Variable ``keystone_ssl`` was deprecated in favor of 5 | ``keystone_backend_ssl``. 6 | -------------------------------------------------------------------------------- /releasenotes/source/train.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Train Series Release Notes 3 | ========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/train 7 | -------------------------------------------------------------------------------- /releasenotes/source/ussuri.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Ussuri Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/ussuri 7 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone-endpoints-urls-679748dec6ee6dd7.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - The keystone endpoints now have versionless URLs. 4 | Any existing endpoints will be updated. 5 | -------------------------------------------------------------------------------- /releasenotes/source/mitaka.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Mitaka Series Release Notes 3 | ============================= 4 | 5 | .. release-notes:: 6 | :branch: origin/stable/mitaka 7 | -------------------------------------------------------------------------------- /releasenotes/source/pike.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Pike Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/pike 7 | -------------------------------------------------------------------------------- /releasenotes/source/rocky.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Rocky Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/rocky 7 | -------------------------------------------------------------------------------- /releasenotes/source/stein.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Stein Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/stein 7 | -------------------------------------------------------------------------------- /releasenotes/source/queens.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Queens Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/queens 7 | -------------------------------------------------------------------------------- /releasenotes/source/newton.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Newton Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: origin/stable/newton 7 | -------------------------------------------------------------------------------- /releasenotes/source/ocata.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Ocata Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: origin/stable/ocata 7 | -------------------------------------------------------------------------------- /releasenotes/notes/remove_rpc_backend-187132a35223d295.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | Remove ``keystone_rpc_backend`` option due to deprecation of 5 | rpc_backend option in oslo.messaging. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/os-keystone-apache-log-format-support-7232177f835222ee.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added keystone_apache_custom_log_format tunable for 4 | changing CustomLog format. Default is "combined". 5 | -------------------------------------------------------------------------------- /templates/keystone.domain.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | [identity] 4 | driver = ldap 5 | 6 | [ldap] 7 | {% for key, value in item.value | dictsort %} 8 | {{ key }} = {{ value }} 9 | {% endfor %} 10 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone-oidc-forwarded-proto-92471121e3949428.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | Fixes use of Apache mod_auth_openidc on Ubuntu Jammy where a new 5 | OIDCXForwardedHeaders configuration option is required. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/sso-callback-template-cf720ab7f6fc2461.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | The conditional that determines whether the ``sso_callback_template.html`` 5 | file is deployed for federated deployments has been fixed. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/os-keystone-only-install-venv-b766568ee8d40354.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - Installation of keystone and its dependent pip packages will now only 4 | occur within a Python virtual environment. The ``keystone_venv_enabled`` 5 | variable has been removed. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/tls_variables-5d7db8f80f158f0d.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | The variable 'keystone_ssl_cipher_suite' is deprecated in favour of 5 | 'keystone_ssl_cipher_suite_tls12' which will continue to manage 6 | configuration of ciphers for TLS v1.2 and earlier. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/primary-container-rebuild-a2f4d7f33d66c843.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | critical: 3 | - A bug that caused the Keystone credential keys to be lost when the playbook 4 | is run during a rebuild of the first Keystone container has been fixed. 5 | Please see launchpad bug 1667960 for more details. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecated-memcached-and-backend-caching-vars-88c48117b232b37e.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | The variables ``keystone_memcached_servers`` and 5 | ``keystone_cache_backend_argument`` have been deprecated in favor of 6 | ``keystone_cache_servers``, a list of servers for caching purposes. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/tls12-only-75222cbe8c32ad57.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | security: 3 | - | 4 | The default TLS verion has been set to TLS1.2. This only allows 5 | version 1.2 of the protocol to be used when terminating or creating TLS 6 | connections. You can change the value with the keystone_ssl_protocol 7 | variable. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/capping_keystone_workers-e284a47fc4dcea38.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Capping the default value for the variable ``keystone_wsgi_processes`` 4 | to 16 when the user doesn't configure this variable. Default value is 5 | half the number of vCPUs available on the machine with a capping value 6 | of 16. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/os-keystone-remove-service-user-f2100fa3127c7c2e.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The tasks creating a keystone service user have been removed, along with 5 | related variables ``keystone_service_user_name`` and 6 | ``keystone_service_password``. This user can be deleted in existing 7 | deployments. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/os-keystone-zero-downtime-upgrade-5f19ab84183490b9.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - The os_keystone role now performs a rolling upgrade 4 | without downtime during installation. `The process 5 | for rolling upgrades is documented here `_. 6 | -------------------------------------------------------------------------------- /releasenotes/source/index.rst: -------------------------------------------------------------------------------- 1 | ================================ 2 | OpenStack-Ansible Release Notes 3 | ================================ 4 | 5 | .. toctree:: 6 | :maxdepth: 1 7 | 8 | unreleased 9 | zed 10 | ussuri 11 | train 12 | stein 13 | rocky 14 | queens 15 | pike 16 | ocata 17 | newton 18 | mitaka 19 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone_uwsgi_role-b61179e170401e21.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Keystone now uses common uwsgi role for uWSGI deployment. Along with that 5 | variable ``keystone_services`` has been extended with required arguments 6 | for uWSGI. If you override this variable locally make sure to update it's 7 | structure accordingly. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-requirements-git-bdf5691b8390ed7c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - The variables ``keystone_requirements_git_repo`` and 4 | ``keystone_requirements_git_install_branch`` have been 5 | removed in favour of using the URL/path to the 6 | upper-constraints file using the 7 | variable ``pip_install_upper_constraints`` instead. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/openstack-distribution-packages-d42a426bb57f76b1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | The role now supports using the distribution packages for the OpenStack 5 | services instead of the pip ones. This feature is disabled by default 6 | and can be enabled by simply setting the ``keystone_install_method`` 7 | variable to ``distro``. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/os-keystone-oidc-scope-spelling-fix-3051b95adeb37901.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | For deployers using Keystone as an OIDC-based Service Provider there has 5 | been a spelling fix for the OIDCScope setting. Please use 6 | ``keystone_sp.trusted_idp_list.0.oidc_scope`` instead of 7 | ``keystone_sp.trusted_idp_list.0.idc_scope``. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/db-pooling-old-vars-6ad7284cd8583218.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The following keystone role variables were previously deprecated, and 5 | are now removed. Replacement variables were introduced in the Xena release. 6 | ``keystone_database_pool_timeout`` ``keystone_database_max_pool_size`` 7 | ``keystone_database_idle_timeout`` 8 | -------------------------------------------------------------------------------- /releasenotes/notes/app-credentials-709e7ae0573b4955.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Application credentials are now enabled by default as a keystone 5 | authentication method. If deployments do not wish to enable 6 | application credentials then the existing keystone_auth_methods variable 7 | can be overidden with the required set of authentication methods. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone_external_ssl-removal-5d972299f98dcc32.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | The variable ``keystone_external_ssl`` was deprecated and is no longer used. 5 | You still can control if communication between HAProxy and Keystone should 6 | be covered with TLS through ``keystone_backend_ssl`` or 7 | ``haproxy_ssl``/``haproxy_ssl_all_vips`` for communication between clients 8 | and HAProxy on frontend. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/cache_backend-3ac67f78fa111445.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | New variables have been added to manage used cache backends: 5 | 6 | * ``openstack_cache_backend``: defines driver, that will be used for 7 | caching. 8 | Default: oslo_cache.memcache_pool 9 | * ``openstack_cache_backend_map``: maps selected backend to 10 | the oslo driver that should be installed and configured for it. 11 | -------------------------------------------------------------------------------- /tasks/main_keystone_federation_sp_idp_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including keystone_federation_sp_idp_setup tasks 3 | ansible.builtin.include_tasks: keystone_federation_sp_idp_setup.yml 4 | with_items: "{{ keystone_sp.trusted_idp_list }}" 5 | loop_control: 6 | loop_var: trusted_idp 7 | no_log: true 8 | when: 9 | - keystone_service_setup | bool 10 | - keystone_sp != {} 11 | run_once: true 12 | tags: 13 | - keystone-config 14 | -------------------------------------------------------------------------------- /releasenotes/notes/add-security-headers-e46c205b42b9598b.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | security: 3 | - | 4 | The following headers were added as additional default (and static) values. 5 | `X-Content-Type-Options nosniff`, `X-XSS-Protection "1; mode=block"`, and 6 | `Content-Security-Policy "default-src 'self' https: wss:;"`. Additionally, 7 | the `X-Frame-Options DENY` header was added, defaulting to DENY. You may 8 | override the header via the `keystone_x_frame_options` variable. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/journal-log-ccbb504642b49611.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - The log path, ``/var/log/keystone`` is no longer used to capture service 4 | logs. All logging for the Keystone service will now be sent directly to the 5 | systemd journal. 6 | other: 7 | - When running keystone with apache(httpd) all apache logs will be stored in 8 | the standard apache log directory which is controlled by the distro specific 9 | variable ``keystone_apache_default_log_folder``. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/package-list-name-changes-007cacee4faf8ee6.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - The variable ``keystone_apt_packages`` has been renamed to 4 | ``keystone_distro_packages``. 5 | - The variable ``keystone_idp_apt_packages`` has been renamed to 6 | ``keystone_idp_distro_packages``. 7 | - The variable ``keystone_sp_apt_packages`` has been renamed to 8 | ``keystone_sp_distro_packages``. 9 | - The variable ``keystone_developer_apt_packages`` has been renamed to 10 | ``keystone_developer_mode_distro_packages``. 11 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone-upstream-config-files-d16f27fc1332ed83.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - The ``os_keystone`` role will now (by default) source the 4 | ``keystone-paste.ini``, ``policy.json`` and ``sso_callback_template.html`` 5 | templates from the service git source instead of from the role. It also 6 | now includes a facility where you can place your own templates in 7 | ``/etc/openstack_deploy/keystone`` (by default) and it will be 8 | deployed to the target host after being interpreted by the 9 | template engine. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone-init-config-overrides-1857d5e5bc5a905f.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - New variables have been added to allow a deployer to customize 4 | a keystone systemd unit file to their liking. 5 | - The task dropping the keystone systemd unit files now uses the 6 | ``config_template`` action plugin allowing deployers access to 7 | customize the unit files as they see fit without having to 8 | load extra options into the defaults and pollute the generic 9 | systemd unit file with jinja2 variables and conditionals. 10 | 11 | -------------------------------------------------------------------------------- /releasenotes/notes/extra-headers-e54a672d3a78dd89.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Extra headers can be added to Keystone responses by adding items to 5 | ``keystone_extra_headers``. Example: 6 | 7 | .. code-block:: yaml 8 | 9 | keystone_extra_headers: 10 | - parameter: "Access-Control-Expose-Headers" 11 | value: "X-Subject-Token" 12 | - parameter: "Access-Control-Allow-Headers" 13 | value: "Content-Type, X-Auth-Token" 14 | - parameter: "Access-Control-Allow-Origin" 15 | value: "*" 16 | -------------------------------------------------------------------------------- /tests/inventory: -------------------------------------------------------------------------------- 1 | [all] 2 | localhost 3 | infra1 4 | keystone1 5 | keystone2 6 | 7 | [all_containers] 8 | infra1 9 | keystone1 10 | keystone2 11 | 12 | [oslomsg_rpc_all] 13 | infra1 14 | 15 | [oslomsg_notify_all] 16 | infra1 17 | 18 | [rabbitmq_all] 19 | infra1 20 | 21 | [galera_all] 22 | infra1 23 | 24 | [memcached_all] 25 | infra1 26 | 27 | [service_all:children] 28 | rabbitmq_all 29 | galera_all 30 | memcached_all 31 | 32 | [keystone_all] 33 | keystone1 34 | keystone2 35 | 36 | [utility_all] 37 | keystone1 38 | 39 | [haproxy_all:children] 40 | haproxy 41 | 42 | [haproxy] 43 | localhost 44 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone-nginx-default-e9d91affd646f379.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - Keystone now uses uWSGI exclusively (instead of Apache with mod_wsgi) 4 | and has the web server acting as a reverse proxy. The default web 5 | server is now set to Nginx instead of Apache, but Apache will 6 | automatically used if federation is configured. 7 | deprecations: 8 | - The variables ``keystone_apache_enabled`` and ``keystone_mod_wsgi_enabled`` 9 | have been removed and replaced with a single variable ``keystone_web_server`` 10 | to optionally set the web server used for keystone. 11 | -------------------------------------------------------------------------------- /releasenotes/notes/db-pooling-f078d5d7668377b2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | For consistency reasons, the following variables were deprecated in favor of 5 | the new ones in a standardized format used in other repositories. 6 | ``keystone_database_pool_timeout`` -> ``keystone_db_pool_timeout`` 7 | ``keystone_database_max_pool_size`` -> ``keystone_db_max_pool_size`` 8 | ``keystone_database_idle_timeout`` -> ``keystone_db_connection_recycle_time`` 9 | However, they will be supported until next Yoga release. 10 | - | 11 | ``keystone_database_min_pool_size`` was deprecated as it's deprecated in oslo.db 12 | -------------------------------------------------------------------------------- /releasenotes/notes/oidc-fix-redirect-uri-5909172a1db5457f.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Keystone OIDC parameter 'oidc_redirect_uri' is replaced with 5 | 'oidc_redirect_path'. This parameter no longer needs to be set explicitly 6 | unless you run additional services which may collide with the default 7 | on the same port as Keystone. Your OIDC provider may need to be updated 8 | to reflect this change in redirect URI which defaults to the Keystone 9 | public URL plus the path /oidc_redirect. 10 | fixes: 11 | - | 12 | Fixed OpenStack command line OIDC integration where Apache mod_auth_openidc 13 | if >= v2.4.9 including on Ubuntu Jammy. 14 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone-service-setup-host-cd3ee3346af823e6.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | The service updates for keystone will now be executed 5 | through delegation to the ``keystone_service_setup_host`` which, 6 | by default, is ``localhost`` (the deploy host). Deployers can 7 | opt to rather change this to the utility container by implementing 8 | the following override in ``user_variables.yml``. 9 | 10 | .. code-block:: yaml 11 | 12 | keystone_service_setup_host: "{{ groups['utility_all'][0] }}" 13 | 14 | deprecations: 15 | - | 16 | The variable ``keystone_requires_pip_packages`` is no longer required 17 | and has therefore been removed. 18 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone_drop_nginx-5e7791d22f0be48a.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | We removed multiple web server support for keystone and left only Apache 5 | since nginx is missing features required for federation setup. 6 | With this change following variables are deprecated and have no effect: 7 | 8 | * keystone_web_server 9 | * keystone_centos_nginx_mirror 10 | * keystone_centos_nginx_key 11 | * keystone_nginx_access_log_format_combined 12 | * keystone_nginx_access_log_format_extras 13 | * keystone_nginx_ports 14 | * keystone_nginx_extra_conf 15 | 16 | Nginx web server will be removed and replaced with Apache during upgrade. 17 | -------------------------------------------------------------------------------- /tests/host_vars/localhost.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | bridges: 17 | - "br-mgmt" 18 | -------------------------------------------------------------------------------- /releasenotes/notes/federated_domain_names-4e169b8b9a947940.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | issues: 3 | - | 4 | Due to the underlying `bug `_ 5 | in Ansible collections for OpenStack, ``Default`` domain name can be 6 | renamed to ``default`` under certain conditions. 7 | One known example is having ``domain: default`` defenition under 8 | ``keystone_sp -> trusted_idp_list -> federated_identities`` structure. 9 | upgrade: 10 | - | 11 | Please, make sure that in case of federation usage you define domain 12 | name instead of it's ID (ie. ``Default`` instead of ``default``) 13 | under ``keystone_sp -> trusted_idp_list -> federated_identities`` 14 | -------------------------------------------------------------------------------- /releasenotes/notes/os-keystone-apache-mpm-tunable-support-1c72f2f99cd502bc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Apache MPM tunable support has been added to the os-keystone 5 | role in order to allow MPM thread tuning. 6 | Default values reflect the current Ubuntu default settings: 7 | 8 | .. code-block:: yaml 9 | 10 | keystone_httpd_mpm_backend: event 11 | keystone_httpd_mpm_start_servers: 2 12 | keystone_httpd_mpm_min_spare_threads: 25 13 | keystone_httpd_mpm_max_spare_threads: 75 14 | keystone_httpd_mpm_thread_limit: 64 15 | keystone_httpd_mpm_thread_child: 25 16 | keystone_httpd_mpm_max_requests: 150 17 | keystone_httpd_mpm_max_conn_child: 0 18 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | The source repository for this project can be found at: 2 | 3 | https://opendev.org/openstack/openstack-ansible-os_keystone 4 | 5 | Pull requests submitted through GitHub are not monitored. 6 | 7 | To start contributing to OpenStack, follow the steps in the contribution guide 8 | to set up and use Gerrit: 9 | 10 | https://docs.openstack.org/contributors/code-and-documentation/quick-start.html 11 | 12 | Bugs should be filed on Launchpad: 13 | 14 | https://bugs.launchpad.net/openstack-ansible 15 | 16 | For more specific information about contributing to this repository, see the 17 | OpenStack-Ansible contributors guide: 18 | 19 | https://docs.openstack.org/openstack-ansible/latest/contributors/contributing.html -------------------------------------------------------------------------------- /releasenotes/notes/package-state-711a1eb4814311cc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - The os_keystone role now supports the ability to configure whether 4 | apt/yum tasks install the latest available package, or just ensure 5 | that the package is present. The default action is to ensure that 6 | the latest package is present. The action taken may be changed to 7 | only ensure that the package is present by setting 8 | ``keystone_package_state`` to ``present``. 9 | upgrade: 10 | - The os_keystone role always checks whether the latest package is 11 | installed when executed. If a deployer wishes to change the check to 12 | only validate the presence of the package, the option 13 | ``keystone_package_state`` should be set to ``present``. 14 | -------------------------------------------------------------------------------- /tests/host_vars/infra1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | ansible_host: 10.1.0.2 17 | ansible_become: True 18 | ansible_user: root 19 | container_name: infra1 20 | -------------------------------------------------------------------------------- /tests/host_vars/keystone1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | ansible_host: 10.1.0.3 17 | ansible_become: True 18 | ansible_user: root 19 | container_name: keystone1 20 | -------------------------------------------------------------------------------- /tests/host_vars/keystone2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | ansible_host: 10.1.0.4 17 | ansible_become: True 18 | ansible_user: root 19 | container_name: keystone2 20 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone_uwsgi-86116742b67bb944.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | The keystone role now supports the option `keystone_use_uwsgi`, which will 5 | allow deployers the ability to run keystone via uWSGI without needing the 6 | apache webserver. When the `keystone_use_uwsgi` option is enabled, it will 7 | setup the uWSGI process on port 5000. 8 | other: 9 | - | 10 | The keystone role can now has the ability to run a minimal uWSGI process 11 | for keystone when the option `keystone_use_uwsgi` is set **true**. This 12 | feature provides operators the ability to run a minimal install without 13 | apache. While the minimal deployment is functional, it is not featureful. 14 | Things like modshib and oath are not supported when running the minimal 15 | setup. 16 | -------------------------------------------------------------------------------- /meta/openstack-ansible.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2017, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # (c) 2017, Jean-Philippe Evrard 17 | 18 | maturity_info: 19 | status: complete 20 | created_during: mitaka 21 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | # The order of packages is significant, because pip processes them in the order 2 | # of appearance. Changing the order has an impact on the overall integration 3 | # process, which may cause wedges in the gate later. 4 | 5 | # WARNING: 6 | # This file is maintained in the openstack-ansible-tests repository. 7 | # https://opendev.org/openstack/openstack-ansible-tests/src/branch/master/sync/doc/requirements.txt 8 | # If you need to modify this file, update the one in the 9 | # openstack-ansible-tests repository. Once it merges there, the changes will 10 | # automatically be proposed to all the repositories which use it. 11 | 12 | sphinx>=2.0.0,!=2.1.0 # BSD 13 | sphinxcontrib-svg2pdfconverter>=0.1.0 # BSD 14 | openstackdocstheme>=2.2.1 # Apache-2.0 15 | reno>=3.1.0 # Apache-2.0 16 | doc8>=0.6.0 # Apache-2.0 17 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | OpenStack-Ansible Keystone 3 | ========================== 4 | 5 | Ansible role that installs and configures OpenStack Keystone. Keystone is 6 | installed behind the Apache webserver listening on port 5000 by default. 7 | 8 | Documentation for the project can be found at: 9 | ``_ 10 | 11 | Release notes for the project can be found at: 12 | ``_ 13 | 14 | The project source code repository is located at: 15 | ``_ 16 | 17 | The project home is at: 18 | ``_ 19 | 20 | The project bug tracker is located at: 21 | `< https://bugs.launchpad.net/openstack-ansible>`_ 22 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone-use-pki-role-d0e905887a5f5bd1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The keystone installation now uses ansible-role-pki to create and install 5 | a server certificate for Apache when keystone_ssl is true. The same role 6 | is also used to create a CA certificate and key for SAML federation when 7 | keystone_idp is populated by the deployer. For an existing keystone SAML 8 | setup the certificate and key will be re-created which may be undesirable, 9 | unless the existing ones are first copied to the relevant directories in 10 | ``/etc/openstack_deploy/pki/roots`` on the deploy host. The variables 11 | ``keystone_ssl_self_signed_regen`` and ``keystone_ssl_self_signed_subject`` 12 | are removed and are replaced with equivalent functionality via the new 13 | ``keystone_pki_*`` variables. 14 | -------------------------------------------------------------------------------- /releasenotes/notes/git-sourced-config-change-5b445d3ce26d29c1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | In order to collect the default files used for various templates, the 5 | implementation has been changed from using a git source to rather 6 | using the built-in templates from the venv build based on the setup.cfg 7 | file. As such, the following variables have been removed. 8 | 9 | * ``keystone_git_config_lookup_location`` 10 | * ``keystone_paste_git_file_path`` 11 | * ``keystone_sso_callback_git_file_path`` 12 | 13 | Instead, a location on the deployment host where the venv defaults are 14 | stored is now configurable using the variable 15 | ``keystone_config_cache_path`` which defaults to ``cache/keystone`` in 16 | the deploy user home directory. This location is used as a template 17 | source when deploying the file to the target host. 18 | -------------------------------------------------------------------------------- /releasenotes/notes/os-keystone-admin-token-auth-deprecation-24e84a18f8a56814.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | security: 3 | - | 4 | The admin_token_auth middleware presents a potential 5 | security risk and will be removed in a future release 6 | of keystone. Its use can be removed by setting the 7 | ``keystone_keystone_paste_ini_overrides`` variable. 8 | 9 | :: 10 | 11 | keystone_keystone_paste_ini_overrides: 12 | pipeline:public_api: 13 | pipeline: cors sizelimit osprofiler url_normalize request_id build_auth_context token_auth json_body ec2_extension public_service 14 | pipeline:admin_api: 15 | pipeline: cors sizelimit osprofiler url_normalize request_id build_auth_context token_auth json_body ec2_extension s3_extension admin_service 16 | pipeline:api_v3: 17 | pipeline: cors sizelimit osprofiler url_normalize request_id build_auth_context token_auth json_body ec2_extension_v3 s3_extension service_v3 18 | -------------------------------------------------------------------------------- /tests/group_vars/all_containers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | container_networks: 17 | management_address: 18 | address: "{{ ansible_host }}" 19 | bridge: "br-mgmt" 20 | interface: "eth1" 21 | netmask: "255.255.255.0" 22 | type: "veth" 23 | physical_host: localhost 24 | properties: 25 | service_name: "{{ inventory_hostname }}" 26 | -------------------------------------------------------------------------------- /zuul.d/project.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2017, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - project: 17 | templates: 18 | - check-requirements 19 | - openstack-ansible-linters-jobs 20 | - openstack-ansible-deploy-aio_metal-jobs 21 | - openstack-ansible-deploy-aio_distro_metal-jobs 22 | - openstack-ansible-deploy-infra_lxc-jobs 23 | - publish-openstack-docs-pti 24 | - build-release-notes-jobs-python3 25 | -------------------------------------------------------------------------------- /releasenotes/notes/mod-auth-openidc-102bd253b677f3fc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added support for using mod_auth_openidc instead of shibboleth as a 4 | service provider for supporting users who have a preference to use OIDC 5 | for federation. Mod_auth_openidc is the apache module that is recommended 6 | in the keystone documentation for implementing openidc. 7 | Added a variable to called apache_mod to keystone_sp, if left undefined 8 | shibboleth will continue to be installed by default provided keystone_sp is 9 | not empty. Mod_auth_openidc will not be installed unless it is spelled 10 | correctly, any misspellings will result in a shibboleth install. 11 | Note that installing shibboleth on Debian based metal distro deployments 12 | may break services that depend on libcurl4, as shib2 requires libcurl3, 13 | and they are unable to coexist. This can be resolved when there is a 14 | shib3 package available in a future release of Ubuntu/Debian. 15 | There is currently no support for simultaneous use of shibboleth2 and 16 | mod_auth_openidc. 17 | -------------------------------------------------------------------------------- /tasks/keystone_credential.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Including keystone_credential_create tasks 17 | ansible.builtin.include_tasks: keystone_credential_create.yml 18 | when: _keystone_is_first_play_host 19 | 20 | - name: Including keystone_credential_distribute tasks 21 | ansible.builtin.include_tasks: keystone_credential_distribute.yml 22 | when: _keystone_is_first_play_host 23 | 24 | - name: Including keystone_credential_autorotate tasks 25 | ansible.builtin.include_tasks: keystone_credential_autorotate.yml 26 | -------------------------------------------------------------------------------- /tasks/keystone_fernet.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Including keystone_fernet_keys_create tasks 17 | ansible.builtin.include_tasks: keystone_fernet_keys_create.yml 18 | when: _keystone_is_first_play_host 19 | 20 | - name: Including keystone_fernet_keys_distribute tasks 21 | ansible.builtin.include_tasks: keystone_fernet_keys_distribute.yml 22 | when: _keystone_is_first_play_host 23 | 24 | - name: Including keystone_fernet_keys_autorotate tasks 25 | ansible.builtin.include_tasks: keystone_fernet_keys_autorotate.yml 26 | -------------------------------------------------------------------------------- /vars/distro_install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2018, SUSE LINUX GmbH 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # 17 | # Compile a list of the distro packages to install based on 18 | # whether the host is in the host group and the service is 19 | # enabled. 20 | # 21 | keystone_package_list: |- 22 | {% set packages = keystone_distro_packages %} 23 | {% if keystone_idp != {} %} 24 | {% set _ = packages.extend(keystone_idp_distro_packages) %} 25 | {% endif %} 26 | {% set _ = packages.extend(keystone_service_distro_packages) %} 27 | {{ packages }} 28 | 29 | _keystone_bin: "/usr/bin" 30 | -------------------------------------------------------------------------------- /releasenotes/notes/oslo-messaging-separate-backends-e68c98d4f9d9a79c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Support separate oslo.messaging services for RPC and Notifications 4 | to enable operation of separate and different messaging backend 5 | servers in keystone. 6 | deprecations: 7 | - | 8 | The rabbitmq server parameters have been replaced by corresponding 9 | oslo.messaging RPC and Notify parameters in order to abstract the 10 | messaging service from the actual backend server deployment. 11 | - keystone_oslomsg_rpc_servers replaces keystone_rabbitmq_servers 12 | - keystone_oslomsg_rpc_port replaces keystone_rabbitmq_port 13 | - keystone_oslomsg_rpc_use_ssl replaces keystone_rabbitmq_use_ssl 14 | - keystone_oslomsg_rpc_userid replaces keystone_rabbitmq_userid 15 | - keystone_oslomsg_rpc_vhost replaces keystone_rabbitmq_vhost 16 | - keystone_oslomsg_notify_servers replaces keystone_rabbitmq_telemetry_servers 17 | - keystone_oslomsg_notify_port replaces keystone_rabbitmq_telemetry_port 18 | - keystone_oslomsg_notify_use_ssl replaces keystone_rabbitmq_telemetry_use_ssl 19 | - keystone_oslomsg_notify_userid replaces keystone_rabbitmq_telemetry_userid 20 | - keystone_oslomsg_notify_vhost replaces keystone_rabbitmq_telemetry_vhost 21 | -------------------------------------------------------------------------------- /tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Prepare the user ssh keys 17 | - import_playbook: common/test-prepare-keys.yml 18 | 19 | # Prepare the host 20 | - import_playbook: common/test-prepare-host.yml 21 | 22 | # Prepare the containers 23 | - import_playbook: common/test-prepare-containers.yml 24 | 25 | # Install haproxy 26 | - import_playbook: common/test-install-haproxy.yml 27 | 28 | # Install RabbitMQ/MariaDB 29 | - import_playbook: common/test-install-infra.yml 30 | 31 | # Install Keystone 32 | - import_playbook: common/test-install-keystone.yml 33 | 34 | # Install and execute Tempest 35 | - import_playbook: common/test-install-tempest.yml 36 | 37 | # Test Keystone 38 | - import_playbook: test-keystone-functional.yml 39 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | galaxy_info: 17 | author: rcbops 18 | description: Installation and setup of keystone 19 | company: Rackspace 20 | license: Apache2 21 | role_name: os_keystone 22 | namespace: openstack 23 | min_ansible_version: "2.10" 24 | platforms: 25 | - name: Debian 26 | versions: 27 | - bullseye 28 | - name: Ubuntu 29 | versions: 30 | - focal 31 | - jammy 32 | - name: EL 33 | versions: 34 | - "9" 35 | galaxy_tags: 36 | - cloud 37 | - python 38 | - keystone 39 | - development 40 | - openstack 41 | dependencies: 42 | - role: apt_package_pinning 43 | when: 44 | - ansible_facts['pkg_mgr'] == 'apt' 45 | -------------------------------------------------------------------------------- /tasks/keystone_credential_distribute.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # TODO(logan): Change to synchronize module to pass ANSIBLE0006 17 | # and remove the skip_ansible_lint tag at that time. 18 | - name: Distribute the credential key repository 19 | command: > 20 | rsync -e 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' 21 | -avz 22 | --delete 23 | {{ keystone_credential_key_repository }}/ 24 | {{ keystone_system_user_name }}@{{ hostvars[item]['ansible_host'] | default(item) }}:{{ keystone_credential_key_repository }}/ 25 | become: true 26 | become_user: "{{ keystone_system_user_name }}" 27 | changed_when: false 28 | with_items: "{{ groups['keystone_all'][1:] }}" 29 | tags: 30 | - skip_ansible_lint 31 | -------------------------------------------------------------------------------- /tasks/keystone_fernet_keys_distribute.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # TODO(logan): Change to synchronize module to pass ANSIBLE0006 17 | # and remove the skip_ansible_lint tag at that time. 18 | - name: Distribute the fernet key repository 19 | command: > 20 | rsync -e 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' 21 | -avz 22 | --delete 23 | {{ keystone_fernet_tokens_key_repository }}/ 24 | {{ keystone_system_user_name }}@{{ hostvars[item]['ansible_host'] | default(item) }}:{{ keystone_fernet_tokens_key_repository }}/ 25 | become: true 26 | become_user: "{{ keystone_system_user_name }}" 27 | changed_when: false 28 | with_items: "{{ groups['keystone_all'][1:] }}" 29 | tags: 30 | - skip_ansible_lint 31 | -------------------------------------------------------------------------------- /releasenotes/notes/os-keystone-uwsgi-and-nginx-options-2157f8e40a7a8156.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Introduced option to deploy Keystone under Uwsgi. A new variable 4 | ``keystone_mod_wsgi_enabled`` is introduced to toggle this 5 | behavior. The default is ``true`` which continues to deploy with 6 | mod_wsgi for Apache. The ports used by Uwsgi for socket and http 7 | connection for both public and admin Keystone services are 8 | configurable (see also the ``keystone_uwsgi_ports`` dictionary 9 | variable). Other Uwsgi configuration can be overridden by using 10 | the ``keystone_uwsgi_ini_overrides`` variable as documented 11 | under "Overriding OpenStack configuration defaults" in the 12 | OpenStack-Ansible Install Guide. Federation features should be 13 | considered _experimental_ with this configuration at this time. 14 | - Introduced option to deploy Keystone behind Nginx. A new 15 | variable ``keystone_apache_enabled`` is introduced to toggle 16 | this behavior. The default is ``true`` which continues to 17 | deploy with Apache. Additional configuration can be delivered to 18 | Nginx through the use of the ``keystone_nginx_extra_conf`` list 19 | variable. Federation features are not supported with this 20 | configuration at this time. Use of this option requires 21 | ``keystone_mod_wsgi_enabled`` to be set to ``false`` which will 22 | deploy Keystone under Uwsgi. -------------------------------------------------------------------------------- /examples/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Installation and setup of Keystone 3 | hosts: keystone_all 4 | user: root 5 | roles: 6 | - role: os_keystone 7 | tags: 8 | - os-keystone 9 | vars: 10 | external_lb_vip_address: 10.100.100.102 11 | internal_lb_vip_address: 10.100.100.102 12 | keystone_galera_address: 10.100.100.101 13 | keystone_galera_database: keystone 14 | keystone_venv_tag: "testing" 15 | keystone_developer_mode: true 16 | keystone_git_install_branch: master 17 | keystone_auth_admin_password: "SuperSecretePassword" 18 | keystone_oslomsg_rpc_password: "secrete" 19 | keystone_oslomsg_notify_password: "secrete" 20 | keystone_container_mysql_password: "SuperSecrete" 21 | keystone_oslomsg_rpc_transport: rabbit 22 | keystone_oslomsg_rpc_servers: 10.100.100.101 23 | keystone_oslomsg_rpc_port: 5671 24 | keystone_oslomsg_rpc_use_ssl: true 25 | keystone_oslomsg_rpc_userid: keystone 26 | keystone_oslomsg_rpc_vhost: /keystone 27 | keystone_oslomsg_notify_transport: rabbit 28 | keystone_oslomsg_notify_servers: 10.100.100.101 29 | keystone_oslomsg_notify_port: 5671 30 | keystone_oslomsg_notify_use_ssl: true 31 | keystone_oslomsg_notify_userid: keystone 32 | keystone_oslomsg_notify_vhost: /keystone 33 | galera_client_drop_config_file: false 34 | galera_root_user: root 35 | vars_prompt: 36 | - name: "galera_root_password" 37 | prompt: "What is galera_root_password?" 38 | -------------------------------------------------------------------------------- /vars/source_install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2017, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # 17 | # Compile a list of the distro packages to install based on 18 | # whether the host is in the host group and the service is 19 | # enabled. 20 | # 21 | keystone_package_list: |- 22 | {% set packages = keystone_distro_packages %} 23 | {% if keystone_idp != {} %} 24 | {% set _ = packages.extend(keystone_idp_distro_packages) %} 25 | {% endif %} 26 | {{ packages }} 27 | 28 | _keystone_bin: "/openstack/venvs/keystone-{{ keystone_venv_tag }}/bin" 29 | keystone_uwsgi_bin: "{{ _keystone_bin }}" 30 | # These vars find a file on the deployment node, if it exists - otherwise the result is empty. 31 | shibboleth_cert_user_content: "{{ lookup('pipe', 'cat ' ~ shibboleth_cert_user_file_path ~ ' 2>/dev/null || true') }}" 32 | shibboleth_key_user_content: "{{ lookup('pipe', 'cat ' ~ shibboleth_key_user_file_path ~ ' 2>/dev/null || true') }}" 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Add patterns in here to exclude files created by tools integrated with this 2 | # repository, such as test frameworks from the project's recommended workflow, 3 | # rendered documentation and package builds. 4 | # 5 | # Don't add patterns to exclude files created by preferred personal tools 6 | # (editors, IDEs, your operating system itself even). These should instead be 7 | # maintained outside the repository, for example in a ~/.gitignore file added 8 | # with: 9 | # 10 | # git config --global core.excludesfile '~/.gitignore' 11 | 12 | # Compiled source # 13 | ################### 14 | *.com 15 | *.class 16 | *.dll 17 | *.exe 18 | *.o 19 | *.so 20 | *.pyc 21 | build/ 22 | dist/ 23 | doc/build/ 24 | 25 | # Packages # 26 | ############ 27 | # it's better to unpack these files and commit the raw source 28 | # git has its own built in compression methods 29 | *.7z 30 | *.dmg 31 | *.gz 32 | *.iso 33 | *.jar 34 | *.rar 35 | *.tar 36 | *.zip 37 | 38 | # Logs and databases # 39 | ###################### 40 | *.log 41 | *.sql 42 | *.sqlite 43 | logs/* 44 | 45 | # OS generated files # 46 | ###################### 47 | ._* 48 | .ansible 49 | .tox 50 | *.egg-info 51 | .eggs 52 | 53 | # Generated by pbr while building docs 54 | ###################################### 55 | AUTHORS 56 | ChangeLog 57 | 58 | # Files created by releasenotes build 59 | releasenotes/build 60 | 61 | # Test temp files 62 | tests/common 63 | tests/*.retry 64 | 65 | # Vagrant artifacts 66 | .vagrant 67 | 68 | # Git clones 69 | openstack-ansible-ops 70 | previous 71 | -------------------------------------------------------------------------------- /tasks/keystone_key_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Ensure .ssh directory is present 17 | ansible.builtin.file: 18 | state: directory 19 | path: "{{ keystone_system_user_home }}/.ssh" 20 | owner: "{{ keystone_system_user_name }}" 21 | group: "{{ keystone_system_group_name }}" 22 | mode: "0755" 23 | 24 | - name: Create ssh keys for synchronising fernet keys 25 | ansible.builtin.include_role: 26 | name: openstack.osa.ssh_keypairs 27 | args: 28 | apply: 29 | tags: 30 | - keystone-key 31 | vars: 32 | ssh_keypairs_setup_host: "{{ keystone_ssh_keypairs_setup_host }}" 33 | ssh_keypairs_dir: "{{ keystone_ssh_keypairs_dir }}" 34 | ssh_keypairs: "{{ keystone_ssh_keypairs }}" 35 | ssh_keypairs_install_keys: "{{ keystone_ssh_keypairs_install_keys }}" 36 | ssh_keypairs_install_ca: "{{ keystone_ssh_keypairs_install_ca }}" 37 | ssh_keypairs_principals: "{{ keystone_ssh_keypairs_principals }}" 38 | tags: 39 | - always 40 | -------------------------------------------------------------------------------- /doc/source/configure-federation.rst: -------------------------------------------------------------------------------- 1 | ========================================== 2 | Scenario - Configuring keystone federation 3 | ========================================== 4 | 5 | Federation for keystone can be utilised in two ways: 6 | 7 | * Supporting keystone as a Service Provider (SP): consuming identity 8 | assertions issued by an external Identity Provider, such as SAML 9 | assertions or OpenID Connect claims. 10 | * Supporting keystone as an Identity Provider (IdP): fulfilling authentication 11 | requests on behalf of Service Providers. 12 | 13 | .. important:: 14 | 15 | It is also possible to have one keystone act as an SP that 16 | consumes Identity from another keystone acting as an IdP. 17 | This will be discussed further in this document. 18 | 19 | In keystone federation, the IdP and SP exchange information securely to 20 | enable a user on the IdP cloud to access resources of the SP cloud. 21 | 22 | The following procedure describes how to set up federation: 23 | 24 | #. Configure keystone SPs. 25 | #. Configure the IdP: 26 | 27 | * Configure keystone as an IdP. 28 | * Configure Active Directory Federation Services (ADFS) 3.0 as an IdP. 29 | 30 | #. Configure the service provider: 31 | 32 | * Configure keystone as a federated service provider. 33 | * Configure keystone mappings. 34 | 35 | #. Run the authentication wrapper to use keystone-as-a-Service-Provider 36 | federation. 37 | 38 | .. toctree:: 39 | 40 | configure-federation-wrapper 41 | configure-federation-sp.rst 42 | configure-federation-idp.rst 43 | configure-federation-mapping.rst 44 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone_init_time_settings-62a1aab4bcfc9779.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - For the ``os_keystone`` role, the systemd unit ``TimeoutSec`` value which 4 | controls the time between sending a SIGTERM signal and a SIGKILL signal 5 | when stopping or restarting the service has been reduced from 300 seconds 6 | to 120 seconds. This provides 2 minutes for long-lived sessions to drain 7 | while preventing new ones from starting before a restart or a stop. The 8 | ``RestartSec`` value which controls the time between the service stop and 9 | start when restarting has been reduced from 150 seconds to 2 seconds to 10 | make the restart happen faster. These values can be adjusted by using the 11 | ``keystone_*_init_config_overrides`` variables which use the 12 | ``config_template`` task to change template defaults. 13 | upgrade: 14 | - For the ``os_keystone`` role, the systemd unit ``TimeoutSec`` value which 15 | controls the time between sending a SIGTERM signal and a SIGKILL signal 16 | when stopping or restarting the service has been reduced from 300 seconds 17 | to 120 seconds. This provides 2 minutes for long-lived sessions to drain 18 | while preventing new ones from starting before a restart or a stop. The 19 | ``RestartSec`` value which controls the time between the service stop and 20 | start when restarting has been reduced from 150 seconds to 2 seconds to 21 | make the restart happen faster. These values can be adjusted by using the 22 | ``keystone_*_init_config_overrides`` variables which use the 23 | ``config_template`` task to change template defaults. 24 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | minversion = 4.6.0 3 | skipsdist = True 4 | envlist = docs 5 | 6 | [testenv] 7 | usedevelop = False 8 | install_command = 9 | pip install -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} {opts} {packages} 10 | commands = 11 | /usr/bin/find . -type f -name "*.pyc" -delete 12 | passenv = 13 | COMMON_TESTS_PATH 14 | HOME 15 | http_proxy 16 | HTTP_PROXY 17 | https_proxy 18 | HTTPS_PROXY 19 | no_proxy 20 | NO_PROXY 21 | TESTING_BRANCH 22 | TESTING_HOME 23 | USER 24 | allowlist_externals = 25 | bash 26 | setenv = 27 | PYTHONUNBUFFERED=1 28 | ROLE_NAME=os_keystone 29 | TEST_IDEMPOTENCE=false 30 | VIRTUAL_ENV={envdir} 31 | WORKING_DIR={toxinidir} 32 | 33 | [testenv:docs] 34 | deps = 35 | -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} 36 | -r{toxinidir}/doc/requirements.txt 37 | commands = 38 | bash -c "rm -rf doc/build" 39 | doc8 doc 40 | sphinx-build -W --keep-going -b html doc/source doc/build/html 41 | 42 | [testenv:pdf-docs] 43 | deps = {[testenv:docs]deps} 44 | allowlist_externals = 45 | make 46 | commands = 47 | sphinx-build -W --keep-going -b latex doc/source doc/build/pdf 48 | make -C doc/build/pdf 49 | 50 | [doc8] 51 | # Settings for doc8: 52 | extensions = .rst 53 | 54 | [testenv:releasenotes] 55 | deps = {[testenv:docs]deps} 56 | commands = 57 | sphinx-build -a -E -W -d releasenotes/build/doctrees --keep-going -b html releasenotes/source releasenotes/build/html 58 | 59 | # environment used by the -infra templated docs job 60 | [testenv:venv] 61 | commands = 62 | {posargs} 63 | -------------------------------------------------------------------------------- /tasks/keystone_idp_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Generate IdP metadata 17 | ansible.builtin.shell: | 18 | {{ keystone_bin }}/keystone-manage saml_idp_metadata > {{ keystone_idp.idp_metadata_path }} 19 | become: true 20 | become_user: "{{ keystone_system_user_name }}" 21 | changed_when: false 22 | when: keystone_idp != {} 23 | notify: 24 | - Restart uWSGI 25 | 26 | - name: Register service providers 27 | openstack.osa.keystone: 28 | command: "ensure_service_provider" 29 | login_user: "{{ keystone_admin_user_name }}" 30 | login_password: "{{ keystone_auth_admin_password }}" 31 | login_project_name: "{{ keystone_admin_tenant_name }}" 32 | endpoint: "{{ keystone_service_adminurl }}" 33 | sp_name: "{{ item.id }}" 34 | sp_url: "{{ item.sp_url }}" 35 | sp_auth_url: "{{ item.auth_url }}" 36 | with_items: "{{ keystone_idp.service_providers | default([]) }}" 37 | no_log: true 38 | register: add_service_providers 39 | until: add_service_providers is success 40 | retries: 5 41 | delay: 10 42 | when: keystone_service_setup | bool 43 | -------------------------------------------------------------------------------- /vars/redhat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | keystone_distro_packages: 17 | - ca-certificates 18 | - cronie 19 | - cronie-anacron 20 | - git 21 | - openssh-server 22 | - rsync 23 | 24 | keystone_devel_distro_packages: 25 | - cyrus-sasl-lib 26 | - libffi-devel 27 | - libxml2-devel 28 | - libxslt-devel 29 | - openldap-devel 30 | - openssl-devel 31 | - systemd-devel 32 | - which 33 | 34 | keystone_service_distro_packages: 35 | - openstack-keystone 36 | - python3-systemd 37 | 38 | keystone_idp_distro_packages: 39 | - xmlsec1 40 | 41 | # From 2.4.11, mod_auth_openidc ignores X-Forwarded headers unless explicitly configured 42 | _keystone_sp_apache_mod_auth_openidc_gte_2_4_11: true 43 | 44 | keystone_sp_apache_mod_packages: 45 | - name: shibboleth 46 | state: "{{ keystone_sp_apache_mod_shib | ternary('present', 'absent') }}" 47 | - name: mod_auth_openidc 48 | state: "{{ keystone_sp_apache_mod_auth_openidc | ternary('present', 'absent') }}" 49 | 50 | keystone_developer_mode_distro_packages: 51 | - gcc 52 | 53 | keystone_deprecated_apache_configs: 54 | - /etc/httpd/conf.d/keystone-httpd.conf 55 | 56 | keystone_uwsgi_bin: "/usr/sbin" 57 | 58 | keystone_sshd: sshd 59 | -------------------------------------------------------------------------------- /tasks/keystone_service_bootstrap.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Wait for service to be up 17 | ansible.builtin.uri: 18 | url: "{{ keystone_service_internaluri }}" 19 | method: "HEAD" 20 | status_code: 300 21 | register: _wait_check 22 | until: _wait_check is success 23 | retries: 12 24 | delay: 5 25 | 26 | - name: Bootstrap keystone admin and endpoint 27 | ansible.builtin.command: | 28 | {{ keystone_bin }}/keystone-manage bootstrap \ 29 | --bootstrap-username {{ keystone_admin_user_name }} \ 30 | --bootstrap-password {{ keystone_auth_admin_password }} \ 31 | --bootstrap-project-name {{ keystone_admin_tenant_name }} \ 32 | --bootstrap-role-name {{ keystone_role_name }} \ 33 | --bootstrap-service-name {{ keystone_service_name }} \ 34 | --bootstrap-region-id {{ keystone_service_region }} \ 35 | --bootstrap-admin-url {{ keystone_service_adminuri }} \ 36 | --bootstrap-public-url {{ keystone_service_publicuri }} \ 37 | --bootstrap-internal-url {{ keystone_service_internaluri }} 38 | no_log: true 39 | become: true 40 | become_user: "{{ keystone_system_user_name }}" 41 | changed_when: false 42 | register: add_service 43 | until: add_service is success 44 | retries: 5 45 | delay: 10 46 | -------------------------------------------------------------------------------- /bindep.txt: -------------------------------------------------------------------------------- 1 | # This file facilitates OpenStack-CI package installation 2 | # before the execution of any tests. 3 | # 4 | # See the following for details: 5 | # - https://docs.openstack.org/infra/bindep/ 6 | # - https://opendev.org/openstack-infra/bindep 7 | # 8 | # Even if the role does not make use of this facility, it 9 | # is better to have this file empty, otherwise OpenStack-CI 10 | # will fall back to installing its default packages which 11 | # will potentially be detrimental to the tests executed. 12 | # 13 | # Note: 14 | # This file is maintained in the openstack-ansible-tests repository. 15 | # https://opendev.org/openstack/openstack-ansible-tests/src/bindep.txt 16 | # If you need to remove or add extra dependencies, you should modify 17 | # the central file instead and once your change is accepted then update 18 | # this file as well. The purpose of this file is to ensure that Python and 19 | # Ansible have all their necessary binary requirements on the test host before 20 | # tox executes. Any binary requirements needed by services/roles should be 21 | # installed by those roles in their applicable package install tasks, not through 22 | # using this file. 23 | # 24 | 25 | # The gcc compiler 26 | gcc 27 | 28 | # Base requirements for Ubuntu 29 | git-core [platform:dpkg] 30 | libssl-dev [platform:dpkg] 31 | libffi-dev [platform:dpkg] 32 | python3 [platform:dpkg] 33 | python3-apt [platform:dpkg] 34 | python3-dev [platform:dpkg] 35 | 36 | # Base requirements for RPM distros 37 | gcc-c++ [platform:rpm] 38 | git [platform:rpm] 39 | libffi-devel [platform:rpm] 40 | openssl-devel [platform:rpm] 41 | python3-dnf [platform:fedora] 42 | python3-devel [platform:rpm] 43 | 44 | # For SELinux 45 | libselinux-python3 [platform:redhat] 46 | libsemanage-python3 [platform:redhat] 47 | iptables [platform:redhat] 48 | -------------------------------------------------------------------------------- /tests/ansible-role-requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: apt_package_pinning 3 | src: https://opendev.org/openstack/openstack-ansible-apt_package_pinning 4 | scm: git 5 | version: master 6 | - name: memcached_server 7 | src: https://opendev.org/openstack/openstack-ansible-memcached_server 8 | scm: git 9 | version: master 10 | - name: openstack_hosts 11 | src: https://opendev.org/openstack/openstack-ansible-openstack_hosts 12 | scm: git 13 | version: master 14 | - name: lxc_hosts 15 | src: https://opendev.org/openstack/openstack-ansible-lxc_hosts 16 | scm: git 17 | version: master 18 | - name: lxc_container_create 19 | src: https://opendev.org/openstack/openstack-ansible-lxc_container_create 20 | scm: git 21 | version: master 22 | - name: galera_client 23 | src: https://opendev.org/openstack/openstack-ansible-galera_client 24 | scm: git 25 | version: master 26 | - name: galera_server 27 | src: https://opendev.org/openstack/openstack-ansible-galera_server 28 | scm: git 29 | version: master 30 | - name: haproxy_server 31 | src: https://opendev.org/openstack/openstack-ansible-haproxy_server 32 | scm: git 33 | version: master 34 | - name: rabbitmq_server 35 | src: https://opendev.org/openstack/openstack-ansible-rabbitmq_server 36 | scm: git 37 | version: master 38 | - name: openstack_openrc 39 | src: https://opendev.org/openstack/openstack-ansible-openstack_openrc 40 | scm: git 41 | version: master 42 | - name: os_tempest 43 | src: https://opendev.org/openstack/openstack-ansible-os_tempest 44 | scm: git 45 | version: master 46 | - name: python_venv_build 47 | src: https://opendev.org/openstack/ansible-role-python_venv_build 48 | scm: git 49 | version: master 50 | - name: systemd_service 51 | src: https://opendev.org/openstack/ansible-role-systemd_service 52 | scm: git 53 | version: master 54 | - name: pki 55 | src: https://opendev.org/openstack/ansible-role-pki 56 | scm: git 57 | version: master 58 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Keystone role for OpenStack-Ansible 3 | =================================== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | configure-keystone.rst 9 | configure-federation.rst 10 | configure-federation-wrapper.rst 11 | configure-federation-sp.rst 12 | configure-federation-idp.rst 13 | configure-federation-mapping.rst 14 | 15 | To clone or view the source code for this repository, visit the role repository 16 | for `os_keystone `_. 17 | 18 | Default variables 19 | ~~~~~~~~~~~~~~~~~ 20 | 21 | .. literalinclude:: ../../defaults/main.yml 22 | :language: yaml 23 | :start-after: under the License. 24 | 25 | 26 | Dependencies 27 | ~~~~~~~~~~~~ 28 | 29 | This role needs pip >= 7.1 installed on the target host. 30 | 31 | To use this role, define the following variables: 32 | 33 | .. code-block:: yaml 34 | 35 | # hostname or IP of load balancer providing external network 36 | # access to Keystone 37 | external_lb_vip_address: 10.100.100.102 38 | 39 | # hostname or IP of load balancer providing internal network 40 | # access to Keystone 41 | internal_lb_vip_address: 10.100.100.102 42 | 43 | # password used by the keystone service to interact with Galera 44 | keystone_container_mysql_password: "YourPassword" 45 | 46 | keystone_auth_admin_password: "SuperSecretePassword" 47 | keystone_rabbitmq_password: "secrete" 48 | keystone_container_mysql_password: "SuperSecrete" 49 | 50 | This list is not exhaustive at present. See role internals for further 51 | details. 52 | 53 | Example playbook 54 | ~~~~~~~~~~~~~~~~ 55 | 56 | .. literalinclude:: ../../examples/playbook.yml 57 | :language: yaml 58 | 59 | Tags 60 | ~~~~ 61 | 62 | This role supports two tags: ``keystone-install`` and ``keystone-config`` 63 | 64 | The ``keystone-install`` tag can be used to install and upgrade. 65 | 66 | The ``keystone-config`` tag can be used to maintain configuration of the 67 | service. 68 | -------------------------------------------------------------------------------- /tasks/keystone_ldap_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Add LDAP domains 17 | openstack.cloud.identity_domain: 18 | cloud: default 19 | state: present 20 | name: "{{ item.key }}" 21 | endpoint_type: admin 22 | verify: "{{ not keystone_service_adminuri_insecure }}" 23 | register: add_ldap_domain 24 | until: add_ldap_domain is success 25 | retries: 5 26 | delay: 10 27 | with_dict: "{{ keystone_ldap }}" 28 | delegate_to: "{{ keystone_service_setup_host }}" 29 | no_log: true 30 | when: 31 | - "_keystone_is_last_play_host" 32 | vars: 33 | ansible_python_interpreter: "{{ keystone_service_setup_host_python_interpreter }}" 34 | 35 | - name: Create Keystone LDAP domain configs 36 | ansible.builtin.template: 37 | src: keystone.domain.conf.j2 38 | dest: "{{ keystone_ldap_domain_config_dir }}/keystone.{{ item.key }}.conf" 39 | owner: "root" 40 | group: "{{ keystone_system_group_name }}" 41 | mode: "0640" 42 | with_dict: "{{ keystone_ldap }}" 43 | no_log: true 44 | notify: 45 | - Restart uWSGI 46 | 47 | # Bug 1547542 - Older versions of the keystone role would deploy a blank 48 | # keystone.Default.conf and this will cause errors when adding LDAP-backed 49 | # domains. 50 | - name: Remove Keystone Default domain configuration file if not needed 51 | ansible.builtin.file: 52 | path: "{{ keystone_ldap_domain_config_dir }}/keystone.Default.conf" 53 | state: absent 54 | when: keystone_ldap.Default is not defined 55 | notify: 56 | - Restart uWSGI 57 | -------------------------------------------------------------------------------- /tasks/keystone_fernet_keys_autorotate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # This script is being created with mode 0755 intentionally. This is so that the 17 | # script can be executed by root to rotate the keys as needed. The script being 18 | # executed will always change it's user context to the keystone user before 19 | # execution and while the script may be world read/executable its contains only 20 | # the necessary bits that are required to run the rotate and sync commands. 21 | - name: Drop fernet key auto rotate script 22 | ansible.builtin.template: 23 | src: "keystone-fernet-rotate.sh.j2" 24 | dest: "{{ keystone_fernet_auto_rotation_script }}" 25 | owner: "{{ keystone_system_user_name }}" 26 | group: "{{ keystone_system_group_name }}" 27 | mode: "0755" 28 | 29 | # This creates the auto rotation job on the first keystone host. 30 | - name: Create auto rotation job 31 | ansible.builtin.cron: 32 | name: "Fernet auto rotate job" 33 | special_time: "{{ keystone_fernet_rotation }}" 34 | user: "{{ keystone_system_user_name }}" 35 | job: "{{ keystone_fernet_auto_rotation_script }}" 36 | cron_file: keystone-fernet-rotate 37 | when: _keystone_is_first_play_host 38 | 39 | # This makes sure that no auto rotation jobs are on any other hosts. 40 | - name: Remove extra auto rotation job 41 | ansible.builtin.cron: 42 | name: "Fernet auto rotate job" 43 | user: "{{ keystone_system_user_name }}" 44 | cron_file: keystone-fernet-rotate 45 | state: "absent" 46 | when: not _keystone_is_first_play_host 47 | -------------------------------------------------------------------------------- /tasks/keystone_credential_autorotate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # This script is being created with mode 0755 intentionally. This is so that the 17 | # script can be executed by root to rotate the keys as needed. The script being 18 | # executed will always change it's user context to the keystone user before 19 | # execution and while the script may be world read/executable its contains only 20 | # the necessary bits that are required to run the rotate and sync commands. 21 | - name: Drop credential key auto rotate script 22 | ansible.builtin.template: 23 | src: "keystone-credential-rotate.sh.j2" 24 | dest: "{{ keystone_credential_auto_rotation_script }}" 25 | owner: "{{ keystone_system_user_name }}" 26 | group: "{{ keystone_system_group_name }}" 27 | mode: "0755" 28 | 29 | # This creates the auto rotation job on the first keystone host. 30 | - name: Create auto rotation job 31 | ansible.builtin.cron: 32 | name: "Credential auto rotate job" 33 | special_time: "{{ keystone_credential_rotation }}" 34 | user: "{{ keystone_system_user_name }}" 35 | job: "{{ keystone_credential_auto_rotation_script }}" 36 | cron_file: keystone-credential-rotate 37 | when: _keystone_is_first_play_host 38 | 39 | # This makes sure that no auto rotation jobs are on any other hosts. 40 | - name: Remove extra auto rotation job 41 | ansible.builtin.cron: 42 | name: "Credential auto rotate job" 43 | user: "{{ keystone_system_user_name }}" 44 | cron_file: keystone-credential-rotate 45 | state: "absent" 46 | when: not _keystone_is_first_play_host 47 | -------------------------------------------------------------------------------- /tests/os_keystone-overrides.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016 Internet Solutions (Pty) Ltd 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # (c) 2016 Donovan Francesco 17 | # (c) 2016 Paul Stevens 18 | 19 | tempest_run: yes 20 | 21 | tempest_plugins: 22 | - name: keystone-tempest-plugin 23 | repo: https://opendev.org/openstack/keystone-tempest-plugin 24 | branch: master 25 | 26 | tempest_test_whitelist: 27 | - keystone_tempest_plugin.tests.api.identity* 28 | 29 | external_lb_vip_address: 10.1.0.1 30 | internal_lb_vip_address: 10.1.0.1 31 | test_keystone_host: "{{ external_lb_vip_address }}" 32 | 33 | # For upgrades we need haproxy variables 34 | haproxy_default_services: 35 | - service: 36 | haproxy_service_name: galera 37 | haproxy_backend_nodes: "{{ [groups['galera_all'][0]] | default([]) }}" # list expected 38 | haproxy_backup_nodes: "{{ groups['galera_all'][1:] | default([]) }}" 39 | haproxy_port: 3306 40 | haproxy_balance_type: tcp 41 | haproxy_timeout_client: 5000s 42 | haproxy_timeout_server: 5000s 43 | haproxy_backend_options: 44 | - "mysql-check user {{ galera_monitoring_user }}" 45 | haproxy_whitelist_networks: 46 | - 192.168.0.0/16 47 | - 172.16.0.0/12 48 | - 10.0.0.0/8 49 | - service: 50 | haproxy_service_name: keystone_service 51 | haproxy_backend_nodes: "{{ groups['keystone_all'] | default([]) }}" 52 | haproxy_port: 5000 53 | haproxy_ssl: "{{ haproxy_ssl }}" 54 | haproxy_balance_type: "http" 55 | haproxy_backend_options: 56 | - "httpchk HEAD /" 57 | 58 | ssl_cipher_suite_tls12: "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS" 59 | ssl_cipher_suite_tls13: "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" 60 | haproxy_ssl: false 61 | -------------------------------------------------------------------------------- /vars/debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | cache_timeout: 600 17 | 18 | keystone_distro_packages: 19 | - git 20 | - libldap-common 21 | - openssh-server 22 | - rsync 23 | - cron 24 | - libpython3-dev 25 | 26 | keystone_devel_distro_packages: 27 | - docutils-common 28 | - libffi-dev 29 | - libjs-sphinxdoc 30 | - libjs-underscore 31 | - libldap2-dev 32 | - libsasl2-dev 33 | - libsystemd-dev 34 | - libssl-dev 35 | - libxslt1.1 36 | - libxslt1-dev 37 | - libxml2-dev 38 | - pkg-config 39 | 40 | keystone_service_distro_packages: 41 | - python3-keystone 42 | - python3-systemd 43 | 44 | keystone_idp_distro_packages: 45 | - shibboleth-sp-utils 46 | - ssl-cert 47 | - xmlsec1 48 | 49 | # From 2.4.11, mod_auth_openidc ignores X-Forwarded headers unless explicitly configured 50 | _keystone_sp_apache_mod_auth_openidc_gte_2_4_11: true 51 | 52 | keystone_sp_apache_mod_packages: 53 | - name: libapache2-mod-shib 54 | state: "{{ keystone_sp_apache_mod_shib | ternary('present', 'absent') }}" 55 | - name: libapache2-mod-auth-openidc 56 | state: "{{ keystone_sp_apache_mod_auth_openidc | ternary('present', 'absent') }}" 57 | 58 | keystone_developer_mode_distro_packages: 59 | - build-essential 60 | 61 | keystone_deprecated_apache_configs: 62 | - /etc/apache2/sites-available/keystone-httpd.conf 63 | - /etc/apache2/sites-enabled/keystone-httpd.conf 64 | 65 | keystone_apache_modules: 66 | - name: "shib" 67 | state: "{{ keystone_sp_apache_mod_shib | ternary('present', 'absent') }}" 68 | - name: "auth_openidc" 69 | state: "{{ keystone_sp_apache_mod_auth_openidc | ternary('present', 'absent') }}" 70 | - name: "proxy_uwsgi" 71 | state: "present" 72 | # This can be enabled when Apache2.5+ is available 73 | # - name: "mod_journald" 74 | # state: "present 75 | 76 | keystone_uwsgi_bin: "/usr/bin" 77 | 78 | keystone_sshd: ssh 79 | -------------------------------------------------------------------------------- /tests/test-keystone-functional.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Test for expected user/project consistency 17 | hosts: localhost 18 | connection: local 19 | vars: 20 | ansible_python_interpreter: "{{ ansible_playbook_python }}" 21 | tasks: 22 | - name: Check for expected users 23 | os_user_facts: 24 | cloud: default 25 | name: "{{ item }}" 26 | domain: default 27 | endpoint_type: admin 28 | with_items: 29 | - "admin" 30 | - "keystone" 31 | register: _user_check 32 | until: _user_check is success 33 | retries: 5 34 | delay: 10 35 | 36 | - name: Check for expected projects 37 | os_project_facts: 38 | cloud: default 39 | name: "{{ item }}" 40 | domain: default 41 | endpoint_type: admin 42 | with_items: 43 | - "admin" 44 | - "service" 45 | register: _project_check 46 | until: _project_check is success 47 | retries: 5 48 | delay: 10 49 | 50 | - name: Test for SSL key/cert consistency 51 | hosts: keystone_all 52 | user: root 53 | gather_facts: false 54 | vars_files: 55 | - common/test-vars.yml 56 | tasks: 57 | - name: Get SSL cert location and permissions 58 | stat: 59 | path: "/etc/ssl/certs/keystone.pem" 60 | register: keystone_ssl_cert_stats 61 | 62 | - name: Check SSL cert location and permissions 63 | fail: 64 | msg: "Keystone SSL cert permissions don't match 0640" 65 | when: keystone_ssl_cert_stats.stat.mode != "0640" 66 | 67 | - name: Get SSL key location and permissions 68 | stat: 69 | path: "/etc/ssl/private/keystone.key" 70 | register: keystone_ssl_key_stats 71 | 72 | - name: Check SSL key location and permissions 73 | fail: 74 | msg: "Keystone SSL key permissions don't match 0640" 75 | when: keystone_ssl_key_stats.stat.mode != "0640" 76 | -------------------------------------------------------------------------------- /templates/keystone-fernet-rotate.sh.j2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # {{ ansible_managed }} 17 | 18 | # This script is being created with mode 0755 intentionally. This is so that the 19 | # script can be executed by root to rotate the keys as needed. The script being 20 | # executed will always change it's user context to the keystone user before 21 | # execution and while the script may be world read/executable its contains only 22 | # the necessary bits that are required to run the rotate and sync commands. 23 | 24 | function autorotate { 25 | # Rotate the keys 26 | {{ keystone_bin }}/keystone-manage fernet_rotate \ 27 | --keystone-user "{{ keystone_system_user_name }}" \ 28 | --keystone-group "{{ keystone_system_group_name }}" 29 | {% for host in groups['keystone_all'] %} 30 | 31 | {% if inventory_hostname != host %} 32 | {% if 'ansible_host' in hostvars[host] %} 33 | {% set destination_host = hostvars[host]['ansible_host'] %} 34 | {% else %} 35 | {% set destination_host = inventory_hostname %} 36 | {% endif %} 37 | 38 | # Fernet sync job to "{{ host }}" 39 | scp -o UserKnownHostsFile=/dev/null \ 40 | -o StrictHostKeyChecking=no \ 41 | $(ls -dtr {{ keystone_fernet_tokens_key_repository }}/* | sort -Vr) \ 42 | {{ keystone_system_user_name }}@{{ destination_host }}:{{ keystone_fernet_tokens_key_repository }}/ 43 | 44 | rsync -e 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \ 45 | -avz \ 46 | --delete \ 47 | {{ keystone_fernet_tokens_key_repository }}/ \ 48 | {{ keystone_system_user_name }}@{{ destination_host }}:{{ keystone_fernet_tokens_key_repository }}/ 49 | 50 | {%- endif %} 51 | 52 | {%- endfor %} 53 | 54 | } 55 | 56 | if [ "$(id -u)" == "0" ];then 57 | # Change the script context to always execute as the "{{ keystone_system_user_name }}" user. 58 | su - "{{ keystone_system_user_name }}" -s "/bin/bash" -c bash << EOC 59 | {{ keystone_fernet_auto_rotation_script }} 60 | EOC 61 | elif [ "$(whoami)" == "{{ keystone_system_user_name }}" ];then 62 | logger $(autorotate) 63 | else 64 | echo "Failed - you do not have permission to rotate, or you've executed the job as the wrong user." 65 | exit 99 66 | fi 67 | -------------------------------------------------------------------------------- /templates/shibboleth-attribute-map.xml.j2: -------------------------------------------------------------------------------- 1 | 3 | 4 | 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 | 51 | {% for idp in keystone_sp.trusted_idp_list %} 52 | {% if idp.protocols is defined %} 53 | {% for protocol in idp.protocols %} 54 | {% if protocol.name == "saml2" and protocol.attributes is defined %} 55 | {% for attr in protocol.attributes %} 56 | 57 | {% endfor %} 58 | {% endif %} 59 | {% endfor %} 60 | {% endif %} 61 | {% endfor %} 62 | 63 | 64 | -------------------------------------------------------------------------------- /doc/source/configure-federation-wrapper.rst: -------------------------------------------------------------------------------- 1 | =========================================== 2 | Configuring keystone-to-keystone federation 3 | =========================================== 4 | 5 | In keystone-to-keystone federation (k2k), the IdP and SP 6 | keystone instances exchange information securely to enable a user on 7 | the IdP cloud to access resources of the SP cloud. 8 | 9 | .. important:: 10 | 11 | This section applies only to federation between keystone IdP 12 | and keystone SP. It does not apply to non-keystone IdP. 13 | 14 | The k2k authentication flow involves the following steps: 15 | 16 | #. Log in to the IdP with your credentials. 17 | #. Send a request to the IdP to generate an assertion for a given SP. 18 | #. Submit the assertion to the SP on the configured ``sp_url`` 19 | endpoint. The Shibboleth service running on the SP receives the assertion 20 | and verifies it. If it is valid, a session with the client starts and 21 | returns the session ID in a cookie. 22 | #. Connect to the SP on the configured ``auth_url`` endpoint, 23 | providing the Shibboleth cookie with the session ID. The SP responds with 24 | an unscoped token that you use to access the SP. 25 | #. You connect to the keystone service on the SP with the unscoped 26 | token, and the desired domain and project, and receive a scoped token 27 | and the service catalog. 28 | #. With your token, you can now make API requests to the endpoints in the 29 | catalog. 30 | 31 | Keystone-to-keystone federation authentication wrapper 32 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 | 34 | The following steps above involve manually sending API requests. 35 | 36 | .. note:: 37 | 38 | The infrastructure for the command line utilities that performs these steps 39 | for the user does not exist. 40 | 41 | To obtain access to a SP cloud, OpenStack-Ansible provides a script that wraps 42 | the above steps. The script is called ``federated-login.sh`` and is 43 | used as follows: 44 | 45 | .. code:: 46 | 47 | # ./scripts/federated-login.sh -p project [-d domain] sp_id 48 | 49 | * ``project`` is the project in the SP cloud that you want to access. 50 | * ``domain`` is the domain in which the project lives (the default domain is 51 | used if this argument is not given). 52 | * ``sp_id`` is the unique ID of the SP. This is given in the IdP configuration. 53 | 54 | The script outputs the results of all the steps in the authentication flow to 55 | the console. At the end, it prints the available endpoints from the catalog 56 | and the scoped token provided by the SP. 57 | 58 | Use the endpoints and token with the openstack command line client as follows: 59 | 60 | .. code:: 61 | 62 | # openstack --os-token= --os-url= [options] 63 | 64 | Or, alternatively: 65 | 66 | .. code:: 67 | 68 | # export OS_TOKEN= 69 | # export OS_URL= 70 | # openstack [options] 71 | 72 | Ensure you select the appropriate endpoint for your operation. 73 | For example, if you want to work with servers, the ``OS_URL`` 74 | argument must be set to the compute endpoint. 75 | 76 | .. note:: 77 | 78 | At this time, the OpenStack client is unable to find endpoints in 79 | the service catalog when using a federated login. 80 | -------------------------------------------------------------------------------- /tasks/keystone_fernet_keys_create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Check if fernet keys already exist 17 | ansible.builtin.stat: 18 | path: "{{ keystone_fernet_tokens_key_repository }}/0" 19 | register: _fernet_keys 20 | 21 | - name: Check for fernet keys on all Keystone containers 22 | ansible.builtin.find: 23 | paths: "{{ keystone_fernet_tokens_key_repository }}" 24 | when: not _fernet_keys.stat.exists 25 | register: _fernet_key_list 26 | delegate_to: "{{ item }}" 27 | with_items: "{{ groups['keystone_all'] }}" 28 | 29 | - name: Identify hosts with existing fernet keys 30 | ansible.builtin.set_fact: 31 | existing_fernet_hosts: >- 32 | {% set _var = [] -%} 33 | {% for result in _fernet_key_list.results -%} 34 | {% if result.files is defined and (result.files | length) > 0 -%} 35 | {% if _var.append(result.item) -%}{% endif -%} 36 | {% endif -%} 37 | {% endfor -%} 38 | {{ _var }} 39 | when: not _fernet_key_list is skipped 40 | 41 | - name: Copy the fernet key repository to the primary 42 | ansible.builtin.command: > 43 | rsync -e 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' 44 | -avz 45 | --delete 46 | {{ keystone_system_user_name }}@{{ existing_fernet_hosts[0] }}:{{ keystone_fernet_tokens_key_repository }}/ 47 | {{ keystone_fernet_tokens_key_repository }}/ 48 | become: true 49 | become_user: "{{ keystone_system_user_name }}" 50 | changed_when: false 51 | register: _fernet_keys_shared 52 | when: 53 | - existing_fernet_hosts is defined 54 | - (existing_fernet_hosts | length) > 0 55 | tags: 56 | - skip_ansible_lint 57 | 58 | - name: Create fernet keys for Keystone # noqa: no-changed-when 59 | ansible.builtin.command: > 60 | {{ keystone_bin }}/keystone-manage fernet_setup 61 | --keystone-user "{{ keystone_system_user_name }}" 62 | --keystone-group "{{ keystone_system_group_name }}" 63 | become: true 64 | become_user: "{{ keystone_system_user_name }}" 65 | when: 66 | - not _fernet_keys.stat.exists 67 | - _fernet_keys_shared is skipped 68 | 69 | - name: Rotate fernet keys for Keystone # noqa: no-changed-when 70 | ansible.builtin.command: > 71 | {{ keystone_bin }}/keystone-manage fernet_rotate 72 | --keystone-user "{{ keystone_system_user_name }}" 73 | --keystone-group "{{ keystone_system_group_name }}" 74 | become: true 75 | become_user: "{{ keystone_system_user_name }}" 76 | when: _fernet_keys.stat.exists 77 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # NOTE(noonedeadpunk): Handler with the same name is triggered from the http role 17 | - name: Restart web server 18 | ansible.builtin.meta: noop 19 | when: false 20 | 21 | - name: Stop uWSGI 22 | ansible.builtin.service: 23 | name: "{{ item }}" 24 | state: "stopped" 25 | daemon_reload: "{{ (ansible_facts['service_mgr'] == 'systemd') | ternary('yes', omit) }}" 26 | register: _stop 27 | until: _stop is success 28 | retries: 5 29 | delay: 2 30 | with_items: "{{ keystone_services.keys() | list }}" 31 | listen: 32 | - "venv changed" 33 | - "Restart uWSGI" 34 | 35 | - name: Start uWSGI 36 | ansible.builtin.service: 37 | name: "{{ item }}" 38 | enabled: true 39 | state: "started" 40 | daemon_reload: "{{ (ansible_facts['service_mgr'] == 'systemd') | ternary('yes', omit) }}" 41 | register: _start 42 | until: _start is success 43 | retries: 5 44 | delay: 2 45 | with_items: "{{ keystone_services.keys() | list }}" 46 | listen: 47 | - "venv changed" 48 | - "Restart uWSGI" 49 | 50 | - name: Wait for uWSGI socket to be ready 51 | ansible.builtin.wait_for: 52 | host: "{{ (keystone_use_uwsgi | bool) | ternary(keystone_uwsgi_bind_address, '127.0.0.1') }}" 53 | port: "{{ (keystone_use_uwsgi | bool) | ternary(keystone_service_port, keystone_uwsgi_ports['keystone-wsgi-public']['socket']) }}" 54 | timeout: 25 55 | delay: 10 56 | register: _wait_check 57 | until: _wait_check is success 58 | retries: 5 59 | listen: 60 | - "venv changed" 61 | - "Restart uWSGI" 62 | - "Start uWSGI" 63 | 64 | - name: Restart Shibd 65 | ansible.builtin.service: 66 | name: "shibd" 67 | enabled: true 68 | state: "restarted" 69 | daemon_reload: "{{ (ansible_facts['service_mgr'] == 'systemd') | ternary('yes', omit) }}" 70 | register: _restart 71 | until: _restart is success 72 | retries: 5 73 | delay: 2 74 | 75 | - name: Restart ssh 76 | ansible.builtin.service: 77 | name: "{{ keystone_sshd }}" 78 | state: "restarted" 79 | 80 | - name: Flush all of the cache in memcached 81 | vars: 82 | nc_command: 83 | debian: nc -q 1 $(awk '/^\-l/ {print $2}' "/etc/memcached.conf" | awk -F, '{print $1}') $(awk '/^\-p/ {print $2}' "/etc/memcached.conf") 84 | redhat: nc $(awk -F '-l' '/^OPTIONS/ {print $2}' "/etc/sysconfig/memcached" | awk -F ',' '{gsub(/"/, "", $1); print $1}' | awk -F '-' '{print $1}') 11211 85 | ansible.builtin.shell: "echo 'flush_all' | {{ nc_command.get(ansible_facts['os_family'] | lower) }}" 86 | changed_when: false 87 | delegate_to: "{{ item }}" 88 | with_items: "{{ groups.memcached_all }}" 89 | listen: flush cache 90 | when: 91 | - keystone_flush_memcache | bool 92 | -------------------------------------------------------------------------------- /templates/keystone-credential-rotate.sh.j2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # {{ ansible_managed }} 17 | 18 | # This script is being created with mode 0755 intentionally. This is so that the 19 | # script can be executed by root to rotate the keys as needed. The script being 20 | # executed will always change it's user context to the keystone user before 21 | # execution and while the script may be world read/executable its contains only 22 | # the necessary bits that are required to run the rotate and sync commands. 23 | 24 | function autorotate { 25 | # Ensure all credentials are encrypted with the newest primary key so the rotation doesn't fail. 26 | {{ keystone_bin }}/keystone-manage credential_migrate \ 27 | --keystone-user "{{ keystone_system_user_name }}" \ 28 | --keystone-group "{{ keystone_system_group_name }}" 29 | 30 | # Rotate the keys 31 | {{ keystone_bin }}/keystone-manage credential_rotate \ 32 | --keystone-user "{{ keystone_system_user_name }}" \ 33 | --keystone-group "{{ keystone_system_group_name }}" 34 | 35 | # Ensure all credentials are encrypted with the new primary key 36 | {{ keystone_bin }}/keystone-manage credential_migrate \ 37 | --keystone-user "{{ keystone_system_user_name }}" \ 38 | --keystone-group "{{ keystone_system_group_name }}" 39 | 40 | {% for host in groups['keystone_all'] %} 41 | 42 | {% if inventory_hostname != host %} 43 | {% if 'ansible_host' in hostvars[host] %} 44 | {% set destination_host = hostvars[host]['ansible_host'] %} 45 | {% else %} 46 | {% set destination_host = inventory_hostname %} 47 | {% endif %} 48 | # Fernet sync job to "{{ host }}" 49 | rsync -e 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \ 50 | -avz \ 51 | --delete \ 52 | {{ keystone_credential_key_repository }}/ \ 53 | {{ keystone_system_user_name }}@{{ destination_host }}:{{ keystone_credential_key_repository }}/ 54 | 55 | {%- endif %} 56 | 57 | {%- endfor %} 58 | 59 | } 60 | 61 | if [ "$(id -u)" == "0" ];then 62 | # Change the script context to always execute as the "{{ keystone_system_user_name }}" user. 63 | su - "{{ keystone_system_user_name }}" -s "/bin/bash" -c bash << EOC 64 | {{ keystone_credential_auto_rotation_script }} 65 | EOC 66 | elif [ "$(whoami)" == "{{ keystone_system_user_name }}" ];then 67 | logger $(autorotate) 68 | else 69 | echo "Failed - you do not have permission to rotate, or you've executed the job as the wrong user." 70 | exit 99 71 | fi 72 | -------------------------------------------------------------------------------- /tasks/keystone_db_sync.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Check current state of Keystone DB 17 | ansible.builtin.command: "{{ keystone_bin }}/keystone-manage db_sync --check" 18 | become: true 19 | become_user: "{{ keystone_system_user_name }}" 20 | register: keystone_db_sync_check 21 | failed_when: "keystone_db_sync_check.rc == 1" 22 | changed_when: "keystone_db_sync_check.rc not in [2, 3, 4]" 23 | run_once: true 24 | 25 | - name: Set the db sync local facts 26 | community.general.ini_file: 27 | dest: "/etc/ansible/facts.d/openstack_ansible.fact" 28 | section: keystone 29 | option: "{{ item.name }}" 30 | value: "{{ item.state }}" 31 | mode: "0644" 32 | with_items: 33 | - name: "need_db_expand" 34 | state: "{{ (keystone_db_sync_check.rc | int == 2) | bool }}" 35 | - name: "need_db_contract" 36 | state: "{{ (keystone_db_sync_check.rc | int in [2, 3, 4]) | bool }}" 37 | 38 | - name: Refresh local facts 39 | ansible.builtin.setup: 40 | filter: ansible_local 41 | gather_subset: "!all" 42 | tags: 43 | - keystone-config 44 | 45 | # When keystone is initially built, the service does not yet exist on the 46 | # host this task is executed on. Detect the presence of the services. 47 | - name: Test if keystone service exists 48 | ansible.builtin.service: # noqa: args[module] 49 | name: "{{ item }}" 50 | check_mode: true 51 | register: keystone_service_exists 52 | with_items: "{{ keystone_services.keys() | list }}" 53 | 54 | - name: Ensure keystone service is stopped 55 | ansible.builtin.service: 56 | name: "{{ item.name }}" 57 | state: stopped 58 | register: _stop 59 | until: _stop is success 60 | retries: 5 61 | delay: 2 62 | with_items: "{{ keystone_service_exists.results }}" 63 | when: 64 | - "(ansible_local['openstack_ansible']['keystone']['need_db_expand'] | bool)" 65 | - "(item.status['LoadState'] == 'loaded' | bool)" 66 | notify: 67 | - Restart uWSGI 68 | 69 | - name: Perform a Keystone DB sync expand 70 | ansible.builtin.command: "{{ keystone_bin }}/keystone-manage db_sync --expand" 71 | changed_when: false 72 | become: true 73 | become_user: "{{ keystone_system_user_name }}" 74 | when: 75 | - "ansible_local['openstack_ansible']['keystone']['need_db_expand'] | bool" 76 | run_once: true 77 | notify: flush cache 78 | 79 | - name: Perform a Keystone DB sync contract 80 | ansible.builtin.command: "{{ keystone_bin }}/keystone-manage db_sync --contract" 81 | changed_when: false 82 | become: true 83 | become_user: "{{ keystone_system_user_name }}" 84 | when: 85 | - "(keystone_all_software_updated | default('no')) | bool" 86 | - "ansible_local['openstack_ansible']['keystone']['need_db_contract'] | bool" 87 | run_once: true 88 | notify: flush cache 89 | -------------------------------------------------------------------------------- /tasks/keystone_apache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Clean-up old vhost files 17 | ansible.builtin.file: 18 | path: "{{ item }}" 19 | state: absent 20 | loop: "{{ keystone_deprecated_apache_configs }}" 21 | 22 | - name: Including HTTPD role 23 | ansible.builtin.import_role: 24 | name: httpd 25 | vars: 26 | httpd_pki_dir: "{{ keystone_pki_dir }}" 27 | httpd_pki_setup_host: "{{ keystone_pki_setup_host }}" 28 | httpd_ssl_protocol: "{{ keystone_ssl_protocol }}" 29 | httpd_ssl_cipher_suite_tls12: "{{ keystone_ssl_cipher_suite_tls12 }}" 30 | httpd_ssl_cipher_suite_tls13: "{{ keystone_ssl_cipher_suite_tls13 }}" 31 | httpd_pki_regen_cert: "{{ keystone_pki_regen_cert }}" 32 | httpd_extra_packages: "{{ keystone_sp_apache_mod_packages | selectattr('state', 'eq', 'present') | map(attribute='name') }}" 33 | httpd_extra_modules: "{{ keystone_apache_modules }}" 34 | httpd_vhosts: 35 | - name: openstack_keystone 36 | address: "{{ keystone_web_server_bind_address }}" 37 | port: "{{ keystone_service_port }}" 38 | log_level: "{{ keystone_apache_log_level }}" 39 | log_format: "{{ keystone_apache_custom_log_format }}" 40 | server_name: "{{ ansible_facts['hostname'] }}" 41 | headers: 42 | - 'Header set X-Content-Type-Options "nosniff"' 43 | - 'Header set X-XSS-Protection "1; mode=block"' 44 | - >- 45 | Header set Content-Security-Policy "default-src 'self' https: wss:;" 46 | - >- 47 | {% set scp_script_src = "script-src 'sha256-oBahlBFQem+nMs1JwgcBB03Hy8nRh5e8qEGTOcxmAuM=';" -%} 48 | {{ (keystone_sp != {}) | ternary('Header set Content-Security-Policy "' ~ scp_script_src ~ '"', '') }} 49 | - "Header set X-Frame-Options {{ keystone_x_frame_options | default('DENY') }}" 50 | options: |- 51 | {% set options = _keystone_httpd_base_options %} 52 | {% if keystone_sp_apache_mod_auth_openidc %} 53 | {% set _ = options.extend(_keystone_httpd_openidc_options) %} 54 | {% endif %} 55 | {% if keystone_sp_apache_mod_shib %} 56 | {% set _ = options.extend(_keystone_httpd_shib_options) %} 57 | {% endif %} 58 | {% set _ = options.append('ProxyPass / uwsgi://127.0.0.1:' ~ keystone_uwsgi_ports['keystone-wsgi-public']['socket'] ~ '/') %} 59 | {{ options }} 60 | locations: |- 61 | {% set locations = [] %} 62 | {% if keystone_sp_apache_mod_auth_openidc %} 63 | {% set _ = locations.extend(_keystone_httpd_openidc_locations) %} 64 | {% endif %} 65 | {% if keystone_sp_apache_mod_shib %} 66 | {% set _ = locations.extend(_keystone_httpd_shib_locations) %} 67 | {% endif %} 68 | {{ locations }} 69 | directories: "{{ (keystone_sp != {}) | ternary(_keystone_httpd_sp_directories, []) }}" 70 | ssl: "{{ keystone_backend_ssl | ternary(_keystone_httpd_vhost_ssl, false) }}" 71 | tags: 72 | - horizon-install 73 | - horizon-config 74 | - httpd 75 | -------------------------------------------------------------------------------- /tasks/keystone_post_install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # If SSH is not running on all nodes immediately, then 17 | # the key rotation script will not be able to copy the 18 | # keys to the other nodes when they rotate. 19 | - name: Enable SSHD on all keystone hosts 20 | ansible.builtin.systemd: 21 | name: "{{ keystone_sshd }}" 22 | state: started 23 | enabled: true 24 | masked: false 25 | daemon_reload: true 26 | delegate_to: "{{ item }}" 27 | with_items: "{{ ansible_play_hosts }}" 28 | when: _keystone_is_first_play_host 29 | 30 | - name: Copy keystone configuration files 31 | openstack.config_template.config_template: 32 | src: "keystone.conf.j2" 33 | dest: "/etc/keystone/keystone.conf" 34 | owner: "root" 35 | group: "{{ keystone_system_group_name }}" 36 | mode: "0640" 37 | config_overrides: "{{ keystone_keystone_conf_overrides }}" 38 | config_type: "ini" 39 | notify: 40 | - Restart uWSGI 41 | 42 | - name: Place policy.yaml file 43 | openstack.config_template.config_template: 44 | content: "{{ keystone_policy_overrides }}" 45 | dest: "/etc/keystone/policy.yaml" 46 | owner: "root" 47 | group: "{{ keystone_system_group_name }}" 48 | mode: "0640" 49 | config_type: yaml 50 | tags: 51 | - keystone-policy-override 52 | 53 | # NOTE(cloudnull): This is using "cp" instead of copy with a remote_source 54 | # because we only want to copy the original files once. and we 55 | # don't want to need multiple tasks. 56 | - name: Preserve original configuration file(s) 57 | ansible.builtin.command: "cp {{ item.target_f }} {{ item.target_f }}.original" 58 | args: 59 | creates: "{{ item.target_f }}.original" 60 | with_items: "{{ keystone_core_files }}" 61 | 62 | - name: Fetch override files 63 | ansible.builtin.fetch: 64 | src: "{{ item.target_f }}" 65 | dest: "{{ item.tmp_f }}" 66 | flat: true 67 | changed_when: false 68 | run_once: true 69 | with_items: "{{ keystone_core_files }}" 70 | 71 | - name: Copy common config 72 | openstack.config_template.config_template: 73 | src: "{{ item.tmp_f }}" 74 | dest: "{{ item.target_f }}" 75 | owner: "root" 76 | group: "{{ item.group | default(keystone_system_group_name) }}" 77 | mode: "0640" 78 | config_overrides: "{{ item.config_overrides }}" 79 | config_type: "{{ item.config_type }}" 80 | with_items: "{{ keystone_core_files }}" 81 | notify: 82 | - Restart uWSGI 83 | 84 | - name: Cleanup fetched temp files 85 | ansible.builtin.file: 86 | path: "{{ item.tmp_f }}" 87 | state: absent 88 | changed_when: false 89 | delegate_to: localhost 90 | run_once: true 91 | with_items: "{{ keystone_core_files }}" 92 | 93 | - name: Copy sso callback file 94 | ansible.builtin.copy: 95 | src: "{{ keystone_sso_callback_file_path }}" 96 | dest: "/etc/keystone/sso_callback_template.html" 97 | mode: "0644" 98 | when: 99 | - keystone_sso_callback_file_path is defined 100 | notify: 101 | - Restart uWSGI 102 | - Restart web server 103 | -------------------------------------------------------------------------------- /tasks/keystone_federation_sp_shib_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2015, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Drop Shibboleth Config 17 | ansible.builtin.template: 18 | src: "{{ item.src }}" 19 | dest: "{{ item.dest }}" 20 | owner: "{{ keystone_system_user_name }}" 21 | group: "{{ keystone_system_group_name }}" 22 | mode: "{{ item.mode | default('0644') }}" 23 | with_items: 24 | - { src: "shibboleth-attribute-map.xml.j2", dest: "/etc/shibboleth/attribute-map.xml" } 25 | - { src: "shibboleth2.xml.j2", dest: "/etc/shibboleth/shibboleth2.xml" } 26 | notify: 27 | - Restart Shibd 28 | 29 | - name: Copy Shibboleth SP key-pair (if provided) 30 | ansible.builtin.copy: 31 | content: "{{ item.content }}" 32 | dest: "{{ item.dest }}" 33 | mode: "{{ item.mode | default('0640') }}" 34 | when: 35 | - _keystone_is_first_play_host 36 | - item.content | length > 0 37 | with_items: 38 | - { content: "{{ shibboleth_cert_user_content }}", dest: "/etc/shibboleth/sp-cert.pem" } 39 | - { content: "{{ shibboleth_key_user_content }}", dest: "/etc/shibboleth/sp-key.pem" } 40 | notify: 41 | - Restart web server 42 | - Restart Shibd 43 | 44 | - name: Generate the Shibboleth SP key-pair 45 | ansible.builtin.command: "shib-keygen -h {{ external_lb_vip_address }} -y {{ keystone_sp.cert_duration_years }}" 46 | args: 47 | creates: "/etc/shibboleth/sp-cert.pem" 48 | when: _keystone_is_first_play_host 49 | notify: 50 | - Restart web server 51 | - Restart Shibd 52 | 53 | - name: Store sp cert 54 | ansible.builtin.slurp: 55 | src: "/etc/shibboleth/sp-cert.pem" 56 | register: _keystone_sp_cert 57 | changed_when: false 58 | when: _keystone_is_first_play_host 59 | 60 | - name: Store sp key 61 | ansible.builtin.slurp: 62 | src: "/etc/shibboleth/sp-key.pem" 63 | register: _keystone_sp_key 64 | changed_when: false 65 | when: _keystone_is_first_play_host 66 | 67 | - name: Register a fact for the cert and key 68 | ansible.builtin.set_fact: 69 | keystone_sp_cert_fact: "{{ _keystone_sp_cert.content }}" 70 | keystone_sp_key_fact: "{{ _keystone_sp_key.content }}" 71 | when: _keystone_is_first_play_host 72 | 73 | - name: Distribute sp key 74 | ansible.builtin.copy: 75 | dest: "/etc/shibboleth/sp-key.pem" 76 | content: "{{ hostvars[groups['keystone_all'][0]]['keystone_sp_key_fact'] | b64decode }}" 77 | owner: "{{ keystone_system_user_name }}" 78 | group: "{{ keystone_system_group_name }}" 79 | mode: "0640" 80 | when: not _keystone_is_first_play_host 81 | notify: 82 | - Restart web server 83 | - Restart Shibd 84 | 85 | - name: Distribute sp cert 86 | ansible.builtin.copy: 87 | dest: "/etc/shibboleth/sp-cert.pem" 88 | content: "{{ hostvars[groups['keystone_all'][0]]['keystone_sp_cert_fact'] | b64decode }}" 89 | owner: "{{ keystone_system_user_name }}" 90 | group: "{{ keystone_system_group_name }}" 91 | mode: "0640" 92 | when: not _keystone_is_first_play_host 93 | notify: 94 | - Restart web server 95 | - Restart Shibd 96 | 97 | - name: Set appropriate file ownership on the Shibboleth SP key-pair 98 | ansible.builtin.file: 99 | path: "{{ item }}" 100 | owner: "_shibd" 101 | group: "_shibd" 102 | with_items: 103 | - "/etc/shibboleth/sp-cert.pem" 104 | - "/etc/shibboleth/sp-key.pem" 105 | when: not _keystone_is_first_play_host 106 | notify: 107 | - Restart web server 108 | - Restart Shibd 109 | -------------------------------------------------------------------------------- /tasks/main_pre.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2022, BBC R&D 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Gather variables for each operating system 17 | ansible.builtin.include_vars: "{{ lookup('first_found', params) }}" 18 | vars: 19 | params: 20 | files: 21 | - "{{ ansible_facts['distribution'] | lower }}-{{ ansible_facts['distribution_version'] | lower }}.yml" 22 | - "{{ ansible_facts['distribution'] | lower }}-{{ ansible_facts['distribution_major_version'] | lower }}.yml" 23 | - "{{ ansible_facts['os_family'] | lower }}-{{ ansible_facts['distribution_major_version'] | lower }}.yml" 24 | - "{{ ansible_facts['distribution'] | lower }}.yml" 25 | - "{{ ansible_facts['os_family'] | lower }}.yml" 26 | paths: 27 | - "{{ role_path }}/vars" 28 | tags: 29 | - always 30 | 31 | - name: Create system groups 32 | ansible.builtin.group: 33 | name: "{{ item }}" 34 | state: "present" 35 | system: "yes" 36 | with_items: "{{ [keystone_system_group_name] + keystone_system_additional_groups }}" 37 | 38 | - name: Create the keystone system user 39 | ansible.builtin.user: 40 | name: "{{ keystone_system_user_name }}" 41 | group: "{{ keystone_system_group_name }}" 42 | groups: "{{ keystone_system_additional_groups | join(',') }}" 43 | comment: "{{ keystone_system_comment }}" 44 | shell: "{{ keystone_system_shell }}" 45 | system: "yes" 46 | createhome: "yes" 47 | home: "{{ keystone_system_user_home }}" 48 | 49 | - name: Create keystone dir 50 | ansible.builtin.file: 51 | path: "{{ item.path | default(omit) }}" 52 | src: "{{ item.src | default(omit) }}" 53 | dest: "{{ item.dest | default(omit) }}" 54 | state: "{{ item.state | default('directory') }}" 55 | owner: "{{ item.owner | default(keystone_system_user_name) }}" 56 | group: "{{ item.group | default(keystone_system_group_name) }}" 57 | mode: "{{ item.mode | default(omit) }}" 58 | force: "{{ item.force | default(omit) }}" 59 | with_items: 60 | - path: "/openstack" 61 | mode: "0755" 62 | owner: "root" 63 | group: "root" 64 | - dest: "/etc/keystone" 65 | mode: "0755" 66 | - path: "{{ keystone_credential_key_repository }}" 67 | mode: "0750" 68 | - path: "{{ keystone_ldap_domain_config_dir }}" 69 | mode: "0750" 70 | - path: "/etc/keystone/ssl" 71 | - path: "{{ keystone_fernet_tokens_key_repository }}" 72 | mode: "2750" 73 | - path: "{{ keystone_system_user_home }}" 74 | - path: "/var/www/cgi-bin" 75 | owner: root 76 | group: root 77 | - path: "/var/www/cgi-bin/keystone" 78 | - path: "/etc/ansible/facts.d" 79 | owner: root 80 | group: root 81 | 82 | - name: Install distro packages 83 | ansible.builtin.package: 84 | name: "{{ keystone_distro_packages }}" 85 | state: "{{ keystone_package_state }}" 86 | update_cache: "{{ (ansible_facts['pkg_mgr'] == 'apt') | ternary('yes', omit) }}" 87 | cache_valid_time: "{{ (ansible_facts['pkg_mgr'] == 'apt') | ternary(cache_timeout, omit) }}" 88 | register: install_packages 89 | until: install_packages is success 90 | retries: 5 91 | delay: 2 92 | notify: 93 | - Restart ssh 94 | 95 | - name: Adjust sshd configuration in container 96 | ansible.builtin.lineinfile: 97 | dest: "/etc/ssh/sshd_config" 98 | regexp: "{{ item.regexp }}" 99 | line: "{{ item.line }}" 100 | state: present 101 | with_items: "{{ keystone_ssh_extra_configuration }}" 102 | notify: 103 | - Restart ssh 104 | 105 | - name: Importing keystone_key_setup tasks 106 | ansible.builtin.import_tasks: keystone_key_setup.yml 107 | tags: 108 | - keystone-install 109 | -------------------------------------------------------------------------------- /doc/source/configure-keystone.rst: -------------------------------------------------------------------------------- 1 | ====================================================== 2 | Configuring the Identity service (keystone) (optional) 3 | ====================================================== 4 | 5 | Customize your keystone deployment in 6 | ``/etc/openstack_deploy/user_variables.yml``. 7 | 8 | 9 | Securing keystone communication with SSL certificates 10 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 | 12 | The OpenStack-Ansible project provides the ability to secure keystone 13 | communications with self-signed or user-provided SSL certificates. By default, 14 | self-signed certificates are in use. However, you can 15 | provide your own certificates by using the following Ansible variables in 16 | ``/etc/openstack_deploy/user_variables.yml``: 17 | 18 | .. code-block:: yaml 19 | 20 | keystone_user_ssl_cert: # Path to certificate 21 | keystone_user_ssl_key: # Path to private key 22 | keystone_user_ssl_ca_cert: # Path to CA certificate 23 | 24 | .. note:: 25 | 26 | If you are providing certificates, keys, and CA file for a 27 | CA without chain of trust (or an invalid/self-generated ca), the variables 28 | ``keystone_service_internaluri_insecure`` and 29 | ``keystone_service_adminuri_insecure`` should be set to ``true``. 30 | 31 | Refer to `Securing services with SSL certificates `_ 32 | for more information on these configuration options and how you can provide 33 | your own certificates and keys to use with keystone. 34 | 35 | Implementing LDAP (or Active Directory) backends 36 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | 38 | You can use the built-in keystone support for services if you already have 39 | LDAP or Active Directory (AD) infrastructure on your deployment. 40 | Keystone uses the existing users, groups, and user-group relationships to 41 | handle authentication and access control in an OpenStack deployment. 42 | 43 | .. note:: 44 | 45 | We do not recommend configuring the default domain in keystone to use 46 | LDAP or AD identity backends. Create additional domains 47 | in keystone and configure either LDAP or active directory backends for 48 | that domain. 49 | 50 | This is critical in situations where the identity backend cannot 51 | be reached due to network issues or other problems. In those situations, 52 | the administrative users in the default domain would still be able to 53 | authenticate to keystone using the default domain which is not backed by 54 | LDAP or AD. 55 | 56 | You can add domains with LDAP backends by adding variables in 57 | ``/etc/openstack_deploy/user_variables.yml``. For example, this dictionary 58 | adds a new keystone domain called ``Users`` that is backed by an LDAP server: 59 | 60 | .. code-block:: yaml 61 | 62 | keystone_ldap: 63 | Users: 64 | url: "ldap://10.10.10.10" 65 | user: "root" 66 | password: "secrete" 67 | 68 | Adding the YAML block above causes the keystone playbook to create a 69 | ``/etc/keystone/domains/keystone.Users.conf`` file within each keystone service 70 | container that configures the LDAP-backed domain called ``Users``. 71 | 72 | You can create more complex configurations that use LDAP filtering and 73 | consume LDAP as a read-only resource. The following example shows how to apply 74 | these configurations: 75 | 76 | .. code-block:: yaml 77 | 78 | keystone_ldap: 79 | MyCorporation: 80 | url: "ldaps://ldap.example.com" 81 | user_tree_dn: "ou=Users,o=MyCorporation" 82 | group_tree_dn: "cn=openstack-users,ou=Users,o=MyCorporation" 83 | user_objectclass: "inetOrgPerson" 84 | user_id_attribute: "cn" 85 | user_name_attribute: "uid" 86 | user_filter: "(groupMembership=cn=openstack-users,ou=Users,o=MyCorporation)" 87 | 88 | In the `MyCorporation` example above, keystone uses the LDAP server as a 89 | read-only resource. The configuration also ensures that keystone filters the 90 | list of possible users to the ones that exist in the 91 | ``cn=openstack-users,ou=Users,o=MyCorporation`` group. 92 | 93 | Horizon offers multi-domain support that can be enabled with an Ansible 94 | variable during deployment: 95 | 96 | .. code-block:: yaml 97 | 98 | horizon_keystone_multidomain_support: true 99 | 100 | Enabling multi-domain support in horizon adds the ``Domain`` input field on 101 | the horizon login page and it adds other domain-specific features in the 102 | keystone section. 103 | 104 | More details regarding valid configuration for the LDAP Identity backend can 105 | be found in the `Keystone Administrator Guide`_. 106 | 107 | .. _Keystone Administrator Guide: https://docs.openstack.org/keystone/latest/admin/configuration.html#integrate-identity-with-ldap 108 | -------------------------------------------------------------------------------- /doc/source/configure-federation-idp.rst: -------------------------------------------------------------------------------- 1 | =================================================== 2 | Configure keystone as a federated Identity Provider 3 | =================================================== 4 | 5 | The IdP configuration for keystone provides a 6 | dictionary attribute with the key ``keystone_idp``. The following is a 7 | complete example: 8 | 9 | .. code:: 10 | 11 | keystone_idp: 12 | certfile: "/etc/keystone/ssl/idp_signing_cert.pem" 13 | keyfile: "/etc/keystone/ssl/idp_signing_key.pem" 14 | self_signed_cert_subject: "/C=US/ST=Texas/L=San Antonio/O=IT/CN={{ external_lb_vip_address }}" 15 | regen_cert: false 16 | idp_entity_id: "{{ keystone_service_publicuri }}/v3/OS-FEDERATION/saml2/idp" 17 | idp_sso_endpoint: "{{ keystone_service_publicuri }}/v3/OS-FEDERATION/saml2/sso" 18 | idp_metadata_path: /etc/keystone/saml2_idp_metadata.xml 19 | service_providers: 20 | - id: "sp_1" 21 | auth_url: https://example.com:5000/v3/OS-FEDERATION/identity_providers/idp/protocols/saml2/auth 22 | sp_url: https://example.com:5000/Shibboleth.sso/SAML2/ECP 23 | organization_name: example_company 24 | organization_display_name: Example Corp. 25 | organization_url: example.com 26 | contact_company: example_company 27 | contact_name: John 28 | contact_surname: Smith 29 | contact_email: jsmith@example.com 30 | contact_telephone: 555-55-5555 31 | contact_type: technical 32 | 33 | The following list is a reference of allowed settings: 34 | 35 | * ``certfile`` defines the location and filename of the SSL certificate that 36 | the IdP uses to sign assertions. This file must be in a location that is 37 | accessible to the keystone system user. 38 | 39 | * ``keyfile`` defines the location and filename of the SSL private key that 40 | the IdP uses to sign assertions. This file must be in a location that is 41 | accessible to the keystone system user. 42 | 43 | * ``self_signed_cert_subject`` is the subject in the SSL signing 44 | certificate. The common name of the certificate 45 | must match the hostname configuration in the service provider(s) for 46 | this IdP. 47 | 48 | * ``regen_cert`` by default is set to ``False``. When set to ``True``, the 49 | next Ansible run replaces the existing signing certificate with a new one. 50 | This setting is added as a convenience mechanism to renew a certificate when 51 | it is close to its expiration date. 52 | 53 | * ``idp_entity_id`` is the entity ID. The service providers 54 | use this as a unique identifier for each IdP. 55 | ``/OS-FEDERATION/saml2/idp`` is the value we 56 | recommend for this setting. 57 | 58 | * ``idp_sso_endpoint`` is the single sign-on endpoint for this IdP. 59 | ``/OS-FEDERATION/saml2/sso>`` is the value 60 | we recommend for this setting. 61 | 62 | * ``idp_metadata_path`` is the location and filename where the metadata for 63 | this IdP is cached. The keystone system user must have access to this 64 | location. 65 | 66 | * ``service_providers`` is a list of the known SPs that 67 | use the keystone instance as IdP. For each SP, provide 68 | three values: ``id`` as a unique identifier, 69 | ``auth_url`` as the authentication endpoint of the SP, and ``sp_url`` 70 | endpoint for posting SAML2 assertions. 71 | 72 | * ``organization_name``, ``organization_display_name``, ``organization_url``, 73 | ``contact_company``, ``contact_name``, ``contact_surname``, 74 | ``contact_email``, ``contact_telephone`` and ``contact_type`` are 75 | settings that describe the identity provider. These settings are all 76 | optional. 77 | 78 | Configuring ADFS 3.0 as an identity provider 79 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 80 | 81 | To install ADFS: 82 | 83 | * `Prerequisites for ADFS from Microsoft Technet `_ 84 | * `ADFS installation procedure from Microsoft Technet `_ 85 | 86 | Configuring ADFS 87 | ~~~~~~~~~~~~~~~~ 88 | 89 | #. Ensure the ADFS server trusts the SP's keystone 90 | certificate. We recommend to have the ADFS CA (or a 91 | public CA) sign a certificate request for the keystone service. 92 | #. In the ADFS Management Console, choose ``Add Relying Party Trust``. 93 | #. Select ``Import data about the relying party published online or on a 94 | local network`` and enter the URL for the SP Metadata ( 95 | for example, ``https://:5000/Shibboleth.sso/Metadata``) 96 | 97 | .. note:: 98 | 99 | ADFS may give a warning message. The message states that ADFS skipped 100 | some of the content gathered from metadata because it is not supported by ADFS 101 | 102 | #. Continuing the wizard, select ``Permit all users to access this 103 | relying party``. 104 | #. In the ``Add Transform Claim Rule Wizard``, select ``Pass Through or 105 | Filter an Incoming Claim``. 106 | #. Name the rule (for example, ``Pass Through UPN``) and select the ``UPN`` 107 | Incoming claim type. 108 | #. Click :guilabel:`OK` to apply the rule and finalize the setup. 109 | -------------------------------------------------------------------------------- /tasks/keystone_federation_sp_idp_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Ensure existence of federation objects 17 | delegate_to: "{{ keystone_service_setup_host }}" 18 | vars: 19 | ansible_python_interpreter: "{{ keystone_service_setup_host_python_interpreter }}" 20 | block: 21 | - name: Ensure domain which remote IDP users are mapped onto exists 22 | openstack.cloud.identity_domain: 23 | cloud: default 24 | state: present 25 | name: "{{ item.domain }}" 26 | interface: admin 27 | verify: "{{ keystone_service_adminuri_insecure }}" 28 | when: item.domain is defined 29 | no_log: true 30 | with_items: "{{ trusted_idp.federated_identities | default([]) }}" 31 | 32 | - name: Ensure project which remote IDP users are mapped onto exists 33 | openstack.cloud.project: 34 | cloud: default 35 | state: present 36 | name: "{{ item.project }}" 37 | domain_id: "{{ item.domain }}" 38 | interface: admin 39 | verify: "{{ keystone_service_adminuri_insecure }}" 40 | when: item.project is defined 41 | no_log: true 42 | with_items: "{{ trusted_idp.federated_identities | default([]) }}" 43 | 44 | - name: Ensure user which remote IDP users are mapped onto exists 45 | openstack.cloud.identity_user: 46 | cloud: default 47 | state: present 48 | name: "{{ item.user }}" 49 | password: "{{ item.password }}" 50 | default_project: "{{ item.project }}" 51 | domain: "{{ item.domain | default('default') }}" 52 | interface: admin 53 | verify: "{{ keystone_service_adminuri_insecure }}" 54 | when: > 55 | item.user is defined and 56 | item.password is defined and 57 | item.project is defined 58 | no_log: true 59 | with_items: "{{ trusted_idp.federated_identities | default([]) }}" 60 | 61 | - name: Ensure Group for external IDP users exists 62 | openstack.cloud.identity_group: 63 | cloud: default 64 | state: present 65 | name: "{{ item.group }}" 66 | domain_id: "{{ item.domain | default('default') }}" 67 | interface: admin 68 | verify: "{{ keystone_service_adminuri_insecure }}" 69 | with_items: "{{ trusted_idp.federated_identities | default([]) }}" 70 | when: item.group is defined 71 | no_log: true 72 | 73 | - name: Ensure Role for external IDP users exists 74 | openstack.cloud.identity_role: 75 | cloud: default 76 | state: present 77 | name: "{{ item.role | default('member') }}" 78 | interface: admin 79 | verify: "{{ keystone_service_adminuri_insecure }}" 80 | with_items: "{{ trusted_idp.federated_identities | default([]) }}" 81 | when: > 82 | item.group is defined and 83 | item.project is defined 84 | no_log: true 85 | 86 | - name: Ensure Group/Project/Role mapping exists 87 | openstack.cloud.role_assignment: 88 | cloud: default 89 | state: present 90 | group: "{{ item.group }}" 91 | project: "{{ item.project }}" 92 | role: "{{ item.role | default('member') }}" 93 | interface: admin 94 | verify: "{{ keystone_service_adminuri_insecure }}" 95 | with_items: "{{ trusted_idp.federated_identities | default([]) }}" 96 | when: > 97 | item.group is defined and 98 | item.project is defined 99 | no_log: true 100 | 101 | - name: Ensure mapping for external IDP attributes exists 102 | openstack.cloud.federation_mapping: 103 | cloud: default 104 | state: present 105 | name: "{{ item.mapping.name }}" 106 | rules: "{{ item.mapping.rules }}" 107 | interface: admin 108 | verify: "{{ keystone_service_adminuri_insecure }}" 109 | when: item.mapping.name is defined 110 | no_log: true 111 | with_items: "{{ trusted_idp.protocols | default([]) }}" 112 | 113 | - name: Ensure external IDP 114 | openstack.cloud.federation_idp: 115 | cloud: default 116 | state: present 117 | name: "{{ trusted_idp.name }}" 118 | remote_ids: "{{ trusted_idp.entity_ids }}" 119 | enabled: true 120 | domain_id: "{{ trusted_idp.domain_id | default(omit) }}" 121 | interface: admin 122 | verify: "{{ keystone_service_adminuri_insecure }}" 123 | when: trusted_idp.name is defined 124 | no_log: true 125 | 126 | - name: Ensure federation protocol exists 127 | openstack.cloud.keystone_federation_protocol: 128 | cloud: default 129 | state: present 130 | name: "{{ item.name }}" 131 | idp_name: "{{ trusted_idp.name }}" 132 | mapping_id: "{{ item.mapping.name }}" 133 | interface: admin 134 | verify: "{{ keystone_service_adminuri_insecure }}" 135 | when: item.name is defined 136 | no_log: true 137 | with_items: "{{ trusted_idp.protocols | default([]) }}" 138 | -------------------------------------------------------------------------------- /tasks/keystone_install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Create keystone dir 17 | ansible.builtin.file: 18 | path: "{{ item.path }}" 19 | state: directory 20 | owner: "{{ item.owner | default(keystone_system_user_name) }}" 21 | group: "{{ item.group | default(keystone_system_group_name) }}" 22 | mode: "{{ item.mode | default('0755') }}" 23 | with_items: 24 | - { path: "/var/lock/keystone", mode: "2755" } 25 | when: 26 | - ansible_facts['pkg_mgr'] == 'dnf' 27 | 28 | - name: Create system links 29 | ansible.builtin.file: 30 | src: "{{ item.src }}" 31 | dest: "{{ item.dest }}" 32 | state: "link" 33 | with_items: 34 | - { src: "/var/log/httpd", dest: "/var/log/apache2" } 35 | when: 36 | - ansible_facts['pkg_mgr'] == 'dnf' 37 | 38 | - name: Add shibboleth repo 39 | ansible.builtin.yum_repository: 40 | name: "shibboleth" 41 | description: "shibboleth Repo" 42 | baseurl: "{{ keystone_centos_shibboleth_mirror }}" 43 | gpgkey: "{{ keystone_centos_shibboleth_key }}" 44 | gpgcheck: true 45 | when: 46 | - ansible_facts['pkg_mgr'] == 'dnf' 47 | - keystone_sp != {} 48 | 49 | - name: Install distro packages 50 | ansible.builtin.package: 51 | name: "{{ keystone_package_list }}" 52 | state: "{{ keystone_package_state }}" 53 | update_cache: "{{ (ansible_facts['pkg_mgr'] == 'apt') | ternary('yes', omit) }}" 54 | cache_valid_time: "{{ (ansible_facts['pkg_mgr'] == 'apt') | ternary(cache_timeout, omit) }}" 55 | register: install_packages 56 | until: install_packages is success 57 | retries: 5 58 | delay: 2 59 | notify: 60 | - Restart uWSGI 61 | 62 | - name: Install the python venv 63 | ansible.builtin.import_role: 64 | name: "python_venv_build" 65 | vars: 66 | venv_python_executable: "{{ keystone_venv_python_executable }}" 67 | venv_build_constraints: "{{ keystone_git_constraints }}" 68 | venv_build_distro_package_list: "{{ keystone_devel_distro_packages }}" 69 | venv_install_destination_path: "{{ keystone_bin | dirname }}" 70 | venv_pip_install_args: "{{ keystone_pip_install_args }}" 71 | venv_pip_packages: "{{ keystone_pip_packages | union(keystone_user_pip_packages) }}" 72 | venv_facts_when_changed: 73 | - section: "keystone" 74 | option: "need_db_expand" 75 | value: "True" 76 | - section: "keystone" 77 | option: "need_db_contract" 78 | value: "True" 79 | - section: "keystone" 80 | option: "venv_tag" 81 | value: "{{ keystone_venv_tag }}" 82 | - section: "keystone" 83 | option: "install_method" 84 | value: "{{ keystone_install_method }}" 85 | when: keystone_install_method == 'source' 86 | 87 | # TODO(hwoarang): We need to have a venv_tag local fact deployed since we use it in the 88 | # integration repo to determine if keystone software is the same across all nodes in the 89 | # keystone_all group so we can safely run the DB migration. See 90 | # https://github.com/openstack/openstack-ansible/blob/master/playbooks/os-keystone-install.yml 91 | - name: Record local facts for distro path 92 | when: keystone_install_method == 'distro' 93 | block: 94 | - name: Record the osa version deployed 95 | community.general.ini_file: 96 | dest: "/etc/ansible/facts.d/openstack_ansible.fact" 97 | section: keystone 98 | option: venv_tag 99 | value: "{{ keystone_venv_tag }}" 100 | mode: "0644" 101 | 102 | # NOTE(noonedeadpunk): Ubuntu packages does recursively chmod all files 103 | # for keystone user $HOME: 104 | # https://bugs.launchpad.net/cloud-archive/+bug/2060235 105 | - name: Ensure SSH keys has right permissions 106 | ansible.builtin.file: 107 | path: "{{ keystone_system_user_home }}/.ssh/id_rsa" 108 | mode: "0600" 109 | when: 110 | - install_packages is changed 111 | - ansible_facts['distribution'] | lower == 'ubuntu' 112 | 113 | - name: Initialise the upgrade facts 114 | community.general.ini_file: 115 | dest: "/etc/ansible/facts.d/openstack_ansible.fact" 116 | section: keystone 117 | option: "{{ item.name }}" 118 | value: "{{ item.state }}" 119 | mode: "0644" 120 | with_items: 121 | - name: "need_db_expand" 122 | state: "True" 123 | - name: "need_db_contract" 124 | state: "True" 125 | - name: "install_method" 126 | state: "{{ keystone_install_method }}" 127 | when: (install_packages is changed) or 128 | (ansible_local is not defined) or 129 | ('openstack_ansible' not in ansible_local) or 130 | ('keystone' not in ansible_local['openstack_ansible']) or 131 | ('need_db_expand' not in ansible_local['openstack_ansible']['keystone']) or 132 | ('need_db_contract' not in ansible_local['openstack_ansible']['keystone']) 133 | 134 | - name: Create WSGI symlinks 135 | ansible.builtin.file: 136 | src: "{{ keystone_bin }}/keystone-wsgi-public" 137 | dest: "/var/www/cgi-bin/keystone/main" 138 | state: link 139 | force: true 140 | -------------------------------------------------------------------------------- /tasks/keystone_credential_create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2016, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Check if credential keys already exist 17 | ansible.builtin.stat: 18 | path: "{{ keystone_credential_key_repository }}/0" 19 | register: _credential_keys 20 | 21 | - name: Check for credential keys on all Keystone containers 22 | ansible.builtin.find: 23 | paths: "{{ keystone_credential_key_repository }}" 24 | patterns: "^[0-9]+$" 25 | use_regex: true 26 | when: not _credential_keys.stat.exists 27 | register: credential_key_list 28 | delegate_to: "{{ item }}" 29 | with_items: "{{ groups['keystone_all'] }}" 30 | 31 | - name: Aggregate the collected file lists 32 | ansible.builtin.set_fact: 33 | existing_credential_keys: >- 34 | {% set _var = [] -%} 35 | {% for result in credential_key_list.results -%} 36 | {% if result.files is defined -%} 37 | {% for file in result.files -%} 38 | {% if _var.append({'host': result.item, 'file': file.path}) -%}{% endif -%} 39 | {% endfor -%} 40 | {% endif -%} 41 | {% endfor -%} 42 | {{ _var }} 43 | when: not credential_key_list is skipped 44 | 45 | - name: Collect the existing keys from containers 46 | ansible.builtin.slurp: 47 | src: "{{ item.file }}" 48 | delegate_to: "{{ item.host }}" 49 | with_items: "{{ existing_credential_keys }}" 50 | register: collected_existing_credential_keys 51 | when: existing_credential_keys is defined 52 | 53 | - name: Ensure the target directory exists on the master Keystone container 54 | ansible.builtin.file: 55 | path: "{{ keystone_credential_key_repository }}" 56 | state: directory 57 | owner: "{{ keystone_system_user_name }}" 58 | group: "{{ keystone_system_group_name }}" 59 | mode: "0700" 60 | when: not collected_existing_credential_keys is skipped 61 | 62 | - name: Drop the existing credential keys in the master Keystone container 63 | ansible.builtin.copy: 64 | content: "{{ item.1 | b64decode }}" 65 | dest: "{{ keystone_credential_key_repository }}/{{ item.0 }}" 66 | owner: "{{ keystone_system_user_name }}" 67 | group: "{{ keystone_system_group_name }}" 68 | mode: "0600" 69 | when: not collected_existing_credential_keys is skipped 70 | register: drop_existing_credential_keys 71 | with_indexed_items: "{{ collected_existing_credential_keys.results | map(attribute='content') | list | unique }}" 72 | 73 | - name: Create credential keys for Keystone # noqa: no-changed-when 74 | ansible.builtin.command: > 75 | {{ keystone_bin }}/keystone-manage credential_setup 76 | --keystone-user "{{ keystone_system_user_name }}" 77 | --keystone-group "{{ keystone_system_group_name }}" 78 | become: true 79 | become_user: "{{ keystone_system_user_name }}" 80 | register: create_credential_keys 81 | when: 82 | - not _credential_keys.stat.exists 83 | - not drop_existing_credential_keys is changed 84 | 85 | - name: Perform rotation and migration of credential keys 86 | when: create_credential_keys is skipped 87 | block: 88 | - name: Rotate credential keys for Keystone # noqa: no-changed-when 89 | ansible.builtin.command: > 90 | {{ keystone_bin }}/keystone-manage credential_rotate 91 | --keystone-user "{{ keystone_system_user_name }}" 92 | --keystone-group "{{ keystone_system_group_name }}" 93 | become: true 94 | become_user: "{{ keystone_system_user_name }}" 95 | # credential_rotate might fail in case any credential is not using current private key 96 | # so in case it fails, we need to try perform the migraton and attempt rotation after that 97 | rescue: 98 | - name: Ensure newest key is used for credential in Keystone # noqa: no-changed-when 99 | ansible.builtin.command: > 100 | {{ keystone_bin }}/keystone-manage credential_migrate 101 | --keystone-user "{{ keystone_system_user_name }}" 102 | --keystone-group "{{ keystone_system_group_name }}" 103 | become: true 104 | become_user: "{{ keystone_system_user_name }}" 105 | 106 | - name: Rotate credential keys for Keystone # noqa: no-changed-when 107 | ansible.builtin.command: > 108 | {{ keystone_bin }}/keystone-manage credential_rotate 109 | --keystone-user "{{ keystone_system_user_name }}" 110 | --keystone-group "{{ keystone_system_group_name }}" 111 | become: true 112 | become_user: "{{ keystone_system_user_name }}" 113 | always: 114 | # Let's run migration at the end anyway, as we need it after successfull rotation. 115 | - name: Ensure newest key is used for credential in Keystone # noqa: no-changed-when 116 | ansible.builtin.command: > 117 | {{ keystone_bin }}/keystone-manage credential_migrate 118 | --keystone-user "{{ keystone_system_user_name }}" 119 | --keystone-group "{{ keystone_system_group_name }}" 120 | become: true 121 | become_user: "{{ keystone_system_user_name }}" 122 | -------------------------------------------------------------------------------- /templates/shibboleth2.xml.j2: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {{ keystone_memcached_servers }} 17 | 18 | 19 | 20 | 21 | 22 | {{ keystone_memcached_servers }} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 41 | 42 | 43 | 44 | 45 | SAML2 SAML1 46 | 47 | 48 | 49 | 50 | SAML2 Local 51 | 52 | 57 | 58 | 59 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 77 | 80 | 81 | 85 | {% if keystone_sp.trusted_idp_list is defined -%} 86 | {% for item in keystone_sp.trusted_idp_list %} 87 | 91 | {% endfor %} 92 | {% endif %} 93 | 94 | 95 | 99 | 100 | 101 | 102 | 103 | 104 | 107 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 119 | 120 | 121 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /doc/source/configure-federation-mapping.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Configure keystone mappings 3 | =========================== 4 | 5 | The federated_identities functionality can be used to create 6 | projects, groups, roles and domains before your federation attribute 7 | mappings route users towards those resources. If you manage creation of 8 | projects, groups, roles and domains via a separate mechanism making use 9 | of federated_identities is not required. 10 | 11 | .. code-block:: yaml 12 | 13 | federated_identities: 14 | - domain: default 15 | project: fedproject 16 | group: fedgroup 17 | role: member 18 | 19 | #. ``project``: The project that federation users have access to. 20 | If the project does not already exist, create it in the 21 | domain with the name, ``domain``. 22 | 23 | #. ``group``: The keystone group that federation users 24 | belong. If the group does not already exist, create it in 25 | the domain with the name, ``domain``. 26 | 27 | #. ``role``: The role that federation users use in that project. 28 | Create the role if it does not already exist. 29 | 30 | #. ``domain``: The domain where the ``project`` lives, and where 31 | the you assign roles. Create the domain if it does not already exist. 32 | This should be the ID of the domain. 33 | 34 | Ansible implements the equivalent of the following OpenStack CLI commands: 35 | 36 | .. code-block:: shell-session 37 | 38 | # if the domain does not already exist 39 | openstack domain create Default 40 | 41 | # if the group does not already exist 42 | openstack group create fedgroup --domain Default 43 | 44 | # if the role does not already exist 45 | openstack role create member 46 | 47 | # if the project does not already exist 48 | openstack project create --domain default fedproject 49 | 50 | # map the role to the project and user group in the domain 51 | openstack role add --project fedproject --group fedgroup member 52 | 53 | To extend simply add more entries to the list. 54 | For example: 55 | 56 | .. code-block:: yaml 57 | 58 | federated_identities: 59 | - domain: default 60 | project: fedproject 61 | group: fedgroup 62 | role: member 63 | - domain: default 64 | project: fedproject2 65 | group: fedgroup2 66 | role: member 67 | 68 | Keystone federation attribute mapping 69 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 | 71 | Attribute mapping adds a set of rules to map federation attributes to keystone 72 | users and groups. IdP specifies one mapping per protocol. 73 | 74 | Use mapping objects multiple times by different combinations of 75 | IdP and protocol. 76 | 77 | The details of how the mapping engine works, the schema, and various rule 78 | examples are in the `keystone developer documentation 79 | `_. 80 | 81 | For example, SP attribute mapping configuration for an ADFS IdP: 82 | 83 | .. code-block:: yaml 84 | 85 | mapping: 86 | name: adfs-IdP-mapping 87 | rules: 88 | - remote: 89 | - type: upn 90 | local: 91 | - group: 92 | name: fedgroup 93 | domain: 94 | name: Default 95 | - user: 96 | name: '{0}' 97 | attributes: 98 | - name: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn' 99 | id: upn 100 | 101 | Each IdP for an SP needs to be set up with a mapping. This tells the SP how 102 | to interpret the attributes provided to the SP from the IdP. 103 | 104 | In this example, the IdP publishes the ``upn`` attribute. As this 105 | is not in the standard Shibboleth attribute map (see 106 | ``/etc/shibboleth/attribute-map.xml`` in the keystone containers), the configuration 107 | of the IdP has extra mapping through the ``attributes`` dictionary. 108 | 109 | The ``mapping`` dictionary is a YAML representation similar to the 110 | keystone mapping property which Ansible uploads. The above mapping 111 | produces the following in keystone. 112 | 113 | .. code-block:: shell-session 114 | 115 | root@aio1_keystone_container-783aa4c0:~# openstack mapping list 116 | +------------------+ 117 | | ID | 118 | +------------------+ 119 | | adfs-IdP-mapping | 120 | +------------------+ 121 | 122 | root@aio1_keystone_container-783aa4c0:~# openstack mapping show adfs-IdP-mapping 123 | +-------+---------------------------------------------------------------------------------------------------------------------------------------+ 124 | | Field | Value | 125 | +-------+---------------------------------------------------------------------------------------------------------------------------------------+ 126 | | id | adfs-IdP-mapping | 127 | | rules | [{"remote": [{"type": "upn"}], "local": [{"group": {"domain": {"name": "Default"}, "name": "fedgroup"}}, {"user": {"name": "{0}"}}]}] | 128 | +-------+---------------------------------------------------------------------------------------------------------------------------------------+ 129 | 130 | root@aio1_keystone_container-783aa4c0:~# openstack mapping show adfs-IdP-mapping | awk -F\| '/rules/ {print $3}' | python -mjson.tool 131 | [ 132 | { 133 | "remote": [ 134 | { 135 | "type": "upn" 136 | } 137 | ], 138 | "local": [ 139 | { 140 | "group": { 141 | "domain": { 142 | "name": "Default" 143 | }, 144 | "name": "fedgroup" 145 | } 146 | }, 147 | { 148 | "user": { 149 | "name": "{0}" 150 | } 151 | } 152 | ] 153 | } 154 | ] 155 | 156 | The interpretation of the above mapping rule is that any federation user 157 | authenticated by the IdP maps to an ``ephemeral`` user in keystone. 158 | The user is a member of a group named ``fedgroup``. This is in a domain 159 | called ``Default``. As we have specified the domain, the users 160 | assignments in the keystone backend will be looked up alongside the 161 | assignments made in the mapping. 162 | The user's ID and Name (federation uses the same value for both properties) 163 | for all OpenStack services is the value of ``upn``. 164 | -------------------------------------------------------------------------------- /templates/keystone.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | [DEFAULT] 4 | use_journal = True 5 | # Disable stderr logging 6 | use_stderr = False 7 | debug = {{ debug }} 8 | {% if keystone_public_endpoint is defined %} 9 | public_endpoint = {{ keystone_public_endpoint }} 10 | {% endif %} 11 | fatal_deprecations = {{ keystone_fatal_deprecations }} 12 | {% if keystone_sp != {} and (keystone_sp.cadf_notifications is defined) and (keystone_sp.cadf_notifications | bool) %} 13 | {% set cadf_notifications = true %} 14 | {% else %} 15 | {% set cadf_notifications = false %} 16 | {% endif %} 17 | {% if cadf_notifications | bool %} 18 | notification_format = cadf 19 | {% if keystone_sp.cadf_notifications_opt_out is defined %} 20 | {% for opt_out in keystone_sp.cadf_notifications_opt_out %} 21 | notification_opt_out = {{ opt_out }} 22 | {% endfor %} 23 | {% endif %} 24 | {% endif %} 25 | 26 | {% if keystone_oslomsg_rpc_configure %} 27 | ## Oslo.Messaging RPC 28 | transport_url = {{ keystone_oslomsg_rpc_transport }}://{% for host in keystone_oslomsg_rpc_servers.split(',') %}{{ keystone_oslomsg_rpc_userid }}:{{ keystone_oslomsg_rpc_password }}@{{ host }}:{{ keystone_oslomsg_rpc_port }}{% if not loop.last %},{% else %}/{{ _keystone_oslomsg_rpc_vhost_conf }}{% if keystone_oslomsg_rpc_use_ssl | bool %}?ssl=1&ssl_version={{ keystone_oslomsg_rpc_ssl_version }}&ssl_ca_file={{ keystone_oslomsg_rpc_ssl_ca_file }}{% else %}?ssl=0{% endif %}{% endif %}{% endfor %} 29 | {% endif %} 30 | 31 | {% if keystone_oslomsg_rpc_configure or keystone_oslomsg_notify_configure %} 32 | [oslo_messaging_rabbit] 33 | rabbit_quorum_queue = {{ keystone_oslomsg_rabbit_quorum_queues }} 34 | rabbit_transient_quorum_queue = {{ keystone_oslomsg_rabbit_transient_quorum_queues }} 35 | rabbit_qos_prefetch_count = {{ keystone_oslomsg_rabbit_qos_prefetch_count }} 36 | use_queue_manager = {{ keystone_oslomsg_rabbit_queue_manager }} 37 | {% if keystone_oslomsg_rabbit_queue_manager %} 38 | hostname = {{ [ansible_facts['hostname'], keystone_service_name] | join('-') }} 39 | {% endif %} 40 | rabbit_stream_fanout = {{ keystone_oslomsg_rabbit_stream_fanout }} 41 | rabbit_quorum_delivery_limit = {{ keystone_oslomsg_rabbit_quorum_delivery_limit }} 42 | rabbit_quorum_max_memory_bytes = {{ keystone_oslomsg_rabbit_quorum_max_memory_bytes }} 43 | {% endif %} 44 | 45 | [oslo_messaging_notifications] 46 | {% if keystone_oslomsg_notify_configure | bool %} 47 | driver = messagingv2 48 | {% set notification_driver = true %} 49 | {% endif %} 50 | {% if cadf_notifications | bool %} 51 | driver = log 52 | {% set notification_driver = true %} 53 | {% endif %} 54 | {% if notification_driver is not defined or notification_driver == false | bool %} 55 | driver = noop 56 | {% endif %} 57 | 58 | transport_url = {{ keystone_oslomsg_notify_transport }}://{% for host in keystone_oslomsg_notify_servers.split(',') %}{{ keystone_oslomsg_notify_userid }}:{{ keystone_oslomsg_notify_password }}@{{ host }}:{{ keystone_oslomsg_notify_port }}{% if not loop.last %},{% else %}/{{ _keystone_oslomsg_notify_vhost_conf }}{% if keystone_oslomsg_notify_use_ssl | bool %}?ssl=1&ssl_version={{ keystone_oslomsg_notify_ssl_version }}&ssl_ca_file={{ keystone_oslomsg_notify_ssl_ca_file }}{% else %}?ssl=0{% endif %}{% endif %}{% endfor %} 59 | 60 | {% if keystone_cache_servers | length > 0 %} 61 | [cache] 62 | backend = {{ keystone_cache_backend }} 63 | {% if keystone_cache_backend in keystone_cache_backend_map['dogpile'] %} 64 | # FIXME(lbragstad): Some strange behaviors have been reported when using 65 | # multiple memcached instances with backend_argument. This has been documented 66 | # in https://bugs.launchpad.net/oslo.cache/+bug/1743036 67 | # For the time being, memcache_servers works with a single memcached instance 68 | # and multiple instances. 69 | memcache_servers = {{ keystone_cache_servers | join(',') }} 70 | {% endif %} 71 | config_prefix = cache.keystone 72 | enabled = true 73 | {% endif %} 74 | 75 | 76 | [revoke] 77 | driver = {{ keystone_revocation_driver }} 78 | expiration_buffer = {{ keystone_revocation_expiration_buffer }} 79 | cache_time = {{ keystone_revocation_cache_time }} 80 | 81 | 82 | [auth] 83 | methods = {{ keystone_auth_methods }}{% if keystone_sp_apache_mod_shib %},saml2{% endif %}{% if keystone_sp_apache_mod_auth_openidc %},openid{% endif %} 84 | 85 | 86 | {% if keystone_database_enabled | bool %} 87 | [database] 88 | connection = {{ keystone_database_connection_string }} 89 | max_overflow = {{ keystone_db_max_overflow }} 90 | max_pool_size = {{ keystone_db_max_pool_size }} 91 | pool_timeout = {{ keystone_db_pool_timeout }} 92 | connection_recycle_time = {{ keystone_db_connection_recycle_time }} 93 | {% endif %} 94 | 95 | {% if 'fernet' in keystone_token_provider %} 96 | [fernet_tokens] 97 | key_repository = {{ keystone_fernet_tokens_key_repository }} 98 | max_active_keys = {{ keystone_fernet_tokens_max_active_keys }} 99 | {% endif %} 100 | 101 | 102 | [identity] 103 | {% if keystone_ldap.Default is not defined %} 104 | driver = sql 105 | {% endif %} 106 | {% if keystone_ldap | length > 0 %} 107 | domain_config_dir = {{ keystone_ldap_domain_config_dir }} 108 | domain_specific_drivers_enabled = True 109 | {% endif %} 110 | 111 | 112 | [assignment] 113 | driver = {{ keystone_assignment_driver }} 114 | 115 | 116 | [resource] 117 | cache_time = {{ keystone_resource_cache_time }} 118 | driver = {{ keystone_resource_driver }} 119 | 120 | 121 | [token] 122 | enforce_token_bind = permissive 123 | expiration = {{ keystone_token_expiration }} 124 | cache_time = {{ keystone_token_cache_time }} 125 | provider = {{ keystone_token_provider }} 126 | 127 | {% if keystone_idp != {} %} 128 | [saml] 129 | certfile = "{{ keystone_idp.certfile }}" 130 | keyfile = "{{ keystone_idp.keyfile }}" 131 | idp_entity_id = "{{ keystone_idp.idp_entity_id }}" 132 | idp_sso_endpoint = "{{ keystone_idp.idp_sso_endpoint }}" 133 | idp_metadata_path = "{{ keystone_idp.idp_metadata_path }}" 134 | {% if keystone_idp.organization_name is defined %} 135 | idp_organization_name = {{ keystone_idp.organization_name }} 136 | {% endif %} 137 | {% if keystone_idp.organization_display_name is defined %} 138 | idp_organization_display_name = {{ keystone_idp.organization_display_name }} 139 | {% endif %} 140 | {% if keystone_idp.organization_url is defined %} 141 | idp_organization_url = {{ keystone_idp.organization_url }} 142 | {% endif %} 143 | {% if keystone_idp.contact_company is defined %} 144 | idp_contact_company = {{ keystone_idp.contact_company }} 145 | {% endif %} 146 | {% if keystone_idp.contact_name is defined %} 147 | idp_contact_name = {{ keystone_idp.contact_name }} 148 | {% endif %} 149 | {% if keystone_idp.contact_surname is defined %} 150 | idp_contact_surname = {{ keystone_idp.contact_surname }} 151 | {% endif %} 152 | {% if keystone_idp.contact_email is defined %} 153 | idp_contact_email = {{ keystone_idp.contact_email }} 154 | {% endif %} 155 | {% if keystone_idp.contact_telephone is defined %} 156 | idp_contact_telephone = {{ keystone_idp.contact_telephone }} 157 | {% endif %} 158 | {% if keystone_idp.contact_type is defined %} 159 | idp_contact_type = {{ keystone_idp.contact_type }} 160 | {% endif %} 161 | {% endif %} 162 | 163 | [credential] 164 | key_repository = {{ keystone_credential_key_repository }} 165 | 166 | {% if keystone_sp != {} %} 167 | [federation] 168 | {% if keystone_sp_apache_mod_auth_openidc %} 169 | remote_id_attribute = HTTP_OIDC_ISS 170 | {% elif keystone_sp_apache_mod_shib %} 171 | remote_id_attribute = Shib-Identity-Provider 172 | {% endif %} 173 | {% if keystone_sp.trusted_dashboard_list is defined %} 174 | {% for item in keystone_sp.trusted_dashboard_list %} 175 | trusted_dashboard = {{ item }} 176 | {% endfor %} 177 | {% endif %} 178 | {% endif %} 179 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " applehelp to make an Apple Help Book" 34 | @echo " devhelp to make HTML files and a Devhelp project" 35 | @echo " epub to make an epub" 36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 37 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 39 | @echo " text to make text files" 40 | @echo " man to make manual pages" 41 | @echo " texinfo to make Texinfo files" 42 | @echo " info to make Texinfo files and run them through makeinfo" 43 | @echo " gettext to make PO message catalogs" 44 | @echo " changes to make an overview of all changed/added/deprecated items" 45 | @echo " xml to make Docutils-native XML files" 46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 47 | @echo " linkcheck to check all external links for integrity" 48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 49 | @echo " coverage to run coverage check of the documentation (if enabled)" 50 | 51 | clean: 52 | rm -rf $(BUILDDIR)/* 53 | 54 | html: 55 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 56 | @echo 57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 58 | 59 | dirhtml: 60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 61 | @echo 62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 63 | 64 | singlehtml: 65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 66 | @echo 67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 68 | 69 | pickle: 70 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 71 | @echo 72 | @echo "Build finished; now you can process the pickle files." 73 | 74 | json: 75 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 76 | @echo 77 | @echo "Build finished; now you can process the JSON files." 78 | 79 | htmlhelp: 80 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 81 | @echo 82 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 83 | ".hhp project file in $(BUILDDIR)/htmlhelp." 84 | 85 | qthelp: 86 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 87 | @echo 88 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 89 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 90 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/openstack-ansible-os_keystone.qhcp" 91 | @echo "To view the help file:" 92 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/openstack-ansible-os_keystone.qhc" 93 | 94 | applehelp: 95 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 96 | @echo 97 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 98 | @echo "N.B. You won't be able to view it unless you put it in" \ 99 | "~/Library/Documentation/Help or install it in your application" \ 100 | "bundle." 101 | 102 | devhelp: 103 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 104 | @echo 105 | @echo "Build finished." 106 | @echo "To view the help file:" 107 | @echo "# mkdir -p $$HOME/.local/share/devhelp/openstack-ansible-os_keystone" 108 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/openstack-ansible-os_keystone" 109 | @echo "# devhelp" 110 | 111 | epub: 112 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 113 | @echo 114 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 115 | 116 | latex: 117 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 118 | @echo 119 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 120 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 121 | "(use \`make latexpdf' here to do that automatically)." 122 | 123 | latexpdf: 124 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 125 | @echo "Running LaTeX files through pdflatex..." 126 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 127 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 128 | 129 | latexpdfja: 130 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 131 | @echo "Running LaTeX files through platex and dvipdfmx..." 132 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 133 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 134 | 135 | text: 136 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 137 | @echo 138 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 139 | 140 | man: 141 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 142 | @echo 143 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 144 | 145 | texinfo: 146 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 147 | @echo 148 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 149 | @echo "Run \`make' in that directory to run these through makeinfo" \ 150 | "(use \`make info' here to do that automatically)." 151 | 152 | info: 153 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 154 | @echo "Running Texinfo files through makeinfo..." 155 | make -C $(BUILDDIR)/texinfo info 156 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 157 | 158 | gettext: 159 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 160 | @echo 161 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 162 | 163 | changes: 164 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 165 | @echo 166 | @echo "The overview file is in $(BUILDDIR)/changes." 167 | 168 | linkcheck: 169 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 170 | @echo 171 | @echo "Link check complete; look for any errors in the above output " \ 172 | "or in $(BUILDDIR)/linkcheck/output.txt." 173 | 174 | doctest: 175 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 176 | @echo "Testing of doctests in the sources finished, look at the " \ 177 | "results in $(BUILDDIR)/doctest/output.txt." 178 | 179 | coverage: 180 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 181 | @echo "Testing of coverage in the sources finished, look at the " \ 182 | "results in $(BUILDDIR)/coverage/python.txt." 183 | 184 | xml: 185 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 186 | @echo 187 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 188 | 189 | pseudoxml: 190 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 191 | @echo 192 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 193 | 194 | livehtml: html 195 | sphinx-autobuild -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 196 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2018, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | keystone_core_files: [] 17 | 18 | uwsgi_keystone_services: |- 19 | {% set services = {} %} 20 | {% for key, value in keystone_services.items() %} 21 | {% if (value['group'] in group_names) and 22 | (('condition' not in value) or ('condition' in value and value['condition'])) 23 | and ('wsgi_app' in value and value['wsgi_app']) %} 24 | {% set _ = value.update( 25 | { 26 | 'wsgi_venv': (keystone_install_method == 'source') | ternary(keystone_bin | dirname, None), 27 | 'uwsgi_uid': keystone_system_user_name, 28 | 'uwsgi_guid': keystone_system_group_name, 29 | 'uwsgi_processes': keystone_wsgi_processes, 30 | 'uwsgi_threads': keystone_wsgi_threads, 31 | } 32 | ) %} 33 | {% set _ = services.update({key: value}) %} 34 | {% endif %} 35 | {% endfor %} 36 | {{ services }} 37 | 38 | _keystone_is_first_play_host: >- 39 | {{ 40 | (keystone_services['keystone-wsgi-public']['group'] in group_names and 41 | inventory_hostname == ((groups[keystone_services['keystone-wsgi-public']['group']] | select('in', ansible_play_hosts)) | list)[0]) | bool 42 | }} 43 | _keystone_is_last_play_host: >- 44 | {{ 45 | (keystone_services['keystone-wsgi-public']['group'] in group_names and 46 | inventory_hostname == ((groups[keystone_services['keystone-wsgi-public']['group']] | select('in', ansible_play_hosts)) | list)[-1]) | bool 47 | }} 48 | 49 | _keystone_oslomsg_rpc_vhost_conf: >- 50 | {{ 51 | (keystone_oslomsg_rpc_vhost is string) | ternary( 52 | keystone_oslomsg_rpc_vhost, keystone_oslomsg_rpc_vhost | selectattr('state', 'eq', 'present') | map(attribute='name') | first) 53 | }} 54 | 55 | _keystone_oslomsg_notify_vhost_conf: >- 56 | {{ 57 | (keystone_oslomsg_notify_vhost is string) | ternary( 58 | keystone_oslomsg_notify_vhost, keystone_oslomsg_notify_vhost | selectattr('state', 'eq', 'present') | map(attribute='name') | first) 59 | }} 60 | 61 | _keystone_cache_backend_map: 62 | dogpile: 63 | - oslo_cache.memcache_pool 64 | - dogpile.cache.pymemcache 65 | - dogpile.cache.memcached 66 | - dogpile.cache.bmemcached 67 | mongo: 68 | - oslo_cache.mongo 69 | etcd3gw: 70 | - oslo_cache.etcd3gw 71 | 72 | _keystone_cache_backend_package: |- 73 | {% set oslo = namespace(backend='dogpile') %} 74 | {% for key, value in _keystone_cache_backend_map.items() %} 75 | {% if keystone_cache_backend in value %} 76 | {% set oslo.backend = key %} 77 | {%- endif %} 78 | {%- endfor %} 79 | oslo.cache[{{ oslo.backend }}] 80 | 81 | keystone_sp_apache_mod_shib: >- 82 | {{ 83 | ( 84 | keystone_sp != {} and (keystone_sp.apache_mod is undefined or ( 85 | keystone_sp.apache_mod is defined and keystone_sp.apache_mod != 'mod_auth_openidc')) 86 | ) 87 | }} 88 | keystone_sp_apache_mod_auth_openidc: >- 89 | {{ (keystone_sp != {} and keystone_sp.apache_mod is defined and keystone_sp.apache_mod == 'mod_auth_openidc') }} 90 | 91 | _keystone_httpd_vhost_ssl: |- 92 | {% set ssl_options = {} %} 93 | {% if (keystone_user_ssl_cert is defined and keystone_user_ssl_cert) and (keystone_user_ssl_key is defined and keystone_user_ssl_key) %} 94 | {% set _ = ssl_options.update({'cert': keystone_user_ssl_cert, 'key': keystone_user_ssl_key}) %} 95 | {% if keystone_user_ssl_ca_cert is defined and keystone_user_ssl_ca_cert %} 96 | {% set _ = ssl_options.update({'ca': keystone_user_ssl_ca_cert}) %} 97 | {% endif %} 98 | {% else %} 99 | {% set _ = ssl_options.update({'san': keystone_pki_san}) %} 100 | {% endif %} 101 | {{ ssl_options }} 102 | 103 | _keystone_httpd_base_options: 104 | - Options +FollowSymLinks 105 | 106 | _keystone_httpd_shib_options: 107 | - "ShibURLScheme {{ keystone_service_publicuri_proto }}" 108 | - "ProxyPass /Shibboleth.sso !" 109 | - "" 110 | - " ShibRequestSetting requireSession 1" 111 | - " AuthType shibboleth" 112 | - " ShibExportAssertion Off" 113 | - " Require valid-user" 114 | - "" 115 | 116 | _keystone_httpd_openidc_base_options: 117 | - "OIDCClaimPrefix \"{{ keystone_sp.trusted_idp_list.0.oidc_claim_prefix | default('OIDC-') }}\"" 118 | - "OIDCResponseType \"{{ keystone_sp.trusted_idp_list.0.oidc_resp_type | default('id_token') }}\"" 119 | - "OIDCScope \"{{ keystone_sp.trusted_idp_list.0.oidc_scope | default('openid email profile') }}\"" 120 | - "OIDCProviderMetadataURL {{ keystone_sp.trusted_idp_list.0.oidc_provider_metadata_url }}" 121 | - "OIDCClientID {{ keystone_sp.trusted_idp_list.0.oidc_client_id }}" 122 | - "OIDCClientSecret {{ keystone_sp.trusted_idp_list.0.oidc_client_secret }}" 123 | - "OIDCCryptoPassphrase {{ keystone_sp.trusted_idp_list.0.oidc_crypto_passphrase }}" 124 | - "OIDCRedirectURI {{ keystone_service_publicuri }}{{ keystone_sp.trusted_idp_list.0.oidc_redirect_path | default('/oidc_redirect') }}" 125 | 126 | _keystone_httpd_openidc_options: |- 127 | {% set openidc_options = _keystone_httpd_openidc_base_options %} 128 | {% if _keystone_sp_apache_mod_auth_openidc_gte_2_4_11 is defined and _keystone_sp_apache_mod_auth_openidc_gte_2_4_11 %} 129 | {% set _ = openidc_options.append('OIDCXForwardedHeaders ' ~ keystone_secure_proxy_ssl_header) %} 130 | {% endif %} 131 | {% if keystone_sp.trusted_idp_list.0.oidc_auth_verify_jwks_uri is defined %} 132 | {% set _ = openidc_options.append('OIDCOAuthVerifyJwksUri ' ~ keystone_sp.trusted_idp_list.0.oidc_auth_verify_jwks_uri) %} 133 | {% endif %} 134 | {% if keystone_sp.trusted_idp_list.0.oidc_outgoing_proxy is defined %} 135 | {% set _ = openidc_options.append('OIDCOutgoingProxy ' ~ keystone_sp.trusted_idp_list.0.oidc_outgoing_proxy) %} 136 | {% endif %} 137 | {% if keystone_sp.trusted_idp_list.0.oidc_oauth_introspection_endpoint is defined %} 138 | {% set _ = openidc_options.append('OIDCOAuthIntrospectionEndpoint ' ~ keystone_sp.trusted_idp_list.0.oidc_oauth_introspection_endpoint) %} 139 | {% endif %} 140 | {% if keystone_sp.trusted_idp_list.0.oidc_oauth_client_id is defined %} 141 | {% set _ = openidc_options.append('OIDCOAuthClientID ' ~ keystone_sp.trusted_idp_list.0.oidc_oauth_client_id) %} 142 | {% endif %} 143 | {% if keystone_sp.trusted_idp_list.0.oidc_oauth_client_secret is defined %} 144 | {% set _ = openidc_options.append('OIDCOAuthClientSecret ' ~ keystone_sp.trusted_idp_list.0.oidc_oauth_client_secret) %} 145 | {% endif %} 146 | {% if keystone_sp.trusted_idp_list.0.oidc_pkce_method is defined %} 147 | {% set _ = openidc_options.append('OIDCPKCEMethod ' ~ keystone_sp.trusted_idp_list.0.oidc_pkce_method) %} 148 | {% endif %} 149 | {% if keystone_cache_servers | length > 0 -%} 150 | {% set _ = openidc_options.append('OIDCCacheType memcache') %} 151 | {% set _ = openidc_options.append('OIDCMemCacheServers "' ~ keystone_cache_servers | join(' ') ~ '"') %} 152 | {% endif %} 153 | {% if keystone_sp.trusted_idp_list.0.oidc_auth_request_params is defined %} 154 | {% set _ = openidc_options.append('OIDCAuthRequestParams ' ~ keystone_sp.trusted_idp_list.0.oidc_auth_request_params) %} 155 | {% endif %} 156 | {% if keystone_sp.trusted_idp_list.0.oidc_state_max_number_of_cookies is defined -%} 157 | {% set _ = openidc_options.append('OIDCStateMaxNumberOfCookies ' ~ keystone_sp.trusted_idp_list.0.oidc_state_max_number_of_cookies) %} 158 | {% endif %} 159 | {% if keystone_sp.trusted_idp_list.0.oidc_default_url is defined %} 160 | {% set _ = openidc_options.append('OIDCDefaultURL ' ~ keystone_sp.trusted_idp_list.0.oidc_default_url) %} 161 | {% endif %} 162 | {% if keystone_sp.trusted_idp_list.0.oidc_claim_delimiter is defined %} 163 | {% set _ = openidc_options.append('OIDCClaimDelimiter ' ~ keystone_sp.trusted_idp_list.0.oidc_claim_delimiter) %} 164 | {% endif %} 165 | {{ openidc_options }} 166 | 167 | _keystone_httpd_openidc_location_options: 168 | - Require valid-user 169 | - AuthType openid-connect 170 | 171 | _keystone_httpd_openidc_locations: 172 | - path: "{{ keystone_sp.trusted_idp_list.0.oidc_redirect_path | default('/oidc_redirect') }}" 173 | options: "{{ _keystone_httpd_openidc_location_options }}" 174 | - path: "/v3/OS-FEDERATION/identity_providers/{{ keystone_sp.trusted_idp_list.0.name }}/protocols/openid/auth" 175 | options: 176 | - Require valid-user 177 | - AuthType auth-openidc 178 | - path: /v3/auth/OS-FEDERATION/websso/openid 179 | options: "{{ _keystone_httpd_openidc_location_options }}" 180 | - path: /v3/auth/OS-FEDERATION/identity_providers/{{ keystone_sp.trusted_idp_list.0.name }}/protocols/openid/websso 181 | options: "{{ _keystone_httpd_openidc_location_options }}" 182 | 183 | _keystone_httpd_shib_locations: 184 | - path: /CShibboleth.sso 185 | options: 186 | - SetHandler shib 187 | - path: /v3/auth/OS-FEDERATION/websso/saml2\ 188 | options: 189 | - AuthType shibboleth 190 | - ShibRequestSetting requireSession 1 191 | - ShibRequestSetting exportAssertion 1 192 | - ShibRequireSession On 193 | - ShibExportAssertion On 194 | - Require valid-user 195 | 196 | _keystone_httpd_sp_directories: 197 | - path: /var/www/cgi-bin/keystone 198 | options: 199 | - Options Indexes FollowSymLinks MultiViews 200 | - AllowOverride All 201 | - Order allow,deny 202 | - allow from all 203 | -------------------------------------------------------------------------------- /releasenotes/source/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # This file is execfile()d with the current directory set to its 17 | # containing dir. 18 | # 19 | # Note that not all possible configuration values are present in this 20 | # autogenerated file. 21 | # 22 | # All configuration values have a default; values that are commented out 23 | # serve to show the default. 24 | 25 | # If extensions (or modules to document with autodoc) are in another directory, 26 | # add these directories to sys.path here. If the directory is relative to the 27 | # documentation root, use os.path.abspath to make it absolute, like shown here. 28 | # sys.path.insert(0, os.path.abspath('.')) 29 | 30 | # -- General configuration ------------------------------------------------ 31 | 32 | # If your documentation needs a minimal Sphinx version, state it here. 33 | # needs_sphinx = '1.0' 34 | 35 | # Add any Sphinx extension module names here, as strings. They can be 36 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 37 | # ones. 38 | extensions = [ 39 | 'openstackdocstheme', 40 | 'reno.sphinxext', 41 | ] 42 | 43 | # Add any paths that contain templates here, relative to this directory. 44 | templates_path = ['_templates'] 45 | 46 | # The suffix of source filenames. 47 | source_suffix = '.rst' 48 | 49 | # The encoding of source files. 50 | # source_encoding = 'utf-8-sig' 51 | 52 | # The master toctree document. 53 | master_doc = 'index' 54 | 55 | # General information about the project. 56 | author = 'OpenStack-Ansible Contributors' 57 | category = 'Miscellaneous' 58 | copyright = '2014-2016, OpenStack-Ansible Contributors' 59 | description = 'OpenStack-Ansible deploys OpenStack environments using Ansible.' 60 | project = 'OpenStack-Ansible' 61 | role_name = 'os_keystone' 62 | target_name = 'openstack-ansible-' + role_name 63 | title = 'OpenStack-Ansible Release Notes: ' + role_name + 'role' 64 | 65 | # Release notes do not need a version number in the title, they 66 | # cover multiple releases. 67 | # The full version, including alpha/beta/rc tags. 68 | release = '' 69 | # The short X.Y version. 70 | version = '' 71 | 72 | # openstackdocstheme options 73 | openstackdocs_repo_name = 'openstack/' + target_name 74 | openstackdocs_bug_project = project.lower() 75 | openstackdocs_bug_tag = '' 76 | 77 | # The language for content autogenerated by Sphinx. Refer to documentation 78 | # for a list of supported languages. 79 | # language = None 80 | 81 | # There are two options for replacing |today|: either, you set today to some 82 | # non-false value, then it is used: 83 | # today = '' 84 | # Else, today_fmt is used as the format for a strftime call. 85 | # today_fmt = '%B %d, %Y' 86 | 87 | # List of patterns, relative to source directory, that match files and 88 | # directories to ignore when looking for source files. 89 | exclude_patterns = [] 90 | 91 | # The reST default role (used for this markup: `text`) to use for all 92 | # documents. 93 | # default_role = None 94 | 95 | # If true, '()' will be appended to :func: etc. cross-reference text. 96 | # add_function_parentheses = True 97 | 98 | # If true, the current module name will be prepended to all description 99 | # unit titles (such as .. function::). 100 | # add_module_names = True 101 | 102 | # If true, sectionauthor and moduleauthor directives will be shown in the 103 | # output. They are ignored by default. 104 | # show_authors = False 105 | 106 | # The name of the Pygments (syntax highlighting) style to use. 107 | pygments_style = 'native' 108 | 109 | # A list of ignored prefixes for module index sorting. 110 | # modindex_common_prefix = [] 111 | 112 | # If true, keep warnings as "system message" paragraphs in the built documents. 113 | # keep_warnings = False 114 | 115 | 116 | # -- Options for HTML output ---------------------------------------------- 117 | 118 | # The theme to use for HTML and HTML Help pages. See the documentation for 119 | # a list of builtin themes. 120 | html_theme = 'openstackdocs' 121 | 122 | # Theme options are theme-specific and customize the look and feel of a theme 123 | # further. For a list of options available for each theme, see the 124 | # documentation. 125 | # html_theme_options = {} 126 | 127 | # Add any paths that contain custom themes here, relative to this directory. 128 | # html_theme_path = [] 129 | 130 | # The name for this set of Sphinx documents. If None, it defaults to 131 | # " v documentation". 132 | # html_title = None 133 | 134 | # A shorter title for the navigation bar. Default is the same as html_title. 135 | # html_short_title = None 136 | 137 | # The name of an image file (relative to this directory) to place at the top 138 | # of the sidebar. 139 | # html_logo = None 140 | 141 | # The name of an image file (within the static path) to use as favicon of the 142 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 143 | # pixels large. 144 | # html_favicon = None 145 | 146 | # Add any paths that contain custom static files (such as style sheets) here, 147 | # relative to this directory. They are copied after the builtin static files, 148 | # so a file named "default.css" will overwrite the builtin "default.css". 149 | html_static_path = ['_static'] 150 | 151 | # Add any extra paths that contain custom files (such as robots.txt or 152 | # .htaccess) here, relative to this directory. These files are copied 153 | # directly to the root of the documentation. 154 | # html_extra_path = [] 155 | 156 | # If true, SmartyPants will be used to convert quotes and dashes to 157 | # typographically correct entities. 158 | # html_use_smartypants = True 159 | 160 | # Custom sidebar templates, maps document names to template names. 161 | # html_sidebars = {} 162 | 163 | # Additional templates that should be rendered to pages, maps page names to 164 | # template names. 165 | # html_additional_pages = {} 166 | 167 | # If false, no module index is generated. 168 | # html_domain_indices = True 169 | 170 | # If false, no index is generated. 171 | # html_use_index = True 172 | 173 | # If true, the index is split into individual pages for each letter. 174 | # html_split_index = False 175 | 176 | # If true, links to the reST sources are added to the pages. 177 | # html_show_sourcelink = True 178 | 179 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 180 | # html_show_sphinx = True 181 | 182 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 183 | # html_show_copyright = True 184 | 185 | # If true, an OpenSearch description file will be output, and all pages will 186 | # contain a tag referring to it. The value of this option must be the 187 | # base URL from which the finished HTML is served. 188 | # html_use_opensearch = '' 189 | 190 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 191 | # html_file_suffix = None 192 | 193 | # Output file base name for HTML help builder. 194 | htmlhelp_basename = target_name + '-docs' 195 | 196 | 197 | # -- Options for LaTeX output --------------------------------------------- 198 | 199 | latex_elements = { 200 | # The paper size ('letterpaper' or 'a4paper'). 201 | # 'papersize': 'letterpaper', 202 | 203 | # The font size ('10pt', '11pt' or '12pt'). 204 | # 'pointsize': '10pt', 205 | 206 | # Additional stuff for the LaTeX preamble. 207 | # 'preamble': '', 208 | } 209 | 210 | # Grouping the document tree into LaTeX files. List of tuples 211 | # (source start file, target name, title, 212 | # author, documentclass [howto, manual, or own class]). 213 | latex_documents = [ 214 | (master_doc, target_name + '.tex', 215 | title, author, 'manual'), 216 | ] 217 | 218 | # The name of an image file (relative to this directory) to place at the top of 219 | # the title page. 220 | # latex_logo = None 221 | 222 | # For "manual" documents, if this is true, then toplevel headings are parts, 223 | # not chapters. 224 | # latex_use_parts = False 225 | 226 | # If true, show page references after internal links. 227 | # latex_show_pagerefs = False 228 | 229 | # If true, show URL addresses after external links. 230 | # latex_show_urls = False 231 | 232 | # Documents to append as an appendix to all manuals. 233 | # latex_appendices = [] 234 | 235 | # If false, no module index is generated. 236 | # latex_domain_indices = True 237 | 238 | 239 | # -- Options for manual page output --------------------------------------- 240 | 241 | # One entry per manual page. List of tuples 242 | # (source start file, name, description, authors, manual section). 243 | man_pages = [ 244 | (master_doc, target_name, 245 | title, [author], 1) 246 | ] 247 | 248 | # If true, show URL addresses after external links. 249 | # man_show_urls = False 250 | 251 | 252 | # -- Options for Texinfo output ------------------------------------------- 253 | 254 | # Grouping the document tree into Texinfo files. List of tuples 255 | # (source start file, target name, title, author, 256 | # dir menu entry, description, category) 257 | texinfo_documents = [ 258 | (master_doc, target_name, 259 | title, author, project, 260 | description, category), 261 | ] 262 | 263 | # Documents to append as an appendix to all manuals. 264 | # texinfo_appendices = [] 265 | 266 | # If false, no module index is generated. 267 | # texinfo_domain_indices = True 268 | 269 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 270 | # texinfo_show_urls = 'footnote' 271 | 272 | # If true, do not generate a @detailmenu in the "Top" node's menu. 273 | # texinfo_no_detailmenu = False 274 | 275 | # -- Options for Internationalization output ------------------------------ 276 | locale_dirs = ['locale/'] 277 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright 2014, Rackspace US, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Fail if our required secrets are not present 17 | ansible.builtin.fail: 18 | msg: "Please set the {{ item }} variable prior to applying this role." 19 | when: (item is undefined) or (item is none) 20 | with_items: "{{ keystone_required_secrets }}" 21 | tags: 22 | - always 23 | 24 | - name: Fail if service was deployed using a different installation method 25 | ansible.builtin.fail: 26 | msg: "Switching installation methods for OpenStack services is not supported" 27 | when: 28 | - ansible_local is defined 29 | - ansible_local.openstack_ansible is defined 30 | - ansible_local.openstack_ansible.keystone is defined 31 | - ansible_local.openstack_ansible.keystone.install_method is defined 32 | - ansible_local.openstack_ansible.keystone.install_method != keystone_install_method 33 | 34 | - name: Gather variables for each operating system 35 | ansible.builtin.include_vars: "{{ lookup('first_found', params) }}" 36 | vars: 37 | params: 38 | files: 39 | - "{{ ansible_facts['distribution'] | lower }}-{{ ansible_facts['distribution_version'] | lower }}.yml" 40 | - "{{ ansible_facts['distribution'] | lower }}-{{ ansible_facts['distribution_major_version'] | lower }}.yml" 41 | - "{{ ansible_facts['os_family'] | lower }}-{{ ansible_facts['distribution_major_version'] | lower }}.yml" 42 | - "{{ ansible_facts['distribution'] | lower }}.yml" 43 | - "{{ ansible_facts['os_family'] | lower }}.yml" 44 | paths: 45 | - "{{ role_path }}/vars" 46 | tags: 47 | - always 48 | 49 | - name: Gather variables for installation method 50 | ansible.builtin.include_vars: "{{ keystone_install_method }}_install.yml" 51 | tags: 52 | - always 53 | 54 | - name: Including osa.db_setup role 55 | ansible.builtin.include_role: 56 | name: openstack.osa.db_setup 57 | apply: 58 | tags: 59 | - common-db 60 | - keystone-config 61 | when: 62 | - "_keystone_is_first_play_host" 63 | vars: 64 | _oslodb_setup_host: "{{ keystone_db_setup_host }}" 65 | _oslodb_ansible_python_interpreter: "{{ keystone_db_setup_python_interpreter }}" 66 | _oslodb_setup_endpoint: "{{ keystone_galera_address }}" 67 | _oslodb_setup_port: "{{ keystone_galera_port }}" 68 | _oslodb_databases: 69 | - name: "{{ keystone_galera_database }}" 70 | users: 71 | - username: "{{ keystone_galera_user }}" 72 | password: "{{ keystone_container_mysql_password }}" 73 | tags: 74 | - always 75 | 76 | - name: Including osa.mq_setup role 77 | ansible.builtin.include_role: 78 | name: openstack.osa.mq_setup 79 | apply: 80 | tags: 81 | - common-mq 82 | - keystone-config 83 | when: 84 | - "_keystone_is_first_play_host" 85 | vars: 86 | _oslomsg_rpc_configure: "{{ keystone_oslomsg_rpc_configure }}" 87 | _oslomsg_rpc_setup_host: "{{ keystone_oslomsg_rpc_setup_host }}" 88 | _oslomsg_rpc_userid: "{{ keystone_oslomsg_rpc_userid }}" 89 | _oslomsg_rpc_password: "{{ keystone_oslomsg_rpc_password }}" 90 | _oslomsg_rpc_vhost: "{{ keystone_oslomsg_rpc_vhost }}" 91 | _oslomsg_rpc_transport: "{{ keystone_oslomsg_rpc_transport }}" 92 | _oslomsg_rpc_policies: "{{ keystone_oslomsg_rpc_policies }}" 93 | _oslomsg_notify_configure: "{{ keystone_oslomsg_notify_configure }}" 94 | _oslomsg_notify_setup_host: "{{ keystone_oslomsg_notify_setup_host }}" 95 | _oslomsg_notify_userid: "{{ keystone_oslomsg_notify_userid }}" 96 | _oslomsg_notify_password: "{{ keystone_oslomsg_notify_password }}" 97 | _oslomsg_notify_vhost: "{{ keystone_oslomsg_notify_vhost }}" 98 | _oslomsg_notify_transport: "{{ keystone_oslomsg_notify_transport }}" 99 | _oslomsg_notify_policies: "{{ keystone_oslomsg_notify_policies }}" 100 | tags: 101 | - always 102 | 103 | - name: Including keystone_federation_sp_shib_setup tasks 104 | ansible.builtin.include_tasks: 105 | file: keystone_federation_sp_shib_setup.yml 106 | apply: 107 | tags: 108 | - keystone-config 109 | when: 110 | - keystone_sp_apache_mod_shib 111 | - not (keystone_use_uwsgi | bool) 112 | tags: 113 | - keystone-config 114 | 115 | - name: Including keystone_apache tasks 116 | ansible.builtin.include_tasks: 117 | file: "keystone_apache.yml" 118 | apply: 119 | tags: 120 | - keystone-config 121 | when: 122 | - not (keystone_use_uwsgi | bool) 123 | tags: 124 | - keystone-config 125 | 126 | - name: Importing keystone_install tasks 127 | ansible.builtin.import_tasks: keystone_install.yml 128 | tags: 129 | - keystone-install 130 | 131 | - name: Refresh local facts 132 | ansible.builtin.setup: 133 | filter: ansible_local 134 | gather_subset: "!all" 135 | tags: 136 | - keystone-config 137 | 138 | - name: Importing keystone_post_install tasks 139 | ansible.builtin.import_tasks: keystone_post_install.yml 140 | tags: 141 | - keystone-config 142 | - post-install 143 | 144 | - name: Including keystone_fernet tasks 145 | ansible.builtin.include_tasks: 146 | file: keystone_fernet.yml 147 | apply: 148 | tags: 149 | - keystone-config 150 | when: 151 | - "'fernet' in keystone_token_provider" 152 | - keystone_service_setup | bool 153 | tags: 154 | - keystone-config 155 | 156 | - name: Including keystone_db_sync tasks 157 | ansible.builtin.include_tasks: 158 | file: keystone_db_sync.yml 159 | apply: 160 | tags: 161 | - keystone-config 162 | when: 163 | - "keystone_database_enabled | bool" 164 | tags: 165 | - keystone-config 166 | 167 | - name: Including keystone_credential tasks 168 | ansible.builtin.include_tasks: 169 | file: keystone_credential.yml 170 | apply: 171 | tags: 172 | - keystone-config 173 | when: keystone_service_setup | bool 174 | tags: 175 | - keystone-config 176 | 177 | - name: Create and install SSL certificates 178 | ansible.builtin.include_role: 179 | name: pki 180 | tasks_from: main_certs.yml 181 | vars: 182 | pki_setup_host: "{{ keystone_pki_setup_host }}" 183 | pki_dir: "{{ keystone_pki_dir }}" 184 | pki_create_ca: "{{ keystone_pki_create_ca }}" 185 | pki_authorities: "{{ keystone_pki_ca_certificates }}" 186 | pki_regen_ca: "{{ keystone_pki_regen_ca }}" 187 | pki_install_certificates: "{{ keystone_pki_install_certificates }}" 188 | when: 189 | - keystone_idp['certfile'] is defined 190 | tags: 191 | - keystone-config 192 | 193 | - name: Import uwsgi role 194 | ansible.builtin.import_role: 195 | name: uwsgi 196 | vars: 197 | uwsgi_services: "{{ uwsgi_keystone_services }}" 198 | uwsgi_install_method: "{{ keystone_install_method }}" 199 | tags: 200 | - keystone-config 201 | - uwsgi 202 | 203 | - name: Flush handlers 204 | ansible.builtin.meta: flush_handlers 205 | 206 | - name: Including keystone_service_bootstrap tasks 207 | ansible.builtin.include_tasks: keystone_service_bootstrap.yml 208 | args: 209 | apply: 210 | tags: 211 | - keystone-config 212 | when: 213 | - "_keystone_is_last_play_host" 214 | - "keystone_service_setup | bool" 215 | tags: 216 | - always 217 | 218 | # Note(odyssey4me): 219 | # This set of tasks specifically runs against the last keystone 220 | # node in the cluster to ensure that the modules have access to 221 | # the endpoints which were bootstrapped in keystone_service_bootstrap. 222 | - name: Wait for services to be up 223 | delegate_to: "{{ keystone_service_setup_host }}" 224 | ansible.builtin.uri: 225 | url: "{{ item.url }}" 226 | validate_certs: "{{ item.validate_certs }}" 227 | method: "HEAD" 228 | status_code: 300 229 | with_items: 230 | - url: "{{ keystone_service_adminuri }}" 231 | validate_certs: "{{ not keystone_service_adminuri_insecure }}" 232 | - url: "{{ keystone_service_internaluri }}" 233 | validate_certs: "{{ not keystone_service_internaluri_insecure }}" 234 | register: _wait_check 235 | when: 236 | - "_keystone_is_last_play_host" 237 | until: _wait_check is success 238 | retries: 12 239 | delay: 5 240 | 241 | - name: Including osa.service_setup role 242 | ansible.builtin.include_role: 243 | name: openstack.osa.service_setup 244 | apply: 245 | tags: 246 | - keystone-config 247 | - common-service 248 | vars: 249 | _service_adminuri_insecure: "{{ keystone_service_adminuri_insecure }}" 250 | _service_in_ldap: "{{ keystone_service_in_ldap }}" 251 | _service_setup_host: "{{ keystone_service_setup_host }}" 252 | _service_setup_host_python_interpreter: "{{ keystone_service_setup_host_python_interpreter }}" 253 | _project_name: "{{ keystone_service_tenant_name }}" 254 | _project_description: "{{ keystone_service_project_description }}" 255 | _service_region: "{{ keystone_service_region }}" 256 | _service_catalog: 257 | - name: "{{ keystone_service_name }}" 258 | type: "{{ keystone_service_type }}" 259 | description: "{{ keystone_service_description }}" 260 | _service_endpoints: 261 | - interface: "public" 262 | url: "{{ keystone_service_publicuri }}" 263 | service: "{{ keystone_service_name }}" 264 | - interface: "internal" 265 | url: "{{ keystone_service_internaluri }}" 266 | service: "{{ keystone_service_name }}" 267 | - interface: "admin" 268 | url: "{{ keystone_service_adminuri }}" 269 | service: "{{ keystone_service_name }}" 270 | when: 271 | - "_keystone_is_last_play_host" 272 | - "keystone_service_setup | bool" 273 | tags: 274 | - always 275 | 276 | - name: Including keystone_ldap_setup tasks 277 | ansible.builtin.include_tasks: 278 | file: keystone_ldap_setup.yml 279 | apply: 280 | tags: 281 | - keystone-config 282 | when: 283 | - keystone_service_setup | bool 284 | - keystone_ldap != {} 285 | tags: 286 | - keystone-config 287 | 288 | - name: Flush handlers 289 | ansible.builtin.meta: flush_handlers 290 | 291 | - name: Including keystone_idp_setup tasks 292 | ansible.builtin.include_tasks: keystone_idp_setup.yml 293 | args: 294 | apply: 295 | tags: 296 | - keystone-config 297 | when: 298 | - keystone_idp != {} 299 | - _keystone_is_last_play_host 300 | tags: 301 | - always 302 | 303 | - name: Diagnose common problems with keystone deployments 304 | ansible.builtin.command: "{{ keystone_bin }}/keystone-manage doctor" 305 | become: true 306 | become_user: "{{ keystone_system_user_name }}" 307 | register: keystone_doctor 308 | failed_when: not debug and keystone_doctor.rc != 0 309 | changed_when: false 310 | run_once: true 311 | when: 312 | - "_keystone_is_last_play_host" 313 | tags: 314 | - keystone-config 315 | -------------------------------------------------------------------------------- /doc/source/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # This file is execfile()d with the current directory set to its 17 | # containing dir. 18 | # 19 | # Note that not all possible configuration values are present in this 20 | # autogenerated file. 21 | # 22 | # All configuration values have a default; values that are commented out 23 | # serve to show the default. 24 | 25 | import openstackdocstheme 26 | 27 | # If extensions (or modules to document with autodoc) are in another directory, 28 | # add these directories to sys.path here. If the directory is relative to the 29 | # documentation root, use os.path.abspath to make it absolute, like shown here. 30 | # sys.path.insert(0, os.path.abspath('.')) 31 | 32 | # -- General configuration ------------------------------------------------ 33 | 34 | # If your documentation needs a minimal Sphinx version, state it here. 35 | # needs_sphinx = '1.0' 36 | 37 | # Add any Sphinx extension module names here, as strings. They can be 38 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 39 | # ones. 40 | extensions = [ 41 | 'openstackdocstheme', 42 | 'sphinx.ext.autodoc', 43 | 'sphinx.ext.extlinks', 44 | 'sphinxcontrib.rsvgconverter', 45 | ] 46 | 47 | # Add any paths that contain templates here, relative to this directory. 48 | templates_path = ['_templates'] 49 | 50 | # The suffix(es) of source filenames. 51 | # You can specify multiple suffix as a list of string: 52 | # source_suffix = ['.rst', '.md'] 53 | source_suffix = '.rst' 54 | 55 | # The encoding of source files. 56 | # source_encoding = 'utf-8-sig' 57 | 58 | # The master toctree document. 59 | master_doc = 'index' 60 | 61 | # General information about the project. 62 | author = 'OpenStack-Ansible Contributors' 63 | category = 'Miscellaneous' 64 | copyright = '2014-2016, OpenStack-Ansible Contributors' 65 | description = 'OpenStack-Ansible deploys OpenStack environments using Ansible.' 66 | project = 'OpenStack-Ansible' 67 | role_name = 'os_keystone' 68 | target_name = 'openstack-ansible-' + role_name 69 | title = 'OpenStack-Ansible Documentation: ' + role_name + ' role' 70 | 71 | # References variable for substitutions 72 | current_series = openstackdocstheme.ext._get_series_name() 73 | deploy_guide_prefix = "https://docs.openstack.org/project-deploy-guide/openstack-ansible/{}/%s".format(current_series) 74 | 75 | # Format: Reference name: (string containing %s for substitution, linkname) 76 | extlinks = {'deploy_guide': (deploy_guide_prefix, '')} 77 | 78 | # openstackdocstheme options 79 | openstackdocs_repo_name = 'openstack/' + target_name 80 | openstackdocs_pdf_link = True 81 | openstackdocs_bug_project = project.lower() 82 | openstackdocs_bug_tag = '' 83 | 84 | # for a list of supported languages. 85 | # 86 | # This is also used if you do content translation via gettext catalogs. 87 | # Usually you set "language" from the command line for these cases. 88 | language = 'en' 89 | 90 | # There are two options for replacing |today|: either, you set today to some 91 | # non-false value, then it is used: 92 | # today = '' 93 | # Else, today_fmt is used as the format for a strftime call. 94 | # today_fmt = '%B %d, %Y' 95 | 96 | # List of patterns, relative to source directory, that match files and 97 | # directories to ignore when looking for source files. 98 | exclude_patterns = [] 99 | 100 | # The reST default role (used for this markup: `text`) to use for all 101 | # documents. 102 | # default_role = None 103 | 104 | # If true, '()' will be appended to :func: etc. cross-reference text. 105 | # add_function_parentheses = True 106 | 107 | # If true, the current module name will be prepended to all description 108 | # unit titles (such as .. function::). 109 | # add_module_names = True 110 | 111 | # If true, sectionauthor and moduleauthor directives will be shown in the 112 | # output. They are ignored by default. 113 | # show_authors = False 114 | 115 | # The name of the Pygments (syntax highlighting) style to use. 116 | pygments_style = 'native' 117 | 118 | # A list of ignored prefixes for module index sorting. 119 | # modindex_common_prefix = [] 120 | 121 | # If true, keep warnings as "system message" paragraphs in the built documents. 122 | # keep_warnings = False 123 | 124 | # If true, `todo` and `todoList` produce output, else they produce nothing. 125 | todo_include_todos = False 126 | 127 | 128 | # -- Options for HTML output ---------------------------------------------- 129 | 130 | # The theme to use for HTML and HTML Help pages. See the documentation for 131 | # a list of builtin themes. 132 | html_theme = 'openstackdocs' 133 | 134 | # Theme options are theme-specific and customize the look and feel of a theme 135 | # further. For a list of options available for each theme, see the 136 | # documentation. 137 | # html_theme_options = {} 138 | 139 | # Add any paths that contain custom themes here, relative to this directory. 140 | # html_theme_path = [] 141 | 142 | # The name for this set of Sphinx documents. If None, it defaults to 143 | # " v documentation". 144 | # html_title = None 145 | 146 | # A shorter title for the navigation bar. Default is the same as html_title. 147 | # html_short_title = None 148 | 149 | # The name of an image file (relative to this directory) to place at the top 150 | # of the sidebar. 151 | # html_logo = None 152 | 153 | # The name of an image file (within the static path) to use as favicon of the 154 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 155 | # pixels large. 156 | # html_favicon = None 157 | 158 | # Add any paths that contain custom static files (such as style sheets) here, 159 | # relative to this directory. They are copied after the builtin static files, 160 | # so a file named "default.css" will overwrite the builtin "default.css". 161 | html_static_path = ['_static'] 162 | 163 | # Add any extra paths that contain custom files (such as robots.txt or 164 | # .htaccess) here, relative to this directory. These files are copied 165 | # directly to the root of the documentation. 166 | # html_extra_path = [] 167 | 168 | # If true, SmartyPants will be used to convert quotes and dashes to 169 | # typographically correct entities. 170 | # html_use_smartypants = True 171 | 172 | # Custom sidebar templates, maps document names to template names. 173 | # html_sidebars = {} 174 | 175 | # Additional templates that should be rendered to pages, maps page names to 176 | # template names. 177 | # html_additional_pages = {} 178 | 179 | # If false, no module index is generated. 180 | # html_domain_indices = True 181 | 182 | # If false, no index is generated. 183 | # html_use_index = True 184 | 185 | # If true, the index is split into individual pages for each letter. 186 | # html_split_index = False 187 | 188 | # If true, links to the reST sources are added to the pages. 189 | # html_show_sourcelink = True 190 | 191 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 192 | # html_show_sphinx = True 193 | 194 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 195 | # html_show_copyright = True 196 | 197 | # If true, an OpenSearch description file will be output, and all pages will 198 | # contain a tag referring to it. The value of this option must be the 199 | # base URL from which the finished HTML is served. 200 | # html_use_opensearch = '' 201 | 202 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 203 | # html_file_suffix = None 204 | 205 | # Language to be used for generating the HTML full-text search index. 206 | # Sphinx supports the following languages: 207 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' 208 | # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' 209 | # html_search_language = 'en' 210 | 211 | # A dictionary with options for the search language support, empty by default. 212 | # Now only 'ja' uses this config value 213 | # html_search_options = {'type': 'default'} 214 | 215 | # The name of a javascript file (relative to the configuration directory) that 216 | # implements a search results scorer. If empty, the default will be used. 217 | # html_search_scorer = 'scorer.js' 218 | 219 | # Output file base name for HTML help builder. 220 | htmlhelp_basename = target_name + '-docs' 221 | 222 | # -- Options for LaTeX output --------------------------------------------- 223 | 224 | latex_elements = { 225 | # The paper size ('letterpaper' or 'a4paper'). 226 | # 'papersize': 'letterpaper', 227 | 228 | # The font size ('10pt', '11pt' or '12pt'). 229 | # 'pointsize': '10pt', 230 | 231 | # Additional stuff for the LaTeX preamble. 232 | # 'preamble': '', 233 | 234 | # Latex figure (float) alignment 235 | # 'figure_align': 'htbp', 236 | } 237 | 238 | # Grouping the document tree into LaTeX files. List of tuples 239 | # (source start file, target name, title, 240 | # author, documentclass [howto, manual, or own class]). 241 | latex_documents = [ 242 | (master_doc, 'doc-' + target_name + '.tex', 243 | title.replace("_", r"\_"), author, 'manual'), 244 | ] 245 | 246 | # The name of an image file (relative to this directory) to place at the top of 247 | # the title page. 248 | # latex_logo = None 249 | 250 | # For "manual" documents, if this is true, then toplevel headings are parts, 251 | # not chapters. 252 | # latex_use_parts = False 253 | 254 | # If true, show page references after internal links. 255 | # latex_show_pagerefs = False 256 | 257 | # If true, show URL addresses after external links. 258 | # latex_show_urls = False 259 | 260 | # Documents to append as an appendix to all manuals. 261 | # latex_appendices = [] 262 | 263 | # If false, no module index is generated. 264 | # latex_domain_indices = True 265 | 266 | 267 | # -- Options for manual page output --------------------------------------- 268 | 269 | # One entry per manual page. List of tuples 270 | # (source start file, name, description, authors, manual section). 271 | man_pages = [ 272 | (master_doc, target_name, 273 | title, [author], 1) 274 | ] 275 | 276 | # If true, show URL addresses after external links. 277 | # man_show_urls = False 278 | 279 | 280 | # -- Options for Texinfo output ------------------------------------------- 281 | 282 | # Grouping the document tree into Texinfo files. List of tuples 283 | # (source start file, target name, title, author, 284 | # dir menu entry, description, category) 285 | texinfo_documents = [ 286 | (master_doc, target_name, 287 | title, author, project, 288 | description, category), 289 | ] 290 | 291 | # Documents to append as an appendix to all manuals. 292 | # texinfo_appendices = [] 293 | 294 | # If false, no module index is generated. 295 | # texinfo_domain_indices = True 296 | 297 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 298 | # texinfo_show_urls = 'footnote' 299 | 300 | # If true, do not generate a @detailmenu in the "Top" node's menu. 301 | # texinfo_no_detailmenu = False 302 | # -- Options for PDF output -------------------------------------------------- 303 | 304 | pdf_documents = [ 305 | (master_doc, target_name, 306 | title, author) 307 | ] 308 | 309 | locale_dirs = ['locale/'] 310 | --------------------------------------------------------------------------------