Esempio n. 1
0
def create_public_ipv4_port(user_id, network=None, address=None,
                            category="user"):
    """Create a port in a public IPv4 network.

    Create a port in a public IPv4 network (that may also have an IPv6
    subnet). If the category is 'user' or 'default' this will try to use
    one of the users floating IPs. If the category is 'admin' will
    create a port to the public network (without floating IPs or quotas).

    """
    if category in ["user", "default"]:
        if address is None:
            ipaddress = ips.get_free_floating_ip(user_id, network)
        else:
            ipaddress = util.get_floating_ip_by_address(user_id, address,
                                                        for_update=True)
    elif category == "admin":
        if network is None:
            ipaddress = ips.allocate_public_ip(user_id)
        else:
            ipaddress = ips.allocate_ip(network, user_id)
    else:
        raise ValueError("Unknown category: %s" % category)
    if network is None:
        network = ipaddress.network
    return _create_port(user_id, network, use_ipaddress=ipaddress)
Esempio n. 2
0
def change_address_of_port(port, userid, old_address, new_address, version):
    """Change."""
    if old_address is not None:
        msg = ("IPv%s Address of server '%s' changed from '%s' to '%s'" %
               (version, port.machine_id, old_address, new_address))
        log.error(msg)

    # Remove the old IP address
    remove_nic_ips(port, version=version)

    if version == 4:
        ipaddress = ips.allocate_ip(port.network, userid, address=new_address)
        ipaddress.nic = port
        ipaddress.save()
    elif version == 6:
        subnet6 = port.network.subnet6
        ipaddress = IPAddress.objects.create(userid=userid,
                                             network=port.network,
                                             subnet=subnet6,
                                             nic=port,
                                             address=new_address,
                                             ipversion=6)
    else:
        raise ValueError("Unknown version: %s" % version)

    # New address log
    ip_log = IPAddressLog.objects.create(server_id=port.machine_id,
                                         network_id=port.network_id,
                                         address=new_address,
                                         active=True)
    log.info("Created IP log entry '%s' for address '%s' to server '%s'",
             ip_log.id, new_address, port.machine_id)

    return ipaddress
Esempio n. 3
0
def create_public_ipv4_port(user_id,
                            network=None,
                            address=None,
                            category="user"):
    """Create a port in a public IPv4 network.

    Create a port in a public IPv4 network (that may also have an IPv6
    subnet). If the category is 'user' or 'default' this will try to use
    one of the users floating IPs. If the category is 'admin' will
    create a port to the public network (without floating IPs or quotas).

    """
    if category in ["user", "default"]:
        if address is None:
            ipaddress = ips.get_free_floating_ip(user_id, network)
        else:
            ipaddress = util.get_floating_ip_by_address(user_id,
                                                        address,
                                                        for_update=True)
    elif category == "admin":
        if network is None:
            ipaddress = ips.allocate_public_ip(user_id)
        else:
            ipaddress = ips.allocate_ip(network, user_id)
    else:
        raise ValueError("Unknown category: %s" % category)
    if network is None:
        network = ipaddress.network
    return _create_port(user_id, network, use_ipaddress=ipaddress)
Esempio n. 4
0
def change_address_of_port(port, userid, old_address, new_address, version):
    """Change."""
    if old_address is not None:
        msg = ("IPv%s Address of server '%s' changed from '%s' to '%s'"
               % (version, port.machine_id, old_address, new_address))
        log.error(msg)

    # Remove the old IP address
    remove_nic_ips(port, version=version)

    if version == 4:
        ipaddress = ips.allocate_ip(port.network, userid, address=new_address)
        ipaddress.nic = port
        ipaddress.save()
    elif version == 6:
        subnet6 = port.network.subnet6
        ipaddress = IPAddress.objects.create(userid=userid,
                                             network=port.network,
                                             subnet=subnet6,
                                             nic=port,
                                             address=new_address,
                                             ipversion=6)
    else:
        raise ValueError("Unknown version: %s" % version)

    # New address log
    ip_log = IPAddressLog.objects.create(server_id=port.machine_id,
                                         network_id=port.network_id,
                                         address=new_address,
                                         active=True)
    log.info("Created IP log entry '%s' for address '%s' to server '%s'",
             ip_log.id, new_address, port.machine_id)

    return ipaddress
