Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / network.py @ fd981f77

History | View | Annotate | Download (20.8 kB)

1 d18e6439 Stavros Sachtouris
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 d18e6439 Stavros Sachtouris
#
3 d18e6439 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 d18e6439 Stavros Sachtouris
# without modification, are permitted provided that the following
5 d18e6439 Stavros Sachtouris
# conditions are met:
6 d18e6439 Stavros Sachtouris
#
7 d18e6439 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 d18e6439 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 d18e6439 Stavros Sachtouris
#      disclaimer.
10 d18e6439 Stavros Sachtouris
#
11 d18e6439 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 d18e6439 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 d18e6439 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 d18e6439 Stavros Sachtouris
#      provided with the distribution.
15 d18e6439 Stavros Sachtouris
#
16 d18e6439 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 d18e6439 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 d18e6439 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 d18e6439 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 d18e6439 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 d18e6439 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 d18e6439 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 d18e6439 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 d18e6439 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 d18e6439 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 d18e6439 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 d18e6439 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 d18e6439 Stavros Sachtouris
#
29 d18e6439 Stavros Sachtouris
# The views and conclusions contained in the software and
30 d18e6439 Stavros Sachtouris
# documentation are those of the authors and should not be
31 d18e6439 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 d18e6439 Stavros Sachtouris
# or implied, of GRNET S.A.
33 d18e6439 Stavros Sachtouris
34 d18e6439 Stavros Sachtouris
from io import StringIO
35 d18e6439 Stavros Sachtouris
from pydoc import pager
36 d18e6439 Stavros Sachtouris
37 d18e6439 Stavros Sachtouris
from kamaki.cli import command
38 d18e6439 Stavros Sachtouris
from kamaki.cli.command_tree import CommandTree
39 62c6652f Stavros Sachtouris
from kamaki.cli.errors import (
40 fd981f77 Stavros Sachtouris
    CLIBaseUrlError, CLIInvalidArgument, raiseCLIError)
41 cd0927f7 Stavros Sachtouris
from kamaki.clients.cyclades import CycladesNetworkClient
42 6f2b87c1 Stavros Sachtouris
from kamaki.cli.argument import (
43 6f2b87c1 Stavros Sachtouris
    FlagArgument, ValueArgument, RepeatableArgument, IntArgument)
44 d18e6439 Stavros Sachtouris
from kamaki.cli.commands import _command_init, errors, addLogSettings
45 d18e6439 Stavros Sachtouris
from kamaki.cli.commands import (
46 d18e6439 Stavros Sachtouris
    _optional_output_cmd, _optional_json, _name_filter, _id_filter)
47 7e57e590 Stavros Sachtouris
from kamaki.cli.utils import filter_dicts_by_dict
48 6f2b87c1 Stavros Sachtouris
from kamaki.cli.commands.cyclades import _service_wait
49 d18e6439 Stavros Sachtouris
50 d18e6439 Stavros Sachtouris
51 d18e6439 Stavros Sachtouris
network_cmds = CommandTree('network', 'Networking API network commands')
52 d18e6439 Stavros Sachtouris
port_cmds = CommandTree('port', 'Networking API network commands')
53 d18e6439 Stavros Sachtouris
subnet_cmds = CommandTree('subnet', 'Networking API network commands')
54 d1bced10 Stavros Sachtouris
ip_cmds = CommandTree('ip', 'Networking API floatingip commands')
55 d1bced10 Stavros Sachtouris
_commands = [network_cmds, port_cmds, subnet_cmds, ip_cmds]
56 d18e6439 Stavros Sachtouris
57 d18e6439 Stavros Sachtouris
58 d18e6439 Stavros Sachtouris
about_authentication = '\nUser Authentication:\
59 d18e6439 Stavros Sachtouris
    \n* to check authentication: /user authenticate\
60 d18e6439 Stavros Sachtouris
    \n* to set authentication token: /config set cloud.<cloud>.token <token>'
61 d18e6439 Stavros Sachtouris
62 d18e6439 Stavros Sachtouris
63 c6afee48 Stavros Sachtouris
class _port_wait(_service_wait):
64 c6afee48 Stavros Sachtouris
65 c6afee48 Stavros Sachtouris
    def _wait(self, port_id, current_status, timeout=60):
66 c6afee48 Stavros Sachtouris
        super(_port_wait, self)._wait(
67 c6afee48 Stavros Sachtouris
            'Port', port_id, self.client.wait_port, current_status,
68 c6afee48 Stavros Sachtouris
            timeout=timeout)
69 c6afee48 Stavros Sachtouris
70 c6afee48 Stavros Sachtouris
71 5c433331 Stavros Sachtouris
class _init_network(_command_init):
72 bc4662d8 Stavros Sachtouris
    @errors.generic.all
73 bc4662d8 Stavros Sachtouris
    @addLogSettings
74 bc4662d8 Stavros Sachtouris
    def _run(self, service='network'):
75 bc4662d8 Stavros Sachtouris
        if getattr(self, 'cloud', None):
76 bc4662d8 Stavros Sachtouris
            base_url = self._custom_url(service) or self._custom_url(
77 264a13f7 Stavros Sachtouris
                'network')
78 bc4662d8 Stavros Sachtouris
            if base_url:
79 bc4662d8 Stavros Sachtouris
                token = self._custom_token(service) or self._custom_token(
80 264a13f7 Stavros Sachtouris
                    'network') or self.config.get_cloud('token')
81 cd0927f7 Stavros Sachtouris
                self.client = CycladesNetworkClient(
82 bc4662d8 Stavros Sachtouris
                  base_url=base_url, token=token)
83 bc4662d8 Stavros Sachtouris
                return
84 bc4662d8 Stavros Sachtouris
        else:
85 bc4662d8 Stavros Sachtouris
            self.cloud = 'default'
