Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (30 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 7493ccb6 Stavros Sachtouris
class server_firewall(_init_cyclades):
435 cd295a1d Stavros Sachtouris
    """Manage server (VM) firewall profiles for public networks"""
436 cd295a1d Stavros Sachtouris
437 cd295a1d Stavros Sachtouris
438 cd295a1d Stavros Sachtouris
@command(server_cmds)
439 cd295a1d Stavros Sachtouris
class server_firewall_set(_init_cyclades, _optional_output_cmd):
440 22b6f063 Stavros Sachtouris
    """Set the server (VM) firewall profile on VMs public network
441 22b6f063 Stavros Sachtouris
    Values for profile:
442 439826ec Stavros Sachtouris
    - DISABLED: Shutdown firewall
443 439826ec Stavros Sachtouris
    - ENABLED: Firewall in normal mode
444 439826ec Stavros Sachtouris
    - PROTECTED: Firewall in secure mode
445 22b6f063 Stavros Sachtouris
    """
446 7493ccb6 Stavros Sachtouris
447 5a673575 Stavros Sachtouris
    @errors.generic.all
448 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
449 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
450 5a673575 Stavros Sachtouris
    @errors.cyclades.firewall
451 5a673575 Stavros Sachtouris
    def _run(self, server_id, profile):
452 cd295a1d Stavros Sachtouris
        self._optional_output(self.client.set_firewall_profile(
453 cd295a1d Stavros Sachtouris
            server_id=int(server_id), profile=('%s' % profile).upper()))
454 5a673575 Stavros Sachtouris
455 7493ccb6 Stavros Sachtouris
    def main(self, server_id, profile):
456 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
457 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, profile=profile)
458 234954d1 Stavros Sachtouris
459 f3e94e06 Stavros Sachtouris
460 d486baec Stavros Sachtouris
@command(server_cmds)
461 cd295a1d Stavros Sachtouris
class server_firewall_get(_init_cyclades):
462 cd295a1d Stavros Sachtouris
    """Get the server (VM) firewall profile for its public network"""
463 cd295a1d Stavros Sachtouris
464 cd295a1d Stavros Sachtouris
    @errors.generic.all
465 cd295a1d Stavros Sachtouris
    @errors.cyclades.connection
466 cd295a1d Stavros Sachtouris
    @errors.cyclades.server_id
467 cd295a1d Stavros Sachtouris
    def _run(self, server_id):
468 cd295a1d Stavros Sachtouris
        print(self.client.get_firewall_profile(server_id))
469 cd295a1d Stavros Sachtouris
470 cd295a1d Stavros Sachtouris
    def main(self, server_id):
471 cd295a1d Stavros Sachtouris
        super(self.__class__, self)._run()
472 cd295a1d Stavros Sachtouris
        self._run(server_id=server_id)
473 cd295a1d Stavros Sachtouris
474 cd295a1d Stavros Sachtouris
475 cd295a1d Stavros Sachtouris
@command(server_cmds)
476 545c6c29 Stavros Sachtouris
class server_addr(_init_cyclades, _optional_json):
477 22b6f063 Stavros Sachtouris
    """List the addresses of all network interfaces on a server (VM)"""
478 7493ccb6 Stavros Sachtouris
479 cd295a1d Stavros Sachtouris
    arguments = dict(
480 545c6c29 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
481 cd295a1d Stavros Sachtouris
    )
482 cd295a1d Stavros Sachtouris
483 5a673575 Stavros Sachtouris
    @errors.generic.all
484 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
485 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
486 5a673575 Stavros Sachtouris
    def _run(self, server_id):
487 5a673575 Stavros Sachtouris
        reply = self.client.list_server_nics(int(server_id))
488 545c6c29 Stavros Sachtouris
        self._print(
489 545c6c29 Stavros Sachtouris
            reply, with_enumeration=self['enum'] and len(reply) > 1)
490 7493ccb6 Stavros Sachtouris
491 5a673575 Stavros Sachtouris
    def main(self, server_id):
