http: only request with DC/OS Auth if request is to DC/OS cluster (#893)
This commit is contained in:
@@ -645,6 +645,15 @@ def update_config(name, value, env=None):
|
||||
returncode, stdout, _ = exec_command(
|
||||
['dcos', 'config', 'show', name], env)
|
||||
|
||||
# when we change the dcos_url we remove the acs_token
|
||||
# we need to also restore the token if this occurs
|
||||
token = None
|
||||
if name == "core.dcos_url":
|
||||
returncode, token_val, _ = exec_command(
|
||||
['dcos', 'config', 'show', "core.dcos_acs_token"], env)
|
||||
if returncode == 0:
|
||||
token = token_val.decode('utf-8').strip()
|
||||
|
||||
result = None
|
||||
# config param already exists
|
||||
if returncode == 0:
|
||||
@@ -666,6 +675,9 @@ def update_config(name, value, env=None):
|
||||
else:
|
||||
exec_command(['dcos', 'config', 'unset', name], env)
|
||||
|
||||
if token:
|
||||
config_set("core.dcos_acs_token", token, env)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def package(package_name, deploy=False, args=[]):
|
||||
|
||||
@@ -67,15 +67,14 @@ def test_get_missing_property(env):
|
||||
|
||||
|
||||
def test_dcos_url_without_scheme(env):
|
||||
old = b'http://dcos.snakeoil.mesosphere.com'
|
||||
new = b"abc.com"
|
||||
out = b"[core.dcos_url]: changed from '%b' to 'https://%b'\n" % (old, new)
|
||||
assert_command(
|
||||
with update_config("core.dcos_url", None, env):
|
||||
new = b"abc.com"
|
||||
out = b"[core.dcos_url]: set to 'https://%b'\n" % (new)
|
||||
assert_command(
|
||||
['dcos', 'config', 'set', 'core.dcos_url', new.decode('utf-8')],
|
||||
returncode=0,
|
||||
stderr=out,
|
||||
returncode=0,
|
||||
env=env)
|
||||
config_set('core.dcos_url', old.decode('utf-8'), env)
|
||||
|
||||
|
||||
def test_get_top_property(env):
|
||||
@@ -105,11 +104,10 @@ def test_set_core_email_property():
|
||||
|
||||
|
||||
def test_set_existing_string_property(env):
|
||||
config_set('core.dcos_url',
|
||||
'http://dcos.snakeoil.mesosphere.com:5081', env)
|
||||
_get_value('core.dcos_url',
|
||||
'http://dcos.snakeoil.mesosphere.com:5081', env)
|
||||
config_set('core.dcos_url', 'http://dcos.snakeoil.mesosphere.com', env)
|
||||
new_value = 'http://dcos.snakeoil.mesosphere.com:5081'
|
||||
with update_config('core.dcos_url', new_value, env):
|
||||
_get_value('core.dcos_url',
|
||||
'http://dcos.snakeoil.mesosphere.com:5081', env)
|
||||
|
||||
|
||||
def test_set_existing_boolean_property(env):
|
||||
@@ -126,33 +124,27 @@ def test_set_existing_number_property(env):
|
||||
|
||||
def test_set_change_output(env):
|
||||
assert_command(
|
||||
['dcos', 'config', 'set', 'core.dcos_url',
|
||||
'http://dcos.snakeoil.mesosphere.com:5081'],
|
||||
stderr=(b"[core.dcos_url]: changed from "
|
||||
b"'http://dcos.snakeoil.mesosphere.com' to "
|
||||
b"'http://dcos.snakeoil.mesosphere.com:5081'\n"),
|
||||
['dcos', 'config', 'set', 'core.timeout', '10'],
|
||||
stderr=b"[core.timeout]: changed from '5' to '10'\n",
|
||||
env=env)
|
||||
config_set('core.dcos_url', 'http://dcos.snakeoil.mesosphere.com', env)
|
||||
config_set('core.timeout', '5', env)
|
||||
|
||||
|
||||
def test_set_same_output(env):
|
||||
assert_command(
|
||||
['dcos', 'config', 'set', 'core.dcos_url',
|
||||
'http://dcos.snakeoil.mesosphere.com'],
|
||||
stderr=(b"[core.dcos_url]: already set to "
|
||||
b"'http://dcos.snakeoil.mesosphere.com'\n"),
|
||||
['dcos', 'config', 'set', 'core.timeout', '5'],
|
||||
stderr=b"[core.timeout]: already set to '5'\n",
|
||||
env=env)
|
||||
|
||||
|
||||
def test_set_new_output(env):
|
||||
config_unset('core.dcos_url', env)
|
||||
assert_command(
|
||||
['dcos', 'config', 'set', 'core.dcos_url',
|
||||
'http://dcos.snakeoil.mesosphere.com:5081'],
|
||||
stderr=(b"[core.dcos_url]: set to "
|
||||
b"'http://dcos.snakeoil.mesosphere.com:5081'\n"),
|
||||
env=env)
|
||||
config_set('core.dcos_url', 'http://dcos.snakeoil.mesosphere.com', env)
|
||||
with update_config("core.dcos_url", None, env):
|
||||
assert_command(
|
||||
['dcos', 'config', 'set', 'core.dcos_url',
|
||||
'http://dcos.snakeoil.mesosphere.com:5081'],
|
||||
stderr=(b"[core.dcos_url]: set to "
|
||||
b"'http://dcos.snakeoil.mesosphere.com:5081'\n"),
|
||||
env=env)
|
||||
|
||||
|
||||
def test_set_nonexistent_subcommand(env):
|
||||
@@ -175,9 +167,8 @@ def test_set_when_extra_section():
|
||||
|
||||
|
||||
def test_unset_property(env):
|
||||
config_unset('core.reporting', env)
|
||||
_get_missing_value('core.reporting', env)
|
||||
config_set('core.reporting', 'false', env)
|
||||
with update_config("core.reporting", None, env):
|
||||
_get_missing_value('core.reporting', env)
|
||||
|
||||
|
||||
def test_unset_missing_property(env):
|
||||
@@ -233,35 +224,33 @@ def test_set_core_property(env):
|
||||
|
||||
|
||||
def test_url_validation(env):
|
||||
key = 'core.dcos_url'
|
||||
default_value = 'http://dcos.snakeoil.mesosphere.com'
|
||||
with update_config('core.dcos_url', None, env):
|
||||
key = 'core.dcos_url'
|
||||
key2 = 'package.cosmos_url'
|
||||
|
||||
key2 = 'package.cosmos_url'
|
||||
config_set(key, 'http://localhost', env)
|
||||
config_set(key, 'https://localhost', env)
|
||||
config_set(key, 'http://dcos-1234', env)
|
||||
config_set(key2, 'http://dcos-1234.mydomain.com', env)
|
||||
|
||||
config_set(key, 'http://localhost', env)
|
||||
config_set(key, 'https://localhost', env)
|
||||
config_set(key, 'http://dcos-1234', env)
|
||||
config_set(key2, 'http://dcos-1234.mydomain.com', env)
|
||||
config_set(key, 'http://localhost:5050', env)
|
||||
config_set(key, 'https://localhost:5050', env)
|
||||
config_set(key, 'http://mesos-1234:5050', env)
|
||||
config_set(key2, 'http://mesos-1234.mydomain.com:5050', env)
|
||||
|
||||
config_set(key, 'http://localhost:5050', env)
|
||||
config_set(key, 'https://localhost:5050', env)
|
||||
config_set(key, 'http://mesos-1234:5050', env)
|
||||
config_set(key2, 'http://mesos-1234.mydomain.com:5050', env)
|
||||
config_set(key, 'http://localhost:8080', env)
|
||||
config_set(key, 'https://localhost:8080', env)
|
||||
config_set(key, 'http://marathon-1234:8080', env)
|
||||
config_set(key2, 'http://marathon-1234.mydomain.com:5050', env)
|
||||
|
||||
config_set(key, 'http://localhost:8080', env)
|
||||
config_set(key, 'https://localhost:8080', env)
|
||||
config_set(key, 'http://marathon-1234:8080', env)
|
||||
config_set(key2, 'http://marathon-1234.mydomain.com:5050', env)
|
||||
config_set(key, 'http://user@localhost:8080', env)
|
||||
config_set(key, 'http://u-ser@localhost:8080', env)
|
||||
config_set(key, 'http://user123_@localhost:8080', env)
|
||||
config_set(key, 'http://user:p-ssw_rd@localhost:8080', env)
|
||||
config_set(key, 'http://user123:password321@localhost:8080', env)
|
||||
config_set(key2, 'http://us%r1$3:pa#sw*rd321@localhost:8080', env)
|
||||
|
||||
config_set(key, 'http://user@localhost:8080', env)
|
||||
config_set(key, 'http://u-ser@localhost:8080', env)
|
||||
config_set(key, 'http://user123_@localhost:8080', env)
|
||||
config_set(key, 'http://user:p-ssw_rd@localhost:8080', env)
|
||||
config_set(key, 'http://user123:password321@localhost:8080', env)
|
||||
config_set(key2, 'http://us%r1$3:pa#sw*rd321@localhost:8080', env)
|
||||
|
||||
config_set(key, default_value, env)
|
||||
config_unset(key2, env)
|
||||
config_unset(key2, env)
|
||||
|
||||
|
||||
def test_fail_url_validation(env):
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import base64
|
||||
import contextlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
import six
|
||||
|
||||
from dcos import subcommand
|
||||
from dcos import constants, subcommand
|
||||
|
||||
from .common import (assert_command, assert_lines, base64_to_dict,
|
||||
delete_zk_node, delete_zk_nodes, exec_command, file_json,
|
||||
@@ -18,6 +19,17 @@ from .common import (assert_command, assert_lines, base64_to_dict,
|
||||
from ..common import file_bytes
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def env():
|
||||
r = os.environ.copy()
|
||||
r.update({
|
||||
constants.PATH_ENV: os.environ[constants.PATH_ENV],
|
||||
constants.DCOS_CONFIG_ENV: os.path.join("tests", "data", "dcos.toml"),
|
||||
})
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def setup_module(module):
|
||||
setup_universe_server()
|
||||
|
||||
@@ -648,11 +660,12 @@ def test_list_cli():
|
||||
_uninstall_cli_helloworld()
|
||||
|
||||
|
||||
def test_list_cli_only():
|
||||
def test_list_cli_only(env):
|
||||
helloworld_path = 'tests/data/package/json/test_list_helloworld_cli.json'
|
||||
helloworld_json = file_json(helloworld_path)
|
||||
|
||||
with _helloworld_cli(), update_config('core.dcos_url', 'http://nohost'):
|
||||
with _helloworld_cli(), \
|
||||
update_config('core.dcos_url', 'http://nohost', env):
|
||||
assert_command(
|
||||
cmd=['dcos', 'package', 'list', '--json', '--cli'],
|
||||
stdout=helloworld_json)
|
||||
|
||||
@@ -2,7 +2,7 @@ import os
|
||||
|
||||
import pytest
|
||||
|
||||
from dcos import constants
|
||||
from dcos import config, constants
|
||||
|
||||
from .common import config_set, exec_command, update_config
|
||||
|
||||
@@ -22,11 +22,15 @@ def env():
|
||||
|
||||
@pytest.yield_fixture(autouse=True)
|
||||
def setup_env(env):
|
||||
# token will be removed when we change dcos_url
|
||||
token = config.get_config_val('core.dcos_acs_token')
|
||||
config_set("core.dcos_url", "https://dcos.snakeoil.mesosphere.com", env)
|
||||
config_set("core.dcos_acs_token", token, env)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
config_set("core.dcos_url", "http://dcos.snakeoil.mesosphere.com", env)
|
||||
config_set("core.dcos_acs_token", token, env)
|
||||
|
||||
|
||||
def test_dont_verify_ssl_with_env_var(env):
|
||||
|
||||
@@ -129,6 +129,11 @@ def set_val(name, value):
|
||||
value_exists = name in toml_config
|
||||
old_value = toml_config.get(name)
|
||||
|
||||
# remove token when core.dcos_url is changed
|
||||
token_unset = False
|
||||
if value_exists and old_value != new_value and name == "core.dcos_url":
|
||||
token_unset = bool(toml_config.pop("core.dcos_acs_token", False))
|
||||
|
||||
toml_config[name] = new_value
|
||||
|
||||
check_config(toml_config_pre, toml_config, section)
|
||||
@@ -150,6 +155,10 @@ def set_val(name, value):
|
||||
else:
|
||||
msg += "changed from '{}' to '{}'".format(old_value, new_value)
|
||||
|
||||
if token_unset:
|
||||
msg += ("\n[core.dcos_acs_token]: removed\n"
|
||||
"Please run `dcos auth login` to authenticate to new dcos_url")
|
||||
|
||||
return toml_config, msg
|
||||
|
||||
|
||||
@@ -220,13 +229,20 @@ def unset(name):
|
||||
if section not in toml_config_pre._dictionary:
|
||||
toml_config_pre._dictionary[section] = {}
|
||||
value = toml_config.pop(name, None)
|
||||
|
||||
if value is None:
|
||||
raise DCOSException("Property {!r} doesn't exist".format(name))
|
||||
elif isinstance(value, collections.Mapping):
|
||||
raise DCOSException(_generate_choice_msg(name, value))
|
||||
else:
|
||||
msg = "Removed [{}]".format(name)
|
||||
# dcos_acs_token is coupled to a specific dcos_url
|
||||
if name == "core.dcos_url":
|
||||
unset_token = bool(toml_config.pop("core.dcos_acs_token", None))
|
||||
if unset_token:
|
||||
msg += " and [core.dcos_acs_token]"
|
||||
save(toml_config)
|
||||
return "Removed [{}]".format(name)
|
||||
return msg
|
||||
|
||||
|
||||
def _generate_choice_msg(name, value):
|
||||
|
||||
20
dcos/http.py
20
dcos/http.py
@@ -1,12 +1,15 @@
|
||||
import requests
|
||||
from requests.auth import AuthBase
|
||||
|
||||
from six.moves.urllib.parse import urlparse
|
||||
|
||||
from dcos import config, util
|
||||
from dcos.errors import (DCOSAuthenticationException,
|
||||
DCOSAuthorizationException, DCOSBadRequest,
|
||||
DCOSException, DCOSHTTPException,
|
||||
DCOSUnprocessableException)
|
||||
|
||||
|
||||
logger = util.get_logger(__name__)
|
||||
|
||||
DEFAULT_TIMEOUT = 5
|
||||
@@ -144,12 +147,19 @@ def request(method,
|
||||
:rtype: Response
|
||||
"""
|
||||
|
||||
auth_token = config.get_config_val(
|
||||
"core.dcos_acs_token", config.get_config())
|
||||
if auth_token is None:
|
||||
auth = None
|
||||
else:
|
||||
toml_config = config.get_config()
|
||||
auth_token = config.get_config_val("core.dcos_acs_token", toml_config)
|
||||
dcos_url = urlparse(config.get_config_val("core.dcos_url", toml_config))
|
||||
parsed_url = urlparse(url)
|
||||
|
||||
# only request with DC/OS Auth if request is to DC/OS cluster
|
||||
# request should match scheme + netloc
|
||||
scheme_eq = parsed_url.scheme == dcos_url.scheme
|
||||
netloc_eq = parsed_url.netloc == dcos_url.netloc
|
||||
if auth_token and scheme_eq and netloc_eq:
|
||||
auth = DCOSAcsAuth(auth_token)
|
||||
else:
|
||||
auth = None
|
||||
response = _request(method, url, is_success, timeout,
|
||||
auth=auth, verify=verify, **kwargs)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user