Skip to content

Commit 2caf5b8

Browse files
Implement get_log_file method returning dictionary of lists of indices of each webapp log type based on list of files gathered using API.
1 parent f0f851e commit 2caf5b8

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

pythonanywhere/api.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,38 @@ def delete_log(self, log_type, index=0):
214214
response_text=response.text,
215215
)
216216
)
217+
218+
def get_log_info(self):
219+
url = get_api_endpoint().format(username=getpass.getuser(),
220+
flavor="files") + "tree/?path=/var/log/"
221+
response = call_api(url, "get")
222+
if not response.ok:
223+
raise Exception(
224+
"GET log files info via API failed, got {response}:{response_text}".format(
225+
response=response,
226+
response_text=response.text,
227+
)
228+
)
229+
if response.text[0] == "[" and response.text[-1] == "]":
230+
file_list = eval(response.text)
231+
else:
232+
raise Exception(
233+
"GET log files info via API failed, got {text} instead of list of files".format(text=response.text))
234+
log_types = ["access", "error", "server"]
235+
logs = {"access": [], "error": [], "server": []}
236+
log_prefix = "/var/log/{domain}.".format(domain=self.domain)
237+
for file in file_list:
238+
if type(file) == str and file.startswith(log_prefix):
239+
log = file[len(log_prefix):].split(".")
240+
if log[0] in log_types:
241+
log_type = log[0]
242+
if log[-1] == "log":
243+
log_index = 0
244+
elif log[-1] == "1":
245+
log_index = 1
246+
elif log[-1] == "gz":
247+
log_index = int(log[-2])
248+
else:
249+
continue
250+
logs[log_type].append(log_index)
251+
return logs

tests/test_api.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ def test_delete_old_access_log(self, api_responses, api_token):
356356
assert post.request.body is None
357357
assert post.request.headers['Authorization'] == 'Token {api_token}'.format(api_token=api_token)
358358

359-
def test_raises_if_post_does_not_20x(self, api_responses, api_token):
359+
def test_raises_if_delete_does_not_20x(self, api_responses, api_token):
360360
expected_url = get_api_endpoint().format(
361361
username=getpass.getuser(), flavor="files") + "path/var/log/mydomain.com.access.log/"
362362
api_responses.add(responses.DELETE, expected_url, status=404, body="nope")
@@ -366,3 +366,48 @@ def test_raises_if_post_does_not_20x(self, api_responses, api_token):
366366

367367
assert "DELETE log file via API failed" in str(e.value)
368368
assert "nope" in str(e.value)
369+
370+
371+
class TestGetWebappLogs:
372+
373+
def test_get_list_of_logs(self, api_responses, api_token):
374+
expected_url = get_api_endpoint().format(
375+
username=getpass.getuser(), flavor="files") + "tree/?path=/var/log/"
376+
api_responses.add(responses.GET, expected_url, status=200,
377+
body="['/var/log/blah','/var/log/mydomain.com.access.log',\
378+
'/var/log/mydomain.com.access.log.1',\
379+
'/var/log/mydomain.com.access.log.2.gz',\
380+
'/var/log/mydomain.com.error.log',\
381+
'/var/log/mydomain.com.error.log.1',\
382+
'/var/log/mydomain.com.error.log.2.gz',\
383+
'/var/log/mydomain.com.server.log',\
384+
'/var/log/mydomain.com.server.log.1',\
385+
'/var/log/mydomain.com.server.log.2.gz']")
386+
387+
logs = Webapp("mydomain.com").get_log_info()
388+
389+
post = api_responses.calls[0]
390+
assert post.request.url == expected_url
391+
assert post.request.headers['Authorization'] == 'Token {api_token}'.format(api_token=api_token)
392+
assert logs == {"access": [0, 1, 2], "error": [0, 1, 2], "server": [0, 1, 2]}
393+
394+
def test_raises_if_get_does_not_20x(self, api_responses, api_token):
395+
expected_url = get_api_endpoint().format(
396+
username=getpass.getuser(), flavor="files") + "tree/?path=/var/log/"
397+
api_responses.add(responses.GET, expected_url, status=404, body="nope")
398+
399+
with pytest.raises(Exception) as e:
400+
Webapp("mydomain.com").get_log_info()
401+
402+
assert "GET log files info via API failed" in str(e.value)
403+
assert "nope" in str(e.value)
404+
405+
def test_raises_if_response_text_not_list(self, api_responses, api_token):
406+
expected_url = get_api_endpoint().format(
407+
username=getpass.getuser(), flavor="files") + "tree/?path=/var/log/"
408+
api_responses.add(responses.GET, expected_url, status=200, body="print('Behold malicious code')")
409+
410+
with pytest.raises(Exception) as e:
411+
Webapp("mydomain.com").get_log_info()
412+
413+
assert "GET log files info via API failed, got print('Behold malicious code')" in str(e.value)

0 commit comments

Comments
 (0)