generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 84
Open
Description
Driver version
2.1.4
Redshift version
PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.79237
Client Operating System
Ubuntu 22.04.4 LTS
Python version
3.11.9
Problem description
- Expected behaviour: Create connection to Redshift Serverless with VPC Endpoint
- Actual behaviour: SSL validation failed
- Error message/stack trace:
SSLError: SSL validation failed for https://vpce-06c30eb85ac87559f-vu0ekkrw.redshift-serverless.ap-southeast-1.vpce.amazonaws.com/ hostname 'vpce-06c30eb85ac87559f-vu0ekkrw.redshift-serverless.ap-southeast-1.vpce.amazonaws.com' doesn't match 'redshift-serverless.ap-southeast-1.amazonaws.com'
Python Driver trace logs
---------------------------------------------------------------------------
CertificateError Traceback (most recent call last)
File /opt/conda/lib/python3.11/site-packages/urllib3/connectionpool.py:715, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
714 # Make the request on the httplib connection object.
--> 715 httplib_response = self._make_request(
716 conn,
717 method,
718 url,
719 timeout=timeout_obj,
720 body=body,
721 headers=headers,
722 chunked=chunked,
723 )
725 # If we're going to release the connection in ``finally:``, then
726 # the response doesn't need to know about the connection. Otherwise
727 # it will also try to release it and we'll have a double-release
728 # mess.
File /opt/conda/lib/python3.11/site-packages/urllib3/connectionpool.py:404, in HTTPConnectionPool._make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
403 try:
--> 404 self._validate_conn(conn)
405 except (SocketTimeout, BaseSSLError) as e:
406 # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.
File /opt/conda/lib/python3.11/site-packages/urllib3/connectionpool.py:1060, in HTTPSConnectionPool._validate_conn(self, conn)
1059 if not getattr(conn, "sock", None): # AppEngine might not have `.sock`
-> 1060 conn.connect()
1062 if not conn.is_verified:
File /opt/conda/lib/python3.11/site-packages/urllib3/connection.py:472, in HTTPSConnection.connect(self)
463 warnings.warn(
464 (
465 "Certificate for {0} has no `subjectAltName`, falling back to check for a "
(...)
470 SubjectAltNameWarning,
471 )
--> 472 _match_hostname(cert, self.assert_hostname or server_hostname)
474 self.is_verified = (
475 context.verify_mode == ssl.CERT_REQUIRED
476 or self.assert_fingerprint is not None
477 )
File /opt/conda/lib/python3.11/site-packages/urllib3/connection.py:545, in _match_hostname(cert, asserted_hostname)
544 try:
--> 545 match_hostname(cert, asserted_hostname)
546 except CertificateError as e:
File /opt/conda/lib/python3.11/site-packages/urllib3/util/ssl_match_hostname.py:155, in match_hostname(cert, hostname)
154 elif len(dnsnames) == 1:
--> 155 raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0]))
156 else:
CertificateError: hostname 'vpce-06c30eb85ac87559f-vu0ekkrw.redshift-serverless.ap-southeast-1.vpce.amazonaws.com' doesn't match 'redshift-serverless.ap-southeast-1.amazonaws.com'
During handling of the above exception, another exception occurred:
SSLError Traceback (most recent call last)
File /opt/conda/lib/python3.11/site-packages/botocore/httpsession.py:464, in URLLib3Session.send(self, request)
463 request_target = self._get_request_target(request.url, proxy_url)
--> 464 urllib_response = conn.urlopen(
465 method=request.method,
466 url=request_target,
467 body=request.body,
468 headers=request.headers,
469 retries=Retry(False),
470 assert_same_host=False,
471 preload_content=False,
472 decode_content=False,
473 chunked=self._chunked(request.headers),
474 )
476 http_response = botocore.awsrequest.AWSResponse(
477 request.url,
478 urllib_response.status,
479 urllib_response.headers,
480 urllib_response,
481 )
File /opt/conda/lib/python3.11/site-packages/urllib3/connectionpool.py:801, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
799 e = ProtocolError("Connection aborted.", e)
--> 801 retries = retries.increment(
802 method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
803 )
804 retries.sleep()
File /opt/conda/lib/python3.11/site-packages/urllib3/util/retry.py:527, in Retry.increment(self, method, url, response, error, _pool, _stacktrace)
525 if self.total is False and error:
526 # Disabled, indicate to re-raise the error.
--> 527 raise six.reraise(type(error), error, _stacktrace)
529 total = self.total
File /opt/conda/lib/python3.11/site-packages/urllib3/packages/six.py:769, in reraise(tp, value, tb)
768 if value.__traceback__ is not tb:
--> 769 raise value.with_traceback(tb)
770 raise value
File /opt/conda/lib/python3.11/site-packages/urllib3/connectionpool.py:715, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
714 # Make the request on the httplib connection object.
--> 715 httplib_response = self._make_request(
716 conn,
717 method,
718 url,
719 timeout=timeout_obj,
720 body=body,
721 headers=headers,
722 chunked=chunked,
723 )
725 # If we're going to release the connection in ``finally:``, then
726 # the response doesn't need to know about the connection. Otherwise
727 # it will also try to release it and we'll have a double-release
728 # mess.
File /opt/conda/lib/python3.11/site-packages/urllib3/connectionpool.py:404, in HTTPConnectionPool._make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
403 try:
--> 404 self._validate_conn(conn)
405 except (SocketTimeout, BaseSSLError) as e:
406 # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.
File /opt/conda/lib/python3.11/site-packages/urllib3/connectionpool.py:1060, in HTTPSConnectionPool._validate_conn(self, conn)
1059 if not getattr(conn, "sock", None): # AppEngine might not have `.sock`
-> 1060 conn.connect()
1062 if not conn.is_verified:
File /opt/conda/lib/python3.11/site-packages/urllib3/connection.py:472, in HTTPSConnection.connect(self)
463 warnings.warn(
464 (
465 "Certificate for {0} has no `subjectAltName`, falling back to check for a "
(...)
470 SubjectAltNameWarning,
471 )
--> 472 _match_hostname(cert, self.assert_hostname or server_hostname)
474 self.is_verified = (
475 context.verify_mode == ssl.CERT_REQUIRED
476 or self.assert_fingerprint is not None
477 )
File /opt/conda/lib/python3.11/site-packages/urllib3/connection.py:545, in _match_hostname(cert, asserted_hostname)
544 try:
--> 545 match_hostname(cert, asserted_hostname)
546 except CertificateError as e:
File /opt/conda/lib/python3.11/site-packages/urllib3/util/ssl_match_hostname.py:155, in match_hostname(cert, hostname)
154 elif len(dnsnames) == 1:
--> 155 raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0]))
156 else:
SSLError: hostname 'vpce-06c30eb85ac87559f-vu0ekkrw.redshift-serverless.ap-southeast-1.vpce.amazonaws.com' doesn't match 'redshift-serverless.ap-southeast-1.amazonaws.com'
During handling of the above exception, another exception occurred:
SSLError Traceback (most recent call last)
Cell In[5], line 1
----> 1 conn = redshift_connector.connect(
2 host=host,
3 port=5439,
4 database=db_name,
5 iam=True,
6 endpoint_url='https://vpce-06c30eb85ac87559f-vu0ekkrw.redshift-serverless.ap-southeast-1.vpce.amazonaws.com'
7 )
9 conn.autocommit = True
10 # conn.run("VACUUM")
File /opt/conda/lib/python3.11/site-packages/redshift_connector/__init__.py:386, in connect(user, database, password, port, host, source_address, unix_sock, ssl, sslmode, timeout, max_prepared_statements, tcp_keepalive, application_name, replication, idp_host, db_user, app_id, app_name, preferred_role, principal_arn, access_key_id, secret_access_key, session_token, profile, credentials_provider, region, cluster_identifier, iam, client_id, idp_tenant, client_secret, partner_sp_id, idp_response_timeout, listen_port, login_to_rp, login_url, auto_create, db_groups, force_lowercase, allow_db_user_override, client_protocol_version, database_metadata_current_db_only, ssl_insecure, web_identity_token, role_session_name, role_arn, iam_disable_cache, auth_profile, endpoint_url, provider_name, scope, numeric_to_float, is_serverless, serverless_acct_id, serverless_work_group, group_federation, identity_namespace, idc_client_display_name, idc_region, issuer_url, token, token_type)
383 _logger.debug("redshift_native_auth enabled")
385 if not redshift_native_auth:
--> 386 IamHelper.set_iam_properties(info)
388 _logger.debug(make_divider_block())
389 _logger.debug("Connection arguments following validation and IAM auth (if applicable)")
File /opt/conda/lib/python3.11/site-packages/redshift_connector/iam_helper.py:149, in IamHelper.set_iam_properties(info)
145 if info.cluster_identifier is None and not info._is_serverless and not info.is_cname:
146 raise InterfaceError(
147 "Invalid connection property setting. cluster_identifier must be provided when IAM is enabled"
148 )
--> 149 IamHelper.set_iam_credentials(info)
150 # Check for Browser based OAuth Native authentication
151 NativeAuthPluginHelper.set_native_auth_plugin_properties(info)
File /opt/conda/lib/python3.11/site-packages/redshift_connector/iam_helper.py:230, in IamHelper.set_iam_credentials(info)
227 IamHelper.set_cluster_identifier(provider, info)
229 # Redshift database credentials will be determined using the redshift client from boto3 API
--> 230 IamHelper.set_cluster_credentials(provider, info)
232 # Redshift instance host and port must be retrieved
233 IamHelper.set_cluster_host_and_port(provider, info)
File /opt/conda/lib/python3.11/site-packages/redshift_connector/iam_helper.py:460, in IamHelper.set_cluster_credentials(cred_provider, info)
456 get_cred_args["customDomainName"] = info.host
457 _logger.debug("Calling get_credentials with parameters %s", get_cred_args)
458 cred = typing.cast(
459 typing.Dict[str, typing.Union[str, datetime.datetime]],
--> 460 client.get_credentials(**get_cred_args),
461 )
462 # re-map expiration for compatibility with redshift credential response
463 cred["Expiration"] = cred["expiration"]
File /opt/conda/lib/python3.11/site-packages/botocore/client.py:565, in ClientCreator._create_api_method.<locals>._api_call(self, *args, **kwargs)
561 raise TypeError(
562 f"{py_operation_name}() only accepts keyword arguments."
563 )
564 # The "self" in this scope is referring to the BaseClient.
--> 565 return self._make_api_call(operation_name, kwargs)
File /opt/conda/lib/python3.11/site-packages/botocore/client.py:1001, in BaseClient._make_api_call(self, operation_name, api_params)
997 maybe_compress_request(
998 self.meta.config, request_dict, operation_model
999 )
1000 apply_request_checksum(request_dict)
-> 1001 http, parsed_response = self._make_request(
1002 operation_model, request_dict, request_context
1003 )
1005 self.meta.events.emit(
1006 'after-call.{service_id}.{operation_name}'.format(
1007 service_id=service_id, operation_name=operation_name
(...)
1012 context=request_context,
1013 )
1015 if http.status_code >= 300:
File /opt/conda/lib/python3.11/site-packages/botocore/client.py:1027, in BaseClient._make_request(self, operation_model, request_dict, request_context)
1025 def _make_request(self, operation_model, request_dict, request_context):
1026 try:
-> 1027 return self._endpoint.make_request(operation_model, request_dict)
1028 except Exception as e:
1029 self.meta.events.emit(
1030 'after-call-error.{service_id}.{operation_name}'.format(
1031 service_id=self._service_model.service_id.hyphenize(),
(...)
1035 context=request_context,
1036 )
File /opt/conda/lib/python3.11/site-packages/botocore/endpoint.py:119, in Endpoint.make_request(self, operation_model, request_dict)
113 def make_request(self, operation_model, request_dict):
114 logger.debug(
115 "Making request for %s with params: %s",
116 operation_model,
117 request_dict,
118 )
--> 119 return self._send_request(request_dict, operation_model)
File /opt/conda/lib/python3.11/site-packages/botocore/endpoint.py:202, in Endpoint._send_request(self, request_dict, operation_model)
198 request = self.create_request(request_dict, operation_model)
199 success_response, exception = self._get_response(
200 request, operation_model, context
201 )
--> 202 while self._needs_retry(
203 attempts,
204 operation_model,
205 request_dict,
206 success_response,
207 exception,
208 ):
209 attempts += 1
210 self._update_retries_context(context, attempts, success_response)
File /opt/conda/lib/python3.11/site-packages/botocore/endpoint.py:354, in Endpoint._needs_retry(self, attempts, operation_model, request_dict, response, caught_exception)
352 service_id = operation_model.service_model.service_id.hyphenize()
353 event_name = f"needs-retry.{service_id}.{operation_model.name}"
--> 354 responses = self._event_emitter.emit(
355 event_name,
356 response=response,
357 endpoint=self,
358 operation=operation_model,
359 attempts=attempts,
360 caught_exception=caught_exception,
361 request_dict=request_dict,
362 )
363 handler_response = first_non_none_response(responses)
364 if handler_response is None:
File /opt/conda/lib/python3.11/site-packages/botocore/hooks.py:412, in EventAliaser.emit(self, event_name, **kwargs)
410 def emit(self, event_name, **kwargs):
411 aliased_event_name = self._alias_event_name(event_name)
--> 412 return self._emitter.emit(aliased_event_name, **kwargs)
File /opt/conda/lib/python3.11/site-packages/botocore/hooks.py:256, in HierarchicalEmitter.emit(self, event_name, **kwargs)
245 def emit(self, event_name, **kwargs):
246 """
247 Emit an event by name with arguments passed as keyword args.
248
(...)
254 handlers.
255 """
--> 256 return self._emit(event_name, kwargs)
File /opt/conda/lib/python3.11/site-packages/botocore/hooks.py:239, in HierarchicalEmitter._emit(self, event_name, kwargs, stop_on_response)
237 for handler in handlers_to_call:
238 logger.debug('Event %s: calling handler %s', event_name, handler)
--> 239 response = handler(**kwargs)
240 responses.append((handler, response))
241 if stop_on_response and response is not None:
File /opt/conda/lib/python3.11/site-packages/botocore/retryhandler.py:207, in RetryHandler.__call__(self, attempts, response, caught_exception, **kwargs)
204 retries_context = kwargs['request_dict']['context'].get('retries')
205 checker_kwargs.update({'retries_context': retries_context})
--> 207 if self._checker(**checker_kwargs):
208 result = self._action(attempts=attempts)
209 logger.debug("Retry needed, action of: %s", result)
File /opt/conda/lib/python3.11/site-packages/botocore/retryhandler.py:284, in MaxAttemptsDecorator.__call__(self, attempt_number, response, caught_exception, retries_context)
279 if retries_context:
280 retries_context['max'] = max(
281 retries_context.get('max', 0), self._max_attempts
282 )
--> 284 should_retry = self._should_retry(
285 attempt_number, response, caught_exception
286 )
287 if should_retry:
288 if attempt_number >= self._max_attempts:
289 # explicitly set MaxAttemptsReached
File /opt/conda/lib/python3.11/site-packages/botocore/retryhandler.py:320, in MaxAttemptsDecorator._should_retry(self, attempt_number, response, caught_exception)
316 return True
317 else:
318 # If we've exceeded the max attempts we just let the exception
319 # propagate if one has occurred.
--> 320 return self._checker(attempt_number, response, caught_exception)
File /opt/conda/lib/python3.11/site-packages/botocore/retryhandler.py:363, in MultiChecker.__call__(self, attempt_number, response, caught_exception)
361 def __call__(self, attempt_number, response, caught_exception):
362 for checker in self._checkers:
--> 363 checker_response = checker(
364 attempt_number, response, caught_exception
365 )
366 if checker_response:
367 return checker_response
File /opt/conda/lib/python3.11/site-packages/botocore/retryhandler.py:247, in BaseChecker.__call__(self, attempt_number, response, caught_exception)
245 return self._check_response(attempt_number, response)
246 elif caught_exception is not None:
--> 247 return self._check_caught_exception(
248 attempt_number, caught_exception
249 )
250 else:
251 raise ValueError("Both response and caught_exception are None.")
File /opt/conda/lib/python3.11/site-packages/botocore/retryhandler.py:416, in ExceptionRaiser._check_caught_exception(self, attempt_number, caught_exception)
408 def _check_caught_exception(self, attempt_number, caught_exception):
409 # This is implementation specific, but this class is useful by
410 # coordinating with the MaxAttemptsDecorator.
(...)
414 # the MaxAttemptsDecorator is not interested in retrying the exception
415 # then this exception just propagates out past the retry code.
--> 416 raise caught_exception
File /opt/conda/lib/python3.11/site-packages/botocore/endpoint.py:281, in Endpoint._do_get_response(self, request, operation_model, context)
279 http_response = first_non_none_response(responses)
280 if http_response is None:
--> 281 http_response = self._send(request)
282 except HTTPClientError as e:
283 return (None, e)
File /opt/conda/lib/python3.11/site-packages/botocore/endpoint.py:377, in Endpoint._send(self, request)
376 def _send(self, request):
--> 377 return self.http_session.send(request)
File /opt/conda/lib/python3.11/site-packages/botocore/httpsession.py:491, in URLLib3Session.send(self, request)
489 return http_response
490 except URLLib3SSLError as e:
--> 491 raise SSLError(endpoint_url=request.url, error=e)
492 except (NewConnectionError, socket.gaierror) as e:
493 raise EndpointConnectionError(endpoint_url=request.url, error=e)
SSLError: SSL validation failed for https://vpce-06c30eb85ac87559f-vu0ekkrw.redshift-serverless.ap-southeast-1.vpce.amazonaws.com/ hostname 'vpce-06c30eb85ac87559f-vu0ekkrw.redshift-serverless.ap-southeast-1.vpce.amazonaws.com' doesn't match 'redshift-serverless.ap-southeast-1.amazonaws.com'
Reproduction code
conn = redshift_connector.connect(
host=host,
port=5439,
database=db_name,
iam=True,
endpoint_url='https://vpce-06c30eb85ac87559f-vu0ekkrw.redshift-serverless.ap-southeast-1.vpce.amazonaws.com'
)
Metadata
Metadata
Assignees
Labels
No labels