86 bc4662d8 Stavros Sachtouris
        if getattr(self, 'auth_base', False):
87 cec2dfcd Stavros Sachtouris
            network_endpoints = self.auth_base.get_service_endpoints(
88 264a13f7 Stavros Sachtouris
                self._custom_type('network') or 'network',
89 264a13f7 Stavros Sachtouris
                self._custom_version('network') or '')
90 cec2dfcd Stavros Sachtouris
            base_url = network_endpoints['publicURL']
91 bc4662d8 Stavros Sachtouris
            token = self.auth_base.token
92 cd0927f7 Stavros Sachtouris
            self.client = CycladesNetworkClient(base_url=base_url, token=token)
93 bc4662d8 Stavros Sachtouris
        else:
94 bc4662d8 Stavros Sachtouris
            raise CLIBaseUrlError(service='network')
95 bc4662d8 Stavros Sachtouris
96 bc4662d8 Stavros Sachtouris
    def main(self):
97 bc4662d8 Stavros Sachtouris
        self._run()
98 d18e6439 Stavros Sachtouris
99 d18e6439 Stavros Sachtouris
100 d18e6439 Stavros Sachtouris
@command(network_cmds)
101 5c433331 Stavros Sachtouris
class network_list(_init_network, _optional_json, _name_filter, _id_filter):
102 d18e6439 Stavros Sachtouris
    """List networks
103 d18e6439 Stavros Sachtouris
    Use filtering arguments (e.g., --name-like) to manage long server lists
104 d18e6439 Stavros Sachtouris
    """
105 d18e6439 Stavros Sachtouris
106 d18e6439 Stavros Sachtouris
    arguments = dict(
107 d18e6439 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
108 cd40143a Stavros Sachtouris
        more=FlagArgument(
109 cd40143a Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
110 cd40143a Stavros Sachtouris
            '--more'),
111 7e57e590 Stavros Sachtouris
        user_id=ValueArgument(
112 7e57e590 Stavros Sachtouris
            'show only networks belonging to user with this id', '--user-id')
113 d18e6439 Stavros Sachtouris
    )
114 d18e6439 Stavros Sachtouris
115 7e57e590 Stavros Sachtouris
    def _filter_by_user_id(self, nets):
116 7e57e590 Stavros Sachtouris
        return filter_dicts_by_dict(nets, dict(user_id=self['user_id'])) if (
117 7e57e590 Stavros Sachtouris
            self['user_id']) else nets
118 7e57e590 Stavros Sachtouris
119 d18e6439 Stavros Sachtouris
    @errors.generic.all
120 d18e6439 Stavros Sachtouris
    @errors.cyclades.connection
121 d18e6439 Stavros Sachtouris
    def _run(self):
122 264a13f7 Stavros Sachtouris
        nets = self.client.list_networks()
123 7e57e590 Stavros Sachtouris
        nets = self._filter_by_user_id(nets)
124 77bf75fe Stavros Sachtouris
        nets = self._filter_by_name(nets)
125 77bf75fe Stavros Sachtouris
        nets = self._filter_by_id(nets)
126 264a13f7 Stavros Sachtouris
        if not self['detail']:
127 7e57e590 Stavros Sachtouris
            nets = [dict(
128 7e57e590 Stavros Sachtouris
                id=n['id'], name=n['name'], links=n['links']) for n in nets]
129 cd40143a Stavros Sachtouris
        kwargs = dict()
130 cd40143a Stavros Sachtouris
        if self['more']:
131 cd40143a Stavros Sachtouris
            kwargs['out'] = StringIO()
132 cd40143a Stavros Sachtouris
            kwargs['title'] = ()
133 cd40143a Stavros Sachtouris
        self._print(nets, **kwargs)
134 cd40143a Stavros Sachtouris
        if self['more']:
135 cd40143a Stavros Sachtouris
            pager(kwargs['out'].getvalue())
136 d18e6439 Stavros Sachtouris
137 d18e6439 Stavros Sachtouris
    def main(self):
138 d18e6439 Stavros Sachtouris
        super(self.__class__, self)._run()
139 d18e6439 Stavros Sachtouris
        self._run()
140 cd40143a Stavros Sachtouris
141 cd40143a Stavros Sachtouris
142 cd40143a Stavros Sachtouris
@command(network_cmds)
143 5c433331 Stavros Sachtouris
class network_info(_init_network, _optional_json):
144 cd40143a Stavros Sachtouris
    """Get details about a network"""
145 cd40143a Stavros Sachtouris
146 cd40143a Stavros Sachtouris
    @errors.generic.all
147 cd40143a Stavros Sachtouris
    @errors.cyclades.connection
148 cd40143a Stavros Sachtouris
    @errors.cyclades.network_id
149 cd40143a Stavros Sachtouris
    def _run(self, network_id):
150 cd40143a Stavros Sachtouris
        net = self.client.get_network_details(network_id)
151 cd40143a Stavros Sachtouris
        self._print(net, self.print_dict)
152 cd40143a Stavros Sachtouris
153 cd40143a Stavros Sachtouris
    def main(self, network_id):
154 cd40143a Stavros Sachtouris
        super(self.__class__, self)._run()
155 cd40143a Stavros Sachtouris
        self._run(network_id=network_id)
156 49413939 Stavros Sachtouris
157 49413939 Stavros Sachtouris
158 264a13f7 Stavros Sachtouris
class NetworkTypeArgument(ValueArgument):
159 264a13f7 Stavros Sachtouris
160 264a13f7 Stavros Sachtouris
    types = ('CUSTOM', 'MAC_FILTERED', 'IP_LESS_ROUTED', 'PHYSICAL_VLAN')
161 264a13f7 Stavros Sachtouris
162 264a13f7 Stavros Sachtouris
    @property
