Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / cyclades.py @ 60c42f9f

History | View | Annotate | Download (28.2 kB)

1 a494a741 Stavros Sachtouris
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 7493ccb6 Stavros Sachtouris
#
3 7493ccb6 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 7493ccb6 Stavros Sachtouris
# without modification, are permitted provided that the following
5 7493ccb6 Stavros Sachtouris
# conditions are met:
6 7493ccb6 Stavros Sachtouris
#
7 7493ccb6 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 7493ccb6 Stavros Sachtouris
#      disclaimer.
10 7493ccb6 Stavros Sachtouris
#
11 7493ccb6 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 7493ccb6 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 7493ccb6 Stavros Sachtouris
#      provided with the distribution.
15 7493ccb6 Stavros Sachtouris
#
16 7493ccb6 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 7493ccb6 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 7493ccb6 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 7493ccb6 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 7493ccb6 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 7493ccb6 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 7493ccb6 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 7493ccb6 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 7493ccb6 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 7493ccb6 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 7493ccb6 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 7493ccb6 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 7493ccb6 Stavros Sachtouris
#
29 7493ccb6 Stavros Sachtouris
# The views and conclusions contained in the software and
30 7493ccb6 Stavros Sachtouris
# documentation are those of the authors and should not be
31 7493ccb6 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 7493ccb6 Stavros Sachtouris
# or implied, of GRNET S.A.
33 7493ccb6 Stavros Sachtouris
34 f3e94e06 Stavros Sachtouris
from kamaki.cli import command
35 d486baec Stavros Sachtouris
from kamaki.cli.command_tree import CommandTree
36 7ba195e5 Stavros Sachtouris
from kamaki.cli.utils import print_dict, remove_from_items
37 8cec3671 Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError, CLISyntaxError, CLIBaseUrlError
38 7493ccb6 Stavros Sachtouris
from kamaki.clients.cyclades import CycladesClient, ClientError
39 57d622b6 Stavros Sachtouris
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
40 bd40efdf Stavros Sachtouris
from kamaki.cli.argument import ProgressBarArgument, DateArgument, IntArgument
41 b4f69041 Stavros Sachtouris
from kamaki.cli.commands import _command_init, errors, addLogSettings
42 545c6c29 Stavros Sachtouris
from kamaki.cli.commands import _optional_output_cmd, _optional_json
43 5eae854d Stavros Sachtouris
44 f3e94e06 Stavros Sachtouris
from base64 import b64encode
45 234954d1 Stavros Sachtouris
from os.path import exists
46 234954d1 Stavros Sachtouris
47 234954d1 Stavros Sachtouris
48 a29d2f88 Stavros Sachtouris
server_cmds = CommandTree('server', 'Cyclades/Compute API server commands')
49 a29d2f88 Stavros Sachtouris
flavor_cmds = CommandTree('flavor', 'Cyclades/Compute API flavor commands')
50 a29d2f88 Stavros Sachtouris
network_cmds = CommandTree('network', 'Cyclades/Compute API network commands')
51 9b47150e Stavros Sachtouris
floatingip_cmds = CommandTree(
52 9b47150e Stavros Sachtouris
    'floatingip', 'Cyclades/Compute API floating ip commands')
53 a57402cd Stavros Sachtouris
_commands = [server_cmds, flavor_cmds, network_cmds, floatingip_cmds]
54 234954d1 Stavros Sachtouris
55 7493ccb6 Stavros Sachtouris
56 c314fc10 Stavros Sachtouris
about_authentication = '\nUser Authentication:\
57 4018326d Stavros Sachtouris
    \n* to check authentication: /user authenticate\
58 9e5341f5 Stavros Sachtouris
    \n* to set authentication token: /config set cloud.<cloud>.token <token>'
59 18edacfe Stavros Sachtouris
60 d7259dd5 Stavros Sachtouris
howto_personality = [
61 d7259dd5 Stavros Sachtouris
    'Defines a file to be injected to VMs personality.',
62 8194b51b Stavros Sachtouris
    'Personality value syntax: PATH,[SERVER_PATH,[OWNER,[GROUP,[MODE]]]]',
63 d7259dd5 Stavros Sachtouris
    '  PATH: of local file to be injected',
64 d7259dd5 Stavros Sachtouris
    '  SERVER_PATH: destination location inside server Image',
65 d7259dd5 Stavros Sachtouris
    '  OWNER: user id of destination file owner',
66 d7259dd5 Stavros Sachtouris
    '  GROUP: group id or name to own destination file',
67 d7259dd5 Stavros Sachtouris
    '  MODEL: permition in octal (e.g. 0777 or o+rwx)']
68 d7259dd5 Stavros Sachtouris
69 18edacfe Stavros Sachtouris
70 60c42f9f Stavros Sachtouris
class _server_wait(object):
71 60c42f9f Stavros Sachtouris
72 60c42f9f Stavros Sachtouris
    wait_arguments = dict(
73 60c42f9f Stavros Sachtouris
        progress_bar=ProgressBarArgument(
74 60c42f9f Stavros Sachtouris
            'do not show progress bar',
75 60c42f9f Stavros Sachtouris
            ('-N', '--no-progress-bar'),
76 60c42f9f Stavros Sachtouris
            False
77 60c42f9f Stavros Sachtouris
        )
78 60c42f9f Stavros Sachtouris
    )
79 60c42f9f Stavros Sachtouris
80 60c42f9f Stavros Sachtouris
    def _wait(self, server_id, currect_status):
81 60c42f9f Stavros Sachtouris
        (progress_bar, wait_cb) = self._safe_progress_bar(
82 60c42f9f Stavros Sachtouris
            'Server %s still in %s mode' % (server_id, currect_status))
83 60c42f9f Stavros Sachtouris
84 60c42f9f Stavros Sachtouris
        try:
85 60c42f9f Stavros Sachtouris
            new_mode = self.client.wait_server(
86 60c42f9f Stavros Sachtouris
                server_id,
87 60c42f9f Stavros Sachtouris
                currect_status,
88 60c42f9f Stavros Sachtouris
                wait_cb=wait_cb)
89 60c42f9f Stavros Sachtouris
        except Exception:
90 60c42f9f Stavros Sachtouris
            self._safe_progress_bar_finish(progress_bar)
91 60c42f9f Stavros Sachtouris
            raise
92 60c42f9f Stavros Sachtouris
        finally:
93 60c42f9f Stavros Sachtouris
            self._safe_progress_bar_finish(progress_bar)
94 60c42f9f Stavros Sachtouris
        if new_mode:
95 60c42f9f Stavros Sachtouris
            print('Server %s is now in %s mode' % (server_id, new_mode))
96 60c42f9f Stavros Sachtouris
        else:
97 60c42f9f Stavros Sachtouris
            raiseCLIError(None, 'Time out')
98 60c42f9f Stavros Sachtouris
99 60c42f9f Stavros Sachtouris
100 5eae854d Stavros Sachtouris
class _init_cyclades(_command_init):
101 b04288f7 Stavros Sachtouris
    @errors.generic.all
