Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (26.4 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 f3740b99 Stavros Sachtouris
from kamaki.clients.cyclades import CycladesNetworkClient, ClientError
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 6f2b87c1 Stavros Sachtouris
from kamaki.cli.commands.cyclades import _service_wait
48 d18e6439 Stavros Sachtouris
49 d18e6439 Stavros Sachtouris
50 d18e6439 Stavros Sachtouris
network_cmds = CommandTree('network', 'Networking API network commands')
51 d18e6439 Stavros Sachtouris
port_cmds = CommandTree('port', 'Networking API network commands')
52 d18e6439 Stavros Sachtouris
subnet_cmds = CommandTree('subnet', 'Networking API network commands')
53 d1bced10 Stavros Sachtouris
ip_cmds = CommandTree('ip', 'Networking API floatingip commands')
54 d1bced10 Stavros Sachtouris
_commands = [network_cmds, port_cmds, subnet_cmds, ip_cmds]
55 d18e6439 Stavros Sachtouris
56 d18e6439 Stavros Sachtouris
57 d18e6439 Stavros Sachtouris
about_authentication = '\nUser Authentication:\
58 7a3c66e1 Stavros Sachtouris
    \n  to check authentication: [kamaki] ]user authenticate\
59 7a3c66e1 Stavros Sachtouris
    \n  to set authentication token: \
60 7a3c66e1 Stavros Sachtouris
    [kamaki] 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 f3740b99 Stavros Sachtouris
    def _filter_by_user_id(self, nets):
97 f3740b99 Stavros Sachtouris
        return [net for net in nets if net['user_id'] == self['user_id']] if (
98 f3740b99 Stavros Sachtouris
            self['user_id']) else nets
99 f3740b99 Stavros Sachtouris
100 bc4662d8 Stavros Sachtouris
    def main(self):
101 bc4662d8 Stavros Sachtouris
        self._run()
102 d18e6439 Stavros Sachtouris
103 d18e6439 Stavros Sachtouris
104 d18e6439 Stavros Sachtouris
@command(network_cmds)
105 5c433331 Stavros Sachtouris
class network_list(_init_network, _optional_json, _name_filter, _id_filter):
106 d18e6439 Stavros Sachtouris
    """List networks
107 d18e6439 Stavros Sachtouris
    Use filtering arguments (e.g., --name-like) to manage long server lists
108 d18e6439 Stavros Sachtouris
    """
109 d18e6439 Stavros Sachtouris
110 d18e6439 Stavros Sachtouris
    arguments = dict(
111 d18e6439 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
112 cd40143a Stavros Sachtouris
        more=FlagArgument(
113 cd40143a Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
114 cd40143a Stavros Sachtouris
            '--more'),
115 7e57e590 Stavros Sachtouris
        user_id=ValueArgument(
116 7e57e590 Stavros Sachtouris
            'show only networks belonging to user with this id', '--user-id')
117 d18e6439 Stavros Sachtouris
    )
118 d18e6439 Stavros Sachtouris
119 d18e6439 Stavros Sachtouris
    @errors.generic.all
120 d18e6439 Stavros Sachtouris
    @errors.cyclades.connection
121 d18e6439 Stavros Sachtouris
    def _run(self):
122 f3740b99 Stavros Sachtouris
        detail = bool(self['detail'] or self['user_id'])
123 f3740b99 Stavros Sachtouris
        nets = self.client.list_networks(detail=detail)
124 7e57e590 Stavros Sachtouris
        nets = self._filter_by_user_id(nets)
125 77bf75fe Stavros Sachtouris
        nets = self._filter_by_name(nets)
126 77bf75fe Stavros Sachtouris
        nets = self._filter_by_id(nets)
127 f3740b99 Stavros Sachtouris
        if detail and not self['detail']:
128 7e57e590 Stavros Sachtouris
            nets = [dict(
129 7e57e590 Stavros Sachtouris
                id=n['id'], name=n['name'], links=n['links']) for n in nets]
130 cd40143a Stavros Sachtouris
        kwargs = dict()
131 cd40143a Stavros Sachtouris
        if self['more']:
132 cd40143a Stavros Sachtouris
            kwargs['out'] = StringIO()
133 cd40143a Stavros Sachtouris
            kwargs['title'] = ()
134 cd40143a Stavros Sachtouris
        self._print(nets, **kwargs)
135 cd40143a Stavros Sachtouris
        if self['more']:
136 cd40143a Stavros Sachtouris
            pager(kwargs['out'].getvalue())
137 d18e6439 Stavros Sachtouris
138 d18e6439 Stavros Sachtouris
    def main(self):
139 d18e6439 Stavros Sachtouris
        super(self.__class__, self)._run()
140 d18e6439 Stavros Sachtouris
        self._run()
141 cd40143a Stavros Sachtouris
142 cd40143a Stavros Sachtouris
143 cd40143a Stavros Sachtouris
@command(network_cmds)
144 5c433331 Stavros Sachtouris
class network_info(_init_network, _optional_json):
145 cd40143a Stavros Sachtouris
    """Get details about a network"""
146 cd40143a Stavros Sachtouris
147 cd40143a Stavros Sachtouris
    @errors.generic.all
148 cd40143a Stavros Sachtouris
    @errors.cyclades.connection
149 cd40143a Stavros Sachtouris
    @errors.cyclades.network_id
150 cd40143a Stavros Sachtouris
    def _run(self, network_id):
151 cd40143a Stavros Sachtouris
        net = self.client.get_network_details(network_id)
152 cd40143a Stavros Sachtouris
        self._print(net, self.print_dict)
153 cd40143a Stavros Sachtouris
154 cd40143a Stavros Sachtouris
    def main(self, network_id):