163 264a13f7 Stavros Sachtouris
    def value(self):
164 264a13f7 Stavros Sachtouris
        return getattr(self, '_value', None)
165 264a13f7 Stavros Sachtouris
166 264a13f7 Stavros Sachtouris
    @value.setter
167 264a13f7 Stavros Sachtouris
    def value(self, new_value):
168 264a13f7 Stavros Sachtouris
        if new_value and new_value.upper() in self.types:
169 264a13f7 Stavros Sachtouris
            self._value = new_value.upper()
170 264a13f7 Stavros Sachtouris
        elif new_value:
171 264a13f7 Stavros Sachtouris
            raise CLIInvalidArgument(
172 264a13f7 Stavros Sachtouris
                'Invalid network type %s' % new_value, details=[
173 264a13f7 Stavros Sachtouris
                    'Valid types: %s' % ', '.join(self.types), ])
174 264a13f7 Stavros Sachtouris
175 264a13f7 Stavros Sachtouris
176 49413939 Stavros Sachtouris
@command(network_cmds)
177 67dfe4a2 Stavros Sachtouris
class network_create(_init_network, _optional_json):
178 264a13f7 Stavros Sachtouris
    """Create a new network"""
179 49413939 Stavros Sachtouris
180 cd0927f7 Stavros Sachtouris
    arguments = dict(
181 cd0927f7 Stavros Sachtouris
        name=ValueArgument('Network name', '--name'),
182 cd0927f7 Stavros Sachtouris
        shared=FlagArgument(
183 264a13f7 Stavros Sachtouris
            'Make network shared (special privileges required)', '--shared'),
184 264a13f7 Stavros Sachtouris
        network_type=NetworkTypeArgument(
185 264a13f7 Stavros Sachtouris
            'Valid network types: %s' % (', '.join(NetworkTypeArgument.types)),
186 67dfe4a2 Stavros Sachtouris
            '--type')
187 49413939 Stavros Sachtouris
    )
188 264a13f7 Stavros Sachtouris
    required = ('network_type', )
189 49413939 Stavros Sachtouris
190 49413939 Stavros Sachtouris
    @errors.generic.all
191 49413939 Stavros Sachtouris
    @errors.cyclades.connection
192 cd0927f7 Stavros Sachtouris
    @errors.cyclades.network_type
193 cd0927f7 Stavros Sachtouris
    def _run(self, network_type):
194 49413939 Stavros Sachtouris
        net = self.client.create_network(
195 cd0927f7 Stavros Sachtouris
            network_type, name=self['name'], shared=self['shared'])
196 49413939 Stavros Sachtouris
        self._print(net, self.print_dict)
197 49413939 Stavros Sachtouris
198 264a13f7 Stavros Sachtouris
    def main(self):
199 49413939 Stavros Sachtouris
        super(self.__class__, self)._run()
200 264a13f7 Stavros Sachtouris
        self._run(network_type=self['network_type'])
201 aef3fa1f Stavros Sachtouris
202 aef3fa1f Stavros Sachtouris
203 aef3fa1f Stavros Sachtouris
@command(network_cmds)
204 5c433331 Stavros Sachtouris
class network_delete(_init_network, _optional_output_cmd):
205 aef3fa1f Stavros Sachtouris
    """Delete a network"""
206 aef3fa1f Stavros Sachtouris
207 aef3fa1f Stavros Sachtouris
    @errors.generic.all
208 aef3fa1f Stavros Sachtouris
    @errors.cyclades.connection
209 58602137 Stavros Sachtouris
    @errors.cyclades.network_id
210 aef3fa1f Stavros Sachtouris
    def _run(self, network_id):
211 aef3fa1f Stavros Sachtouris
        r = self.client.delete_network(network_id)
212 aef3fa1f Stavros Sachtouris
        self._optional_output(r)
213 aef3fa1f Stavros Sachtouris
214 aef3fa1f Stavros Sachtouris
    def main(self, network_id):
215 aef3fa1f Stavros Sachtouris
        super(self.__class__, self)._run()
216 aef3fa1f Stavros Sachtouris
        self._run(network_id=network_id)
217 58602137 Stavros Sachtouris
218 58602137 Stavros Sachtouris
219 58602137 Stavros Sachtouris
@command(network_cmds)
220 264a13f7 Stavros Sachtouris
class network_modify(_init_network, _optional_json):
221 264a13f7 Stavros Sachtouris
    """Modify network attributes"""
222 58602137 Stavros Sachtouris
223 264a13f7 Stavros Sachtouris
    arguments = dict(new_name=ValueArgument('Rename the network', '--name'))
224 264a13f7 Stavros Sachtouris
    required = ['new_name', ]
225 58602137 Stavros Sachtouris
226 58602137 Stavros Sachtouris
    @errors.generic.all
227 58602137 Stavros Sachtouris
    @errors.cyclades.connection
228 58602137 Stavros Sachtouris
    @errors.cyclades.network_id
229 58602137 Stavros Sachtouris
    def _run(self, network_id):
230 264a13f7 Stavros Sachtouris
        r = self.client.update_network(network_id, name=self['new_name'])
231 58602137 Stavros Sachtouris
        self._print(r, self.print_dict)
232 58602137 Stavros Sachtouris
233 58602137 Stavros Sachtouris
    def main(self, network_id):
234 58602137 Stavros Sachtouris
        super(self.__class__, self)._run()
235 58602137 Stavros Sachtouris
        self._run(network_id=network_id)
236 62c6652f Stavros Sachtouris
237 62c6652f Stavros Sachtouris
238 62c6652f Stavros Sachtouris
@command(subnet_cmds)
239 62c6652f Stavros Sachtouris
class subnet_list(_init_network, _optional_json, _name_filter, _id_filter):
240 62c6652f Stavros Sachtouris
    """List subnets
241 62c6652f Stavros Sachtouris
    Use filtering arguments (e.g., --name-like) to manage long server lists
242 62c6652f Stavros Sachtouris
    """
