Statistics
| Branch: | Tag: | Revision:

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

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