Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (35.4 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 89ea97e1 Stavros Sachtouris
from kamaki.cli.utils import (
37 89ea97e1 Stavros Sachtouris
    print_dict, remove_from_items, filter_dicts_by_dict)
38 8cec3671 Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError, CLISyntaxError, CLIBaseUrlError
39 7493ccb6 Stavros Sachtouris
from kamaki.clients.cyclades import CycladesClient, ClientError
40 57d622b6 Stavros Sachtouris
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
41 bd40efdf Stavros Sachtouris
from kamaki.cli.argument import ProgressBarArgument, DateArgument, IntArgument
42 b4f69041 Stavros Sachtouris
from kamaki.cli.commands import _command_init, errors, addLogSettings
43 6d190dd1 Stavros Sachtouris
from kamaki.cli.commands import (
44 6d190dd1 Stavros Sachtouris
    _optional_output_cmd, _optional_json, _name_filter, _id_filter)
45 5eae854d Stavros Sachtouris
46 f3e94e06 Stavros Sachtouris
from base64 import b64encode
47 234954d1 Stavros Sachtouris
from os.path import exists
48 234954d1 Stavros Sachtouris
49 234954d1 Stavros Sachtouris
50 a29d2f88 Stavros Sachtouris
server_cmds = CommandTree('server', 'Cyclades/Compute API server commands')
51 a29d2f88 Stavros Sachtouris
flavor_cmds = CommandTree('flavor', 'Cyclades/Compute API flavor commands')
52 a29d2f88 Stavros Sachtouris
network_cmds = CommandTree('network', 'Cyclades/Compute API network commands')
53 8be50626 Stavros Sachtouris
_commands = [server_cmds, flavor_cmds, network_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 6d190dd1 Stavros Sachtouris
class server_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
160 c314fc10 Stavros Sachtouris
    """List Virtual Machines accessible by user"""
161 18edacfe Stavros Sachtouris
162 89ea97e1 Stavros Sachtouris
    PERMANENTS = ('id', 'name')
163 89ea97e1 Stavros Sachtouris
164 18edacfe Stavros Sachtouris
    __doc__ += about_authentication
165 7493ccb6 Stavros Sachtouris
166 e15d78e2 Stavros Sachtouris
    arguments = dict(
167 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
168 67469d65 Stavros Sachtouris
        since=DateArgument(
169 a382ea56 Stavros Sachtouris
            'show only items since date (\' d/m/Y H:M:S \')',
170 a4d0d88a Stavros Sachtouris
            '--since'),
171 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit number of listed VMs', ('-n', '--number')),
172 a4d0d88a Stavros Sachtouris
        more=FlagArgument(
173 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
174 ed9af02c Stavros Sachtouris
            '--more'),
175 89ea97e1 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
176 89ea97e1 Stavros Sachtouris
        flavor_id=ValueArgument('filter by flavor id', ('--flavor-id')),
177 89ea97e1 Stavros Sachtouris
        image_id=ValueArgument('filter by image id', ('--image-id')),
178 d8ff7b56 Stavros Sachtouris
        user_id=ValueArgument('filter by user id', ('--user-id')),
179 d8ff7b56 Stavros Sachtouris
        user_name=ValueArgument('filter by user name', ('--user-name')),
180 d8ff7b56 Stavros Sachtouris
        status=ValueArgument(
181 d8ff7b56 Stavros Sachtouris
            'filter by status (ACTIVE, STOPPED, REBOOT, ERROR, etc.)',
182 d8ff7b56 Stavros Sachtouris
            ('--status')),
183 89ea97e1 Stavros Sachtouris
        meta=KeyValueArgument('filter by metadata key=values', ('--metadata')),
184 89ea97e1 Stavros Sachtouris
        meta_like=KeyValueArgument(
185 89ea97e1 Stavros Sachtouris
            'print only if in key=value, the value is part of actual value',
186 89ea97e1 Stavros Sachtouris
            ('--metadata-like')),
187 e15d78e2 Stavros Sachtouris
    )
188 e15d78e2 Stavros Sachtouris
189 f00db940 Stavros Sachtouris
    def _add_user_name(self, servers):
190 9d2f656a Stavros Sachtouris
        uuids = self._uuids2usernames(list(set(
191 9d2f656a Stavros Sachtouris
                [srv['user_id'] for srv in servers] +
192 9d2f656a Stavros Sachtouris
                [srv['tenant_id'] for srv in servers])))
193 f00db940 Stavros Sachtouris
        for srv in servers:
194 f00db940 Stavros Sachtouris
            srv['user_id'] += ' (%s)' % uuids[srv['user_id']]
195 9d2f656a Stavros Sachtouris
            srv['tenant_id'] += ' (%s)' % uuids[srv['tenant_id']]
196 f00db940 Stavros Sachtouris
        return servers
197 f00db940 Stavros Sachtouris
198 d8ff7b56 Stavros Sachtouris
    def _apply_common_filters(self, servers):
199 d8ff7b56 Stavros Sachtouris
        common_filters = dict()
200 d8ff7b56 Stavros Sachtouris
        if self['status']:
201 d8ff7b56 Stavros Sachtouris
            common_filters['status'] = self['status']
202 d8ff7b56 Stavros Sachtouris
        if self['user_id'] or self['user_name']:
203 d8ff7b56 Stavros Sachtouris
            uuid = self['user_id'] or self._username2uuid(self['user_name'])
204 d8ff7b56 Stavros Sachtouris
            common_filters['user_id'] = uuid
205 d8ff7b56 Stavros Sachtouris
        return filter_dicts_by_dict(servers, common_filters)
206 d8ff7b56 Stavros Sachtouris
207 6d190dd1 Stavros Sachtouris
    def _filter_by_image(self, servers):
208 89ea97e1 Stavros Sachtouris
        iid = self['image_id']
209 89ea97e1 Stavros Sachtouris
        new_servers = []
210 89ea97e1 Stavros Sachtouris
        for srv in servers:
211 89ea97e1 Stavros Sachtouris
            if srv['image']['id'] == iid:
212 89ea97e1 Stavros Sachtouris
                new_servers.append(srv)
213 89ea97e1 Stavros Sachtouris
        return new_servers
214 89ea97e1 Stavros Sachtouris
215 6d190dd1 Stavros Sachtouris
    def _filter_by_flavor(self, servers):
216 89ea97e1 Stavros Sachtouris
        fid = self['flavor_id']
217 89ea97e1 Stavros Sachtouris
        new_servers = []
218 89ea97e1 Stavros Sachtouris
        for srv in servers:
219 89ea97e1 Stavros Sachtouris
            if '%s' % srv['flavor']['id'] == '%s' % fid:
220 89ea97e1 Stavros Sachtouris
                new_servers.append(srv)
221 89ea97e1 Stavros Sachtouris
        return new_servers
222 89ea97e1 Stavros Sachtouris
223 6d190dd1 Stavros Sachtouris
    def _filter_by_metadata(self, servers):
224 89ea97e1 Stavros Sachtouris
        new_servers = []
225 89ea97e1 Stavros Sachtouris
        for srv in servers:
226 89ea97e1 Stavros Sachtouris
            if not 'metadata' in srv:
227 89ea97e1 Stavros Sachtouris
                continue
228 89ea97e1 Stavros Sachtouris
            meta = [dict(srv['metadata'])]
229 89ea97e1 Stavros Sachtouris
            if self['meta']:
230 89ea97e1 Stavros Sachtouris
                meta = filter_dicts_by_dict(meta, self['meta'])
231 89ea97e1 Stavros Sachtouris
            if meta and self['meta_like']:
232 89ea97e1 Stavros Sachtouris
                meta = filter_dicts_by_dict(
233 89ea97e1 Stavros Sachtouris
                    meta, self['meta_like'], exact_match=False)
234 89ea97e1 Stavros Sachtouris
            if meta:
235 89ea97e1 Stavros Sachtouris
                new_servers.append(srv)
236 89ea97e1 Stavros Sachtouris
        return new_servers
237 89ea97e1 Stavros Sachtouris
238 b04288f7 Stavros Sachtouris
    @errors.generic.all
239 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
240 b04288f7 Stavros Sachtouris
    @errors.cyclades.date
241 b04288f7 Stavros Sachtouris
    def _run(self):
242 89ea97e1 Stavros Sachtouris
        withimage = bool(self['image_id'])
243 89ea97e1 Stavros Sachtouris
        withflavor = bool(self['flavor_id'])
244 89ea97e1 Stavros Sachtouris
        withmeta = bool(self['meta'] or self['meta_like'])
245 d8ff7b56 Stavros Sachtouris
        withcommons = bool(
246 d8ff7b56 Stavros Sachtouris
            self['status'] or self['user_id'] or self['user_name'])
247 d8ff7b56 Stavros Sachtouris
        detail = self['detail'] or (
248 d8ff7b56 Stavros Sachtouris
            withimage or withflavor or withmeta or withcommons)
249 89ea97e1 Stavros Sachtouris
        servers = self.client.list_servers(detail, self['since'])
250 89ea97e1 Stavros Sachtouris
251 6d190dd1 Stavros Sachtouris
        servers = self._filter_by_name(servers)
252 6d190dd1 Stavros Sachtouris
        servers = self._filter_by_id(servers)
253 d8ff7b56 Stavros Sachtouris
        servers = self._apply_common_filters(servers)
254 89ea97e1 Stavros Sachtouris
        if withimage:
255 6d190dd1 Stavros Sachtouris
            servers = self._filter_by_image(servers)
256 89ea97e1 Stavros Sachtouris
        if withflavor:
257 6d190dd1 Stavros Sachtouris
            servers = self._filter_by_flavor(servers)
258 89ea97e1 Stavros Sachtouris
        if withmeta:
259 6d190dd1 Stavros Sachtouris
            servers = self._filter_by_metadata(servers)
260 89ea97e1 Stavros Sachtouris
261 f00db940 Stavros Sachtouris
        if self['detail'] and not self['json_output']:
262 f00db940 Stavros Sachtouris
            servers = self._add_user_name(servers)
263 f00db940 Stavros Sachtouris
        elif not (self['detail'] or self['json_output']):
264 7ba195e5 Stavros Sachtouris
            remove_from_items(servers, 'links')
265 89ea97e1 Stavros Sachtouris
        if detail and not self['detail']:
266 89ea97e1 Stavros Sachtouris
            for srv in servers:
267 89ea97e1 Stavros Sachtouris
                for key in set(srv).difference(self.PERMANENTS):
268 89ea97e1 Stavros Sachtouris
                    srv.pop(key)
269 545c6c29 Stavros Sachtouris
        kwargs = dict(with_enumeration=self['enum'])
270 a4d0d88a Stavros Sachtouris
        if self['more']:
271 545c6c29 Stavros Sachtouris
            kwargs['page_size'] = self['limit'] if self['limit'] else 10
272 545c6c29 Stavros Sachtouris
        elif self['limit']:
273 545c6c29 Stavros Sachtouris
            servers = servers[:self['limit']]
274 545c6c29 Stavros Sachtouris
        self._print(servers, **kwargs)
275 7493ccb6 Stavros Sachtouris
276 b04288f7 Stavros Sachtouris
    def main(self):
277 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
278 b04288f7 Stavros Sachtouris
        self._run()
279 b04288f7 Stavros Sachtouris
280 234954d1 Stavros Sachtouris
281 d486baec Stavros Sachtouris
@command(server_cmds)
282 545c6c29 Stavros Sachtouris
class server_info(_init_cyclades, _optional_json):
283 67469d65 Stavros Sachtouris
    """Detailed information on a Virtual Machine
284 67469d65 Stavros Sachtouris
    Contains:
285 67469d65 Stavros Sachtouris
    - name, id, status, create/update dates
286 67469d65 Stavros Sachtouris
    - network interfaces
287 67469d65 Stavros Sachtouris
    - metadata (e.g. os, superuser) and diagnostics
288 67469d65 Stavros Sachtouris
    - hardware flavor and os image ids
289 67469d65 Stavros Sachtouris
    """
290 7493ccb6 Stavros Sachtouris
291 b04288f7 Stavros Sachtouris
    @errors.generic.all
292 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
293 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
294 b04288f7 Stavros Sachtouris
    def _run(self, server_id):
295 bcef3ac9 Stavros Sachtouris
        self._print(self.client.get_server_details(server_id), print_dict)
296 7493ccb6 Stavros Sachtouris
297 b04288f7 Stavros Sachtouris
    def main(self, server_id):
298 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
299 b04288f7 Stavros Sachtouris
        self._run(server_id=server_id)
300 b04288f7 Stavros Sachtouris
301 234954d1 Stavros Sachtouris
302 57d622b6 Stavros Sachtouris
class PersonalityArgument(KeyValueArgument):
303 234954d1 Stavros Sachtouris
    @property
304 f3e94e06 Stavros Sachtouris
    def value(self):
305 57d622b6 Stavros Sachtouris
        return self._value if hasattr(self, '_value') else []
306 234954d1 Stavros Sachtouris
307 234954d1 Stavros Sachtouris
    @value.setter
308 f3e94e06 Stavros Sachtouris
    def value(self, newvalue):
309 f3e94e06 Stavros Sachtouris
        if newvalue == self.default:
310 f3e94e06 Stavros Sachtouris
            return self.value
311 57d622b6 Stavros Sachtouris
        self._value = []
312 57d622b6 Stavros Sachtouris
        for i, terms in enumerate(newvalue):
313 57d622b6 Stavros Sachtouris
            termlist = terms.split(',')
314 57d622b6 Stavros Sachtouris
            if len(termlist) > 5:
315 de73876b Stavros Sachtouris
                msg = 'Wrong number of terms (should be 1 to 5)'
316 de73876b Stavros Sachtouris
                raiseCLIError(CLISyntaxError(msg), details=howto_personality)
317 57d622b6 Stavros Sachtouris
            path = termlist[0]
318 57d622b6 Stavros Sachtouris
            if not exists(path):
319 de73876b Stavros Sachtouris
                raiseCLIError(
320 de73876b Stavros Sachtouris
                    None,
321 8194b51b Stavros Sachtouris
                    '--personality: File %s does not exist' % path,
322 8194b51b Stavros Sachtouris
                    importance=1,
323 8194b51b Stavros Sachtouris
                    details=howto_personality)
324 57d622b6 Stavros Sachtouris
            self._value.append(dict(path=path))
325 57d622b6 Stavros Sachtouris
            with open(path) as f:
326 57d622b6 Stavros Sachtouris
                self._value[i]['contents'] = b64encode(f.read())
327 57d622b6 Stavros Sachtouris
            try:
328 57d622b6 Stavros Sachtouris
                self._value[i]['path'] = termlist[1]
329 57d622b6 Stavros Sachtouris
                self._value[i]['owner'] = termlist[2]
330 57d622b6 Stavros Sachtouris
                self._value[i]['group'] = termlist[3]
331 57d622b6 Stavros Sachtouris
                self._value[i]['mode'] = termlist[4]
332 57d622b6 Stavros Sachtouris
            except IndexError:
333 57d622b6 Stavros Sachtouris
                pass
334 f3e94e06 Stavros Sachtouris
335 234954d1 Stavros Sachtouris
336 d486baec Stavros Sachtouris
@command(server_cmds)
337 60c42f9f Stavros Sachtouris
class server_create(_init_cyclades, _optional_json, _server_wait):
338 8194b51b Stavros Sachtouris
    """Create a server (aka Virtual Machine)
339 8194b51b Stavros Sachtouris
    Parameters:
340 439826ec Stavros Sachtouris
    - name: (single quoted text)
341 439826ec Stavros Sachtouris
    - flavor id: Hardware flavor. Pick one from: /flavor list
342 439826ec Stavros Sachtouris
    - image id: OS images. Pick one from: /image list
343 8194b51b Stavros Sachtouris
    """
344 7493ccb6 Stavros Sachtouris
345 93914390 Stavros Sachtouris
    arguments = dict(
346 93914390 Stavros Sachtouris
        personality=PersonalityArgument(
347 60c42f9f Stavros Sachtouris
            (80 * ' ').join(howto_personality), ('-p', '--personality')),
348 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to build', ('-w', '--wait'))
349 93914390 Stavros Sachtouris
    )
350 f3e94e06 Stavros Sachtouris
351 b04288f7 Stavros Sachtouris
    @errors.generic.all
352 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
353 b04288f7 Stavros Sachtouris
    @errors.plankton.id
354 b04288f7 Stavros Sachtouris
    @errors.cyclades.flavor_id
355 b04288f7 Stavros Sachtouris
    def _run(self, name, flavor_id, image_id):
356 60c42f9f Stavros Sachtouris
        r = self.client.create_server(
357 60c42f9f Stavros Sachtouris
            name, int(flavor_id), image_id, self['personality'])
358 60c42f9f Stavros Sachtouris
        self._print(r, print_dict)
359 60c42f9f Stavros Sachtouris
        if self['wait']:
360 60c42f9f Stavros Sachtouris
            self._wait(r['id'], r['status'])
361 b04288f7 Stavros Sachtouris
362 7493ccb6 Stavros Sachtouris
    def main(self, name, flavor_id, image_id):
363 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
364 b04288f7 Stavros Sachtouris
        self._run(name=name, flavor_id=flavor_id, image_id=image_id)
365 7493ccb6 Stavros Sachtouris
366 234954d1 Stavros Sachtouris
367 d486baec Stavros Sachtouris
@command(server_cmds)
368 cd295a1d Stavros Sachtouris
class server_rename(_init_cyclades, _optional_output_cmd):
369 22b6f063 Stavros Sachtouris
    """Set/update a server (VM) name
370 5a673575 Stavros Sachtouris
    VM names are not unique, therefore multiple servers may share the same name
371 22b6f063 Stavros Sachtouris
    """
372 7493ccb6 Stavros Sachtouris
373 5a673575 Stavros Sachtouris
    @errors.generic.all
374 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
375 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
376 5a673575 Stavros Sachtouris
    def _run(self, server_id, new_name):
377 cd295a1d Stavros Sachtouris
        self._optional_output(
378 cd295a1d Stavros Sachtouris
            self.client.update_server_name(int(server_id), new_name))
379 5a673575 Stavros Sachtouris
380 7493ccb6 Stavros Sachtouris
    def main(self, server_id, new_name):
381 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
382 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, new_name=new_name)
383 234954d1 Stavros Sachtouris
384 7493ccb6 Stavros Sachtouris
385 d486baec Stavros Sachtouris
@command(server_cmds)
386 60c42f9f Stavros Sachtouris
class server_delete(_init_cyclades, _optional_output_cmd, _server_wait):
387 22b6f063 Stavros Sachtouris
    """Delete a server (VM)"""
388 7493ccb6 Stavros Sachtouris
389 60c42f9f Stavros Sachtouris
    arguments = dict(
390 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
391 60c42f9f Stavros Sachtouris
    )
392 60c42f9f Stavros Sachtouris
393 5a673575 Stavros Sachtouris
    @errors.generic.all
394 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
395 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
396 5a673575 Stavros Sachtouris
    def _run(self, server_id):
397 60c42f9f Stavros Sachtouris
            status = 'DELETED'
398 60c42f9f Stavros Sachtouris
            if self['wait']:
399 60c42f9f Stavros Sachtouris
                details = self.client.get_server_details(server_id)
400 60c42f9f Stavros Sachtouris
                status = details['status']
401 60c42f9f Stavros Sachtouris
402 60c42f9f Stavros Sachtouris
            r = self.client.delete_server(int(server_id))
403 60c42f9f Stavros Sachtouris
            self._optional_output(r)
404 60c42f9f Stavros Sachtouris
405 60c42f9f Stavros Sachtouris
            if self['wait']:
406 60c42f9f Stavros Sachtouris
                self._wait(server_id, status)
407 5a673575 Stavros Sachtouris
408 5a673575 Stavros Sachtouris
    def main(self, server_id):
409 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
410 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
411 234954d1 Stavros Sachtouris
412 7493ccb6 Stavros Sachtouris
413 d486baec Stavros Sachtouris
@command(server_cmds)
414 60c42f9f Stavros Sachtouris
class server_reboot(_init_cyclades, _optional_output_cmd, _server_wait):
415 22b6f063 Stavros Sachtouris
    """Reboot a server (VM)"""
416 18edacfe Stavros Sachtouris
417 93914390 Stavros Sachtouris
    arguments = dict(
418 60c42f9f Stavros Sachtouris
        hard=FlagArgument('perform a hard reboot', ('-f', '--force')),
419 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
420 93914390 Stavros Sachtouris
    )
421 7493ccb6 Stavros Sachtouris
422 5a673575 Stavros Sachtouris
    @errors.generic.all
423 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
424 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
425 5a673575 Stavros Sachtouris
    def _run(self, server_id):
426 60c42f9f Stavros Sachtouris
        r = self.client.reboot_server(int(server_id), self['hard'])
427 60c42f9f Stavros Sachtouris
        self._optional_output(r)
428 60c42f9f Stavros Sachtouris
429 60c42f9f Stavros Sachtouris
        if self['wait']:
430 60c42f9f Stavros Sachtouris
            self._wait(server_id, 'REBOOT')
431 5a673575 Stavros Sachtouris
432 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
433 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
434 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
435 234954d1 Stavros Sachtouris
436 7493ccb6 Stavros Sachtouris
437 d486baec Stavros Sachtouris
@command(server_cmds)
438 60c42f9f Stavros Sachtouris
class server_start(_init_cyclades, _optional_output_cmd, _server_wait):
439 22b6f063 Stavros Sachtouris
    """Start an existing server (VM)"""
440 7493ccb6 Stavros Sachtouris
441 60c42f9f Stavros Sachtouris
    arguments = dict(
442 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
443 60c42f9f Stavros Sachtouris
    )
444 60c42f9f Stavros Sachtouris
445 5a673575 Stavros Sachtouris
    @errors.generic.all
446 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
447 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
448 5a673575 Stavros Sachtouris
    def _run(self, server_id):
449 60c42f9f Stavros Sachtouris
        status = 'ACTIVE'
450 60c42f9f Stavros Sachtouris
        if self['wait']:
451 60c42f9f Stavros Sachtouris
            details = self.client.get_server_details(server_id)
452 60c42f9f Stavros Sachtouris
            status = details['status']
453 60c42f9f Stavros Sachtouris
            if status in ('ACTIVE', ):
454 60c42f9f Stavros Sachtouris
                return
455 60c42f9f Stavros Sachtouris
456 60c42f9f Stavros Sachtouris
        r = self.client.start_server(int(server_id))
457 60c42f9f Stavros Sachtouris
        self._optional_output(r)
458 60c42f9f Stavros Sachtouris
459 60c42f9f Stavros Sachtouris
        if self['wait']:
460 60c42f9f Stavros Sachtouris
            self._wait(server_id, status)
461 5a673575 Stavros Sachtouris
462 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
463 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
464 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
465 234954d1 Stavros Sachtouris
466 7493ccb6 Stavros Sachtouris
467 d486baec Stavros Sachtouris
@command(server_cmds)
468 60c42f9f Stavros Sachtouris
class server_shutdown(_init_cyclades, _optional_output_cmd, _server_wait):
469 22b6f063 Stavros Sachtouris
    """Shutdown an active server (VM)"""
470 7493ccb6 Stavros Sachtouris
471 60c42f9f Stavros Sachtouris
    arguments = dict(
472 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
473 60c42f9f Stavros Sachtouris
    )
474 60c42f9f Stavros Sachtouris
475 5a673575 Stavros Sachtouris
    @errors.generic.all
476 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
477 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
478 5a673575 Stavros Sachtouris
    def _run(self, server_id):
479 60c42f9f Stavros Sachtouris
        status = 'STOPPED'
480 60c42f9f Stavros Sachtouris
        if self['wait']:
481 60c42f9f Stavros Sachtouris
            details = self.client.get_server_details(server_id)
482 60c42f9f Stavros Sachtouris
            status = details['status']
483 60c42f9f Stavros Sachtouris
            if status in ('STOPPED', ):
484 60c42f9f Stavros Sachtouris
                return
485 60c42f9f Stavros Sachtouris
486 60c42f9f Stavros Sachtouris
        r = self.client.shutdown_server(int(server_id))
487 60c42f9f Stavros Sachtouris
        self._optional_output(r)
488 60c42f9f Stavros Sachtouris
489 60c42f9f Stavros Sachtouris
        if self['wait']:
490 60c42f9f Stavros Sachtouris
            self._wait(server_id, status)
491 5a673575 Stavros Sachtouris
492 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
493 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
494 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
495 234954d1 Stavros Sachtouris
496 7493ccb6 Stavros Sachtouris
497 d486baec Stavros Sachtouris
@command(server_cmds)
498 545c6c29 Stavros Sachtouris
class server_console(_init_cyclades, _optional_json):
499 22b6f063 Stavros Sachtouris
    """Get a VNC console to access an existing server (VM)
500 22b6f063 Stavros Sachtouris
    Console connection information provided (at least):
501 439826ec Stavros Sachtouris
    - host: (url or address) a VNC host
502 439826ec Stavros Sachtouris
    - port: (int) the gateway to enter VM on host
503 439826ec Stavros Sachtouris
    - password: for VNC authorization
504 22b6f063 Stavros Sachtouris
    """
505 7493ccb6 Stavros Sachtouris
506 5a673575 Stavros Sachtouris
    @errors.generic.all
507 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
508 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
509 5a673575 Stavros Sachtouris
    def _run(self, server_id):
510 bcef3ac9 Stavros Sachtouris
        self._print(
511 bcef3ac9 Stavros Sachtouris
            self.client.get_server_console(int(server_id)), print_dict)
512 5a673575 Stavros Sachtouris
513 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
514 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
515 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
516 7493ccb6 Stavros Sachtouris
517 234954d1 Stavros Sachtouris
518 d486baec Stavros Sachtouris
@command(server_cmds)
519 eb8208a5 Stavros Sachtouris
class server_resize(_init_cyclades, _optional_output_cmd):
520 eb8208a5 Stavros Sachtouris
    """Set a different flavor for an existing server
521 eb8208a5 Stavros Sachtouris
    To get server ids and flavor ids:
522 fc7c3c4c Stavros Sachtouris
    /server list
523 fc7c3c4c Stavros Sachtouris
    /flavor list
524 eb8208a5 Stavros Sachtouris
    """
525 eb8208a5 Stavros Sachtouris
526 eb8208a5 Stavros Sachtouris
    @errors.generic.all
527 eb8208a5 Stavros Sachtouris
    @errors.cyclades.connection
528 eb8208a5 Stavros Sachtouris
    @errors.cyclades.server_id
529 eb8208a5 Stavros Sachtouris
    @errors.cyclades.flavor_id
530 eb8208a5 Stavros Sachtouris
    def _run(self, server_id, flavor_id):
531 eb8208a5 Stavros Sachtouris
        self._optional_output(self.client.resize_server(server_id, flavor_id))
532 eb8208a5 Stavros Sachtouris
533 eb8208a5 Stavros Sachtouris
    def main(self, server_id, flavor_id):
534 eb8208a5 Stavros Sachtouris
        super(self.__class__, self)._run()
535 eb8208a5 Stavros Sachtouris
        self._run(server_id=server_id, flavor_id=flavor_id)
536 eb8208a5 Stavros Sachtouris
537 eb8208a5 Stavros Sachtouris
538 eb8208a5 Stavros Sachtouris
@command(server_cmds)
539 7493ccb6 Stavros Sachtouris
class server_firewall(_init_cyclades):
540 cd295a1d Stavros Sachtouris
    """Manage server (VM) firewall profiles for public networks"""
541 cd295a1d Stavros Sachtouris
542 cd295a1d Stavros Sachtouris
543 cd295a1d Stavros Sachtouris
@command(server_cmds)
544 cd295a1d Stavros Sachtouris
class server_firewall_set(_init_cyclades, _optional_output_cmd):
545 22b6f063 Stavros Sachtouris
    """Set the server (VM) firewall profile on VMs public network
546 22b6f063 Stavros Sachtouris
    Values for profile:
547 439826ec Stavros Sachtouris
    - DISABLED: Shutdown firewall
548 439826ec Stavros Sachtouris
    - ENABLED: Firewall in normal mode
549 439826ec Stavros Sachtouris
    - PROTECTED: Firewall in secure mode
550 22b6f063 Stavros Sachtouris
    """
551 7493ccb6 Stavros Sachtouris
552 5a673575 Stavros Sachtouris
    @errors.generic.all
553 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
554 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
555 5a673575 Stavros Sachtouris
    @errors.cyclades.firewall
556 5a673575 Stavros Sachtouris
    def _run(self, server_id, profile):
557 cd295a1d Stavros Sachtouris
        self._optional_output(self.client.set_firewall_profile(
558 cd295a1d Stavros Sachtouris
            server_id=int(server_id), profile=('%s' % profile).upper()))
559 5a673575 Stavros Sachtouris
560 7493ccb6 Stavros Sachtouris
    def main(self, server_id, profile):
561 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
562 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, profile=profile)
563 234954d1 Stavros Sachtouris
564 f3e94e06 Stavros Sachtouris
565 d486baec Stavros Sachtouris
@command(server_cmds)
566 cd295a1d Stavros Sachtouris
class server_firewall_get(_init_cyclades):
567 cd295a1d Stavros Sachtouris
    """Get the server (VM) firewall profile for its public network"""