243 62c6652f Stavros Sachtouris
244 62c6652f Stavros Sachtouris
    arguments = dict(
245 62c6652f Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
246 62c6652f Stavros Sachtouris
        more=FlagArgument(
247 62c6652f Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
248 5c5eb675 Stavros Sachtouris
            '--more')
249 62c6652f Stavros Sachtouris
    )
250 62c6652f Stavros Sachtouris
251 62c6652f Stavros Sachtouris
    @errors.generic.all
252 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
253 62c6652f Stavros Sachtouris
    def _run(self):
254 62c6652f Stavros Sachtouris
        nets = self.client.list_subnets()
255 62c6652f Stavros Sachtouris
        nets = self._filter_by_name(nets)
256 62c6652f Stavros Sachtouris
        nets = self._filter_by_id(nets)
257 5c5eb675 Stavros Sachtouris
        if not self['detail']:
258 62c6652f Stavros Sachtouris
            nets = [dict(
259 62c6652f Stavros Sachtouris
                id=n['id'], name=n['name'], links=n['links']) for n in nets]
260 62c6652f Stavros Sachtouris
        kwargs = dict()
261 62c6652f Stavros Sachtouris
        if self['more']:
262 62c6652f Stavros Sachtouris
            kwargs['out'] = StringIO()
263 62c6652f Stavros Sachtouris
            kwargs['title'] = ()
264 62c6652f Stavros Sachtouris
        self._print(nets, **kwargs)
265 62c6652f Stavros Sachtouris
        if self['more']:
266 62c6652f Stavros Sachtouris
            pager(kwargs['out'].getvalue())
267 62c6652f Stavros Sachtouris
268 62c6652f Stavros Sachtouris
    def main(self):
269 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
270 62c6652f Stavros Sachtouris
        self._run()
271 62c6652f Stavros Sachtouris
272 62c6652f Stavros Sachtouris
273 62c6652f Stavros Sachtouris
@command(subnet_cmds)
274 62c6652f Stavros Sachtouris
class subnet_info(_init_network, _optional_json):
275 62c6652f Stavros Sachtouris
    """Get details about a subnet"""
276 62c6652f Stavros Sachtouris
277 62c6652f Stavros Sachtouris
    @errors.generic.all
278 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
279 62c6652f Stavros Sachtouris
    def _run(self, subnet_id):
280 62c6652f Stavros Sachtouris
        net = self.client.get_subnet_details(subnet_id)
281 62c6652f Stavros Sachtouris
        self._print(net, self.print_dict)
282 62c6652f Stavros Sachtouris
283 62c6652f Stavros Sachtouris
    def main(self, subnet_id):
284 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
285 62c6652f Stavros Sachtouris
        self._run(subnet_id=subnet_id)
286 62c6652f Stavros Sachtouris
287 62c6652f Stavros Sachtouris
288 62c6652f Stavros Sachtouris
class AllocationPoolArgument(RepeatableArgument):
289 62c6652f Stavros Sachtouris
290 62c6652f Stavros Sachtouris
    @property
291 62c6652f Stavros Sachtouris
    def value(self):
292 62c6652f Stavros Sachtouris
        return super(AllocationPoolArgument, self).value or []
293 62c6652f Stavros Sachtouris
294 62c6652f Stavros Sachtouris
    @value.setter
295 62c6652f Stavros Sachtouris
    def value(self, new_pools):
296 62c6652f Stavros Sachtouris
        new_list = []
297 62c6652f Stavros Sachtouris
        for pool in new_pools:
298 62c6652f Stavros Sachtouris
            start, comma, end = pool.partition(',')
299 62c6652f Stavros Sachtouris
            if not (start and comma and end):
300 62c6652f Stavros Sachtouris
                raise CLIInvalidArgument(
301 62c6652f Stavros Sachtouris
                    'Invalid allocation pool argument %s' % pool, details=[
302 62c6652f Stavros Sachtouris
                    'Allocation values must be of the form:',
303 62c6652f Stavros Sachtouris
                    '  <start address>,<end address>'])
304 62c6652f Stavros Sachtouris
            new_list.append(dict(start=start, end=end))
305 62c6652f Stavros Sachtouris
        self._value = new_list
306 62c6652f Stavros Sachtouris
307 62c6652f Stavros Sachtouris
308 62c6652f Stavros Sachtouris
@command(subnet_cmds)
309 62c6652f Stavros Sachtouris
class subnet_create(_init_network, _optional_json):
310 264a13f7 Stavros Sachtouris
    """Create a new subnet"""
311 62c6652f Stavros Sachtouris
312 62c6652f Stavros Sachtouris
    arguments = dict(
313 62c6652f Stavros Sachtouris
        name=ValueArgument('Subnet name', '--name'),
314 62c6652f Stavros Sachtouris
        allocation_pools=AllocationPoolArgument(
315 62c6652f Stavros Sachtouris
            'start_address,end_address of allocation pool (can be repeated)'
316 62c6652f Stavros Sachtouris
            ' e.g., --alloc-pool=123.45.67.1,123.45.67.8',
317 62c6652f Stavros Sachtouris
            '--alloc-pool'),
318 62c6652f Stavros Sachtouris
        gateway=ValueArgument('Gateway IP', '--gateway'),
319 62c6652f Stavros Sachtouris
        subnet_id=ValueArgument('The id for the subnet', '--id'),
320 62c6652f Stavros Sachtouris
        ipv6=FlagArgument('If set, IP version is set to 6, else 4', '--ipv6'),
321 264a13f7 Stavros Sachtouris
        enable_dhcp=FlagArgument('Enable dhcp (default: off)', '--with-dhcp'),
322 264a13f7 Stavros Sachtouris
        network_id=ValueArgument('Set the network ID', '--network-id'),
323 264a13f7 Stavros Sachtouris
        cidr=ValueArgument('Set the CIDR', '--cidr')
324 62c6652f Stavros Sachtouris
    )