Esempio n. 5
0
def _create_port(userid, network, machine=None, use_ipaddress=None,
                 address=None, name="", security_groups=None,
                 device_owner=None):
    """Create a new port on the specified network.

    Create a new Port(NetworkInterface model) on the specified Network. If
    'machine' is specified, the machine will be connected to the network using
    this port. If 'use_ipaddress' argument is specified, the port will be
    assigned this IPAddress. Otherwise, an IPv4 address from the IPv4 subnet
    will be allocated.

    """
    if network.state != "ACTIVE":
        raise faults.Conflict("Cannot create port while network '%s' is in"
                              " '%s' status" % (network.id, network.state))
    elif network.action == "DESTROY":
        msg = "Cannot create port. Network %s is being deleted."
        raise faults.Conflict(msg % network.id)

    utils.check_name_length(name, NetworkInterface.NETWORK_IFACE_NAME_LENGTH,
                            "Port name is too long")

    ipaddress = None
    if use_ipaddress is not None:
        # Use an existing IPAddress object.
        ipaddress = use_ipaddress
        if ipaddress and (ipaddress.network_id != network.id):
            msg = "IP Address %s does not belong to network %s"
            raise faults.Conflict(msg % (ipaddress.address, network.id))
    else:
        # Do not allow allocation of new IPs if the network is drained
        if network.drained:
            raise faults.Conflict("Cannot create port while network %s is in"
                                  " 'SNF:DRAINED' status" % network.id)
        # If network has IPv4 subnets, try to allocate the address that the
        # the user specified or a random one.
        if network.subnets.filter(ipversion=4).exists():
            ipaddress = ips.allocate_ip(network, userid=userid,
                                        address=address)
        elif address is not None:
            raise faults.BadRequest("Address %s is not a valid IP for the"
                                    " defined network subnets" % address)

    if ipaddress is not None and ipaddress.nic is not None:
        raise faults.Conflict("IP address '%s' is already in use" %
                              ipaddress.address)

    port = NetworkInterface.objects.create(network=network,
                                           state="DOWN",
                                           userid=userid,
                                           device_owner=None,
                                           name=name)

    # add the security groups if any
    if security_groups:
        port.security_groups.add(*security_groups)

    if ipaddress is not None:
        # Associate IPAddress with the Port
        ipaddress.nic = port
        ipaddress.save()

    if machine is not None:
        # Connect port to the instance.
        machine = connect(machine, network, port)
        jobID = machine.task_job_id
        log.info("Created Port %s with IP %s. Ganeti Job: %s",
                 port, ipaddress, jobID)
    else:
        log.info("Created Port %s with IP %s not attached to any instance",
                 port, ipaddress)

    return port
