error based on user command auth not auth to get CLUSTER_ID

We try to get the CLUSTER_ID before we run the user specified command.
If the user if authenticated, but not authorized (to get the
CLUSTER_ID), let them continue and error based on access to the command
they ran.
This commit is contained in:
Tamar Ben-Shachar
2016-02-22 17:29:11 -08:00
parent ff45e211e9
commit be43c3cf88
4 changed files with 38 additions and 11 deletions

View File

@@ -9,7 +9,7 @@ import docopt
import pkg_resources import pkg_resources
from dcos import (auth, constants, emitting, errors, http, mesos, subcommand, from dcos import (auth, constants, emitting, errors, http, mesos, subcommand,
util) util)
from dcos.errors import DCOSException from dcos.errors import DCOSAuthenticationException, DCOSException
from dcoscli import analytics from dcoscli import analytics
logger = util.get_logger(__name__) logger = util.get_logger(__name__)
@@ -57,11 +57,12 @@ def _main():
executable = subcommand.command_executables(command) executable = subcommand.command_executables(command)
cluster_id = None cluster_id = None
if dcoscli.version != 'SNAPSHOT' and command and command != "config": if dcoscli.version != 'SNAPSHOT' and command and \
command not in ["config", "help"]:
try: try:
cluster_id = mesos.DCOSClient().metadata().get('CLUSTER_ID') cluster_id = mesos.DCOSClient().metadata().get('CLUSTER_ID')
except DCOSException: except DCOSAuthenticationException:
raise raise
except: except:
msg = 'Unable to get the cluster_id of the cluster.' msg = 'Unable to get the cluster_id of the cluster.'
logger.exception(msg) logger.exception(msg)

View File

@@ -1,5 +1,5 @@
from dcos import emitting, http, util from dcos import emitting, http, util
from dcos.errors import DCOSException, DCOSHTTPException from dcos.errors import DCOSAuthenticationException
from six.moves import urllib from six.moves import urllib
@@ -26,9 +26,7 @@ class Cosmos:
headers=_get_cosmos_header("capabilities")) headers=_get_cosmos_header("capabilities"))
# return `Authentication failed` error messages, but all other errors # return `Authentication failed` error messages, but all other errors
# are treated as endpoint not available # are treated as endpoint not available
except DCOSHTTPException: except DCOSAuthenticationException:
return False
except DCOSException:
raise raise
except Exception as e: except Exception as e:
logger.exception(e) logger.exception(e)

View File

@@ -21,6 +21,32 @@ class DCOSHTTPException(DCOSException):
self.response.reason) self.response.reason)
class DCOSAuthenticationException(DCOSHTTPException):
"""A wrapper around Response objects for HTTP Authentication errors (401).
:param response: requests Response object
:type response: Response
"""
def __init__(self, response):
self.response = response
def __str__(self):
return "Authentication failed"
class DCOSAuthorizationException(DCOSHTTPException):
"""A wrapper around Response objects for HTTP Authorization errors (403).
:param response: requests Response object
:type response: Response
"""
def __init__(self, response):
self.response = response
def __str__(self):
return "You are not authorized to perform this operation"
class Error(object): class Error(object):
"""Abstract class for describing errors.""" """Abstract class for describing errors."""

View File

@@ -5,7 +5,9 @@ import threading
import requests import requests
from dcos import config, constants, util from dcos import config, constants, util
from dcos.errors import DCOSException, DCOSHTTPException from dcos.errors import (DCOSAuthenticationException,
DCOSAuthorizationException, DCOSException,
DCOSHTTPException)
from requests.auth import AuthBase, HTTPBasicAuth from requests.auth import AuthBase, HTTPBasicAuth
from six.moves import urllib from six.moves import urllib
@@ -147,7 +149,7 @@ def _request_with_auth(response,
i += 1 i += 1
if response.status_code == 401: if response.status_code == 401:
raise DCOSException("Authentication failed") raise DCOSAuthenticationException(response)
return response return response
@@ -201,7 +203,7 @@ def request(method,
if is_success(response.status_code): if is_success(response.status_code):
return response return response
elif response.status_code == 403: elif response.status_code == 403:
raise DCOSException("You are not authorized to perform this operation") raise DCOSAuthorizationException(response)
else: else:
raise DCOSHTTPException(response) raise DCOSHTTPException(response)