This will pull changes from the resource server to the local server. But what if there is no resource server??
Demo:
$ python manage.py resource_sync
2024-09-05 17:55:43,479 DEBUG [] psycopg.pq couldn't import psycopg 'c' implementation: No module named 'psycopg_c'
2024-09-05 17:55:43,964 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.api_documentation.urls
2024-09-05 17:55:43,964 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.api_documentation.urls
2024-09-05 17:55:44,181 DEBUG [] ansible_base.authentication.urls Loaded URLS from ansible_base.authentication.authenticator_plugins.saml
2024-09-05 17:55:44,181 DEBUG [] ansible_base.authentication.urls Loaded URLS from ansible_base.authentication.authenticator_plugins.saml
2024-09-05 17:55:44,208 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.authentication.urls
2024-09-05 17:55:44,208 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.authentication.urls
2024-09-05 17:55:44,208 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Module ansible_base.rest_filters does not specify urls.py
2024-09-05 17:55:44,208 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Module ansible_base.rest_filters does not specify urls.py
2024-09-05 17:55:44,209 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.jwt_consumer.urls
2024-09-05 17:55:44,209 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.jwt_consumer.urls
2024-09-05 17:55:44,212 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.resource_registry.urls
2024-09-05 17:55:44,212 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.resource_registry.urls
2024-09-05 17:55:44,212 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Module ansible_base.rest_pagination does not specify urls.py
2024-09-05 17:55:44,212 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Module ansible_base.rest_pagination does not specify urls.py
2024-09-05 17:55:44,216 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.rbac.urls
2024-09-05 17:55:44,216 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.rbac.urls
2024-09-05 17:55:44,218 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.oauth2_provider.urls
2024-09-05 17:55:44,218 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.oauth2_provider.urls
2024-09-05 17:55:44,220 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.activitystream.urls
2024-09-05 17:55:44,220 DEBUG [] ansible_base.lib.dynamic_config.dynamic_urls Including URLS from ansible_base.activitystream.urls
----- RESOURCE SYNC STARTED -----
>>> shared.authenticator
2024-09-05 17:55:44,341 INFO [] ansible_base.resources_api.rest_client Making get request to http://localhost/api/gateway/v1/service-index/metadata/.
2024-09-05 17:55:44,341 INFO [] ansible_base.resources_api.rest_client Making get request to http://localhost/api/gateway/v1/service-index/metadata/.
2024-09-05 17:55:44,553 DEBUG [] urllib3.connectionpool Starting new HTTP connection (1): localhost:80
Traceback (most recent call last):
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/connection.py", line 174, in _new_conn
conn = connection.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/util/connection.py", line 95, in create_connection
raise err
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/util/connection.py", line 85, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/connectionpool.py", line 715, in urlopen
httplib_response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/connectionpool.py", line 416, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/connection.py", line 244, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File "/usr/lib64/python3.12/http/client.py", line 1336, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib64/python3.12/http/client.py", line 1382, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/lib64/python3.12/http/client.py", line 1331, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib64/python3.12/http/client.py", line 1091, in _send_output
self.send(msg)
File "/usr/lib64/python3.12/http/client.py", line 1035, in send
self.connect()
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/connection.py", line 205, in connect
conn = self._new_conn()
^^^^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/connection.py", line 186, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7fbf3209c9b0>: Failed to establish a new connection: [Errno 111] Connection refused
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/requests/adapters.py", line 486, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/connectionpool.py", line 799, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/urllib3/util/retry.py", line 592, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='localhost', port=80): Max retries exceeded with url: /api/gateway/v1/service-index/metadata/ (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fbf3209c9b0>: Failed to establish a new connection: [Errno 111] Connection refused'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/arominge/repos/awx/django-ansible-base/manage.py", line 22, in <module>
main()
File "/home/arominge/repos/awx/django-ansible-base/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/django/core/management/base.py", line 412, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/django/core/management/base.py", line 458, in execute
output = self.handle(*args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/repos/awx/django-ansible-base/ansible_base/resource_registry/management/commands/resource_sync.py", line 80, in handle
executor.run()
File "/home/arominge/repos/awx/django-ansible-base/ansible_base/resource_registry/tasks/sync.py", line 373, in run
manifest_list = fetch_manifest(resource_type_name, api_client=self.api_client)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/repos/awx/django-ansible-base/ansible_base/resource_registry/tasks/sync.py", line 85, in fetch_manifest
resp_metadata = api_client.get_service_metadata()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/repos/awx/django-ansible-base/ansible_base/resource_registry/rest_client.py", line 127, in get_service_metadata
return self._make_request("get", "metadata/")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/repos/awx/django-ansible-base/ansible_base/resource_registry/rest_client.py", line 106, in _make_request
resp = requests.request(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/arominge/venv/awx/lib64/python3.12/site-packages/requests/adapters.py", line 519, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=80): Max retries exceeded with url: /api/gateway/v1/service-index/metadata/ (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fbf3209c9b0>: Failed to establish a new connection: [Errno 111] Connection refused'))
We have an emerging practice in other places where we check resource_server_defined() and do a silent exit if that returns False. This is because a resource server URL has not been configured, and there are many deployments we expect to run this way. The above traceback does not follow this practice, and it should.
We have a command:
https://github.com/ansible/django-ansible-base/blob/devel/ansible_base/resource_registry/management/commands/resource_sync.py
This will pull changes from the resource server to the local server. But what if there is no resource server??
Demo:
We have an emerging practice in other places where we check
resource_server_defined()
and do a silent exit if that returnsFalse
. This is because a resource server URL has not been configured, and there are many deployments we expect to run this way. The above traceback does not follow this practice, and it should.Notably, AWX will run this every 15 minutes:
https://github.com/ansible/awx/blob/79684ab6033fb999ddfcf8e3ef7c2e4c7d806e39/awx/main/tasks/system.py#L979
And that would result in the above error. Still, even if it gives that error, no harm. But we would prefer a simple debug-level message and exit.