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