diff --git a/cli/tests/integrations/test_ssl.py b/cli/tests/integrations/test_ssl.py index 2696685..0319f79 100644 --- a/cli/tests/integrations/test_ssl.py +++ b/cli/tests/integrations/test_ssl.py @@ -52,7 +52,7 @@ def test_verify_ssl_without_cert_env_var(env): returncode, stdout, stderr = exec_command( ['dcos', 'marathon', 'app', 'list'], env) assert returncode == 1 - assert "certificate verify failed" in stderr.decode('utf-8') + assert stderr.decode('utf-8') == _ssl_error_msg() env.pop(constants.DCOS_SSL_VERIFY_ENV) @@ -62,7 +62,7 @@ def test_verify_ssl_without_cert_config(env): returncode, stdout, stderr = exec_command( ['dcos', 'marathon', 'app', 'list'], env) assert returncode == 1 - assert "certificate verify failed" in stderr.decode('utf-8') + assert stderr.decode('utf-8') == _ssl_error_msg() def test_verify_ssl_with_bad_cert_env_var(env): @@ -72,7 +72,7 @@ def test_verify_ssl_with_bad_cert_env_var(env): returncode, stdout, stderr = exec_command( ['dcos', 'marathon', 'app', 'list'], env) assert returncode == 1 - assert "PEM lib" in stderr.decode('utf-8') # wrong private key + assert stderr.decode('utf-8') == _ssl_error_msg() env.pop(constants.DCOS_SSL_VERIFY_ENV) @@ -82,7 +82,7 @@ def test_verify_ssl_with_bad_cert_config(env): returncode, stdout, stderr = exec_command( ['dcos', 'marathon', 'app', 'list'], env) assert returncode == 1 - assert "PEM lib" in stderr.decode('utf-8') # wrong private key + assert stderr.decode('utf-8') == _ssl_error_msg() def test_verify_ssl_with_good_cert_env_var(env): @@ -104,3 +104,10 @@ def test_verify_ssl_with_good_cert_config(env): ['dcos', 'marathon', 'app', 'list'], env) assert returncode == 0 assert stderr == b'' + + +def _ssl_error_msg(): + return ( + "An SSL error occurred. To configure your SSL settings, please run: " + "`dcos config set core.ssl_verify `\n" + ": Whether to verify SSL certs for HTTPS or path to certs\n") diff --git a/dcos/config.py b/dcos/config.py index bb25e93..8e60fc0 100644 --- a/dcos/config.py +++ b/dcos/config.py @@ -213,6 +213,25 @@ def get_config_schema(command): return subcommand.config_schema(executable, command) +def get_property_description(section, subkey): + """ + :param section: section of config paramater + :type section: str + :param subkey: property within 'section' + :type subkey: str + :returns: description of section.subkey or None if no description + :rtype: str | None + """ + + schema = get_config_schema(section) + property_info = schema["properties"].get(subkey) + if property_info is not None: + return property_info.get("description") + else: + raise DCOSException( + "No schema found found for {}.{}".format(section, subkey)) + + def check_config(toml_config_pre, toml_config_post): """ :param toml_config_pre: dictionary for the value before change diff --git a/dcos/data/config-schema/core.json b/dcos/data/config-schema/core.json index 244eb47..8b19a90 100644 --- a/dcos/data/config-schema/core.json +++ b/dcos/data/config-schema/core.json @@ -3,13 +3,13 @@ "additionalProperties": false, "properties": { "dcos_url": { - "description": "The the public master IP of your DCOS installation", + "description": "The public master IP of your DCOS installation", "format": "uri", "title": "DCOS URL", "type": "string" }, "dcos_acs_token": { - "description": "This is the token generated by authenticating to DCOS with ACS", + "description": "The token generated by authenticating to DCOS with ACS", "title": "DCOS ACS token", "type": "string" }, diff --git a/dcos/http.py b/dcos/http.py index 8629845..583b00c 100644 --- a/dcos/http.py +++ b/dcos/http.py @@ -95,6 +95,14 @@ def _request(method, auth=auth, verify=verify, **kwargs) + except requests.exceptions.SSLError as e: + logger.exception("HTTP SSL Error") + msg = ("An SSL error occurred. To configure your SSL settings, " + "please run: `dcos config set core.ssl_verify `") + description = config.get_property_description("core", "ssl_verify") + if description is not None: + msg += "\n: {}".format(description) + raise DCOSException(msg) except requests.exceptions.ConnectionError as e: logger.exception("HTTP Connection Error") raise DCOSException('URL [{0}] is unreachable: {1}'.format(url, e))