492 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
493 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
494 5a673575 Stavros Sachtouris
495 234954d1 Stavros Sachtouris
496 d486baec Stavros Sachtouris
@command(server_cmds)
497 cd295a1d Stavros Sachtouris
class server_metadata(_init_cyclades):
498 cd295a1d Stavros Sachtouris
    """Manage Server metadata (key:value pairs of server attributes)"""
499 cd295a1d Stavros Sachtouris
500 cd295a1d Stavros Sachtouris
501 cd295a1d Stavros Sachtouris
@command(server_cmds)
502 545c6c29 Stavros Sachtouris
class server_metadata_list(_init_cyclades, _optional_json):
503 cd295a1d Stavros Sachtouris
    """Get server metadata"""
504 7493ccb6 Stavros Sachtouris
505 5a673575 Stavros Sachtouris
    @errors.generic.all
506 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
507 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
508 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
509 5a673575 Stavros Sachtouris
    def _run(self, server_id, key=''):
510 545c6c29 Stavros Sachtouris
        self._print(
511 bcef3ac9 Stavros Sachtouris
            self.client.get_server_metadata(int(server_id), key), print_dict)
512 5a673575 Stavros Sachtouris
513 a34888b4 Stavros Sachtouris
    def main(self, server_id, key=''):
514 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
515 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
516 7493ccb6 Stavros Sachtouris
517 234954d1 Stavros Sachtouris
518 d486baec Stavros Sachtouris
@command(server_cmds)
519 545c6c29 Stavros Sachtouris
class server_metadata_set(_init_cyclades, _optional_json):
520 cd295a1d Stavros Sachtouris
    """Set / update server(VM) metadata
521 cd295a1d Stavros Sachtouris
    Metadata should be given in key/value pairs in key=value format
522 9dc6159f Stavros Sachtouris
    For example: /server metadata set <server id> key1=value1 key2=value2
523 cd295a1d Stavros Sachtouris
    Old, unreferenced metadata will remain intact
524 22b6f063 Stavros Sachtouris
    """
525 7493ccb6 Stavros Sachtouris
526 5a673575 Stavros Sachtouris
    @errors.generic.all
527 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
528 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
529 cd295a1d Stavros Sachtouris
    def _run(self, server_id, keyvals):
530 545c6c29 Stavros Sachtouris
        assert keyvals, 'Please, add some metadata ( key=value)'
531 cd295a1d Stavros Sachtouris
        metadata = dict()
532 cd295a1d Stavros Sachtouris
        for keyval in keyvals:
533 cd295a1d Stavros Sachtouris
            k, sep, v = keyval.partition('=')
534 cd295a1d Stavros Sachtouris
            if sep and k:
535 cd295a1d Stavros Sachtouris
                metadata[k] = v
536 cd295a1d Stavros Sachtouris
            else:
537 cd295a1d Stavros Sachtouris
                raiseCLIError(
538 cd295a1d Stavros Sachtouris
                    'Invalid piece of metadata %s' % keyval,
539 cd295a1d Stavros Sachtouris
                    importance=2, details=[
540 cd295a1d Stavros Sachtouris
                        'Correct metadata format: key=val',
541 cd295a1d Stavros Sachtouris
                        'For example:',
542 cd295a1d Stavros Sachtouris
                        '/server metadata set <server id>'
543 cd295a1d Stavros Sachtouris
                        'key1=value1 key2=value2'])
544 545c6c29 Stavros Sachtouris
        self._print(
545 bcef3ac9 Stavros Sachtouris
            self.client.update_server_metadata(int(server_id), **metadata),
546 bcef3ac9 Stavros Sachtouris
            print_dict)
547 cd295a1d Stavros Sachtouris
548 cd295a1d Stavros Sachtouris
    def main(self, server_id, *key_equals_val):
549 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
550 cd295a1d Stavros Sachtouris
        self._run(server_id=server_id, keyvals=key_equals_val)
