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