Merge "Included OCCI IPReservation support"

This commit is contained in:
Jenkins 2017-04-03 07:07:34 +00:00 committed by Gerrit Code Review
commit 2e6c6b22c0
21 changed files with 1014 additions and 152 deletions

View File

@ -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
************

View File

@ -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:

View File

@ -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
View 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()

View File

@ -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 []

View File

@ -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)

View 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

View File

@ -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))

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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")

View File

@ -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")

View File

@ -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'])

View 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)

View File

@ -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()

View File

@ -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 = [

View File

@ -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)

View File

@ -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")

View File

@ -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)