Esempio n. 1
0
def retag_node_for_hardware_by_modalias(node, modaliases, parent_tag_name,
                                        hardware_descriptors):
    """Adds or removes tags on a node based on its modaliases.

    Returns the Tag model objects added and removed, respectively.

    :param node: The node whose tags to modify.
    :param modaliases: The modaliases discovered on the node.
    :param parent_tag_name: The tag name for the hardware type given in the
        `hardware_descriptors` list. For example, if switch ASICs are being
        discovered, the string "switch" might be appropriate. Then, if switch
        hardware is found, the node will be tagged with the matching
        descriptors' tag(s), *and* with the more general "switch" tag.
    :param hardware_descriptors: A list of hardware descriptor dictionaries.

    :returns: tuple of (tags_added, tags_removed)
    """
    # Don't unconditionally create the tag. Check for it with a filter first.
    parent_tag = get_one(Tag.objects.filter(name=parent_tag_name))
    tags_added = set()
    tags_removed = set()
    discovered_hardware, ruled_out_hardware = determine_hardware_matches(
        modaliases, hardware_descriptors)
    if len(discovered_hardware) > 0:
        if parent_tag is None:
            # Create the tag "just in time" if we found matching hardware, and
            # we hadn't created the tag yet.
            parent_tag = Tag(name=parent_tag_name)
            parent_tag.save()
        node.tags.add(parent_tag)
        tags_added.add(parent_tag)
        logger.info("%s: Added tag '%s' for detected hardware type." %
                    (node.hostname, parent_tag_name))
        for descriptor in discovered_hardware:
            tag = descriptor["tag"]
            comment = descriptor["comment"]
            matches = descriptor["matches"]
            hw_tag, _ = Tag.objects.get_or_create(
                name=tag, defaults={"comment": comment})
            node.tags.add(hw_tag)
            tags_added.add(hw_tag)
            logger.info("%s: Added tag '%s' for detected hardware: %s "
                        "(Matched: %s)." %
                        (node.hostname, tag, comment, matches))
    else:
        if parent_tag is not None:
            node.tags.remove(parent_tag)
            tags_removed.add(parent_tag)
            logger.info(
                "%s: Removed tag '%s'; machine does not match hardware "
                "description." % (node.hostname, parent_tag_name))
    for descriptor in ruled_out_hardware:
        tag_name = descriptor["tag"]
        existing_tag = get_one(node.tags.filter(name=tag_name))
        if existing_tag is not None:
            node.tags.remove(existing_tag)
            tags_removed.add(existing_tag)
            logger.info("%s: Removed tag '%s'; hardware is missing." %
                        (node.hostname, tag_name))
    return tags_added, tags_removed
Esempio n. 2
0
    def test__clears_node_set_before_populating(self):
        tag = Tag(name=factory.make_name("tag"), definition="//foo")
        tag.save(populate=False)

        nodes = [factory.make_Node() for _ in range(3)]
        tag.node_set.add(*nodes)
        tag._populate_nodes_now()
        self.assertItemsEqual([], tag.node_set.all())
Esempio n. 3
0
    def test__does_nothing_if_tag_is_not_defined(self):
        post_commit_do = self.patch(tag_module, "post_commit_do")

        tag = Tag(name=factory.make_name("tag"), definition="")
        tag.save(populate=False)

        self.assertFalse(tag.is_defined)
        self.assertThat(post_commit_do, MockNotCalled())
        tag._populate_nodes_later()
        self.assertThat(post_commit_do, MockNotCalled())
Esempio n. 4
0
    def test__does_nothing_if_tag_is_not_defined(self):
        populate_multiple = self.patch_autospec(
            populate_tags, "populate_tag_for_multiple_nodes")

        tag = Tag(name=factory.make_name("tag"), definition="")
        tag.save(populate=False)

        self.assertFalse(tag.is_defined)
        self.assertThat(populate_multiple, MockNotCalled())
        tag._populate_nodes_now()
        self.assertThat(populate_multiple, MockNotCalled())
Esempio n. 5
0
    def test__populates_if_tag_is_defined(self):
        populate_multiple = self.patch_autospec(
            populate_tags, "populate_tag_for_multiple_nodes")

        tag = Tag(name=factory.make_name("tag"), definition="//foo")
        tag.save(populate=False)

        self.assertTrue(tag.is_defined)
        self.assertThat(populate_multiple, MockNotCalled())
        tag._populate_nodes_now()
        self.assertThat(populate_multiple, MockCalledOnceWith(tag, ANY))
Esempio n. 6
0
    def test__populates_if_tag_is_defined(self):
        post_commit_do = self.patch(tag_module, "post_commit_do")

        tag = Tag(name=factory.make_name("tag"), definition="//foo")
        tag.save(populate=False)

        self.assertTrue(tag.is_defined)
        self.assertThat(post_commit_do, MockNotCalled())
        tag._populate_nodes_later()
        self.assertThat(
            post_commit_do,
            MockCalledOnceWith(reactor.callLater, 0, deferToDatabase,
                               populate_tags.populate_tags, tag))
Esempio n. 7
0
    def test__does_not_clear_node_set_before_populating(self):
        post_commit_do = self.patch(tag_module, "post_commit_do")

        tag = Tag(name=factory.make_name("tag"), definition="//foo")
        tag.save(populate=False)

        nodes = [factory.make_Node() for _ in range(3)]
        tag.node_set.add(*nodes)
        tag._populate_nodes_later()
        self.assertItemsEqual(nodes, tag.node_set.all())
        self.assertThat(
            post_commit_do,
            MockCalledOnceWith(reactor.callLater, 0, deferToDatabase,
                               populate_tags.populate_tags, tag))
Esempio n. 8
0
 def test_is_defined(self):
     tag = Tag(name="tag", definition=self.definition)
     self.assertIs(self.expected, tag.is_defined)
Esempio n. 9
0
 def test_applies_tags_to_nodes_on_save(self):
     populate_nodes = self.patch_autospec(Tag, "populate_nodes")
     tag = Tag(name=factory.make_name("tag"), definition="//node/child")
     self.assertThat(populate_nodes, MockNotCalled())
     tag.save()
     self.assertThat(populate_nodes, MockCalledOnceWith(tag))
Esempio n. 10
0
 def test__later_is_the_default(self):
     tag = Tag(name=factory.make_name("tag"))
     self.patch(tag, "_populate_nodes_later")
     self.assertThat(tag._populate_nodes_later, MockNotCalled())
     tag.save()
     self.assertThat(tag._populate_nodes_later, MockCalledOnceWith())