102 b4f69041 Stavros Sachtouris
    @addLogSettings
103 236e7d08 Stavros Sachtouris
    def _run(self, service='compute'):
104 b4f69041 Stavros Sachtouris
        if getattr(self, 'cloud', None):
105 b4f69041 Stavros Sachtouris
            base_url = self._custom_url(service)\
106 b4f69041 Stavros Sachtouris
                or self._custom_url('cyclades')
107 b4f69041 Stavros Sachtouris
            if base_url:
108 b4f69041 Stavros Sachtouris
                token = self._custom_token(service)\
109 b4f69041 Stavros Sachtouris
                    or self._custom_token('cyclades')\
110 144b3551 Stavros Sachtouris
                    or self.config.get_cloud('token')
111 b4f69041 Stavros Sachtouris
                self.client = CycladesClient(
112 b4f69041 Stavros Sachtouris
                    base_url=base_url, token=token)
113 b4f69041 Stavros Sachtouris
                return
114 b4f69041 Stavros Sachtouris
        else:
115 b4f69041 Stavros Sachtouris
            self.cloud = 'default'
116 8cec3671 Stavros Sachtouris
        if getattr(self, 'auth_base', False):
117 8cec3671 Stavros Sachtouris
            cyclades_endpoints = self.auth_base.get_service_endpoints(
118 b4f69041 Stavros Sachtouris
                self._custom_type('cyclades') or 'compute',
119 b4f69041 Stavros Sachtouris
                self._custom_version('cyclades') or '')
120 8cec3671 Stavros Sachtouris
            base_url = cyclades_endpoints['publicURL']
121 b4f69041 Stavros Sachtouris
            token = self.auth_base.token
122 b4f69041 Stavros Sachtouris
            self.client = CycladesClient(base_url=base_url, token=token)
123 8cec3671 Stavros Sachtouris
        else:
124 8cec3671 Stavros Sachtouris
            raise CLIBaseUrlError(service='cyclades')
125 8cec3671 Stavros Sachtouris
126 b04288f7 Stavros Sachtouris
    def main(self):
127 b04288f7 Stavros Sachtouris
        self._run()
128 236e7d08 Stavros Sachtouris
129 234954d1 Stavros Sachtouris
130 d486baec Stavros Sachtouris
@command(server_cmds)
131 545c6c29 Stavros Sachtouris
class server_list(_init_cyclades, _optional_json):
132 c314fc10 Stavros Sachtouris
    """List Virtual Machines accessible by user"""
133 18edacfe Stavros Sachtouris
134 18edacfe Stavros Sachtouris
    __doc__ += about_authentication
135 7493ccb6 Stavros Sachtouris
136 e15d78e2 Stavros Sachtouris
    arguments = dict(
137 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
138 67469d65 Stavros Sachtouris
        since=DateArgument(
139 a382ea56 Stavros Sachtouris
            'show only items since date (\' d/m/Y H:M:S \')',
140 a4d0d88a Stavros Sachtouris
            '--since'),
141 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit number of listed VMs', ('-n', '--number')),
142 a4d0d88a Stavros Sachtouris
        more=FlagArgument(
143 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
144 ed9af02c Stavros Sachtouris
            '--more'),
145 ed9af02c Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
146 e15d78e2 Stavros Sachtouris
    )
147 e15d78e2 Stavros Sachtouris
148 b04288f7 Stavros Sachtouris
    @errors.generic.all
149 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
150 b04288f7 Stavros Sachtouris
    @errors.cyclades.date
151 b04288f7 Stavros Sachtouris
    def _run(self):
152 b04288f7 Stavros Sachtouris
        servers = self.client.list_servers(self['detail'], self['since'])
153 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
154 7ba195e5 Stavros Sachtouris
            remove_from_items(servers, 'links')
155 545c6c29 Stavros Sachtouris
156 545c6c29 Stavros Sachtouris
        kwargs = dict(with_enumeration=self['enum'])
157 a4d0d88a Stavros Sachtouris
        if self['more']:
158 545c6c29 Stavros Sachtouris
            kwargs['page_size'] = self['limit'] if self['limit'] else 10
159 545c6c29 Stavros Sachtouris
        elif self['limit']:
160 545c6c29 Stavros Sachtouris
            servers = servers[:self['limit']]
161 545c6c29 Stavros Sachtouris
        self._print(servers, **kwargs)
162 7493ccb6 Stavros Sachtouris
163 b04288f7 Stavros Sachtouris
    def main(self):
164 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
165 b04288f7 Stavros Sachtouris
        self._run()
166 b04288f7 Stavros Sachtouris
167 234954d1 Stavros Sachtouris
168 d486baec Stavros Sachtouris
@command(server_cmds)
169 545c6c29 Stavros Sachtouris
class server_info(_init_cyclades, _optional_json):
170 67469d65 Stavros Sachtouris
    """Detailed information on a Virtual Machine
171 67469d65 Stavros Sachtouris
    Contains:
172 67469d65 Stavros Sachtouris
    - name, id, status, create/update dates
173 67469d65 Stavros Sachtouris
    - network interfaces
174 67469d65 Stavros Sachtouris
    - metadata (e.g. os, superuser) and diagnostics
175 67469d65 Stavros Sachtouris
    - hardware flavor and os image ids
176 67469d65 Stavros Sachtouris
    """
177 7493ccb6 Stavros Sachtouris
178 b04288f7 Stavros Sachtouris
    @errors.generic.all
179 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
180 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
181 b04288f7 Stavros Sachtouris
    def _run(self, server_id):
182 bcef3ac9 Stavros Sachtouris
        self._print(self.client.get_server_details(server_id), print_dict)
183 7493ccb6 Stavros Sachtouris
184 b04288f7 Stavros Sachtouris
    def main(self, server_id):
185 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
186 b04288f7 Stavros Sachtouris
        self._run(server_id=server_id)
187 b04288f7 Stavros Sachtouris
188 234954d1 Stavros Sachtouris
189 57d622b6 Stavros Sachtouris
class PersonalityArgument(KeyValueArgument):
190 234954d1 Stavros Sachtouris
    @property
191 f3e94e06 Stavros Sachtouris
    def value(self):
192 57d622b6 Stavros Sachtouris
        return self._value if hasattr(self, '_value') else []
193 234954d1 Stavros Sachtouris
194 234954d1 Stavros Sachtouris
    @value.setter
195 f3e94e06 Stavros Sachtouris
    def value(self, newvalue):
196 f3e94e06 Stavros Sachtouris
        if newvalue == self.default:
197 f3e94e06 Stavros Sachtouris
            return self.value
198 57d622b6 Stavros Sachtouris
        self._value = []
199 57d622b6 Stavros Sachtouris
        for i, terms in enumerate(newvalue):
200 57d622b6 Stavros Sachtouris
            termlist = terms.split(',')
201 57d622b6 Stavros Sachtouris
            if len(termlist) > 5:
