def test_update_change_cluster(self):
        cluster_old = ClusterFactory(name='f5-1-fake-old')
        ethernet = EthernetFactory(base_object=cluster_old)
        vip = VIPFactory(
            ip=IPAddressFactory(ethernet=ethernet),
            parent=cluster_old,
        )
        self.data['load_balancer'] = 'f5-1-fake-new'
        self.data['ip'] = vip.ip.address
        self.data['port'] = vip.port
        self.data['protocol'] = VIPProtocol.from_id(vip.protocol).name

        self.assertEqual(VIP.objects.count(), 1)
        self.assertEqual(Cluster.objects.count(), 1)
        self.assertEqual(Ethernet.objects.count(), 1)

        handle_update_vip_event(self.data)

        vips = VIP.objects.all()
        self.assertEqual(vips.count(), 1)
        self.assertEqual(Cluster.objects.count(), 2)
        self.assertEqual(Ethernet.objects.count(), 1)
        self.assertEqual(vips[0].ip.ethernet, ethernet)
        self.assertEqual(
            Ethernet.objects.get(
                id=ethernet.id).base_object.last_descendant.name,
            self.data['load_balancer'])
Example #2
0
    def test_delete_with_valid_event_data(self):
        vip = VIPFactory()
        self.data['ip'] = vip.ip.address
        self.data['port'] = vip.port
        self.data['protocol'] = VIPProtocol.from_id(vip.protocol).name

        self.assertEqual(VIP.objects.count(), 1)
        handle_delete_vip_event(self.data)
        self.assertEqual(VIP.objects.count(), 0)
Example #3
0
def handle_create_vip_event(data):
    errors = validate_vip_event_data(data)
    if errors:
        msg = ('Error(s) detected in event data: %s. Ignoring received create '
               'event.')
        logger.error(msg, '; '.join(errors))
        return

    # Check if VIP already exists.
    ip, ip_created = IPAddress.objects.get_or_create(address=data['ip'])
    protocol = VIPProtocol.from_name(data['protocol'].upper())
    vip = get_vip(ip, data['port'], protocol)
    if vip:
        msg = ('VIP designated by IP address %s, port %s and protocol %s '
               'already exists. Ignoring received event.')
        logger.warning(msg, ip.address, data['port'], protocol.name)
        return

    # Create it.
    cluster_type, _ = ClusterType.objects.get_or_create(
        name=data['load_balancer_type'])
    cluster, _ = Cluster.objects.get_or_create(
        name=data['load_balancer'],
        type=cluster_type,
    )
    if ip_created:
        eth = Ethernet.objects.create(base_object=cluster)
        ip.ethernet = eth
        ip.save()
    elif ip.dhcp_expose:
        logger.error(
            'Trying to create VIP with IP %s, port %s and protocol %s '
            'failed because IP is exposed in dhcp', ip.address, data['port'],
            protocol.name)
        return
    try:
        service_env = ServiceEnvironment.objects.get(
            service__uid=data['service']['uid'],
            environment__name=data['environment'],
        )
    except ServiceEnvironment.DoesNotExist:
        msg = ('ServiceEnvironment for service UID "%s" and environment "%s" '
               'does not exist. Ignoring received create event.')
        logger.error(msg, data['service']['uid'], data['environment'])
        return
    vip = VIP(
        name=data['name'],
        ip=ip,
        port=data['port'],
        protocol=protocol,
        parent=cluster,
        service_env=service_env,
    )
    vip.save()
    logger.debug('VIP %s created successfully.', vip.name)
Example #4
0
def handle_update_vip_event(data):
    errors = validate_vip_event_data(data)
    if errors:
        msg = ('Error(s) detected in event data: %s. Ignoring received update '
               'event.')
        logger.error(msg, '; '.join(errors))
        return

    ip, _ = IPAddress.objects.get_or_create(address=data['ip'])
    protocol = VIPProtocol.from_name(data['protocol'].upper())
    if ip.dhcp_expose:
        logger.error(
            'Trying to update VIP with IP %s, port %s and protocol %s '
            'failed because IP is exposed in dhcp', ip.address, data['port'],
            protocol.name)
        return

    vip = get_vip(ip, data['port'], protocol)
    if vip is None:
        # VIP not found, should create new one.
        return handle_create_vip_event(data)

    # update cluster.
    cluster_type, _ = ClusterType.objects.get_or_create(
        name=data['load_balancer_type'])
    cluster, _ = Cluster.objects.get_or_create(
        name=data['load_balancer'],
        type=cluster_type,
    )

    if (vip.parent != cluster
            or (ip.ethernet and ip.ethernet.base_object != cluster)):
        with transaction.atomic():
            for migrated_vip in VIP.objects.select_for_update().filter(ip=ip):
                migrate_vip_to_cluster(migrated_vip, cluster, protocol)

    # update service/environment if changed.
    try:
        service_env = ServiceEnvironment.objects.get(
            service__uid=data['service']['uid'],
            environment__name=data['environment'],
        )
    except ServiceEnvironment.DoesNotExist:
        msg = ('ServiceEnvironment for service UID "%s" and environment "%s" '
               'does not exist. Ignoring received update event.')
        logger.error(msg, data['service']['uid'], data['environment'])
        return

    if vip.service_env != service_env:
        vip.service_env = service_env
        vip.save()
        logger.debug('VIP %s changed service/env to %s.', vip.name,
                     service_env)

    logger.debug('VIP %s update processed successfuly.', vip.name)