568 cd295a1d Stavros Sachtouris
569 cd295a1d Stavros Sachtouris
    @errors.generic.all
570 cd295a1d Stavros Sachtouris
    @errors.cyclades.connection
571 cd295a1d Stavros Sachtouris
    @errors.cyclades.server_id
572 cd295a1d Stavros Sachtouris
    def _run(self, server_id):
573 cd295a1d Stavros Sachtouris
        print(self.client.get_firewall_profile(server_id))
574 cd295a1d Stavros Sachtouris
575 cd295a1d Stavros Sachtouris
    def main(self, server_id):
576 cd295a1d Stavros Sachtouris
        super(self.__class__, self)._run()
577 cd295a1d Stavros Sachtouris
        self._run(server_id=server_id)
578 cd295a1d Stavros Sachtouris
579 cd295a1d Stavros Sachtouris
580 cd295a1d Stavros Sachtouris
@command(server_cmds)
581 545c6c29 Stavros Sachtouris
class server_addr(_init_cyclades, _optional_json):
582 22b6f063 Stavros Sachtouris
    """List the addresses of all network interfaces on a server (VM)"""
583 7493ccb6 Stavros Sachtouris
584 cd295a1d Stavros Sachtouris
    arguments = dict(
585 545c6c29 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
586 cd295a1d Stavros Sachtouris
    )
587 cd295a1d Stavros Sachtouris
588 5a673575 Stavros Sachtouris
    @errors.generic.all
589 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
590 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
591 5a673575 Stavros Sachtouris
    def _run(self, server_id):
592 5a673575 Stavros Sachtouris
        reply = self.client.list_server_nics(int(server_id))
593 545c6c29 Stavros Sachtouris
        self._print(
594 545c6c29 Stavros Sachtouris
            reply, with_enumeration=self['enum'] and len(reply) > 1)
595 7493ccb6 Stavros Sachtouris
596 5a673575 Stavros Sachtouris
    def main(self, server_id):
597 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
598 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
599 5a673575 Stavros Sachtouris
600 234954d1 Stavros Sachtouris
601 d486baec Stavros Sachtouris
@command(server_cmds)
602 cd295a1d Stavros Sachtouris
class server_metadata(_init_cyclades):
603 cd295a1d Stavros Sachtouris
    """Manage Server metadata (key:value pairs of server attributes)"""
604 cd295a1d Stavros Sachtouris
605 cd295a1d Stavros Sachtouris
606 cd295a1d Stavros Sachtouris
@command(server_cmds)
607 545c6c29 Stavros Sachtouris
class server_metadata_list(_init_cyclades, _optional_json):
608 cd295a1d Stavros Sachtouris
    """Get server metadata"""
609 7493ccb6 Stavros Sachtouris
610 5a673575 Stavros Sachtouris
    @errors.generic.all
611 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
612 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
613 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
614 5a673575 Stavros Sachtouris
    def _run(self, server_id, key=''):
615 545c6c29 Stavros Sachtouris
        self._print(
616 bcef3ac9 Stavros Sachtouris
            self.client.get_server_metadata(int(server_id), key), print_dict)
617 5a673575 Stavros Sachtouris
618 a34888b4 Stavros Sachtouris
    def main(self, server_id, key=''):
619 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
620 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
621 7493ccb6 Stavros Sachtouris
622 234954d1 Stavros Sachtouris
623 d486baec Stavros Sachtouris
@command(server_cmds)
624 545c6c29 Stavros Sachtouris
class server_metadata_set(_init_cyclades, _optional_json):
625 cd295a1d Stavros Sachtouris
    """Set / update server(VM) metadata
626 cd295a1d Stavros Sachtouris
    Metadata should be given in key/value pairs in key=value format
627 9dc6159f Stavros Sachtouris
    For example: /server metadata set <server id> key1=value1 key2=value2
628 cd295a1d Stavros Sachtouris
    Old, unreferenced metadata will remain intact
629 22b6f063 Stavros Sachtouris
    """
630 7493ccb6 Stavros Sachtouris
631 5a673575 Stavros Sachtouris
    @errors.generic.all
632 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
633 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
634 cd295a1d Stavros Sachtouris
    def _run(self, server_id, keyvals):
635 545c6c29 Stavros Sachtouris
        assert keyvals, 'Please, add some metadata ( key=value)'
636 cd295a1d Stavros Sachtouris
        metadata = dict()
637 cd295a1d Stavros Sachtouris
        for keyval in keyvals:
638 cd295a1d Stavros Sachtouris
            k, sep, v = keyval.partition('=')
639 cd295a1d Stavros Sachtouris
            if sep and k:
640 cd295a1d Stavros Sachtouris
                metadata[k] = v
641 cd295a1d Stavros Sachtouris
            else:
642 cd295a1d Stavros Sachtouris
                raiseCLIError(
643 cd295a1d Stavros Sachtouris
                    'Invalid piece of metadata %s' % keyval,
644 cd295a1d Stavros Sachtouris
                    importance=2, details=[
645 cd295a1d Stavros Sachtouris
                        'Correct metadata format: key=val',
646 cd295a1d Stavros Sachtouris
                        'For example:',
647 cd295a1d Stavros Sachtouris
                        '/server metadata set <server id>'
648 cd295a1d Stavros Sachtouris
                        'key1=value1 key2=value2'])
649 545c6c29 Stavros Sachtouris
        self._print(
650 bcef3ac9 Stavros Sachtouris
            self.client.update_server_metadata(int(server_id), **metadata),
651 bcef3ac9 Stavros Sachtouris
            print_dict)
652 cd295a1d Stavros Sachtouris
653 cd295a1d Stavros Sachtouris
    def main(self, server_id, *key_equals_val):
654 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
655 cd295a1d Stavros Sachtouris
        self._run(server_id=server_id, keyvals=key_equals_val)
656 7493ccb6 Stavros Sachtouris
657 234954d1 Stavros Sachtouris
658 d486baec Stavros Sachtouris
@command(server_cmds)
659 cd295a1d Stavros Sachtouris
class server_metadata_delete(_init_cyclades, _optional_output_cmd):
660 22b6f063 Stavros Sachtouris
    """Delete server (VM) metadata"""
661 7493ccb6 Stavros Sachtouris
662 5a673575 Stavros Sachtouris
    @errors.generic.all
663 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
664 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
665 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
666 5a673575 Stavros Sachtouris
    def _run(self, server_id, key):
667 cd295a1d Stavros Sachtouris
        self._optional_output(
668 cd295a1d Stavros Sachtouris
            self.client.delete_server_metadata(int(server_id), key))
669 5a673575 Stavros Sachtouris
670 7493ccb6 Stavros Sachtouris
    def main(self, server_id, key):
671 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
672 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
673 234954d1 Stavros Sachtouris
674 7493ccb6 Stavros Sachtouris
675 d486baec Stavros Sachtouris
@command(server_cmds)
676 545c6c29 Stavros Sachtouris
class server_stats(_init_cyclades, _optional_json):
677 22b6f063 Stavros Sachtouris
    """Get server (VM) statistics"""
678 7493ccb6 Stavros Sachtouris
679 5a673575 Stavros Sachtouris
    @errors.generic.all
680 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
681 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
682 5a673575 Stavros Sachtouris
    def _run(self, server_id):
683 bcef3ac9 Stavros Sachtouris
        self._print(self.client.get_server_stats(int(server_id)), print_dict)
684 5a673575 Stavros Sachtouris
685 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
686 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
687 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
688 7493ccb6 Stavros Sachtouris
689 234954d1 Stavros Sachtouris
690 d486baec Stavros Sachtouris
@command(server_cmds)
691 60c42f9f Stavros Sachtouris
class server_wait(_init_cyclades, _server_wait):
692 fd1f1d96 Stavros Sachtouris
    """Wait for server to finish [BUILD, STOPPED, REBOOT, ACTIVE]"""
693 fd1f1d96 Stavros Sachtouris
694 5a673575 Stavros Sachtouris
    @errors.generic.all
695 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
696 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
697 5a673575 Stavros Sachtouris
    def _run(self, server_id, currect_status):
698 60c42f9f Stavros Sachtouris
        self._wait(server_id, currect_status)
699 fd1f1d96 Stavros Sachtouris
700 5a673575 Stavros Sachtouris
    def main(self, server_id, currect_status='BUILD'):
701 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
702 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, currect_status=currect_status)
703 5a673575 Stavros Sachtouris
704 fd1f1d96 Stavros Sachtouris
705 d486baec Stavros Sachtouris
@command(flavor_cmds)
706 6d190dd1 Stavros Sachtouris
class flavor_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
707 bd40efdf Stavros Sachtouris
    """List available hardware flavors"""
708 7493ccb6 Stavros Sachtouris
709 d8ff7b56 Stavros Sachtouris
    PERMANENTS = ('id', 'name')
710 d8ff7b56 Stavros Sachtouris
711 93914390 Stavros Sachtouris
    arguments = dict(
712 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
713 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed flavors', ('-n', '--number')),
714 bd40efdf Stavros Sachtouris
        more=FlagArgument(
715 de73876b Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
716 ed9af02c Stavros Sachtouris
            '--more'),
717 d8ff7b56 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
718 d8ff7b56 Stavros Sachtouris
        ram=ValueArgument('filter by ram', ('--ram')),
719 d8ff7b56 Stavros Sachtouris
        vcpus=ValueArgument('filter by number of VCPUs', ('--vcpus')),
720 d8ff7b56 Stavros Sachtouris
        disk=ValueArgument('filter by disk size in GB', ('--disk')),
721 d8ff7b56 Stavros Sachtouris
        disk_template=ValueArgument(
722 d8ff7b56 Stavros Sachtouris
            'filter by disk_templace', ('--disk-template'))
723 93914390 Stavros Sachtouris
    )
724 7493ccb6 Stavros Sachtouris
725 d8ff7b56 Stavros Sachtouris
    def _apply_common_filters(self, flavors):
726 d8ff7b56 Stavros Sachtouris
        common_filters = dict()
727 d8ff7b56 Stavros Sachtouris
        if self['ram']:
728 d8ff7b56 Stavros Sachtouris
            common_filters['ram'] = self['ram']
729 d8ff7b56 Stavros Sachtouris
        if self['vcpus']:
730 d8ff7b56 Stavros Sachtouris
            common_filters['vcpus'] = self['vcpus']
731 d8ff7b56 Stavros Sachtouris
        if self['disk']:
732 d8ff7b56 Stavros Sachtouris
            common_filters['disk'] = self['disk']
733 d8ff7b56 Stavros Sachtouris
        if self['disk_template']:
734 d8ff7b56 Stavros Sachtouris
            common_filters['SNF:disk_template'] = self['disk_template']
735 d8ff7b56 Stavros Sachtouris
        return filter_dicts_by_dict(flavors, common_filters)
736 d8ff7b56 Stavros Sachtouris
737 5a673575 Stavros Sachtouris
    @errors.generic.all
738 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
739 5a673575 Stavros Sachtouris
    def _run(self):
740 d8ff7b56 Stavros Sachtouris
        withcommons = self['ram'] or self['vcpus'] or (
741 d8ff7b56 Stavros Sachtouris
            self['disk'] or self['disk_template'])
742 d8ff7b56 Stavros Sachtouris
        detail = self['detail'] or withcommons
743 d8ff7b56 Stavros Sachtouris
        flavors = self.client.list_flavors(detail)
744 6d190dd1 Stavros Sachtouris
        flavors = self._filter_by_name(flavors)
745 6d190dd1 Stavros Sachtouris
        flavors = self._filter_by_id(flavors)
746 d8ff7b56 Stavros Sachtouris
        if withcommons:
747 d8ff7b56 Stavros Sachtouris
            flavors = self._apply_common_filters(flavors)
748 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
749 7ba195e5 Stavros Sachtouris
            remove_from_items(flavors, 'links')
750 d8ff7b56 Stavros Sachtouris
        if detail and not self['detail']:
751 d8ff7b56 Stavros Sachtouris
            for flv in flavors:
752 d8ff7b56 Stavros Sachtouris
                for key in set(flv).difference(self.PERMANENTS):
753 d8ff7b56 Stavros Sachtouris
                    flv.pop(key)
754 5a673575 Stavros Sachtouris
        pg_size = 10 if self['more'] and not self['limit'] else self['limit']
755 545c6c29 Stavros Sachtouris
        self._print(
756 ed9af02c Stavros Sachtouris
            flavors,
757 ed9af02c Stavros Sachtouris
            with_redundancy=self['detail'],
758 ed9af02c Stavros Sachtouris
            page_size=pg_size,
759 ed9af02c Stavros Sachtouris
            with_enumeration=self['enum'])
760 5a673575 Stavros Sachtouris
761 7493ccb6 Stavros Sachtouris
    def main(self):
762 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
763 5a673575 Stavros Sachtouris
        self._run()
764 7493ccb6 Stavros Sachtouris
765 234954d1 Stavros Sachtouris
766 d486baec Stavros Sachtouris
@command(flavor_cmds)
767 545c6c29 Stavros Sachtouris
class flavor_info(_init_cyclades, _optional_json):
768 769dbf53 Stavros Sachtouris
    """Detailed information on a hardware flavor
769 ddc0b290 Stavros Sachtouris
    To get a list of available flavors and flavor ids, try /flavor list
770 ddc0b290 Stavros Sachtouris
    """
771 7493ccb6 Stavros Sachtouris
772 5a673575 Stavros Sachtouris
    @errors.generic.all
773 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
774 5a673575 Stavros Sachtouris
    @errors.cyclades.flavor_id
775 5a673575 Stavros Sachtouris
    def _run(self, flavor_id):
776 bcef3ac9 Stavros Sachtouris
        self._print(
777 bcef3ac9 Stavros Sachtouris
            self.client.get_flavor_details(int(flavor_id)), print_dict)
778 7493ccb6 Stavros Sachtouris
779 5a673575 Stavros Sachtouris
    def main(self, flavor_id):
780 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
781 5a673575 Stavros Sachtouris
        self._run(flavor_id=flavor_id)
782 5a673575 Stavros Sachtouris
783 234954d1 Stavros Sachtouris
784 d486baec Stavros Sachtouris
@command(network_cmds)
785 545c6c29 Stavros Sachtouris
class network_info(_init_cyclades, _optional_json):
786 ddc0b290 Stavros Sachtouris
    """Detailed information on a network
787 ddc0b290 Stavros Sachtouris
    To get a list of available networks and network ids, try /network list
788 ddc0b290 Stavros Sachtouris
    """
789 c17b8bc0 Stavros Sachtouris
790 5a673575 Stavros Sachtouris
    @errors.generic.all
791 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
792 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
793 5a673575 Stavros Sachtouris
    def _run(self, network_id):
794 5a673575 Stavros Sachtouris
        network = self.client.get_network_details(int(network_id))
795 545c6c29 Stavros Sachtouris
        self._print(network, print_dict, exclude=('id'))
796 5a673575 Stavros Sachtouris
797 c17b8bc0 Stavros Sachtouris
    def main(self, network_id):
798 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
799 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
800 c17b8bc0 Stavros Sachtouris
801 c17b8bc0 Stavros Sachtouris
802 c17b8bc0 Stavros Sachtouris
@command(network_cmds)
803 6d190dd1 Stavros Sachtouris
class network_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
804 7493ccb6 Stavros Sachtouris
    """List networks"""
805 7493ccb6 Stavros Sachtouris
806 93914390 Stavros Sachtouris
    arguments = dict(
807 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
808 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed networks', ('-n', '--number')),
809 ddc0b290 Stavros Sachtouris
        more=FlagArgument(
810 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
811 ed9af02c Stavros Sachtouris
            '--more'),
812 ed9af02c Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
813 93914390 Stavros Sachtouris
    )
814 7493ccb6 Stavros Sachtouris
815 5a673575 Stavros Sachtouris
    @errors.generic.all
816 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
817 5a673575 Stavros Sachtouris
    def _run(self):
818 5a673575 Stavros Sachtouris
        networks = self.client.list_networks(self['detail'])
819 6d190dd1 Stavros Sachtouris
        networks = self._filter_by_name(networks)
820 6d190dd1 Stavros Sachtouris
        networks = self._filter_by_id(networks)
821 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
822 7ba195e5 Stavros Sachtouris
            remove_from_items(networks, 'links')
823 545c6c29 Stavros Sachtouris
        kwargs = dict(with_enumeration=self['enum'])
824 ddc0b290 Stavros Sachtouris
        if self['more']:
825 545c6c29 Stavros Sachtouris
            kwargs['page_size'] = self['limit'] or 10
826 0e806947 Stavros Sachtouris
        elif self['limit']:
827 545c6c29 Stavros Sachtouris
            networks = networks[:self['limit']]
828 545c6c29 Stavros Sachtouris
        self._print(networks, **kwargs)
829 7493ccb6 Stavros Sachtouris
830 5a673575 Stavros Sachtouris
    def main(self):
831 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
832 5a673575 Stavros Sachtouris
        self._run()
833 5a673575 Stavros Sachtouris
834 234954d1 Stavros Sachtouris
835 d486baec Stavros Sachtouris
@command(network_cmds)
836 77df3d4a Stavros Sachtouris
class network_create(_init_cyclades, _optional_json, _network_wait):
837 0e806947 Stavros Sachtouris
    """Create an (unconnected) network"""
838 7493ccb6 Stavros Sachtouris
839 93914390 Stavros Sachtouris
    arguments = dict(
840 0e806947 Stavros Sachtouris
        cidr=ValueArgument('explicitly set cidr', '--with-cidr'),
841 0e806947 Stavros Sachtouris
        gateway=ValueArgument('explicitly set gateway', '--with-gateway'),
842 9d1db11e Stavros Sachtouris
        dhcp=FlagArgument('Use dhcp (default: off)', '--with-dhcp'),
843 f6f81cd3 Stavros Sachtouris
        type=ValueArgument(
844 f6f81cd3 Stavros Sachtouris
            'Valid network types are '
845 f6f81cd3 Stavros Sachtouris
            'CUSTOM, IP_LESS_ROUTED, MAC_FILTERED (default), PHYSICAL_VLAN',
846 f6f81cd3 Stavros Sachtouris
            '--with-type',
847 77df3d4a Stavros Sachtouris
            default='MAC_FILTERED'),
848 77df3d4a Stavros Sachtouris
        wait=FlagArgument('Wait network to build', ('-w', '--wait'))
849 93914390 Stavros Sachtouris
    )
850 7493ccb6 Stavros Sachtouris
851 5a673575 Stavros Sachtouris
    @errors.generic.all
852 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
853 5a673575 Stavros Sachtouris
    @errors.cyclades.network_max
854 5a673575 Stavros Sachtouris
    def _run(self, name):
855 77df3d4a Stavros Sachtouris
        r = self.client.create_network(
856 de73876b Stavros Sachtouris
            name,
857 5a673575 Stavros Sachtouris
            cidr=self['cidr'],
858 5a673575 Stavros Sachtouris
            gateway=self['gateway'],
859 5a673575 Stavros Sachtouris
            dhcp=self['dhcp'],
860 77df3d4a Stavros Sachtouris
            type=self['type'])
861 77df3d4a Stavros Sachtouris
        self._print(r, print_dict)
862 77df3d4a Stavros Sachtouris
863 77df3d4a Stavros Sachtouris
        if self['wait']:
864 77df3d4a Stavros Sachtouris
            self._wait(r['id'], 'PENDING')
865 5a673575 Stavros Sachtouris
866 7493ccb6 Stavros Sachtouris
    def main(self, name):
867 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
868 5a673575 Stavros Sachtouris
        self._run(name)
869 7493ccb6 Stavros Sachtouris
870 234954d1 Stavros Sachtouris
871 d486baec Stavros Sachtouris
@command(network_cmds)
872 1b73b4c1 Stavros Sachtouris
class network_rename(_init_cyclades, _optional_output_cmd):
873 0e806947 Stavros Sachtouris
    """Set the name of a network"""
874 7493ccb6 Stavros Sachtouris
875 5a673575 Stavros Sachtouris
    @errors.generic.all
876 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
877 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
878 5a673575 Stavros Sachtouris
    def _run(self, network_id, new_name):
879 1b73b4c1 Stavros Sachtouris
        self._optional_output(
880 1b73b4c1 Stavros Sachtouris
                self.client.update_network_name(int(network_id), new_name))
881 5a673575 Stavros Sachtouris
882 7493ccb6 Stavros Sachtouris
    def main(self, network_id, new_name):
883 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
884 5a673575 Stavros Sachtouris
        self._run(network_id=network_id, new_name=new_name)
885 7493ccb6 Stavros Sachtouris
886 234954d1 Stavros Sachtouris
887 d486baec Stavros Sachtouris
@command(network_cmds)
888 77df3d4a Stavros Sachtouris
class network_delete(_init_cyclades, _optional_output_cmd, _network_wait):
889 7493ccb6 Stavros Sachtouris
    """Delete a network"""
890 7493ccb6 Stavros Sachtouris
891 77df3d4a Stavros Sachtouris
    arguments = dict(
892 77df3d4a Stavros Sachtouris
        wait=FlagArgument('Wait network to build', ('-w', '--wait'))
893 77df3d4a Stavros Sachtouris
    )
894 77df3d4a Stavros Sachtouris
895 5a673575 Stavros Sachtouris
    @errors.generic.all
896 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
897 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
898 5a673575 Stavros Sachtouris
    @errors.cyclades.network_in_use
899 5a673575 Stavros Sachtouris
    def _run(self, network_id):
900 77df3d4a Stavros Sachtouris
        status = 'DELETED'
901 77df3d4a Stavros Sachtouris
        if self['wait']:
902 77df3d4a Stavros Sachtouris
            r = self.client.get_network_details(network_id)
903 77df3d4a Stavros Sachtouris
            status = r['status']
904 77df3d4a Stavros Sachtouris
            if status in ('DELETED', ):
905 77df3d4a Stavros Sachtouris
                return
906 77df3d4a Stavros Sachtouris
907 77df3d4a Stavros Sachtouris
        r = self.client.delete_network(int(network_id))
908 77df3d4a Stavros Sachtouris
        self._optional_output(r)
909 77df3d4a Stavros Sachtouris
910 77df3d4a Stavros Sachtouris
        if self['wait']:
911 77df3d4a Stavros Sachtouris
            self._wait(network_id, status)
912 5a673575 Stavros Sachtouris
913 7493ccb6 Stavros Sachtouris
    def main(self, network_id):
914 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
915 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
916 7493ccb6 Stavros Sachtouris
917 234954d1 Stavros Sachtouris
918 d486baec Stavros Sachtouris
@command(network_cmds)
919 1b73b4c1 Stavros Sachtouris
class network_connect(_init_cyclades, _optional_output_cmd):
920 7493ccb6 Stavros Sachtouris
    """Connect a server to a network"""
921 7493ccb6 Stavros Sachtouris
922 5a673575 Stavros Sachtouris
    @errors.generic.all
923 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
924 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
925 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
926 5a673575 Stavros Sachtouris
    def _run(self, server_id, network_id):
927 1b73b4c1 Stavros Sachtouris
        self._optional_output(
928 1b73b4c1 Stavros Sachtouris
                self.client.connect_server(int(server_id), int(network_id)))
929 5a673575 Stavros Sachtouris
930 7493ccb6 Stavros Sachtouris
    def main(self, server_id, network_id):
931 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
932 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, network_id=network_id)
933 7493ccb6 Stavros Sachtouris
934 234954d1 Stavros Sachtouris
935 d486baec Stavros Sachtouris
@command(network_cmds)
936 7493ccb6 Stavros Sachtouris
class network_disconnect(_init_cyclades):
937 0e806947 Stavros Sachtouris
    """Disconnect a nic that connects a server to a network
938 0e806947 Stavros Sachtouris
    Nic ids are listed as "attachments" in detailed network information
939 439826ec Stavros Sachtouris
    To get detailed network information: /network info <network id>
940 0e806947 Stavros Sachtouris
    """
941 7493ccb6 Stavros Sachtouris
942 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_format
943 5a673575 Stavros Sachtouris
    def _server_id_from_nic(self, nic_id):
944 5a673575 Stavros Sachtouris
        return nic_id.split('-')[1]
945 5a673575 Stavros Sachtouris
946 5a673575 Stavros Sachtouris
    @errors.generic.all
947 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
948 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
949 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_id
950 5a673575 Stavros Sachtouris
    def _run(self, nic_id, server_id):
951 1b73b4c1 Stavros Sachtouris
        num_of_disconnected = self.client.disconnect_server(server_id, nic_id)
952 1b73b4c1 Stavros Sachtouris
        if not num_of_disconnected:
953 5a673575 Stavros Sachtouris
            raise ClientError(
954 5a673575 Stavros Sachtouris
                'Network Interface %s not found on server %s' % (
955 5a673575 Stavros Sachtouris
                    nic_id,
956 5a673575 Stavros Sachtouris
                    server_id),
957 5a673575 Stavros Sachtouris
                status=404)
958 1b73b4c1 Stavros Sachtouris
        print('Disconnected %s connections' % num_of_disconnected)
959 5a673575 Stavros Sachtouris
960 7493ccb6 Stavros Sachtouris
    def main(self, nic_id):
961 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
962 5a673575 Stavros Sachtouris
        server_id = self._server_id_from_nic(nic_id=nic_id)
963 5a673575 Stavros Sachtouris
        self._run(nic_id=nic_id, server_id=server_id)
964 9b47150e Stavros Sachtouris
965 9b47150e Stavros Sachtouris
966 7b2e4bf1 Stavros Sachtouris
@command(network_cmds)
967 7b2e4bf1 Stavros Sachtouris
class network_wait(_init_cyclades, _network_wait):
968 7b2e4bf1 Stavros Sachtouris
    """Wait for server to finish [PENDING, ACTIVE, DELETED]"""
969 7b2e4bf1 Stavros Sachtouris
970 7b2e4bf1 Stavros Sachtouris
    @errors.generic.all
971 7b2e4bf1 Stavros Sachtouris
    @errors.cyclades.connection
972 7b2e4bf1 Stavros Sachtouris
    @errors.cyclades.network_id
973 7b2e4bf1 Stavros Sachtouris
    def _run(self, network_id, currect_status):
974 7b2e4bf1 Stavros Sachtouris
        self._wait(network_id, currect_status)
975 7b2e4bf1 Stavros Sachtouris
976 7b2e4bf1 Stavros Sachtouris
    def main(self, network_id, currect_status='PENDING'):
977 7b2e4bf1 Stavros Sachtouris
        super(self.__class__, self)._run()
978 7b2e4bf1 Stavros Sachtouris
        self._run(network_id=network_id, currect_status=currect_status)
979 7b2e4bf1 Stavros Sachtouris
980 7b2e4bf1 Stavros Sachtouris
981 8be50626 Stavros Sachtouris
@command(server_cmds)
982 8be50626 Stavros Sachtouris
class server_ip(_init_cyclades):
983 8be50626 Stavros Sachtouris
    """Manage floating IPs for the servers"""
984 8be50626 Stavros Sachtouris
985 8be50626 Stavros Sachtouris
986 8be50626 Stavros Sachtouris
@command(server_cmds)
987 8be50626 Stavros Sachtouris
class server_ip_pools(_init_cyclades, _optional_json):
988 9b47150e Stavros Sachtouris
    """List all floating pools of floating ips"""
989 9b47150e Stavros Sachtouris
990 9b47150e Stavros Sachtouris
    @errors.generic.all
991 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
992 9b47150e Stavros Sachtouris
    def _run(self):
993 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ip_pools()
994 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ip_pools'])
995 9b47150e Stavros Sachtouris
996 9b47150e Stavros Sachtouris
    def main(self):
997 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
998 9b47150e Stavros Sachtouris
        self._run()
999 9b47150e Stavros Sachtouris
1000 9b47150e Stavros Sachtouris
1001 8be50626 Stavros Sachtouris
@command(server_cmds)
1002 8be50626 Stavros Sachtouris
class server_ip_list(_init_cyclades, _optional_json):
1003 9b47150e Stavros Sachtouris
    """List all floating ips"""
1004 9b47150e Stavros Sachtouris
1005 9b47150e Stavros Sachtouris
    @errors.generic.all
1006 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1007 9b47150e Stavros Sachtouris
    def _run(self):
1008 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ips()
1009 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ips'])
1010 9b47150e Stavros Sachtouris
1011 9b47150e Stavros Sachtouris
    def main(self):
1012 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1013 9b47150e Stavros Sachtouris
        self._run()
1014 9b47150e Stavros Sachtouris
1015 9b47150e Stavros Sachtouris
1016 8be50626 Stavros Sachtouris
@command(server_cmds)
1017 8be50626 Stavros Sachtouris
class server_ip_info(_init_cyclades, _optional_json):
1018 9b47150e Stavros Sachtouris
    """A floating IPs' details"""
1019 9b47150e Stavros Sachtouris
1020 9b47150e Stavros Sachtouris
    @errors.generic.all
1021 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1022 9b47150e Stavros Sachtouris
    def _run(self, ip):
1023 9b47150e Stavros Sachtouris
        self._print(self.client.get_floating_ip(ip), print_dict)
1024 9b47150e Stavros Sachtouris
1025 9b47150e Stavros Sachtouris
    def main(self, ip):
1026 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1027 9b47150e Stavros Sachtouris
        self._run(ip=ip)
1028 9b47150e Stavros Sachtouris
1029 9b47150e Stavros Sachtouris
1030 8be50626 Stavros Sachtouris
@command(server_cmds)
1031 8be50626 Stavros Sachtouris
class server_ip_create(_init_cyclades, _optional_json):
1032 9b47150e Stavros Sachtouris
    """Create a new floating IP"""
1033 9b47150e Stavros Sachtouris
1034 9b47150e Stavros Sachtouris
    arguments = dict(
1035 9b47150e Stavros Sachtouris
        pool=ValueArgument('Source IP pool', ('--pool'), None)
1036 9b47150e Stavros Sachtouris
    )
1037 9b47150e Stavros Sachtouris
1038 9b47150e Stavros Sachtouris
    @errors.generic.all
1039 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1040 9b47150e Stavros Sachtouris
    def _run(self, ip=None):
1041 2e6e03da Stavros Sachtouris
        self._print([self.client.alloc_floating_ip(self['pool'], ip)])
1042 9b47150e Stavros Sachtouris
1043 9b47150e Stavros Sachtouris
    def main(self, requested_address=None):
1044 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1045 9b47150e Stavros Sachtouris
        self._run(ip=requested_address)
1046 9b47150e Stavros Sachtouris
1047 9b47150e Stavros Sachtouris
1048 8be50626 Stavros Sachtouris
@command(server_cmds)
1049 8be50626 Stavros Sachtouris
class server_ip_delete(_init_cyclades, _optional_output_cmd):
1050 9b47150e Stavros Sachtouris
    """Delete a floating ip"""
1051 9b47150e Stavros Sachtouris
1052 9b47150e Stavros Sachtouris
    @errors.generic.all
1053 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1054 9b47150e Stavros Sachtouris
    def _run(self, ip):
1055 9b47150e Stavros Sachtouris
        self._optional_output(self.client.delete_floating_ip(ip))
1056 9b47150e Stavros Sachtouris
1057 9b47150e Stavros Sachtouris
    def main(self, ip):
1058 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1059 9b47150e Stavros Sachtouris
        self._run(ip=ip)
1060 9b47150e Stavros Sachtouris
1061 9b47150e Stavros Sachtouris
1062 9b47150e Stavros Sachtouris
@command(server_cmds)
1063 9b47150e Stavros Sachtouris
class server_ip_attach(_init_cyclades, _optional_output_cmd):
1064 9b47150e Stavros Sachtouris
    """Attach a floating ip to a server with server_id
1065 9b47150e Stavros Sachtouris
    """
1066 9b47150e Stavros Sachtouris
1067 9b47150e Stavros Sachtouris
    @errors.generic.all
1068 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1069 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
1070 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
1071 9b47150e Stavros Sachtouris
        self._optional_output(self.client.attach_floating_ip(server_id, ip))
1072 9b47150e Stavros Sachtouris
1073 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
1074 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1075 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)
1076 9b47150e Stavros Sachtouris
1077 9b47150e Stavros Sachtouris
1078 9b47150e Stavros Sachtouris
@command(server_cmds)
1079 2e6e03da Stavros Sachtouris
class server_ip_detach(_init_cyclades, _optional_output_cmd):
1080 8be50626 Stavros Sachtouris
    """Detach floating IP from server
1081 9b47150e Stavros Sachtouris
    """
1082 9b47150e Stavros Sachtouris
1083 9b47150e Stavros Sachtouris
    @errors.generic.all
1084 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1085 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
1086 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
1087 9b47150e Stavros Sachtouris
        self._optional_output(self.client.detach_floating_ip(server_id, ip))
1088 9b47150e Stavros Sachtouris
1089 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
1090 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1091 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)