202 de73876b Stavros Sachtouris
                msg = 'Wrong number of terms (should be 1 to 5)'
203 de73876b Stavros Sachtouris
                raiseCLIError(CLISyntaxError(msg), details=howto_personality)
204 57d622b6 Stavros Sachtouris
            path = termlist[0]
205 57d622b6 Stavros Sachtouris
            if not exists(path):
206 de73876b Stavros Sachtouris
                raiseCLIError(
207 de73876b Stavros Sachtouris
                    None,
208 8194b51b Stavros Sachtouris
                    '--personality: File %s does not exist' % path,
209 8194b51b Stavros Sachtouris
                    importance=1,
210 8194b51b Stavros Sachtouris
                    details=howto_personality)
211 57d622b6 Stavros Sachtouris
            self._value.append(dict(path=path))
212 57d622b6 Stavros Sachtouris
            with open(path) as f:
213 57d622b6 Stavros Sachtouris
                self._value[i]['contents'] = b64encode(f.read())
214 57d622b6 Stavros Sachtouris
            try:
215 57d622b6 Stavros Sachtouris
                self._value[i]['path'] = termlist[1]
216 57d622b6 Stavros Sachtouris
                self._value[i]['owner'] = termlist[2]
217 57d622b6 Stavros Sachtouris
                self._value[i]['group'] = termlist[3]
218 57d622b6 Stavros Sachtouris
                self._value[i]['mode'] = termlist[4]
219 57d622b6 Stavros Sachtouris
            except IndexError:
220 57d622b6 Stavros Sachtouris
                pass
221 f3e94e06 Stavros Sachtouris
222 234954d1 Stavros Sachtouris
223 d486baec Stavros Sachtouris
@command(server_cmds)
224 60c42f9f Stavros Sachtouris
class server_create(_init_cyclades, _optional_json, _server_wait):
225 8194b51b Stavros Sachtouris
    """Create a server (aka Virtual Machine)
226 8194b51b Stavros Sachtouris
    Parameters:
227 439826ec Stavros Sachtouris
    - name: (single quoted text)
228 439826ec Stavros Sachtouris
    - flavor id: Hardware flavor. Pick one from: /flavor list
229 439826ec Stavros Sachtouris
    - image id: OS images. Pick one from: /image list
230 8194b51b Stavros Sachtouris
    """
231 7493ccb6 Stavros Sachtouris
232 93914390 Stavros Sachtouris
    arguments = dict(
233 93914390 Stavros Sachtouris
        personality=PersonalityArgument(
234 60c42f9f Stavros Sachtouris
            (80 * ' ').join(howto_personality), ('-p', '--personality')),
235 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to build', ('-w', '--wait'))
236 93914390 Stavros Sachtouris
    )
237 f3e94e06 Stavros Sachtouris
238 b04288f7 Stavros Sachtouris
    @errors.generic.all
239 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
240 b04288f7 Stavros Sachtouris
    @errors.plankton.id
241 b04288f7 Stavros Sachtouris
    @errors.cyclades.flavor_id
242 b04288f7 Stavros Sachtouris
    def _run(self, name, flavor_id, image_id):
243 60c42f9f Stavros Sachtouris
        r = self.client.create_server(
244 60c42f9f Stavros Sachtouris
            name, int(flavor_id), image_id, self['personality'])
245 60c42f9f Stavros Sachtouris
        self._print(r, print_dict)
246 60c42f9f Stavros Sachtouris
        if self['wait']:
247 60c42f9f Stavros Sachtouris
            self._wait(r['id'], r['status'])
248 b04288f7 Stavros Sachtouris
249 7493ccb6 Stavros Sachtouris
    def main(self, name, flavor_id, image_id):
250 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
251 b04288f7 Stavros Sachtouris
        self._run(name=name, flavor_id=flavor_id, image_id=image_id)
252 7493ccb6 Stavros Sachtouris
253 234954d1 Stavros Sachtouris
254 d486baec Stavros Sachtouris
@command(server_cmds)
255 cd295a1d Stavros Sachtouris
class server_rename(_init_cyclades, _optional_output_cmd):
256 22b6f063 Stavros Sachtouris
    """Set/update a server (VM) name
257 5a673575 Stavros Sachtouris
    VM names are not unique, therefore multiple servers may share the same name
258 22b6f063 Stavros Sachtouris
    """
259 7493ccb6 Stavros Sachtouris
260 5a673575 Stavros Sachtouris
    @errors.generic.all
261 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
262 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
263 5a673575 Stavros Sachtouris
    def _run(self, server_id, new_name):
264 cd295a1d Stavros Sachtouris
        self._optional_output(
265 cd295a1d Stavros Sachtouris
            self.client.update_server_name(int(server_id), new_name))
266 5a673575 Stavros Sachtouris
267 7493ccb6 Stavros Sachtouris
    def main(self, server_id, new_name):
268 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
269 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, new_name=new_name)
270 234954d1 Stavros Sachtouris
271 7493ccb6 Stavros Sachtouris
272 d486baec Stavros Sachtouris
@command(server_cmds)
273 60c42f9f Stavros Sachtouris
class server_delete(_init_cyclades, _optional_output_cmd, _server_wait):
274 22b6f063 Stavros Sachtouris
    """Delete a server (VM)"""
275 7493ccb6 Stavros Sachtouris
276 60c42f9f Stavros Sachtouris
    arguments = dict(
277 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
278 60c42f9f Stavros Sachtouris
    )
279 60c42f9f Stavros Sachtouris
280 5a673575 Stavros Sachtouris
    @errors.generic.all
281 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
282 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
283 5a673575 Stavros Sachtouris
    def _run(self, server_id):
284 60c42f9f Stavros Sachtouris
            status = 'DELETED'
285 60c42f9f Stavros Sachtouris
            if self['wait']:
286 60c42f9f Stavros Sachtouris
                details = self.client.get_server_details(server_id)
287 60c42f9f Stavros Sachtouris
                status = details['status']
288 60c42f9f Stavros Sachtouris
289 60c42f9f Stavros Sachtouris
            r = self.client.delete_server(int(server_id))
290 60c42f9f Stavros Sachtouris
            self._optional_output(r)
291 60c42f9f Stavros Sachtouris
292 60c42f9f Stavros Sachtouris
            if self['wait']:
293 60c42f9f Stavros Sachtouris
                self._wait(server_id, status)
294 5a673575 Stavros Sachtouris
295 5a673575 Stavros Sachtouris
    def main(self, server_id):
296 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
297 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
298 234954d1 Stavros Sachtouris
299 7493ccb6 Stavros Sachtouris
300 d486baec Stavros Sachtouris
@command(server_cmds)
301 60c42f9f Stavros Sachtouris
class server_reboot(_init_cyclades, _optional_output_cmd, _server_wait):
302 22b6f063 Stavros Sachtouris
    """Reboot a server (VM)"""