155 cd40143a Stavros Sachtouris
        super(self.__class__, self)._run()
156 cd40143a Stavros Sachtouris
        self._run(network_id=network_id)
157 49413939 Stavros Sachtouris
158 49413939 Stavros Sachtouris
159 264a13f7 Stavros Sachtouris
class NetworkTypeArgument(ValueArgument):
160 264a13f7 Stavros Sachtouris
161 1c366ac9 Stavros Sachtouris
    types = ('MAC_FILTERED', 'CUSTOM', 'IP_LESS_ROUTED', 'PHYSICAL_VLAN')
162 264a13f7 Stavros Sachtouris
163 264a13f7 Stavros Sachtouris
    @property
164 264a13f7 Stavros Sachtouris
    def value(self):
165 1c366ac9 Stavros Sachtouris
        return getattr(self, '_value', self.types[0])
166 264a13f7 Stavros Sachtouris
167 264a13f7 Stavros Sachtouris
    @value.setter
168 264a13f7 Stavros Sachtouris
    def value(self, new_value):
169 264a13f7 Stavros Sachtouris
        if new_value and new_value.upper() in self.types:
170 264a13f7 Stavros Sachtouris
            self._value = new_value.upper()
171 264a13f7 Stavros Sachtouris
        elif new_value:
172 264a13f7 Stavros Sachtouris
            raise CLIInvalidArgument(
173 264a13f7 Stavros Sachtouris
                'Invalid network type %s' % new_value, details=[
174 264a13f7 Stavros Sachtouris
                    'Valid types: %s' % ', '.join(self.types), ])
175 264a13f7 Stavros Sachtouris
176 264a13f7 Stavros Sachtouris
177 49413939 Stavros Sachtouris
@command(network_cmds)
178 67dfe4a2 Stavros Sachtouris
class network_create(_init_network, _optional_json):
179 1c366ac9 Stavros Sachtouris
    """Create a new network (default type: MAC_FILTERED)"""
180 49413939 Stavros Sachtouris
181 cd0927f7 Stavros Sachtouris
    arguments = dict(
182 cd0927f7 Stavros Sachtouris
        name=ValueArgument('Network name', '--name'),
183 cd0927f7 Stavros Sachtouris
        shared=FlagArgument(
184 264a13f7 Stavros Sachtouris
            'Make network shared (special privileges required)', '--shared'),
185 264a13f7 Stavros Sachtouris
        network_type=NetworkTypeArgument(
186 264a13f7 Stavros Sachtouris
            'Valid network types: %s' % (', '.join(NetworkTypeArgument.types)),
187 67dfe4a2 Stavros Sachtouris
            '--type')
188 49413939 Stavros Sachtouris
    )
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 7a3c66e1 Stavros Sachtouris
        if not new_pools:
297 7a3c66e1 Stavros Sachtouris
            return
298 62c6652f Stavros Sachtouris
        new_list = []
299 62c6652f Stavros Sachtouris
        for pool in new_pools:
300 62c6652f Stavros Sachtouris
            start, comma, end = pool.partition(',')
301 62c6652f Stavros Sachtouris
            if not (start and comma and end):
302 62c6652f Stavros Sachtouris
                raise CLIInvalidArgument(
303 62c6652f Stavros Sachtouris
                    'Invalid allocation pool argument %s' % pool, details=[
304 62c6652f Stavros Sachtouris
                    'Allocation values must be of the form:',
305 62c6652f Stavros Sachtouris
                    '  <start address>,<end address>'])
306 62c6652f Stavros Sachtouris
            new_list.append(dict(start=start, end=end))
307 62c6652f Stavros Sachtouris
        self._value = new_list
308 62c6652f Stavros Sachtouris
309 62c6652f Stavros Sachtouris
310 62c6652f Stavros Sachtouris
@command(subnet_cmds)
311 62c6652f Stavros Sachtouris
class subnet_create(_init_network, _optional_json):
312 264a13f7 Stavros Sachtouris
    """Create a new subnet"""
313 62c6652f Stavros Sachtouris
314 62c6652f Stavros Sachtouris
    arguments = dict(
315 62c6652f Stavros Sachtouris
        name=ValueArgument('Subnet name', '--name'),
316 62c6652f Stavros Sachtouris
        allocation_pools=AllocationPoolArgument(
317 62c6652f Stavros Sachtouris
            'start_address,end_address of allocation pool (can be repeated)'
318 62c6652f Stavros Sachtouris
            ' e.g., --alloc-pool=123.45.67.1,123.45.67.8',
319 62c6652f Stavros Sachtouris
            '--alloc-pool'),
320 62c6652f Stavros Sachtouris
        gateway=ValueArgument('Gateway IP', '--gateway'),
321 62c6652f Stavros Sachtouris
        subnet_id=ValueArgument('The id for the subnet', '--id'),
322 62c6652f Stavros Sachtouris
        ipv6=FlagArgument('If set, IP version is set to 6, else 4', '--ipv6'),
323 264a13f7 Stavros Sachtouris
        enable_dhcp=FlagArgument('Enable dhcp (default: off)', '--with-dhcp'),
324 264a13f7 Stavros Sachtouris
        network_id=ValueArgument('Set the network ID', '--network-id'),
325 264a13f7 Stavros Sachtouris
        cidr=ValueArgument('Set the CIDR', '--cidr')
326 62c6652f Stavros Sachtouris
    )
327 264a13f7 Stavros Sachtouris
    required = ('network_id', 'cidr')
328 62c6652f Stavros Sachtouris
329 62c6652f Stavros Sachtouris
    @errors.generic.all
330 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
331 62c6652f Stavros Sachtouris
    @errors.cyclades.network_id
