Esempio n. 1
0
    def test__can_watch_fields(self):
        connect_to_field_change = self.patch_autospec(
            signals_module, "connect_to_field_change")
        connect_to_field_change.return_value = (
            sentinel.connect,
            sentinel.disconnect,
        )

        manager = SignalsManager()
        manager.watch_fields(sentinel.callback, sentinel.model,
                             sentinel.fields, sentinel.delete)

        self.assertThat(
            manager._signals,
            Equals({Signal(sentinel.connect, sentinel.disconnect)}),
        )
        self.assertThat(
            connect_to_field_change,
            MockCalledOnceWith(
                sentinel.callback,
                sentinel.model,
                sentinel.fields,
                sentinel.delete,
            ),
        )
Esempio n. 2
0
    """Updates the `StaticIPAddress`'s to ensure that they are linked to the
    correct subnet."""

    # Remove the IP addresses that no longer fall with in the CIDR.
    remove_ips = StaticIPAddress.objects.filter(
        alloc_type=IPADDRESS_TYPE.USER_RESERVED, subnet_id=subnet.id)
    remove_ips = remove_ips.extra(where=["NOT(ip << %s)"],
                                  params=[subnet.cidr])
    remove_ips.update(subnet=None)

    # Add the IP addresses that now fall into CIDR.
    add_ips = StaticIPAddress.objects.filter(subnet__isnull=True)
    add_ips = add_ips.extra(where=["ip << %s"], params=[subnet.cidr])
    add_ips.update(subnet_id=subnet.id)


def post_created(sender, instance, created, **kwargs):
    if created:
        update_referenced_ip_addresses(instance)


def updated_cidr(instance, old_values, **kwargs):
    update_referenced_ip_addresses(instance)


signals.watch(post_save, post_created, sender=Subnet)
signals.watch_fields(updated_cidr, Subnet, ["cidr"], delete=False)

# Enable all signals by default.
signals.enable()
Esempio n. 3
0
            alloc_type=IPADDRESS_TYPE.DISCOVERED
        ):
            instance.unlink_ip_address(ip_address, clearing_config=True)
        # If any of the children of this interface are now disabled, all of
        # their links need to be removed as well.
        for rel in instance.children_relationships.all():
            if not rel.child.is_enabled():
                for ip_address in rel.child.ip_addresses.all():
                    rel.child.unlink_ip_address(
                        ip_address, clearing_config=True
                    )


for klass in INTERFACE_CLASSES:
    signals.watch_fields(
        interface_enabled_or_disabled, klass, ["enabled"], delete=False
    )


def _update_mtu(interface, mtu, instance):
    log.msg(
        "%s: MTU updated to %d (for consistency with %s)."
        % (interface.get_log_string(), mtu, instance.get_log_string())
    )
    params = interface.params.copy()
    params["mtu"] = mtu
    interface.params = params
    interface.save()


