Repository: pypa/pip

Issue:
Add SSL CA certificate information to `pip debug`
**What's the problem this feature will solve?**

As described in [#6720 (comment)](https://github.com/pypa/pip/issues/6720#issuecomment-538791684), pip may be using several sources of information for the CA certificate bundle to use for HTTPS requests. This makes it hard to debug user issues.

**Describe the solution you'd like**

In the output of `pip debug` we should include:

* the `cert` setting from the highest-priority pip configuration file (~~and the configuration file path~~) - on second thought the location doesn't matter much
* `os.environ.get('REQUESTS_CA_BUNDLE')`
* `os.environ.get('CURL_CA_BUNDLE')`
* `pip._vendor.certifi.where()`

This will provide insight into the CA certificate bundle in use for a given request, which can then be used in instructions to the user in conjunction with curl/openssl to submit an HTTP request independent of pip and rule out pip-specific issues.

**Alternative Solutions**

Do nothing.

**Additional context**

* #4459
* #4919
* #6335
* #6720
* #6915


Discussion:
I think I can handle this one, but how would one get the `highest-priority pip configuration file`?

I see: https://github.com/pypa/pip/blob/a0b75cc46042f031366d4206e8613dc336a9767f/src/pip/_internal/configuration.py#L102 but it doesn't seem to know which file is highest priority
Discussed this in person at PyCon India sprints.

Noting here for myself, that the suggested approach makes sense, since our configuration is cascading in a manner not handled by `Configuration`.
@Pachwenko I don't have the answer offhand, but if you want to do the others that would be totally fine. We can check them off in the original post as they get completed.
@chrahunt I think it's best to leave the "get highest level file" details to a follow up PR since we'd need to keep track of more details than we're exposing publicly from the Configuration object currently.

Resolving patch:
diff --git a/src/pip/_internal/commands/debug.py b/src/pip/_internal/commands/debug.py
--- a/src/pip/_internal/commands/debug.py
+++ b/src/pip/_internal/commands/debug.py
@@ -5,8 +5,11 @@
 
 import locale
 import logging
+import os
 import sys
 
+from pip._vendor.certifi import where
+
 from pip._internal.cli import cmdoptions
 from pip._internal.cli.base_command import Command
 from pip._internal.cli.cmdoptions import make_target_python
@@ -17,14 +20,14 @@
 from pip._internal.wheel import format_tag
 
 if MYPY_CHECK_RUNNING:
-    from typing import Any, List
+    from typing import Any, List, Optional
     from optparse import Values
 
 logger = logging.getLogger(__name__)
 
 
 def show_value(name, value):
-    # type: (str, str) -> None
+    # type: (str, Optional[str]) -> None
     logger.info('{}: {}'.format(name, value))
 
 
@@ -75,6 +78,25 @@ def show_tags(options):
             logger.info(msg)
 
 
+def ca_bundle_info(config):
+    levels = set()
+    for key, value in config.items():
+        levels.add(key.split('.')[0])
+
+    if not levels:
+        return "Not specified"
+
+    levels_that_override_global = ['install', 'wheel', 'download']
+    global_overriding_level = [
+        level for level in levels if level in levels_that_override_global
+    ]
+    if not global_overriding_level:
+        return 'global'
+
+    levels.remove('global')
+    return ", ".join(levels)
+
+
 class DebugCommand(Command):
     """
     Display debug information.
@@ -90,6 +112,7 @@ def __init__(self, *args, **kw):
         cmd_opts = self.cmd_opts
         cmdoptions.add_target_python_options(cmd_opts)
         self.parser.insert_option_group(0, cmd_opts)
+        self.parser.config.load()
 
     def run(self, options, args):
         # type: (Values, List[Any]) -> int
@@ -110,6 +133,11 @@ def run(self, options, args):
         show_value('sys.platform', sys.platform)
         show_sys_implementation()
 
+        show_value("'cert' config value", ca_bundle_info(self.parser.config))
+        show_value("REQUESTS_CA_BUNDLE", os.environ.get('REQUESTS_CA_BUNDLE'))
+        show_value("CURL_CA_BUNDLE", os.environ.get('CURL_CA_BUNDLE'))
+        show_value("pip._vendor.certifi.where()", where())
+
         show_tags(options)
 
         return SUCCESS


Test patch:
diff --git a/tests/functional/test_debug.py b/tests/functional/test_debug.py
--- a/tests/functional/test_debug.py
+++ b/tests/functional/test_debug.py
@@ -10,6 +10,11 @@
     'locale.getpreferredencoding: ',
     'sys.platform: ',
     'sys.implementation:',
+    '\'cert\' config value: ',
+    'REQUESTS_CA_BUNDLE: ',
+    'CURL_CA_BUNDLE: ',
+    'pip._vendor.certifi.where(): ',
+
 ])
 def test_debug(script, expected_text):
     """