303 18edacfe Stavros Sachtouris
304 93914390 Stavros Sachtouris
    arguments = dict(
305 60c42f9f Stavros Sachtouris
        hard=FlagArgument('perform a hard reboot', ('-f', '--force')),
306 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
307 93914390 Stavros Sachtouris
    )
308 7493ccb6 Stavros Sachtouris
309 5a673575 Stavros Sachtouris
    @errors.generic.all
310 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
311 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
312 5a673575 Stavros Sachtouris
    def _run(self, server_id):
313 60c42f9f Stavros Sachtouris
        r = self.client.reboot_server(int(server_id), self['hard'])
314 60c42f9f Stavros Sachtouris
        self._optional_output(r)
315 60c42f9f Stavros Sachtouris
316 60c42f9f Stavros Sachtouris
        if self['wait']:
317 60c42f9f Stavros Sachtouris
            self._wait(server_id, 'REBOOT')
318 5a673575 Stavros Sachtouris
319 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
320 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
321 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
322 234954d1 Stavros Sachtouris
323 7493ccb6 Stavros Sachtouris
324 d486baec Stavros Sachtouris
@command(server_cmds)
325 60c42f9f Stavros Sachtouris
class server_start(_init_cyclades, _optional_output_cmd, _server_wait):
326 22b6f063 Stavros Sachtouris
    """Start an existing server (VM)"""
327 7493ccb6 Stavros Sachtouris
328 60c42f9f Stavros Sachtouris
    arguments = dict(
329 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
330 60c42f9f Stavros Sachtouris
    )
331 60c42f9f Stavros Sachtouris
332 5a673575 Stavros Sachtouris
    @errors.generic.all
333 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
334 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
335 5a673575 Stavros Sachtouris
    def _run(self, server_id):
336 60c42f9f Stavros Sachtouris
        status = 'ACTIVE'
337 60c42f9f Stavros Sachtouris
        if self['wait']:
338 60c42f9f Stavros Sachtouris
            details = self.client.get_server_details(server_id)
339 60c42f9f Stavros Sachtouris
            status = details['status']
340 60c42f9f Stavros Sachtouris
            if status in ('ACTIVE', ):
341 60c42f9f Stavros Sachtouris
                return
342 60c42f9f Stavros Sachtouris
343 60c42f9f Stavros Sachtouris
        r = self.client.start_server(int(server_id))
344 60c42f9f Stavros Sachtouris
        self._optional_output(r)
345 60c42f9f Stavros Sachtouris
346 60c42f9f Stavros Sachtouris
        if self['wait']:
347 60c42f9f Stavros Sachtouris
            self._wait(server_id, status)
348 5a673575 Stavros Sachtouris
349 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
350 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
351 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
352 234954d1 Stavros Sachtouris
353 7493ccb6 Stavros Sachtouris
354 d486baec Stavros Sachtouris
@command(server_cmds)
355 60c42f9f Stavros Sachtouris
class server_shutdown(_init_cyclades, _optional_output_cmd, _server_wait):
356 22b6f063 Stavros Sachtouris
    """Shutdown an active server (VM)"""
357 7493ccb6 Stavros Sachtouris
358 60c42f9f Stavros Sachtouris
    arguments = dict(
359 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
360 60c42f9f Stavros Sachtouris
    )
361 60c42f9f Stavros Sachtouris
362 5a673575 Stavros Sachtouris
    @errors.generic.all
363 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
364 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
365 5a673575 Stavros Sachtouris
    def _run(self, server_id):
366 60c42f9f Stavros Sachtouris
        status = 'STOPPED'
367 60c42f9f Stavros Sachtouris
        if self['wait']:
368 60c42f9f Stavros Sachtouris
            details = self.client.get_server_details(server_id)
369 60c42f9f Stavros Sachtouris
            status = details['status']
370 60c42f9f Stavros Sachtouris
            if status in ('STOPPED', ):
371 60c42f9f Stavros Sachtouris
                return
372 60c42f9f Stavros Sachtouris
373 60c42f9f Stavros Sachtouris
        r = self.client.shutdown_server(int(server_id))
374 60c42f9f Stavros Sachtouris
        self._optional_output(r)
375 60c42f9f Stavros Sachtouris
376 60c42f9f Stavros Sachtouris
        if self['wait']:
377 60c42f9f Stavros Sachtouris
            self._wait(server_id, status)
378 5a673575 Stavros Sachtouris
379 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
380 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
381 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
382 234954d1 Stavros Sachtouris
383 7493ccb6 Stavros Sachtouris
384 d486baec Stavros Sachtouris
@command(server_cmds)
385 545c6c29 Stavros Sachtouris
class server_console(_init_cyclades, _optional_json):
386 22b6f063 Stavros Sachtouris
    """Get a VNC console to access an existing server (VM)
387 22b6f063 Stavros Sachtouris
    Console connection information provided (at least):
388 439826ec Stavros Sachtouris
    - host: (url or address) a VNC host
389 439826ec Stavros Sachtouris
    - port: (int) the gateway to enter VM on host
390 439826ec Stavros Sachtouris
    - password: for VNC authorization
391 22b6f063 Stavros Sachtouris
    """
392 7493ccb6 Stavros Sachtouris
393 5a673575 Stavros Sachtouris
    @errors.generic.all
394 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
395 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
396 5a673575 Stavros Sachtouris
    def _run(self, server_id):
397 bcef3ac9 Stavros Sachtouris
        self._print(
398 bcef3ac9 Stavros Sachtouris
            self.client.get_server_console(int(server_id)), print_dict)
399 5a673575 Stavros Sachtouris
400 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
401 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
402 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
403 7493ccb6 Stavros Sachtouris
404 234954d1 Stavros Sachtouris
405 d486baec Stavros Sachtouris
@command(server_cmds)
406 7493ccb6 Stavros Sachtouris
class server_firewall(_init_cyclades):
407 cd295a1d Stavros Sachtouris
    """Manage server (VM) firewall profiles for public networks"""
408 cd295a1d Stavros Sachtouris
409 cd295a1d Stavros Sachtouris
410 cd295a1d Stavros Sachtouris
@command(server_cmds)
411 cd295a1d Stavros Sachtouris
class server_firewall_set(_init_cyclades, _optional_output_cmd):
412 22b6f063 Stavros Sachtouris
    """Set the server (VM) firewall profile on VMs public network
413 22b6f063 Stavros Sachtouris
    Values for profile:
414 439826ec Stavros Sachtouris
    - DISABLED: Shutdown firewall
415 439826ec Stavros Sachtouris
    - ENABLED: Firewall in normal mode
416 439826ec Stavros Sachtouris
    - PROTECTED: Firewall in secure mode
417 22b6f063 Stavros Sachtouris
    """
418 7493ccb6 Stavros Sachtouris
419 5a673575 Stavros Sachtouris
    @errors.generic.all
420 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
421 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
422 5a673575 Stavros Sachtouris
    @errors.cyclades.firewall
423 5a673575 Stavros Sachtouris
    def _run(self, server_id, profile):