551 7493ccb6 Stavros Sachtouris
552 234954d1 Stavros Sachtouris
553 d486baec Stavros Sachtouris
@command(server_cmds)
554 cd295a1d Stavros Sachtouris
class server_metadata_delete(_init_cyclades, _optional_output_cmd):
555 22b6f063 Stavros Sachtouris
    """Delete server (VM) metadata"""
556 7493ccb6 Stavros Sachtouris
557 5a673575 Stavros Sachtouris
    @errors.generic.all
558 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
559 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
560 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
561 5a673575 Stavros Sachtouris
    def _run(self, server_id, key):
562 cd295a1d Stavros Sachtouris
        self._optional_output(
563 cd295a1d Stavros Sachtouris
            self.client.delete_server_metadata(int(server_id), key))
564 5a673575 Stavros Sachtouris
565 7493ccb6 Stavros Sachtouris
    def main(self, server_id, key):
566 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
567 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
568 234954d1 Stavros Sachtouris
569 7493ccb6 Stavros Sachtouris
570 d486baec Stavros Sachtouris
@command(server_cmds)
571 545c6c29 Stavros Sachtouris
class server_stats(_init_cyclades, _optional_json):
572 22b6f063 Stavros Sachtouris
    """Get server (VM) statistics"""
573 7493ccb6 Stavros Sachtouris
574 5a673575 Stavros Sachtouris
    @errors.generic.all
575 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
576 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
577 5a673575 Stavros Sachtouris
    def _run(self, server_id):
578 bcef3ac9 Stavros Sachtouris
        self._print(self.client.get_server_stats(int(server_id)), print_dict)
579 5a673575 Stavros Sachtouris
580 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
581 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
582 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
583 7493ccb6 Stavros Sachtouris
584 234954d1 Stavros Sachtouris
585 d486baec Stavros Sachtouris
@command(server_cmds)
586 60c42f9f Stavros Sachtouris
class server_wait(_init_cyclades, _server_wait):
587 fd1f1d96 Stavros Sachtouris
    """Wait for server to finish [BUILD, STOPPED, REBOOT, ACTIVE]"""
588 fd1f1d96 Stavros Sachtouris
589 5a673575 Stavros Sachtouris
    @errors.generic.all
590 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
591 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
592 5a673575 Stavros Sachtouris
    def _run(self, server_id, currect_status):
593 60c42f9f Stavros Sachtouris
        self._wait(server_id, currect_status)
594 fd1f1d96 Stavros Sachtouris
595 5a673575 Stavros Sachtouris
    def main(self, server_id, currect_status='BUILD'):
596 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
597 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, currect_status=currect_status)
598 5a673575 Stavros Sachtouris
599 fd1f1d96 Stavros Sachtouris
600 d486baec Stavros Sachtouris
@command(flavor_cmds)
601 545c6c29 Stavros Sachtouris
class flavor_list(_init_cyclades, _optional_json):
602 bd40efdf Stavros Sachtouris
    """List available hardware flavors"""
603 7493ccb6 Stavros Sachtouris
604 93914390 Stavros Sachtouris
    arguments = dict(
605 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
606 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed flavors', ('-n', '--number')),
607 bd40efdf Stavros Sachtouris
        more=FlagArgument(
608 de73876b Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
609 ed9af02c Stavros Sachtouris
            '--more'),
610 ed9af02c Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
611 93914390 Stavros Sachtouris
    )
612 7493ccb6 Stavros Sachtouris
613 5a673575 Stavros Sachtouris
    @errors.generic.all
614 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
615 5a673575 Stavros Sachtouris
    def _run(self):
616 5a673575 Stavros Sachtouris
        flavors = self.client.list_flavors(self['detail'])
617 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
618 7ba195e5 Stavros Sachtouris
            remove_from_items(flavors, 'links')
619 5a673575 Stavros Sachtouris
        pg_size = 10 if self['more'] and not self['limit'] else self['limit']
620 545c6c29 Stavros Sachtouris
        self._print(
621 ed9af02c Stavros Sachtouris
            flavors,
622 ed9af02c Stavros Sachtouris
            with_redundancy=self['detail'],
623 ed9af02c Stavros Sachtouris
            page_size=pg_size,
624 ed9af02c Stavros Sachtouris
            with_enumeration=self['enum'])
