peterknife / boto

Automatically exported from code.google.com/p/boto
0 stars 0 forks source link

remove_tag() always deletes tag from internal dictionnary even when "value" does not match #591

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago

What steps will reproduce the problem?
1. Add a tag to any e2 object (e.g. ec2.Instance or Subnet) with a certain 
value. 
2. Call the remove_tag() on that object while specifying a _DIFFERENT VALUE_ 
than the one set. According to documentation, the tag should NOT be removed.
3. Look at the .tags of the object : the tag will have been removed, although 
it still exists on the "real" AWS object.

Code sample:
# Assuming object is an existing Instance/Subnet/Vpc/..
object.add_tag("TEST", "abcdef")     # Note that the value is abcdef
object("Before:" + str(object.tags))
object.remove_tag("TEST", "123456")  # Value is wrong, WONT be deleted from AWS
print("After:" + str(object.tags))   # It was deleted? Wuuuut?

What is the expected output? What do you see instead?
remove_tag with incorrect value should _NOT_ be deleted (according to doc), but 
internally, they are.

What version of the product are you using? On what operating system?
Boto 2.31.1 on Linux CentOS 6 (python 2.6.6)

Please provide any additional information below.
This might be a problem with the documentation OR the implementation.
The documentation of remove_tag states:
   "An optional value that can be stored with the tag.
   If a value is provided, it must match the value
   currently stored in EC2.  If not, the tag will not
   be removed.  If a value of None is provided, all
   tags with the specified name will be deleted."

However, the code is as follow:
boto/ec2/ec2object.py (line 126)
        if value is not None:
            tags = {key : value}
        else:
            tags = [key]
        status = self.connection.delete_tags(
            [self.id],
            tags,
            dry_run=dry_run
        )
        if key in self.tags:
            del self.tags[key]

AWS will not delete the tag if the value does not match but boto never perform 
this verification. So remove_tag() will ALWAYS delete the tag from the internal 
dictionary, but it might still exists on the "real" AWS object. 
This behavior is _very_ confusing to the end users because they might think 
their tag got deleted since they are no longer in the internal dict but in 
reality AWS would still have them.
Mitigation for the end users is to reload the object _each time_ a remove_tag() 
is performed, but that implies a deep understanding of the internal of the 
library. 

Original issue reported on code.google.com by wbour...@secureops.com on 16 Jul 2014 at 4:17