Revision 79f4eec0

b/snf-cyclades-app/synnefo/api/management/commands/port-create.py
37 37
from synnefo.management.common import convert_api_faults
38 38

  
39 39
from synnefo.api import util
40
from synnefo.management.common import get_network, get_vm
40
from synnefo.management.common import (get_network, get_vm,
41
                                       get_floating_ip_by_id)
41 42
from synnefo.logic import ports
42 43

  
43 44
HELP_MSG = """Create a new port.
44 45

  
45
Connect a server/router to a network by creating a new port. The port will
46
get an IP address for each Subnet that is associated with the network."""
46
Connect a server/router to a network by creating a new port. If 'floating_ip'
47
option is used, the specified floating IP will be assigned to the new port.
48
Otherwise, the port will get an IP address for each Subnet that is associated
49
with the network."""
47 50

  
48 51

  
49 52
class Command(BaseCommand):
......
71 74
            default=None,
72 75
            help="The ID of the router that the port will be connected to."),
73 76
        make_option(
77
            "--floating-ip",
78
            dest="floating_ip_id",
79
            default=None,
80
            help="The ID of the floating IP to use for the port."),
81
        make_option(
74 82
            "--security-groups",
75 83
            dest="security-groups",
76 84
            default=None,
......
87 95
        network_id = options["network_id"]
88 96
        server_id = options["server_id"]
89 97
        router_id = options["router_id"]
98
        floating_ip_id = options["floating_ip_id"]
90 99
        # assume giving security groups comma separated
91 100
        security_group_ids = options["security-groups"]
92 101

  
......
112 121
        else:
113 122
            raise CommandError("Neither server or router is specified")
114 123

  
124
        if floating_ip_id:
125
            floating_ip = get_floating_ip_by_id(floating_ip_id,
126
                                                for_update=True)
127
            if floating_ip.userid != vm.userid:
128
                msg = "Floating IP %s does not belong to server/router owner."
129
                raise CommandError(msg % floating_ip)
130

  
115 131
        # get the network
116 132
        network = get_network(network_id)
117 133

  
......
123 139
                sg = util.get_security_group(int(gid))
124 140
                sg_list.append(sg)
125 141

  
126
        new_port = ports.create(network, vm, name, security_groups=sg_list,
142
        new_port = ports.create(network, vm, name=name, ipaddress=floating_ip,
143
                                security_groups=sg_list,
127 144
                                device_owner=owner)
128 145
        self.stdout.write("Created port '%s' in DB.\n" % new_port)
129 146
        # TODO: Display port information, like ip address
b/snf-cyclades-app/synnefo/logic/ports.py
54 54

  
55 55

  
56 56
@transaction.commit_on_success
57
def create(network, machine, name="", security_groups=None,
57
def create(network, machine, ipaddress, name="", security_groups=None,
58 58
           device_owner='vm'):
59
    """Create a new port by giving a vm and a network"""
59
    """Create a new port connecting a server/router to a network.
60

  
61
    Connect a server/router to a network by creating a new Port. If
62
    'ipaddress' argument is specified, the port will be assigned this
63
    IPAddress. Otherwise, an IPv4 address from the IPv4 subnet will be
64
    allocated.
65

  
66
    """
60 67
    if network.state != 'ACTIVE':
61 68
        raise faults.Conflict('Network build in process')
62 69

  
63 70
    user_id = machine.userid
71

  
72
    if ipaddress is None:
73
        if network.subnets.filter(ipversion=4).exists():
74
            ipaddress = util.allocate_ip(network, user_id)
75
    else:
76
        if ipaddress.nic is not None:
77
            raise faults.BadRequest("Address '%s' already in use." %
78
                                    ipaddress.address)
64 79
    #create the port
65 80
    port = NetworkInterface.objects.create(name=name,
66 81
                                           network=network,
......
72 87
    if security_groups:
73 88
        port.security_groups.add(*security_groups)
74 89

  
75
    ipaddress = None
76
    if network.subnets.filter(ipversion=4).exists():
77
            ipaddress = util.allocate_ip(network, user_id)
78
            ipaddress.nic = port
79
            ipaddress.save()
90
    # If no IPAddress is specified, try to allocate one
91
    if ipaddress is None and network.subnets.filter(ipversion=4).exists():
92
        ipaddress = util.allocate_ip(network, user_id)
93

  
94
    # Associate the IPAddress with the NIC
95
    if ipaddress is not None:
96
        ipaddress.nic = port
97
        ipaddress.save()
80 98

  
81 99
    jobID = backend.connect_to_network(machine, port)
82 100

  
b/snf-cyclades-app/synnefo/management/common.py
33 33

  
34 34
from django.core.management import CommandError
35 35
from synnefo.db.models import (Backend, VirtualMachine, Network,
36
                               Flavor, IPAddress)
36
                               Flavor, IPAddress, Subnet)
37 37
from functools import wraps
38 38

  
39 39
from snf_django.lib.api import faults
......
160 160
        raise CommandError("Floating IP does not exist.")
161 161

  
162 162

  
163
def get_floating_ip_by_id(floating_ip_id, for_update=False):
164
    try:
165
        objects = IPAddress.objects
166
        if for_update:
167
            objects = objects.select_for_update()
168
        return objects.get(floating_ip=True, id=floating_ip_id, deleted=False)
169
    except IPAddress.DoesNotExist:
170
        raise CommandError("Floating IP does not exist.")
171

  
172

  
163 173
def check_backend_credentials(clustername, port, username, password):
164 174
    try:
165 175
        client = GanetiRapiClient(clustername, port, username, password)

Also available in: Unified diff