Skip to content

Commit e3c1f79

Browse files
committed
feat: Check connection
In case of DNS failure. 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 a public CloudFlare URL one.one.one.one and its IP 1.1.1.1 is tried.
1 parent c393d5b commit e3c1f79

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

insights/client/connection.py

+63-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from __future__ import print_function
55
from __future__ import absolute_import
66
import requests
7+
import socket
78
import os
89
import six
910
import json
@@ -18,10 +19,12 @@
1819
try:
1920
# python 2
2021
from urlparse import urlparse
22+
from urlparse import urlunparse
2123
from urllib import quote
2224
except ImportError:
2325
# python 3
2426
from urllib.parse import urlparse
27+
from urllib.parse import urlunparse
2528
from urllib.parse import quote
2629
from .utilities import (determine_hostname,
2730
generate_machine_id,
@@ -74,6 +77,26 @@ def _api_request_failed(exception, message='The Insights API could not be reache
7477
logger.error(message)
7578

7679

80+
def _is_dns_error(exception):
81+
while exception:
82+
if isinstance(exception, socket.gaierror):
83+
return True
84+
85+
exception = exception.__context__
86+
87+
return False
88+
89+
90+
def _fallback_ip(hostname):
91+
if hostname.endswith("redhat.com"):
92+
if hostname.endswith("stage.redhat.com"):
93+
return constants.insights_ip_stage
94+
else:
95+
return constants.insights_ip_prod
96+
else:
97+
return None
98+
99+
77100
class InsightsConnection(object):
78101

79102
"""
@@ -369,7 +392,6 @@ def _legacy_test_urls(self, url, method):
369392
if test_req.status_code in (200, 201):
370393
return True
371394
else:
372-
logger.error(" Failed.")
373395
return False
374396
except REQUEST_FAILED_EXCEPTIONS as exc:
375397
last_ex = exc
@@ -492,6 +514,22 @@ def test_connection(self, rc=0):
492514
logger.info("Running Connection Tests...")
493515
logger.info("")
494516

517+
# base_url_hostname = urlparse(self.base_url).hostname
518+
# if base_url_hostname.endswith("redhat.com"):
519+
# if base_url_hostname.endswith("stage.redhat.com"):
520+
# base_url_ip = constants.insights_ip_stage
521+
# else:
522+
# base_url_ip = constants.insights_ip_prod
523+
# else:
524+
# base_url_ip = None
525+
#
526+
# resolved_base_url_ip, success_base_url_ip = self._test_connection(base_url_hostname, base_url_ip)
527+
# if not resolved_base_url_ip or not success_base_url_ip:
528+
# resolved_fallback_ip, success_fallback_ip = self._test_connection("www.redhat.com", constants.stable_public_ip)
529+
# logger.debug("dns %s, conn %s", resolved_fallback_ip, success_fallback_ip)
530+
# return False
531+
532+
last_ex = None
495533
for description, url, method in [
496534
("Uploading a file to Ingress", self.upload_url, "POST"),
497535
("Getting hosts from Inventory", self.inventory_url + "/hosts", "GET"),
@@ -520,6 +558,30 @@ def test_connection(self, rc=0):
520558
logger.error(" Additional information may be in %s" % self.config.logging_file)
521559
logger.error("")
522560

561+
if _is_dns_error(last_ex):
562+
parsed_url = urlparse(url)
563+
logger.error(" Could not resolve %s.", parsed_url.hostname)
564+
fallback = [constants.stable_public_url, constants.stable_public_ip]
565+
ip = _fallback_ip(parsed_url.hostname)
566+
if ip:
567+
fallback = [ip] + fallback
568+
569+
for fallback_url in fallback:
570+
parsed_ip_url = urlunparse((parsed_url.scheme, fallback_url, "/", "", "", ""))
571+
try:
572+
logger.info(' Testing %s', parsed_ip_url)
573+
log_prefix = " "
574+
log_level = NETWORK if self.config.verbose else logging.DEBUG
575+
self.get(parsed_ip_url, log_prefix=log_prefix, log_level=log_level, verify=False)
576+
except REQUEST_FAILED_EXCEPTIONS as exc:
577+
logger.debug(" Caught %s: %s", type(exc).__name__, exc)
578+
logger.error(" Failed.")
579+
else:
580+
logger.info(" SUCCESS.")
581+
break
582+
else:
583+
logger.info(" FAILED.")
584+
523585
return 1
524586

525587
def handle_fail_rcs(self, req):

insights/client/constants.py

+4
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,7 @@ class InsightsConstants(object):
9090
rhsm_facts_file = os.path.join(os.sep, 'etc', 'rhsm', 'facts', 'insights-client.facts')
9191
# In MB
9292
archive_filesize_max = 100
93+
insights_ip_prod = "23.37.45.238"
94+
insights_ip_stage = "23.53.5.13"
95+
stable_public_url = "one.one.one.one" # Public CloudFlare DNS
96+
stable_public_ip = "1.1.1.1" # Public CloudFlare DNS

0 commit comments

Comments
 (0)