Revision 460ef073
b/lib/rapi/rlib2.py | ||
---|---|---|
1199 | 1199 |
return self.GetClient().QueryFields(self.items[0], fields).ToDict() |
1200 | 1200 |
|
1201 | 1201 |
|
1202 |
class _R_Tags(baserlib.ResourceBase):
|
|
1202 |
class _R_Tags(baserlib.OpcodeResource):
|
|
1203 | 1203 |
""" Quasiclass for tagging resources |
1204 | 1204 |
|
1205 | 1205 |
Manages tags. When inheriting this class you must define the |
... | ... | |
1207 | 1207 |
|
1208 | 1208 |
""" |
1209 | 1209 |
TAG_LEVEL = None |
1210 |
PUT_OPCODE = opcodes.OpTagsSet |
|
1211 |
DELETE_OPCODE = opcodes.OpTagsDel |
|
1210 | 1212 |
|
1211 |
def __init__(self, items, queryargs, req): |
|
1213 |
def __init__(self, items, queryargs, req, **kwargs):
|
|
1212 | 1214 |
"""A tag resource constructor. |
1213 | 1215 |
|
1214 | 1216 |
We have to override the default to sort out cluster naming case. |
1215 | 1217 |
|
1216 | 1218 |
""" |
1217 |
baserlib.ResourceBase.__init__(self, items, queryargs, req)
|
|
1219 |
baserlib.OpcodeResource.__init__(self, items, queryargs, req, **kwargs)
|
|
1218 | 1220 |
|
1219 | 1221 |
if self.TAG_LEVEL == constants.TAG_CLUSTER: |
1220 | 1222 |
self.name = None |
... | ... | |
1255 | 1257 |
|
1256 | 1258 |
return list(tags) |
1257 | 1259 |
|
1258 |
def PUT(self):
|
|
1260 |
def GetPutOpInput(self):
|
|
1259 | 1261 |
"""Add a set of tags. |
1260 | 1262 |
|
1261 | 1263 |
The request as a list of strings should be PUT to this URI. And |
1262 | 1264 |
you'll have back a job id. |
1263 | 1265 |
|
1264 | 1266 |
""" |
1265 |
# pylint: disable-msg=W0212 |
|
1266 |
if "tag" not in self.queryargs: |
|
1267 |
raise http.HttpBadRequest("Please specify tag(s) to add using the" |
|
1268 |
" the 'tag' parameter") |
|
1269 |
op = opcodes.OpTagsSet(kind=self.TAG_LEVEL, name=self.name, |
|
1270 |
tags=self.queryargs["tag"], dry_run=self.dryRun()) |
|
1271 |
return self.SubmitJob([op]) |
|
1267 |
return ({}, { |
|
1268 |
"kind": self.TAG_LEVEL, |
|
1269 |
"name": self.name, |
|
1270 |
"tags": self.queryargs.get("tag", []), |
|
1271 |
"dry_run": self.dryRun(), |
|
1272 |
}) |
|
1272 | 1273 |
|
1273 |
def DELETE(self):
|
|
1274 |
def GetDeleteOpInput(self):
|
|
1274 | 1275 |
"""Delete a tag. |
1275 | 1276 |
|
1276 | 1277 |
In order to delete a set of tags, the DELETE |
... | ... | |
1278 | 1279 |
/tags?tag=[tag]&tag=[tag] |
1279 | 1280 |
|
1280 | 1281 |
""" |
1281 |
# pylint: disable-msg=W0212 |
|
1282 |
if "tag" not in self.queryargs: |
|
1283 |
# no we not gonna delete all tags |
|
1284 |
raise http.HttpBadRequest("Cannot delete all tags - please specify" |
|
1285 |
" tag(s) using the 'tag' parameter") |
|
1286 |
op = opcodes.OpTagsDel(kind=self.TAG_LEVEL, name=self.name, |
|
1287 |
tags=self.queryargs["tag"], dry_run=self.dryRun()) |
|
1288 |
return self.SubmitJob([op]) |
|
1282 |
# Re-use code |
|
1283 |
return self.GetPutOpInput() |
|
1289 | 1284 |
|
1290 | 1285 |
|
1291 | 1286 |
class R_2_instances_name_tags(_R_Tags): |
b/test/ganeti.rapi.rlib2_unittest.py | ||
---|---|---|
699 | 699 |
self.assertRaises(http.HttpBadRequest, handler.PUT) |
700 | 700 |
|
701 | 701 |
|
702 |
class TestTags(unittest.TestCase): |
|
703 |
TAG_HANDLERS = [ |
|
704 |
rlib2.R_2_instances_name_tags, |
|
705 |
rlib2.R_2_nodes_name_tags, |
|
706 |
rlib2.R_2_groups_name_tags, |
|
707 |
rlib2.R_2_tags, |
|
708 |
] |
|
709 |
|
|
710 |
def testSetAndDelete(self): |
|
711 |
clfactory = _FakeClientFactory(_FakeClient) |
|
712 |
|
|
713 |
for method, opcls in [("PUT", opcodes.OpTagsSet), |
|
714 |
("DELETE", opcodes.OpTagsDel)]: |
|
715 |
for idx, handler in enumerate(self.TAG_HANDLERS): |
|
716 |
dry_run = bool(idx % 2) |
|
717 |
name = "test%s" % idx |
|
718 |
queryargs = { |
|
719 |
"tag": ["foo", "bar", "baz"], |
|
720 |
"dry-run": str(int(dry_run)), |
|
721 |
} |
|
722 |
|
|
723 |
handler = _CreateHandler(handler, [name], queryargs, {}, clfactory) |
|
724 |
job_id = getattr(handler, method)() |
|
725 |
|
|
726 |
cl = clfactory.GetNextClient() |
|
727 |
self.assertRaises(IndexError, clfactory.GetNextClient) |
|
728 |
|
|
729 |
(exp_job_id, (op, )) = cl.GetNextSubmittedJob() |
|
730 |
self.assertEqual(job_id, exp_job_id) |
|
731 |
self.assertTrue(isinstance(op, opcls)) |
|
732 |
self.assertEqual(op.kind, handler.TAG_LEVEL) |
|
733 |
if handler.TAG_LEVEL == constants.TAG_CLUSTER: |
|
734 |
self.assertTrue(op.name is None) |
|
735 |
else: |
|
736 |
self.assertEqual(op.name, name) |
|
737 |
self.assertEqual(op.tags, ["foo", "bar", "baz"]) |
|
738 |
self.assertEqual(op.dry_run, dry_run) |
|
739 |
self.assertFalse(hasattr(op, "force")) |
|
740 |
|
|
741 |
self.assertRaises(IndexError, cl.GetNextSubmittedJob) |
|
742 |
|
|
743 |
|
|
702 | 744 |
class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase): |
703 | 745 |
def setUp(self): |
704 | 746 |
testutils.GanetiTestCase.setUp(self) |
Also available in: Unified diff