424 cd295a1d Stavros Sachtouris
        self._optional_output(self.client.set_firewall_profile(
425 cd295a1d Stavros Sachtouris
            server_id=int(server_id), profile=('%s' % profile).upper()))
426 5a673575 Stavros Sachtouris
427 7493ccb6 Stavros Sachtouris
    def main(self, server_id, profile):
428 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
429 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, profile=profile)
430 234954d1 Stavros Sachtouris
431 f3e94e06 Stavros Sachtouris
432 d486baec Stavros Sachtouris
@command(server_cmds)
433 cd295a1d Stavros Sachtouris
class server_firewall_get(_init_cyclades):
434 cd295a1d Stavros Sachtouris
    """Get the server (VM) firewall profile for its public network"""
435 cd295a1d Stavros Sachtouris
436 cd295a1d Stavros Sachtouris
    @errors.generic.all
437 cd295a1d Stavros Sachtouris
    @errors.cyclades.connection
438 cd295a1d Stavros Sachtouris
    @errors.cyclades.server_id
439 cd295a1d Stavros Sachtouris
    def _run(self, server_id):
440 cd295a1d Stavros Sachtouris
        print(self.client.get_firewall_profile(server_id))
441 cd295a1d Stavros Sachtouris
442 cd295a1d Stavros Sachtouris
    def main(self, server_id):
443 cd295a1d Stavros Sachtouris
        super(self.__class__, self)._run()
444 cd295a1d Stavros Sachtouris
        self._run(server_id=server_id)
445 cd295a1d Stavros Sachtouris
446 cd295a1d Stavros Sachtouris
447 cd295a1d Stavros Sachtouris
@command(server_cmds)
448 545c6c29 Stavros Sachtouris
class server_addr(_init_cyclades, _optional_json):
449 22b6f063 Stavros Sachtouris
    """List the addresses of all network interfaces on a server (VM)"""
450 7493ccb6 Stavros Sachtouris
451 cd295a1d Stavros Sachtouris
    arguments = dict(
452 545c6c29 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
453 cd295a1d Stavros Sachtouris
    )
454 cd295a1d Stavros Sachtouris
455 5a673575 Stavros Sachtouris
    @errors.generic.all
456 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
457 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
458 5a673575 Stavros Sachtouris
    def _run(self, server_id):
459 5a673575 Stavros Sachtouris
        reply = self.client.list_server_nics(int(server_id))
460 545c6c29 Stavros Sachtouris
        self._print(
461 545c6c29 Stavros Sachtouris
            reply, with_enumeration=self['enum'] and len(reply) > 1)
462 7493ccb6 Stavros Sachtouris
463 5a673575 Stavros Sachtouris
    def main(self, server_id):
464 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
465 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
466 5a673575 Stavros Sachtouris
467 234954d1 Stavros Sachtouris
468 d486baec Stavros Sachtouris
@command(server_cmds)
469 cd295a1d Stavros Sachtouris
class server_metadata(_init_cyclades):
470 cd295a1d Stavros Sachtouris
    """Manage Server metadata (key:value pairs of server attributes)"""
471 cd295a1d Stavros Sachtouris
472 cd295a1d Stavros Sachtouris
473 cd295a1d Stavros Sachtouris
@command(server_cmds)
474 545c6c29 Stavros Sachtouris
class server_metadata_list(_init_cyclades, _optional_json):
475 cd295a1d Stavros Sachtouris
    """Get server metadata"""
476 7493ccb6 Stavros Sachtouris
477 5a673575 Stavros Sachtouris
    @errors.generic.all
478 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
479 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
480 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
481 5a673575 Stavros Sachtouris
    def _run(self, server_id, key=''):
482 545c6c29 Stavros Sachtouris
        self._print(
483 bcef3ac9 Stavros Sachtouris
            self.client.get_server_metadata(int(server_id), key), print_dict)
484 5a673575 Stavros Sachtouris
485 a34888b4 Stavros Sachtouris
    def main(self, server_id, key=''):
486 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
487 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
488 7493ccb6 Stavros Sachtouris
489 234954d1 Stavros Sachtouris
490 d486baec Stavros Sachtouris
@command(server_cmds)
491 545c6c29 Stavros Sachtouris
class server_metadata_set(_init_cyclades, _optional_json):
492 cd295a1d Stavros Sachtouris
    """Set / update server(VM) metadata
493 cd295a1d Stavros Sachtouris
    Metadata should be given in key/value pairs in key=value format
494 9dc6159f Stavros Sachtouris
    For example: /server metadata set <server id> key1=value1 key2=value2
495 cd295a1d Stavros Sachtouris
    Old, unreferenced metadata will remain intact
496 22b6f063 Stavros Sachtouris
    """
497 7493ccb6 Stavros Sachtouris
498 5a673575 Stavros Sachtouris
    @errors.generic.all
499 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
500 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
501 cd295a1d Stavros Sachtouris
    def _run(self, server_id, keyvals):
502 545c6c29 Stavros Sachtouris
        assert keyvals, 'Please, add some metadata ( key=value)'
503 cd295a1d Stavros Sachtouris
        metadata = dict()
504 cd295a1d Stavros Sachtouris
        for keyval in keyvals:
505 cd295a1d Stavros Sachtouris
            k, sep, v = keyval.partition('=')
506 cd295a1d Stavros Sachtouris
            if sep and k:
507 cd295a1d Stavros Sachtouris
                metadata[k] = v
508 cd295a1d Stavros Sachtouris
            else:
509 cd295a1d Stavros Sachtouris
                raiseCLIError(
510 cd295a1d Stavros Sachtouris
                    'Invalid piece of metadata %s' % keyval,
511 cd295a1d Stavros Sachtouris
                    importance=2, details=[
512 cd295a1d Stavros Sachtouris
                        'Correct metadata format: key=val',
513 cd295a1d Stavros Sachtouris
                        'For example:',
514 cd295a1d Stavros Sachtouris
                        '/server metadata set <server id>'
515 cd295a1d Stavros Sachtouris
                        'key1=value1 key2=value2'])
516 545c6c29 Stavros Sachtouris
        self._print(
517 bcef3ac9 Stavros Sachtouris
            self.client.update_server_metadata(int(server_id), **metadata),
518 bcef3ac9 Stavros Sachtouris
            print_dict)
519 cd295a1d Stavros Sachtouris
520 cd295a1d Stavros Sachtouris
    def main(self, server_id, *key_equals_val):
521 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
522 cd295a1d Stavros Sachtouris
        self._run(server_id=server_id, keyvals=key_equals_val)
523 7493ccb6 Stavros Sachtouris
524 234954d1 Stavros Sachtouris
525 d486baec Stavros Sachtouris
@command(server_cmds)
526 cd295a1d Stavros Sachtouris
class server_metadata_delete(_init_cyclades, _optional_output_cmd):
527 22b6f063 Stavros Sachtouris
    """Delete server (VM) metadata"""
528 7493ccb6 Stavros Sachtouris
529 5a673575 Stavros Sachtouris
    @errors.generic.all
