Пример #1
0
    def create_or_update(self, conn, filters=None):
        changed = False
        refs = self._refs_from_ser(conn)

        # 1. ensure a port exists with the required `fixed_ips`
        sdk_params = self._to_sdk_params(refs)
        port = self._find_port_by_subnet_ips(conn, refs, filters)

        if port:
            # port exists but is assigned to something else => fail
            if ((port['device_owner'] and port['device_owner'] != 'network:router_interface')
                    or (port['device_id'] and port['device_id'] != refs['device_id'])):
                raise exc.CannotConverge(
                    "Port with IP address for router import exists, and it is assigned "
                    "to a different device: {0}".format(port.to_dict())
                )

            if self._port_needs_update(self.from_sdk(conn, port)):
                port = self._update_port(conn, port['id'], sdk_params)
                changed = True
        else:
            port = self._create_port(conn, sdk_params)
            changed = True

        # 2. ensure the port is attached to the router by `router_name`
        if port['device_owner'] != 'network:router_interface' \
           and port['device_id'] != refs['device_id']:
            conn.network.add_interface_to_router(
                refs['device_id'], port_id=port['id'])
            changed = True
        return changed
Пример #2
0
    def _find_my_server_port(self, conn, sdk_srv, delay=5, retries=5):
        params = self.params()
        for try_number in range(retries):
            srv_ports = conn.network.ports(device_id=sdk_srv['id'])
            for port in srv_ports:
                port_fixed_ips = [item['ip_address'] for item in port['fixed_ips']]
                if params['fixed_ip_address'] in port_fixed_ips:
                    return port

            # wait and retry
            time.sleep(delay)

        # still failing after max retries
        raise exc.CannotConverge(
            "Floating IP for server '{0}' ('{1}') is meant to attach "
            "to a port with fixed IP '{2}', but no such port was found "
            "on that server.".format(
                sdk_srv['name'],
                sdk_srv['id'],
                params['fixed_ip_address'],
            )
        )
Пример #3
0
 def _find_port_by_subnet_ips(self, conn, refs, filters=None):
     net_ports = conn.network.ports(network_id=refs['network_id'], **(filters or {}))
     matching_ports = []
     for port in net_ports:
         for fixed_ip in port['fixed_ips']:
             filtered = dict(filter(
                 lambda keyval: keyval[0] in ['subnet_id', 'ip_address'],
                 fixed_ip.items()))
             if filtered in refs['fixed_ips']:
                 matching_ports.append(port)
                 break
     if len(matching_ports) == 0:
         return None
     elif len(matching_ports) == 1:
         return matching_ports[0]
     else:
         raise exc.CannotConverge(
             "When creating a port for router '{0}', multiple "
             "existing ports were found owning addresses that should "
             "belong to a single port on the router. The ports are: {1}"
             .format(refs['device_ref']['name'], matching_ports)
         )