Esempio n. 6
0
def create_port(request):
    user_id = request.user_uniq
    req = api.utils.get_json_body(request)

    log.debug("User: %s, Action: create_port, Request: %s", user_id, req)

    port_dict = api.utils.get_attribute(req, "port", attr_type=dict)
    net_id = api.utils.get_attribute(port_dict,
                                     "network_id",
                                     attr_type=(basestring, int))

    device_id = api.utils.get_attribute(port_dict,
                                        "device_id",
                                        required=False,
                                        attr_type=(basestring, int))
    vm = None
    if device_id is not None:
        vm = util.get_vm(device_id,
                         user_id,
                         request.user_projects,
                         for_update=True,
                         non_deleted=True,
                         non_suspended=True)

    # Check if the request contains a valid IPv4 address
    fixed_ips = api.utils.get_attribute(port_dict,
                                        "fixed_ips",
                                        required=False,
                                        attr_type=list)
    if fixed_ips is not None and len(fixed_ips) > 0:
        if len(fixed_ips) > 1:
            msg = "'fixed_ips' attribute must contain only one fixed IP."
            raise faults.BadRequest(msg)
        fixed_ip = fixed_ips[0]
        if not isinstance(fixed_ip, dict):
            raise faults.BadRequest("Invalid 'fixed_ips' field.")
        fixed_ip_address = fixed_ip.get("ip_address")
        if fixed_ip_address is not None:
            try:
                ip = ipaddr.IPAddress(fixed_ip_address)
                if ip.version == 6:
                    msg = "'ip_address' can be only an IPv4 address'"
                    raise faults.BadRequest(msg)
            except ValueError:
                msg = "%s is not a valid IPv4 Address" % fixed_ip_address
                raise faults.BadRequest(msg)
    else:
        fixed_ip_address = None

    network = util.get_network(net_id,
                               user_id,
                               request.user_projects,
                               non_deleted=True,
                               for_update=True)

    ipaddress = None
    if network.public:
        # Creating a port to a public network is only allowed if the user has
        # already a floating IP address in this network which is specified
        # as the fixed IP address of the port
        if fixed_ip_address is None:
            msg = ("'fixed_ips' attribute must contain a floating IP address"
                   " in order to connect to a public network.")
            raise faults.BadRequest(msg)
        ipaddress = util.get_floating_ip_by_address(user_id,
                                                    request.user_projects,
                                                    fixed_ip_address,
                                                    for_update=True)
    elif fixed_ip_address:
        ipaddress = ips.allocate_ip(network, user_id, address=fixed_ip_address)

    name = api.utils.get_attribute(port_dict,
                                   "name",
                                   required=False,
                                   attr_type=basestring)
    if name is None:
        name = ""

    security_groups = api.utils.get_attribute(port_dict,
                                              "security_groups",
                                              required=False,
                                              attr_type=list)
    #validate security groups
    # like get security group from db
    sg_list = []
    if security_groups:
        for gid in security_groups:
            try:
                sg = util.get_security_group(int(gid))
            except (KeyError, ValueError):
                raise faults.BadRequest("Invalid 'security_groups' field.")
            sg_list.append(sg)

    new_port = servers.create_port(user_id,
                                   network,
                                   use_ipaddress=ipaddress,
                                   machine=vm,
                                   name=name)

    log.info("User %s created port %s, network: %s, machine: %s, ip: %s",
             user_id, new_port.id, network, vm, ipaddress)

    response = render_port(request, port_to_dict(new_port), status=201)

    return response
Esempio n. 7
0
def create_port(request):
    user_id = request.user_uniq
    req = api.utils.get_json_body(request)
    log.info('create_port user: %s request: %s', user_id, req)

    port_dict = api.utils.get_attribute(req, "port", attr_type=dict)
    net_id = api.utils.get_attribute(port_dict, "network_id",
                                     attr_type=(basestring, int))

    device_id = api.utils.get_attribute(port_dict, "device_id", required=False,
                                        attr_type=(basestring, int))
    vm = None
    if device_id is not None:
        vm = util.get_vm(device_id, user_id, for_update=True, non_deleted=True,
                         non_suspended=True)

    # Check if the request contains a valid IPv4 address
    fixed_ips = api.utils.get_attribute(port_dict, "fixed_ips", required=False,
                                        attr_type=list)
    if fixed_ips is not None and len(fixed_ips) > 0:
        if len(fixed_ips) > 1:
            msg = "'fixed_ips' attribute must contain only one fixed IP."
            raise faults.BadRequest(msg)
        fixed_ip = fixed_ips[0]
        if not isinstance(fixed_ip, dict):
            raise faults.BadRequest("Invalid 'fixed_ips' field.")
        fixed_ip_address = fixed_ip.get("ip_address")
        if fixed_ip_address is not None:
            try:
                ip = ipaddr.IPAddress(fixed_ip_address)
                if ip.version == 6:
                    msg = "'ip_address' can be only an IPv4 address'"
                    raise faults.BadRequest(msg)
            except ValueError:
                msg = "%s is not a valid IPv4 Address" % fixed_ip_address
                raise faults.BadRequest(msg)
    else:
        fixed_ip_address = None

    network = util.get_network(net_id, user_id, non_deleted=True,
                               for_update=True)

    ipaddress = None
    if network.public:
        # Creating a port to a public network is only allowed if the user has
        # already a floating IP address in this network which is specified
        # as the fixed IP address of the port
        if fixed_ip_address is None:
            msg = ("'fixed_ips' attribute must contain a floating IP address"
                   " in order to connect to a public network.")
            raise faults.BadRequest(msg)
        ipaddress = util.get_floating_ip_by_address(user_id, fixed_ip_address,
                                                    for_update=True)
    elif fixed_ip_address:
        ipaddress = ips.allocate_ip(network, user_id,
                                    address=fixed_ip_address)

    name = api.utils.get_attribute(port_dict, "name", required=False,
                                   attr_type=basestring)
    if name is None:
        name = ""

    security_groups = api.utils.get_attribute(port_dict,
                                              "security_groups",
                                              required=False,
                                              attr_type=list)
    #validate security groups
    # like get security group from db
    sg_list = []
    if security_groups:
        for gid in security_groups:
            try:
                sg = util.get_security_group(int(gid))
            except (KeyError, ValueError):
                raise faults.BadRequest("Invalid 'security_groups' field.")
            sg_list.append(sg)

    new_port = servers.create_port(user_id, network, use_ipaddress=ipaddress,
                                   machine=vm, name=name)

    response = render_port(request, port_to_dict(new_port), status=201)

    return response