625 5a673575 Stavros Sachtouris
626 7493ccb6 Stavros Sachtouris
    def main(self):
627 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
628 5a673575 Stavros Sachtouris
        self._run()
629 7493ccb6 Stavros Sachtouris
630 234954d1 Stavros Sachtouris
631 d486baec Stavros Sachtouris
@command(flavor_cmds)
632 545c6c29 Stavros Sachtouris
class flavor_info(_init_cyclades, _optional_json):
633 769dbf53 Stavros Sachtouris
    """Detailed information on a hardware flavor
634 ddc0b290 Stavros Sachtouris
    To get a list of available flavors and flavor ids, try /flavor list
635 ddc0b290 Stavros Sachtouris
    """
636 7493ccb6 Stavros Sachtouris
637 5a673575 Stavros Sachtouris
    @errors.generic.all
638 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
639 5a673575 Stavros Sachtouris
    @errors.cyclades.flavor_id
640 5a673575 Stavros Sachtouris
    def _run(self, flavor_id):
641 bcef3ac9 Stavros Sachtouris
        self._print(
642 bcef3ac9 Stavros Sachtouris
            self.client.get_flavor_details(int(flavor_id)), print_dict)
643 7493ccb6 Stavros Sachtouris
644 5a673575 Stavros Sachtouris
    def main(self, flavor_id):
645 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
646 5a673575 Stavros Sachtouris
        self._run(flavor_id=flavor_id)
647 5a673575 Stavros Sachtouris
648 234954d1 Stavros Sachtouris
649 d486baec Stavros Sachtouris
@command(network_cmds)
650 545c6c29 Stavros Sachtouris
class network_info(_init_cyclades, _optional_json):
651 ddc0b290 Stavros Sachtouris
    """Detailed information on a network
652 ddc0b290 Stavros Sachtouris
    To get a list of available networks and network ids, try /network list
653 ddc0b290 Stavros Sachtouris
    """
654 c17b8bc0 Stavros Sachtouris
655 5a673575 Stavros Sachtouris
    @errors.generic.all
656 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
657 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
658 5a673575 Stavros Sachtouris
    def _run(self, network_id):
659 5a673575 Stavros Sachtouris
        network = self.client.get_network_details(int(network_id))
660 545c6c29 Stavros Sachtouris
        self._print(network, print_dict, exclude=('id'))
661 5a673575 Stavros Sachtouris
662 c17b8bc0 Stavros Sachtouris
    def main(self, network_id):
663 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
664 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
665 c17b8bc0 Stavros Sachtouris
666 c17b8bc0 Stavros Sachtouris
667 c17b8bc0 Stavros Sachtouris
@command(network_cmds)
668 545c6c29 Stavros Sachtouris
class network_list(_init_cyclades, _optional_json):
669 7493ccb6 Stavros Sachtouris
    """List networks"""
670 7493ccb6 Stavros Sachtouris
671 93914390 Stavros Sachtouris
    arguments = dict(
672 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
673 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed networks', ('-n', '--number')),
674 ddc0b290 Stavros Sachtouris
        more=FlagArgument(
675 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
676 ed9af02c Stavros Sachtouris
            '--more'),
677 ed9af02c Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
678 93914390 Stavros Sachtouris
    )
679 7493ccb6 Stavros Sachtouris
680 5a673575 Stavros Sachtouris
    @errors.generic.all
681 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
682 5a673575 Stavros Sachtouris
    def _run(self):
683 5a673575 Stavros Sachtouris
        networks = self.client.list_networks(self['detail'])
684 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
685 7ba195e5 Stavros Sachtouris
            remove_from_items(networks, 'links')
686 545c6c29 Stavros Sachtouris
        kwargs = dict(with_enumeration=self['enum'])
687 ddc0b290 Stavros Sachtouris
        if self['more']:
688 545c6c29 Stavros Sachtouris
            kwargs['page_size'] = self['limit'] or 10