530 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
531 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
532 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
533 5a673575 Stavros Sachtouris
    def _run(self, server_id, key):
534 cd295a1d Stavros Sachtouris
        self._optional_output(
535 cd295a1d Stavros Sachtouris
            self.client.delete_server_metadata(int(server_id), key))
536 5a673575 Stavros Sachtouris
537 7493ccb6 Stavros Sachtouris
    def main(self, server_id, key):
538 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
539 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
540 234954d1 Stavros Sachtouris
541 7493ccb6 Stavros Sachtouris
542 d486baec Stavros Sachtouris
@command(server_cmds)
543 545c6c29 Stavros Sachtouris
class server_stats(_init_cyclades, _optional_json):
544 22b6f063 Stavros Sachtouris
    """Get server (VM) statistics"""
545 7493ccb6 Stavros Sachtouris
546 5a673575 Stavros Sachtouris
    @errors.generic.all
547 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
548 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
549 5a673575 Stavros Sachtouris
    def _run(self, server_id):
550 bcef3ac9 Stavros Sachtouris
        self._print(self.client.get_server_stats(int(server_id)), print_dict)
551 5a673575 Stavros Sachtouris
552 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
553 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
554 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
555 7493ccb6 Stavros Sachtouris
556 234954d1 Stavros Sachtouris
557 d486baec Stavros Sachtouris
@command(server_cmds)
558 60c42f9f Stavros Sachtouris
class server_wait(_init_cyclades, _server_wait):
559 fd1f1d96 Stavros Sachtouris
    """Wait for server to finish [BUILD, STOPPED, REBOOT, ACTIVE]"""
560 fd1f1d96 Stavros Sachtouris
561 5a673575 Stavros Sachtouris
    @errors.generic.all
562 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
563 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
564 5a673575 Stavros Sachtouris
    def _run(self, server_id, currect_status):
565 60c42f9f Stavros Sachtouris
        self._wait(server_id, currect_status)
566 fd1f1d96 Stavros Sachtouris
567 5a673575 Stavros Sachtouris
    def main(self, server_id, currect_status='BUILD'):
568 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
569 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, currect_status=currect_status)
570 5a673575 Stavros Sachtouris
571 fd1f1d96 Stavros Sachtouris
572 d486baec Stavros Sachtouris
@command(flavor_cmds)
573 545c6c29 Stavros Sachtouris
class flavor_list(_init_cyclades, _optional_json):
574 bd40efdf Stavros Sachtouris
    """List available hardware flavors"""
575 7493ccb6 Stavros Sachtouris
576 93914390 Stavros Sachtouris
    arguments = dict(
577 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
578 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed flavors', ('-n', '--number')),
579 bd40efdf Stavros Sachtouris
        more=FlagArgument(
580 de73876b Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
581 ed9af02c Stavros Sachtouris
            '--more'),
582 ed9af02c Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
583 93914390 Stavros Sachtouris
    )
584 7493ccb6 Stavros Sachtouris
585 5a673575 Stavros Sachtouris
    @errors.generic.all
586 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
587 5a673575 Stavros Sachtouris
    def _run(self):
588 5a673575 Stavros Sachtouris
        flavors = self.client.list_flavors(self['detail'])
589 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
590 7ba195e5 Stavros Sachtouris
            remove_from_items(flavors, 'links')
591 5a673575 Stavros Sachtouris
        pg_size = 10 if self['more'] and not self['limit'] else self['limit']
592 545c6c29 Stavros Sachtouris
        self._print(
593 ed9af02c Stavros Sachtouris
            flavors,
594 ed9af02c Stavros Sachtouris
            with_redundancy=self['detail'],
595 ed9af02c Stavros Sachtouris
            page_size=pg_size,
596 ed9af02c Stavros Sachtouris
            with_enumeration=self['enum'])
597 5a673575 Stavros Sachtouris
598 7493ccb6 Stavros Sachtouris
    def main(self):
599 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
600 5a673575 Stavros Sachtouris
        self._run()
601 7493ccb6 Stavros Sachtouris
602 234954d1 Stavros Sachtouris
603 d486baec Stavros Sachtouris
@command(flavor_cmds)
604 545c6c29 Stavros Sachtouris
class flavor_info(_init_cyclades, _optional_json):
605 769dbf53 Stavros Sachtouris
    """Detailed information on a hardware flavor
606 ddc0b290 Stavros Sachtouris
    To get a list of available flavors and flavor ids, try /flavor list
607 ddc0b290 Stavros Sachtouris
    """
608 7493ccb6 Stavros Sachtouris
609 5a673575 Stavros Sachtouris
    @errors.generic.all
610 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
611 5a673575 Stavros Sachtouris
    @errors.cyclades.flavor_id
612 5a673575 Stavros Sachtouris
    def _run(self, flavor_id):
613 bcef3ac9 Stavros Sachtouris
        self._print(
614 bcef3ac9 Stavros Sachtouris
            self.client.get_flavor_details(int(flavor_id)), print_dict)
615 7493ccb6 Stavros Sachtouris
616 5a673575 Stavros Sachtouris
    def main(self, flavor_id):
617 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
618 5a673575 Stavros Sachtouris
        self._run(flavor_id=flavor_id)
619 5a673575 Stavros Sachtouris
620 234954d1 Stavros Sachtouris
621 d486baec Stavros Sachtouris
@command(network_cmds)
622 545c6c29 Stavros Sachtouris
class network_info(_init_cyclades, _optional_json):
623 ddc0b290 Stavros Sachtouris
    """Detailed information on a network
624 ddc0b290 Stavros Sachtouris
    To get a list of available networks and network ids, try /network list
625 ddc0b290 Stavros Sachtouris
    """
626 c17b8bc0 Stavros Sachtouris
627 5a673575 Stavros Sachtouris
    @errors.generic.all
628 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
629 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
630 5a673575 Stavros Sachtouris
    def _run(self, network_id):
631 5a673575 Stavros Sachtouris
        network = self.client.get_network_details(int(network_id))
632 545c6c29 Stavros Sachtouris
        self._print(network, print_dict, exclude=('id'))
633 5a673575 Stavros Sachtouris
634 c17b8bc0 Stavros Sachtouris
    def main(self, network_id):
635 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
636 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
637 c17b8bc0 Stavros Sachtouris
638 c17b8bc0 Stavros Sachtouris
639 c17b8bc0 Stavros Sachtouris
@command(network_cmds)
640 545c6c29 Stavros Sachtouris
class network_list(_init_cyclades, _optional_json):
641 7493ccb6 Stavros Sachtouris
    """List networks"""
642 7493ccb6 Stavros Sachtouris
643 93914390 Stavros Sachtouris
    arguments = dict(
644 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
645 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed networks', ('-n', '--number')),
646 ddc0b290 Stavros Sachtouris
        more=FlagArgument(
647 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
648 ed9af02c Stavros Sachtouris
            '--more'),
649 ed9af02c Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
650 93914390 Stavros Sachtouris
    )