325 264a13f7 Stavros Sachtouris
    required = ('network_id', 'cidr')
326 62c6652f Stavros Sachtouris
327 62c6652f Stavros Sachtouris
    @errors.generic.all
328 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
329 62c6652f Stavros Sachtouris
    @errors.cyclades.network_id
330 62c6652f Stavros Sachtouris
    def _run(self, network_id, cidr):
331 62c6652f Stavros Sachtouris
        net = self.client.create_subnet(
332 62c6652f Stavros Sachtouris
            network_id, cidr,
333 62c6652f Stavros Sachtouris
            self['name'], self['allocation_pools'], self['gateway'],
334 62c6652f Stavros Sachtouris
            self['subnet_id'], self['ipv6'], self['enable_dhcp'])
335 62c6652f Stavros Sachtouris
        self._print(net, self.print_dict)
336 62c6652f Stavros Sachtouris
337 264a13f7 Stavros Sachtouris
    def main(self):
338 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
339 264a13f7 Stavros Sachtouris
        self._run(network_id=self['network_id'], cidr=self['cidr'])
340 62c6652f Stavros Sachtouris
341 62c6652f Stavros Sachtouris
342 62c6652f Stavros Sachtouris
# @command(subnet_cmds)
343 62c6652f Stavros Sachtouris
# class subnet_delete(_init_network, _optional_output_cmd):
344 62c6652f Stavros Sachtouris
#     """Delete a subnet"""
345 62c6652f Stavros Sachtouris
346 62c6652f Stavros Sachtouris
#     @errors.generic.all
347 62c6652f Stavros Sachtouris
#     @errors.cyclades.connection
348 62c6652f Stavros Sachtouris
#     def _run(self, subnet_id):
349 62c6652f Stavros Sachtouris
#         r = self.client.delete_subnet(subnet_id)
350 62c6652f Stavros Sachtouris
#         self._optional_output(r)
351 62c6652f Stavros Sachtouris
352 62c6652f Stavros Sachtouris
#     def main(self, subnet_id):
353 62c6652f Stavros Sachtouris
#         super(self.__class__, self)._run()
354 62c6652f Stavros Sachtouris
#         self._run(subnet_id=subnet_id)
355 62c6652f Stavros Sachtouris
356 62c6652f Stavros Sachtouris
357 62c6652f Stavros Sachtouris
@command(subnet_cmds)
358 264a13f7 Stavros Sachtouris
class subnet_modify(_init_network, _optional_json):
359 264a13f7 Stavros Sachtouris
    """Modify the attributes of a subnet"""
360 62c6652f Stavros Sachtouris
361 264a13f7 Stavros Sachtouris
    arguments = dict(
362 264a13f7 Stavros Sachtouris
        new_name=ValueArgument('New name of the subnet', '--name')
363 264a13f7 Stavros Sachtouris
    )
364 264a13f7 Stavros Sachtouris
    required = ['new_name']
365 62c6652f Stavros Sachtouris
366 62c6652f Stavros Sachtouris
    @errors.generic.all
367 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
368 62c6652f Stavros Sachtouris
    def _run(self, subnet_id):
369 62c6652f Stavros Sachtouris
        r = self.client.get_subnet_details(subnet_id)
370 62c6652f Stavros Sachtouris
        r = self.client.update_subnet(
371 264a13f7 Stavros Sachtouris
            subnet_id, r['network_id'], name=self['new_name'])
372 62c6652f Stavros Sachtouris
        self._print(r, self.print_dict)
373 62c6652f Stavros Sachtouris
374 62c6652f Stavros Sachtouris
    def main(self, subnet_id):
375 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
376 62c6652f Stavros Sachtouris
        self._run(subnet_id=subnet_id)
377 447365fe Stavros Sachtouris
378 447365fe Stavros Sachtouris
379 447365fe Stavros Sachtouris
@command(port_cmds)
380 11cc86af Stavros Sachtouris
class port_list(_init_network, _optional_json):
381 11cc86af Stavros Sachtouris
    """List all ports"""
382 447365fe Stavros Sachtouris
383 447365fe Stavros Sachtouris
    @errors.generic.all
384 447365fe Stavros Sachtouris
    @errors.cyclades.connection
385 11cc86af Stavros Sachtouris
    def _run(self):
386 11cc86af Stavros Sachtouris
        net = self.client.list_ports()
387 1d565254 Stavros Sachtouris
        self._print(net)
388 447365fe Stavros Sachtouris
389 11cc86af Stavros Sachtouris
    def main(self):
390 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
391 11cc86af Stavros Sachtouris
        self._run()
392 447365fe Stavros Sachtouris
393 447365fe Stavros Sachtouris
394 447365fe Stavros Sachtouris
@command(port_cmds)
395 447365fe Stavros Sachtouris
class port_info(_init_network, _optional_json):
396 447365fe Stavros Sachtouris
    """Get details about a port"""
397 447365fe Stavros Sachtouris
398 447365fe Stavros Sachtouris
    @errors.generic.all
399 447365fe Stavros Sachtouris
    @errors.cyclades.connection
400 447365fe Stavros Sachtouris
    def _run(self, port_id):
401 447365fe Stavros Sachtouris
        net = self.client.get_port_details(port_id)
402 447365fe Stavros Sachtouris
        self._print(net, self.print_dict)
403 447365fe Stavros Sachtouris
404 447365fe Stavros Sachtouris
    def main(self, port_id):
