Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / network.py @ 75ae8a08

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