Add vpn ip/port setting support for CloudPipe
This extends the cloudpipe REST API to allow the setting of the IP and port for the VPN for each network in the project /v2/{tenant_id/os-cloudpipe/configure-project # POST ip/port This forms part of the work to provide APIs for functionality currently implemented by nova-manage that needs direct db access so nova-manage can eventually be removed DocImpact Implements: blueprint apis-for-nova-manage Change-Id: I416c0bfbe1c88470638f1c2004d1dcaeb51a6c41
This commit is contained in:
parent
37df2052d7
commit
0bf27df376
@ -96,6 +96,14 @@
|
||||
"namespace": "http://docs.openstack.org/compute/ext/cloudpipe/api/v1.1",
|
||||
"updated": "2011-12-16T00:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"alias": "os-cloudpipe-update",
|
||||
"description": "Adds the ability to set the vpn ip/port for cloudpipe instances.",
|
||||
"links": [],
|
||||
"name": "CloudpipeUpdate",
|
||||
"namespace": "http://docs.openstack.org/compute/ext/cloudpipe-update/api/v2",
|
||||
"updated": "2012-11-14T00:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"alias": "os-config-drive",
|
||||
"description": "Config Drive Extension",
|
||||
|
@ -48,6 +48,9 @@
|
||||
a SSH Bastion host is forthcoming.
|
||||
</description>
|
||||
</extension>
|
||||
<extension alias="os-cloudpipe-update" updated="2012-11-14T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/cloudpipe-update/api/v2" name="CloudpipeUpdate">
|
||||
<description>Adds the ability to set the vpn ip/port for cloudpipe instances.</description>
|
||||
</extension>
|
||||
<extension alias="os-config-drive" updated="2012-07-16T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/config_drive/api/v1.1" name="ConfigDrive">
|
||||
<description>Config Drive Extension</description>
|
||||
</extension>
|
||||
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"configure_project": {
|
||||
"vpn_ip": "192.168.1.1",
|
||||
"vpn_port": "2000"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<configure_project>
|
||||
<vpn_ip>192.168.1.1</vpn_ip>
|
||||
<vpn_port>2000</vpn_port>
|
||||
</configure_project>
|
@ -30,6 +30,7 @@
|
||||
"compute_extension:aggregates": "rule:admin_api",
|
||||
"compute_extension:certificates": "",
|
||||
"compute_extension:cloudpipe": "rule:admin_api",
|
||||
"compute_extension:cloudpipe_update": "rule:admin_api",
|
||||
"compute_extension:console_output": "",
|
||||
"compute_extension:consoles": "",
|
||||
"compute_extension:createserverext": "",
|
||||
|
78
nova/api/openstack/compute/contrib/cloudpipe_update.py
Normal file
78
nova/api/openstack/compute/contrib/cloudpipe_update.py
Normal file
@ -0,0 +1,78 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012 IBM
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 webob.exc
|
||||
|
||||
from nova.api.openstack.compute.contrib import cloudpipe
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
authorize = extensions.extension_authorizer('compute', 'cloudpipe_update')
|
||||
|
||||
|
||||
class CloudpipeUpdateController(wsgi.Controller):
|
||||
"""Handle updating the vpn ip/port for cloudpipe instances."""
|
||||
|
||||
def __init__(self):
|
||||
super(CloudpipeUpdateController, self).__init__()
|
||||
|
||||
@wsgi.action("update")
|
||||
def update(self, req, id, body):
|
||||
"""Configure cloudpipe parameters for the project"""
|
||||
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
|
||||
if id != "configure-project":
|
||||
msg = _("Unknown action %s") % id
|
||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
project_id = context.project_id
|
||||
|
||||
try:
|
||||
params = body['configure_project']
|
||||
vpn_ip = params['vpn_ip']
|
||||
vpn_port = params['vpn_port']
|
||||
except (TypeError, KeyError):
|
||||
raise webob.exc.HTTPUnprocessableEntity()
|
||||
|
||||
networks = db.project_get_networks(context, project_id)
|
||||
for network in networks:
|
||||
db.network_update(context, network['id'],
|
||||
{'vpn_public_address': vpn_ip,
|
||||
'vpn_public_port': int(vpn_port)})
|
||||
return webob.exc.HTTPAccepted()
|
||||
|
||||
|
||||
class Cloudpipe_update(extensions.ExtensionDescriptor):
|
||||
"""Adds the ability to set the vpn ip/port for cloudpipe instances."""
|
||||
|
||||
name = "CloudpipeUpdate"
|
||||
alias = "os-cloudpipe-update"
|
||||
namespace = "http://docs.openstack.org/compute/ext/cloudpipe-update/api/v2"
|
||||
updated = "2012-11-14T00:00:00+00:00"
|
||||
|
||||
def get_controller_extensions(self):
|
||||
controller = CloudpipeUpdateController()
|
||||
extension = extensions.ControllerExtension(self, 'os-cloudpipe',
|
||||
controller)
|
||||
return [extension]
|
@ -0,0 +1,73 @@
|
||||
# Copyright 2012 IBM
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 webob
|
||||
|
||||
from nova.api.openstack.compute.contrib import cloudpipe_update
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import db
|
||||
from nova import test
|
||||
from nova.tests.api.openstack import fakes
|
||||
from nova.tests import fake_network
|
||||
|
||||
|
||||
fake_networks = [fake_network.fake_network(1),
|
||||
fake_network.fake_network(2)]
|
||||
|
||||
|
||||
def fake_project_get_networks(context, project_id, associate=True):
|
||||
return fake_networks
|
||||
|
||||
|
||||
def fake_network_update(context, network_id, values):
|
||||
for network in fake_networks:
|
||||
if network['id'] == network_id:
|
||||
for key in values:
|
||||
network[key] = values[key]
|
||||
|
||||
|
||||
class CloudpipeUpdateTest(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(CloudpipeUpdateTest, self).setUp()
|
||||
self.controller = cloudpipe_update.CloudpipeUpdateController()
|
||||
self.stubs.Set(db, "project_get_networks", fake_project_get_networks)
|
||||
self.stubs.Set(db, "network_update", fake_network_update)
|
||||
|
||||
def test_cloudpipe_configure_project(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-cloudpipe/configure-project')
|
||||
body = {"configure_project": {"vpn_ip": "1.2.3.4", "vpn_port": 222}}
|
||||
result = self.controller.update(req, 'configure-project',
|
||||
body=body)
|
||||
self.assertEqual('202 Accepted', result.status)
|
||||
self.assertEqual(fake_networks[0]['vpn_public_address'], "1.2.3.4")
|
||||
self.assertEqual(fake_networks[0]['vpn_public_port'], 222)
|
||||
|
||||
def test_cloudpipe_configure_project_bad_url(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-cloudpipe/configure-projectx')
|
||||
body = {"vpn_ip": "1.2.3.4", "vpn_port": 222}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.update, req,
|
||||
'configure-projectx', body)
|
||||
|
||||
def test_cloudpipe_configure_project_bad_data(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-cloudpipe/configure-project')
|
||||
body = {"vpn_ipxx": "1.2.3.4", "vpn_port": 222}
|
||||
self.assertRaises(webob.exc.HTTPUnprocessableEntity,
|
||||
self.controller.update, req,
|
||||
'configure-project', body)
|
@ -160,6 +160,7 @@ class ExtensionControllerTest(ExtensionTestCase):
|
||||
"AvailabilityZone",
|
||||
"Certificates",
|
||||
"Cloudpipe",
|
||||
"CloudpipeUpdate",
|
||||
"ConsoleOutput",
|
||||
"Consoles",
|
||||
"Createserverext",
|
||||
|
@ -96,6 +96,14 @@
|
||||
"namespace": "http://docs.openstack.org/compute/ext/cloudpipe/api/v1.1",
|
||||
"updated": "%(timestamp)s"
|
||||
},
|
||||
{
|
||||
"alias": "os-cloudpipe-update",
|
||||
"description": "%(text)s",
|
||||
"links": [],
|
||||
"name": "CloudpipeUpdate",
|
||||
"namespace": "http://docs.openstack.org/compute/ext/cloudpipe-update/api/v2",
|
||||
"updated": "%(timestamp)s"
|
||||
},
|
||||
{
|
||||
"alias": "os-config-drive",
|
||||
"description": "%(text)s",
|
||||
|
@ -36,6 +36,9 @@
|
||||
<extension alias="os-cloudpipe" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/cloudpipe/api/v1.1" name="Cloudpipe">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
<extension alias="os-cloudpipe-update" updated="%(timestamp)s" name="CloudpipeUpdate" namespace="http://docs.openstack.org/compute/ext/cloudpipe-update/api/v2">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
<extension alias="os-config-drive" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/config_drive/api/v1.1" name="ConfigDrive">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"configure_project": {
|
||||
"vpn_ip": "%(vpn_ip)s",
|
||||
"vpn_port": "%(vpn_port)s"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<configure_project>
|
||||
<vpn_ip>%(vpn_ip)s</vpn_ip>
|
||||
<vpn_port>%(vpn_port)s</vpn_port>
|
||||
</configure_project>
|
@ -1256,6 +1256,34 @@ class CloudPipeSampleXmlTest(CloudPipeSampleJsonTest):
|
||||
ctype = "xml"
|
||||
|
||||
|
||||
class CloudPipeUpdateJsonTest(ApiSampleTestBase):
|
||||
extension_name = ("nova.api.openstack.compute.contrib"
|
||||
".cloudpipe_update.Cloudpipe_update")
|
||||
|
||||
def _get_flags(self):
|
||||
f = super(CloudPipeUpdateJsonTest, self)._get_flags()
|
||||
f['osapi_compute_extension'] = CONF.osapi_compute_extension[:]
|
||||
# Cloudpipe_update also needs cloudpipe to be loaded
|
||||
f['osapi_compute_extension'].append(
|
||||
'nova.api.openstack.compute.contrib.cloudpipe.Cloudpipe')
|
||||
return f
|
||||
|
||||
def setUp(self):
|
||||
super(CloudPipeUpdateJsonTest, self).setUp()
|
||||
|
||||
def test_cloud_pipe_update(self):
|
||||
subs = {'vpn_ip': '192.168.1.1',
|
||||
'vpn_port': 2000}
|
||||
response = self._do_put('os-cloudpipe/configure-project',
|
||||
'cloud-pipe-update-req',
|
||||
subs)
|
||||
self.assertEqual(response.status, 202)
|
||||
|
||||
|
||||
class CloudPipeUpdateXmlTest(CloudPipeUpdateJsonTest):
|
||||
ctype = "xml"
|
||||
|
||||
|
||||
class AggregatesSampleJsonTest(ServersSampleBase):
|
||||
extension_name = "nova.api.openstack.compute.contrib" + \
|
||||
".aggregates.Aggregates"
|
||||
|
@ -87,6 +87,7 @@
|
||||
"compute_extension:aggregates": "",
|
||||
"compute_extension:certificates": "",
|
||||
"compute_extension:cloudpipe": "",
|
||||
"compute_extension:cloudpipe_update": "",
|
||||
"compute_extension:config_drive": "",
|
||||
"compute_extension:console_output": "",
|
||||
"compute_extension:consoles": "",
|
||||
|
Loading…
x
Reference in New Issue
Block a user