405 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
406 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
407 447365fe Stavros Sachtouris
408 447365fe Stavros Sachtouris
409 447365fe Stavros Sachtouris
@command(port_cmds)
410 f261965c Stavros Sachtouris
class port_delete(_init_network, _optional_output_cmd, _port_wait):
411 264a13f7 Stavros Sachtouris
    """Delete a port (== disconnect server from network)"""
412 447365fe Stavros Sachtouris
413 f261965c Stavros Sachtouris
    arguments = dict(
414 f261965c Stavros Sachtouris
        wait=FlagArgument('Wait port to be established', ('-w', '--wait'))
415 f261965c Stavros Sachtouris
    )
416 f261965c Stavros Sachtouris
417 447365fe Stavros Sachtouris
    @errors.generic.all
418 447365fe Stavros Sachtouris
    @errors.cyclades.connection
419 447365fe Stavros Sachtouris
    def _run(self, port_id):
420 447365fe Stavros Sachtouris
        r = self.client.delete_port(port_id)
421 f261965c Stavros Sachtouris
        if self['wait']:
422 f261965c Stavros Sachtouris
            self._wait(r['id'], r['status'])
423 447365fe Stavros Sachtouris
        self._optional_output(r)
424 447365fe Stavros Sachtouris
425 447365fe Stavros Sachtouris
    def main(self, port_id):
426 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
427 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
428 447365fe Stavros Sachtouris
429 447365fe Stavros Sachtouris
430 447365fe Stavros Sachtouris
@command(port_cmds)
431 264a13f7 Stavros Sachtouris
class port_modify(_init_network, _optional_json):
432 264a13f7 Stavros Sachtouris
    """Modify the attributes of a port"""
433 447365fe Stavros Sachtouris
434 264a13f7 Stavros Sachtouris
    arguments = dict(new_name=ValueArgument('New name of the port', '--name'))
435 264a13f7 Stavros Sachtouris
    required = ['new_name', ]
436 447365fe Stavros Sachtouris
437 447365fe Stavros Sachtouris
    @errors.generic.all
438 447365fe Stavros Sachtouris
    @errors.cyclades.connection
439 447365fe Stavros Sachtouris
    def _run(self, port_id):
440 447365fe Stavros Sachtouris
        r = self.client.get_port_details(port_id)
441 447365fe Stavros Sachtouris
        r = self.client.update_port(
442 264a13f7 Stavros Sachtouris
            port_id, r['network_id'], name=self['new_name'])
443 447365fe Stavros Sachtouris
        self._print(r, self.print_dict)
444 447365fe Stavros Sachtouris
445 447365fe Stavros Sachtouris
    def main(self, port_id):
446 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
447 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
448 447365fe Stavros Sachtouris
449 447365fe Stavros Sachtouris
450 fd981f77 Stavros Sachtouris
class _port_create(_init_network):
451 fd981f77 Stavros Sachtouris
452 fd981f77 Stavros Sachtouris
    @errors.generic.all
453 fd981f77 Stavros Sachtouris
    @errors.cyclades.connection
454 fd981f77 Stavros Sachtouris
    @errors.cyclades.network_id
455 fd981f77 Stavros Sachtouris
    def _run(self, network_id, device_id):
456 fd981f77 Stavros Sachtouris
        fixed_ips = [dict(
457 fd981f77 Stavros Sachtouris
            subnet_id=self['subnet_id'], ip_address=self['ip_address'])] if (
458 fd981f77 Stavros Sachtouris
                self['subnet_id']) else None
459 fd981f77 Stavros Sachtouris
        r = self.client.create_port(
460 fd981f77 Stavros Sachtouris
            network_id, device_id,
461 fd981f77 Stavros Sachtouris
            name=self['name'],
462 fd981f77 Stavros Sachtouris
            security_groups=self['security_group_id'],
463 fd981f77 Stavros Sachtouris
            fixed_ips=fixed_ips)
464 fd981f77 Stavros Sachtouris
        if self['wait']:
465 fd981f77 Stavros Sachtouris
            self._wait(r['id'], r['status'])
466 fd981f77 Stavros Sachtouris
        self._print(r, self.print_dict)
467 fd981f77 Stavros Sachtouris
468 fd981f77 Stavros Sachtouris
469 ccdd1b82 Stavros Sachtouris
@command(port_cmds)
470 c6afee48 Stavros Sachtouris
class port_create(_init_network, _optional_json, _port_wait):
471 264a13f7 Stavros Sachtouris
    """Create a new port (== connect server to network)"""
472 ccdd1b82 Stavros Sachtouris
473 ccdd1b82 Stavros Sachtouris
    arguments = dict(
474 b7d79306 Stavros Sachtouris
        name=ValueArgument('A human readable name', '--name'),
475 ccdd1b82 Stavros Sachtouris
        security_group_id=RepeatableArgument(
476 ccdd1b82 Stavros Sachtouris
            'Add a security group id (can be repeated)',
477 b7d79306 Stavros Sachtouris
            ('-g', '--security-group')),
478 b7d79306 Stavros Sachtouris
        subnet_id=ValueArgument(
479 b7d79306 Stavros Sachtouris
            'Subnet id for fixed ips (used with --ip-address)',
480 b7d79306 Stavros Sachtouris
            '--subnet-id'),
481 b7d79306 Stavros Sachtouris
        ip_address=ValueArgument(
482 264a13f7 Stavros Sachtouris
            'IP address for subnet id (used with --subnet-id', '--ip-address'),
483 264a13f7 Stavros Sachtouris
        network_id=ValueArgument('Set the network ID', '--network-id'),
484 264a13f7 Stavros Sachtouris
        device_id=ValueArgument(
485 264a13f7 Stavros Sachtouris
            'The device is either a virtual server or a virtual router',
486 c6afee48 Stavros Sachtouris
            '--device-id'),
487 c6afee48 Stavros Sachtouris
        wait=FlagArgument('Wait port to be established', ('-w', '--wait')),
488 ccdd1b82 Stavros Sachtouris
    )