651 7493ccb6 Stavros Sachtouris
652 5a673575 Stavros Sachtouris
    @errors.generic.all
653 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
654 5a673575 Stavros Sachtouris
    def _run(self):
655 5a673575 Stavros Sachtouris
        networks = self.client.list_networks(self['detail'])
656 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
657 7ba195e5 Stavros Sachtouris
            remove_from_items(networks, 'links')
658 545c6c29 Stavros Sachtouris
        kwargs = dict(with_enumeration=self['enum'])
659 ddc0b290 Stavros Sachtouris
        if self['more']:
660 545c6c29 Stavros Sachtouris
            kwargs['page_size'] = self['limit'] or 10
661 0e806947 Stavros Sachtouris
        elif self['limit']:
662 545c6c29 Stavros Sachtouris
            networks = networks[:self['limit']]
663 545c6c29 Stavros Sachtouris
        self._print(networks, **kwargs)
664 7493ccb6 Stavros Sachtouris
665 5a673575 Stavros Sachtouris
    def main(self):
666 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
667 5a673575 Stavros Sachtouris
        self._run()
668 5a673575 Stavros Sachtouris
669 234954d1 Stavros Sachtouris
670 d486baec Stavros Sachtouris
@command(network_cmds)
671 545c6c29 Stavros Sachtouris
class network_create(_init_cyclades, _optional_json):
672 0e806947 Stavros Sachtouris
    """Create an (unconnected) network"""
673 7493ccb6 Stavros Sachtouris
674 93914390 Stavros Sachtouris
    arguments = dict(
675 0e806947 Stavros Sachtouris
        cidr=ValueArgument('explicitly set cidr', '--with-cidr'),
676 0e806947 Stavros Sachtouris
        gateway=ValueArgument('explicitly set gateway', '--with-gateway'),
677 9d1db11e Stavros Sachtouris
        dhcp=FlagArgument('Use dhcp (default: off)', '--with-dhcp'),
678 f6f81cd3 Stavros Sachtouris
        type=ValueArgument(
679 f6f81cd3 Stavros Sachtouris
            'Valid network types are '
680 f6f81cd3 Stavros Sachtouris
            'CUSTOM, IP_LESS_ROUTED, MAC_FILTERED (default), PHYSICAL_VLAN',
681 f6f81cd3 Stavros Sachtouris
            '--with-type',
682 f6f81cd3 Stavros Sachtouris
            default='MAC_FILTERED')
683 93914390 Stavros Sachtouris
    )
684 7493ccb6 Stavros Sachtouris
685 5a673575 Stavros Sachtouris
    @errors.generic.all
686 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
687 5a673575 Stavros Sachtouris
    @errors.cyclades.network_max
688 5a673575 Stavros Sachtouris
    def _run(self, name):
689 bcef3ac9 Stavros Sachtouris
        self._print(self.client.create_network(
690 de73876b Stavros Sachtouris
            name,
691 5a673575 Stavros Sachtouris
            cidr=self['cidr'],
692 5a673575 Stavros Sachtouris
            gateway=self['gateway'],
693 5a673575 Stavros Sachtouris
            dhcp=self['dhcp'],
694 bcef3ac9 Stavros Sachtouris
            type=self['type']), print_dict)
695 5a673575 Stavros Sachtouris
696 7493ccb6 Stavros Sachtouris
    def main(self, name):
697 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
698 5a673575 Stavros Sachtouris
        self._run(name)
699 7493ccb6 Stavros Sachtouris
700 234954d1 Stavros Sachtouris
701 d486baec Stavros Sachtouris
@command(network_cmds)
702 1b73b4c1 Stavros Sachtouris
class network_rename(_init_cyclades, _optional_output_cmd):
703 0e806947 Stavros Sachtouris
    """Set the name of a network"""
704 7493ccb6 Stavros Sachtouris
705 5a673575 Stavros Sachtouris
    @errors.generic.all
706 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
707 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
708 5a673575 Stavros Sachtouris
    def _run(self, network_id, new_name):
709 1b73b4c1 Stavros Sachtouris
        self._optional_output(
710 1b73b4c1 Stavros Sachtouris
                self.client.update_network_name(int(network_id), new_name))
711 5a673575 Stavros Sachtouris
712 7493ccb6 Stavros Sachtouris
    def main(self, network_id, new_name):
713 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
714 5a673575 Stavros Sachtouris
        self._run(network_id=network_id, new_name=new_name)
715 7493ccb6 Stavros Sachtouris
716 234954d1 Stavros Sachtouris
717 d486baec Stavros Sachtouris
@command(network_cmds)
718 1b73b4c1 Stavros Sachtouris
class network_delete(_init_cyclades, _optional_output_cmd):
719 7493ccb6 Stavros Sachtouris
    """Delete a network"""
720 7493ccb6 Stavros Sachtouris
721 5a673575 Stavros Sachtouris
    @errors.generic.all
722 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
723 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
724 5a673575 Stavros Sachtouris
    @errors.cyclades.network_in_use
725 5a673575 Stavros Sachtouris
    def _run(self, network_id):
726 1b73b4c1 Stavros Sachtouris
        self._optional_output(self.client.delete_network(int(network_id)))
727 5a673575 Stavros Sachtouris
728 7493ccb6 Stavros Sachtouris
    def main(self, network_id):
729 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
730 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
731 7493ccb6 Stavros Sachtouris
732 234954d1 Stavros Sachtouris
733 d486baec Stavros Sachtouris
@command(network_cmds)
734 1b73b4c1 Stavros Sachtouris
class network_connect(_init_cyclades, _optional_output_cmd):
735 7493ccb6 Stavros Sachtouris
    """Connect a server to a network"""
736 7493ccb6 Stavros Sachtouris
737 5a673575 Stavros Sachtouris
    @errors.generic.all
738 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
739 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
740 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
741 5a673575 Stavros Sachtouris
    def _run(self, server_id, network_id):
742 1b73b4c1 Stavros Sachtouris
        self._optional_output(
743 1b73b4c1 Stavros Sachtouris
                self.client.connect_server(int(server_id), int(network_id)))
744 5a673575 Stavros Sachtouris
745 7493ccb6 Stavros Sachtouris
    def main(self, server_id, network_id):
746 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
747 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, network_id=network_id)
748 7493ccb6 Stavros Sachtouris
749 234954d1 Stavros Sachtouris
750 d486baec Stavros Sachtouris
@command(network_cmds)
751 7493ccb6 Stavros Sachtouris
class network_disconnect(_init_cyclades):
752 0e806947 Stavros Sachtouris
    """Disconnect a nic that connects a server to a network
753 0e806947 Stavros Sachtouris
    Nic ids are listed as "attachments" in detailed network information
754 439826ec Stavros Sachtouris
    To get detailed network information: /network info <network id>
755 0e806947 Stavros Sachtouris
    """
756 7493ccb6 Stavros Sachtouris
757 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_format
758 5a673575 Stavros Sachtouris
    def _server_id_from_nic(self, nic_id):
