diff --git a/ansible_ai_connect/main/settings/base.py b/ansible_ai_connect/main/settings/base.py index 313918ec6..ab6f00b73 100644 --- a/ansible_ai_connect/main/settings/base.py +++ b/ansible_ai_connect/main/settings/base.py @@ -192,6 +192,8 @@ AUTHZ_SSO_TOKEN_SERVICE_TIMEOUT = float(os.getenv("AUTHZ_SSO_TOKEN_SERVICE_TIMEOUT") or "1.0") AUTHZ_SSO_TOKEN_SERVICE_RETRY_COUNT = int(os.getenv("AUTHZ_SSO_TOKEN_SERVICE_RETRY_COUNT") or "3") AUTHZ_AMS_SERVICE_RETRY_COUNT = int(os.getenv("AMS_SERVICE_RETRY_COUNT") or "3") +AUTHZ_AMS_SERVICE_TIMEOUT = float(os.getenv("AUTHZ_AMS_SERVICE_TIMEOUT") or "2.0") + t_deployment_mode = Literal["saas", "upstream", "onprem"] DEPLOYMENT_MODE: t_deployment_mode = cast( diff --git a/ansible_ai_connect/users/authz_checker.py b/ansible_ai_connect/users/authz_checker.py index a2e68eb84..62dea4d7b 100644 --- a/ansible_ai_connect/users/authz_checker.py +++ b/ansible_ai_connect/users/authz_checker.py @@ -195,6 +195,7 @@ def __init__(self, client_id, client_secret, sso_server, api_server): self._api_server = api_server self._ams_org_cache = {} self.retries = settings.AUTHZ_AMS_SERVICE_RETRY_COUNT + self.timeout = settings.AUTHZ_AMS_SERVICE_TIMEOUT if self._api_server.startswith("https://api.stage.openshift.com"): proxy = {"https": "http://squid.corp.redhat.com:3128"} @@ -235,7 +236,7 @@ def get_request(): return self._session.get( self._api_server + "/api/accounts_mgmt/v1/organizations", params=params, - timeout=0.8, + timeout=self.timeout, ) r = get_request() @@ -272,7 +273,7 @@ def self_test(self): r = self._session.get( # A _basic_ call that needs no parameters. self._api_server + "/api/accounts_mgmt/v1/metrics", - timeout=0.8, + timeout=self.timeout, ) r.raise_for_status() @@ -290,7 +291,7 @@ def check(self, user_id: str, username: str, organization_id: int) -> bool: # Organization has not yet been created in AMS, either the organization # is too recent (sync is done every 1h), or the organization has no AMS related # services (e.g Ansible, OpenShift, cloud.r.c) and so is not synchronized. - logger.warning(f"Organization not found in AMS, organization_id={organization_id}") + logger.warning(f"Organization can't be found in AMS, organization_id={organization_id}") return False params = { @@ -303,7 +304,7 @@ def check(self, user_id: str, username: str, organization_id: int) -> bool: r = self._session.get( self._api_server + "/api/accounts_mgmt/v1/subscriptions", params=params, - timeout=0.8, + timeout=self.timeout, ) except (requests.exceptions.Timeout, requests.exceptions.ConnectionError): logger.error(self.ERROR_AMS_CONNECTION_TIMEOUT) @@ -330,7 +331,7 @@ def rh_user_is_org_admin(self, username: str, organization_id: int): # Organization has not yet been created in AMS, either the organization # is too recent (sync is done every 1h), or the organization has no AMS related # services (e.g Ansible, OpenShift, cloud.r.c) and so is not synchronized. - logger.warning(f"Organization not found in AMS, organization_id={organization_id}") + logger.warning(f"Organization can't be found in AMS, organization_id={organization_id}") return False params = {"search": f"account.username = '{username}' AND organization.id='{ams_org_id}'"} @@ -340,7 +341,7 @@ def rh_user_is_org_admin(self, username: str, organization_id: int): r = self._session.get( self._api_server + "/api/accounts_mgmt/v1/role_bindings", params=params, - timeout=0.8, + timeout=self.timeout, ) except (requests.exceptions.Timeout, requests.exceptions.ConnectionError): logger.error(self.ERROR_AMS_CONNECTION_TIMEOUT) @@ -375,7 +376,7 @@ def rh_org_has_subscription(self, organization_id: int) -> bool: # Organization has not yet been created in AMS, either the organization # is too recent (sync is done every 1h), or the organization has no AMS related # services (e.g Ansible, OpenShift, cloud.r.c) and so is not synchronized. - logger.warning(f"Organization not found in AMS, organization_id={organization_id}") + logger.warning(f"Organization can't be found in AMS, organization_id={organization_id}") return False # Check cache @@ -406,7 +407,7 @@ def get_request(): f"/api/accounts_mgmt/v1/organizations/{ams_org_id}/quota_cost" ), params=params, - timeout=0.8, + timeout=2.0, ) r = get_request() diff --git a/ansible_ai_connect/users/tests/test_authz_checker.py b/ansible_ai_connect/users/tests/test_authz_checker.py index f4408fa9b..2e601d328 100644 --- a/ansible_ai_connect/users/tests/test_authz_checker.py +++ b/ansible_ai_connect/users/tests/test_authz_checker.py @@ -214,7 +214,7 @@ def test_ams_get_ams_org(self): checker._session.get.assert_called_with( "https://some-api.server.host/api/accounts_mgmt/v1/organizations", params={"search": "external_id='123'"}, - timeout=0.8, + timeout=2.0, ) # Ensure the second call is cached @@ -287,7 +287,7 @@ def test_ams_check(self): "search": "plan.id = 'AnsibleWisdom' AND status = 'Active' " "AND creator.username = 'my_name' AND organization_id='qwe'" }, - timeout=0.8, + timeout=2.0, ) def test_ams_check_multiple_seats(self): @@ -309,7 +309,7 @@ def test_ams_check_multiple_seats(self): "search": "plan.id = 'AnsibleWisdom' AND status = 'Active' " "AND creator.username = 'my_name' AND organization_id='qwe'" }, - timeout=0.8, + timeout=2.0, ) def test_ams_check_with_500_status_code(self): @@ -369,7 +369,7 @@ def test_rh_user_is_org_admin(self): checker._session.get.assert_called_with( "https://some-api.server.host/api/accounts_mgmt/v1/role_bindings", params={"search": "account.username = 'user' AND organization.id='123'"}, - timeout=0.8, + timeout=2.0, ) def test_rh_user_is_org_admin_when_ams_fails(self): @@ -425,7 +425,7 @@ def test_is_not_org_admin(self): checker._session.get.assert_called_with( "https://some-api.server.host/api/accounts_mgmt/v1/role_bindings", params={"search": "account.username = 'user' AND organization.id='123'"}, - timeout=0.8, + timeout=2.0, ) def test_user_has_no_role(self): @@ -505,7 +505,7 @@ def test_rh_org_has_subscription(self): "/api/accounts_mgmt/v1/organizations/rdgdfhbrdb/quota_cost" ), params={"search": "quota_id LIKE 'seat|ansible.wisdom%'"}, - timeout=0.8, + timeout=2.0, ) # Ensure the second call is cached @@ -586,7 +586,7 @@ def test_is_org_not_lightspeed_subscriber(self): "/api/accounts_mgmt/v1/organizations/rdgdfhbrdb/quota_cost" ), params={"search": "quota_id LIKE 'seat|ansible.wisdom%'"}, - timeout=0.8, + timeout=2.0, ) def test_rh_org_has_subscription_timeout(self):