Skip to content

Commit ed67944

Browse files
committed
refactor(logging): add additional debug stmts
1 parent bccb7d2 commit ed67944

16 files changed

+154
-22
lines changed

redshift_connector/__init__.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@
3838
PGVarchar,
3939
)
4040
from redshift_connector.redshift_property import RedshiftProperty
41-
from redshift_connector.utils import DriverInfo
41+
from redshift_connector.utils import (
42+
DriverInfo,
43+
make_divider_block,
44+
mask_secure_info_in_props,
45+
)
4246
from redshift_connector.utils.type_utils import (
4347
BIGINT,
4448
BIGINTEGER,
@@ -88,6 +92,7 @@
8892
from .version import __version__
8993

9094
logging.getLogger(__name__).addHandler(logging.NullHandler())
95+
_logger: logging.Logger = logging.getLogger(__name__)
9196

9297
# Copyright (c) 2007-2009, Mathieu Fenniak
9398
# Copyright (c) The Contributors
@@ -296,6 +301,12 @@ def connect(
296301
role_arn=role_arn,
297302
)
298303

304+
_logger.debug(make_divider_block())
305+
_logger.debug("Initializing Connection object")
306+
_logger.debug(make_divider_block())
307+
_logger.debug(mask_secure_info_in_props(info).__str__())
308+
_logger.debug(make_divider_block())
309+
299310
return Connection(
300311
user=info.user_name,
301312
host=info.host,

redshift_connector/auth/aws_credentials_provider.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def get_credentials(
5757
try:
5858
self.refresh()
5959
except Exception as e:
60-
_logger.error("refresh failed: {}".format(str(e)))
60+
_logger.error("Refreshing IdP credentials failed: {}".format(str(e)))
6161
raise InterfaceError(e)
6262

6363
credentials: typing.Union[AWSDirectCredentialsHolder, AWSProfileCredentialsHolder] = self.cache[key]

redshift_connector/core.py

+14
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
ii_pack,
7272
iii_pack,
7373
int_array_recv,
74+
make_divider_block,
7475
numeric_in,
7576
numeric_in_binary,
7677
)
@@ -493,6 +494,11 @@ def __init__(
493494
if credentials_provider:
494495
init_params["plugin_name"] = credentials_provider
495496

497+
_logger.debug(make_divider_block())
498+
_logger.debug("Establishing a connection")
499+
_logger.debug(init_params)
500+
_logger.debug(make_divider_block())
501+
496502
for k, v in tuple(init_params.items()):
497503
if isinstance(v, str):
498504
init_params[k] = v.encode("utf8")
@@ -559,6 +565,9 @@ def __init__(
559565
self._usock.sendall(ii_pack(8, 80877103))
560566
resp: bytes = self._usock.recv(1)
561567
if resp != b"S":
568+
_logger.debug(
569+
"Server response code when attempting to establish ssl connection: {!r}".format(resp)
570+
)
562571
raise InterfaceError("Server refuses SSL")
563572

564573
if sslmode == "verify-ca":
@@ -642,6 +651,7 @@ def __init__(
642651

643652
code = None
644653
self.error: typing.Optional[Exception] = None
654+
_logger.debug("Sending start-up message")
645655
# When driver send the start-up message to database, DB will respond multi messages to driver
646656
# whose format is same with the message that driver send to DB.
647657
while code not in (READY_FOR_QUERY, ERROR_RESPONSE):
@@ -661,6 +671,7 @@ def __init__(
661671
self._client_protocol_version > ClientProtocolVersion.BASE_SERVER
662672
and not (b"server_protocol_version", str(self._client_protocol_version).encode()) in self.parameter_statuses
663673
):
674+
_logger.debug("Server_protocol_version not received from server")
664675
self._client_protocol_version = ClientProtocolVersion.BASE_SERVER
665676
self._enable_protocol_based_conversion_funcs()
666677

@@ -1027,6 +1038,7 @@ def handle_ROW_DESCRIPTION(self: "Connection", data, cursor: Cursor) -> None:
10271038
raise InterfaceError("Prepared Statement is missing row description")
10281039

10291040
count: int = h_unpack(data)[0]
1041+
_logger.debug("field count={}".format(count))
10301042
idx = 2
10311043
for i in range(count):
10321044
column_label = data[idx : data.find(NULL_BYTE, idx)]
@@ -1056,6 +1068,8 @@ def handle_ROW_DESCRIPTION(self: "Connection", data, cursor: Cursor) -> None:
10561068
cursor.ps["row_desc"].append(field)
10571069
field["pg8000_fc"], field["func"] = self.pg_types[field["type_oid"]]
10581070

1071+
_logger.debug(cursor.ps["row_desc"])
1072+
10591073
def execute(self: "Connection", cursor: Cursor, operation: str, vals) -> None:
10601074
"""
10611075
Executes a database operation. Parameters may be provided as a sequence, or as a mapping, depending upon the value of `redshift_connector.paramstyle`.

redshift_connector/cursor.py

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import functools
2+
import logging
23
import re
34
import typing
45
from collections import deque
@@ -23,6 +24,8 @@
2324
except:
2425
pass
2526

27+
_logger: logging.Logger = logging.getLogger(__name__)
28+
2629

2730
class Cursor:
2831
"""A cursor object is returned by the :meth:`~Connection.cursor` method of
@@ -98,6 +101,8 @@ def __init__(self: "Cursor", connection: "Connection", paramstyle=None) -> None:
98101
else:
99102
self.paramstyle = paramstyle
100103

104+
_logger.debug("Cursor.paramstyle={}".format(self.paramstyle))
105+
101106
def __enter__(self: "Cursor") -> "Cursor":
102107
return self
103108

redshift_connector/iam_helper.py

+10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from redshift_connector.error import InterfaceError
1717
from redshift_connector.plugin import SamlCredentialsProvider
1818
from redshift_connector.redshift_property import RedshiftProperty
19+
from redshift_connector.utils import make_divider_block
1920

2021
_logger: logging.Logger = logging.getLogger(__name__)
2122

@@ -153,6 +154,7 @@ def set_iam_properties(
153154
)
154155
else:
155156
info.credentials_provider = credentials_provider
157+
_logger.debug("IDP Credential Provider {}".format(info.credentials_provider))
156158
elif profile is not None:
157159
if any((access_key_id, secret_access_key, session_token)):
158160
raise InterfaceError(
@@ -161,6 +163,7 @@ def set_iam_properties(
161163
)
162164
else:
163165
info.profile = profile
166+
_logger.debug("AWS Profile {}".format(info.profile))
164167
elif access_key_id is not None:
165168
info.access_key_id = access_key_id
166169

@@ -170,6 +173,7 @@ def set_iam_properties(
170173
# SQL Workbench.
171174
elif password != "":
172175
info.secret_access_key = password
176+
_logger.debug("Value of password will be used for secret_access_key")
173177
else:
174178
raise InterfaceError(
175179
"Invalid connection property setting. "
@@ -178,6 +182,11 @@ def set_iam_properties(
178182

179183
if session_token is not None:
180184
info.session_token = session_token
185+
_logger.debug(
186+
"AWS Credentials access_key_id: {} secret_access_key: {} session_token: {}".format(
187+
bool(info.access_key_id), bool(info.secret_access_key), bool(info.session_token)
188+
)
189+
)
181190
elif secret_access_key is not None:
182191
raise InterfaceError(
183192
"Invalid connection property setting. access_key_id is required when secret_access_key is "
@@ -290,6 +299,7 @@ def set_iam_credentials(info: RedshiftProperty) -> None:
290299
)
291300
raise InterfaceError("Invalid credentials provider " + info.credentials_provider)
292301
else: # indicates AWS Credentials will be used
302+
_logger.debug("AWS Credentials provider will be used for authentication")
293303
provider = AWSCredentialsProvider()
294304
provider.add_parameter(info)
295305

redshift_connector/plugin/adfs_credentials_provider.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,16 @@ def form_based_authentication(self: "AdfsCredentialsProvider") -> str:
3535
url: str = "https://{host}:{port}/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices".format(
3636
host=self.idp_host, port=str(self.idpPort)
3737
)
38+
_logger.debug("Uri: {}".format(url))
39+
3840
try:
3941
response: "requests.Response" = requests.get(url, verify=self.do_verify_ssl_cert())
4042
response.raise_for_status()
4143
except requests.exceptions.HTTPError as e:
4244
if "response" in vars():
43-
_logger.debug("form_based_authentication https response: {}".format(response.text)) # type: ignore
45+
_logger.debug("Form_based_authentication https response: {}".format(response.content)) # type: ignore
4446
else:
45-
_logger.debug("form_based_authentication could not receive https response due to an error")
47+
_logger.debug("Form_based_authentication could not receive https response due to an error")
4648
_logger.error("Request for SAML assertion when refreshing credentials was unsuccessful. {}".format(str(e)))
4749
raise InterfaceError(e)
4850
except requests.exceptions.Timeout as e:
@@ -58,6 +60,8 @@ def form_based_authentication(self: "AdfsCredentialsProvider") -> str:
5860
_logger.error("A unknown error occurred when requesting SAML assertion to refresh credentials")
5961
raise InterfaceError(e)
6062

63+
_logger.debug(response.text)
64+
6165
try:
6266
soup = bs4.BeautifulSoup(response.text, features="lxml")
6367
except Exception as e:
@@ -69,6 +73,9 @@ def form_based_authentication(self: "AdfsCredentialsProvider") -> str:
6973
for inputtag in soup.find_all(re.compile("(INPUT|input)")):
7074
name: str = inputtag.get("name", "")
7175
value: str = inputtag.get("value", "")
76+
77+
_logger.debug("Name={}".format(name))
78+
7279
if "username" in name.lower():
7380
payload[name] = self.user_name
7481
elif "authmethod" in name.lower():
@@ -82,6 +89,8 @@ def form_based_authentication(self: "AdfsCredentialsProvider") -> str:
8289
if action and action.startswith("/"):
8390
url = "https://{host}:{port}{action}".format(host=self.idp_host, port=str(self.idpPort), action=action)
8491

92+
_logger.debug("Action uri: {}".format(url))
93+
8594
try:
8695
response = requests.post(url, data=payload, verify=self.do_verify_ssl_cert())
8796
response.raise_for_status()

redshift_connector/plugin/azure_credentials_provider.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ def azure_oauth_based_authentication(self: "AzureCredentialsProvider") -> str:
6161

6262
# endpoint to connect with Microsoft Azure to get SAML Assertion token
6363
url: str = "https://login.microsoftonline.com/{tenant}/oauth2/token".format(tenant=self.idp_tenant)
64+
_logger.debug("Uri: {}".format(url))
65+
6466
# headers to pass with POST request
6567
headers: typing.Dict[str, str] = azure_headers
6668
# required parameters to pass in POST body
@@ -82,10 +84,10 @@ def azure_oauth_based_authentication(self: "AzureCredentialsProvider") -> str:
8284
except requests.exceptions.HTTPError as e:
8385
if "response" in vars():
8486
_logger.debug(
85-
"azure_oauth_based_authentication https response: {}".format(response.text) # type: ignore
87+
"azure_oauth_based_authentication https response: {}".format(response.content) # type: ignore
8688
)
8789
else:
88-
_logger.debug("azure_oauth_based_authentication could not receive https response due to an error")
90+
_logger.debug("Azure_oauth_based_authentication could not receive https response due to an error")
8991
_logger.error("Request for authentication from Azure was unsuccessful. {}".format(str(e)))
9092
raise InterfaceError(e)
9193
except requests.exceptions.Timeout as e:
@@ -100,6 +102,8 @@ def azure_oauth_based_authentication(self: "AzureCredentialsProvider") -> str:
100102
_logger.error("A unknown error occurred when requesting authentication from Azure.")
101103
raise InterfaceError(e)
102104

105+
_logger.debug(response.text)
106+
103107
# parse the JSON response to grab access_token field which contains Base64 encoded SAML
104108
# Assertion and decode it
105109
saml_assertion: str = ""

redshift_connector/plugin/browser_azure_credentials_provider.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ def add_parameter(self: "BrowserAzureCredentialsProvider", info: RedshiftPropert
5252

5353
self.idp_response_timeout = info.idp_response_timeout
5454

55+
_logger.debug("Idp_tenant={}".format(self.idp_tenant))
56+
_logger.debug("Client_id={}".format(self.client_id))
57+
_logger.debug("Idp_response_timeout={}".format(self.idp_response_timeout))
58+
_logger.debug("Listen_port={}".format(self.listen_port))
59+
5560
# Required method to grab the SAML Response. Used in base class to refresh temporary credentials.
5661
def get_saml_assertion(self: "BrowserAzureCredentialsProvider") -> str:
5762

@@ -65,6 +70,7 @@ def get_saml_assertion(self: "BrowserAzureCredentialsProvider") -> str:
6570

6671
listen_socket: socket.socket = self.get_listen_socket()
6772
self.redirectUri = "http://localhost:{port}/redshift/".format(port=self.listen_port)
73+
_logger.debug("Listening for connection on port {}".format(self.listen_port))
6874

6975
try:
7076
token: str = self.fetch_authorization_token(listen_socket)
@@ -73,7 +79,7 @@ def get_saml_assertion(self: "BrowserAzureCredentialsProvider") -> str:
7379
raise e
7480
finally:
7581
listen_socket.close()
76-
82+
_logger.debug("Got SAML assertion")
7783
return self.wrap_and_encode_assertion(saml_assertion)
7884

7985
# First authentication phase:
@@ -93,10 +99,10 @@ def fetch_authorization_token(self: "BrowserAzureCredentialsProvider", listen_so
9399

94100
return str(return_value)
95101
except socket.error as e:
96-
_logger.error("socket error: %s", e)
102+
_logger.error("Socket error: %s", e)
97103
raise e
98104
except Exception as e:
99-
_logger.error("other Exception: %s", e)
105+
_logger.error("Other Exception: %s", e)
100106
raise e
101107

102108
# Initiates the request to the IDP and gets the response body
@@ -119,14 +125,17 @@ def fetch_saml_response(self: "BrowserAzureCredentialsProvider", token):
119125
"client_secret": self.client_secret,
120126
"redirect_uri": self.redirectUri,
121127
}
128+
129+
_logger.debug("Uri: {}".format(url))
130+
122131
try:
123132
response = requests.post(url, data=payload, headers=headers, verify=self.do_verify_ssl_cert())
124133
response.raise_for_status()
125134
except requests.exceptions.HTTPError as e:
126135
if "response" in vars():
127-
_logger.debug("fetch_saml_response https response: {}".format(response.text)) # type: ignore
136+
_logger.debug("Fetch_saml_response https response: {}".format(response.content)) # type: ignore
128137
else:
129-
_logger.debug("fetch_saml_response could not receive https response due to an error")
138+
_logger.debug("Fetch_saml_response could not receive https response due to an error")
130139
_logger.error("Request for authentication from Microsoft was unsuccessful. {}".format(str(e)))
131140
raise InterfaceError(e)
132141
except requests.exceptions.Timeout as e:
@@ -141,6 +150,8 @@ def fetch_saml_response(self: "BrowserAzureCredentialsProvider", token):
141150
_logger.error("A unknown error occurred when requesting authentication from Azure")
142151
raise InterfaceError(e)
143152

153+
_logger.debug(response.text)
154+
144155
try:
145156
saml_assertion: str = response.json()["access_token"]
146157
except TypeError as e:

redshift_connector/plugin/browser_saml_credentials_provider.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ def add_parameter(self: "BrowserSamlCredentialsProvider", info: RedshiftProperty
3434
self.idp_response_timeout = info.idp_response_timeout
3535
self.listen_port = info.listen_port
3636

37+
_logger.debug("Listen_port={}".format(self.listen_port))
38+
_logger.debug("Login_url={}".format(self.login_url))
39+
_logger.debug("Idp_response_timeout={}".format(self.idp_response_timeout))
40+
3741
# Required method to grab the SAML Response. Used in base class to refresh temporary credentials.
3842
def get_saml_assertion(self: "BrowserSamlCredentialsProvider") -> str:
3943

@@ -54,17 +58,18 @@ def get_saml_assertion(self: "BrowserSamlCredentialsProvider") -> str:
5458
def authenticate(self: "BrowserSamlCredentialsProvider") -> str:
5559
try:
5660
with concurrent.futures.ThreadPoolExecutor() as executor:
61+
_logger.debug("Listening for connection on port {}".format(self.listen_port))
5762
future = executor.submit(self.run_server, self.listen_port, self.idp_response_timeout)
5863
self.open_browser()
5964
return_value: str = future.result()
6065

6166
samlresponse = urllib.parse.unquote(return_value)
6267
return str(samlresponse)
6368
except socket.error as e:
64-
_logger.error("socket error: %s", e)
69+
_logger.error("Socket error: %s", e)
6570
raise e
6671
except Exception as e:
67-
_logger.error("other Exception: %s", e)
72+
_logger.error("Other Exception: %s", e)
6873
raise e
6974

7075
def run_server(self: "BrowserSamlCredentialsProvider", listen_port: int, idp_response_timeout: int) -> str:
@@ -85,6 +90,7 @@ def run_server(self: "BrowserSamlCredentialsProvider", listen_port: int, idp_res
8590
result: typing.Optional[typing.Match] = re.search(
8691
pattern="SAMLResponse[:=]+[\\n\\r]*", string=decoded_part, flags=re.MULTILINE
8792
)
93+
_logger.debug("Data received contained SAMLResponse: {}".format(bool(result is not None)))
8894

8995
if result is not None:
9096
saml_resp_block: str = decoded_part[result.regs[0][1] :]
@@ -98,6 +104,8 @@ def open_browser(self: "BrowserSamlCredentialsProvider") -> None:
98104
import webbrowser
99105

100106
url: typing.Optional[str] = self.login_url
107+
_logger.debug("SSO URI: {}".format(url))
108+
101109
if url is None:
102110
raise InterfaceError("the login_url could not be empty")
103111
webbrowser.open(url)

redshift_connector/plugin/jwt_credentials_provider.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def get_credentials(self: "SamlCredentialsProvider") -> CredentialsHolder:
6363
try:
6464
self.refresh()
6565
except Exception as e:
66-
_logger.error("refresh failed: {}".format(str(e)))
66+
_logger.error("Refreshing IdP credentials failed: {}".format(str(e)))
6767
raise InterfaceError(e)
6868

6969
if key not in self.cache or self.cache[key] is None:
@@ -118,7 +118,7 @@ def refresh(self: "JwtCredentialsProvider") -> None:
118118
_logger.error("RegionDisabledException: %s", e)
119119
raise e
120120
except Exception as e:
121-
_logger.error("other Exception: %s", e)
121+
_logger.error("Other Exception: %s", e)
122122
raise e
123123

124124
def check_required_parameters(self: "JwtCredentialsProvider") -> None:

0 commit comments

Comments
 (0)