Merge "Included OCCI IPReservation support"
This commit is contained in:
commit
2e6c6b22c0
@ -291,6 +291,60 @@ It deletes a network::
|
||||
|
||||
It returns a 204 empty response.
|
||||
|
||||
IPReservation
|
||||
**************
|
||||
|
||||
OOI allows to manage public IPs by using IPReservation resources. This resource is a special network to provide public access.
|
||||
It allocates and releases IPs from public network pools.
|
||||
|
||||
List IPReservations
|
||||
-------------------
|
||||
It list IPReservation resources::
|
||||
|
||||
curl -H "X-Auth-token: "$OS_TOKEN http://127.0.0.1:8787/occi1.1/ipreservation
|
||||
|
||||
It returns a HTTP 200 with output::
|
||||
|
||||
X-OCCI-Location: http://127.0.0.1:8787/occi1.1/ipreservation/3318c3af-ce57-41ef-a9c1-9a5ecfbe0526
|
||||
|
||||
Show IPReservation
|
||||
------------------
|
||||
It shows the IPReservation details::
|
||||
|
||||
curl -H "X-Auth-token: "$OS_TOKEN http://127.0.0.1:8787/occi1.1/ipreservation/3318c3af-ce57-41ef-a9c1-9a5ecfbe0526
|
||||
|
||||
It returns a HTTP 200 with output::
|
||||
|
||||
Category: ipreservation; scheme="http://schemas.ogf.org/occi/infrastructure#"; class="kind"; title="IPReservation"; rel="http://schemas.ogf.org/occi/infrastructure#network"; location="http://127.0.0.1:8787/occi1.1/ipreservation/"
|
||||
X-OCCI-Attribute: occi.core.title="external-net"
|
||||
X-OCCI-Attribute: occi.core.summary=[]
|
||||
X-OCCI-Attribute: occi.core.id="3318c3af-ce57-41ef-a9c1-9a5ecfbe0526"
|
||||
X-OCCI-Attribute: occi.ipreservation.address="193.136.75.90"
|
||||
X-OCCI-Attribute: occi.ipreservation.used="true"
|
||||
Link: <http://127.0.0.1:8787/occi1.1/ipreservation/3318c3af-ce57-41ef-a9c1-9a5ecfbe0526?action=up>; rel="http://schemas.ogf.org/occi/infrastructure/network/action#up"
|
||||
Link: <http://127.0.0.1:8787/occi1.1/ipreservation/3318c3af-ce57-41ef-a9c1-9a5ecfbe0526?action=down>; rel="http://schemas.ogf.org/occi/infrastructure/network/action#down"
|
||||
|
||||
Create IPReservation
|
||||
--------------------
|
||||
It creates a IPReservation resource::
|
||||
|
||||
curl -X POST http://127.0.0.1:8787/occi1.1/ipreservation -H 'X-Auth-token: '$OS_TOKEN \
|
||||
-H 'Category: ipreshemas.ogf.org/occi/infrastructure#"; class="kind",' \
|
||||
'external-net; scheme="http://schemas.openstack.org/network/floatingippool#"; class="mixin"' \
|
||||
-H 'Content-Type: text/occi'
|
||||
|
||||
It returns a HTTP 200 with output::
|
||||
|
||||
X-OCCI-Location: http://127.0.0.1:8787/occi1.1/ipreservation/3318c3af-ce57-41ef-a9c1-9a5ecfbe0526
|
||||
|
||||
Delete IPReservation
|
||||
--------------------
|
||||
It deletes IPReservation resources::
|
||||
|
||||
curl -X DELETE -H "X-Auth-token: "$OS_TOKEN http://127.0.0.1:8787/occi1.1/ipreservation/3318c3af-ce57-41ef-a9c1-9a5ecfbe0526
|
||||
|
||||
It returns a 204 empty response.
|
||||
|
||||
Network Link
|
||||
************
|
||||
|
||||
|
@ -22,6 +22,7 @@ from ooi import exception
|
||||
from ooi.occi.core import collection
|
||||
from ooi.occi.infrastructure import compute
|
||||
from ooi.occi.infrastructure import contextualization
|
||||
from ooi.occi.infrastructure import ip_reservation
|
||||
from ooi.occi.infrastructure import network
|
||||
from ooi.occi.infrastructure import storage
|
||||
from ooi.occi.infrastructure import storage_link
|
||||
@ -32,8 +33,13 @@ from ooi.openstack import network as os_network
|
||||
from ooi.openstack import templates
|
||||
|
||||
|
||||
def _create_network_link(addr, comp, net_id):
|
||||
net = network.NetworkResource(title="network", id=net_id)
|
||||
def _create_network_link(addr, comp, net_id, type_ip):
|
||||
if type_ip == "floating":
|
||||
net = ip_reservation.IPReservation(title="network",
|
||||
address=None,
|
||||
id=net_id)
|
||||
else:
|
||||
net = network.NetworkResource(title="network", id=net_id)
|
||||
return os_network.OSNetworkInterface(comp, net,
|
||||
addr["OS-EXT-IPS-MAC:mac_addr"],
|
||||
addr["addr"])
|
||||
@ -278,7 +284,9 @@ class Controller(ooi.api.base.Controller):
|
||||
for addr in addr_set:
|
||||
# TODO(jorgesece): add pool information
|
||||
if addr["OS-EXT-IPS:type"] == "floating":
|
||||
net_id = helpers.PUBLIC_NETWORK
|
||||
net_id = self.os_helper.get_floatingip_id(
|
||||
req, addr['addr']
|
||||
)
|
||||
else:
|
||||
try:
|
||||
net_id = self.os_helper.get_network_id(
|
||||
@ -286,7 +294,9 @@ class Controller(ooi.api.base.Controller):
|
||||
)
|
||||
except webob.exc.HTTPNotFound:
|
||||
net_id = "FIXED"
|
||||
comp.add_link(_create_network_link(addr, comp, net_id))
|
||||
comp.add_link(_create_network_link(
|
||||
addr, comp, net_id,
|
||||
addr["OS-EXT-IPS:type"]))
|
||||
|
||||
return comp
|
||||
|
||||
@ -310,7 +320,6 @@ class Controller(ooi.api.base.Controller):
|
||||
if server_ip == ip["ip"]:
|
||||
self.os_helper.remove_floating_ip(req, server_id,
|
||||
ip["ip"])
|
||||
self.os_helper.release_floating_ip(req, ip["id"])
|
||||
|
||||
def _delete(self, req, server_ids):
|
||||
for server_id in server_ids:
|
||||
|
@ -541,6 +541,19 @@ class OpenStackHelper(BaseHelper):
|
||||
response = req.get_response(self.app)
|
||||
return self.get_from_response(response, "floating_ips", [])
|
||||
|
||||
def get_floating_ip(self, req, floating_id):
|
||||
"""Get information about a floating IP.
|
||||
|
||||
:param req: the incoming request
|
||||
:param floating_id: floating ip id to get info from
|
||||
"""
|
||||
tenant_id = self.tenant_from_req(req)
|
||||
path = "/%s/os-floating-ips/%s" % (tenant_id,
|
||||
floating_id)
|
||||
req = self._make_get_request(req, path)
|
||||
response = req.get_response(self.app)
|
||||
return self.get_from_response(response, "floating_ip", [])
|
||||
|
||||
def _get_floating_ip_pools_req(self, req):
|
||||
tenant_id = self.tenant_from_req(req)
|
||||
path = "/%s/os-floating-ip-pools" % tenant_id
|
||||
@ -715,7 +728,7 @@ class OpenStackHelper(BaseHelper):
|
||||
|
||||
@staticmethod
|
||||
def _build_link(net_id, compute_id, ip, ip_id=None, mac=None, pool=None,
|
||||
state='ACTIVE'):
|
||||
state='ACTIVE', public_ip=False):
|
||||
link = {}
|
||||
link['mac'] = mac
|
||||
link['pool'] = pool
|
||||
@ -724,6 +737,7 @@ class OpenStackHelper(BaseHelper):
|
||||
link['ip'] = ip
|
||||
link['ip_id'] = ip_id
|
||||
link['state'] = os_helpers.vm_state(state)
|
||||
link['public_ip'] = public_ip
|
||||
return link
|
||||
|
||||
def _get_ports(self, req, compute_id):
|
||||
@ -739,48 +753,55 @@ class OpenStackHelper(BaseHelper):
|
||||
LOG.exception("Interfaces can not be shown: " + e.explanation)
|
||||
return result
|
||||
|
||||
def get_compute_net_link(self, req, compute_id, network_id,
|
||||
address):
|
||||
def get_compute_net_link(self, req, compute_id, address):
|
||||
"""Get a specific network/server link
|
||||
|
||||
It shows a specific link (either private or public ip)
|
||||
|
||||
:param req: the incoming request
|
||||
:param compute_id: server id
|
||||
:param network_id: network id
|
||||
:param address: ip connected
|
||||
"""
|
||||
|
||||
s = self.get_server(req, compute_id)
|
||||
pool = None
|
||||
ip_id = None
|
||||
server_addrs = s.get("addresses", {})
|
||||
compute = self.get_server(req, compute_id)
|
||||
server_addrs = compute.get("addresses", {})
|
||||
compute_id = compute["id"]
|
||||
ports = self._get_ports(req, compute_id)
|
||||
floating_ips = self.get_floating_ips(
|
||||
req
|
||||
)
|
||||
for addr_set in server_addrs.values():
|
||||
for addr in addr_set:
|
||||
if addr["addr"] == address:
|
||||
public_ip = False
|
||||
pool = None
|
||||
ip_id = None
|
||||
mac = addr["OS-EXT-IPS-MAC:mac_addr"]
|
||||
if network_id == os_helpers.PUBLIC_NETWORK:
|
||||
floating_ips = self.get_floating_ips(
|
||||
req
|
||||
)
|
||||
for ip in floating_ips:
|
||||
if address == ip['ip']:
|
||||
pool = ip['pool']
|
||||
ip_id = ip['id']
|
||||
else:
|
||||
ports = self._get_ports(req, compute_id)
|
||||
ip_type = addr["OS-EXT-IPS:type"]
|
||||
if ip_type == "fixed":
|
||||
network_id = "FIXED"
|
||||
for p in ports:
|
||||
if p["net_id"] == network_id:
|
||||
for ip in p["fixed_ips"]:
|
||||
if ip['ip_address'] == address:
|
||||
ip_id = p['port_id']
|
||||
return self._build_link(network_id,
|
||||
compute_id,
|
||||
address,
|
||||
mac=mac,
|
||||
pool=pool,
|
||||
ip_id=ip_id
|
||||
)
|
||||
if p['mac_addr'] == mac:
|
||||
ip_id = str(p['port_id'])
|
||||
network_id = str(p['net_id'])
|
||||
break
|
||||
else:
|
||||
network_id = "PUBLIC"
|
||||
for fp in floating_ips:
|
||||
if compute_id == fp['instance_id']:
|
||||
pool = fp['pool']
|
||||
ip_id = str(fp['id'])
|
||||
network_id = str(fp['id'])
|
||||
public_ip = True
|
||||
break
|
||||
return self._build_link(
|
||||
network_id,
|
||||
compute_id,
|
||||
address,
|
||||
mac=mac,
|
||||
pool=pool,
|
||||
ip_id=ip_id,
|
||||
public_ip=public_ip
|
||||
)
|
||||
raise exception.NotFound()
|
||||
|
||||
def list_compute_net_links(self, req):
|
||||
@ -788,45 +809,48 @@ class OpenStackHelper(BaseHelper):
|
||||
|
||||
:param req: the incoming request
|
||||
"""
|
||||
floating_ips = self.get_floating_ips(req)
|
||||
float_list = {}
|
||||
for ip in floating_ips:
|
||||
if ip["instance_id"]:
|
||||
float_list.update({ip['fixed_ip']: ip})
|
||||
servers = self.index(req)
|
||||
link_list = []
|
||||
for s in servers:
|
||||
ports = self._get_ports(req, s['id'])
|
||||
for p in ports:
|
||||
for ip in p["fixed_ips"]:
|
||||
mac = p['mac_addr']
|
||||
state = p["port_state"]
|
||||
link = self._build_link(p["net_id"],
|
||||
s['id'],
|
||||
ip['ip_address'],
|
||||
ip_id=p["port_id"],
|
||||
mac=mac,
|
||||
state=state)
|
||||
link_list.append(link)
|
||||
float_ip = float_list.get(ip['ip_address'], None)
|
||||
if float_ip:
|
||||
link = self._build_link(p["net_id"],
|
||||
float_ip['instance_id'],
|
||||
float_ip['ip'],
|
||||
ip_id=float_ip["id"],
|
||||
mac=mac,
|
||||
pool=float_ip["pool"]
|
||||
)
|
||||
link_list.append(link)
|
||||
if not link_list:
|
||||
for ip in floating_ips:
|
||||
if ip["instance_id"]:
|
||||
link = self._build_link(os_helpers.PUBLIC_NETWORK,
|
||||
ip['instance_id'],
|
||||
ip['ip'],
|
||||
ip_id=ip["id"],
|
||||
pool=ip["pool"]
|
||||
)
|
||||
compute_list = self.index(req)
|
||||
floating_ips = self.get_floating_ips(
|
||||
req
|
||||
)
|
||||
for c in compute_list:
|
||||
compute_id = c["id"]
|
||||
compute = self.get_server(req, compute_id)
|
||||
ports = self._get_ports(req, compute_id)
|
||||
server_addrs = compute.get("addresses", {})
|
||||
for addr_set in server_addrs.values():
|
||||
for addr in addr_set:
|
||||
public_ip = False
|
||||
pool = None
|
||||
network_id = "fixed"
|
||||
mac = addr["OS-EXT-IPS-MAC:mac_addr"]
|
||||
ip_type = addr["OS-EXT-IPS:type"]
|
||||
address = addr['addr']
|
||||
ip_id = None
|
||||
if ip_type == "fixed":
|
||||
for p in ports:
|
||||
if p['mac_addr'] == mac:
|
||||
ip_id = p['port_id']
|
||||
network_id = p["net_id"]
|
||||
break
|
||||
else:
|
||||
for fp in floating_ips:
|
||||
if address == fp['ip']:
|
||||
pool = fp['pool']
|
||||
ip_id = fp['id']
|
||||
network_id = fp['id']
|
||||
public_ip = True
|
||||
break
|
||||
link = self._build_link(
|
||||
network_id,
|
||||
compute_id,
|
||||
address,
|
||||
mac=mac,
|
||||
pool=pool,
|
||||
ip_id=ip_id,
|
||||
public_ip=public_ip
|
||||
)
|
||||
link_list.append(link)
|
||||
return link_list
|
||||
|
||||
@ -893,8 +917,43 @@ class OpenStackHelper(BaseHelper):
|
||||
|
||||
raise webob.exc.HTTPNotFound
|
||||
|
||||
def assign_floating_ip(self, req, network_id, device_id,
|
||||
pool=None):
|
||||
def get_floatingip_id(self, req, address):
|
||||
"""Get the floating IP ID
|
||||
|
||||
:param req: the incoming network
|
||||
:param address: floating ip address
|
||||
"""
|
||||
floating_ips = self.get_floating_ips(req)
|
||||
for fp in floating_ips:
|
||||
if address == fp['ip']:
|
||||
return str(fp['id'])
|
||||
raise webob.exc.HTTPNotFound
|
||||
|
||||
def assign_floating_ip(self, req, floatingip_id, device_id):
|
||||
"""assign floating ip to a server
|
||||
|
||||
:param req: the incoming request
|
||||
:param floatingip_id: floating ip id
|
||||
:param device_id: device id
|
||||
"""
|
||||
ip = self.get_floating_ip(req, floatingip_id)
|
||||
|
||||
self.associate_floating_ip(req, device_id, ip['ip'])
|
||||
|
||||
try:
|
||||
link_public = self._build_link(
|
||||
floatingip_id,
|
||||
device_id,
|
||||
ip['ip'],
|
||||
ip_id=floatingip_id,
|
||||
public_ip=True
|
||||
)
|
||||
except Exception:
|
||||
raise exception.OCCIInvalidSchema()
|
||||
return link_public
|
||||
|
||||
def assign_floating_ip_deprecated(self, req, network_id, device_id,
|
||||
pool=None):
|
||||
"""assign floating ip to a server
|
||||
|
||||
:param req: the incoming request
|
||||
|
131
ooi/api/ip_reservation.py
Normal file
131
ooi/api/ip_reservation.py
Normal file
@ -0,0 +1,131 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 LIP - INDIGO-DataCloud
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ooi.api import base
|
||||
from ooi.api import helpers
|
||||
from ooi import exception
|
||||
from ooi.occi.core import collection
|
||||
from ooi.occi.infrastructure import ip_reservation
|
||||
from ooi.occi import validator as occi_validator
|
||||
from ooi.openstack import network as os_network
|
||||
|
||||
|
||||
class Controller(base.Controller):
|
||||
def __init__(self, app=None, openstack_version=None):
|
||||
"""IP reservation controller initialization
|
||||
|
||||
:param app: application
|
||||
:param: openstack_version: nova version
|
||||
"""
|
||||
|
||||
super(Controller, self).__init__(
|
||||
app=app,
|
||||
openstack_version=openstack_version)
|
||||
self.os_helper = helpers.OpenStackHelper(
|
||||
self.app,
|
||||
self.openstack_version
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _get_ipreservation_resources(ipreservation_list):
|
||||
"""Create network instances from ip reservations in json format
|
||||
|
||||
:param ipreservation_list: ip reservation objects provides by
|
||||
the cloud infrastructure
|
||||
"""
|
||||
occi_ipreservation_resources = []
|
||||
if ipreservation_list:
|
||||
for s in ipreservation_list:
|
||||
n_id = str(s["id"]) # some versions retrieve int.
|
||||
n_name = s["pool"]
|
||||
n_address = s["ip"]
|
||||
n_used = False
|
||||
if s["instance_id"]:
|
||||
n_used = True
|
||||
s = ip_reservation.IPReservation(title=n_name,
|
||||
id=n_id,
|
||||
address=n_address,
|
||||
used=n_used
|
||||
)
|
||||
occi_ipreservation_resources.append(s)
|
||||
return occi_ipreservation_resources
|
||||
|
||||
def index(self, req):
|
||||
"""List ip reservations
|
||||
|
||||
:param req: request object
|
||||
"""
|
||||
occi_ipreservation = self.os_helper.get_floating_ips(req)
|
||||
occi_ipreservation_resources = self._get_ipreservation_resources(
|
||||
occi_ipreservation)
|
||||
|
||||
return collection.Collection(
|
||||
resources=occi_ipreservation_resources)
|
||||
|
||||
def show(self, req, id):
|
||||
"""Get ip reservation details
|
||||
|
||||
:param req: request object
|
||||
:param id: ip reservation identification
|
||||
"""
|
||||
resp = self.os_helper.get_floating_ip(req, id)
|
||||
occi_network_resources = self._get_ipreservation_resources(
|
||||
[resp])
|
||||
return occi_network_resources[0]
|
||||
|
||||
def create(self, req, body=None):
|
||||
"""Create an ip reservation instance in the cloud
|
||||
|
||||
:param req: request object
|
||||
:param body: body request (not used)
|
||||
"""
|
||||
parser = req.get_parser()(req.headers, req.body)
|
||||
scheme = {
|
||||
"category": ip_reservation.IPReservation.kind,
|
||||
"optional_mixins": [
|
||||
os_network.OSFloatingIPPool,
|
||||
]
|
||||
}
|
||||
obj = parser.parse()
|
||||
validator = occi_validator.Validator(obj)
|
||||
validator.validate(scheme)
|
||||
pool = None
|
||||
if os_network.OSFloatingIPPool.scheme in obj["schemes"]:
|
||||
pool = (
|
||||
obj["schemes"][os_network.OSFloatingIPPool.scheme][0]
|
||||
)
|
||||
resp = self.os_helper.allocate_floating_ip(req, pool)
|
||||
occi_network_resources = self._get_ipreservation_resources(
|
||||
[resp])
|
||||
return collection.Collection(resources=occi_network_resources)
|
||||
|
||||
def delete(self, req, id):
|
||||
"""delete an ip reservation instance
|
||||
|
||||
:param req: current request
|
||||
:param id: identification
|
||||
"""
|
||||
self.os_helper.release_floating_ip(req, id)
|
||||
return []
|
||||
|
||||
def run_action(self, req, id, body):
|
||||
"""Run action over the network
|
||||
|
||||
:param req: current request
|
||||
:param id: ip reservation identification
|
||||
:param body: body
|
||||
"""
|
||||
raise exception.NotImplemented()
|
@ -18,6 +18,7 @@ from ooi.api import helpers
|
||||
from ooi import exception
|
||||
from ooi.occi.core import collection
|
||||
from ooi.occi.infrastructure import compute
|
||||
from ooi.occi.infrastructure import ip_reservation
|
||||
from ooi.occi.infrastructure import network
|
||||
from ooi.occi.infrastructure import network_link
|
||||
from ooi.occi import validator as occi_validator
|
||||
@ -40,8 +41,14 @@ def _get_network_link_resources(link_list):
|
||||
state = l.get('state', None)
|
||||
ip_id = l.get('ip_id', None)
|
||||
net_id = l['network_id']
|
||||
n = network.NetworkResource(title="network",
|
||||
id=net_id)
|
||||
public_ip = l['public_ip']
|
||||
if public_ip:
|
||||
n = ip_reservation.IPReservation(title="network",
|
||||
address=ip,
|
||||
id=net_id)
|
||||
else:
|
||||
n = network.NetworkResource(title="network",
|
||||
id=net_id)
|
||||
c = compute.ComputeResource(title="Compute",
|
||||
id=compute_id
|
||||
)
|
||||
@ -77,14 +84,13 @@ class Controller(base.Controller):
|
||||
:param id: network link identification
|
||||
"""
|
||||
try:
|
||||
server_id, network_id, server_addr = id.split('_', 2)
|
||||
server_id, server_addr = id.split('_', 1)
|
||||
except ValueError:
|
||||
raise exception.LinkNotFound(link_id=id)
|
||||
try:
|
||||
link = self.os_helper.get_compute_net_link(
|
||||
req,
|
||||
server_id,
|
||||
network_id,
|
||||
server_addr)
|
||||
occi_instance = _get_network_link_resources([link])[0]
|
||||
except Exception:
|
||||
@ -122,28 +128,42 @@ class Controller(base.Controller):
|
||||
validator.validate(scheme)
|
||||
|
||||
attrs = obj.get("attributes", {})
|
||||
_, net_id = helpers.get_id_with_kind(
|
||||
req,
|
||||
attrs.get("occi.core.target"),
|
||||
network.NetworkResource.kind)
|
||||
_, server_id = helpers.get_id_with_kind(
|
||||
req,
|
||||
attrs.get("occi.core.source"),
|
||||
compute.ComputeResource.kind)
|
||||
pool = None
|
||||
if os_network.OSFloatingIPPool.scheme in obj["schemes"]:
|
||||
pool = (
|
||||
obj["schemes"][os_network.OSFloatingIPPool.scheme][0]
|
||||
)
|
||||
# Allocate public IP and associate it ot the server
|
||||
if net_id == os_helpers.PUBLIC_NETWORK:
|
||||
|
||||
if (ip_reservation.IPReservation.kind.location in
|
||||
attrs.get("occi.core.target")):
|
||||
_, net_id = helpers.get_id_with_kind(
|
||||
req,
|
||||
attrs.get("occi.core.target"),
|
||||
ip_reservation.IPReservation.kind)
|
||||
os_link = self.os_helper.assign_floating_ip(
|
||||
req, net_id, server_id, pool
|
||||
req, net_id, server_id
|
||||
)
|
||||
else:
|
||||
# Allocate private network
|
||||
os_link = self.os_helper.create_port(
|
||||
req, net_id, server_id)
|
||||
_, net_id = helpers.get_id_with_kind(
|
||||
req,
|
||||
attrs.get("occi.core.target"),
|
||||
network.NetworkResource.kind)
|
||||
# TODO(jorgesece): DEPRECATION
|
||||
# Delete this method for linking public network.
|
||||
if net_id == os_helpers.PUBLIC_NETWORK:
|
||||
pool = None
|
||||
if os_network.OSFloatingIPPool.scheme in obj["schemes"]:
|
||||
pool = (
|
||||
obj["schemes"][os_network.OSFloatingIPPool.scheme][0]
|
||||
)
|
||||
# Allocate public IP and associate it on the server
|
||||
os_link = self.os_helper.assign_floating_ip_deprecated(
|
||||
req, net_id, server_id, pool
|
||||
)
|
||||
# END DEPRECATION
|
||||
else:
|
||||
# Allocate private network
|
||||
os_link = self.os_helper.create_port(
|
||||
req, net_id, server_id)
|
||||
occi_link = _get_network_link_resources([os_link])
|
||||
return collection.Collection(resources=occi_link)
|
||||
|
||||
@ -155,6 +175,7 @@ class Controller(base.Controller):
|
||||
"""
|
||||
iface = self._get_interface_from_id(req, id)
|
||||
server = iface.source.id
|
||||
# TODO(jorgesece): DEPRECATION
|
||||
if iface.target.id == os_helpers.PUBLIC_NETWORK:
|
||||
# remove floating IP
|
||||
self.os_helper.remove_floating_ip(req, server,
|
||||
@ -163,7 +184,13 @@ class Controller(base.Controller):
|
||||
# release IP
|
||||
self.os_helper.release_floating_ip(req,
|
||||
iface.ip_id)
|
||||
# END DEPRECATION
|
||||
else:
|
||||
self.os_helper.delete_port(
|
||||
req, server, iface.ip_id)
|
||||
if isinstance(iface.target,
|
||||
ip_reservation.IPReservation):
|
||||
self.os_helper.remove_floating_ip(req, server,
|
||||
iface.address)
|
||||
else:
|
||||
self.os_helper.delete_port(
|
||||
req, server, iface.ip_id)
|
||||
return []
|
@ -21,6 +21,7 @@ from ooi.occi.core import link
|
||||
from ooi.occi.core import resource
|
||||
from ooi.occi.infrastructure import compute
|
||||
from ooi.occi.infrastructure import contextualization
|
||||
from ooi.occi.infrastructure import ip_reservation
|
||||
from ooi.occi.infrastructure import network
|
||||
from ooi.occi.infrastructure import network_link
|
||||
from ooi.occi.infrastructure import storage
|
||||
@ -99,6 +100,7 @@ class Controller(base.Controller):
|
||||
mixins.append(network.ip_network)
|
||||
kinds.append(network_link.NetworkInterface.kind)
|
||||
mixins.append(network_link.ip_network_interface)
|
||||
kinds.append(ip_reservation.IPReservation.kind)
|
||||
|
||||
# OCCI infra compute mixins
|
||||
mixins.append(infra_templates.os_tpl)
|
||||
|
73
ooi/occi/infrastructure/ip_reservation.py
Normal file
73
ooi/occi/infrastructure/ip_reservation.py
Normal file
@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 LIP - INDIGO-DataCloud
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ooi.occi.core import attribute as attr
|
||||
from ooi.occi.core import kind
|
||||
from ooi.occi import helpers
|
||||
from ooi.occi.infrastructure import network
|
||||
|
||||
|
||||
class IPReservation(network.NetworkResource):
|
||||
attributes = attr.AttributeCollection({
|
||||
"occi.ipreservation.address": attr.MutableAttribute(
|
||||
"occi.ipreservation.address",
|
||||
description="Internet Protocol(IP) network"
|
||||
" address re-served for Compute instances"
|
||||
" linking with this IPReservation instance",
|
||||
attr_type=attr.AttributeType.string_type),
|
||||
"occi.ipreservation.used": attr.InmutableAttribute(
|
||||
"occi.ipreservation.used",
|
||||
description="Indication whether"
|
||||
" the reserved address is currently in use.",
|
||||
attr_type=attr.AttributeType.boolean_type),
|
||||
"occi.ipreservation.state": attr.InmutableAttribute(
|
||||
"occi.ipreservation.state",
|
||||
description="Indicates the state of the resource.",
|
||||
attr_type=attr.AttributeType.string_type),
|
||||
})
|
||||
|
||||
kind = kind.Kind(helpers.build_scheme('infrastructure'), 'ipreservation',
|
||||
'IPReservation', attributes, 'ipreservation/',
|
||||
parent=network.NetworkResource.kind)
|
||||
|
||||
def __init__(self, title, address, id=None, used=False,
|
||||
state=None, mixins=[]):
|
||||
super(IPReservation, self).__init__(title, id=id,
|
||||
mixins=mixins)
|
||||
|
||||
self.address = address
|
||||
self.attributes["occi.ipreservation.used"] = (
|
||||
attr.InmutableAttribute.from_attr(
|
||||
self.attributes["occi.ipreservation.used"], used))
|
||||
self.attributes["occi.ipreservation.state"] = (
|
||||
attr.InmutableAttribute.from_attr(
|
||||
self.attributes["occi.ipreservation.state"], state))
|
||||
|
||||
@property
|
||||
def address(self):
|
||||
return self.attributes["occi.ipreservation.address"].value
|
||||
|
||||
@address.setter
|
||||
def address(self, value):
|
||||
self.attributes["occi.ipreservation.address"].value = value
|
||||
|
||||
@property
|
||||
def used(self):
|
||||
return self.attributes["occi.ipreservation.used"].value
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self.attributes["occi.ipreservation.state"].value
|
@ -46,7 +46,7 @@ class OSNetworkInterface(network_link.NetworkInterface):
|
||||
|
||||
def __init__(self, source, target, mac, address, ip_id=None,
|
||||
pool=None, state='active'):
|
||||
link_id = '_'.join([source.id, target.id, address])
|
||||
link_id = '_'.join([source.id, address])
|
||||
mixins = [network_link.ip_network_interface]
|
||||
if pool:
|
||||
mixins.append(OSFloatingIPPool(pool))
|
||||
|
@ -125,8 +125,12 @@ pools = {
|
||||
}
|
||||
|
||||
linked_vm_id = uuid.uuid4().hex
|
||||
linked_vm_id_2 = uuid.uuid4().hex
|
||||
|
||||
allocated_ip = "192.168.253.23"
|
||||
allocated_ip = {"ip": "192.168.253.23",
|
||||
"id": 1,
|
||||
"pool": uuid.uuid4().hex,
|
||||
"instance_id": None}
|
||||
|
||||
floating_ips = {
|
||||
tenants["foo"]["id"]: [],
|
||||
@ -182,6 +186,16 @@ ports = {
|
||||
"net_id": uuid.uuid4().hex,
|
||||
"server_id": linked_vm_id
|
||||
},
|
||||
{
|
||||
"port_id": uuid.uuid4().hex,
|
||||
"fixed_ips": [
|
||||
{"ip_address": "192.168.253.2"}
|
||||
],
|
||||
"mac_addr": uuid.uuid4().hex,
|
||||
"port_state": "ACTIVE",
|
||||
"net_id": uuid.uuid4().hex,
|
||||
"server_id": linked_vm_id_2
|
||||
},
|
||||
|
||||
],
|
||||
}
|
||||
@ -251,6 +265,32 @@ servers = {
|
||||
"security_groups":[
|
||||
{"name": "group1"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": linked_vm_id_2,
|
||||
"name": "withvolume",
|
||||
"flavor": {"id": flavors[1]["id"]},
|
||||
"image": {"id": images["bar"]["id"]},
|
||||
"status": "ACTIVE",
|
||||
"os-extended-volumes:volumes_attached": [
|
||||
{"id": volumes[tenants["baz"]["id"]][0]["id"]}
|
||||
],
|
||||
"addresses": {
|
||||
"private": [
|
||||
{"addr": (
|
||||
(ports[tenants["baz"]["id"]]
|
||||
[1]["fixed_ips"][0]["ip_address"])
|
||||
),
|
||||
"OS-EXT-IPS:type": "fixed",
|
||||
"OS-EXT-IPS-MAC:mac_addr": (
|
||||
ports[tenants["baz"]["id"]][1]["mac_addr"]
|
||||
)
|
||||
},
|
||||
{"addr": floating_ips[tenants["baz"]["id"]][0]["ip"],
|
||||
"OS-EXT-IPS:type": "floating",
|
||||
"OS-EXT-IPS-MAC:mac_addr": "1234"},
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
}
|
||||
@ -441,6 +481,12 @@ def fake_query_results():
|
||||
'scheme="http://schemas.ogf.org/occi/infrastructure/'
|
||||
'networkinterface#"; '
|
||||
'class="mixin"; title="IP Network interface Mixin"')
|
||||
cats.append(
|
||||
'ipreservation; '
|
||||
'scheme="http://schemas.ogf.org/occi/infrastructure#"; '
|
||||
'class="kind"; title="IPReservation"; '
|
||||
'rel="http://schemas.ogf.org/occi/infrastructure#network"; '
|
||||
'location="%s/ipreservation/"' % application_url)
|
||||
|
||||
# OCCI Infrastructure Storage
|
||||
cats.append(
|
||||
@ -615,6 +661,20 @@ class FakeApp(object):
|
||||
self.routes[path_base] = create_fake_json_resp(
|
||||
{obj: list_obj})
|
||||
|
||||
def _populate_ports(self, path, servers_list, ports_list):
|
||||
for s in servers_list:
|
||||
p_list = []
|
||||
path_base = "%s/servers/%s/%s" % (
|
||||
path,
|
||||
s["id"],
|
||||
"os-interface"
|
||||
)
|
||||
for p in ports_list:
|
||||
if p["server_id"] == s["id"]:
|
||||
p_list.append(p)
|
||||
self.routes[path_base] = create_fake_json_resp(
|
||||
{"interfaceAttachments": p_list})
|
||||
|
||||
@webob.dec.wsgify()
|
||||
def __call__(self, req):
|
||||
if req.method == "GET":
|
||||
@ -660,7 +720,7 @@ class FakeApp(object):
|
||||
else:
|
||||
exc = webob.exc.HTTPNotFound()
|
||||
return FakeOpenStackFault(exc)
|
||||
ip = {"floating_ip": {"ip": allocated_ip, "id": 1}}
|
||||
ip = {"floating_ip": allocated_ip}
|
||||
return create_fake_json_resp(ip, 202)
|
||||
|
||||
def _do_create_port(self, req):
|
||||
@ -673,10 +733,9 @@ class FakeApp(object):
|
||||
p = {"interfaceAttachment": {
|
||||
"port_id": uuid.uuid4().hex,
|
||||
"fixed_ips":
|
||||
[{"ip_address":
|
||||
port[0]["fixed_ips"]
|
||||
[0]["ip_address"]
|
||||
}],
|
||||
[{
|
||||
"ip_address": port[0]["fixed_ips"][0]["ip_address"]
|
||||
}],
|
||||
"mac_addr": port[0]["mac_addr"],
|
||||
"port_state": "DOWN",
|
||||
"net_id": net,
|
||||
|
@ -292,7 +292,7 @@ def create_headers(category, content_type=None,
|
||||
|
||||
|
||||
def fake_build_link(net_id, compute_id, ip, mac=None,
|
||||
pool=None, state='active'):
|
||||
pool=None, state='active', public_ip=False):
|
||||
link = {}
|
||||
link['mac'] = mac
|
||||
link['pool'] = pool
|
||||
@ -300,6 +300,7 @@ def fake_build_link(net_id, compute_id, ip, mac=None,
|
||||
link['compute_id'] = compute_id
|
||||
link['ip'] = ip
|
||||
link['state'] = state
|
||||
link['public_ip'] = public_ip
|
||||
return link
|
||||
|
||||
|
||||
|
@ -424,12 +424,21 @@ class TestComputeController(test_middleware.TestMiddleware):
|
||||
for addr in addr_set:
|
||||
ip = addr["addr"]
|
||||
if addr["OS-EXT-IPS:type"] == "fixed":
|
||||
net_id = fakes.ports[tenant["id"]][0]["net_id"]
|
||||
for p in fakes.ports[tenant["id"]]:
|
||||
if (p["mac_addr"] ==
|
||||
addr["OS-EXT-IPS-MAC:mac_addr"]):
|
||||
net_id = p["net_id"]
|
||||
break
|
||||
target = utils.join_url(self.application_url + "/",
|
||||
"network/%s" % net_id)
|
||||
else:
|
||||
net_id = "PUBLIC"
|
||||
link_id = '_'.join([server["id"], net_id, ip])
|
||||
target = utils.join_url(self.application_url + "/",
|
||||
"network/%s" % net_id)
|
||||
for floating_ip in fakes.floating_ips[tenant["id"]]:
|
||||
if floating_ip["ip"] == ip:
|
||||
net_id = floating_ip['id']
|
||||
break
|
||||
target = utils.join_url(self.application_url + "/",
|
||||
"ipreservation/%s" % net_id)
|
||||
link_id = '_'.join([server["id"], ip])
|
||||
self.assertResultIncludesLink(link_id, source, target,
|
||||
resp)
|
||||
|
||||
|
@ -0,0 +1,178 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 LIP - INDIGO-DataCloud
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import uuid
|
||||
|
||||
from ooi.tests import fakes
|
||||
from ooi.tests.functional.middleware import test_middleware
|
||||
from ooi import utils
|
||||
|
||||
|
||||
def build_occi_ip_reservation(ip, application_url):
|
||||
name = ip["pool"]
|
||||
network_id = ip["id"]
|
||||
address = ip["ip"]
|
||||
if ip["instance_id"]:
|
||||
used = str(True).lower()
|
||||
else:
|
||||
used = str(False).lower()
|
||||
cats = []
|
||||
cats.append('ipreservation; '
|
||||
'scheme='
|
||||
'"http://schemas.ogf.org/occi/infrastructure#";'
|
||||
' class="kind"; title="IPReservation"; rel='
|
||||
'"http://schemas.ogf.org/occi/infrastructure#network";'
|
||||
' location="%s/ipreservation/"' % application_url)
|
||||
links = []
|
||||
links.append('<%s/ipreservation/%s?action=up>; '
|
||||
'rel="http://schemas.ogf.org/occi/'
|
||||
'infrastructure/network/action#up"' %
|
||||
(application_url, network_id))
|
||||
links.append('<%s/ipreservation/%s?action=down>; '
|
||||
'rel="http://schemas.ogf.org/occi/'
|
||||
'infrastructure/network/action#down"' %
|
||||
(application_url, network_id))
|
||||
|
||||
attrs = [
|
||||
'occi.core.title="%s"' % name,
|
||||
'occi.core.id="%s"' % network_id,
|
||||
'occi.ipreservation.address="%s"' % address,
|
||||
'occi.ipreservation.used="%s"' % used,
|
||||
]
|
||||
result = []
|
||||
for c in cats:
|
||||
result.append(("Category", c))
|
||||
for a in attrs:
|
||||
result.append(("X-OCCI-Attribute", a))
|
||||
for l in links:
|
||||
result.append(("Link", l))
|
||||
return result
|
||||
|
||||
|
||||
class TestNetIPReservationController(test_middleware.TestMiddleware):
|
||||
"""Test OCCI IP Reservation controller."""
|
||||
def setUp(self):
|
||||
super(TestNetIPReservationController, self).setUp()
|
||||
self.application_url = fakes.application_url
|
||||
self.app = self.get_app()
|
||||
|
||||
def test_list_empty(self):
|
||||
tenant = fakes.tenants["bar"]
|
||||
|
||||
for url in ("/ipreservation/", "/ipreservation"):
|
||||
req = self._build_req(url, tenant["id"], method="GET")
|
||||
|
||||
req.environ["HTTP_X_PROJECT_ID"] = tenant["id"]
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
expected_result = ""
|
||||
self.assertContentType(resp)
|
||||
self.assertExpectedResult(expected_result, resp)
|
||||
self.assertEqual(204, resp.status_code)
|
||||
|
||||
def test_list(self):
|
||||
tenant = fakes.tenants["baz"]
|
||||
|
||||
for url in ("/ipreservation/", "/ipreservation"):
|
||||
req = self._build_req(url, tenant["id"], method="GET")
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
expected = []
|
||||
for ip in fakes.floating_ips[tenant["id"]]:
|
||||
expected.append(
|
||||
("X-OCCI-Location",
|
||||
utils.join_url(self.application_url + "/",
|
||||
"ipreservation/%s" % ip["id"]))
|
||||
)
|
||||
|
||||
self.assertExpectedResult(expected, resp)
|
||||
|
||||
def test_show(self):
|
||||
tenant = fakes.tenants["baz"]
|
||||
for ip in fakes.floating_ips[tenant["id"]]:
|
||||
ip_id = ip["id"]
|
||||
req = self._build_req("/ipreservation/%s" % ip_id,
|
||||
tenant["id"], method="GET")
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
self.assertContentType(resp)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
expected = build_occi_ip_reservation(
|
||||
ip,
|
||||
self.application_url)
|
||||
self.assertExpectedResult(expected, resp)
|
||||
|
||||
def test_show_invalid_id(self):
|
||||
tenant = fakes.tenants["foo"]
|
||||
link_id = uuid.uuid4().hex
|
||||
req = self._build_req("/ipreservation/%s" % link_id,
|
||||
tenant["id"], method="GET")
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(404, resp.status_code)
|
||||
|
||||
def test_delete(self):
|
||||
tenant = fakes.tenants["foo"]
|
||||
link_id = uuid.uuid4().hex
|
||||
req = self._build_req("/ipreservation/%s" % link_id,
|
||||
tenant["id"], method="DELETE")
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(204, resp.status_code)
|
||||
|
||||
def test_create(self):
|
||||
tenant = fakes.tenants["baz"]
|
||||
ip_id = fakes.allocated_ip["id"]
|
||||
headers = {
|
||||
'Category': 'ipreservation;'
|
||||
' scheme='
|
||||
'"http://schemas.ogf.org/occi/infrastructure#";'
|
||||
'class="kind",'
|
||||
}
|
||||
req = self._build_req("/ipreservation/",
|
||||
tenant["id"],
|
||||
method="POST",
|
||||
headers=headers)
|
||||
resp = req.get_response(self.app)
|
||||
expected = [("X-OCCI-Location",
|
||||
utils.join_url(self.application_url + "/",
|
||||
"ipreservation/%s" % ip_id))]
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertExpectedResult(expected, resp)
|
||||
|
||||
def test_create_with_pool(self):
|
||||
tenant = fakes.tenants["baz"]
|
||||
ip_id = fakes.allocated_ip["id"]
|
||||
pool_name = "public"
|
||||
headers = {
|
||||
'Category': ('ipreservation;'
|
||||
' scheme='
|
||||
'"http://schemas.ogf.org/occi/infrastructure#";'
|
||||
'class="kind",'
|
||||
'%s;'
|
||||
'scheme="http://schemas.openstack.org/network/'
|
||||
'floatingippool#"; class="mixin"') % pool_name,
|
||||
}
|
||||
req = self._build_req("/ipreservation/",
|
||||
tenant["id"],
|
||||
method="POST",
|
||||
headers=headers)
|
||||
resp = req.get_response(self.app)
|
||||
expected = [("X-OCCI-Location",
|
||||
utils.join_url(self.application_url + "/",
|
||||
"ipreservation/%s" % ip_id))]
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertExpectedResult(expected, resp)
|
@ -52,42 +52,29 @@ class TestNetInterfaceController(test_middleware.TestMiddleware):
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
servers = fakes.servers[tenant["id"]]
|
||||
expected = []
|
||||
float_list = {}
|
||||
for floating_ip in fakes.floating_ips[tenant["id"]]:
|
||||
if floating_ip["instance_id"]:
|
||||
float_list.update({floating_ip['fixed_ip']: floating_ip})
|
||||
instance_vm = fakes.linked_vm_id
|
||||
for p in fakes.ports[tenant["id"]]:
|
||||
for ip in p["fixed_ips"]:
|
||||
link_id = '_'.join([instance_vm,
|
||||
p["net_id"],
|
||||
ip["ip_address"]])
|
||||
expected.append(
|
||||
("X-OCCI-Location",
|
||||
utils.join_url(self.application_url + "/",
|
||||
"networklink/%s" % link_id))
|
||||
)
|
||||
float_ip = float_list.get(ip['ip_address'], None)
|
||||
if float_ip:
|
||||
for server in servers:
|
||||
server_addrs = server.get("addresses", {})
|
||||
instance_vm = server["id"]
|
||||
for addr_set in server_addrs.values():
|
||||
for addr in addr_set:
|
||||
address = addr['addr']
|
||||
link_id = '_'.join([instance_vm,
|
||||
"PUBLIC",
|
||||
float_ip["ip"]])
|
||||
address])
|
||||
expected.append(
|
||||
("X-OCCI-Location",
|
||||
utils.join_url(self.application_url + "/",
|
||||
"networklink/%s" % link_id))
|
||||
)
|
||||
"networklink/%s" % link_id)))
|
||||
|
||||
self.assertExpectedResult(expected, resp)
|
||||
|
||||
def test_show_iface(self):
|
||||
tenant = fakes.tenants["baz"]
|
||||
instance_vm = fakes.linked_vm_id
|
||||
for p in fakes.ports[tenant["id"]]:
|
||||
for ip in p["fixed_ips"]:
|
||||
instance_vm = p["server_id"]
|
||||
link_id = '_'.join([instance_vm,
|
||||
p["net_id"],
|
||||
ip["ip_address"]]
|
||||
)
|
||||
req = self._build_req("/networklink/%s" % link_id,
|
||||
@ -178,7 +165,6 @@ class TestNetInterfaceController(test_middleware.TestMiddleware):
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
link_id = '_'.join([link_info['server_id'],
|
||||
link_info['net_id'],
|
||||
link_info['fixed_ips'][0]
|
||||
["ip_address"]])
|
||||
expected = [("X-OCCI-Location",
|
||||
@ -188,6 +174,28 @@ class TestNetInterfaceController(test_middleware.TestMiddleware):
|
||||
self.assertExpectedResult(expected, resp)
|
||||
self.assertDefaults(resp)
|
||||
|
||||
def test_create_link_ipreservation(self):
|
||||
tenant = fakes.tenants["baz"]
|
||||
net_id = fakes.floating_ips[tenant['id']][0]['id']
|
||||
occi_compute_id = utils.join_url(
|
||||
self.application_url + "/",
|
||||
"compute/%s" % fakes.linked_vm_id)
|
||||
occi_net_id = utils.join_url(self.application_url + "/",
|
||||
"ipreservation/%s" % net_id)
|
||||
headers = {
|
||||
'Category': (
|
||||
'networkinterface;'
|
||||
'scheme="http://schemas.ogf.org/occi/infrastructure#";'
|
||||
'class="kind"'),
|
||||
'X-OCCI-Attribute': ('occi.core.source="%s", '
|
||||
'occi.core.target="%s"'
|
||||
) % (occi_compute_id, occi_net_id)
|
||||
}
|
||||
req = self._build_req("/networklink", tenant["id"], method="POST",
|
||||
headers=headers)
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
def test_delete_fixed(self):
|
||||
tenant = fakes.tenants["baz"]
|
||||
|
||||
@ -195,7 +203,6 @@ class TestNetInterfaceController(test_middleware.TestMiddleware):
|
||||
if n["net_id"] != "PUBLIC":
|
||||
if n["server_id"]:
|
||||
link_id = '_'.join([n["server_id"],
|
||||
n["net_id"],
|
||||
n["fixed_ips"]
|
||||
[0]["ip_address"]])
|
||||
req = self._build_req(
|
||||
@ -210,7 +217,18 @@ class TestNetInterfaceController(test_middleware.TestMiddleware):
|
||||
for n in fakes.floating_ips[tenant["id"]]:
|
||||
if n["instance_id"]:
|
||||
link_id = '_'.join([n["instance_id"],
|
||||
"PUBLIC",
|
||||
n["ip"]])
|
||||
req = self._build_req("/networklink/%s" % link_id,
|
||||
tenant["id"], method="DELETE")
|
||||
resp = req.get_response(self.app)
|
||||
self.assertContentType(resp)
|
||||
self.assertEqual(204, resp.status_code)
|
||||
|
||||
def test_delete_ipreservation(self):
|
||||
tenant = fakes.tenants["baz"]
|
||||
for n in fakes.floating_ips[tenant["id"]]:
|
||||
if n["instance_id"]:
|
||||
link_id = '_'.join([n["instance_id"],
|
||||
n["ip"]])
|
||||
req = self._build_req("/networklink/%s" % link_id,
|
||||
tenant["id"], method="DELETE")
|
||||
|
@ -86,8 +86,7 @@ class TestComputeController(base.TestController):
|
||||
@mock.patch.object(compute.Controller, "_get_server_floating_ips")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_floating_ips")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "remove_floating_ip")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "release_floating_ip")
|
||||
def test_release_floating_ips(self, mock_release, mock_remove,
|
||||
def test_release_floating_ips(self, mock_remove,
|
||||
mock_get_floating,
|
||||
mock_server_floating):
|
||||
mock_server_floating.return_value = ["1.2.3.4", "5.6.7.8"]
|
||||
@ -100,8 +99,6 @@ class TestComputeController(base.TestController):
|
||||
mock_get_floating.assert_called_with(None)
|
||||
mock_remove.assert_has_calls([mock.call(None, "foo", "1.2.3.4"),
|
||||
mock.call(None, "foo", "5.6.7.8")])
|
||||
mock_release.assert_has_calls([mock.call(None, "bar"),
|
||||
mock.call(None, "baz")])
|
||||
|
||||
@mock.patch.object(compute.Controller, "_delete")
|
||||
def test_delete(self, mock_delete):
|
||||
@ -179,7 +176,8 @@ class TestComputeController(base.TestController):
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_flavor")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_server")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_network_id")
|
||||
def test_show(self, m_net_id, m_server, m_flavor, m_image, m_vol):
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_floatingip_id")
|
||||
def test_show(self, m_ipr, m_net_id, m_server, m_flavor, m_image, m_vol):
|
||||
for tenant in fakes.tenants.values():
|
||||
servers = fakes.servers[tenant["id"]]
|
||||
for server in servers:
|
||||
@ -194,6 +192,11 @@ class TestComputeController(base.TestController):
|
||||
net_id = fakes.networks.get(tenant["id"], [])
|
||||
if net_id:
|
||||
net_id = net_id[0]['id']
|
||||
floatip_ip = fakes.floating_ips.get(tenant["id"], [])
|
||||
floatip_id = 0
|
||||
if floatip_ip.__len__() > 0:
|
||||
floatip_id = floatip_ip[0]['id']
|
||||
m_ipr.return_value = floatip_id
|
||||
m_net_id.return_value = net_id
|
||||
m_server.return_value = server
|
||||
m_flavor.return_value = flavor
|
||||
@ -207,13 +210,17 @@ class TestComputeController(base.TestController):
|
||||
m_flavor.assert_called_with(None, flavor["id"])
|
||||
m_image.assert_called_with(None, image["id"])
|
||||
m_vol.assert_called_with(None, server["id"])
|
||||
if floatip_ip:
|
||||
m_ipr.assert_called_with(None, floatip_ip[0]["ip"])
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_server_volumes_link")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_image")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_flavor")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_server")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_network_id")
|
||||
def test_show_no_image(self, m_net_id, m_server, m_flavor, m_image, m_vol):
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_floatingip_id")
|
||||
def test_show_no_image(self, m_ipr, m_net_id, m_server, m_flavor,
|
||||
m_image, m_vol):
|
||||
for tenant in fakes.tenants.values():
|
||||
servers = fakes.servers[tenant["id"]]
|
||||
for server in servers:
|
||||
@ -225,6 +232,11 @@ class TestComputeController(base.TestController):
|
||||
net_id = fakes.networks.get(tenant["id"], [])
|
||||
if net_id:
|
||||
net_id = net_id[0]['id']
|
||||
floatip_ip = fakes.floating_ips.get(tenant["id"], [])
|
||||
floatip_id = 0
|
||||
if floatip_ip:
|
||||
floatip_id = floatip_ip[0]['id']
|
||||
m_ipr.return_value = floatip_id
|
||||
m_net_id.return_value = net_id
|
||||
m_server.return_value = server
|
||||
m_flavor.return_value = flavor
|
||||
@ -238,6 +250,8 @@ class TestComputeController(base.TestController):
|
||||
m_flavor.assert_called_with(None, flavor["id"])
|
||||
m_image.assert_called_with(None, image["id"])
|
||||
m_vol.assert_called_with(None, server["id"])
|
||||
if floatip_ip:
|
||||
m_ipr.assert_called_with(None, floatip_ip[0]["ip"])
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "create_server")
|
||||
@mock.patch.object(compute.Controller, "_get_network_from_req")
|
||||
|
@ -1403,4 +1403,33 @@ class TestOpenStackHelperReqs(TestBaseHelper):
|
||||
self.assertEqual(net_id, ret['network_id'])
|
||||
self.assertEqual(device_id, ret['compute_id'])
|
||||
self.assertEqual(ip, ret['ip'])
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper,
|
||||
"_get_req")
|
||||
@mock.patch.object(helpers.OpenStackHelper, "tenant_from_req")
|
||||
def test_associate_floating_ip_deprecated(self, m_ten, m_req):
|
||||
m_ten.return_value = uuid.uuid4().hex
|
||||
net_id = uuid.uuid4().hex
|
||||
device_id = uuid.uuid4().hex
|
||||
ip = uuid.uuid4().hex
|
||||
ip_id = uuid.uuid4().hex
|
||||
pool = uuid.uuid4().hex
|
||||
resp = fakes.create_fake_json_resp(
|
||||
{"floating_ip": {"ip": ip, "pool": pool, 'id': ip_id}},
|
||||
202
|
||||
)
|
||||
req_all = mock.MagicMock()
|
||||
req_all.get_response.return_value = resp
|
||||
resp_ass = fakes.create_fake_json_resp({}, 202)
|
||||
req_ass = mock.MagicMock()
|
||||
req_ass.get_response.return_value = resp_ass
|
||||
m_req.side_effect = [req_all,
|
||||
req_ass]
|
||||
ret = self.helper.assign_floating_ip_deprecated(None,
|
||||
net_id,
|
||||
device_id)
|
||||
self.assertIsNotNone(ret)
|
||||
self.assertEqual(net_id, ret['network_id'])
|
||||
self.assertEqual(device_id, ret['compute_id'])
|
||||
self.assertEqual(ip, ret['ip'])
|
||||
self.assertEqual(pool, ret['pool'])
|
||||
|
120
ooi/tests/unit/controllers/test_ip_reservation.py
Normal file
120
ooi/tests/unit/controllers/test_ip_reservation.py
Normal file
@ -0,0 +1,120 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 LIP - INDIGO-DataCloud
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from ooi.api import helpers
|
||||
from ooi.api import ip_reservation as ip_reservation_control
|
||||
from ooi.occi.infrastructure import ip_reservation
|
||||
from ooi.openstack import network as os_network
|
||||
from ooi.tests import base
|
||||
from ooi.tests import fakes
|
||||
from ooi.tests import fakes_network as fake_nets
|
||||
|
||||
|
||||
class TestIPReservationController(base.TestController):
|
||||
def setUp(self):
|
||||
super(TestIPReservationController, self).setUp()
|
||||
self.controller = ip_reservation_control.Controller(
|
||||
mock.MagicMock(), None
|
||||
)
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_floating_ips")
|
||||
def test_index_empty(self, m_iplist):
|
||||
tenant = fakes.tenants["foo"]
|
||||
floating_list = fakes.floating_ips[tenant["id"]]
|
||||
m_iplist.return_value = floating_list
|
||||
result = self.controller.index(None)
|
||||
expected = self.controller._get_ipreservation_resources(floating_list)
|
||||
self.assertEqual(expected, result.resources)
|
||||
self.assertEqual([], result.resources)
|
||||
m_iplist.assert_called_with(None)
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_floating_ips")
|
||||
def test_index(self, m_iplist):
|
||||
tenant = fakes.tenants["baz"]
|
||||
floating_list = fakes.floating_ips[tenant["id"]]
|
||||
m_iplist.return_value = floating_list
|
||||
result = self.controller.index(None)
|
||||
expected = self.controller._get_ipreservation_resources(floating_list)
|
||||
self.assertEqual(expected, result.resources)
|
||||
m_iplist.assert_called_with(None)
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "get_floating_ip")
|
||||
def test_show(self, m_ip):
|
||||
tenant = fakes.tenants["baz"]
|
||||
floating_ip = fakes.floating_ips[tenant["id"]][0]
|
||||
m_ip.return_value = floating_ip
|
||||
result = self.controller.show(None, floating_ip["id"])
|
||||
expected = self.controller._get_ipreservation_resources(
|
||||
[floating_ip])[0]
|
||||
self.assertIsInstance(result, ip_reservation.IPReservation)
|
||||
self.assertEqual(expected, result)
|
||||
m_ip.assert_called_with(None, floating_ip["id"])
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper,
|
||||
"release_floating_ip")
|
||||
def test_delete(self, mock_release):
|
||||
tenant = fakes.tenants["baz"]
|
||||
floating_ip = fakes.floating_ips[tenant["id"]][0]
|
||||
mock_release.return_value = []
|
||||
self.controller.delete(None, floating_ip["id"])
|
||||
mock_release.assert_called_with(None, floating_ip["id"])
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper,
|
||||
"allocate_floating_ip")
|
||||
def test_create(self, mock_allocate):
|
||||
tenant = fakes.tenants["baz"]
|
||||
floating_list = fakes.floating_ips[tenant["id"]][0]
|
||||
mock_allocate.return_value = floating_list
|
||||
parameters = {}
|
||||
categories = {ip_reservation.IPReservation.kind}
|
||||
req = fake_nets.create_req_test_occi(parameters, categories)
|
||||
|
||||
result = self.controller.create(req)
|
||||
|
||||
expected = self.controller._get_ipreservation_resources(
|
||||
[floating_list])
|
||||
self.assertEqual(expected, result.resources)
|
||||
mock_allocate.assert_called_with(req, None)
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "allocate_floating_ip")
|
||||
@mock.patch("ooi.occi.validator.Validator")
|
||||
def test_create_pool(self, mock_validator, mock_allocate):
|
||||
tenant = fakes.tenants["baz"]
|
||||
floating_list = fakes.floating_ips[tenant["id"]][0]
|
||||
mock_allocate.return_value = floating_list
|
||||
pool_name = "public"
|
||||
obj = {
|
||||
"attributes": {},
|
||||
"schemes": {
|
||||
os_network.OSFloatingIPPool.scheme: [pool_name],
|
||||
}
|
||||
}
|
||||
parameters = {}
|
||||
categories = {ip_reservation.IPReservation.kind}
|
||||
req = fake_nets.create_req_test_occi(parameters, categories)
|
||||
|
||||
req.get_parser = mock.MagicMock()
|
||||
req.get_parser.return_value.return_value.parse.return_value = obj
|
||||
mock_validator.validate.return_value = True
|
||||
|
||||
result = self.controller.create(req)
|
||||
|
||||
expected = self.controller._get_ipreservation_resources(
|
||||
[floating_list])
|
||||
self.assertEqual(expected, result.resources)
|
||||
mock_allocate.assert_called_with(req, pool_name)
|
@ -22,6 +22,7 @@ from ooi.api import network_link as network_link_api
|
||||
from ooi import exception
|
||||
from ooi.occi.core import collection
|
||||
from ooi.occi.infrastructure import compute
|
||||
from ooi.occi.infrastructure import ip_reservation
|
||||
from ooi.occi.infrastructure import network
|
||||
from ooi.occi.infrastructure import network_link
|
||||
from ooi.openstack import network as os_network
|
||||
@ -133,16 +134,14 @@ class TestNetworkLinkController(base.TestController):
|
||||
os_link['network_id'], os_link['instance_id'], os_link['ip'],
|
||||
mac=None, pool=os_link['pool'], state=os_link['status']
|
||||
)
|
||||
link_id = '%s_%s_%s' % (
|
||||
link_id = '%s_%s' % (
|
||||
os_link['instance_id'],
|
||||
os_link['network_id'],
|
||||
os_link['ip'])
|
||||
|
||||
ret = self.controller.show(None, link_id)
|
||||
self.assertIsInstance(ret, os_network.OSNetworkInterface)
|
||||
self.assertEqual(os_link["ip"], ret.address)
|
||||
mock_get.assert_called_with(None, str(os_link['instance_id']),
|
||||
os_link['network_id'],
|
||||
os_link['ip'])
|
||||
|
||||
@mock.patch.object(network_link_api.Controller, "_get_interface_from_id")
|
||||
@ -173,13 +172,13 @@ class TestNetworkLinkController(base.TestController):
|
||||
server_id = uuid.uuid4().hex
|
||||
net_id = uuid.uuid4().hex
|
||||
server_addr = "1.1.1.1"
|
||||
link_id = "%s_%s_%s" % (server_id, net_id, server_addr)
|
||||
link_id = "%s_%s" % (server_id, server_addr)
|
||||
mock_get_server.return_value = fake_nets.fake_build_link(
|
||||
net_id, server_id, server_addr
|
||||
)
|
||||
ret = self.controller.show(None, link_id)
|
||||
self.assertIsInstance(ret, os_network.OSNetworkInterface)
|
||||
mock_get_server.assert_called_with(None, server_id, net_id,
|
||||
mock_get_server.assert_called_with(None, server_id,
|
||||
server_addr)
|
||||
|
||||
def test_get_network_link_resources_fixed(self):
|
||||
@ -228,7 +227,8 @@ class TestNetworkLinkController(base.TestController):
|
||||
ret = network_link_api._get_network_link_resources(None)
|
||||
self.assertEqual(ret.__len__(), 0)
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "assign_floating_ip")
|
||||
@mock.patch.object(helpers.OpenStackHelper,
|
||||
"assign_floating_ip_deprecated")
|
||||
@mock.patch("ooi.api.helpers.get_id_with_kind")
|
||||
def test_create_public(self, mock_get_id, mock_assign):
|
||||
server_id = uuid.uuid4().hex
|
||||
@ -243,7 +243,7 @@ class TestNetworkLinkController(base.TestController):
|
||||
mock_assign.return_value = fake_nets.fake_build_link(
|
||||
net_id, server_id, ip
|
||||
)
|
||||
mock_get_id.side_effect = [('', net_id), ('', server_id)]
|
||||
mock_get_id.side_effect = [('', server_id), ('', net_id)]
|
||||
ret = self.controller.create(req)
|
||||
self.assertIsNotNone(ret)
|
||||
link = ret.resources.pop()
|
||||
@ -254,12 +254,39 @@ class TestNetworkLinkController(base.TestController):
|
||||
self.assertEqual(server_id, link.source.id)
|
||||
mock_assign.assert_called_with(mock.ANY, net_id, server_id, None)
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "assign_floating_ip")
|
||||
@mock.patch("ooi.api.helpers.get_id_with_kind")
|
||||
def test_create_ipreservation(self, mock_get_id, mock_assign):
|
||||
server_id = uuid.uuid4().hex
|
||||
net_id = "foo/ipreservation/%s" % uuid.uuid4().hex
|
||||
ip = '8.0.0.0'
|
||||
parameters = {
|
||||
"occi.core.target": net_id,
|
||||
"occi.core.source": server_id,
|
||||
}
|
||||
categories = {network_link.NetworkInterface.kind}
|
||||
req = fake_nets.create_req_test_occi(parameters, categories)
|
||||
mock_assign.return_value = fake_nets.fake_build_link(
|
||||
net_id, server_id, ip, public_ip=True
|
||||
)
|
||||
mock_get_id.side_effect = [('', server_id), ('', net_id)]
|
||||
ret = self.controller.create(req)
|
||||
self.assertIsNotNone(ret)
|
||||
link = ret.resources.pop()
|
||||
self.assertIsInstance(link, os_network.OSNetworkInterface)
|
||||
self.assertIsInstance(link.source, compute.ComputeResource)
|
||||
self.assertIsInstance(link.target, network.NetworkResource)
|
||||
self.assertIsInstance(link.target, ip_reservation.IPReservation)
|
||||
self.assertEqual(net_id, link.target.id)
|
||||
self.assertEqual(server_id, link.source.id)
|
||||
mock_assign.assert_called_with(mock.ANY, net_id, server_id)
|
||||
|
||||
@mock.patch.object(helpers.OpenStackHelper, "create_port")
|
||||
@mock.patch("ooi.api.helpers.get_id_with_kind")
|
||||
def test_create_fixed(self, mock_get_id, mock_cre_port):
|
||||
server_id = uuid.uuid4().hex
|
||||
net_id = uuid.uuid4().hex
|
||||
mock_get_id.side_effect = [('', net_id), ('', server_id)]
|
||||
mock_get_id.side_effect = [('', server_id), ('', net_id)]
|
||||
ip = '8.0.0.0'
|
||||
parameters = {
|
||||
"occi.core.target": net_id,
|
||||
@ -327,7 +354,7 @@ class TestNetworkLinkController(base.TestController):
|
||||
mock_validator.validate.return_value = True
|
||||
mock_allocate.return_value = ip
|
||||
mock_associate.return_value = None
|
||||
mock_get_id.side_effect = [('', net_id), ('', server_id)]
|
||||
mock_get_id.side_effect = [('', server_id), ('', net_id)]
|
||||
|
||||
ret = self.controller.create(req, None)
|
||||
link = ret.resources.pop()
|
||||
@ -368,7 +395,7 @@ class TestNetworkLinkController(base.TestController):
|
||||
mock_validator.validate.return_value = True
|
||||
mock_allocate.return_value = ip
|
||||
mock_associate.return_value = None
|
||||
mock_get_id.side_effect = [('', net_id), ('', server_id)]
|
||||
mock_get_id.side_effect = [('', server_id), ('', net_id)]
|
||||
|
||||
ret = self.controller.create(req, None)
|
||||
link = ret.resources.pop()
|
||||
|
@ -21,6 +21,7 @@ from ooi.occi.core import link
|
||||
from ooi.occi.core import resource
|
||||
from ooi.occi.infrastructure import compute
|
||||
from ooi.occi.infrastructure import contextualization
|
||||
from ooi.occi.infrastructure import ip_reservation
|
||||
from ooi.occi.infrastructure import network
|
||||
from ooi.occi.infrastructure import network_link
|
||||
from ooi.occi.infrastructure import storage
|
||||
@ -65,6 +66,7 @@ class TestQueryController(base.TestController):
|
||||
storage_link.StorageLink.kind,
|
||||
network.NetworkResource.kind,
|
||||
network_link.NetworkInterface.kind,
|
||||
ip_reservation.IPReservation.kind,
|
||||
]
|
||||
|
||||
expected_mixins = [
|
||||
@ -133,6 +135,7 @@ class TestQueryController(base.TestController):
|
||||
storage_link.StorageLink.kind,
|
||||
network.NetworkResource.kind,
|
||||
network_link.NetworkInterface.kind,
|
||||
ip_reservation.IPReservation.kind,
|
||||
]
|
||||
|
||||
expected_mixins = [
|
||||
|
@ -19,6 +19,7 @@ from ooi.occi.core import mixin
|
||||
from ooi.occi.core import resource
|
||||
from ooi.occi.infrastructure import compute
|
||||
from ooi.occi.infrastructure import contextualization
|
||||
from ooi.occi.infrastructure import ip_reservation
|
||||
from ooi.occi.infrastructure import network
|
||||
from ooi.occi.infrastructure import network_link
|
||||
from ooi.occi.infrastructure import securitygroup
|
||||
@ -439,3 +440,45 @@ class TestOCCISecurityGroupLink(base.TestCase):
|
||||
id=uuid.uuid4().hex)
|
||||
l = securitygroup_link.SecurityGroupLink(c, s, state="foobar")
|
||||
self.assertEqual("foobar", l.state)
|
||||
|
||||
|
||||
class TestOCCIIPReservation(base.TestCase):
|
||||
def test_ipreservation_class(self):
|
||||
ir = ip_reservation.IPReservation
|
||||
self.assertIn(network.up, ir.actions)
|
||||
self.assertIn(network.down, ir.actions)
|
||||
self.assertIn("occi.ipreservation.address", ir.attributes)
|
||||
self.assertIn("occi.ipreservation.used", ir.attributes)
|
||||
self.assertIn("occi.ipreservation.state", ir.attributes)
|
||||
self.assertEqual(network.NetworkResource.kind, ir.kind.parent)
|
||||
self.assertEqual(ir.kind.location, "ipreservation/")
|
||||
|
||||
def test_ip_reservation(self):
|
||||
id = uuid.uuid4().hex
|
||||
ir = ip_reservation.IPReservation("foo",
|
||||
address="xx",
|
||||
id=id)
|
||||
self.assertEqual("foo", ir.title)
|
||||
self.assertEqual(id, ir.id)
|
||||
self.assertEqual("xx", ir.address)
|
||||
self.assertEqual(False, ir.used)
|
||||
self.assertIsNone(ir.state)
|
||||
|
||||
def test_setters(self):
|
||||
ir = ip_reservation.IPReservation("foo", address="xx")
|
||||
ir.address = "zzz"
|
||||
self.assertEqual(
|
||||
"zzz",
|
||||
ir.attributes["occi.ipreservation.address"].value)
|
||||
|
||||
def test_getters(self):
|
||||
id_ip = uuid.uuid4().hex
|
||||
ir = ip_reservation.IPReservation("foo",
|
||||
address="xx",
|
||||
state="active",
|
||||
used=True,
|
||||
id=id_ip)
|
||||
self.assertEqual("active", ir.state)
|
||||
self.assertEqual("xx", ir.address)
|
||||
self.assertEqual(True, ir.used)
|
||||
self.assertEqual(id_ip, ir.id)
|
||||
|
@ -118,7 +118,7 @@ class TestOSNetworkInterface(base.TestCase):
|
||||
id=uuid.uuid4().hex)
|
||||
i = os_network.OSNetworkInterface(c, n, "00:01:02:03:04:05",
|
||||
"127.0.0.1", pool="foo")
|
||||
self.assertEqual('_'.join([c.id, n.id, "127.0.0.1"]), i.id)
|
||||
self.assertEqual('_'.join([c.id, "127.0.0.1"]), i.id)
|
||||
self.assertEqual(i.address, "127.0.0.1")
|
||||
self.assertEqual(i.interface, "eth0")
|
||||
self.assertEqual(i.mac, "00:01:02:03:04:05")
|
||||
|
@ -20,6 +20,7 @@ import routes.middleware
|
||||
import webob.dec
|
||||
|
||||
import ooi.api.compute
|
||||
import ooi.api.ip_reservation
|
||||
import ooi.api.network
|
||||
import ooi.api.network_link
|
||||
from ooi.api import query
|
||||
@ -257,6 +258,11 @@ class OCCIMiddleware(object):
|
||||
self._setup_resource_routes("network",
|
||||
self.resources["network"])
|
||||
|
||||
self.resources["ipreservation"] = self._create_resource(
|
||||
ooi.api.ip_reservation.Controller)
|
||||
self._setup_resource_routes("ipreservation",
|
||||
self.resources["ipreservation"])
|
||||
|
||||
@webob.dec.wsgify(RequestClass=Request)
|
||||
def __call__(self, req):
|
||||
response = self.process_request(req)
|
||||
|
Loading…
Reference in New Issue
Block a user