489 e3f54dc0 Stavros Sachtouris
    required = ('network_id', 'device_id')
490 ccdd1b82 Stavros Sachtouris
491 264a13f7 Stavros Sachtouris
    def main(self):
492 ccdd1b82 Stavros Sachtouris
        super(self.__class__, self)._run()
493 264a13f7 Stavros Sachtouris
        self._run(network_id=self['network_id'], device_id=self['device_id'])
494 264a13f7 Stavros Sachtouris
495 264a13f7 Stavros Sachtouris
496 c6afee48 Stavros Sachtouris
@command(port_cmds)
497 c6afee48 Stavros Sachtouris
class port_wait(_init_network, _port_wait):
498 67dfe4a2 Stavros Sachtouris
    """Wait for port to finish [ACTIVE, DOWN, BUILD, ERROR]"""
499 c6afee48 Stavros Sachtouris
500 c6afee48 Stavros Sachtouris
    arguments = dict(
501 c6afee48 Stavros Sachtouris
        timeout=IntArgument(
502 c6afee48 Stavros Sachtouris
            'Wait limit in seconds (default: 60)', '--timeout', default=60)
503 c6afee48 Stavros Sachtouris
    )
504 c6afee48 Stavros Sachtouris
505 c6afee48 Stavros Sachtouris
    @errors.generic.all
506 c6afee48 Stavros Sachtouris
    @errors.cyclades.connection
507 c6afee48 Stavros Sachtouris
    def _run(self, port_id, current_status):
508 c6afee48 Stavros Sachtouris
        port = self.client.get_port_details(port_id)
509 c6afee48 Stavros Sachtouris
        if port['status'].lower() == current_status.lower():
510 c6afee48 Stavros Sachtouris
            self._wait(port_id, current_status, timeout=self['timeout'])
511 c6afee48 Stavros Sachtouris
        else:
512 c6afee48 Stavros Sachtouris
            self.error(
513 c6afee48 Stavros Sachtouris
                'Port %s: Cannot wait for status %s, '
514 c6afee48 Stavros Sachtouris
                'status is already %s' % (
515 c6afee48 Stavros Sachtouris
                    port_id, current_status, port['status']))
516 c6afee48 Stavros Sachtouris
517 67dfe4a2 Stavros Sachtouris
    def main(self, port_id, current_status='BUILD'):
518 c6afee48 Stavros Sachtouris
        super(self.__class__, self)._run()
519 c6afee48 Stavros Sachtouris
        self._run(port_id=port_id, current_status=current_status)
520 c6afee48 Stavros Sachtouris
521 c6afee48 Stavros Sachtouris
522 d1bced10 Stavros Sachtouris
@command(ip_cmds)
523 d1bced10 Stavros Sachtouris
class ip_list(_init_network, _optional_json):
524 d1bced10 Stavros Sachtouris
    """List reserved floating IPs"""
525 d1bced10 Stavros Sachtouris
526 d1bced10 Stavros Sachtouris
    @errors.generic.all
527 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
528 d1bced10 Stavros Sachtouris
    def _run(self):
529 d1bced10 Stavros Sachtouris
        self._print(self.client.list_floatingips())
530 d1bced10 Stavros Sachtouris
531 d1bced10 Stavros Sachtouris
    def main(self):
532 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
533 d1bced10 Stavros Sachtouris
        self._run()
534 d1bced10 Stavros Sachtouris
535 d1bced10 Stavros Sachtouris
536 d1bced10 Stavros Sachtouris
@command(ip_cmds)
537 d1bced10 Stavros Sachtouris
class ip_info(_init_network, _optional_json):
538 d1bced10 Stavros Sachtouris
    """Get details on a floating IP"""
539 d1bced10 Stavros Sachtouris
540 d1bced10 Stavros Sachtouris
    @errors.generic.all
541 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
542 d1bced10 Stavros Sachtouris
    def _run(self, ip_id):
543 291cab21 Stavros Sachtouris
        self._print(
544 291cab21 Stavros Sachtouris
            self.client.get_floatingip_details(ip_id), self.print_dict)
545 d1bced10 Stavros Sachtouris
546 d1bced10 Stavros Sachtouris
    def main(self, ip_id):
547 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
548 d1bced10 Stavros Sachtouris
        self._run(ip_id=ip_id)
549 d1bced10 Stavros Sachtouris
550 d1bced10 Stavros Sachtouris
551 d1bced10 Stavros Sachtouris
@command(ip_cmds)
552 d1bced10 Stavros Sachtouris
class ip_create(_init_network, _optional_json):
553 d1bced10 Stavros Sachtouris
    """Reserve an IP on a network"""
554 264a13f7 Stavros Sachtouris
555 d1bced10 Stavros Sachtouris
    arguments = dict(
556 d1bced10 Stavros Sachtouris
        network_id=ValueArgument(
557 d1bced10 Stavros Sachtouris
            'The network to preserve the IP on', '--network-id'),
558 d1bced10 Stavros Sachtouris
        ip_address=ValueArgument('Allocate a specific IP address', '--address')
559 d1bced10 Stavros Sachtouris
    )
560 d1bced10 Stavros Sachtouris
    required = ('network_id', )
561 d1bced10 Stavros Sachtouris
562 d1bced10 Stavros Sachtouris
    @errors.generic.all
563 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
564 d1bced10 Stavros Sachtouris
    @errors.cyclades.network_id
565 d1bced10 Stavros Sachtouris
    def _run(self, network_id):