Example #5
0
    def test_delete_when_ip_does_not_exist(self):
        vip = VIPFactory()
        ip = IPAddressFactory()
        self.data['ip'] = ip.address
        ip.delete()
        self.data['port'] = vip.port
        self.data['protocol'] = VIPProtocol.from_id(vip.protocol).name

        self.assertEqual(VIP.objects.count(), 1)
        handle_delete_vip_event(self.data)
        self.assertEqual(VIP.objects.count(), 1)
Example #6
0
    def test_ip_with_eth_being_deleted_when_no_longer_used(self):
        vip = VIPFactory()
        self.data['ip'] = vip.ip.address
        self.data['port'] = vip.port
        self.data['protocol'] = VIPProtocol.from_id(vip.protocol).name

        self.assertEqual(VIP.objects.count(), 1)
        self.assertEqual(IPAddress.objects.count(), 1)
        self.assertEqual(Ethernet.objects.count(), 1)
        handle_delete_vip_event(self.data)
        self.assertEqual(VIP.objects.count(), 0)
        self.assertEqual(IPAddress.objects.count(), 0)
        self.assertEqual(Ethernet.objects.count(), 0)
Example #7
0
    def test_create_when_vip_already_exists(self):
        vip = VIPFactory()
        self.data['ip'] = vip.ip.address
        self.data['port'] = vip.port
        self.data['protocol'] = VIPProtocol.from_id(vip.protocol).name

        vips = VIP.objects.all()
        self.assertEqual(vips.count(), 1)
        modified_before = vips[0].modified
        handle_create_vip_event(self.data)
        vips = VIP.objects.all()
        self.assertEqual(vips.count(), 1)
        self.assertEqual(vips[0].modified, modified_before)
    def test_update_change_service_env(self):
        vip = VIPFactory()
        self.data['ip'] = vip.ip.address
        self.data['port'] = vip.port
        self.data['protocol'] = VIPProtocol.from_id(vip.protocol).name
        service_env = ServiceEnvironmentFactory()
        self.data['service']['uid'] = service_env.service.uid
        self.data['environment'] = service_env.environment.name

        vips = VIP.objects.all()
        self.assertEqual(vips.count(), 1)
        handle_update_vip_event(self.data)
        vips = VIP.objects.all()
        self.assertEqual(vips.count(), 1)
        self.assertEqual(vips[0].service_env, service_env)
Example #9
0
    def test_ip_with_eth_not_being_deleted_when_still_used_by_some_vip(self):
        vip = VIPFactory()
        self.data['ip'] = vip.ip.address
        self.data['port'] = vip.port
        self.data['protocol'] = VIPProtocol.from_id(vip.protocol).name
        vip2 = VIPFactory()
        vip2.ip = vip.ip
        vip2.save()

        self.assertEqual(VIP.objects.count(), 2)
        self.assertEqual(IPAddress.objects.count(), 2)
        self.assertEqual(Ethernet.objects.count(), 2)
        handle_delete_vip_event(self.data)
        self.assertEqual(VIP.objects.count(), 1)
        self.assertEqual(IPAddress.objects.count(), 2)
        self.assertEqual(Ethernet.objects.count(), 2)
Example #10
0
def handle_delete_vip_event(data):
    errors = validate_vip_event_data(data)
    if errors:
        msg = ('Error(s) detected in event data: %s. Ignoring received delete '
               'event.')
        logger.error(msg, '; '.join(errors))
        return

    try:
        ip = IPAddress.objects.get(address=data['ip'])
    except IPAddress.DoesNotExist:
        msg = (
            "IP address %s doesn't exist. Ignoring received delete VIP event.")
        logger.error(msg, data['ip'])
        return
    protocol = VIPProtocol.from_name(data['protocol'].upper())
    vip = get_vip(ip, data['port'], protocol)
    if vip is None:
        msg = ("VIP designated by IP address %s, port %s and protocol %s "
               "doesn't exist. Ignoring received delete event.")
        logger.warning(msg, ip.address, data['port'], protocol.name)
        return
    vip.delete()
    logger.info('VIP %s deleted successfully.', vip.name)

    # Delete IP address associated with it (along with its Ethernet), but only
    # when this IP is not used anymore by other VIP(s).
    if not VIP.objects.filter(ip=ip).exists():
        eth_deleted = False
        if ip.ethernet is not None:
            ip.ethernet.delete()
            eth_deleted = True
        ip.delete()
        if eth_deleted:
            msg = (
                'IP address %s has been deleted (along with Ethernet '
                'associated with it) since it is no longer being used by any '
                'VIP.')
        else:
            msg = (
                'IP address %s has been deleted since it is no longer being '
                'used by any VIP.')
        logger.info(msg, ip.address)
Example #11
0
def handle_update_vip_event(data):
    # TODO(xor-xor): Since update event doesn't contain any changes yet, it
    # will be ignored for now. Remember to remove logger.info/return below when
    # this will get changed.
    logger.info(
        "Ignoring received update VIP event, since handling logic is not "
        "implemented yet.")
    return

    errors = validate_vip_event_data(data)
    if errors:
        msg = ('Error(s) detected in event data: %s. Ignoring received update '
               'event.')
        logger.error(msg, '; '.join(errors))
        return

    ip, = IPAddress.objects.get_or_create(address=data['ip'])
    protocol = VIPProtocol.from_name(data['protocol'].upper())
    vip = get_vip(ip.address, data['port'], protocol.name)
    if vip is None:
        msg = ("VIP designated by IP address %s, port %s and protocol %s "
               "doesn't exist. Ignoring received update event.")
        logger.warning(msg, ip.address, data['port'], protocol.name)
        return