689 0e806947 Stavros Sachtouris
        elif self['limit']:
690 545c6c29 Stavros Sachtouris
            networks = networks[:self['limit']]
691 545c6c29 Stavros Sachtouris
        self._print(networks, **kwargs)
692 7493ccb6 Stavros Sachtouris
693 5a673575 Stavros Sachtouris
    def main(self):
694 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
695 5a673575 Stavros Sachtouris
        self._run()
696 5a673575 Stavros Sachtouris
697 234954d1 Stavros Sachtouris
698 d486baec Stavros Sachtouris
@command(network_cmds)
699 77df3d4a Stavros Sachtouris
class network_create(_init_cyclades, _optional_json, _network_wait):
700 0e806947 Stavros Sachtouris
    """Create an (unconnected) network"""
701 7493ccb6 Stavros Sachtouris
702 93914390 Stavros Sachtouris
    arguments = dict(
703 0e806947 Stavros Sachtouris
        cidr=ValueArgument('explicitly set cidr', '--with-cidr'),
704 0e806947 Stavros Sachtouris
        gateway=ValueArgument('explicitly set gateway', '--with-gateway'),
705 9d1db11e Stavros Sachtouris
        dhcp=FlagArgument('Use dhcp (default: off)', '--with-dhcp'),
706 f6f81cd3 Stavros Sachtouris
        type=ValueArgument(
707 f6f81cd3 Stavros Sachtouris
            'Valid network types are '
708 f6f81cd3 Stavros Sachtouris
            'CUSTOM, IP_LESS_ROUTED, MAC_FILTERED (default), PHYSICAL_VLAN',
709 f6f81cd3 Stavros Sachtouris
            '--with-type',
710 77df3d4a Stavros Sachtouris
            default='MAC_FILTERED'),
711 77df3d4a Stavros Sachtouris
        wait=FlagArgument('Wait network to build', ('-w', '--wait'))
712 93914390 Stavros Sachtouris
    )
713 7493ccb6 Stavros Sachtouris
714 5a673575 Stavros Sachtouris
    @errors.generic.all
715 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
716 5a673575 Stavros Sachtouris
    @errors.cyclades.network_max
717 5a673575 Stavros Sachtouris
    def _run(self, name):
718 77df3d4a Stavros Sachtouris
        r = self.client.create_network(
719 de73876b Stavros Sachtouris
            name,
720 5a673575 Stavros Sachtouris
            cidr=self['cidr'],
721 5a673575 Stavros Sachtouris
            gateway=self['gateway'],
722 5a673575 Stavros Sachtouris
            dhcp=self['dhcp'],
723 77df3d4a Stavros Sachtouris
            type=self['type'])
724 77df3d4a Stavros Sachtouris
        self._print(r, print_dict)
725 77df3d4a Stavros Sachtouris
726 77df3d4a Stavros Sachtouris
        if self['wait']:
727 77df3d4a Stavros Sachtouris
            self._wait(r['id'], 'PENDING')
728 5a673575 Stavros Sachtouris
729 7493ccb6 Stavros Sachtouris
    def main(self, name):
730 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
731 5a673575 Stavros Sachtouris
        self._run(name)
732 7493ccb6 Stavros Sachtouris
733 234954d1 Stavros Sachtouris
734 d486baec Stavros Sachtouris
@command(network_cmds)
735 1b73b4c1 Stavros Sachtouris
class network_rename(_init_cyclades, _optional_output_cmd):
736 0e806947 Stavros Sachtouris
    """Set the name of a network"""
737 7493ccb6 Stavros Sachtouris
738 5a673575 Stavros Sachtouris
    @errors.generic.all
739 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
740 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
741 5a673575 Stavros Sachtouris
    def _run(self, network_id, new_name):
742 1b73b4c1 Stavros Sachtouris
        self._optional_output(
743 1b73b4c1 Stavros Sachtouris
                self.client.update_network_name(int(network_id), new_name))
744 5a673575 Stavros Sachtouris
745 7493ccb6 Stavros Sachtouris
    def main(self, network_id, new_name):
