Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / cyclades.py @ eb8208a5

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