Merge ~ltrager/maas:lp1916317_2.9 into maas:2.9

Proposed by Lee Trager
Status: Merged
Approved by: Lee Trager
Approved revision: 3bb737249f737f8959788efaecadfee890888839
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ltrager/maas:lp1916317_2.9
Merge into: maas:2.9
Diff against target: 158 lines (+117/-4)
2 files modified
src/maasserver/websockets/handlers/script.py (+35/-2)
src/maasserver/websockets/handlers/tests/test_script.py (+82/-2)
Reviewer Review Type Date Requested Status
Lee Trager (community) Approve
MAAS Lander unittests Pending
Review via email: mp+398663@code.launchpad.net

Commit message

LP: #1916317 - Add web socket function to delete or download Script content

Backport of 6fa37cd

To post a comment you must log in.
Revision history for this message
Lee Trager (ltrager) :
review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/websockets/handlers/script.py b/src/maasserver/websockets/handlers/script.py
2index 19db14c..c46a4f9 100644
3--- a/src/maasserver/websockets/handlers/script.py
4+++ b/src/maasserver/websockets/handlers/script.py
5@@ -1,9 +1,14 @@
6-# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
7+# Copyright 2017-2021 Canonical Ltd. This software is licensed under the
8 # GNU Affero General Public License version 3 (see the file LICENSE).
9
10 """The Script handler for the WebSocket connection."""
11
12
13+from maasserver.permissions import NodePermission
14+from maasserver.websockets.base import (
15+ HandlerDoesNotExistError,
16+ HandlerPermissionError,
17+)
18 from maasserver.websockets.handlers.timestampedmodel import (
19 TimestampedModelHandler,
20 )
21@@ -14,5 +19,33 @@ class ScriptHandler(TimestampedModelHandler):
22 class Meta:
23 queryset = Script.objects.all()
24 pk = "id"
25- allowed_methods = ["list"]
26+ allowed_methods = [
27+ "delete",
28+ "get_script",
29+ "list",
30+ ]
31 listen_channels = ["script"]
32+
33+ def delete(self, params):
34+ script = self.get_object(params)
35+ if not self.user.has_perm(NodePermission.admin) or script.default:
36+ raise HandlerPermissionError()
37+ script.delete()
38+
39+ def get_script(self, params):
40+ id = params.get("id")
41+ revision = params.get("revision")
42+ script = self.get_object(params)
43+ if not script:
44+ raise HandlerDoesNotExistError(
45+ f"Script with id({id}) does not exist!"
46+ )
47+ if revision:
48+ for rev in script.script.previous_versions():
49+ if rev.id == revision:
50+ return rev.data
51+ raise HandlerDoesNotExistError(
52+ f"Unable to find revision {revision} for {script.name}."
53+ )
54+ else:
55+ return script.script.data
56diff --git a/src/maasserver/websockets/handlers/tests/test_script.py b/src/maasserver/websockets/handlers/tests/test_script.py
57index 8ddf5cd..5c778fe 100644
58--- a/src/maasserver/websockets/handlers/tests/test_script.py
59+++ b/src/maasserver/websockets/handlers/tests/test_script.py
60@@ -1,12 +1,18 @@
61-# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
62+# Copyright 2017-2021 Canonical Ltd. This software is licensed under the
63 # GNU Affero General Public License version 3 (see the file LICENSE).
64
65 """Tests for `maasserver.websockets.handlers.script`"""
66
67+import random
68
69 from maasserver.testing.factory import factory
70 from maasserver.testing.testcase import MAASServerTestCase
71-from maasserver.websockets.base import dehydrate_datetime
72+from maasserver.utils.orm import reload_object
73+from maasserver.websockets.base import (
74+ dehydrate_datetime,
75+ HandlerDoesNotExistError,
76+ HandlerPermissionError,
77+)
78 from maasserver.websockets.handlers.script import ScriptHandler
79
80
81@@ -52,3 +58,77 @@ class TestScriptHandler(MAASServerTestCase):
82 sorted_results = sorted(handler.list({}), key=lambda i: i["id"])
83 for expected, real in zip(expected_scripts, sorted_results):
84 self.assertDictEqual(expected, real)
85+
86+ def test_delete(self):
87+ script = factory.make_Script()
88+ admin = factory.make_admin()
89+ handler = ScriptHandler(admin, {}, None)
90+
91+ handler.delete({"id": script.id})
92+
93+ self.assertIsNone(reload_object(script))
94+
95+ def test_delete_admin_only(self):
96+ script = factory.make_Script()
97+ user = factory.make_User()
98+ handler = ScriptHandler(user, {}, None)
99+
100+ self.assertRaises(
101+ HandlerPermissionError, handler.delete, {"id": script.id}
102+ )
103+
104+ self.assertIsNotNone(reload_object(script))
105+
106+ def test_delete_cannot_delete_default(self):
107+ script = factory.make_Script(default=True)
108+ admin = factory.make_admin()
109+ handler = ScriptHandler(admin, {}, None)
110+
111+ self.assertRaises(
112+ HandlerPermissionError, handler.delete, {"id": script.id}
113+ )
114+
115+ self.assertIsNotNone(reload_object(script))
116+
117+ def test_get_script(self):
118+ script = factory.make_Script()
119+ user = factory.make_User()
120+ handler = ScriptHandler(user, {}, None)
121+
122+ self.assertEqual(
123+ script.script.data, handler.get_script({"id": script.id})
124+ )
125+
126+ def test_get_script_not_found(self):
127+ user = factory.make_User()
128+ handler = ScriptHandler(user, {}, None)
129+
130+ self.assertRaises(
131+ HandlerDoesNotExistError,
132+ handler.get_script,
133+ {"id": random.randint(1000, 10000)},
134+ )
135+
136+ def test_get_script_revision(self):
137+ script = factory.make_Script()
138+ old_vtf = script.script
139+ script.script = script.script.update(factory.make_string())
140+ script.save()
141+ user = factory.make_User()
142+ handler = ScriptHandler(user, {}, None)
143+
144+ self.assertEqual(
145+ old_vtf.data,
146+ handler.get_script({"id": script.id, "revision": old_vtf.id}),
147+ )
148+
149+ def test_get_script_revision_not_found(self):
150+ script = factory.make_Script()
151+ user = factory.make_User()
152+ handler = ScriptHandler(user, {}, None)
153+
154+ self.assertRaises(
155+ HandlerDoesNotExistError,
156+ handler.get_script,
157+ {"id": script.id, "revision": random.randint(1000, 10000)},
158+ )

Subscribers

People subscribed via source and target branches