746 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
747 5a673575 Stavros Sachtouris
        self._run(network_id=network_id, new_name=new_name)
748 7493ccb6 Stavros Sachtouris
749 234954d1 Stavros Sachtouris
750 d486baec Stavros Sachtouris
@command(network_cmds)
751 77df3d4a Stavros Sachtouris
class network_delete(_init_cyclades, _optional_output_cmd, _network_wait):
752 7493ccb6 Stavros Sachtouris
    """Delete a network"""
753 7493ccb6 Stavros Sachtouris
754 77df3d4a Stavros Sachtouris
    arguments = dict(
755 77df3d4a Stavros Sachtouris
        wait=FlagArgument('Wait network to build', ('-w', '--wait'))
756 77df3d4a Stavros Sachtouris
    )
757 77df3d4a 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
    @errors.cyclades.network_in_use
762 5a673575 Stavros Sachtouris
    def _run(self, network_id):
763 77df3d4a Stavros Sachtouris
        status = 'DELETED'
764 77df3d4a Stavros Sachtouris
        if self['wait']:
765 77df3d4a Stavros Sachtouris
            r = self.client.get_network_details(network_id)
766 77df3d4a Stavros Sachtouris
            status = r['status']
767 77df3d4a Stavros Sachtouris
            if status in ('DELETED', ):
768 77df3d4a Stavros Sachtouris
                return
769 77df3d4a Stavros Sachtouris
770 77df3d4a Stavros Sachtouris
        r = self.client.delete_network(int(network_id))
771 77df3d4a Stavros Sachtouris
        self._optional_output(r)
772 77df3d4a Stavros Sachtouris
773 77df3d4a Stavros Sachtouris
        if self['wait']:
774 77df3d4a Stavros Sachtouris
            self._wait(network_id, status)
775 5a673575 Stavros Sachtouris
776 7493ccb6 Stavros Sachtouris
    def main(self, network_id):
777 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
778 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
779 7493ccb6 Stavros Sachtouris
780 234954d1 Stavros Sachtouris
781 d486baec Stavros Sachtouris
@command(network_cmds)
782 1b73b4c1 Stavros Sachtouris
class network_connect(_init_cyclades, _optional_output_cmd):
783 7493ccb6 Stavros Sachtouris
    """Connect a server to a network"""
784 7493ccb6 Stavros Sachtouris
785 5a673575 Stavros Sachtouris
    @errors.generic.all
786 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
787 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
788 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
789 5a673575 Stavros Sachtouris
    def _run(self, server_id, network_id):
790 1b73b4c1 Stavros Sachtouris
        self._optional_output(
791 1b73b4c1 Stavros Sachtouris
                self.client.connect_server(int(server_id), int(network_id)))
792 5a673575 Stavros Sachtouris
793 7493ccb6 Stavros Sachtouris
    def main(self, server_id, network_id):
794 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
795 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, network_id=network_id)
796 7493ccb6 Stavros Sachtouris
797 234954d1 Stavros Sachtouris
798 d486baec Stavros Sachtouris
@command(network_cmds)
799 7493ccb6 Stavros Sachtouris
class network_disconnect(_init_cyclades):
800 0e806947 Stavros Sachtouris
    """Disconnect a nic that connects a server to a network
801 0e806947 Stavros Sachtouris
    Nic ids are listed as "attachments" in detailed network information
802 439826ec Stavros Sachtouris
    To get detailed network information: /network info <network id>
803 0e806947 Stavros Sachtouris
    """
804 7493ccb6 Stavros Sachtouris
805 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_format
806 5a673575 Stavros Sachtouris
    def _server_id_from_nic(self, nic_id):
807 5a673575 Stavros Sachtouris
        return nic_id.split('-')[1]
808 5a673575 Stavros Sachtouris
809 5a673575 Stavros Sachtouris
    @errors.generic.all
810 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
811 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
812 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_id
813 5a673575 Stavros Sachtouris
    def _run(self, nic_id, server_id):
