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)
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
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
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
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
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