Skip to content

Commit

Permalink
feat: Check connection
Browse files Browse the repository at this point in the history
First, the internet connection is tested. The DNS is queried, then a connection is established to the resolved IP. If resolving fails, a hard-coded IP is tried for production or staging. In case of either failure, DNS query for www.redhat.com and connection to 1.1.1.1 is tried.
  • Loading branch information
Glutexo committed Dec 18, 2024
1 parent 1f7879c commit ca48f81
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
78 changes: 77 additions & 1 deletion insights/client/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"""
from __future__ import print_function
from __future__ import absolute_import

import socket

import requests
import os
import six
Expand Down Expand Up @@ -365,7 +368,6 @@ def _legacy_test_urls(self, url, method):
if test_req.status_code in (200, 201):
return True
else:
logger.error(" Failed.")
return False
except REQUEST_FAILED_EXCEPTIONS as exc:
last_ex = exc
Expand Down Expand Up @@ -474,6 +476,65 @@ def _dump_urls(self):

logger.info("")

def _test_dns(self, hostname):
port = requests.utils.DEFAULT_PORTS["http"]

if self.config.verbose:
logger.info(" Checking DNS for %s:%s...", hostname, port)
else:
logger.info(" Resolving %s...", hostname)

try:
with socket.create_connection((hostname, port)) as conn:
conn_ip, conn_port = conn.getpeername()
logger.debug(" Resolved as: %s:%s", conn_ip, conn_port)
except socket.gaierror as exc:
logger.debug(" socket.gaierror: %s", exc)
logger.error(" Can't resolve the domain name.")
logger.error(" FAILED.")
logger.error("")
return None

logger.info(" SUCCESS.")
logger.info("")
return conn_ip

def _test_ip(self, ip):
port = requests.utils.DEFAULT_PORTS["http"]

try:
if self.config.verbose:
logger.info(" Connecting to %s:%s...", ip, port)
else:
logger.info(" Connecting to %s...", ip)

with socket.create_connection((ip, port)) as conn:
logger.info(" SUCCESS.")
logger.info("")
conn.close()
except socket.timeout:
logger.error(" Connection to %s:%s timed out.", ip, port)
logger.error(" FAILED.")
logger.info("")
return False
except socket.error:
logger.error(" Can't connect to %s:%s.", ip, port)
logger.error(" FAILED.")
logger.info("")
return False

return True

def _test_connection(self, hostname, fallback_ip=None):
resolved_ip = self._test_dns(hostname)

for ip in filter(None, [resolved_ip, fallback_ip]):
success = self._test_ip(ip)
if success:
return resolved_ip, ip

return resolved_ip, None

def test_connection(self, rc=0):
"""
Test connection to Red Hat
Expand All @@ -487,6 +548,21 @@ def test_connection(self, rc=0):
logger.info("Running Connection Tests...")
logger.info("")

base_url_hostname = urlparse(self.base_url).hostname
if base_url_hostname.endswith("redhat.com"):
if base_url_hostname.endswith("stage.redhat.com"):
base_url_ip = constants.insights_ip_stage
else:
base_url_ip = constants.insights_ip_prod
else:
base_url_ip = None

resolved_base_url_ip, success_base_url_ip = self._test_connection(base_url_hostname, base_url_ip)
if not resolved_base_url_ip or not success_base_url_ip:
resolved_fallback_ip, success_fallback_ip = self._test_connection("www.redhat.com", constants.stable_public_ip)
logger.debug("dns %s, conn %s", resolved_fallback_ip, success_fallback_ip)
return False

for description, url, method in [
("Uploading a file to Ingress", self.upload_url, "POST"),
("Getting hosts from Inventory", self.inventory_url + "/hosts", "GET"),
Expand Down
5 changes: 5 additions & 0 deletions insights/client/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ class InsightsConstants(object):
default_payload_log = os.path.join(log_dir, app_name + '-payload.log')
custom_network_log_level = 11
default_sed_file = os.path.join(default_conf_dir, '.exp.sed')
# base_url = 'cert-api.access.redhat.com/r/insights/platform'
base_url = 'cert-api.access.redhat.com/r/insights/platform'
# legacy_base_url = 'cert-api.access.redhat.com/r/insights'
legacy_base_url = 'cert-api.access.redhat.com/r/insights'
unregistered_files = [os.path.join(default_conf_dir, '.unregistered'),
os.path.join(simple_find_replace_dir, '.unregistered')]
Expand Down Expand Up @@ -90,3 +92,6 @@ class InsightsConstants(object):
rhsm_facts_file = os.path.join(os.sep, 'etc', 'rhsm', 'facts', 'insights-client.facts')
# In MB
archive_filesize_max = 100
insights_ip_prod = "23.37.45.238"
insights_ip_stage = "23.53.5.13"
stable_public_ip = "1.1.1.1" # Public CloudFlare DNS

0 comments on commit ca48f81

Please sign in to comment.