814 1b73b4c1 Stavros Sachtouris
        num_of_disconnected = self.client.disconnect_server(server_id, nic_id)
815 1b73b4c1 Stavros Sachtouris
        if not num_of_disconnected:
816 5a673575 Stavros Sachtouris
            raise ClientError(
817 5a673575 Stavros Sachtouris
                'Network Interface %s not found on server %s' % (
818 5a673575 Stavros Sachtouris
                    nic_id,
819 5a673575 Stavros Sachtouris
                    server_id),
820 5a673575 Stavros Sachtouris
                status=404)
821 1b73b4c1 Stavros Sachtouris
        print('Disconnected %s connections' % num_of_disconnected)
822 5a673575 Stavros Sachtouris
823 7493ccb6 Stavros Sachtouris
    def main(self, nic_id):
824 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
825 5a673575 Stavros Sachtouris
        server_id = self._server_id_from_nic(nic_id=nic_id)
826 5a673575 Stavros Sachtouris
        self._run(nic_id=nic_id, server_id=server_id)
827 9b47150e Stavros Sachtouris
828 9b47150e Stavros Sachtouris
829 7b2e4bf1 Stavros Sachtouris
@command(network_cmds)
830 7b2e4bf1 Stavros Sachtouris
class network_wait(_init_cyclades, _network_wait):
831 7b2e4bf1 Stavros Sachtouris
    """Wait for server to finish [PENDING, ACTIVE, DELETED]"""
832 7b2e4bf1 Stavros Sachtouris
833 7b2e4bf1 Stavros Sachtouris
    @errors.generic.all
834 7b2e4bf1 Stavros Sachtouris
    @errors.cyclades.connection
835 7b2e4bf1 Stavros Sachtouris
    @errors.cyclades.network_id
836 7b2e4bf1 Stavros Sachtouris
    def _run(self, network_id, currect_status):
837 7b2e4bf1 Stavros Sachtouris
        self._wait(network_id, currect_status)
838 7b2e4bf1 Stavros Sachtouris
839 7b2e4bf1 Stavros Sachtouris
    def main(self, network_id, currect_status='PENDING'):
840 7b2e4bf1 Stavros Sachtouris
        super(self.__class__, self)._run()
841 7b2e4bf1 Stavros Sachtouris
        self._run(network_id=network_id, currect_status=currect_status)
842 7b2e4bf1 Stavros Sachtouris
843 7b2e4bf1 Stavros Sachtouris
844 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
845 9b47150e Stavros Sachtouris
class floatingip_pools(_init_cyclades, _optional_json):
846 9b47150e Stavros Sachtouris
    """List all floating pools of floating ips"""
847 9b47150e Stavros Sachtouris
848 9b47150e Stavros Sachtouris
    @errors.generic.all
849 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
850 9b47150e Stavros Sachtouris
    def _run(self):
851 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ip_pools()
852 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ip_pools'])
853 9b47150e Stavros Sachtouris
854 9b47150e Stavros Sachtouris
    def main(self):
855 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
856 9b47150e Stavros Sachtouris
        self._run()
857 9b47150e Stavros Sachtouris
858 9b47150e Stavros Sachtouris
859 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
860 9b47150e Stavros Sachtouris
class floatingip_list(_init_cyclades, _optional_json):
861 9b47150e Stavros Sachtouris
    """List all floating ips"""
862 9b47150e Stavros Sachtouris
863 9b47150e Stavros Sachtouris
    @errors.generic.all
864 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
865 9b47150e Stavros Sachtouris
    def _run(self):
866 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ips()
867 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ips'])
868 9b47150e Stavros Sachtouris
869 9b47150e Stavros Sachtouris
    def main(self):
870 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
871 9b47150e Stavros Sachtouris
        self._run()
872 9b47150e Stavros Sachtouris
873 9b47150e Stavros Sachtouris
874 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
875 9b47150e Stavros Sachtouris
class floatingip_info(_init_cyclades, _optional_json):
876 9b47150e Stavros Sachtouris
    """A floating IPs' details"""