332 62c6652f Stavros Sachtouris
    def _run(self, network_id, cidr):
333 62c6652f Stavros Sachtouris
        net = self.client.create_subnet(
334 62c6652f Stavros Sachtouris
            network_id, cidr,
335 62c6652f Stavros Sachtouris
            self['name'], self['allocation_pools'], self['gateway'],
336 62c6652f Stavros Sachtouris
            self['subnet_id'], self['ipv6'], self['enable_dhcp'])
337 62c6652f Stavros Sachtouris
        self._print(net, self.print_dict)
338 62c6652f Stavros Sachtouris
339 264a13f7 Stavros Sachtouris
    def main(self):
340 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
341 264a13f7 Stavros Sachtouris
        self._run(network_id=self['network_id'], cidr=self['cidr'])
342 62c6652f Stavros Sachtouris
343 62c6652f Stavros Sachtouris
344 62c6652f Stavros Sachtouris
# @command(subnet_cmds)
345 62c6652f Stavros Sachtouris
# class subnet_delete(_init_network, _optional_output_cmd):
346 62c6652f Stavros Sachtouris
#     """Delete a subnet"""
347 62c6652f Stavros Sachtouris
348 62c6652f Stavros Sachtouris
#     @errors.generic.all
349 62c6652f Stavros Sachtouris
#     @errors.cyclades.connection
350 62c6652f Stavros Sachtouris
#     def _run(self, subnet_id):
351 62c6652f Stavros Sachtouris
#         r = self.client.delete_subnet(subnet_id)
352 62c6652f Stavros Sachtouris
#         self._optional_output(r)
353 62c6652f Stavros Sachtouris
354 62c6652f Stavros Sachtouris
#     def main(self, subnet_id):
355 62c6652f Stavros Sachtouris
#         super(self.__class__, self)._run()
356 62c6652f Stavros Sachtouris
#         self._run(subnet_id=subnet_id)
357 62c6652f Stavros Sachtouris
358 62c6652f Stavros Sachtouris
359 62c6652f Stavros Sachtouris
@command(subnet_cmds)
360 264a13f7 Stavros Sachtouris
class subnet_modify(_init_network, _optional_json):
361 264a13f7 Stavros Sachtouris
    """Modify the attributes of a subnet"""
362 62c6652f Stavros Sachtouris
363 264a13f7 Stavros Sachtouris
    arguments = dict(
364 264a13f7 Stavros Sachtouris
        new_name=ValueArgument('New name of the subnet', '--name')
365 264a13f7 Stavros Sachtouris
    )
366 264a13f7 Stavros Sachtouris
    required = ['new_name']
367 62c6652f Stavros Sachtouris
368 62c6652f Stavros Sachtouris
    @errors.generic.all
369 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
370 62c6652f Stavros Sachtouris
    def _run(self, subnet_id):
371 62c6652f Stavros Sachtouris
        r = self.client.get_subnet_details(subnet_id)
372 62c6652f Stavros Sachtouris
        r = self.client.update_subnet(
373 264a13f7 Stavros Sachtouris
            subnet_id, r['network_id'], name=self['new_name'])
374 62c6652f Stavros Sachtouris
        self._print(r, self.print_dict)
375 62c6652f Stavros Sachtouris
376 62c6652f Stavros Sachtouris
    def main(self, subnet_id):
377 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
378 62c6652f Stavros Sachtouris
        self._run(subnet_id=subnet_id)
379 447365fe Stavros Sachtouris
380 447365fe Stavros Sachtouris
381 447365fe Stavros Sachtouris
@command(port_cmds)
382 f3740b99 Stavros Sachtouris
class port_list(_init_network, _optional_json, _name_filter, _id_filter):
383 11cc86af Stavros Sachtouris
    """List all ports"""
384 447365fe Stavros Sachtouris
385 f3740b99 Stavros Sachtouris
    arguments = dict(
386 f3740b99 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
387 f3740b99 Stavros Sachtouris
        more=FlagArgument(
388 f3740b99 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
389 f3740b99 Stavros Sachtouris
            '--more'),
390 f3740b99 Stavros Sachtouris
        user_id=ValueArgument(
391 f3740b99 Stavros Sachtouris
            'show only networks belonging to user with this id', '--user-id')
392 f3740b99 Stavros Sachtouris
    )
393 f3740b99 Stavros Sachtouris
394 447365fe Stavros Sachtouris
    @errors.generic.all
395 447365fe Stavros Sachtouris
    @errors.cyclades.connection
396 11cc86af Stavros Sachtouris
    def _run(self):
397 f3740b99 Stavros Sachtouris
        detail = bool(self['detail'] or self['user_id'])
398 f3740b99 Stavros Sachtouris
        ports = self.client.list_ports(detail=detail)
399 f3740b99 Stavros Sachtouris
        ports = self._filter_by_user_id(ports)
400 f3740b99 Stavros Sachtouris
        ports = self._filter_by_name(ports)
401 f3740b99 Stavros Sachtouris
        ports = self._filter_by_id(ports)
402 f3740b99 Stavros Sachtouris
        if detail and not self['detail']:
403 f3740b99 Stavros Sachtouris
            ports = [dict(
404 f3740b99 Stavros Sachtouris
                id=p['id'], name=p['name'], links=p['links']) for p in ports]
405 f3740b99 Stavros Sachtouris
        kwargs = dict()
406 f3740b99 Stavros Sachtouris
        if self['more']:
407 f3740b99 Stavros Sachtouris
            kwargs['out'] = StringIO()
408 f3740b99 Stavros Sachtouris
            kwargs['title'] = ()
409 f3740b99 Stavros Sachtouris
        self._print(ports, **kwargs)
410 f3740b99 Stavros Sachtouris
        if self['more']:
411 f3740b99 Stavros Sachtouris
            pager(kwargs['out'].getvalue())
412 447365fe Stavros Sachtouris
413 11cc86af Stavros Sachtouris
    def main(self):
414 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
415 11cc86af Stavros Sachtouris
        self._run()
416 447365fe Stavros Sachtouris
417 447365fe Stavros Sachtouris
418 447365fe Stavros Sachtouris
@command(port_cmds)
419 447365fe Stavros Sachtouris
class port_info(_init_network, _optional_json):
420 447365fe Stavros Sachtouris
    """Get details about a port"""
421 447365fe Stavros Sachtouris
422 447365fe Stavros Sachtouris
    @errors.generic.all
423 447365fe Stavros Sachtouris
    @errors.cyclades.connection
424 447365fe Stavros Sachtouris
    def _run(self, port_id):
425 f3740b99 Stavros Sachtouris
        port = self.client.get_port_details(port_id)
426 f3740b99 Stavros Sachtouris
        self._print(port, self.print_dict)
427 447365fe Stavros Sachtouris
428 447365fe Stavros Sachtouris
    def main(self, port_id):
429 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
430 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
431 447365fe Stavros Sachtouris
432 447365fe Stavros Sachtouris
433 447365fe Stavros Sachtouris
@command(port_cmds)
434 f261965c Stavros Sachtouris
class port_delete(_init_network, _optional_output_cmd, _port_wait):
435 264a13f7 Stavros Sachtouris
    """Delete a port (== disconnect server from network)"""
436 447365fe Stavros Sachtouris
437 f261965c Stavros Sachtouris
    arguments = dict(
438 f261965c Stavros Sachtouris
        wait=FlagArgument('Wait port to be established', ('-w', '--wait'))
439 f261965c Stavros Sachtouris
    )
440 f261965c Stavros Sachtouris
441 447365fe Stavros Sachtouris
    @errors.generic.all
442 447365fe Stavros Sachtouris
    @errors.cyclades.connection
443 447365fe Stavros Sachtouris
    def _run(self, port_id):
444 f3740b99 Stavros Sachtouris
        if self['wait']:
445 f3740b99 Stavros Sachtouris
            status = self.client.get_port_details(port_id)['status']
446 447365fe Stavros Sachtouris
        r = self.client.delete_port(port_id)
447 f261965c Stavros Sachtouris
        if self['wait']:
448 f3740b99 Stavros Sachtouris
            try:
449 f3740b99 Stavros Sachtouris
                self._wait(port_id, status)
450 f3740b99 Stavros Sachtouris
            except ClientError as ce:
451 f3740b99 Stavros Sachtouris
                if ce.status not in (404, ):
452 f3740b99 Stavros Sachtouris
                    raise
453 f3740b99 Stavros Sachtouris
                self.error('Port %s is deleted' % port_id)
454 447365fe Stavros Sachtouris
        self._optional_output(r)
455 447365fe Stavros Sachtouris
456 447365fe Stavros Sachtouris
    def main(self, port_id):
457 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
458 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
459 447365fe Stavros Sachtouris
460 447365fe Stavros Sachtouris
461 447365fe Stavros Sachtouris
@command(port_cmds)
462 264a13f7 Stavros Sachtouris
class port_modify(_init_network, _optional_json):
463 264a13f7 Stavros Sachtouris
    """Modify the attributes of a port"""
464 447365fe Stavros Sachtouris
465 264a13f7 Stavros Sachtouris
    arguments = dict(new_name=ValueArgument('New name of the port', '--name'))
466 264a13f7 Stavros Sachtouris
    required = ['new_name', ]
467 447365fe Stavros Sachtouris
468 447365fe Stavros Sachtouris
    @errors.generic.all
469 447365fe Stavros Sachtouris
    @errors.cyclades.connection
470 447365fe Stavros Sachtouris
    def _run(self, port_id):
471 447365fe Stavros Sachtouris
        r = self.client.get_port_details(port_id)
472 447365fe Stavros Sachtouris
        r = self.client.update_port(
473 264a13f7 Stavros Sachtouris
            port_id, r['network_id'], name=self['new_name'])
474 447365fe Stavros Sachtouris
        self._print(r, self.print_dict)
475 447365fe Stavros Sachtouris
476 447365fe Stavros Sachtouris
    def main(self, port_id):
477 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
478 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
479 447365fe Stavros Sachtouris
480 447365fe Stavros Sachtouris
481 17cfc2f0 Stavros Sachtouris
class _port_create(_init_network, _optional_json, _port_wait):
482 fd981f77 Stavros Sachtouris
483 17cfc2f0 Stavros Sachtouris
    def connect(self, network_id, device_id):
484 909ae594 Stavros Sachtouris
        fixed_ips = [dict(ip_address=self['ip_address'])] if (
485 cc5da5a5 Stavros Sachtouris
            self['ip_address']) else None
486 909ae594 Stavros Sachtouris
        if fixed_ips and self['subnet_id']:
487 909ae594 Stavros Sachtouris
            fixed_ips[0]['subnet_id'] = self['subnet_id']
488 fd981f77 Stavros Sachtouris
        r = self.client.create_port(
489 fd981f77 Stavros Sachtouris
            network_id, device_id,
490 fd981f77 Stavros Sachtouris
            name=self['name'],
491 fd981f77 Stavros Sachtouris
            security_groups=self['security_group_id'],
492 fd981f77 Stavros Sachtouris
            fixed_ips=fixed_ips)
493 fd981f77 Stavros Sachtouris
        if self['wait']:
494 fd981f77 Stavros Sachtouris
            self._wait(r['id'], r['status'])
495 f3740b99 Stavros Sachtouris
            r = self.client.get_port_details(r['id'])
496 f3740b99 Stavros Sachtouris
        self._print([r])
497 fd981f77 Stavros Sachtouris
498 fd981f77 Stavros Sachtouris
499 ccdd1b82 Stavros Sachtouris
@command(port_cmds)
500 f25bd53b Stavros Sachtouris
class port_create(_port_create):
501 264a13f7 Stavros Sachtouris
    """Create a new port (== connect server to network)"""
502 ccdd1b82 Stavros Sachtouris
503 ccdd1b82 Stavros Sachtouris
    arguments = dict(
504 b7d79306 Stavros Sachtouris
        name=ValueArgument('A human readable name', '--name'),
505 ccdd1b82 Stavros Sachtouris
        security_group_id=RepeatableArgument(
506 ccdd1b82 Stavros Sachtouris
            'Add a security group id (can be repeated)',
507 b7d79306 Stavros Sachtouris
            ('-g', '--security-group')),
508 b7d79306 Stavros Sachtouris
        subnet_id=ValueArgument(
509 b7d79306 Stavros Sachtouris
            'Subnet id for fixed ips (used with --ip-address)',
510 b7d79306 Stavros Sachtouris
            '--subnet-id'),
511 b7d79306 Stavros Sachtouris
        ip_address=ValueArgument(
512 909ae594 Stavros Sachtouris
            'IP address for subnet id', '--ip-address'),
513 264a13f7 Stavros Sachtouris
        network_id=ValueArgument('Set the network ID', '--network-id'),
514 264a13f7 Stavros Sachtouris
        device_id=ValueArgument(
515 264a13f7 Stavros Sachtouris
            'The device is either a virtual server or a virtual router',
516 c6afee48 Stavros Sachtouris
            '--device-id'),
517 c6afee48 Stavros Sachtouris
        wait=FlagArgument('Wait port to be established', ('-w', '--wait')),
518 ccdd1b82 Stavros Sachtouris
    )
519 e3f54dc0 Stavros Sachtouris
    required = ('network_id', 'device_id')
520 ccdd1b82 Stavros Sachtouris
521 17cfc2f0 Stavros Sachtouris
    @errors.generic.all
522 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.connection
523 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.network_id
524 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.server_id
525 17cfc2f0 Stavros Sachtouris
    def _run(self, network_id, server_id):
526 17cfc2f0 Stavros Sachtouris
        self.connect(network_id, server_id)
527 17cfc2f0 Stavros Sachtouris
528 264a13f7 Stavros Sachtouris
    def main(self):
529 ccdd1b82 Stavros Sachtouris
        super(self.__class__, self)._run()
530 17cfc2f0 Stavros Sachtouris
        self._run(network_id=self['network_id'], server_id=self['device_id'])
531 264a13f7 Stavros Sachtouris
532 264a13f7 Stavros Sachtouris
533 c6afee48 Stavros Sachtouris
@command(port_cmds)
534 c6afee48 Stavros Sachtouris
class port_wait(_init_network, _port_wait):
535 67dfe4a2 Stavros Sachtouris
    """Wait for port to finish [ACTIVE, DOWN, BUILD, ERROR]"""
536 c6afee48 Stavros Sachtouris
537 c6afee48 Stavros Sachtouris
    arguments = dict(
538 c6afee48 Stavros Sachtouris
        timeout=IntArgument(
539 c6afee48 Stavros Sachtouris
            'Wait limit in seconds (default: 60)', '--timeout', default=60)
540 c6afee48 Stavros Sachtouris
    )
541 c6afee48 Stavros Sachtouris
542 c6afee48 Stavros Sachtouris
    @errors.generic.all
543 c6afee48 Stavros Sachtouris
    @errors.cyclades.connection
544 c6afee48 Stavros Sachtouris
    def _run(self, port_id, current_status):
545 c6afee48 Stavros Sachtouris
        port = self.client.get_port_details(port_id)
546 c6afee48 Stavros Sachtouris
        if port['status'].lower() == current_status.lower():
547 c6afee48 Stavros Sachtouris
            self._wait(port_id, current_status, timeout=self['timeout'])
548 c6afee48 Stavros Sachtouris
        else:
549 c6afee48 Stavros Sachtouris
            self.error(
550 c6afee48 Stavros Sachtouris
                'Port %s: Cannot wait for status %s, '
551 c6afee48 Stavros Sachtouris
                'status is already %s' % (
552 c6afee48 Stavros Sachtouris
                    port_id, current_status, port['status']))
553 c6afee48 Stavros Sachtouris
554 67dfe4a2 Stavros Sachtouris
    def main(self, port_id, current_status='BUILD'):
555 c6afee48 Stavros Sachtouris
        super(self.__class__, self)._run()
556 c6afee48 Stavros Sachtouris
        self._run(port_id=port_id, current_status=current_status)
557 c6afee48 Stavros Sachtouris
558 c6afee48 Stavros Sachtouris
559 d1bced10 Stavros Sachtouris
@command(ip_cmds)
560 d1bced10 Stavros Sachtouris
class ip_list(_init_network, _optional_json):
561 d1bced10 Stavros Sachtouris
    """List reserved floating IPs"""
562 d1bced10 Stavros Sachtouris
563 d1bced10 Stavros Sachtouris
    @errors.generic.all
564 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
565 d1bced10 Stavros Sachtouris
    def _run(self):
566 d1bced10 Stavros Sachtouris
        self._print(self.client.list_floatingips())
567 d1bced10 Stavros Sachtouris
568 d1bced10 Stavros Sachtouris
    def main(self):
569 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
570 d1bced10 Stavros Sachtouris
        self._run()
571 d1bced10 Stavros Sachtouris
572 d1bced10 Stavros Sachtouris
573 d1bced10 Stavros Sachtouris
@command(ip_cmds)
574 d1bced10 Stavros Sachtouris
class ip_info(_init_network, _optional_json):
575 d1bced10 Stavros Sachtouris
    """Get details on a floating IP"""
576 d1bced10 Stavros Sachtouris
577 d1bced10 Stavros Sachtouris
    @errors.generic.all
578 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
579 d1bced10 Stavros Sachtouris
    def _run(self, ip_id):
580 291cab21 Stavros Sachtouris
        self._print(
581 291cab21 Stavros Sachtouris
            self.client.get_floatingip_details(ip_id), self.print_dict)
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
@command(ip_cmds)
589 d1bced10 Stavros Sachtouris
class ip_create(_init_network, _optional_json):
590 d1bced10 Stavros Sachtouris
    """Reserve an IP on a network"""
591 264a13f7 Stavros Sachtouris
592 d1bced10 Stavros Sachtouris
    arguments = dict(
593 d1bced10 Stavros Sachtouris
        network_id=ValueArgument(
594 d1bced10 Stavros Sachtouris
            'The network to preserve the IP on', '--network-id'),
595 cc5da5a5 Stavros Sachtouris
        ip_address=ValueArgument('Allocate an IP address', '--address')
596 d1bced10 Stavros Sachtouris
    )
597 d1bced10 Stavros Sachtouris
    required = ('network_id', )
598 d1bced10 Stavros Sachtouris
599 d1bced10 Stavros Sachtouris
    @errors.generic.all
600 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
601 d1bced10 Stavros Sachtouris
    @errors.cyclades.network_id
602 d1bced10 Stavros Sachtouris
    def _run(self, network_id):
603 d1bced10 Stavros Sachtouris
        self._print(
604 d1bced10 Stavros Sachtouris
            self.client.create_floatingip(
605 d1bced10 Stavros Sachtouris
                network_id, floating_ip_address=self['ip_address']),
606 d1bced10 Stavros Sachtouris
            self.print_dict)
607 d1bced10 Stavros Sachtouris
608 d1bced10 Stavros Sachtouris
    def main(self):
609 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
610 d1bced10 Stavros Sachtouris
        self._run(network_id=self['network_id'])
611 d1bced10 Stavros Sachtouris
612 d1bced10 Stavros Sachtouris
613 d1bced10 Stavros Sachtouris
@command(ip_cmds)
614 d1bced10 Stavros Sachtouris
class ip_delete(_init_network, _optional_output_cmd):
615 d1bced10 Stavros Sachtouris
    """Unreserve an IP (also delete the port, if attached)"""
616 d1bced10 Stavros Sachtouris
617 d1bced10 Stavros Sachtouris
    def _run(self, ip_id):
618 291cab21 Stavros Sachtouris
        self._optional_output(self.client.delete_floatingip(ip_id))
619 d1bced10 Stavros Sachtouris
620 d1bced10 Stavros Sachtouris
    def main(self, ip_id):
621 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
622 d1bced10 Stavros Sachtouris
        self._run(ip_id=ip_id)
623 d1bced10 Stavros Sachtouris
624 d1bced10 Stavros Sachtouris
625 cc5da5a5 Stavros Sachtouris
@command(ip_cmds)
626 cc5da5a5 Stavros Sachtouris
class ip_attach(_port_create):
627 cc5da5a5 Stavros Sachtouris
    """Attach an IP on a virtual server"""
628 cc5da5a5 Stavros Sachtouris
629 cc5da5a5 Stavros Sachtouris
    arguments = dict(
630 cc5da5a5 Stavros Sachtouris
        name=ValueArgument('A human readable name for the port', '--name'),
631 cc5da5a5 Stavros Sachtouris
        security_group_id=RepeatableArgument(
632 cc5da5a5 Stavros Sachtouris
            'Add a security group id (can be repeated)',
633 cc5da5a5 Stavros Sachtouris
            ('-g', '--security-group')),
634 cc5da5a5 Stavros Sachtouris
        subnet_id=ValueArgument('Subnet id', '--subnet-id'),
635 cc5da5a5 Stavros Sachtouris
        wait=FlagArgument('Wait IP to be attached', ('-w', '--wait')),
636 cc5da5a5 Stavros Sachtouris
        server_id=ValueArgument(
637 cc5da5a5 Stavros Sachtouris
            'Server to attach to this IP', '--server-id')
638 cc5da5a5 Stavros Sachtouris
    )
639 cc5da5a5 Stavros Sachtouris
    required = ('server_id', )
640 cc5da5a5 Stavros Sachtouris
641 cc5da5a5 Stavros Sachtouris
    @errors.generic.all
642 cc5da5a5 Stavros Sachtouris
    @errors.cyclades.connection
643 cc5da5a5 Stavros Sachtouris
    @errors.cyclades.server_id
644 cc5da5a5 Stavros Sachtouris
    def _run(self, ip_address, server_id):
645 cc5da5a5 Stavros Sachtouris
        netid = None
646 cc5da5a5 Stavros Sachtouris
        for ip in self.client.list_floatingips():
647 cc5da5a5 Stavros Sachtouris
            if ip['floating_ip_address'] == ip_address:
648 cc5da5a5 Stavros Sachtouris
                netid = ip['floating_network_id']
649 cc5da5a5 Stavros Sachtouris
                iparg = ValueArgument(parsed_name='--ip')
650 cc5da5a5 Stavros Sachtouris
                iparg.value = ip_address
651 cc5da5a5 Stavros Sachtouris
                self.arguments['ip_address'] = iparg