def interface_mtu_params_update(instance, old_values, **kwargs):
Esempio n. 4
0
    This schedules a check of the node's power state after a delay of
    `WAIT_TO_QUERY`.

    :return: A `DelayedCall` instance, describing the pending update. Don't
        use this outside of the reactor thread though!
    """
    return clock.callLater(
        WAIT_TO_QUERY.total_seconds(), update_power_state_of_node, system_id
    )


@synchronous
def signal_update_power_state_of_node(instance, old_values, **kwargs):
    """Updates the power state of a node, when its status changes."""
    node = instance
    [old_status] = old_values

    # Only check the power state if it's an interesting transition.
    if old_status in QUERY_TRANSITIONS:
        if node.status in QUERY_TRANSITIONS[old_status]:
            post_commit().addCallback(
                callOut, update_power_state_of_node_soon, node.system_id
            )


signals.watch_fields(signal_update_power_state_of_node, Node, ["status"])


# Enable all signals by default.
signals.enable()
Esempio n. 5
0
        return
    node = instance
    [old_status] = old_values

    type_name = EVENT_TYPES.NODE_CHANGED_STATUS
    event_details = EVENT_DETAILS[type_name]
    description = "From '%s' to '%s'" % (
        NODE_STATUS_CHOICES_DICT[old_status],
        NODE_STATUS_CHOICES_DICT[node.status],
    )

    # Special-case for allocating nodes: we can include usernames here
    # to make the event log more useful.
    if node.status == NODE_STATUS.ALLOCATED:
        description += " (to %s)" % node.owner.username

    Event.objects.register_event_and_event_type(
        type_name,
        type_level=event_details.level,
        type_description=event_details.description,
        event_description=description,
        system_id=node.system_id)


signals.watch_fields(emit_state_transition_event,
                     Node, ['status'],
                     delete=False)

# Enable all signals by default.
signals.enable()
Esempio n. 6
0
        )
    else:
        old_status_name = None
        new_status_name = None
        for status, status_name in SCRIPT_STATUS_CHOICES:
            if old_status == status:
                old_status_name = status_name
            elif script_result.status == status:
                new_status_name = status_name
        Event.objects.create_node_event(
            script_result.script_set.node,
            EVENT_TYPES.SCRIPT_RESULT_CHANGED_STATUS,
            event_description="%s changed status from '%s' to '%s'" %
            (script_name, old_status_name, new_status_name),
        )
        if (CURTIN_INSTALL_LOG == script_result.name
                and not script_result.script_set.node.netboot):
            Event.objects.create_node_event(script_result.script_set.node,
                                            EVENT_TYPES.REBOOTING)


signals.watch_fields(
    emit_script_result_status_transition_event,
    ScriptResult,
    ["status"],
    delete=False,
)

# Enable all signals by default.
signals.enable()
Esempio n. 7
0
        # Was disabled. Remove the links.
        for ip_address in instance.ip_addresses.exclude(
                alloc_type=IPADDRESS_TYPE.DISCOVERED):
            instance.unlink_ip_address(ip_address, clearing_config=True)
        # If any of the children of this interface are now disabled, all of
        # their links need to be removed as well.
        for rel in instance.children_relationships.all():
            if not rel.child.is_enabled():
                for ip_address in rel.child.ip_addresses.all():
                    rel.child.unlink_ip_address(
                        ip_address, clearing_config=True)


for klass in INTERFACE_CLASSES:
    signals.watch_fields(
        interface_enabled_or_disabled,
        klass, ['enabled'], delete=False)


def _update_mtu(interface, mtu, instance):
    log.msg("%s: MTU updated to %d (for consistency with %s)." % (
        interface.get_log_string(), mtu, instance.get_log_string()))
    params = interface.params.copy()
    params['mtu'] = mtu
    interface.params = params
    interface.save()


def interface_mtu_params_update(instance, old_values, **kwargs):
    """When an interfaces MTU is changed we need to do two things.
Esempio n. 8
0
    type_name = EVENT_TYPES.NODE_CHANGED_STATUS
    event_details = EVENT_DETAILS[type_name]
    description = "From '%s' to '%s'" % (
        NODE_STATUS_CHOICES_DICT[old_status],
        NODE_STATUS_CHOICES_DICT[node.status],
    )

    # Special-case for allocating nodes: we can include usernames here
    # to make the event log more useful.
    if node.status == NODE_STATUS.ALLOCATED:
        description += " (to %s)" % node.owner.username

    Event.objects.register_event_and_event_type(
        type_name,
        type_level=event_details.level,
        type_description=event_details.description,
        event_description=description,
        system_id=node.system_id,
    )


for klass in NODE_CLASSES:
    # Watch the status of all classes, as the node might switch types.
    # Only if its a machine will the handler care.
    signals.watch_fields(emit_state_transition_event,
                         klass, ["status"],
                         delete=False)

# Enable all signals by default.
signals.enable()
Esempio n. 9
0
def clear_nodekey_when_owner_changes(node, old_values, deleted=False):
    """Erase related `NodeKey` when node ownership changes."""
    assert not deleted, ("clear_nodekey_when_owner_changes is not prepared "
                         "to deal with deletion of nodes.")

    owner_id_old = old_values[0]
    owner_id_new = node.owner_id

    if owner_id_new != owner_id_old:
        NodeKey.objects.clear_token_for_node(node)


for klass in NODE_CLASSES:
    signals.watch_fields(clear_nodekey_when_owner_changes,
                         klass, ['owner_id'],
                         delete=False)


def create_services_on_node_type_change(node, old_values, deleted=False):
    """Create services when node_type changes."""
    old_node_type = old_values[0]
    new_node_type = node.node_type
    if new_node_type != old_node_type:
        Service.objects.create_services_for(node)


def create_services_on_create(sender, instance, created, **kwargs):
    """Create services when node created."""
    if created:
        Service.objects.create_services_for(instance)