Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / network.py @ 58f4caba

History | View | Annotate | Download (27.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 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 c77131f4 Stavros Sachtouris
        nets = self.client.list_networks(detail=True)
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 c77131f4 Stavros Sachtouris
        if not self['detail']:
127 7e57e590 Stavros Sachtouris
            nets = [dict(
128 c77131f4 Stavros Sachtouris
                _0_id=n['id'],
129 c77131f4 Stavros Sachtouris
                _1_name=n['name'],
130 c77131f4 Stavros Sachtouris
                _2_public='( %s )' % 'public' if (
131 c77131f4 Stavros Sachtouris
                    n.get('public', None)) else 'private') for n in nets]
132 c77131f4 Stavros Sachtouris
            kwargs = dict(title=('_0_id', '_1_name', '_2_public'))
133 c77131f4 Stavros Sachtouris
        else:
134 c77131f4 Stavros Sachtouris
            kwargs = dict()
135 cd40143a Stavros Sachtouris
        if self['more']:
136 cd40143a Stavros Sachtouris
            kwargs['out'] = StringIO()
137 cd40143a Stavros Sachtouris
            kwargs['title'] = ()
138 cd40143a Stavros Sachtouris
        self._print(nets, **kwargs)
139 cd40143a Stavros Sachtouris
        if self['more']:
140 cd40143a Stavros Sachtouris
            pager(kwargs['out'].getvalue())
141 d18e6439 Stavros Sachtouris
142 d18e6439 Stavros Sachtouris
    def main(self):
143 d18e6439 Stavros Sachtouris
        super(self.__class__, self)._run()
144 d18e6439 Stavros Sachtouris
        self._run()
145 cd40143a Stavros Sachtouris
146 cd40143a Stavros Sachtouris
147 cd40143a Stavros Sachtouris
@command(network_cmds)
148 5c433331 Stavros Sachtouris
class network_info(_init_network, _optional_json):
149 cd40143a Stavros Sachtouris
    """Get details about a network"""
150 cd40143a Stavros Sachtouris
151 cd40143a Stavros Sachtouris
    @errors.generic.all
152 cd40143a Stavros Sachtouris
    @errors.cyclades.connection
153 cd40143a Stavros Sachtouris
    @errors.cyclades.network_id
154 cd40143a Stavros Sachtouris
    def _run(self, network_id):
155 cd40143a Stavros Sachtouris
        net = self.client.get_network_details(network_id)
156 cd40143a Stavros Sachtouris
        self._print(net, self.print_dict)
157 cd40143a Stavros Sachtouris
158 cd40143a Stavros Sachtouris
    def main(self, network_id):
159 cd40143a Stavros Sachtouris
        super(self.__class__, self)._run()
160 cd40143a Stavros Sachtouris
        self._run(network_id=network_id)
161 49413939 Stavros Sachtouris
162 49413939 Stavros Sachtouris
163 264a13f7 Stavros Sachtouris
class NetworkTypeArgument(ValueArgument):
164 264a13f7 Stavros Sachtouris
165 1c366ac9 Stavros Sachtouris
    types = ('MAC_FILTERED', 'CUSTOM', 'IP_LESS_ROUTED', 'PHYSICAL_VLAN')
166 264a13f7 Stavros Sachtouris
167 264a13f7 Stavros Sachtouris
    @property
168 264a13f7 Stavros Sachtouris
    def value(self):
169 1c366ac9 Stavros Sachtouris
        return getattr(self, '_value', self.types[0])
170 264a13f7 Stavros Sachtouris
171 264a13f7 Stavros Sachtouris
    @value.setter
172 264a13f7 Stavros Sachtouris
    def value(self, new_value):
173 264a13f7 Stavros Sachtouris
        if new_value and new_value.upper() in self.types:
174 264a13f7 Stavros Sachtouris
            self._value = new_value.upper()
175 264a13f7 Stavros Sachtouris
        elif new_value:
176 264a13f7 Stavros Sachtouris
            raise CLIInvalidArgument(
177 264a13f7 Stavros Sachtouris
                'Invalid network type %s' % new_value, details=[
178 264a13f7 Stavros Sachtouris
                    'Valid types: %s' % ', '.join(self.types), ])
179 264a13f7 Stavros Sachtouris
180 264a13f7 Stavros Sachtouris
181 49413939 Stavros Sachtouris
@command(network_cmds)
182 67dfe4a2 Stavros Sachtouris
class network_create(_init_network, _optional_json):
183 1c366ac9 Stavros Sachtouris
    """Create a new network (default type: MAC_FILTERED)"""
184 49413939 Stavros Sachtouris
185 cd0927f7 Stavros Sachtouris
    arguments = dict(
186 cd0927f7 Stavros Sachtouris
        name=ValueArgument('Network name', '--name'),
187 cd0927f7 Stavros Sachtouris
        shared=FlagArgument(
188 264a13f7 Stavros Sachtouris
            'Make network shared (special privileges required)', '--shared'),
189 264a13f7 Stavros Sachtouris
        network_type=NetworkTypeArgument(
190 264a13f7 Stavros Sachtouris
            'Valid network types: %s' % (', '.join(NetworkTypeArgument.types)),
191 67dfe4a2 Stavros Sachtouris
            '--type')
192 49413939 Stavros Sachtouris
    )
193 49413939 Stavros Sachtouris
194 49413939 Stavros Sachtouris
    @errors.generic.all
195 49413939 Stavros Sachtouris
    @errors.cyclades.connection
196 cd0927f7 Stavros Sachtouris
    @errors.cyclades.network_type
197 cd0927f7 Stavros Sachtouris
    def _run(self, network_type):
198 49413939 Stavros Sachtouris
        net = self.client.create_network(
199 cd0927f7 Stavros Sachtouris
            network_type, name=self['name'], shared=self['shared'])
200 49413939 Stavros Sachtouris
        self._print(net, self.print_dict)
201 49413939 Stavros Sachtouris
202 264a13f7 Stavros Sachtouris
    def main(self):
203 49413939 Stavros Sachtouris
        super(self.__class__, self)._run()
204 264a13f7 Stavros Sachtouris
        self._run(network_type=self['network_type'])
205 aef3fa1f Stavros Sachtouris
206 aef3fa1f Stavros Sachtouris
207 aef3fa1f Stavros Sachtouris
@command(network_cmds)
208 5c433331 Stavros Sachtouris
class network_delete(_init_network, _optional_output_cmd):
209 aef3fa1f Stavros Sachtouris
    """Delete a network"""
210 aef3fa1f Stavros Sachtouris
211 aef3fa1f Stavros Sachtouris
    @errors.generic.all
212 aef3fa1f Stavros Sachtouris
    @errors.cyclades.connection
213 58602137 Stavros Sachtouris
    @errors.cyclades.network_id
214 aef3fa1f Stavros Sachtouris
    def _run(self, network_id):
215 aef3fa1f Stavros Sachtouris
        r = self.client.delete_network(network_id)
216 aef3fa1f Stavros Sachtouris
        self._optional_output(r)
217 aef3fa1f Stavros Sachtouris
218 aef3fa1f Stavros Sachtouris
    def main(self, network_id):
219 aef3fa1f Stavros Sachtouris
        super(self.__class__, self)._run()
220 aef3fa1f Stavros Sachtouris
        self._run(network_id=network_id)
221 58602137 Stavros Sachtouris
222 58602137 Stavros Sachtouris
223 58602137 Stavros Sachtouris
@command(network_cmds)
224 264a13f7 Stavros Sachtouris
class network_modify(_init_network, _optional_json):
225 264a13f7 Stavros Sachtouris
    """Modify network attributes"""
226 58602137 Stavros Sachtouris
227 264a13f7 Stavros Sachtouris
    arguments = dict(new_name=ValueArgument('Rename the network', '--name'))
228 264a13f7 Stavros Sachtouris
    required = ['new_name', ]
229 58602137 Stavros Sachtouris
230 58602137 Stavros Sachtouris
    @errors.generic.all
231 58602137 Stavros Sachtouris
    @errors.cyclades.connection
232 58602137 Stavros Sachtouris
    @errors.cyclades.network_id
233 58602137 Stavros Sachtouris
    def _run(self, network_id):
234 264a13f7 Stavros Sachtouris
        r = self.client.update_network(network_id, name=self['new_name'])
235 58602137 Stavros Sachtouris
        self._print(r, self.print_dict)
236 58602137 Stavros Sachtouris
237 58602137 Stavros Sachtouris
    def main(self, network_id):
238 58602137 Stavros Sachtouris
        super(self.__class__, self)._run()
239 58602137 Stavros Sachtouris
        self._run(network_id=network_id)
240 62c6652f Stavros Sachtouris
241 62c6652f Stavros Sachtouris
242 62c6652f Stavros Sachtouris
@command(subnet_cmds)
243 62c6652f Stavros Sachtouris
class subnet_list(_init_network, _optional_json, _name_filter, _id_filter):
244 62c6652f Stavros Sachtouris
    """List subnets
245 62c6652f Stavros Sachtouris
    Use filtering arguments (e.g., --name-like) to manage long server lists
246 62c6652f Stavros Sachtouris
    """
247 62c6652f Stavros Sachtouris
248 62c6652f Stavros Sachtouris
    arguments = dict(
249 62c6652f Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
250 62c6652f Stavros Sachtouris
        more=FlagArgument(
251 62c6652f Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
252 5c5eb675 Stavros Sachtouris
            '--more')
253 62c6652f Stavros Sachtouris
    )
254 62c6652f Stavros Sachtouris
255 62c6652f Stavros Sachtouris
    @errors.generic.all
256 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
257 62c6652f Stavros Sachtouris
    def _run(self):
258 62c6652f Stavros Sachtouris
        nets = self.client.list_subnets()
259 62c6652f Stavros Sachtouris
        nets = self._filter_by_name(nets)
260 62c6652f Stavros Sachtouris
        nets = self._filter_by_id(nets)
261 5c5eb675 Stavros Sachtouris
        if not self['detail']:
262 62c6652f Stavros Sachtouris
            nets = [dict(
263 c77131f4 Stavros Sachtouris
                _0_id=n['id'],
264 c77131f4 Stavros Sachtouris
                _1_name=n['name'],
265 c77131f4 Stavros Sachtouris
                _2_net='( of network %s )' % n['network_id']) for n in nets]
266 c77131f4 Stavros Sachtouris
            kwargs = dict(title=('_0_id', '_1_name', '_2_net'))
267 c77131f4 Stavros Sachtouris
        else:
268 c77131f4 Stavros Sachtouris
            kwargs = dict()
269 62c6652f Stavros Sachtouris
        if self['more']:
270 62c6652f Stavros Sachtouris
            kwargs['out'] = StringIO()
271 62c6652f Stavros Sachtouris
            kwargs['title'] = ()
272 62c6652f Stavros Sachtouris
        self._print(nets, **kwargs)
273 62c6652f Stavros Sachtouris
        if self['more']:
274 62c6652f Stavros Sachtouris
            pager(kwargs['out'].getvalue())
275 62c6652f Stavros Sachtouris
276 62c6652f Stavros Sachtouris
    def main(self):
277 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
278 62c6652f Stavros Sachtouris
        self._run()
279 62c6652f Stavros Sachtouris
280 62c6652f Stavros Sachtouris
281 62c6652f Stavros Sachtouris
@command(subnet_cmds)
282 62c6652f Stavros Sachtouris
class subnet_info(_init_network, _optional_json):
283 62c6652f Stavros Sachtouris
    """Get details about a subnet"""
284 62c6652f Stavros Sachtouris
285 62c6652f Stavros Sachtouris
    @errors.generic.all
286 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
287 62c6652f Stavros Sachtouris
    def _run(self, subnet_id):
288 62c6652f Stavros Sachtouris
        net = self.client.get_subnet_details(subnet_id)
289 62c6652f Stavros Sachtouris
        self._print(net, self.print_dict)
290 62c6652f Stavros Sachtouris
291 62c6652f Stavros Sachtouris
    def main(self, subnet_id):
292 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
293 62c6652f Stavros Sachtouris
        self._run(subnet_id=subnet_id)
294 62c6652f Stavros Sachtouris
295 62c6652f Stavros Sachtouris
296 62c6652f Stavros Sachtouris
class AllocationPoolArgument(RepeatableArgument):
297 62c6652f Stavros Sachtouris
298 62c6652f Stavros Sachtouris
    @property
299 62c6652f Stavros Sachtouris
    def value(self):
300 62c6652f Stavros Sachtouris
        return super(AllocationPoolArgument, self).value or []
301 62c6652f Stavros Sachtouris
302 62c6652f Stavros Sachtouris
    @value.setter
303 62c6652f Stavros Sachtouris
    def value(self, new_pools):
304 7a3c66e1 Stavros Sachtouris
        if not new_pools:
305 7a3c66e1 Stavros Sachtouris
            return
306 62c6652f Stavros Sachtouris
        new_list = []
307 62c6652f Stavros Sachtouris
        for pool in new_pools:
308 62c6652f Stavros Sachtouris
            start, comma, end = pool.partition(',')
309 62c6652f Stavros Sachtouris
            if not (start and comma and end):
310 62c6652f Stavros Sachtouris
                raise CLIInvalidArgument(
311 62c6652f Stavros Sachtouris
                    'Invalid allocation pool argument %s' % pool, details=[
312 62c6652f Stavros Sachtouris
                    'Allocation values must be of the form:',
313 62c6652f Stavros Sachtouris
                    '  <start address>,<end address>'])
314 62c6652f Stavros Sachtouris
            new_list.append(dict(start=start, end=end))
315 62c6652f Stavros Sachtouris
        self._value = new_list
316 62c6652f Stavros Sachtouris
317 62c6652f Stavros Sachtouris
318 62c6652f Stavros Sachtouris
@command(subnet_cmds)
319 62c6652f Stavros Sachtouris
class subnet_create(_init_network, _optional_json):
320 264a13f7 Stavros Sachtouris
    """Create a new subnet"""
321 62c6652f Stavros Sachtouris
322 62c6652f Stavros Sachtouris
    arguments = dict(
323 62c6652f Stavros Sachtouris
        name=ValueArgument('Subnet name', '--name'),
324 62c6652f Stavros Sachtouris
        allocation_pools=AllocationPoolArgument(
325 62c6652f Stavros Sachtouris
            'start_address,end_address of allocation pool (can be repeated)'
326 62c6652f Stavros Sachtouris
            ' e.g., --alloc-pool=123.45.67.1,123.45.67.8',
327 62c6652f Stavros Sachtouris
            '--alloc-pool'),
328 62c6652f Stavros Sachtouris
        gateway=ValueArgument('Gateway IP', '--gateway'),
329 62c6652f Stavros Sachtouris
        subnet_id=ValueArgument('The id for the subnet', '--id'),
330 62c6652f Stavros Sachtouris
        ipv6=FlagArgument('If set, IP version is set to 6, else 4', '--ipv6'),
331 264a13f7 Stavros Sachtouris
        enable_dhcp=FlagArgument('Enable dhcp (default: off)', '--with-dhcp'),
332 264a13f7 Stavros Sachtouris
        network_id=ValueArgument('Set the network ID', '--network-id'),
333 264a13f7 Stavros Sachtouris
        cidr=ValueArgument('Set the CIDR', '--cidr')
334 62c6652f Stavros Sachtouris
    )
335 264a13f7 Stavros Sachtouris
    required = ('network_id', 'cidr')
336 62c6652f Stavros Sachtouris
337 62c6652f Stavros Sachtouris
    @errors.generic.all
338 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
339 62c6652f Stavros Sachtouris
    @errors.cyclades.network_id
340 62c6652f Stavros Sachtouris
    def _run(self, network_id, cidr):
341 62c6652f Stavros Sachtouris
        net = self.client.create_subnet(
342 62c6652f Stavros Sachtouris
            network_id, cidr,
343 62c6652f Stavros Sachtouris
            self['name'], self['allocation_pools'], self['gateway'],
344 62c6652f Stavros Sachtouris
            self['subnet_id'], self['ipv6'], self['enable_dhcp'])
345 62c6652f Stavros Sachtouris
        self._print(net, self.print_dict)
346 62c6652f Stavros Sachtouris
347 264a13f7 Stavros Sachtouris
    def main(self):
348 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
349 264a13f7 Stavros Sachtouris
        self._run(network_id=self['network_id'], cidr=self['cidr'])
350 62c6652f Stavros Sachtouris
351 62c6652f Stavros Sachtouris
352 62c6652f Stavros Sachtouris
# @command(subnet_cmds)
353 62c6652f Stavros Sachtouris
# class subnet_delete(_init_network, _optional_output_cmd):
354 62c6652f Stavros Sachtouris
#     """Delete a subnet"""
355 62c6652f Stavros Sachtouris
356 62c6652f Stavros Sachtouris
#     @errors.generic.all
357 62c6652f Stavros Sachtouris
#     @errors.cyclades.connection
358 62c6652f Stavros Sachtouris
#     def _run(self, subnet_id):
359 62c6652f Stavros Sachtouris
#         r = self.client.delete_subnet(subnet_id)
360 62c6652f Stavros Sachtouris
#         self._optional_output(r)
361 62c6652f Stavros Sachtouris
362 62c6652f Stavros Sachtouris
#     def main(self, subnet_id):
363 62c6652f Stavros Sachtouris
#         super(self.__class__, self)._run()
364 62c6652f Stavros Sachtouris
#         self._run(subnet_id=subnet_id)
365 62c6652f Stavros Sachtouris
366 62c6652f Stavros Sachtouris
367 62c6652f Stavros Sachtouris
@command(subnet_cmds)
368 264a13f7 Stavros Sachtouris
class subnet_modify(_init_network, _optional_json):
369 264a13f7 Stavros Sachtouris
    """Modify the attributes of a subnet"""
370 62c6652f Stavros Sachtouris
371 264a13f7 Stavros Sachtouris
    arguments = dict(
372 264a13f7 Stavros Sachtouris
        new_name=ValueArgument('New name of the subnet', '--name')
373 264a13f7 Stavros Sachtouris
    )
374 264a13f7 Stavros Sachtouris
    required = ['new_name']
375 62c6652f Stavros Sachtouris
376 62c6652f Stavros Sachtouris
    @errors.generic.all
377 62c6652f Stavros Sachtouris
    @errors.cyclades.connection
378 62c6652f Stavros Sachtouris
    def _run(self, subnet_id):
379 2da652e2 Stavros Sachtouris
        r = self.client.update_subnet(subnet_id, name=self['new_name'])
380 62c6652f Stavros Sachtouris
        self._print(r, self.print_dict)
381 62c6652f Stavros Sachtouris
382 62c6652f Stavros Sachtouris
    def main(self, subnet_id):
383 62c6652f Stavros Sachtouris
        super(self.__class__, self)._run()
384 62c6652f Stavros Sachtouris
        self._run(subnet_id=subnet_id)
385 447365fe Stavros Sachtouris
386 447365fe Stavros Sachtouris
387 447365fe Stavros Sachtouris
@command(port_cmds)
388 f3740b99 Stavros Sachtouris
class port_list(_init_network, _optional_json, _name_filter, _id_filter):
389 11cc86af Stavros Sachtouris
    """List all ports"""
390 447365fe Stavros Sachtouris
391 f3740b99 Stavros Sachtouris
    arguments = dict(
392 f3740b99 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
393 f3740b99 Stavros Sachtouris
        more=FlagArgument(
394 f3740b99 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
395 f3740b99 Stavros Sachtouris
            '--more'),
396 f3740b99 Stavros Sachtouris
        user_id=ValueArgument(
397 f3740b99 Stavros Sachtouris
            'show only networks belonging to user with this id', '--user-id')
398 f3740b99 Stavros Sachtouris
    )
399 f3740b99 Stavros Sachtouris
400 447365fe Stavros Sachtouris
    @errors.generic.all
401 447365fe Stavros Sachtouris
    @errors.cyclades.connection
402 11cc86af Stavros Sachtouris
    def _run(self):
403 f3740b99 Stavros Sachtouris
        detail = bool(self['detail'] or self['user_id'])
404 f3740b99 Stavros Sachtouris
        ports = self.client.list_ports(detail=detail)
405 f3740b99 Stavros Sachtouris
        ports = self._filter_by_user_id(ports)
406 f3740b99 Stavros Sachtouris
        ports = self._filter_by_name(ports)
407 f3740b99 Stavros Sachtouris
        ports = self._filter_by_id(ports)
408 f3740b99 Stavros Sachtouris
        if detail and not self['detail']:
409 f3740b99 Stavros Sachtouris
            ports = [dict(
410 f3740b99 Stavros Sachtouris
                id=p['id'], name=p['name'], links=p['links']) for p in ports]
411 f3740b99 Stavros Sachtouris
        kwargs = dict()
412 f3740b99 Stavros Sachtouris
        if self['more']:
413 f3740b99 Stavros Sachtouris
            kwargs['out'] = StringIO()
414 f3740b99 Stavros Sachtouris
            kwargs['title'] = ()
415 f3740b99 Stavros Sachtouris
        self._print(ports, **kwargs)
416 f3740b99 Stavros Sachtouris
        if self['more']:
417 f3740b99 Stavros Sachtouris
            pager(kwargs['out'].getvalue())
418 447365fe Stavros Sachtouris
419 11cc86af Stavros Sachtouris
    def main(self):
420 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
421 11cc86af Stavros Sachtouris
        self._run()
422 447365fe Stavros Sachtouris
423 447365fe Stavros Sachtouris
424 447365fe Stavros Sachtouris
@command(port_cmds)
425 447365fe Stavros Sachtouris
class port_info(_init_network, _optional_json):
426 447365fe Stavros Sachtouris
    """Get details about a port"""
427 447365fe Stavros Sachtouris
428 447365fe Stavros Sachtouris
    @errors.generic.all
429 447365fe Stavros Sachtouris
    @errors.cyclades.connection
430 447365fe Stavros Sachtouris
    def _run(self, port_id):
431 f3740b99 Stavros Sachtouris
        port = self.client.get_port_details(port_id)
432 f3740b99 Stavros Sachtouris
        self._print(port, self.print_dict)
433 447365fe Stavros Sachtouris
434 447365fe Stavros Sachtouris
    def main(self, port_id):
435 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
436 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
437 447365fe Stavros Sachtouris
438 447365fe Stavros Sachtouris
439 447365fe Stavros Sachtouris
@command(port_cmds)
440 f261965c Stavros Sachtouris
class port_delete(_init_network, _optional_output_cmd, _port_wait):
441 264a13f7 Stavros Sachtouris
    """Delete a port (== disconnect server from network)"""
442 447365fe Stavros Sachtouris
443 f261965c Stavros Sachtouris
    arguments = dict(
444 f261965c Stavros Sachtouris
        wait=FlagArgument('Wait port to be established', ('-w', '--wait'))
445 f261965c Stavros Sachtouris
    )
446 f261965c Stavros Sachtouris
447 447365fe Stavros Sachtouris
    @errors.generic.all
448 447365fe Stavros Sachtouris
    @errors.cyclades.connection
449 447365fe Stavros Sachtouris
    def _run(self, port_id):
450 f3740b99 Stavros Sachtouris
        if self['wait']:
451 f3740b99 Stavros Sachtouris
            status = self.client.get_port_details(port_id)['status']
452 447365fe Stavros Sachtouris
        r = self.client.delete_port(port_id)
453 f261965c Stavros Sachtouris
        if self['wait']:
454 f3740b99 Stavros Sachtouris
            try:
455 f3740b99 Stavros Sachtouris
                self._wait(port_id, status)
456 f3740b99 Stavros Sachtouris
            except ClientError as ce:
457 f3740b99 Stavros Sachtouris
                if ce.status not in (404, ):
458 f3740b99 Stavros Sachtouris
                    raise
459 f3740b99 Stavros Sachtouris
                self.error('Port %s is deleted' % port_id)
460 447365fe Stavros Sachtouris
        self._optional_output(r)
461 447365fe Stavros Sachtouris
462 447365fe Stavros Sachtouris
    def main(self, port_id):
463 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
464 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
465 447365fe Stavros Sachtouris
466 447365fe Stavros Sachtouris
467 447365fe Stavros Sachtouris
@command(port_cmds)
468 264a13f7 Stavros Sachtouris
class port_modify(_init_network, _optional_json):
469 264a13f7 Stavros Sachtouris
    """Modify the attributes of a port"""
470 447365fe Stavros Sachtouris
471 264a13f7 Stavros Sachtouris
    arguments = dict(new_name=ValueArgument('New name of the port', '--name'))
472 264a13f7 Stavros Sachtouris
    required = ['new_name', ]
473 447365fe Stavros Sachtouris
474 447365fe Stavros Sachtouris
    @errors.generic.all
475 447365fe Stavros Sachtouris
    @errors.cyclades.connection
476 447365fe Stavros Sachtouris
    def _run(self, port_id):
477 447365fe Stavros Sachtouris
        r = self.client.get_port_details(port_id)
478 447365fe Stavros Sachtouris
        r = self.client.update_port(
479 264a13f7 Stavros Sachtouris
            port_id, r['network_id'], name=self['new_name'])
480 447365fe Stavros Sachtouris
        self._print(r, self.print_dict)
481 447365fe Stavros Sachtouris
482 447365fe Stavros Sachtouris
    def main(self, port_id):
483 447365fe Stavros Sachtouris
        super(self.__class__, self)._run()
484 447365fe Stavros Sachtouris
        self._run(port_id=port_id)
485 447365fe Stavros Sachtouris
486 447365fe Stavros Sachtouris
487 dbf65aaf Stavros Sachtouris
class PortStatusArgument(ValueArgument):
488 dbf65aaf Stavros Sachtouris
489 dbf65aaf Stavros Sachtouris
    valid = ('BUILD', 'ACTIVE', 'DOWN', 'ERROR')
490 dbf65aaf Stavros Sachtouris
491 dbf65aaf Stavros Sachtouris
    @property
492 dbf65aaf Stavros Sachtouris
    def value(self):
493 dbf65aaf Stavros Sachtouris
        return getattr(self, '_value', None)
494 dbf65aaf Stavros Sachtouris
495 dbf65aaf Stavros Sachtouris
    @value.setter
496 dbf65aaf Stavros Sachtouris
    def value(self, new_status):
497 dbf65aaf Stavros Sachtouris
        if new_status:
498 dbf65aaf Stavros Sachtouris
            new_status = new_status.upper()
499 dbf65aaf Stavros Sachtouris
            if new_status in self.valid:
500 dbf65aaf Stavros Sachtouris
                raise CLIInvalidArgument(
501 dbf65aaf Stavros Sachtouris
                    'Invalid argument %s' % new_status, details=[
502 dbf65aaf Stavros Sachtouris
                    'Status valid values: %s'] % ', '.join(self.valid))
503 dbf65aaf Stavros Sachtouris
            self._value = new_status
504 dbf65aaf Stavros Sachtouris
505 dbf65aaf Stavros Sachtouris
506 17cfc2f0 Stavros Sachtouris
class _port_create(_init_network, _optional_json, _port_wait):
507 fd981f77 Stavros Sachtouris
508 17cfc2f0 Stavros Sachtouris
    def connect(self, network_id, device_id):
509 909ae594 Stavros Sachtouris
        fixed_ips = [dict(ip_address=self['ip_address'])] if (
510 cc5da5a5 Stavros Sachtouris
            self['ip_address']) else None
511 909ae594 Stavros Sachtouris
        if fixed_ips and self['subnet_id']:
512 909ae594 Stavros Sachtouris
            fixed_ips[0]['subnet_id'] = self['subnet_id']
513 fd981f77 Stavros Sachtouris
        r = self.client.create_port(
514 fd981f77 Stavros Sachtouris
            network_id, device_id,
515 fd981f77 Stavros Sachtouris
            name=self['name'],
516 fd981f77 Stavros Sachtouris
            security_groups=self['security_group_id'],
517 fd981f77 Stavros Sachtouris
            fixed_ips=fixed_ips)
518 fd981f77 Stavros Sachtouris
        if self['wait']:
519 fd981f77 Stavros Sachtouris
            self._wait(r['id'], r['status'])
520 f3740b99 Stavros Sachtouris
            r = self.client.get_port_details(r['id'])
521 f3740b99 Stavros Sachtouris
        self._print([r])
522 fd981f77 Stavros Sachtouris
523 fd981f77 Stavros Sachtouris
524 ccdd1b82 Stavros Sachtouris
@command(port_cmds)
525 f25bd53b Stavros Sachtouris
class port_create(_port_create):
526 264a13f7 Stavros Sachtouris
    """Create a new port (== connect server to network)"""
527 ccdd1b82 Stavros Sachtouris
528 ccdd1b82 Stavros Sachtouris
    arguments = dict(
529 b7d79306 Stavros Sachtouris
        name=ValueArgument('A human readable name', '--name'),
530 ccdd1b82 Stavros Sachtouris
        security_group_id=RepeatableArgument(
531 ccdd1b82 Stavros Sachtouris
            'Add a security group id (can be repeated)',
532 b7d79306 Stavros Sachtouris
            ('-g', '--security-group')),
533 b7d79306 Stavros Sachtouris
        subnet_id=ValueArgument(
534 b7d79306 Stavros Sachtouris
            'Subnet id for fixed ips (used with --ip-address)',
535 b7d79306 Stavros Sachtouris
            '--subnet-id'),
536 b7d79306 Stavros Sachtouris
        ip_address=ValueArgument(
537 909ae594 Stavros Sachtouris
            'IP address for subnet id', '--ip-address'),
538 264a13f7 Stavros Sachtouris
        network_id=ValueArgument('Set the network ID', '--network-id'),
539 264a13f7 Stavros Sachtouris
        device_id=ValueArgument(
540 264a13f7 Stavros Sachtouris
            'The device is either a virtual server or a virtual router',
541 c6afee48 Stavros Sachtouris
            '--device-id'),
542 c6afee48 Stavros Sachtouris
        wait=FlagArgument('Wait port to be established', ('-w', '--wait')),
543 ccdd1b82 Stavros Sachtouris
    )
544 e3f54dc0 Stavros Sachtouris
    required = ('network_id', 'device_id')
545 ccdd1b82 Stavros Sachtouris
546 17cfc2f0 Stavros Sachtouris
    @errors.generic.all
547 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.connection
548 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.network_id
549 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.server_id
550 17cfc2f0 Stavros Sachtouris
    def _run(self, network_id, server_id):
551 17cfc2f0 Stavros Sachtouris
        self.connect(network_id, server_id)
552 17cfc2f0 Stavros Sachtouris
553 264a13f7 Stavros Sachtouris
    def main(self):
554 ccdd1b82 Stavros Sachtouris
        super(self.__class__, self)._run()
555 17cfc2f0 Stavros Sachtouris
        self._run(network_id=self['network_id'], server_id=self['device_id'])
556 264a13f7 Stavros Sachtouris
557 264a13f7 Stavros Sachtouris
558 c6afee48 Stavros Sachtouris
@command(port_cmds)
559 c6afee48 Stavros Sachtouris
class port_wait(_init_network, _port_wait):
560 67dfe4a2 Stavros Sachtouris
    """Wait for port to finish [ACTIVE, DOWN, BUILD, ERROR]"""
561 c6afee48 Stavros Sachtouris
562 c6afee48 Stavros Sachtouris
    arguments = dict(
563 dbf65aaf Stavros Sachtouris
        current_status=PortStatusArgument(
564 dbf65aaf Stavros Sachtouris
            'Wait while in this status', '--status'),
565 c6afee48 Stavros Sachtouris
        timeout=IntArgument(
566 c6afee48 Stavros Sachtouris
            'Wait limit in seconds (default: 60)', '--timeout', default=60)
567 c6afee48 Stavros Sachtouris
    )
568 c6afee48 Stavros Sachtouris
569 c6afee48 Stavros Sachtouris
    @errors.generic.all
570 c6afee48 Stavros Sachtouris
    @errors.cyclades.connection
571 c6afee48 Stavros Sachtouris
    def _run(self, port_id, current_status):
572 c6afee48 Stavros Sachtouris
        port = self.client.get_port_details(port_id)
573 c6afee48 Stavros Sachtouris
        if port['status'].lower() == current_status.lower():
574 c6afee48 Stavros Sachtouris
            self._wait(port_id, current_status, timeout=self['timeout'])
575 c6afee48 Stavros Sachtouris
        else:
576 c6afee48 Stavros Sachtouris
            self.error(
577 c6afee48 Stavros Sachtouris
                'Port %s: Cannot wait for status %s, '
578 c6afee48 Stavros Sachtouris
                'status is already %s' % (
579 c6afee48 Stavros Sachtouris
                    port_id, current_status, port['status']))
580 c6afee48 Stavros Sachtouris
581 dbf65aaf Stavros Sachtouris
    def main(self, port_id):
582 c6afee48 Stavros Sachtouris
        super(self.__class__, self)._run()
583 dbf65aaf Stavros Sachtouris
        current_status = self['current_status'] or self.arguments[
584 dbf65aaf Stavros Sachtouris
            'current_status'].valid[0]
585 c6afee48 Stavros Sachtouris
        self._run(port_id=port_id, current_status=current_status)
586 c6afee48 Stavros Sachtouris
587 c6afee48 Stavros Sachtouris
588 d1bced10 Stavros Sachtouris
@command(ip_cmds)
589 d1bced10 Stavros Sachtouris
class ip_list(_init_network, _optional_json):
590 d1bced10 Stavros Sachtouris
    """List reserved floating IPs"""
591 d1bced10 Stavros Sachtouris
592 d1bced10 Stavros Sachtouris
    @errors.generic.all
593 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
594 d1bced10 Stavros Sachtouris
    def _run(self):
595 d1bced10 Stavros Sachtouris
        self._print(self.client.list_floatingips())
596 d1bced10 Stavros Sachtouris
597 d1bced10 Stavros Sachtouris
    def main(self):
598 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
599 d1bced10 Stavros Sachtouris
        self._run()
600 d1bced10 Stavros Sachtouris
601 d1bced10 Stavros Sachtouris
602 d1bced10 Stavros Sachtouris
@command(ip_cmds)
603 d1bced10 Stavros Sachtouris
class ip_info(_init_network, _optional_json):
604 d1bced10 Stavros Sachtouris
    """Get details on a floating IP"""
605 d1bced10 Stavros Sachtouris
606 d1bced10 Stavros Sachtouris
    @errors.generic.all
607 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
608 d1bced10 Stavros Sachtouris
    def _run(self, ip_id):
609 291cab21 Stavros Sachtouris
        self._print(
610 291cab21 Stavros Sachtouris
            self.client.get_floatingip_details(ip_id), self.print_dict)
611 d1bced10 Stavros Sachtouris
612 d1bced10 Stavros Sachtouris
    def main(self, ip_id):
613 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
614 d1bced10 Stavros Sachtouris
        self._run(ip_id=ip_id)
615 d1bced10 Stavros Sachtouris
616 d1bced10 Stavros Sachtouris
617 d1bced10 Stavros Sachtouris
@command(ip_cmds)
618 d1bced10 Stavros Sachtouris
class ip_create(_init_network, _optional_json):
619 d1bced10 Stavros Sachtouris
    """Reserve an IP on a network"""
620 264a13f7 Stavros Sachtouris
621 d1bced10 Stavros Sachtouris
    arguments = dict(
622 d1bced10 Stavros Sachtouris
        network_id=ValueArgument(
623 d1bced10 Stavros Sachtouris
            'The network to preserve the IP on', '--network-id'),
624 cc5da5a5 Stavros Sachtouris
        ip_address=ValueArgument('Allocate an IP address', '--address')
625 d1bced10 Stavros Sachtouris
    )
626 d1bced10 Stavros Sachtouris
    required = ('network_id', )
627 d1bced10 Stavros Sachtouris
628 d1bced10 Stavros Sachtouris
    @errors.generic.all
629 d1bced10 Stavros Sachtouris
    @errors.cyclades.connection
630 d1bced10 Stavros Sachtouris
    @errors.cyclades.network_id
631 d1bced10 Stavros Sachtouris
    def _run(self, network_id):
632 d1bced10 Stavros Sachtouris
        self._print(
633 d1bced10 Stavros Sachtouris
            self.client.create_floatingip(
634 d1bced10 Stavros Sachtouris
                network_id, floating_ip_address=self['ip_address']),
635 d1bced10 Stavros Sachtouris
            self.print_dict)
636 d1bced10 Stavros Sachtouris
637 d1bced10 Stavros Sachtouris
    def main(self):
638 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
639 d1bced10 Stavros Sachtouris
        self._run(network_id=self['network_id'])
640 d1bced10 Stavros Sachtouris
641 d1bced10 Stavros Sachtouris
642 d1bced10 Stavros Sachtouris
@command(ip_cmds)
643 d1bced10 Stavros Sachtouris
class ip_delete(_init_network, _optional_output_cmd):
644 d1bced10 Stavros Sachtouris
    """Unreserve an IP (also delete the port, if attached)"""
645 d1bced10 Stavros Sachtouris
646 d1bced10 Stavros Sachtouris
    def _run(self, ip_id):
647 291cab21 Stavros Sachtouris
        self._optional_output(self.client.delete_floatingip(ip_id))
648 d1bced10 Stavros Sachtouris
649 d1bced10 Stavros Sachtouris
    def main(self, ip_id):
650 d1bced10 Stavros Sachtouris
        super(self.__class__, self)._run()
651 d1bced10 Stavros Sachtouris
        self._run(ip_id=ip_id)
652 d1bced10 Stavros Sachtouris
653 d1bced10 Stavros Sachtouris
654 cc5da5a5 Stavros Sachtouris
@command(ip_cmds)
655 cc5da5a5 Stavros Sachtouris
class ip_attach(_port_create):
656 cc5da5a5 Stavros Sachtouris
    """Attach an IP on a virtual server"""
657 cc5da5a5 Stavros Sachtouris
658 cc5da5a5 Stavros Sachtouris
    arguments = dict(
659 cc5da5a5 Stavros Sachtouris
        name=ValueArgument('A human readable name for the port', '--name'),
660 cc5da5a5 Stavros Sachtouris
        security_group_id=RepeatableArgument(
661 cc5da5a5 Stavros Sachtouris
            'Add a security group id (can be repeated)',
662 cc5da5a5 Stavros Sachtouris
            ('-g', '--security-group')),
663 cc5da5a5 Stavros Sachtouris
        subnet_id=ValueArgument('Subnet id', '--subnet-id'),
664 cc5da5a5 Stavros Sachtouris
        wait=FlagArgument('Wait IP to be attached', ('-w', '--wait')),
665 cc5da5a5 Stavros Sachtouris
        server_id=ValueArgument(
666 cc5da5a5 Stavros Sachtouris
            'Server to attach to this IP', '--server-id')
667 cc5da5a5 Stavros Sachtouris
    )
668 cc5da5a5 Stavros Sachtouris
    required = ('server_id', )
669 cc5da5a5 Stavros Sachtouris
670 cc5da5a5 Stavros Sachtouris
    @errors.generic.all
671 cc5da5a5 Stavros Sachtouris
    @errors.cyclades.connection
672 cc5da5a5 Stavros Sachtouris
    @errors.cyclades.server_id
673 58f4caba Stavros Sachtouris
    def _run(self, ip_or_ip_id, server_id):
674 cc5da5a5 Stavros Sachtouris
        netid = None
675 cc5da5a5 Stavros Sachtouris
        for ip in self.client.list_floatingips():
676 58f4caba Stavros Sachtouris
            if ip_or_ip_id in (ip['floating_ip_address'], ip['id']):
677 cc5da5a5 Stavros Sachtouris
                netid = ip['floating_network_id']
678 cc5da5a5 Stavros Sachtouris
                iparg = ValueArgument(parsed_name='--ip')
679 58f4caba Stavros Sachtouris
                iparg.value = ip['floating_ip_address']
680 cc5da5a5 Stavros Sachtouris
                self.arguments['ip_address'] = iparg
681 cc5da5a5 Stavros Sachtouris
                break
682 cc5da5a5 Stavros Sachtouris
        if netid:
683 cc5da5a5 Stavros Sachtouris
            self.error('Creating a port to attach IP %s to server %s' % (
684 58f4caba Stavros Sachtouris
                ip_or_ip_id, server_id))
685 cc5da5a5 Stavros Sachtouris
            self.connect(netid, server_id)
686 cc5da5a5 Stavros Sachtouris
        else:
687 cc5da5a5 Stavros Sachtouris
            raiseCLIError(
688 58f4caba Stavros Sachtouris
                '%s does not match any reserved IPs or IP ids' % ip_or_ip_id,
689 cc5da5a5 Stavros Sachtouris
                details=[
690 cc5da5a5 Stavros Sachtouris
                    'To reserve an IP:', '  [kamaki] ip create',
691 cc5da5a5 Stavros Sachtouris
                    'To see all reserved IPs:', '  [kamaki] ip list'])
692 cc5da5a5 Stavros Sachtouris
693 58f4caba Stavros Sachtouris
    def main(self, ip_or_ip_id):
694 cc5da5a5 Stavros Sachtouris
        super(self.__class__, self)._run()
695 58f4caba Stavros Sachtouris
        self._run(ip_or_ip_id=ip_or_ip_id, server_id=self['server_id'])
696 cc5da5a5 Stavros Sachtouris
697 cc5da5a5 Stavros Sachtouris
698 cc5da5a5 Stavros Sachtouris
@command(ip_cmds)
699 cc5da5a5 Stavros Sachtouris
class ip_detach(_init_network, _port_wait, _optional_json):
700 cc5da5a5 Stavros Sachtouris
    """Detach an IP from a virtual server"""
701 cc5da5a5 Stavros Sachtouris
702 cc5da5a5 Stavros Sachtouris
    arguments = dict(
703 cc5da5a5 Stavros Sachtouris
        wait=FlagArgument('Wait network to disconnect', ('-w', '--wait')),
704 cc5da5a5 Stavros Sachtouris
    )
705 cc5da5a5 Stavros Sachtouris
706 cc5da5a5 Stavros Sachtouris
    @errors.generic.all
707 cc5da5a5 Stavros Sachtouris
    @errors.cyclades.connection
708 58f4caba Stavros Sachtouris
    def _run(self, ip_or_ip_id):
709 cc5da5a5 Stavros Sachtouris
        for ip in self.client.list_floatingips():
710 58f4caba Stavros Sachtouris
            if ip_or_ip_id in (ip['floating_ip_address'], ip['id']):
711 cc5da5a5 Stavros Sachtouris
                if not ip['port_id']:
712 58f4caba Stavros Sachtouris
                    raiseCLIError('IP %s is not attached' % ip_or_ip_id)
713 cc5da5a5 Stavros Sachtouris
                self.error('Deleting port %s:' % ip['port_id'])
714 cc5da5a5 Stavros Sachtouris
                self.client.delete_port(ip['port_id'])
715 cc5da5a5 Stavros Sachtouris
                if self['wait']:
716 cc5da5a5 Stavros Sachtouris
                    port_status = self.client.get_port_details(ip['port_id'])[
717 cc5da5a5 Stavros Sachtouris
                        'status']
718 cc5da5a5 Stavros Sachtouris
                    try:
719 cc5da5a5 Stavros Sachtouris
                        self._wait(ip['port_id'], port_status)
720 cc5da5a5 Stavros Sachtouris
                    except ClientError as ce:
721 cc5da5a5 Stavros Sachtouris
                        if ce.status not in (404, ):
722 cc5da5a5 Stavros Sachtouris
                            raise
723 cc5da5a5 Stavros Sachtouris
                        self.error('Port %s is deleted' % ip['port_id'])
724 cc5da5a5 Stavros Sachtouris
                return
725 58f4caba Stavros Sachtouris
        raiseCLIError('IP or IP id %s not found' % ip_or_ip_id)
726 cc5da5a5 Stavros Sachtouris
727 58f4caba Stavros Sachtouris
    def main(self, ip_or_ip_id):
728 cc5da5a5 Stavros Sachtouris
        super(self.__class__, self)._run()
729 58f4caba Stavros Sachtouris
        self._run(ip_or_ip_id)
730 cc5da5a5 Stavros Sachtouris
731 cc5da5a5 Stavros Sachtouris
732 d1bced10 Stavros Sachtouris
#  Warn users for some importand changes
733 264a13f7 Stavros Sachtouris
734 264a13f7 Stavros Sachtouris
@command(network_cmds)
735 fd981f77 Stavros Sachtouris
class network_connect(_port_create):
736 fd981f77 Stavros Sachtouris
    """Connect a network with a device (server or router)"""
737 264a13f7 Stavros Sachtouris
738 fd981f77 Stavros Sachtouris
    arguments = dict(
739 17cfc2f0 Stavros Sachtouris
        name=ValueArgument('A human readable name for the port', '--name'),
740 fd981f77 Stavros Sachtouris
        security_group_id=RepeatableArgument(
741 fd981f77 Stavros Sachtouris
            'Add a security group id (can be repeated)',
742 fd981f77 Stavros Sachtouris
            ('-g', '--security-group')),
743 fd981f77 Stavros Sachtouris
        subnet_id=ValueArgument(
744 fd981f77 Stavros Sachtouris
            'Subnet id for fixed ips (used with --ip-address)',
745 fd981f77 Stavros Sachtouris
            '--subnet-id'),
746 fd981f77 Stavros Sachtouris
        ip_address=ValueArgument(
747 fd981f77 Stavros Sachtouris
            'IP address for subnet id (used with --subnet-id', '--ip-address'),
748 17cfc2f0 Stavros Sachtouris
        wait=FlagArgument('Wait network to connect', ('-w', '--wait')),
749 7a3c66e1 Stavros Sachtouris
        device_id=RepeatableArgument(
750 7a3c66e1 Stavros Sachtouris
            'Connect this device to the network (can be repeated)',
751 7a3c66e1 Stavros Sachtouris
            '--device-id')
752 fd981f77 Stavros Sachtouris
    )
753 7a3c66e1 Stavros Sachtouris
    required = ('device_id', )
754 fd981f77 Stavros Sachtouris
755 17cfc2f0 Stavros Sachtouris
    @errors.generic.all
756 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.connection
757 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.network_id
758 17cfc2f0 Stavros Sachtouris
    @errors.cyclades.server_id
759 17cfc2f0 Stavros Sachtouris
    def _run(self, network_id, server_id):
760 f3740b99 Stavros Sachtouris
        self.error('Creating a port to connect network %s with device %s' % (
761 f3740b99 Stavros Sachtouris
            network_id, server_id))
762 17cfc2f0 Stavros Sachtouris
        self.connect(network_id, server_id)
763 17cfc2f0 Stavros Sachtouris
764 7a3c66e1 Stavros Sachtouris
    def main(self, network_id):
765 fd981f77 Stavros Sachtouris
        super(self.__class__, self)._run()
766 7a3c66e1 Stavros Sachtouris
        for sid in self['device_id']:
767 7a3c66e1 Stavros Sachtouris
            self._run(network_id=network_id, server_id=sid)
768 264a13f7 Stavros Sachtouris
769 264a13f7 Stavros Sachtouris
770 264a13f7 Stavros Sachtouris
@command(network_cmds)
771 17cfc2f0 Stavros Sachtouris
class network_disconnect(_init_network, _port_wait, _optional_json):
772 6318da0c Dionysis Grigoropoulos
    """Disconnect a network from a device"""
773 264a13f7 Stavros Sachtouris
774 fd981f77 Stavros Sachtouris
    def _cyclades_client(self):
775 fd981f77 Stavros Sachtouris
        auth = getattr(self, 'auth_base')
776 fd981f77 Stavros Sachtouris
        endpoints = auth.get_service_endpoints('compute')
777 fd981f77 Stavros Sachtouris
        URL = endpoints['publicURL']
778 fd981f77 Stavros Sachtouris
        from kamaki.clients.cyclades import CycladesClient
779 fd981f77 Stavros Sachtouris
        return CycladesClient(URL, self.client.token)
780 fd981f77 Stavros Sachtouris
781 17cfc2f0 Stavros Sachtouris
    arguments = dict(
782 7a3c66e1 Stavros Sachtouris
        wait=FlagArgument('Wait network to disconnect', ('-w', '--wait')),
783 7a3c66e1 Stavros Sachtouris
        device_id=RepeatableArgument(
784 7a3c66e1 Stavros Sachtouris
            'Disconnect device from the network (can be repeated)',
785 7a3c66e1 Stavros Sachtouris
            '--device-id')
786 17cfc2f0 Stavros Sachtouris
    )
787 7a3c66e1 Stavros Sachtouris
    required = ('device_id', )
788 17cfc2f0 Stavros Sachtouris
789 fd981f77 Stavros Sachtouris
    @errors.generic.all
790 fd981f77 Stavros Sachtouris
    @errors.cyclades.connection
791 fd981f77 Stavros Sachtouris
    @errors.cyclades.network_id
792 fd981f77 Stavros Sachtouris
    @errors.cyclades.server_id
793 f3740b99 Stavros Sachtouris
    def _run(self, network_id, server_id):
794 f3740b99 Stavros Sachtouris
        vm = self._cyclades_client().get_server_details(server_id)
795 f3740b99 Stavros Sachtouris
        ports = [port for port in vm['attachments'] if (
796 7a3c66e1 Stavros Sachtouris
            port['network_id'] in (network_id, ))]
797 f3740b99 Stavros Sachtouris
        if not ports:
798 fd981f77 Stavros Sachtouris
            raiseCLIError('Network %s is not connected to device %s' % (
799 f3740b99 Stavros Sachtouris
                network_id, server_id))
800 f3740b99 Stavros Sachtouris
        for port in ports:
801 f3740b99 Stavros Sachtouris
            if self['wait']:
802 f3740b99 Stavros Sachtouris
                port['status'] = self.client.get_port_details(port['id'])[
803 f3740b99 Stavros Sachtouris
                    'status']
804 f3740b99 Stavros Sachtouris
            self.client.delete_port(port['id'])
805 f3740b99 Stavros Sachtouris
            self.error('Deleting port %s:' % port['id'])
806 f3740b99 Stavros Sachtouris
            self.print_dict(port)
807 17cfc2f0 Stavros Sachtouris
            if self['wait']:
808 f3740b99 Stavros Sachtouris
                try:
809 f3740b99 Stavros Sachtouris
                    self._wait(port['id'], port['status'])
810 f3740b99 Stavros Sachtouris
                except ClientError as ce:
811 f3740b99 Stavros Sachtouris
                    if ce.status not in (404, ):
812 f3740b99 Stavros Sachtouris
                        raise
813 f3740b99 Stavros Sachtouris
                    self.error('Port %s is deleted' % port['id'])
814 fd981f77 Stavros Sachtouris
815 7a3c66e1 Stavros Sachtouris
    def main(self, network_id):
816 fd981f77 Stavros Sachtouris
        super(self.__class__, self)._run()
817 7a3c66e1 Stavros Sachtouris
        for sid in self['device_id']:
818 7a3c66e1 Stavros Sachtouris
            self._run(network_id=network_id, server_id=sid)