566 d1bced10 Stavros Sachtouris
        self._print(
567 d1bced10 Stavros Sachtouris
            self.client.create_floatingip(
568 d1bced10 Stavros Sachtouris
                network_id, floating_ip_address=self['ip_address']),
569 d1bced10 Stavros Sachtouris
            self.print_dict)
570 d1bced10 Stavros Sachtouris
571 d1bced10 Stavros Sachtouris
    def main(self):
572 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
573 d1bced10 Stavros Sachtouris
        self._run(network_id=self['network_id'])
574 d1bced10 Stavros Sachtouris
575 d1bced10 Stavros Sachtouris
576 d1bced10 Stavros Sachtouris
@command(ip_cmds)
577 d1bced10 Stavros Sachtouris
class ip_delete(_init_network, _optional_output_cmd):
578 d1bced10 Stavros Sachtouris
    """Unreserve an IP (also delete the port, if attached)"""
579 d1bced10 Stavros Sachtouris
580 d1bced10 Stavros Sachtouris
    def _run(self, ip_id):
581 291cab21 Stavros Sachtouris
        self._optional_output(self.client.delete_floatingip(ip_id))
582 d1bced10 Stavros Sachtouris
583 d1bced10 Stavros Sachtouris
    def main(self, ip_id):
584 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
585 d1bced10 Stavros Sachtouris
        self._run(ip_id=ip_id)
586 d1bced10 Stavros Sachtouris
587 d1bced10 Stavros Sachtouris
588 d1bced10 Stavros Sachtouris
#  Warn users for some importand changes
589 264a13f7 Stavros Sachtouris
590 264a13f7 Stavros Sachtouris
@command(network_cmds)
591 fd981f77 Stavros Sachtouris
class network_connect(_port_create):
592 fd981f77 Stavros Sachtouris
    """Connect a network with a device (server or router)"""
593 264a13f7 Stavros Sachtouris
594 fd981f77 Stavros Sachtouris
    arguments = dict(
595 fd981f77 Stavros Sachtouris
        name=ValueArgument('A human readable name', '--name'),
596 fd981f77 Stavros Sachtouris
        security_group_id=RepeatableArgument(
597 fd981f77 Stavros Sachtouris
            'Add a security group id (can be repeated)',
598 fd981f77 Stavros Sachtouris
            ('-g', '--security-group')),
599 fd981f77 Stavros Sachtouris
        subnet_id=ValueArgument(
600 fd981f77 Stavros Sachtouris
            'Subnet id for fixed ips (used with --ip-address)',
601 fd981f77 Stavros Sachtouris
            '--subnet-id'),
602 fd981f77 Stavros Sachtouris
        ip_address=ValueArgument(
603 fd981f77 Stavros Sachtouris
            'IP address for subnet id (used with --subnet-id', '--ip-address'),
604 fd981f77 Stavros Sachtouris
        wait=FlagArgument('Wait port to be established', ('-w', '--wait')),
605 fd981f77 Stavros Sachtouris
    )
606 fd981f77 Stavros Sachtouris
607 fd981f77 Stavros Sachtouris
    def main(self, network_id, device_id):
608 fd981f77 Stavros Sachtouris
        super(self.__class__, self)._run()
609 fd981f77 Stavros Sachtouris
        self._run(network_id=network_id, device_id=device_id)
610 264a13f7 Stavros Sachtouris
611 264a13f7 Stavros Sachtouris
612 264a13f7 Stavros Sachtouris
@command(network_cmds)
613 fd981f77 Stavros Sachtouris
class network_disconnect(_init_network, _optional_json):
614 fd981f77 Stavros Sachtouris
    """Disconnnect a network from a device"""
615 264a13f7 Stavros Sachtouris
616 fd981f77 Stavros Sachtouris
    def _cyclades_client(self):
617 fd981f77 Stavros Sachtouris
        auth = getattr(self, 'auth_base')
618 fd981f77 Stavros Sachtouris
        endpoints = auth.get_service_endpoints('compute')
619 fd981f77 Stavros Sachtouris
        URL = endpoints['publicURL']
620 fd981f77 Stavros Sachtouris
        from kamaki.clients.cyclades import CycladesClient
621 fd981f77 Stavros Sachtouris
        return CycladesClient(URL, self.client.token)
622 fd981f77 Stavros Sachtouris
623 fd981f77 Stavros Sachtouris
    @errors.generic.all
624 fd981f77 Stavros Sachtouris
    @errors.cyclades.connection
625 fd981f77 Stavros Sachtouris
    @errors.cyclades.network_id
626 fd981f77 Stavros Sachtouris
    @errors.cyclades.server_id
627 fd981f77 Stavros Sachtouris
    def _run(self, network_id, device_id):
628 fd981f77 Stavros Sachtouris
        vm = self._cyclades_client().get_server_details(device_id)
629 fd981f77 Stavros Sachtouris
        nets = [net for net in vm['attachments'] if net['network_id'] not in (
630 fd981f77 Stavros Sachtouris
            'network_id', )]
631 fd981f77 Stavros Sachtouris
        if not nets:
632 fd981f77 Stavros Sachtouris
            raiseCLIError('Network %s is not connected to device %s' % (
633 fd981f77 Stavros Sachtouris
                network_id, device_id))
634 fd981f77 Stavros Sachtouris
        for net in nets:
635 fd981f77 Stavros Sachtouris
            self.client.port_delete(net['id'])
636 fd981f77 Stavros Sachtouris
            self.error('Deleted connection:')
637 fd981f77 Stavros Sachtouris
            self.print_dict(net)
638 fd981f77 Stavros Sachtouris
639 fd981f77 Stavros Sachtouris
    def main(self, network_id, device_id):
640 fd981f77 Stavros Sachtouris
        super(self.__class__, self)._run()
641 fd981f77 Stavros Sachtouris
        self._run(network_id=network_id, device_id=device_id)