Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
itminedu
synnefo
Commits
a8819ad5
Commit
a8819ad5
authored
Nov 04, 2013
by
Christos Stavrakakis
Browse files
cyclades: Refactor code
Move code relative with allocating ips and floating IPs to 'logic.ips' module.
parent
227ccc21
Changes
7
Hide whitespace changes
Inline
Side-by-side
snf-cyclades-app/synnefo/api/floating_ips.py
View file @
a8819ad5
...
...
@@ -39,7 +39,7 @@ from django.utils import simplejson as json
from
snf_django.lib
import
api
from
snf_django.lib.api
import
faults
,
utils
from
synnefo.api
import
util
from
synnefo
import
quota
s
from
synnefo
.logic
import
ip
s
from
synnefo.db.models
import
Network
,
IPAddress
from
logging
import
getLogger
...
...
@@ -147,7 +147,7 @@ def allocate_floating_ip(request):
"floating_network_id"
,
required
=
False
)
if
network_id
is
None
:
floating_ip
=
util
.
allocate_public_ip
(
userid
,
floating_ip
=
True
)
floating_ip
=
ips
.
create_
floating_ip
(
userid
)
else
:
try
:
network_id
=
int
(
network_id
)
...
...
@@ -156,28 +156,12 @@ def allocate_floating_ip(request):
network
=
util
.
get_network
(
network_id
,
userid
,
for_update
=
True
,
non_deleted
=
True
)
if
not
network
.
floating_ip_pool
:
msg
=
(
"Can not allocate floating IP. Network %s is"
" not a floating IP pool."
)
raise
faults
.
Conflict
(
msg
%
network
.
id
)
if
network
.
action
==
"DESTROY"
:
msg
=
"Can not allocate floating IP. Network %s is being deleted."
raise
faults
.
Conflict
(
msg
%
network
.
id
)
address
=
api
.
utils
.
get_attribute
(
floating_ip_dict
,
"floating_ip_address"
,
required
=
False
)
# Allocate the floating IP
floating_ip
=
util
.
allocate_ip
(
network
,
userid
,
address
=
address
,
floating_ip
=
True
)
# Issue commission (quotas)
quotas
.
issue_and_accept_commission
(
floating_ip
)
transaction
.
commit
()
floating_ip
=
ips
.
create_floating_ip
(
userid
,
network
,
address
)
log
.
info
(
"User '%s' allocated floating IP '%s'"
,
userid
,
floating_ip
)
request
.
serialization
=
"json"
data
=
json
.
dumps
({
"floatingip"
:
ip_to_dict
(
floating_ip
)})
return
HttpResponse
(
data
,
status
=
200
)
...
...
@@ -193,23 +177,7 @@ def release_floating_ip(request, floating_ip_id):
floating_ip
=
util
.
get_floating_ip_by_id
(
userid
,
floating_ip_id
,
for_update
=
True
)
if
floating_ip
.
nic
:
# This is safe, you also need for_update to attach floating IP to
# instance.
msg
=
"Floating IP '%s' is attached to instance."
%
floating_ip
.
id
raise
faults
.
Conflict
(
msg
)
# Return the address of the floating IP back to pool
floating_ip
.
release_address
()
# And mark the floating IP as deleted
floating_ip
.
deleted
=
True
floating_ip
.
save
()
# Release quota for floating IP
quotas
.
issue_and_accept_commission
(
floating_ip
,
delete
=
True
)
transaction
.
commit
()
# Delete the floating IP from DB
floating_ip
.
delete
()
ips
.
delete_floating_ip
(
floating_ip
)
log
.
info
(
"User '%s' released IP '%s"
,
userid
,
floating_ip
)
return
HttpResponse
(
status
=
204
)
...
...
snf-cyclades-app/synnefo/api/management/commands/floating-ip-create.py
View file @
a8819ad5
...
...
@@ -33,26 +33,21 @@
from
optparse
import
make_option
from
django.db
import
transaction
from
django.core.management.base
import
BaseCommand
,
CommandError
from
synnefo.management.common
import
convert_api_faults
from
synnefo.logic
import
ips
from
synnefo.api
import
util
from
synnefo.db
import
pools
from
synnefo
import
quotas
class
Command
(
BaseCommand
):
can_import_settings
=
True
output_transaction
=
True
help
=
"Allocate a new floating IP"
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'--pool'
,
dest
=
'pool'
,
help
=
"The IP pool to allocate the address from"
),
help
=
"The ID of the floating IP pool(network) to allocate the"
" address from"
),
make_option
(
'--address'
,
dest
=
'address'
,
...
...
@@ -61,48 +56,29 @@ class Command(BaseCommand):
'--owner'
,
dest
=
'owner'
,
default
=
None
,
# required=True,
help
=
'The owner of the floating IP'
),
)
@
transaction
.
commit_on_success
@
convert_api_faults
def
handle
(
self
,
*
args
,
**
options
):
if
args
:
raise
CommandError
(
"Command doesn't accept any arguments"
)
pool
=
options
[
'pool'
]
network_id
=
options
[
'pool'
]
address
=
options
[
'address'
]
owner
=
options
[
'owner'
]
if
not
owner
:
raise
CommandError
(
"'owner' is required for floating IP creation"
)
if
pool
is
None
:
if
address
:
raise
CommandError
(
'Please specify a pool as well'
)
# User did not specified a pool. Choose a random public IP
try
:
floating_ip
=
util
.
allocate_public_ip
(
userid
=
owner
,
floating_ip
=
True
)
except
pools
.
EmptyPool
:
raise
faults
.
Conflict
(
"No more IP addresses available."
)
else
:
try
:
network_id
=
int
(
pool
)
except
ValueError
:
raise
CommandError
(
"Invalid pool ID."
)
if
network_id
is
not
None
:
network
=
util
.
get_network
(
network_id
,
owner
,
for_update
=
True
,
non_deleted
=
True
)
if
not
network
.
floating_ip_pool
:
# Check that it is a floating IP pool
raise
CommandError
(
"Floating IP pool %s does not exist."
%
network_id
)
floating_ip
=
util
.
allocate_ip
(
network
,
owner
,
address
=
address
,
floating_ip
=
True
)
else
:
network
=
None
quotas
.
issue_and_accept_commission
(
floating_ip
)
transaction
.
commit
()
floating_ip
=
ips
.
create_floating_ip
(
userid
=
owner
,
network
=
network
,
address
=
address
)
self
.
stdout
.
write
(
"Created floating IP '%s'.
\n
"
%
floating_ip
)
snf-cyclades-app/synnefo/api/management/commands/floating-ip-release.py
View file @
a8819ad5
# Copyright 201
2
GRNET S.A. All rights reserved.
# Copyright 201
3
GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
...
...
@@ -31,18 +31,15 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from
optparse
import
make_option
#
from optparse import make_option
from
django.db
import
transaction
from
django.core.management.base
import
BaseCommand
,
CommandError
from
synnefo.management
import
common
from
synnefo.logic
import
ips
from
synnefo.management.common
import
get_floating_ip_by_address
from
synnefo
import
quotas
class
Command
(
BaseCommand
):
can_import_settings
=
True
output_transaction
=
True
help
=
"Release a floating IP"
@
transaction
.
commit_on_success
...
...
@@ -50,24 +47,9 @@ class Command(BaseCommand):
if
not
args
:
raise
CommandError
(
"Please provide a floating-ip address"
)
address
=
args
[
0
]
floating_ip
=
get_floating_ip_by_address
(
address
,
for_update
=
True
)
if
floating_ip
.
nic
:
# This is safe, you also need for_update to attach floating IP to
# instance.
msg
=
"Floating IP '%s' is attached to instance."
%
floating_ip
.
id
raise
CommandError
(
msg
)
# Return the address of the floating IP back to pool
floating_ip
.
release_address
()
# And mark the floating IP as deleted
floating_ip
.
deleted
=
True
floating_ip
.
save
()
# Release quota for floating IP
quotas
.
issue_and_accept_commission
(
floating_ip
,
delete
=
True
)
transaction
.
commit
()
# Delete the floating IP from DB
floating_ip
.
delete
()
floating_ip_id
=
args
[
0
]
self
.
stdout
.
write
(
"Deleted floating IP '%s'.
\n
"
%
address
)
floating_ip
=
common
.
get_floating_ip_by_id
(
floating_ip_id
,
for_update
=
True
)
ips
.
delete_floating_ip
(
floating_ip
)
self
.
stdout
.
write
(
"Deleted floating IP '%s'.
\n
"
%
floating_ip_id
)
snf-cyclades-app/synnefo/api/ports.py
View file @
a8819ad5
...
...
@@ -44,7 +44,7 @@ from snf_django.lib.api import faults
from
synnefo.api
import
util
from
synnefo.db.models
import
NetworkInterface
from
synnefo.logic
import
servers
from
synnefo.logic
import
servers
,
ips
from
logging
import
getLogger
...
...
@@ -141,8 +141,8 @@ def create_port(request):
ipaddress
=
util
.
get_floating_ip_by_address
(
user_id
,
fixed_ip_address
,
for_update
=
True
)
elif
fixed_ip_address
:
ipaddress
=
util
.
allocate_ip
(
network
,
user_id
,
address
=
fixed_ip_address
)
ipaddress
=
ips
.
allocate_ip
(
network
,
user_id
,
address
=
fixed_ip_address
)
device_id
=
api
.
utils
.
get_attribute
(
port_dict
,
"device_id"
,
required
=
False
)
vm
=
None
...
...
snf-cyclades-app/synnefo/api/util.py
View file @
a8819ad5
...
...
@@ -50,8 +50,6 @@ from synnefo.db.models import (Flavor, VirtualMachine, VirtualMachineMetadata,
Network
,
NetworkInterface
,
SecurityGroup
,
BridgePoolTable
,
MacPrefixPoolTable
,
IPAddress
,
IPPoolTable
)
from
synnefo.db
import
pools
from
synnefo.plankton.utils
import
image_backend
from
synnefo.cyclades_settings
import
cyclades_services
,
BASE_HOST
...
...
@@ -272,103 +270,6 @@ def get_floating_ip_by_id(userid, floating_ip_id, for_update=False):
floating_ip_id
)
def
allocate_ip_from_pools
(
pool_rows
,
userid
,
address
=
None
,
floating_ip
=
False
):
"""Try to allocate a value from a number of pools.
This function takes as argument a number of PoolTable objects and tries to
allocate a value from them. If all pools are empty EmptyPool is raised.
If an address is specified and does not belong to any of the pools,
InvalidValue is raised.
"""
for
pool_row
in
pool_rows
:
pool
=
pool_row
.
pool
try
:
value
=
pool
.
get
(
value
=
address
)
pool
.
save
()
subnet
=
pool_row
.
subnet
ipaddress
=
IPAddress
.
objects
.
create
(
subnet
=
subnet
,
network
=
subnet
.
network
,
userid
=
userid
,
address
=
value
,
floating_ip
=
floating_ip
)
return
ipaddress
except
pools
.
EmptyPool
:
pass
except
pools
.
InvalidValue
:
pass
if
address
is
None
:
raise
pools
.
EmptyPool
(
"No more IP addresses available on pools %s"
%
pool_rows
)
else
:
raise
pools
.
InvalidValue
(
"Address %s does not belong to pools %s"
%
(
address
,
pool_rows
))
def
allocate_ip
(
network
,
userid
,
address
=
None
,
floating_ip
=
False
):
"""Try to allocate an IP from networks IP pools."""
if
network
.
action
==
"DESTROY"
:
raise
faults
.
Conflict
(
"Can not allocate IP. Network %s is being"
" deleted"
%
network
.
id
)
ip_pools
=
IPPoolTable
.
objects
.
select_for_update
()
\
.
filter
(
subnet__network
=
network
)
try
:
return
allocate_ip_from_pools
(
ip_pools
,
userid
,
address
=
address
,
floating_ip
=
floating_ip
)
except
pools
.
EmptyPool
:
raise
faults
.
Conflict
(
"No more IP addresses available on network %s"
%
network
.
id
)
except
pools
.
ValueNotAvailable
:
raise
faults
.
Conflict
(
"IP address %s is already used."
%
address
)
except
pools
.
InvalidValue
:
raise
faults
.
BadRequest
(
"Address %s does not belong to network %s"
%
(
address
,
network
.
id
))
def
allocate_public_ip
(
userid
,
floating_ip
=
False
,
backend
=
None
):
"""Try to allocate a public or floating IP address.
Try to allocate a a public IPv4 address from one of the available networks.
If 'floating_ip' is set, only networks which are floating IP pools will be
used and the IPAddress that will be created will be marked as a floating
IP. If 'backend' is set, only the networks that exist in this backend will
be used.
"""
ip_pool_rows
=
IPPoolTable
.
objects
.
select_for_update
()
\
.
prefetch_related
(
"subnet__network"
)
\
.
filter
(
subnet__deleted
=
False
)
\
.
filter
(
subnet__network__deleted
=
False
)
\
.
filter
(
subnet__network__public
=
True
)
\
.
filter
(
subnet__network__drained
=
False
)
if
floating_ip
:
ip_pool_rows
=
ip_pool_rows
\
.
filter
(
subnet__network__floating_ip_pool
=
True
)
if
backend
is
not
None
:
ip_pool_rows
=
ip_pool_rows
\
.
filter
(
subnet__network__backend_networks__backend
=
backend
)
try
:
return
allocate_ip_from_pools
(
ip_pool_rows
,
userid
,
floating_ip
=
floating_ip
)
except
pools
.
EmptyPool
:
ip_type
=
"floating"
if
floating_ip
else
"public"
log_msg
=
"Failed to allocate a %s IP. Reason:"
%
ip_type
if
ip_pool_rows
:
log_msg
+=
" No network exists."
else
:
log_msg
+=
" All network are full."
if
backend
is
not
None
:
log_msg
+=
" Backend: %s"
%
backend
log
.
error
(
log_msg
)
exception_msg
=
"Can not allocate a %s IP address."
%
ip_type
if
floating_ip
:
raise
faults
.
Conflict
(
exception_msg
)
else
:
raise
faults
.
ServiceUnavailable
(
exception_msg
)
def
backend_has_free_public_ip
(
backend
):
"""Check if a backend has a free public IPv4 address."""
ip_pool_rows
=
IPPoolTable
.
objects
.
select_for_update
()
\
...
...
snf-cyclades-app/synnefo/logic/backend.py
View file @
a8819ad5
...
...
@@ -38,9 +38,9 @@ from synnefo.db.models import (Backend, VirtualMachine, Network,
BackendNetwork
,
BACKEND_STATUSES
,
pooled_rapi_client
,
VirtualMachineDiagnostic
,
Flavor
,
IPAddressLog
)
from
synnefo.logic
import
utils
from
synnefo.logic
import
utils
,
ips
from
synnefo
import
quotas
from
synnefo.api.util
import
release_resource
,
allocate_ip
from
synnefo.api.util
import
release_resource
from
synnefo.util.mac2eui64
import
mac2eui64
from
synnefo.logic.rapi
import
GanetiApiError
...
...
@@ -273,8 +273,8 @@ def _process_net_status(vm, etime, nics):
remove_nic_ips
(
db_nic
)
if
ipv4_address
:
network
=
ganeti_nic
[
"network"
]
ipaddress
=
allocate_ip
(
network
,
vm
.
userid
,
address
=
ipv4_address
)
ipaddress
=
ips
.
allocate_ip
(
network
,
vm
.
userid
,
address
=
ipv4_address
)
ipaddress
.
nic
=
nic
ipaddress
.
save
()
...
...
snf-cyclades-app/synnefo/logic/servers.py
View file @
a8819ad5
...
...
@@ -10,9 +10,8 @@ from snf_django.lib.api import faults
from
django.conf
import
settings
from
synnefo
import
quotas
from
synnefo.api
import
util
from
synnefo.logic
import
backend
from
synnefo.logic
import
backend
,
ips
from
synnefo.logic.backend_allocator
import
BackendAllocator
from
synnefo.db
import
pools
from
synnefo.db.models
import
(
NetworkInterface
,
VirtualMachine
,
VirtualMachineMetadata
,
IPAddressLog
)
from
vncauthproxy.client
import
request_forwarding
as
request_vnc_forwarding
...
...
@@ -243,8 +242,8 @@ def create_instance_nics(vm, userid, networks=[], floating_ips=[]):
ports
=
[]
for
network_id
in
settings
.
DEFAULT_INSTANCE_NETWORKS
:
if
network_id
==
"SNF:ANY_PUBLIC"
:
ipaddress
=
util
.
allocate_public_ip
(
userid
=
userid
,
backend
=
vm
.
backend
)
ipaddress
=
ips
.
allocate_public_ip
(
userid
=
userid
,
backend
=
vm
.
backend
)
port
=
_create_port
(
userid
,
network
=
ipaddress
.
network
,
use_ipaddress
=
ipaddress
)
else
:
...
...
@@ -480,12 +479,8 @@ def _create_port(userid, network, machine=None, use_ipaddress=None,
# 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
():
try
:
ipaddress
=
util
.
allocate_ip
(
network
,
userid
=
userid
,
address
=
address
)
except
pools
.
ValueNotAvailable
:
msg
=
"Address %s is already in use."
%
address
raise
faults
.
Conflict
(
msg
)
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
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment