Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / cyclades.py @ 2e6e03da

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