877 9b47150e Stavros Sachtouris
878 9b47150e Stavros Sachtouris
    @errors.generic.all
879 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
880 9b47150e Stavros Sachtouris
    def _run(self, ip):
881 9b47150e Stavros Sachtouris
        self._print(self.client.get_floating_ip(ip), print_dict)
882 9b47150e Stavros Sachtouris
883 9b47150e Stavros Sachtouris
    def main(self, ip):
884 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
885 9b47150e Stavros Sachtouris
        self._run(ip=ip)
886 9b47150e Stavros Sachtouris
887 9b47150e Stavros Sachtouris
888 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
889 9b47150e Stavros Sachtouris
class floatingip_create(_init_cyclades, _optional_json):
890 9b47150e Stavros Sachtouris
    """Create a new floating IP"""
891 9b47150e Stavros Sachtouris
892 9b47150e Stavros Sachtouris
    arguments = dict(
893 9b47150e Stavros Sachtouris
        pool=ValueArgument('Source IP pool', ('--pool'), None)
894 9b47150e Stavros Sachtouris
    )
895 9b47150e Stavros Sachtouris
896 9b47150e Stavros Sachtouris
    @errors.generic.all
897 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
898 9b47150e Stavros Sachtouris
    def _run(self, ip=None):
899 9b47150e Stavros Sachtouris
        self._print(
900 9b47150e Stavros Sachtouris
            self.client.alloc_floating_ip(self['pool'], ip), print_dict)
901 9b47150e Stavros Sachtouris
902 9b47150e Stavros Sachtouris
    def main(self, requested_address=None):
903 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
904 9b47150e Stavros Sachtouris
        self._run(ip=requested_address)
905 9b47150e Stavros Sachtouris
906 9b47150e Stavros Sachtouris
907 9b47150e Stavros Sachtouris
@command(floatingip_cmds)
908 9b47150e Stavros Sachtouris
class floatingip_delete(_init_cyclades, _optional_output_cmd):
909 9b47150e Stavros Sachtouris
    """Delete a floating ip"""
910 9b47150e Stavros Sachtouris
911 9b47150e Stavros Sachtouris
    @errors.generic.all
912 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
913 9b47150e Stavros Sachtouris
    def _run(self, ip):
914 9b47150e Stavros Sachtouris
        self._optional_output(self.client.delete_floating_ip(ip))
915 9b47150e Stavros Sachtouris
916 9b47150e Stavros Sachtouris
    def main(self, ip):
917 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
918 9b47150e Stavros Sachtouris
        self._run(ip=ip)
919 9b47150e Stavros Sachtouris
920 9b47150e Stavros Sachtouris
921 9b47150e Stavros Sachtouris
@command(server_cmds)
922 9b47150e Stavros Sachtouris
class server_ip_attach(_init_cyclades, _optional_output_cmd):
923 9b47150e Stavros Sachtouris
    """Attach a floating ip to a server with server_id
924 9b47150e Stavros Sachtouris
    """
925 9b47150e Stavros Sachtouris
926 9b47150e Stavros Sachtouris
    @errors.generic.all
927 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
928 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
929 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
930 9b47150e Stavros Sachtouris
        self._optional_output(self.client.attach_floating_ip(server_id, ip))
931 9b47150e Stavros Sachtouris
932 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
933 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
934 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)
935 9b47150e Stavros Sachtouris
936 9b47150e Stavros Sachtouris
937 9b47150e Stavros Sachtouris
@command(server_cmds)
938 9b47150e Stavros Sachtouris
class server_ip_detach(_init_cyclades):
939 9b47150e Stavros Sachtouris
    """detach_floating_ip_to_server
940 9b47150e Stavros Sachtouris
    """
941 9b47150e Stavros Sachtouris
942 9b47150e Stavros Sachtouris
    @errors.generic.all
943 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
944 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
945 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
946 9b47150e Stavros Sachtouris
        self._optional_output(self.client.detach_floating_ip(server_id, ip))
947 9b47150e Stavros Sachtouris
948 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
949 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
950 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)