diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/run.yml | 19 | ||||
| -rw-r--r-- | tests/templates/globals-default.j2 | 11 | ||||
| -rw-r--r-- | tests/templates/inventory.j2 | 11 | ||||
| -rw-r--r-- | tests/templates/keystone-federation/attribute_mapping.json | 42 | ||||
| -rw-r--r-- | tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.client.j2 | 4 | ||||
| -rw-r--r-- | tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.conf.j2 | 1 | ||||
| -rw-r--r-- | tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.provider.j2 | 324 | ||||
| -rw-r--r-- | tests/templates/mariadb-overrides.j2 | 1 | ||||
| -rw-r--r-- | tests/testinfra/test_horizon.py | 51 |
9 files changed, 458 insertions, 6 deletions
diff --git a/tests/run.yml b/tests/run.yml index 57a3de61b..78d34d8eb 100644 --- a/tests/run.yml +++ b/tests/run.yml @@ -164,6 +164,8 @@ - neutron - nova - bifrost + - keystone-httpd/federation/oidc/metadata + - keystone-httpd/federation/oidc/attribute_maps - name: Generate configuration files template: @@ -210,6 +212,19 @@ - src: "tests/templates/tenks-deploy-config.yml.j2" dest: "{{ ansible_env.HOME }}/tenks.yml" when: "{{ scenario == 'ironic' }}" + # keystone-federation config + - src: "tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.conf.j2" + dest: "/etc/kolla/config/keystone-httpd/federation/oidc/metadata/idp.example.org%2Frealms%2Fexample.conf" + when: "{{ scenario == 'federation' }}" + - src: "tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.provider.j2" + dest: "/etc/kolla/config/keystone-httpd/federation/oidc/metadata/idp.example.org%2Frealms%2Fexample.provider" + when: "{{ scenario == 'federation' }}" + - src: "tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.client.j2" + dest: "/etc/kolla/config/keystone-httpd/federation/oidc/metadata/idp.example.org%2Frealms%2Fexample.client" + when: "{{ scenario == 'federation' }}" + - src: "tests/templates/keystone-federation/attribute_mapping.json" + dest: "/etc/kolla/config/keystone-httpd/federation/oidc/attribute_maps/attribute_mapping.json" + when: "{{ scenario == 'federation' }}" when: item.when | default(true) - block: @@ -788,6 +803,10 @@ executable: /bin/bash chdir: "{{ kolla_ansible_src_dir }}" + - name: Import role kolla-ansible-check + import_role: + name: kolla-ansible-check + - hosts: primary any_errors_fatal: true tasks: diff --git a/tests/templates/globals-default.j2 b/tests/templates/globals-default.j2 index b722f7dba..feb6a6054 100644 --- a/tests/templates/globals-default.j2 +++ b/tests/templates/globals-default.j2 @@ -284,6 +284,17 @@ enable_valkey: "yes" {% if scenario == "federation" %} enable_keystone_federation: true +keystone_identity_providers: + - name: "example_provider" + openstack_domain: "Default" + protocol: "openid" + identifier: "https://idp.example.org/realms/example" + public_name: "Example Provider" + attribute_mapping: "sso_oidc_mapping" + metadata_folder: "/etc/kolla/config/keystone-httpd/federation/oidc/metadata" +keystone_identity_mappings: + - name: "sso_oidc_mapping" + file: "/etc/kolla/config/keystone-httpd/federation/oidc/attribute_maps/attribute_mapping.json" {% endif %} mariadb_monitor_read_only_interval: "30000" diff --git a/tests/templates/inventory.j2 b/tests/templates/inventory.j2 index 1dc739c78..e2f4b3dcc 100644 --- a/tests/templates/inventory.j2 +++ b/tests/templates/inventory.j2 @@ -255,17 +255,16 @@ common {% if is_upgrade | bool %} [kolla-logs:children] common -{% endif %} [kolla-toolbox:children] common +{% endif %} [kolla_logs:children] -control -network -compute -storage -monitoring +common + +[kolla_toolbox:children] +common [opensearch:children] control diff --git a/tests/templates/keystone-federation/attribute_mapping.json b/tests/templates/keystone-federation/attribute_mapping.json new file mode 100644 index 000000000..022cbafd2 --- /dev/null +++ b/tests/templates/keystone-federation/attribute_mapping.json @@ -0,0 +1,42 @@ +[ + { + "local": [ + { + "user": { + "name": "{0}", + "email": "{1}", + "domain": { + "name": "{2}" + } + }, + "domain": { + "name": "{2}" + }, + "projects": [ + { + "name": "{3}", + "roles": [ + { + "name": "member" + } + ] + } + ] + } + ], + "remote": [ + { + "type": "OIDC-preferred_username" + }, + { + "type": "OIDC-email" + }, + { + "type": "OIDC-openstack-user-domain" + }, + { + "type": "OIDC-openstack-default-project" + } + ] + } +] diff --git a/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.client.j2 b/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.client.j2 new file mode 100644 index 000000000..253898f3a --- /dev/null +++ b/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.client.j2 @@ -0,0 +1,4 @@ +{ + "client_id":"keystone", + "client_secret":"example_secret" +} diff --git a/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.conf.j2 b/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.conf.j2 new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.conf.j2 @@ -0,0 +1 @@ +{} diff --git a/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.provider.j2 b/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.provider.j2 new file mode 100644 index 000000000..c45eb26f9 --- /dev/null +++ b/tests/templates/keystone-federation/idp.example.org%2Frealms%2Fexample.provider.j2 @@ -0,0 +1,324 @@ +{ + "issuer": "https://idp.example.org/realms/example", + "authorization_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/auth", + "token_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/token", + "introspection_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/token/introspect", + "userinfo_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/userinfo", + "end_session_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/logout", + "frontchannel_logout_session_supported": true, + "frontchannel_logout_supported": true, + "jwks_uri": "https://idp.example.org/realms/example/protocol/openid-connect/certs", + "check_session_iframe": "https://idp.example.org/realms/example/protocol/openid-connect/login-status-iframe.html", + "grant_types_supported": [ + "authorization_code", + "implicit", + "refresh_token", + "password", + "client_credentials", + "urn:openid:params:grant-type:ciba", + "urn:ietf:params:oauth:grant-type:device_code" + ], + "acr_values_supported": [ + "0", + "1" + ], + "response_types_supported": [ + "code", + "none", + "id_token", + "token", + "id_token token", + "code id_token", + "code token", + "code id_token token" + ], + "subject_types_supported": [ + "public", + "pairwise" + ], + "prompt_values_supported": [ + "none", + "login", + "consent" + ], + "id_token_signing_alg_values_supported": [ + "PS384", + "RS384", + "EdDSA", + "ES384", + "HS256", + "HS512", + "ES256", + "RS256", + "HS384", + "ES512", + "PS256", + "PS512", + "RS512" + ], + "id_token_encryption_alg_values_supported": [ + "ECDH-ES+A256KW", + "ECDH-ES+A192KW", + "ECDH-ES+A128KW", + "RSA-OAEP", + "RSA-OAEP-256", + "RSA1_5", + "ECDH-ES" + ], + "id_token_encryption_enc_values_supported": [ + "A256GCM", + "A192GCM", + "A128GCM", + "A128CBC-HS256", + "A192CBC-HS384", + "A256CBC-HS512" + ], + "userinfo_signing_alg_values_supported": [ + "PS384", + "RS384", + "EdDSA", + "ES384", + "HS256", + "HS512", + "ES256", + "RS256", + "HS384", + "ES512", + "PS256", + "PS512", + "RS512", + "none" + ], + "userinfo_encryption_alg_values_supported": [ + "ECDH-ES+A256KW", + "ECDH-ES+A192KW", + "ECDH-ES+A128KW", + "RSA-OAEP", + "RSA-OAEP-256", + "RSA1_5", + "ECDH-ES" + ], + "userinfo_encryption_enc_values_supported": [ + "A256GCM", + "A192GCM", + "A128GCM", + "A128CBC-HS256", + "A192CBC-HS384", + "A256CBC-HS512" + ], + "request_object_signing_alg_values_supported": [ + "PS384", + "RS384", + "EdDSA", + "ES384", + "HS256", + "HS512", + "ES256", + "RS256", + "HS384", + "ES512", + "PS256", + "PS512", + "RS512", + "none" + ], + "request_object_encryption_alg_values_supported": [ + "ECDH-ES+A256KW", + "ECDH-ES+A192KW", + "ECDH-ES+A128KW", + "RSA-OAEP", + "RSA-OAEP-256", + "RSA1_5", + "ECDH-ES" + ], + "request_object_encryption_enc_values_supported": [ + "A256GCM", + "A192GCM", + "A128GCM", + "A128CBC-HS256", + "A192CBC-HS384", + "A256CBC-HS512" + ], + "response_modes_supported": [ + "query", + "fragment", + "form_post", + "query.jwt", + "fragment.jwt", + "form_post.jwt", + "jwt" + ], + "registration_endpoint": "https://idp.example.org/realms/example/clients-registrations/openid-connect", + "token_endpoint_auth_methods_supported": [ + "private_key_jwt", + "client_secret_basic", + "client_secret_post", + "tls_client_auth", + "client_secret_jwt" + ], + "token_endpoint_auth_signing_alg_values_supported": [ + "PS384", + "RS384", + "EdDSA", + "ES384", + "HS256", + "HS512", + "ES256", + "RS256", + "HS384", + "ES512", + "PS256", + "PS512", + "RS512" + ], + "introspection_endpoint_auth_methods_supported": [ + "private_key_jwt", + "client_secret_basic", + "client_secret_post", + "tls_client_auth", + "client_secret_jwt" + ], + "introspection_endpoint_auth_signing_alg_values_supported": [ + "PS384", + "RS384", + "EdDSA", + "ES384", + "HS256", + "HS512", + "ES256", + "RS256", + "HS384", + "ES512", + "PS256", + "PS512", + "RS512" + ], + "authorization_signing_alg_values_supported": [ + "PS384", + "RS384", + "EdDSA", + "ES384", + "HS256", + "HS512", + "ES256", + "RS256", + "HS384", + "ES512", + "PS256", + "PS512", + "RS512" + ], + "authorization_encryption_alg_values_supported": [ + "ECDH-ES+A256KW", + "ECDH-ES+A192KW", + "ECDH-ES+A128KW", + "RSA-OAEP", + "RSA-OAEP-256", + "RSA1_5", + "ECDH-ES" + ], + "authorization_encryption_enc_values_supported": [ + "A256GCM", + "A192GCM", + "A128GCM", + "A128CBC-HS256", + "A192CBC-HS384", + "A256CBC-HS512" + ], + "claims_supported": [ + "aud", + "sub", + "iss", + "auth_time", + "name", + "given_name", + "family_name", + "preferred_username", + "email", + "acr" + ], + "claim_types_supported": [ + "normal" + ], + "claims_parameter_supported": true, + "scopes_supported": [ + "openid", + "roles", + "acr", + "profile", + "address", + "basic", + "offline_access", + "groups", + "email", + "phone", + "service_account", + "web-origins", + "microprofile-jwt" + ], + "request_parameter_supported": true, + "request_uri_parameter_supported": true, + "require_request_uri_registration": true, + "code_challenge_methods_supported": [ + "plain", + "S256" + ], + "tls_client_certificate_bound_access_tokens": true, + "revocation_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/revoke", + "revocation_endpoint_auth_methods_supported": [ + "private_key_jwt", + "client_secret_basic", + "client_secret_post", + "tls_client_auth", + "client_secret_jwt" + ], + "revocation_endpoint_auth_signing_alg_values_supported": [ + "PS384", + "RS384", + "EdDSA", + "ES384", + "HS256", + "HS512", + "ES256", + "RS256", + "HS384", + "ES512", + "PS256", + "PS512", + "RS512" + ], + "backchannel_logout_supported": true, + "backchannel_logout_session_supported": true, + "device_authorization_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/auth/device", + "backchannel_token_delivery_modes_supported": [ + "poll", + "ping" + ], + "backchannel_authentication_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/ext/ciba/auth", + "backchannel_authentication_request_signing_alg_values_supported": [ + "PS384", + "RS384", + "EdDSA", + "ES384", + "ES256", + "RS256", + "ES512", + "PS256", + "PS512", + "RS512" + ], + "require_pushed_authorization_requests": false, + "pushed_authorization_request_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/ext/par/request", + "mtls_endpoint_aliases": { + "token_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/token", + "revocation_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/revoke", + "introspection_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/token/introspect", + "device_authorization_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/auth/device", + "registration_endpoint": "https://idp.example.org/realms/example/clients-registrations/openid-connect", + "userinfo_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/userinfo", + "pushed_authorization_request_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/ext/par/request", + "backchannel_authentication_endpoint": "https://idp.example.org/realms/example/protocol/openid-connect/ext/ciba/auth" + }, + "authorization_response_iss_parameter_supported": true +} + diff --git a/tests/templates/mariadb-overrides.j2 b/tests/templates/mariadb-overrides.j2 index e87de7108..05dcd1c12 100644 --- a/tests/templates/mariadb-overrides.j2 +++ b/tests/templates/mariadb-overrides.j2 @@ -3,3 +3,4 @@ max_connections = 300 innodb_buffer_pool_size = 1024M max_heap_table_size = 32M tmp_table_size = 32M +wsrep_slave_threads = 8 diff --git a/tests/testinfra/test_horizon.py b/tests/testinfra/test_horizon.py index 9b27e4700..0c1527a9d 100644 --- a/tests/testinfra/test_horizon.py +++ b/tests/testinfra/test_horizon.py @@ -12,13 +12,17 @@ # License for the specific language governing permissions and limitations # under the License. +import os +import pytest import time import yaml from pathlib import Path from selenium.common.exceptions import TimeoutException +from selenium.common.exceptions import WebDriverException from selenium import webdriver from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import WebDriverWait home = Path.home() @@ -122,3 +126,50 @@ def test_horizon_login(host): raise e finally: driver.quit() + + +@pytest.mark.skipif( + os.getenv("SCENARIO") != "federation", + reason=( + "Current scenario is not federation. " + "Not running test." + ) +) +def test_horizon_login_federation(host): + + firefox_options = webdriver.FirefoxOptions() + selenium_url = host.environment().get( + 'SELENIUM_REMOTE_URL', 'http://localhost:4500/wd/hub') + + driver = webdriver.Remote( + command_executor=selenium_url, + options=firefox_options) + + horizon_proto = host.environment().get('HORIZON_PROTO') + horizon_url = horizon_proto + "://192.0.2.10" + login_url = '/'.join(( + horizon_url, + 'auth', + 'login')) + + try: + driver.get(login_url) + auth_type_field = driver.find_element(By.ID, 'id_auth_type') + select = Select(auth_type_field) + select.select_by_value('example_provider_openid') + button = driver.find_element(By.CSS_SELECTOR, '.btn-primary') + + try: + button.click() + except WebDriverException as e: + if "Reached error page" in str(e) or "dnsNotFound" in str(e): + pass # This is expected behavior, so we ignore the exception + else: + raise # Re-raise if it failed for an unexpected reason + + assert "idp.example.org" in driver.current_url # nosec B101 + + except TimeoutException as e: + raise e + finally: + driver.quit() |