Esempio n. 8
0
def _create_port(userid,
                 network,
                 machine=None,
                 use_ipaddress=None,
                 address=None,
                 name="",
                 security_groups=None,
                 device_owner=None):
    """Create a new port on the specified network.

    Create a new Port(NetworkInterface model) on the specified Network. If
    'machine' is specified, the machine will be connected to the network using
    this port. If 'use_ipaddress' argument is specified, the port will be
    assigned this IPAddress. Otherwise, an IPv4 address from the IPv4 subnet
    will be allocated.

    """
    if network.state != "ACTIVE":
        raise faults.Conflict("Cannot create port while network '%s' is in"
                              " '%s' status" % (network.id, network.state))
    elif network.action == "DESTROY":
        msg = "Cannot create port. Network %s is being deleted."
        raise faults.Conflict(msg % network.id)
    elif network.drained:
        raise faults.Conflict("Cannot create port while network %s is in"
                              " 'SNF:DRAINED' status" % network.id)

    utils.check_name_length(name, NetworkInterface.NETWORK_IFACE_NAME_LENGTH,
                            "Port name is too long")

    ipaddress = None
    if use_ipaddress is not None:
        # Use an existing IPAddress object.
        ipaddress = use_ipaddress
        if ipaddress and (ipaddress.network_id != network.id):
            msg = "IP Address %s does not belong to network %s"
            raise faults.Conflict(msg % (ipaddress.address, network.id))
    else:
        # If network has IPv4 subnets, try to allocate the address that the
        # the user specified or a random one.
        if network.subnets.filter(ipversion=4).exists():
            ipaddress = ips.allocate_ip(network,
                                        userid=userid,
                                        address=address)
        elif address is not None:
            raise faults.BadRequest("Address %s is not a valid IP for the"
                                    " defined network subnets" % address)

    if ipaddress is not None and ipaddress.nic is not None:
        raise faults.Conflict("IP address '%s' is already in use" %
                              ipaddress.address)

    port = NetworkInterface.objects.create(network=network,
                                           state="DOWN",
                                           userid=userid,
                                           device_owner=None,
                                           name=name)

    # add the security groups if any
    if security_groups:
        port.security_groups.add(*security_groups)

    if ipaddress is not None:
        # Associate IPAddress with the Port
        ipaddress.nic = port
        ipaddress.save()

    if machine is not None:
        # Connect port to the instance.
        machine = connect(machine, network, port)
        jobID = machine.task_job_id
        log.info("Created Port %s with IP %s. Ganeti Job: %s", port, ipaddress,
                 jobID)
    else:
        log.info("Created Port %s with IP %s not attached to any instance",
                 port, ipaddress)

    return port