652 cc5da5a5 Stavros Sachtouris
                break
653 cc5da5a5 Stavros Sachtouris
        if netid:
654 cc5da5a5 Stavros Sachtouris
            self.error('Creating a port to attach IP %s to server %s' % (
655 cc5da5a5 Stavros Sachtouris
                ip_address, server_id))
656 cc5da5a5 Stavros Sachtouris
            self.connect(netid, server_id)
657 cc5da5a5 Stavros Sachtouris
        else:
658 cc5da5a5 Stavros Sachtouris
            raiseCLIError(
659 cc5da5a5 Stavros Sachtouris
                'IP address %s does not match any reserved IPs' % ip_address,
660 cc5da5a5 Stavros Sachtouris
                details=[
661 cc5da5a5 Stavros Sachtouris
                    'To reserve an IP:', '  [kamaki] ip create',
662 cc5da5a5 Stavros Sachtouris
                    'To see all reserved IPs:', '  [kamaki] ip list'])
663 cc5da5a5 Stavros Sachtouris
664 cc5da5a5 Stavros Sachtouris
    def main(self, ip_address):
665 cc5da5a5 Stavros Sachtouris
        super(self.__class__, self)._run()
666 cc5da5a5 Stavros Sachtouris
        self._run(ip_address=ip_address, server_id=self['server_id'])
667 cc5da5a5 Stavros Sachtouris
668 cc5da5a5 Stavros Sachtouris
669 cc5da5a5 Stavros Sachtouris
@command(ip_cmds)
670 cc5da5a5 Stavros Sachtouris
class ip_detach(_init_network, _port_wait, _optional_json):
671 cc5da5a5 Stavros Sachtouris
    """Detach an IP from a virtual server"""
672 cc5da5a5 Stavros Sachtouris
673 cc5da5a5 Stavros Sachtouris
    arguments = dict(
674 cc5da5a5 Stavros Sachtouris
        wait=FlagArgument('Wait network to disconnect', ('-w', '--wait')),
675 cc5da5a5 Stavros Sachtouris
    )
676 cc5da5a5 Stavros Sachtouris
677 cc5da5a5 Stavros Sachtouris
    @errors.generic.all
678 cc5da5a5 Stavros Sachtouris
    @errors.cyclades.connection
679 cc5da5a5 Stavros Sachtouris
    def _run(self, ip_address):
680 cc5da5a5 Stavros Sachtouris
        for ip in self.client.list_floatingips():
681 cc5da5a5 Stavros Sachtouris
            if ip['floating_ip_address'] == ip_address:
682 cc5da5a5 Stavros Sachtouris
                if not ip['port_id']:
683 cc5da5a5 Stavros Sachtouris
                    raiseCLIError('IP %s is not attached' % ip_address)
684 cc5da5a5 Stavros Sachtouris
                self.error('Deleting port %s:' % ip['port_id'])
685 cc5da5a5 Stavros Sachtouris
                self.client.delete_port(ip['port_id'])
686 cc5da5a5 Stavros Sachtouris
                if self['wait']:
687 cc5da5a5 Stavros Sachtouris
                    port_status = self.client.get_port_details(ip['port_id'])[
688 cc5da5a5 Stavros Sachtouris
                        'status']
689 cc5da5a5 Stavros Sachtouris
                    try:
690 cc5da5a5 Stavros Sachtouris
                        self._wait(ip['port_id'], port_status)
691 cc5da5a5 Stavros Sachtouris
                    except ClientError as ce:
692 cc5da5a5 Stavros Sachtouris
                        if ce.status not in (404, ):
693 cc5da5a5 Stavros Sachtouris
                            raise
694 cc5da5a5 Stavros Sachtouris
                        self.error('Port %s is deleted' % ip['port_id'])
695 cc5da5a5 Stavros Sachtouris
                return
696 cc5da5a5 Stavros Sachtouris
        raiseCLIError('IP %s not found' % ip_address)
697 cc5da5a5 Stavros Sachtouris
698 cc5da5a5 Stavros Sachtouris
    def main(self, ip_address):
699 cc5da5a5 Stavros Sachtouris
        super(self.__class__, self)._run()
700 cc5da5a5 Stavros Sachtouris
        self._run(ip_address)
701 cc5da5a5 Stavros Sachtouris
702 cc5da5a5 Stavros Sachtouris
703 d1bced10 Stavros Sachtouris
#  Warn users for some importand changes
704 264a13f7 Stavros Sachtouris
705 264a13f7 Stavros Sachtouris
@command(network_cmds)
706 fd981f77 Stavros Sachtouris
class network_connect(_port_create):
707 fd981f77 Stavros Sachtouris
    """Connect a network with a device (server or router)"""
708 264a13f7 Stavros Sachtouris
709 fd981f77 Stavros Sachtouris
    arguments = dict(
710 17cfc2f0 Stavros Sachtouris
        name=ValueArgument('A human readable name for the port', '--name'),
711 fd981f77 Stavros Sachtouris
        security_group_id=RepeatableArgument(
712 fd981f77 Stavros Sachtouris
            'Add a security group id (can be repeated)',
713 fd981f77 Stavros Sachtouris
            ('-g', '--security-group')),
714 fd981f77 Stavros Sachtouris
        subnet_id=ValueArgument(
715 fd981f77 Stavros Sachtouris
            'Subnet id for fixed ips (used with --ip-address)',
716 fd981f77 Stavros Sachtouris
            '--subnet-id'),
717 fd981f77 Stavros Sachtouris
        ip_address=ValueArgument(
718 fd981f77 Stavros Sachtouris
            'IP address for subnet id (used with --subnet-id', '--ip-address'),
719 17cfc2f0 Stavros Sachtouris
        wait=FlagArgument('Wait network to connect', ('-w', '--wait')),
720 7a3c66e1 Stavros Sachtouris
        device_id=RepeatableArgument(
721 7a3c66e1 Stavros Sachtouris
            'Connect this device to the network (can be repeated)',
722 7a3c66e1 Stavros Sachtouris
            '--device-id')
723 fd981f77 Stavros Sachtouris
    )
