Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / network.py @ 6893e31c

History | View | Annotate | Download (21.3 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 17cfc2f0 Stavros Sachtouris
class _port_create(_init_network, _optional_json, _port_wait):
451 fd981f77 Stavros Sachtouris
452 17cfc2f0 Stavros Sachtouris
    def connect(self, network_id, device_id):
453 fd981f77 Stavros Sachtouris
        fixed_ips = [dict(
454 fd981f77 Stavros Sachtouris
            subnet_id=self['subnet_id'], ip_address=self['ip_address'])] if (
455 fd981f77 Stavros Sachtouris
                self['subnet_id']) else None
456 fd981f77 Stavros Sachtouris
        r = self.client.create_port(
457 fd981f77 Stavros Sachtouris
            network_id, device_id,
458 fd981f77 Stavros Sachtouris
            name=self['name'],
459 fd981f77 Stavros Sachtouris
            security_groups=self['security_group_id'],
460 fd981f77 Stavros Sachtouris
            fixed_ips=fixed_ips)
461 fd981f77 Stavros Sachtouris
        if self['wait']:
462 fd981f77 Stavros Sachtouris
            self._wait(r['id'], r['status'])
463 fd981f77 Stavros Sachtouris
        self._print(r, self.print_dict)
464 fd981f77 Stavros Sachtouris
465 fd981f77 Stavros Sachtouris
466 ccdd1b82 Stavros Sachtouris
@command(port_cmds)
467 17cfc2f0 Stavros Sachtouris
class port_create(_init_network):
468 264a13f7 Stavros Sachtouris
    """Create a new port (== connect server to network)"""
469 ccdd1b82 Stavros Sachtouris
470 ccdd1b82 Stavros Sachtouris
    arguments = dict(
471 b7d79306 Stavros Sachtouris
        name=ValueArgument('A human readable name', '--name'),
472 ccdd1b82 Stavros Sachtouris
        security_group_id=RepeatableArgument(
473 ccdd1b82 Stavros Sachtouris
            'Add a security group id (can be repeated)',
474 b7d79306 Stavros Sachtouris
            ('-g', '--security-group')),
475 b7d79306 Stavros Sachtouris
        subnet_id=ValueArgument(
476 b7d79306 Stavros Sachtouris
            'Subnet id for fixed ips (used with --ip-address)',
477 b7d79306 Stavros Sachtouris
            '--subnet-id'),
478 b7d79306 Stavros Sachtouris
        ip_address=ValueArgument(
479 264a13f7 Stavros Sachtouris
            'IP address for subnet id (used with --subnet-id', '--ip-address'),
480 264a13f7 Stavros Sachtouris
        network_id=ValueArgument('Set the network ID', '--network-id'),
481 264a13f7 Stavros Sachtouris
        device_id=ValueArgument(
482 264a13f7 Stavros Sachtouris
            'The device is either a virtual server or a virtual router',
483 c6afee48 Stavros Sachtouris
            '--device-id'),
484 c6afee48 Stavros Sachtouris
        wait=FlagArgument('Wait port to be established', ('-w', '--wait')),
485 ccdd1b82 Stavros Sachtouris
    )
486 e3f54dc0 Stavros Sachtouris
    required = ('network_id', 'device_id')
487 ccdd1b82 Stavros Sachtouris
488 17cfc2f0 Stavros Sachtouris
    @errors.generic.all
489 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.connection
490 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.network_id
491 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.server_id
492 17cfc2f0 Stavros Sachtouris
    def _run(self, network_id, server_id):
493 17cfc2f0 Stavros Sachtouris
        self.connect(network_id, server_id)
494 17cfc2f0 Stavros Sachtouris
495 264a13f7 Stavros Sachtouris
    def main(self):
496 ccdd1b82 Stavros Sachtouris
        super(self.__class__, self)._run()
497 17cfc2f0 Stavros Sachtouris
        self._run(network_id=self['network_id'], server_id=self['device_id'])
498 264a13f7 Stavros Sachtouris
499 264a13f7 Stavros Sachtouris
500 c6afee48 Stavros Sachtouris
@command(port_cmds)
501 c6afee48 Stavros Sachtouris
class port_wait(_init_network, _port_wait):
502 67dfe4a2 Stavros Sachtouris
    """Wait for port to finish [ACTIVE, DOWN, BUILD, ERROR]"""
503 c6afee48 Stavros Sachtouris
504 c6afee48 Stavros Sachtouris
    arguments = dict(
505 c6afee48 Stavros Sachtouris
        timeout=IntArgument(
506 c6afee48 Stavros Sachtouris
            'Wait limit in seconds (default: 60)', '--timeout', default=60)
507 c6afee48 Stavros Sachtouris
    )
508 c6afee48 Stavros Sachtouris
509 c6afee48 Stavros Sachtouris
    @errors.generic.all
510 c6afee48 Stavros Sachtouris
    @errors.cyclades.connection
511 c6afee48 Stavros Sachtouris
    def _run(self, port_id, current_status):
512 c6afee48 Stavros Sachtouris
        port = self.client.get_port_details(port_id)
513 c6afee48 Stavros Sachtouris
        if port['status'].lower() == current_status.lower():
514 c6afee48 Stavros Sachtouris
            self._wait(port_id, current_status, timeout=self['timeout'])
515 c6afee48 Stavros Sachtouris
        else:
516 c6afee48 Stavros Sachtouris
            self.error(
517 c6afee48 Stavros Sachtouris
                'Port %s: Cannot wait for status %s, '
518 c6afee48 Stavros Sachtouris
                'status is already %s' % (
519 c6afee48 Stavros Sachtouris
                    port_id, current_status, port['status']))
520 c6afee48 Stavros Sachtouris
521 67dfe4a2 Stavros Sachtouris
    def main(self, port_id, current_status='BUILD'):
522 c6afee48 Stavros Sachtouris
        super(self.__class__, self)._run()
523 c6afee48 Stavros Sachtouris
        self._run(port_id=port_id, current_status=current_status)
524 c6afee48 Stavros Sachtouris
525 c6afee48 Stavros Sachtouris
526 d1bced10 Stavros Sachtouris
@command(ip_cmds)
527 d1bced10 Stavros Sachtouris
class ip_list(_init_network, _optional_json):
528 d1bced10 Stavros Sachtouris
    """List reserved floating IPs"""
529 d1bced10 Stavros Sachtouris
530 d1bced10 Stavros Sachtouris
    @errors.generic.all
531 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
532 d1bced10 Stavros Sachtouris
    def _run(self):
533 d1bced10 Stavros Sachtouris
        self._print(self.client.list_floatingips())
534 d1bced10 Stavros Sachtouris
535 d1bced10 Stavros Sachtouris
    def main(self):
536 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
537 d1bced10 Stavros Sachtouris
        self._run()
538 d1bced10 Stavros Sachtouris
539 d1bced10 Stavros Sachtouris
540 d1bced10 Stavros Sachtouris
@command(ip_cmds)
541 d1bced10 Stavros Sachtouris
class ip_info(_init_network, _optional_json):
542 d1bced10 Stavros Sachtouris
    """Get details on a floating IP"""
543 d1bced10 Stavros Sachtouris
544 d1bced10 Stavros Sachtouris
    @errors.generic.all
545 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
546 d1bced10 Stavros Sachtouris
    def _run(self, ip_id):
547 291cab21 Stavros Sachtouris
        self._print(
548 291cab21 Stavros Sachtouris
            self.client.get_floatingip_details(ip_id), self.print_dict)
549 d1bced10 Stavros Sachtouris
550 d1bced10 Stavros Sachtouris
    def main(self, ip_id):
551 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
552 d1bced10 Stavros Sachtouris
        self._run(ip_id=ip_id)
553 d1bced10 Stavros Sachtouris
554 d1bced10 Stavros Sachtouris
555 d1bced10 Stavros Sachtouris
@command(ip_cmds)
556 d1bced10 Stavros Sachtouris
class ip_create(_init_network, _optional_json):
557 d1bced10 Stavros Sachtouris
    """Reserve an IP on a network"""
558 264a13f7 Stavros Sachtouris
559 d1bced10 Stavros Sachtouris
    arguments = dict(
560 d1bced10 Stavros Sachtouris
        network_id=ValueArgument(
561 d1bced10 Stavros Sachtouris
            'The network to preserve the IP on', '--network-id'),
562 d1bced10 Stavros Sachtouris
        ip_address=ValueArgument('Allocate a specific IP address', '--address')
563 d1bced10 Stavros Sachtouris
    )
564 d1bced10 Stavros Sachtouris
    required = ('network_id', )
565 d1bced10 Stavros Sachtouris
566 d1bced10 Stavros Sachtouris
    @errors.generic.all
567 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
568 d1bced10 Stavros Sachtouris
    @errors.cyclades.network_id
569 d1bced10 Stavros Sachtouris
    def _run(self, network_id):
570 d1bced10 Stavros Sachtouris
        self._print(
571 d1bced10 Stavros Sachtouris
            self.client.create_floatingip(
572 d1bced10 Stavros Sachtouris
                network_id, floating_ip_address=self['ip_address']),
573 d1bced10 Stavros Sachtouris
            self.print_dict)
574 d1bced10 Stavros Sachtouris
575 d1bced10 Stavros Sachtouris
    def main(self):
576 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
577 d1bced10 Stavros Sachtouris
        self._run(network_id=self['network_id'])
578 d1bced10 Stavros Sachtouris
579 d1bced10 Stavros Sachtouris
580 d1bced10 Stavros Sachtouris
@command(ip_cmds)
581 d1bced10 Stavros Sachtouris
class ip_delete(_init_network, _optional_output_cmd):
582 d1bced10 Stavros Sachtouris
    """Unreserve an IP (also delete the port, if attached)"""
583 d1bced10 Stavros Sachtouris
584 d1bced10 Stavros Sachtouris
    def _run(self, ip_id):
585 291cab21 Stavros Sachtouris
        self._optional_output(self.client.delete_floatingip(ip_id))
586 d1bced10 Stavros Sachtouris
587 d1bced10 Stavros Sachtouris
    def main(self, ip_id):
588 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
589 d1bced10 Stavros Sachtouris
        self._run(ip_id=ip_id)
590 d1bced10 Stavros Sachtouris
591 d1bced10 Stavros Sachtouris
592 d1bced10 Stavros Sachtouris
#  Warn users for some importand changes
593 264a13f7 Stavros Sachtouris
594 264a13f7 Stavros Sachtouris
@command(network_cmds)
595 fd981f77 Stavros Sachtouris
class network_connect(_port_create):
596 fd981f77 Stavros Sachtouris
    """Connect a network with a device (server or router)"""
597 264a13f7 Stavros Sachtouris
598 fd981f77 Stavros Sachtouris
    arguments = dict(
599 17cfc2f0 Stavros Sachtouris
        name=ValueArgument('A human readable name for the port', '--name'),
600 fd981f77 Stavros Sachtouris
        security_group_id=RepeatableArgument(
601 fd981f77 Stavros Sachtouris
            'Add a security group id (can be repeated)',
602 fd981f77 Stavros Sachtouris
            ('-g', '--security-group')),
603 fd981f77 Stavros Sachtouris
        subnet_id=ValueArgument(
604 fd981f77 Stavros Sachtouris
            'Subnet id for fixed ips (used with --ip-address)',
605 fd981f77 Stavros Sachtouris
            '--subnet-id'),
606 fd981f77 Stavros Sachtouris
        ip_address=ValueArgument(
607 fd981f77 Stavros Sachtouris
            'IP address for subnet id (used with --subnet-id', '--ip-address'),
608 17cfc2f0 Stavros Sachtouris
        wait=FlagArgument('Wait network to connect', ('-w', '--wait')),
609 fd981f77 Stavros Sachtouris
    )
610 fd981f77 Stavros Sachtouris
611 17cfc2f0 Stavros Sachtouris
    @errors.generic.all
612 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.connection
613 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.network_id
614 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.server_id
615 17cfc2f0 Stavros Sachtouris
    def _run(self, network_id, server_id):
616 17cfc2f0 Stavros Sachtouris
        self.connect(network_id, server_id)
617 17cfc2f0 Stavros Sachtouris
618 fd981f77 Stavros Sachtouris
    def main(self, network_id, device_id):
619 fd981f77 Stavros Sachtouris
        super(self.__class__, self)._run()
620 fd981f77 Stavros Sachtouris
        self._run(network_id=network_id, device_id=device_id)
621 264a13f7 Stavros Sachtouris
622 264a13f7 Stavros Sachtouris
623 264a13f7 Stavros Sachtouris
@command(network_cmds)
624 17cfc2f0 Stavros Sachtouris
class network_disconnect(_init_network, _port_wait, _optional_json):
625 fd981f77 Stavros Sachtouris
    """Disconnnect a network from a device"""
626 264a13f7 Stavros Sachtouris
627 fd981f77 Stavros Sachtouris
    def _cyclades_client(self):
628 fd981f77 Stavros Sachtouris
        auth = getattr(self, 'auth_base')
629 fd981f77 Stavros Sachtouris
        endpoints = auth.get_service_endpoints('compute')
630 fd981f77 Stavros Sachtouris
        URL = endpoints['publicURL']
631 fd981f77 Stavros Sachtouris
        from kamaki.clients.cyclades import CycladesClient
632 fd981f77 Stavros Sachtouris
        return CycladesClient(URL, self.client.token)
633 fd981f77 Stavros Sachtouris
634 17cfc2f0 Stavros Sachtouris
    arguments = dict(
635 17cfc2f0 Stavros Sachtouris
        wait=FlagArgument('Wait network to disconnect', ('-w', '--wait'))
636 17cfc2f0 Stavros Sachtouris
    )
637 17cfc2f0 Stavros Sachtouris
638 fd981f77 Stavros Sachtouris
    @errors.generic.all
639 fd981f77 Stavros Sachtouris
    @errors.cyclades.connection
640 fd981f77 Stavros Sachtouris
    @errors.cyclades.network_id
641 fd981f77 Stavros Sachtouris
    @errors.cyclades.server_id
642 fd981f77 Stavros Sachtouris
    def _run(self, network_id, device_id):
643 fd981f77 Stavros Sachtouris
        vm = self._cyclades_client().get_server_details(device_id)
644 fd981f77 Stavros Sachtouris
        nets = [net for net in vm['attachments'] if net['network_id'] not in (
645 fd981f77 Stavros Sachtouris
            'network_id', )]
646 fd981f77 Stavros Sachtouris
        if not nets:
647 fd981f77 Stavros Sachtouris
            raiseCLIError('Network %s is not connected to device %s' % (
648 fd981f77 Stavros Sachtouris
                network_id, device_id))
649 fd981f77 Stavros Sachtouris
        for net in nets:
650 fd981f77 Stavros Sachtouris
            self.client.port_delete(net['id'])
651 17cfc2f0 Stavros Sachtouris
            self.error('Deleting this connection:')
652 fd981f77 Stavros Sachtouris
            self.print_dict(net)
653 17cfc2f0 Stavros Sachtouris
            if self['wait']:
654 17cfc2f0 Stavros Sachtouris
                self._wait(net['id'], net['status'])
655 fd981f77 Stavros Sachtouris
656 fd981f77 Stavros Sachtouris
    def main(self, network_id, device_id):
657 fd981f77 Stavros Sachtouris
        super(self.__class__, self)._run()
658 fd981f77 Stavros Sachtouris
        self._run(network_id=network_id, device_id=device_id)