From e47d733281d18366076fe092082028fa2add8834 Mon Sep 17 00:00:00 2001 From: Quentin Madec Date: Fri, 3 Apr 2015 17:35:42 -0400 Subject: [PATCH] [flare] Warn user if not root As otherwise `supervisorctl status` won't be collected. Ask for email even to update a case, as it is now the 'id' to check if it is the good case (ie a case open by this customer). --- agent.py | 1 + packaging/centos/datadog-agent.init | 2 +- packaging/debian/datadog-agent.init | 2 +- tests/test_flare.py | 9 +++++---- utils/flare.py | 28 +++++++++++++++++++++------- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/agent.py b/agent.py index 4a13d47dbd..03c4b59fed 100755 --- a/agent.py +++ b/agent.py @@ -336,6 +336,7 @@ def parent_func(): agent.start_event = False print "If you think it's not normal please get in touch with Datadog Support" elif 'flare' == command: + Flare.check_user_rights() case_id = int(args[1]) if len(args) > 1 else None f = Flare(True, case_id) f.collect() diff --git a/packaging/centos/datadog-agent.init b/packaging/centos/datadog-agent.init index 148e89e104..c5d9381dfb 100644 --- a/packaging/centos/datadog-agent.init +++ b/packaging/centos/datadog-agent.init @@ -189,7 +189,7 @@ case "$1" in flare) shift - su $AGENTUSER -c "$AGENTPATH flare $@" + $AGENTPATH flare $@ exit $? ;; diff --git a/packaging/debian/datadog-agent.init b/packaging/debian/datadog-agent.init index d7c63234f7..8ebc67409a 100644 --- a/packaging/debian/datadog-agent.init +++ b/packaging/debian/datadog-agent.init @@ -160,7 +160,7 @@ case "$1" in flare) shift - su $AGENTUSER -c "$AGENTPATH flare $@" + $AGENTPATH flare $@ exit $? ;; diff --git a/tests/test_flare.py b/tests/test_flare.py index e88d69d8c4..4fdb45871f 100644 --- a/tests/test_flare.py +++ b/tests/test_flare.py @@ -59,9 +59,10 @@ def test_init(self, mock_config, mock_version, mock_tempdir, mock_strftime): @mock.patch('utils.flare.get_config', side_effect=get_mocked_config) def test_upload_with_case(self, mock_config, mock_tempdir, mock_stfrtime, mock_version, mock_requests): f = Flare(case_id=1337) + f._ask_for_email = lambda: 'test@example.com' assert not mock_requests.called - f.upload(confirmation=False) + f.upload() assert mock_requests.called args, kwargs = mock_requests.call_args_list[0] self.assertEqual( @@ -73,7 +74,7 @@ def test_upload_with_case(self, mock_config, mock_tempdir, mock_stfrtime, mock_v os.path.join(get_mocked_temp(), "datadog-agent-1.tar.bz2") ) self.assertEqual(kwargs['data']['case_id'], 1337) - self.assertEqual(kwargs['data']['email'], '') + self.assertEqual(kwargs['data']['email'], 'test@example.com') assert kwargs['data']['hostname'] @mock.patch('utils.flare.requests.post', return_value=FakeResponse()) @@ -86,7 +87,7 @@ def test_upload_no_case(self, mock_config, mock_tempdir, mock_stfrtime, mock_ver f._ask_for_email = lambda: 'test@example.com' assert not mock_requests.called - f.upload(confirmation=False) + f.upload() assert mock_requests.called args, kwargs = mock_requests.call_args_list[0] self.assertEqual( @@ -108,7 +109,7 @@ def test_endpoint(self, mock_config, mock_temp, mock_stfrtime): f = Flare() f._ask_for_email = lambda: None try: - f.upload(confirmation=False) + f.upload() raise Exception('Should fail before') except Exception, e: self.assertEqual(str(e), "Your request is incorrect: Invalid inputs: 'API key unknown'") diff --git a/utils/flare.py b/utils/flare.py index 48324b7660..e0339b2307 100644 --- a/utils/flare.py +++ b/utils/flare.py @@ -64,7 +64,7 @@ class Flare(object): APIKEY_REGEX = re.compile('^api_key: *\w+(\w{5})$') REPLACE_APIKEY = r'api_key: *************************\1' COMPRESSED_FILE = 'datadog-agent-{0}.tar.bz2' - # We limit to 10MB arbitrary + # We limit to 10MB arbitrarily MAX_UPLOAD_SIZE = 10485000 TIMEOUT = 60 @@ -82,6 +82,20 @@ def __init__(self, cmdline=False, case_id=None): self._hostname = get_hostname(config) self._prefix = "datadog-{0}".format(self._hostname) + # On Unix system, check that the user is root (to call supervisorctl & status) + # Otherwise emit a warning, and ask for confirmation + @staticmethod + def check_user_rights(): + if Platform.is_unix() and not os.geteuid() == 0: + log.warning("You are not root, some information won't be collected") + choice = raw_input('Are you sure you want to continue [y/N]? ').lower() + if choice not in ['yes', 'y']: + print 'Aborting' + sys.exit(1) + else: + log.warn('Your user has to have at least read access' + ' to the logs and conf files of the agent') + # Collect all conf and logs files and compress them def collect(self): if not self._api_key: @@ -103,10 +117,10 @@ def collect(self): self._tar.close() # Upload the tar file - def upload(self, confirmation=True): + def upload(self): self._check_size() - if confirmation: + if self._cmdline: self._ask_for_confirmation() email = self._ask_for_email() @@ -314,8 +328,8 @@ def _pip_freeze(self): # Check if the file is not too big before upload def _check_size(self): if os.path.getsize(self._tar_path) > self.MAX_UPLOAD_SIZE: - log.info('{0} won\'t be uploaded, its size is too important.\n' - 'You can send it directly to support by mail.') + log.info("{0} won't be uploaded, its size is too important.\n" + "You can send it directly to support by mail.") sys.exit(1) # Function to ask for confirmation before upload @@ -328,8 +342,8 @@ def _ask_for_confirmation(self): # Ask for email if needed def _ask_for_email(self): - if self._case_id: - return '' + # We ask everytime now, as it is also the 'id' to check + # that the case is the good one if it exists return raw_input('Please enter your email: ').lower() # Print output (success/error) of the request