Included OCCI IPReservation support
This is a complete change in which we have add the OCCI IPRESERVATION class with the features provided by CESNET. We include: the controller, the occi class, middleware changes, and tests to control it. In addition, we have modified networklink to support this feature, now networklink is identified by using only compute id and ipreservation ip. Last, we add the documentation relate to its usage. Change-Id: I52f80a9a7a39e00d1d7487001863586a551edf5f
This commit is contained in:
parent
ddbe190568
commit
7566dce6af
@ -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:
|
||||
|
@ -534,6 +534,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
|
||||
@ -708,7 +721,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
|
||||
@ -717,6 +730,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):
|
||||
@ -732,48 +746,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):
|
||||
@ -781,45 +802,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
|
||||
|
||||
@ -886,8 +910,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…
x
Reference in New Issue
Block a user