diff --git a/AUTHORS b/AUTHORS index 54b69d146..c51f4d5fe 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,5 @@ Aaron Lee <aaron.lee@rackspace.com> +Alvaro Lopez Garcia <aloga@ifca.unican.es> Andrey Brindeyev <abrindeyev@griddynamics.com> Andy Smith <github@anarkystic.com> Anthony Young <sleepsonthefloor@gmail.com> diff --git a/novaclient/v1_1/client.py b/novaclient/v1_1/client.py index 32ae7f44d..5cd856ff8 100644 --- a/novaclient/v1_1/client.py +++ b/novaclient/v1_1/client.py @@ -1,5 +1,6 @@ from novaclient import client from novaclient.v1_1 import certs +from novaclient.v1_1 import cloudpipe from novaclient.v1_1 import aggregates from novaclient.v1_1 import flavors from novaclient.v1_1 import floating_ip_dns @@ -55,6 +56,7 @@ class Client(object): # extensions self.dns_domains = floating_ip_dns.FloatingIPDNSDomainManager(self) self.dns_entries = floating_ip_dns.FloatingIPDNSEntryManager(self) + self.cloudpipe = cloudpipe.CloudpipeManager(self) self.certs = certs.CertificateManager(self) self.floating_ips = floating_ips.FloatingIPManager(self) self.floating_ip_pools = floating_ip_pools.FloatingIPPoolManager(self) diff --git a/novaclient/v1_1/cloudpipe.py b/novaclient/v1_1/cloudpipe.py new file mode 100644 index 000000000..4dea3f2a6 --- /dev/null +++ b/novaclient/v1_1/cloudpipe.py @@ -0,0 +1,48 @@ +# Copyright 2012 OpenStack LLC. +# 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. + +"""Cloudpipe interface.""" + +from novaclient import base + + +class Cloudpipe(base.Resource): + """A cloudpipe instance is a VPN attached to a proejct's VLAN.""" + + def __repr__(self): + return "<Cloudpipe: %s>" % self.project_id + + def delete(self): + self.manager.delete(self) + + +class CloudpipeManager(base.ManagerWithFind): + resource_class = Cloudpipe + + def create(self, project): + """ + Launch a cloudpipe instance. + + :param project: name of the project for the cloudpipe + """ + body = {'cloudpipe': {'project_id': project}} + return self._create('/os-cloudpipe', body, 'instance_id', + return_raw=True) + + def list(self): + """ + Get a list of cloudpipe instances. + """ + return self._list('/os-cloudpipe', 'cloudpipes') diff --git a/novaclient/v1_1/shell.py b/novaclient/v1_1/shell.py index c0b52dcf1..c56c008e2 100644 --- a/novaclient/v1_1/shell.py +++ b/novaclient/v1_1/shell.py @@ -230,6 +230,19 @@ def do_boot(cs, args): _poll_for_status(cs.servers.get, info['id'], 'building', ['active']) +def do_cloudpipe_list(cs, args): + """Print a list of all cloudpipe instances.""" + cloudpipes = cs.cloudpipe.list() + columns = ['Project Id', "Public IP", "Public Port", "Internal IP"] + utils.print_list(cloudpipes, columns) + + +@utils.arg('project', metavar='<project>', help='Name of the project.') +def do_cloudpipe_create(cs, args): + """Create a cloudpipe instance for the given project""" + cs.cloudpipe.create(args.project) + + def _poll_for_status(poll_fn, obj_id, action, final_ok_states, poll_period=5, show_progress=True): """Block while an action is being performed, periodically printing diff --git a/tests/v1_1/fakes.py b/tests/v1_1/fakes.py index a50c62ac7..52ea02efd 100644 --- a/tests/v1_1/fakes.py +++ b/tests/v1_1/fakes.py @@ -339,6 +339,18 @@ class FakeHTTPClient(base_client.HTTPClient): raise AssertionError("Unexpected server action: %s" % action) return (resp, _body) + # + # Cloudpipe + # + + def get_os_cloudpipe(self, **kw): + return (200, {'cloudpipes': [ + {'project_id':1} + ]}) + + def post_os_cloudpipe(self, **ks): + return (202, {'instance_id': '9d5824aa-20e6-4b9f-b967-76a699fc51fd'}) + # # Flavors # diff --git a/tests/v1_1/test_cloudpipe.py b/tests/v1_1/test_cloudpipe.py new file mode 100644 index 000000000..82a750f0a --- /dev/null +++ b/tests/v1_1/test_cloudpipe.py @@ -0,0 +1,22 @@ +from novaclient import exceptions +from novaclient.v1_1 import cloudpipe +from tests import utils +from tests.v1_1 import fakes + + +cs = fakes.FakeClient() + + +class CloudpipeTest(utils.TestCase): + + def test_list_cloudpipes(self): + cp = cs.cloudpipe.list() + cs.assert_called('GET', '/os-cloudpipe') + [self.assertTrue(isinstance(c, cloudpipe.Cloudpipe)) for c in cp] + + def test_create(self): + project = "test" + cp = cs.cloudpipe.create(project) + body = {'cloudpipe': {'project_id': project}} + cs.assert_called('POST', '/os-cloudpipe', body) + self.assertTrue(isinstance(cp, str))