724 7a3c66e1 Stavros Sachtouris
    required = ('device_id', )
725 fd981f77 Stavros Sachtouris
726 17cfc2f0 Stavros Sachtouris
    @errors.generic.all
727 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.connection
728 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.network_id
729 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.server_id
730 17cfc2f0 Stavros Sachtouris
    def _run(self, network_id, server_id):
731 f3740b99 Stavros Sachtouris
        self.error('Creating a port to connect network %s with device %s' % (
732 f3740b99 Stavros Sachtouris
            network_id, server_id))
733 17cfc2f0 Stavros Sachtouris
        self.connect(network_id, server_id)
734 17cfc2f0 Stavros Sachtouris
735 7a3c66e1 Stavros Sachtouris
    def main(self, network_id):
736 fd981f77 Stavros Sachtouris
        super(self.__class__, self)._run()
737 7a3c66e1 Stavros Sachtouris
        for sid in self['device_id']:
738 7a3c66e1 Stavros Sachtouris
            self._run(network_id=network_id, server_id=sid)
739 264a13f7 Stavros Sachtouris
740 264a13f7 Stavros Sachtouris
741 264a13f7 Stavros Sachtouris
@command(network_cmds)
742 17cfc2f0 Stavros Sachtouris
class network_disconnect(_init_network, _port_wait, _optional_json):
743 fd981f77 Stavros Sachtouris
    """Disconnnect a network from a device"""
744 264a13f7 Stavros Sachtouris
745 fd981f77 Stavros Sachtouris
    def _cyclades_client(self):
746 fd981f77 Stavros Sachtouris
        auth = getattr(self, 'auth_base')
747 fd981f77 Stavros Sachtouris
        endpoints = auth.get_service_endpoints('compute')
748 fd981f77 Stavros Sachtouris
        URL = endpoints['publicURL']
749 fd981f77 Stavros Sachtouris
        from kamaki.clients.cyclades import CycladesClient
750 fd981f77 Stavros Sachtouris
        return CycladesClient(URL, self.client.token)
751 fd981f77 Stavros Sachtouris
752 17cfc2f0 Stavros Sachtouris
    arguments = dict(
753 7a3c66e1 Stavros Sachtouris
        wait=FlagArgument('Wait network to disconnect', ('-w', '--wait')),
754 7a3c66e1 Stavros Sachtouris
        device_id=RepeatableArgument(
755 7a3c66e1 Stavros Sachtouris
            'Disconnect device from the network (can be repeated)',
756 7a3c66e1 Stavros Sachtouris
            '--device-id')
757 17cfc2f0 Stavros Sachtouris
    )
758 7a3c66e1 Stavros Sachtouris
    required = ('device_id', )
759 17cfc2f0 Stavros Sachtouris
760 fd981f77 Stavros Sachtouris
    @errors.generic.all
761 fd981f77 Stavros Sachtouris
    @errors.cyclades.connection
762 fd981f77 Stavros Sachtouris
    @errors.cyclades.network_id
763 fd981f77 Stavros Sachtouris
    @errors.cyclades.server_id
764 f3740b99 Stavros Sachtouris
    def _run(self, network_id, server_id):
765 f3740b99 Stavros Sachtouris
        vm = self._cyclades_client().get_server_details(server_id)
766 f3740b99 Stavros Sachtouris
        ports = [port for port in vm['attachments'] if (
767 7a3c66e1 Stavros Sachtouris
            port['network_id'] in (network_id, ))]
768 f3740b99 Stavros Sachtouris
        if not ports:
769 fd981f77 Stavros Sachtouris
            raiseCLIError('Network %s is not connected to device %s' % (
770 f3740b99 Stavros Sachtouris
                network_id, server_id))
771 f3740b99 Stavros Sachtouris
        for port in ports:
772 f3740b99 Stavros Sachtouris
            if self['wait']:
773 f3740b99 Stavros Sachtouris
                port['status'] = self.client.get_port_details(port['id'])[
774 f3740b99 Stavros Sachtouris
                    'status']
775 f3740b99 Stavros Sachtouris
            self.client.delete_port(port['id'])
776 f3740b99 Stavros Sachtouris
            self.error('Deleting port %s:' % port['id'])
777 f3740b99 Stavros Sachtouris
            self.print_dict(port)
778 17cfc2f0 Stavros Sachtouris
            if self['wait']:
779 f3740b99 Stavros Sachtouris
                try:
780 f3740b99 Stavros Sachtouris
                    self._wait(port['id'], port['status'])
781 f3740b99 Stavros Sachtouris
                except ClientError as ce:
782 f3740b99 Stavros Sachtouris
                    if ce.status not in (404, ):
783 f3740b99 Stavros Sachtouris
                        raise
784 f3740b99 Stavros Sachtouris
                    self.error('Port %s is deleted' % port['id'])
785 fd981f77 Stavros Sachtouris
786 7a3c66e1 Stavros Sachtouris
    def main(self, network_id):
787 fd981f77 Stavros Sachtouris
        super(self.__class__, self)._run()
788 7a3c66e1 Stavros Sachtouris
        for sid in self['device_id']:
789 7a3c66e1 Stavros Sachtouris
            self._run(network_id=network_id, server_id=sid)