759 5a673575 Stavros Sachtouris
        return nic_id.split('-')[1]
760 5a673575 Stavros Sachtouris
761 5a673575 Stavros Sachtouris
    @errors.generic.all
762 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
763 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
764 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_id
765 5a673575 Stavros Sachtouris
    def _run(self, nic_id, server_id):
766 1b73b4c1 Stavros Sachtouris
        num_of_disconnected = self.client.disconnect_server(server_id, nic_id)
767 1b73b4c1 Stavros Sachtouris
        if not num_of_disconnected:
768 5a673575 Stavros Sachtouris
            raise ClientError(
769 5a673575 Stavros Sachtouris
                'Network Interface %s not found on server %s' % (
770 5a673575 Stavros Sachtouris
                    nic_id,
771 5a673575 Stavros Sachtouris
                    server_id),
772 5a673575 Stavros Sachtouris
                status=404)
773 1b73b4c1 Stavros Sachtouris
        print('Disconnected %s connections' % num_of_disconnected)
774 5a673575 Stavros Sachtouris
775 7493ccb6 Stavros Sachtouris
    def main(self, nic_id):
776 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
777 5a673575 Stavros Sachtouris
        server_id = self._server_id_from_nic(nic_id=nic_id)
778 5a673575 Stavros Sachtouris
        self._run(nic_id=nic_id, server_id=server_id)
779 9b47150e Stavros Sachtouris
780 9b47150e Stavros Sachtouris
781 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
782 9b47150e Stavros Sachtouris
class floatingip_pools(_init_cyclades, _optional_json):
783 9b47150e Stavros Sachtouris
    """List all floating pools of floating ips"""
784 9b47150e Stavros Sachtouris
785 9b47150e Stavros Sachtouris
    @errors.generic.all
786 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
787 9b47150e Stavros Sachtouris
    def _run(self):
788 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ip_pools()
789 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ip_pools'])
790 9b47150e Stavros Sachtouris
791 9b47150e Stavros Sachtouris
    def main(self):
792 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
793 9b47150e Stavros Sachtouris
        self._run()
794 9b47150e Stavros Sachtouris
795 9b47150e Stavros Sachtouris
796 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
797 9b47150e Stavros Sachtouris
class floatingip_list(_init_cyclades, _optional_json):
798 9b47150e Stavros Sachtouris
    """List all floating ips"""
799 9b47150e Stavros Sachtouris
800 9b47150e Stavros Sachtouris
    @errors.generic.all
801 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
802 9b47150e Stavros Sachtouris
    def _run(self):
803 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ips()
804 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ips'])
805 9b47150e Stavros Sachtouris
806 9b47150e Stavros Sachtouris
    def main(self):
807 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
808 9b47150e Stavros Sachtouris
        self._run()
809 9b47150e Stavros Sachtouris
810 9b47150e Stavros Sachtouris
811 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
812 9b47150e Stavros Sachtouris
class floatingip_info(_init_cyclades, _optional_json):
813 9b47150e Stavros Sachtouris
    """A floating IPs' details"""
814 9b47150e Stavros Sachtouris
815 9b47150e Stavros Sachtouris
    @errors.generic.all
816 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
817 9b47150e Stavros Sachtouris
    def _run(self, ip):
818 9b47150e Stavros Sachtouris
        self._print(self.client.get_floating_ip(ip), print_dict)
819 9b47150e Stavros Sachtouris
820 9b47150e Stavros Sachtouris
    def main(self, ip):
821 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
822 9b47150e Stavros Sachtouris
        self._run(ip=ip)
823 9b47150e Stavros Sachtouris
824 9b47150e Stavros Sachtouris
825 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
826 9b47150e Stavros Sachtouris
class floatingip_create(_init_cyclades, _optional_json):
827 9b47150e Stavros Sachtouris
    """Create a new floating IP"""
828 9b47150e Stavros Sachtouris
829 9b47150e Stavros Sachtouris
    arguments = dict(
830 9b47150e Stavros Sachtouris
        pool=ValueArgument('Source IP pool', ('--pool'), None)
831 9b47150e Stavros Sachtouris
    )
832 9b47150e Stavros Sachtouris
833 9b47150e Stavros Sachtouris
    @errors.generic.all
834 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
835 9b47150e Stavros Sachtouris
    def _run(self, ip=None):
836 9b47150e Stavros Sachtouris
        self._print(
837 9b47150e Stavros Sachtouris
            self.client.alloc_floating_ip(self['pool'], ip), print_dict)
838 9b47150e Stavros Sachtouris
839 9b47150e Stavros Sachtouris
    def main(self, requested_address=None):
840 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
841 9b47150e Stavros Sachtouris
        self._run(ip=requested_address)
842 9b47150e Stavros Sachtouris
843 9b47150e Stavros Sachtouris
844 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
845 9b47150e Stavros Sachtouris
class floatingip_delete(_init_cyclades, _optional_output_cmd):
846 9b47150e Stavros Sachtouris
    """Delete a floating ip"""
847 9b47150e Stavros Sachtouris
848 9b47150e Stavros Sachtouris
    @errors.generic.all
849 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
850 9b47150e Stavros Sachtouris
    def _run(self, ip):
851 9b47150e Stavros Sachtouris
        self._optional_output(self.client.delete_floating_ip(ip))
852 9b47150e Stavros Sachtouris
853 9b47150e Stavros Sachtouris
    def main(self, ip):
854 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
855 9b47150e Stavros Sachtouris
        self._run(ip=ip)
856 9b47150e Stavros Sachtouris
857 9b47150e Stavros Sachtouris
858 9b47150e Stavros Sachtouris
@command(server_cmds)
859 9b47150e Stavros Sachtouris
class server_ip_attach(_init_cyclades, _optional_output_cmd):
860 9b47150e Stavros Sachtouris
    """Attach a floating ip to a server with server_id
861 9b47150e Stavros Sachtouris
    """
862 9b47150e Stavros Sachtouris
863 9b47150e Stavros Sachtouris
    @errors.generic.all
864 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
865 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
866 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
867 9b47150e Stavros Sachtouris
        self._optional_output(self.client.attach_floating_ip(server_id, ip))
868 9b47150e Stavros Sachtouris
869 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
870 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
871 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)
872 9b47150e Stavros Sachtouris
873 9b47150e Stavros Sachtouris
874 9b47150e Stavros Sachtouris
@command(server_cmds)
875 9b47150e Stavros Sachtouris
class server_ip_detach(_init_cyclades):
876 9b47150e Stavros Sachtouris
    """detach_floating_ip_to_server
877 9b47150e Stavros Sachtouris
    """
878 9b47150e Stavros Sachtouris
879 9b47150e Stavros Sachtouris
    @errors.generic.all
880 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
881 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
882 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
883 9b47150e Stavros Sachtouris
        self._optional_output(self.client.detach_floating_ip(server_id, ip))
884 9b47150e Stavros Sachtouris
885 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
886 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
887 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)