Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (39 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 cf115aed Stavros Sachtouris
        vm = self.client.get_server_details(server_id)
296 cf115aed Stavros Sachtouris
        uuids = self._uuids2usernames([vm['user_id'], vm['tenant_id']])
297 cf115aed Stavros Sachtouris
        vm['user_id'] += ' (%s)' % uuids[vm['user_id']]
298 cf115aed Stavros Sachtouris
        vm['tenant_id'] += ' (%s)' % uuids[vm['tenant_id']]
299 cf115aed Stavros Sachtouris
        self._print(vm, print_dict)
300 7493ccb6 Stavros Sachtouris
301 b04288f7 Stavros Sachtouris
    def main(self, server_id):
302 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
303 b04288f7 Stavros Sachtouris
        self._run(server_id=server_id)
304 b04288f7 Stavros Sachtouris
305 234954d1 Stavros Sachtouris
306 57d622b6 Stavros Sachtouris
class PersonalityArgument(KeyValueArgument):
307 234954d1 Stavros Sachtouris
    @property
308 f3e94e06 Stavros Sachtouris
    def value(self):
309 57d622b6 Stavros Sachtouris
        return self._value if hasattr(self, '_value') else []
310 234954d1 Stavros Sachtouris
311 234954d1 Stavros Sachtouris
    @value.setter
312 f3e94e06 Stavros Sachtouris
    def value(self, newvalue):
313 f3e94e06 Stavros Sachtouris
        if newvalue == self.default:
314 f3e94e06 Stavros Sachtouris
            return self.value
315 57d622b6 Stavros Sachtouris
        self._value = []
316 57d622b6 Stavros Sachtouris
        for i, terms in enumerate(newvalue):
317 57d622b6 Stavros Sachtouris
            termlist = terms.split(',')
318 57d622b6 Stavros Sachtouris
            if len(termlist) > 5:
319 de73876b Stavros Sachtouris
                msg = 'Wrong number of terms (should be 1 to 5)'
320 de73876b Stavros Sachtouris
                raiseCLIError(CLISyntaxError(msg), details=howto_personality)
321 57d622b6 Stavros Sachtouris
            path = termlist[0]
322 57d622b6 Stavros Sachtouris
            if not exists(path):
323 de73876b Stavros Sachtouris
                raiseCLIError(
324 de73876b Stavros Sachtouris
                    None,
325 8194b51b Stavros Sachtouris
                    '--personality: File %s does not exist' % path,
326 8194b51b Stavros Sachtouris
                    importance=1,
327 8194b51b Stavros Sachtouris
                    details=howto_personality)
328 57d622b6 Stavros Sachtouris
            self._value.append(dict(path=path))
329 57d622b6 Stavros Sachtouris
            with open(path) as f:
330 57d622b6 Stavros Sachtouris
                self._value[i]['contents'] = b64encode(f.read())
331 57d622b6 Stavros Sachtouris
            try:
332 57d622b6 Stavros Sachtouris
                self._value[i]['path'] = termlist[1]
333 57d622b6 Stavros Sachtouris
                self._value[i]['owner'] = termlist[2]
334 57d622b6 Stavros Sachtouris
                self._value[i]['group'] = termlist[3]
335 57d622b6 Stavros Sachtouris
                self._value[i]['mode'] = termlist[4]
336 57d622b6 Stavros Sachtouris
            except IndexError:
337 57d622b6 Stavros Sachtouris
                pass
338 f3e94e06 Stavros Sachtouris
339 234954d1 Stavros Sachtouris
340 d486baec Stavros Sachtouris
@command(server_cmds)
341 60c42f9f Stavros Sachtouris
class server_create(_init_cyclades, _optional_json, _server_wait):
342 8194b51b Stavros Sachtouris
    """Create a server (aka Virtual Machine)
343 8194b51b Stavros Sachtouris
    Parameters:
344 439826ec Stavros Sachtouris
    - name: (single quoted text)
345 439826ec Stavros Sachtouris
    - flavor id: Hardware flavor. Pick one from: /flavor list
346 439826ec Stavros Sachtouris
    - image id: OS images. Pick one from: /image list
347 8194b51b Stavros Sachtouris
    """
348 7493ccb6 Stavros Sachtouris
349 93914390 Stavros Sachtouris
    arguments = dict(
350 93914390 Stavros Sachtouris
        personality=PersonalityArgument(
351 60c42f9f Stavros Sachtouris
            (80 * ' ').join(howto_personality), ('-p', '--personality')),
352 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to build', ('-w', '--wait'))
353 93914390 Stavros Sachtouris
    )
354 f3e94e06 Stavros Sachtouris
355 b04288f7 Stavros Sachtouris
    @errors.generic.all
356 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
357 b04288f7 Stavros Sachtouris
    @errors.plankton.id
358 b04288f7 Stavros Sachtouris
    @errors.cyclades.flavor_id
359 b04288f7 Stavros Sachtouris
    def _run(self, name, flavor_id, image_id):
360 60c42f9f Stavros Sachtouris
        r = self.client.create_server(
361 60c42f9f Stavros Sachtouris
            name, int(flavor_id), image_id, self['personality'])
362 cf115aed Stavros Sachtouris
        usernames = self._uuids2usernames([r['user_id'], r['tenant_id']])
363 cf115aed Stavros Sachtouris
        r['user_id'] += ' (%s)' % usernames[r['user_id']]
364 cf115aed Stavros Sachtouris
        r['tenant_id'] += ' (%s)' % usernames[r['tenant_id']]
365 60c42f9f Stavros Sachtouris
        self._print(r, print_dict)
366 60c42f9f Stavros Sachtouris
        if self['wait']:
367 60c42f9f Stavros Sachtouris
            self._wait(r['id'], r['status'])
368 b04288f7 Stavros Sachtouris
369 7493ccb6 Stavros Sachtouris
    def main(self, name, flavor_id, image_id):
370 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
371 b04288f7 Stavros Sachtouris
        self._run(name=name, flavor_id=flavor_id, image_id=image_id)
372 7493ccb6 Stavros Sachtouris
373 234954d1 Stavros Sachtouris
374 d486baec Stavros Sachtouris
@command(server_cmds)
375 cd295a1d Stavros Sachtouris
class server_rename(_init_cyclades, _optional_output_cmd):
376 22b6f063 Stavros Sachtouris
    """Set/update a server (VM) name
377 5a673575 Stavros Sachtouris
    VM names are not unique, therefore multiple servers may share the same name
378 22b6f063 Stavros Sachtouris
    """
379 7493ccb6 Stavros Sachtouris
380 5a673575 Stavros Sachtouris
    @errors.generic.all
381 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
382 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
383 5a673575 Stavros Sachtouris
    def _run(self, server_id, new_name):
384 cd295a1d Stavros Sachtouris
        self._optional_output(
385 cd295a1d Stavros Sachtouris
            self.client.update_server_name(int(server_id), new_name))
386 5a673575 Stavros Sachtouris
387 7493ccb6 Stavros Sachtouris
    def main(self, server_id, new_name):
388 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
389 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, new_name=new_name)
390 234954d1 Stavros Sachtouris
391 7493ccb6 Stavros Sachtouris
392 d486baec Stavros Sachtouris
@command(server_cmds)
393 60c42f9f Stavros Sachtouris
class server_delete(_init_cyclades, _optional_output_cmd, _server_wait):
394 22b6f063 Stavros Sachtouris
    """Delete a server (VM)"""
395 7493ccb6 Stavros Sachtouris
396 60c42f9f Stavros Sachtouris
    arguments = dict(
397 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
398 60c42f9f Stavros Sachtouris
    )
399 60c42f9f Stavros Sachtouris
400 5a673575 Stavros Sachtouris
    @errors.generic.all
401 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
402 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
403 5a673575 Stavros Sachtouris
    def _run(self, server_id):
404 60c42f9f Stavros Sachtouris
            status = 'DELETED'
405 60c42f9f Stavros Sachtouris
            if self['wait']:
406 60c42f9f Stavros Sachtouris
                details = self.client.get_server_details(server_id)
407 60c42f9f Stavros Sachtouris
                status = details['status']
408 60c42f9f Stavros Sachtouris
409 60c42f9f Stavros Sachtouris
            r = self.client.delete_server(int(server_id))
410 60c42f9f Stavros Sachtouris
            self._optional_output(r)
411 60c42f9f Stavros Sachtouris
412 60c42f9f Stavros Sachtouris
            if self['wait']:
413 60c42f9f Stavros Sachtouris
                self._wait(server_id, status)
414 5a673575 Stavros Sachtouris
415 5a673575 Stavros Sachtouris
    def main(self, server_id):
416 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
417 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
418 234954d1 Stavros Sachtouris
419 7493ccb6 Stavros Sachtouris
420 d486baec Stavros Sachtouris
@command(server_cmds)
421 60c42f9f Stavros Sachtouris
class server_reboot(_init_cyclades, _optional_output_cmd, _server_wait):
422 22b6f063 Stavros Sachtouris
    """Reboot a server (VM)"""
423 18edacfe Stavros Sachtouris
424 93914390 Stavros Sachtouris
    arguments = dict(
425 60c42f9f Stavros Sachtouris
        hard=FlagArgument('perform a hard reboot', ('-f', '--force')),
426 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
427 93914390 Stavros Sachtouris
    )
428 7493ccb6 Stavros Sachtouris
429 5a673575 Stavros Sachtouris
    @errors.generic.all
430 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
431 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
432 5a673575 Stavros Sachtouris
    def _run(self, server_id):
433 60c42f9f Stavros Sachtouris
        r = self.client.reboot_server(int(server_id), self['hard'])
434 60c42f9f Stavros Sachtouris
        self._optional_output(r)
435 60c42f9f Stavros Sachtouris
436 60c42f9f Stavros Sachtouris
        if self['wait']:
437 60c42f9f Stavros Sachtouris
            self._wait(server_id, 'REBOOT')
438 5a673575 Stavros Sachtouris
439 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
440 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
441 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
442 234954d1 Stavros Sachtouris
443 7493ccb6 Stavros Sachtouris
444 d486baec Stavros Sachtouris
@command(server_cmds)
445 60c42f9f Stavros Sachtouris
class server_start(_init_cyclades, _optional_output_cmd, _server_wait):
446 22b6f063 Stavros Sachtouris
    """Start an existing server (VM)"""
447 7493ccb6 Stavros Sachtouris
448 60c42f9f Stavros Sachtouris
    arguments = dict(
449 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
450 60c42f9f Stavros Sachtouris
    )
451 60c42f9f Stavros Sachtouris
452 5a673575 Stavros Sachtouris
    @errors.generic.all
453 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
454 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
455 5a673575 Stavros Sachtouris
    def _run(self, server_id):
456 60c42f9f Stavros Sachtouris
        status = 'ACTIVE'
457 60c42f9f Stavros Sachtouris
        if self['wait']:
458 60c42f9f Stavros Sachtouris
            details = self.client.get_server_details(server_id)
459 60c42f9f Stavros Sachtouris
            status = details['status']
460 60c42f9f Stavros Sachtouris
            if status in ('ACTIVE', ):
461 60c42f9f Stavros Sachtouris
                return
462 60c42f9f Stavros Sachtouris
463 60c42f9f Stavros Sachtouris
        r = self.client.start_server(int(server_id))
464 60c42f9f Stavros Sachtouris
        self._optional_output(r)
465 60c42f9f Stavros Sachtouris
466 60c42f9f Stavros Sachtouris
        if self['wait']:
467 60c42f9f Stavros Sachtouris
            self._wait(server_id, status)
468 5a673575 Stavros Sachtouris
469 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
470 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
471 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
472 234954d1 Stavros Sachtouris
473 7493ccb6 Stavros Sachtouris
474 d486baec Stavros Sachtouris
@command(server_cmds)
475 60c42f9f Stavros Sachtouris
class server_shutdown(_init_cyclades, _optional_output_cmd, _server_wait):
476 22b6f063 Stavros Sachtouris
    """Shutdown an active server (VM)"""
477 7493ccb6 Stavros Sachtouris
478 60c42f9f Stavros Sachtouris
    arguments = dict(
479 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
480 60c42f9f Stavros Sachtouris
    )
481 60c42f9f Stavros Sachtouris
482 5a673575 Stavros Sachtouris
    @errors.generic.all
483 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
484 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
485 5a673575 Stavros Sachtouris
    def _run(self, server_id):
486 60c42f9f Stavros Sachtouris
        status = 'STOPPED'
487 60c42f9f Stavros Sachtouris
        if self['wait']:
488 60c42f9f Stavros Sachtouris
            details = self.client.get_server_details(server_id)
489 60c42f9f Stavros Sachtouris
            status = details['status']
490 60c42f9f Stavros Sachtouris
            if status in ('STOPPED', ):
491 60c42f9f Stavros Sachtouris
                return
492 60c42f9f Stavros Sachtouris
493 60c42f9f Stavros Sachtouris
        r = self.client.shutdown_server(int(server_id))
494 60c42f9f Stavros Sachtouris
        self._optional_output(r)
495 60c42f9f Stavros Sachtouris
496 60c42f9f Stavros Sachtouris
        if self['wait']:
497 60c42f9f Stavros Sachtouris
            self._wait(server_id, status)
498 5a673575 Stavros Sachtouris
499 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
500 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
501 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
502 234954d1 Stavros Sachtouris
503 7493ccb6 Stavros Sachtouris
504 d486baec Stavros Sachtouris
@command(server_cmds)
505 545c6c29 Stavros Sachtouris
class server_console(_init_cyclades, _optional_json):
506 22b6f063 Stavros Sachtouris
    """Get a VNC console to access an existing server (VM)
507 22b6f063 Stavros Sachtouris
    Console connection information provided (at least):
508 439826ec Stavros Sachtouris
    - host: (url or address) a VNC host
509 439826ec Stavros Sachtouris
    - port: (int) the gateway to enter VM on host
510 439826ec Stavros Sachtouris
    - password: for VNC authorization
511 22b6f063 Stavros Sachtouris
    """
512 7493ccb6 Stavros Sachtouris
513 5a673575 Stavros Sachtouris
    @errors.generic.all
514 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
515 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
516 5a673575 Stavros Sachtouris
    def _run(self, server_id):
517 bcef3ac9 Stavros Sachtouris
        self._print(
518 bcef3ac9 Stavros Sachtouris
            self.client.get_server_console(int(server_id)), print_dict)
519 5a673575 Stavros Sachtouris
520 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
521 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
522 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
523 7493ccb6 Stavros Sachtouris
524 234954d1 Stavros Sachtouris
525 d486baec Stavros Sachtouris
@command(server_cmds)
526 eb8208a5 Stavros Sachtouris
class server_resize(_init_cyclades, _optional_output_cmd):
527 eb8208a5 Stavros Sachtouris
    """Set a different flavor for an existing server
528 eb8208a5 Stavros Sachtouris
    To get server ids and flavor ids:
529 fc7c3c4c Stavros Sachtouris
    /server list
530 fc7c3c4c Stavros Sachtouris
    /flavor list
531 eb8208a5 Stavros Sachtouris
    """
532 eb8208a5 Stavros Sachtouris
533 eb8208a5 Stavros Sachtouris
    @errors.generic.all
534 eb8208a5 Stavros Sachtouris
    @errors.cyclades.connection
535 eb8208a5 Stavros Sachtouris
    @errors.cyclades.server_id
536 eb8208a5 Stavros Sachtouris
    @errors.cyclades.flavor_id
537 eb8208a5 Stavros Sachtouris
    def _run(self, server_id, flavor_id):
538 eb8208a5 Stavros Sachtouris
        self._optional_output(self.client.resize_server(server_id, flavor_id))
539 eb8208a5 Stavros Sachtouris
540 eb8208a5 Stavros Sachtouris
    def main(self, server_id, flavor_id):
541 eb8208a5 Stavros Sachtouris
        super(self.__class__, self)._run()
542 eb8208a5 Stavros Sachtouris
        self._run(server_id=server_id, flavor_id=flavor_id)
543 eb8208a5 Stavros Sachtouris
544 eb8208a5 Stavros Sachtouris
545 eb8208a5 Stavros Sachtouris
@command(server_cmds)
546 7493ccb6 Stavros Sachtouris
class server_firewall(_init_cyclades):
547 cd295a1d Stavros Sachtouris
    """Manage server (VM) firewall profiles for public networks"""
548 cd295a1d Stavros Sachtouris
549 cd295a1d Stavros Sachtouris
550 cd295a1d Stavros Sachtouris
@command(server_cmds)
551 cd295a1d Stavros Sachtouris
class server_firewall_set(_init_cyclades, _optional_output_cmd):
552 22b6f063 Stavros Sachtouris
    """Set the server (VM) firewall profile on VMs public network
553 22b6f063 Stavros Sachtouris
    Values for profile:
554 439826ec Stavros Sachtouris
    - DISABLED: Shutdown firewall
555 439826ec Stavros Sachtouris
    - ENABLED: Firewall in normal mode
556 439826ec Stavros Sachtouris
    - PROTECTED: Firewall in secure mode
557 22b6f063 Stavros Sachtouris
    """
558 7493ccb6 Stavros Sachtouris
559 5a673575 Stavros Sachtouris
    @errors.generic.all
560 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
561 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
562 5a673575 Stavros Sachtouris
    @errors.cyclades.firewall
563 5a673575 Stavros Sachtouris
    def _run(self, server_id, profile):
564 cd295a1d Stavros Sachtouris
        self._optional_output(self.client.set_firewall_profile(
565 cd295a1d Stavros Sachtouris
            server_id=int(server_id), profile=('%s' % profile).upper()))
566 5a673575 Stavros Sachtouris
567 7493ccb6 Stavros Sachtouris
    def main(self, server_id, profile):
568 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
569 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, profile=profile)
570 234954d1 Stavros Sachtouris
571 f3e94e06 Stavros Sachtouris
572 d486baec Stavros Sachtouris
@command(server_cmds)
573 cd295a1d Stavros Sachtouris
class server_firewall_get(_init_cyclades):
574 cd295a1d Stavros Sachtouris
    """Get the server (VM) firewall profile for its public network"""
575 cd295a1d Stavros Sachtouris
576 cd295a1d Stavros Sachtouris
    @errors.generic.all
577 cd295a1d Stavros Sachtouris
    @errors.cyclades.connection
578 cd295a1d Stavros Sachtouris
    @errors.cyclades.server_id
579 cd295a1d Stavros Sachtouris
    def _run(self, server_id):
580 cd295a1d Stavros Sachtouris
        print(self.client.get_firewall_profile(server_id))
581 cd295a1d Stavros Sachtouris
582 cd295a1d Stavros Sachtouris
    def main(self, server_id):
583 cd295a1d Stavros Sachtouris
        super(self.__class__, self)._run()
584 cd295a1d Stavros Sachtouris
        self._run(server_id=server_id)
585 cd295a1d Stavros Sachtouris
586 cd295a1d Stavros Sachtouris
587 cd295a1d Stavros Sachtouris
@command(server_cmds)
588 545c6c29 Stavros Sachtouris
class server_addr(_init_cyclades, _optional_json):
589 22b6f063 Stavros Sachtouris
    """List the addresses of all network interfaces on a server (VM)"""
590 7493ccb6 Stavros Sachtouris
591 cd295a1d Stavros Sachtouris
    arguments = dict(
592 545c6c29 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate')
593 cd295a1d Stavros Sachtouris
    )
594 cd295a1d Stavros Sachtouris
595 5a673575 Stavros Sachtouris
    @errors.generic.all
596 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
597 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
598 5a673575 Stavros Sachtouris
    def _run(self, server_id):
599 5a673575 Stavros Sachtouris
        reply = self.client.list_server_nics(int(server_id))
600 545c6c29 Stavros Sachtouris
        self._print(
601 545c6c29 Stavros Sachtouris
            reply, with_enumeration=self['enum'] and len(reply) > 1)
602 7493ccb6 Stavros Sachtouris
603 5a673575 Stavros Sachtouris
    def main(self, server_id):
604 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
605 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
606 5a673575 Stavros Sachtouris
607 234954d1 Stavros Sachtouris
608 d486baec Stavros Sachtouris
@command(server_cmds)
609 cd295a1d Stavros Sachtouris
class server_metadata(_init_cyclades):
610 cd295a1d Stavros Sachtouris
    """Manage Server metadata (key:value pairs of server attributes)"""
611 cd295a1d Stavros Sachtouris
612 cd295a1d Stavros Sachtouris
613 cd295a1d Stavros Sachtouris
@command(server_cmds)
614 545c6c29 Stavros Sachtouris
class server_metadata_list(_init_cyclades, _optional_json):
615 cd295a1d Stavros Sachtouris
    """Get server metadata"""
616 7493ccb6 Stavros Sachtouris
617 5a673575 Stavros Sachtouris
    @errors.generic.all
618 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
619 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
620 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
621 5a673575 Stavros Sachtouris
    def _run(self, server_id, key=''):
622 545c6c29 Stavros Sachtouris
        self._print(
623 bcef3ac9 Stavros Sachtouris
            self.client.get_server_metadata(int(server_id), key), print_dict)
624 5a673575 Stavros Sachtouris
625 a34888b4 Stavros Sachtouris
    def main(self, server_id, key=''):
626 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
627 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
628 7493ccb6 Stavros Sachtouris
629 234954d1 Stavros Sachtouris
630 d486baec Stavros Sachtouris
@command(server_cmds)
631 545c6c29 Stavros Sachtouris
class server_metadata_set(_init_cyclades, _optional_json):
632 cd295a1d Stavros Sachtouris
    """Set / update server(VM) metadata
633 cd295a1d Stavros Sachtouris
    Metadata should be given in key/value pairs in key=value format
634 9dc6159f Stavros Sachtouris
    For example: /server metadata set <server id> key1=value1 key2=value2
635 cd295a1d Stavros Sachtouris
    Old, unreferenced metadata will remain intact
636 22b6f063 Stavros Sachtouris
    """
637 7493ccb6 Stavros Sachtouris
638 5a673575 Stavros Sachtouris
    @errors.generic.all
639 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
640 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
641 cd295a1d Stavros Sachtouris
    def _run(self, server_id, keyvals):
642 545c6c29 Stavros Sachtouris
        assert keyvals, 'Please, add some metadata ( key=value)'
643 cd295a1d Stavros Sachtouris
        metadata = dict()
644 cd295a1d Stavros Sachtouris
        for keyval in keyvals:
645 cd295a1d Stavros Sachtouris
            k, sep, v = keyval.partition('=')
646 cd295a1d Stavros Sachtouris
            if sep and k:
647 cd295a1d Stavros Sachtouris
                metadata[k] = v
648 cd295a1d Stavros Sachtouris
            else:
649 cd295a1d Stavros Sachtouris
                raiseCLIError(
650 cd295a1d Stavros Sachtouris
                    'Invalid piece of metadata %s' % keyval,
651 cd295a1d Stavros Sachtouris
                    importance=2, details=[
652 cd295a1d Stavros Sachtouris
                        'Correct metadata format: key=val',
653 cd295a1d Stavros Sachtouris
                        'For example:',
654 cd295a1d Stavros Sachtouris
                        '/server metadata set <server id>'
655 cd295a1d Stavros Sachtouris
                        'key1=value1 key2=value2'])
656 545c6c29 Stavros Sachtouris
        self._print(
657 bcef3ac9 Stavros Sachtouris
            self.client.update_server_metadata(int(server_id), **metadata),
658 bcef3ac9 Stavros Sachtouris
            print_dict)
659 cd295a1d Stavros Sachtouris
660 cd295a1d Stavros Sachtouris
    def main(self, server_id, *key_equals_val):
661 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
662 cd295a1d Stavros Sachtouris
        self._run(server_id=server_id, keyvals=key_equals_val)
663 7493ccb6 Stavros Sachtouris
664 234954d1 Stavros Sachtouris
665 d486baec Stavros Sachtouris
@command(server_cmds)
666 cd295a1d Stavros Sachtouris
class server_metadata_delete(_init_cyclades, _optional_output_cmd):
667 22b6f063 Stavros Sachtouris
    """Delete server (VM) metadata"""
668 7493ccb6 Stavros Sachtouris
669 5a673575 Stavros Sachtouris
    @errors.generic.all
670 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
671 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
672 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
673 5a673575 Stavros Sachtouris
    def _run(self, server_id, key):
674 cd295a1d Stavros Sachtouris
        self._optional_output(
675 cd295a1d Stavros Sachtouris
            self.client.delete_server_metadata(int(server_id), key))
676 5a673575 Stavros Sachtouris
677 7493ccb6 Stavros Sachtouris
    def main(self, server_id, key):
678 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
679 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
680 234954d1 Stavros Sachtouris
681 7493ccb6 Stavros Sachtouris
682 d486baec Stavros Sachtouris
@command(server_cmds)
683 545c6c29 Stavros Sachtouris
class server_stats(_init_cyclades, _optional_json):
684 22b6f063 Stavros Sachtouris
    """Get server (VM) statistics"""
685 7493ccb6 Stavros Sachtouris
686 5a673575 Stavros Sachtouris
    @errors.generic.all
687 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
688 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
689 5a673575 Stavros Sachtouris
    def _run(self, server_id):
690 bcef3ac9 Stavros Sachtouris
        self._print(self.client.get_server_stats(int(server_id)), print_dict)
691 5a673575 Stavros Sachtouris
692 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
693 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
694 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
695 7493ccb6 Stavros Sachtouris
696 234954d1 Stavros Sachtouris
697 d486baec Stavros Sachtouris
@command(server_cmds)
698 60c42f9f Stavros Sachtouris
class server_wait(_init_cyclades, _server_wait):
699 fd1f1d96 Stavros Sachtouris
    """Wait for server to finish [BUILD, STOPPED, REBOOT, ACTIVE]"""
700 fd1f1d96 Stavros Sachtouris
701 5a673575 Stavros Sachtouris
    @errors.generic.all
702 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
703 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
704 5a673575 Stavros Sachtouris
    def _run(self, server_id, currect_status):
705 60c42f9f Stavros Sachtouris
        self._wait(server_id, currect_status)
706 fd1f1d96 Stavros Sachtouris
707 5a673575 Stavros Sachtouris
    def main(self, server_id, currect_status='BUILD'):
708 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
709 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, currect_status=currect_status)
710 5a673575 Stavros Sachtouris
711 fd1f1d96 Stavros Sachtouris
712 d486baec Stavros Sachtouris
@command(flavor_cmds)
713 6d190dd1 Stavros Sachtouris
class flavor_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
714 bd40efdf Stavros Sachtouris
    """List available hardware flavors"""
715 7493ccb6 Stavros Sachtouris
716 d8ff7b56 Stavros Sachtouris
    PERMANENTS = ('id', 'name')
717 d8ff7b56 Stavros Sachtouris
718 93914390 Stavros Sachtouris
    arguments = dict(
719 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
720 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed flavors', ('-n', '--number')),
721 bd40efdf Stavros Sachtouris
        more=FlagArgument(
722 de73876b Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
723 ed9af02c Stavros Sachtouris
            '--more'),
724 d8ff7b56 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
725 d8ff7b56 Stavros Sachtouris
        ram=ValueArgument('filter by ram', ('--ram')),
726 d8ff7b56 Stavros Sachtouris
        vcpus=ValueArgument('filter by number of VCPUs', ('--vcpus')),
727 d8ff7b56 Stavros Sachtouris
        disk=ValueArgument('filter by disk size in GB', ('--disk')),
728 d8ff7b56 Stavros Sachtouris
        disk_template=ValueArgument(
729 d8ff7b56 Stavros Sachtouris
            'filter by disk_templace', ('--disk-template'))
730 93914390 Stavros Sachtouris
    )
731 7493ccb6 Stavros Sachtouris
732 d8ff7b56 Stavros Sachtouris
    def _apply_common_filters(self, flavors):
733 d8ff7b56 Stavros Sachtouris
        common_filters = dict()
734 d8ff7b56 Stavros Sachtouris
        if self['ram']:
735 d8ff7b56 Stavros Sachtouris
            common_filters['ram'] = self['ram']
736 d8ff7b56 Stavros Sachtouris
        if self['vcpus']:
737 d8ff7b56 Stavros Sachtouris
            common_filters['vcpus'] = self['vcpus']
738 d8ff7b56 Stavros Sachtouris
        if self['disk']:
739 d8ff7b56 Stavros Sachtouris
            common_filters['disk'] = self['disk']
740 d8ff7b56 Stavros Sachtouris
        if self['disk_template']:
741 d8ff7b56 Stavros Sachtouris
            common_filters['SNF:disk_template'] = self['disk_template']
742 d8ff7b56 Stavros Sachtouris
        return filter_dicts_by_dict(flavors, common_filters)
743 d8ff7b56 Stavros Sachtouris
744 5a673575 Stavros Sachtouris
    @errors.generic.all
745 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
746 5a673575 Stavros Sachtouris
    def _run(self):
747 d8ff7b56 Stavros Sachtouris
        withcommons = self['ram'] or self['vcpus'] or (
748 d8ff7b56 Stavros Sachtouris
            self['disk'] or self['disk_template'])
749 d8ff7b56 Stavros Sachtouris
        detail = self['detail'] or withcommons
750 d8ff7b56 Stavros Sachtouris
        flavors = self.client.list_flavors(detail)
751 6d190dd1 Stavros Sachtouris
        flavors = self._filter_by_name(flavors)
752 6d190dd1 Stavros Sachtouris
        flavors = self._filter_by_id(flavors)
753 d8ff7b56 Stavros Sachtouris
        if withcommons:
754 d8ff7b56 Stavros Sachtouris
            flavors = self._apply_common_filters(flavors)
755 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
756 7ba195e5 Stavros Sachtouris
            remove_from_items(flavors, 'links')
757 d8ff7b56 Stavros Sachtouris
        if detail and not self['detail']:
758 d8ff7b56 Stavros Sachtouris
            for flv in flavors:
759 d8ff7b56 Stavros Sachtouris
                for key in set(flv).difference(self.PERMANENTS):
760 d8ff7b56 Stavros Sachtouris
                    flv.pop(key)
761 5a673575 Stavros Sachtouris
        pg_size = 10 if self['more'] and not self['limit'] else self['limit']
762 545c6c29 Stavros Sachtouris
        self._print(
763 ed9af02c Stavros Sachtouris
            flavors,
764 ed9af02c Stavros Sachtouris
            with_redundancy=self['detail'],
765 ed9af02c Stavros Sachtouris
            page_size=pg_size,
766 ed9af02c Stavros Sachtouris
            with_enumeration=self['enum'])
767 5a673575 Stavros Sachtouris
768 7493ccb6 Stavros Sachtouris
    def main(self):
769 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
770 5a673575 Stavros Sachtouris
        self._run()
771 7493ccb6 Stavros Sachtouris
772 234954d1 Stavros Sachtouris
773 d486baec Stavros Sachtouris
@command(flavor_cmds)
774 545c6c29 Stavros Sachtouris
class flavor_info(_init_cyclades, _optional_json):
775 769dbf53 Stavros Sachtouris
    """Detailed information on a hardware flavor
776 ddc0b290 Stavros Sachtouris
    To get a list of available flavors and flavor ids, try /flavor list
777 ddc0b290 Stavros Sachtouris
    """
778 7493ccb6 Stavros Sachtouris
779 5a673575 Stavros Sachtouris
    @errors.generic.all
780 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
781 5a673575 Stavros Sachtouris
    @errors.cyclades.flavor_id
782 5a673575 Stavros Sachtouris
    def _run(self, flavor_id):
783 bcef3ac9 Stavros Sachtouris
        self._print(
784 bcef3ac9 Stavros Sachtouris
            self.client.get_flavor_details(int(flavor_id)), print_dict)
785 7493ccb6 Stavros Sachtouris
786 5a673575 Stavros Sachtouris
    def main(self, flavor_id):
787 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
788 5a673575 Stavros Sachtouris
        self._run(flavor_id=flavor_id)
789 5a673575 Stavros Sachtouris
790 234954d1 Stavros Sachtouris
791 cf115aed Stavros Sachtouris
def _add_name(self, net):
792 cf115aed Stavros Sachtouris
        user_id, tenant_id, uuids = net['user_id'], net['tenant_id'], []
793 cf115aed Stavros Sachtouris
        if user_id:
794 cf115aed Stavros Sachtouris
            uuids.append(user_id)
795 cf115aed Stavros Sachtouris
        if tenant_id:
796 cf115aed Stavros Sachtouris
            uuids.append(tenant_id)
797 cf115aed Stavros Sachtouris
        if uuids:
798 cf115aed Stavros Sachtouris
            usernames = self._uuids2usernames(uuids)
799 cf115aed Stavros Sachtouris
            if user_id:
800 cf115aed Stavros Sachtouris
                net['user_id'] += ' (%s)' % usernames[user_id]
801 cf115aed Stavros Sachtouris
            if tenant_id:
802 cf115aed Stavros Sachtouris
                net['tenant_id'] += ' (%s)' % usernames[tenant_id]
803 cf115aed Stavros Sachtouris
804 cf115aed Stavros Sachtouris
805 d486baec Stavros Sachtouris
@command(network_cmds)
806 545c6c29 Stavros Sachtouris
class network_info(_init_cyclades, _optional_json):
807 ddc0b290 Stavros Sachtouris
    """Detailed information on a network
808 ddc0b290 Stavros Sachtouris
    To get a list of available networks and network ids, try /network list
809 ddc0b290 Stavros Sachtouris
    """
810 c17b8bc0 Stavros Sachtouris
811 5a673575 Stavros Sachtouris
    @errors.generic.all
812 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
813 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
814 5a673575 Stavros Sachtouris
    def _run(self, network_id):
815 5a673575 Stavros Sachtouris
        network = self.client.get_network_details(int(network_id))
816 cf115aed Stavros Sachtouris
        _add_name(self, network)
817 545c6c29 Stavros Sachtouris
        self._print(network, print_dict, exclude=('id'))
818 5a673575 Stavros Sachtouris
819 c17b8bc0 Stavros Sachtouris
    def main(self, network_id):
820 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
821 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
822 c17b8bc0 Stavros Sachtouris
823 c17b8bc0 Stavros Sachtouris
824 c17b8bc0 Stavros Sachtouris
@command(network_cmds)
825 6d190dd1 Stavros Sachtouris
class network_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
826 7493ccb6 Stavros Sachtouris
    """List networks"""
827 7493ccb6 Stavros Sachtouris
828 c79faeb5 Stavros Sachtouris
    PERMANENTS = ('id', 'name')
829 c79faeb5 Stavros Sachtouris
830 93914390 Stavros Sachtouris
    arguments = dict(
831 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
832 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed networks', ('-n', '--number')),
833 ddc0b290 Stavros Sachtouris
        more=FlagArgument(
834 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
835 ed9af02c Stavros Sachtouris
            '--more'),
836 c79faeb5 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
837 c79faeb5 Stavros Sachtouris
        status=ValueArgument('filter by status', ('--status')),
838 c79faeb5 Stavros Sachtouris
        public=FlagArgument('only public networks', ('--public')),
839 c79faeb5 Stavros Sachtouris
        private=FlagArgument('only private networks', ('--private')),
840 c79faeb5 Stavros Sachtouris
        dhcp=FlagArgument('show networks with dhcp', ('--with-dhcp')),
841 c79faeb5 Stavros Sachtouris
        no_dhcp=FlagArgument('show networks without dhcp', ('--without-dhcp')),
842 c79faeb5 Stavros Sachtouris
        user_id=ValueArgument('filter by user id', ('--user-id')),
843 c79faeb5 Stavros Sachtouris
        user_name=ValueArgument('filter by user name', ('--user-name')),
844 c79faeb5 Stavros Sachtouris
        gateway=ValueArgument('filter by gateway (IPv4)', ('--gateway')),
845 c79faeb5 Stavros Sachtouris
        gateway6=ValueArgument('filter by gateway (IPv6)', ('--gateway6')),
846 c79faeb5 Stavros Sachtouris
        cidr=ValueArgument('filter by cidr (IPv4)', ('--cidr')),
847 c79faeb5 Stavros Sachtouris
        cidr6=ValueArgument('filter by cidr (IPv6)', ('--cidr6')),
848 c79faeb5 Stavros Sachtouris
        type=ValueArgument('filter by type', ('--type')),
849 93914390 Stavros Sachtouris
    )
850 7493ccb6 Stavros Sachtouris
851 c79faeb5 Stavros Sachtouris
    def _apply_common_filters(self, networks):
852 c79faeb5 Stavros Sachtouris
        common_filter = dict()
853 c79faeb5 Stavros Sachtouris
        if self['public']:
854 c79faeb5 Stavros Sachtouris
            if self['private']:
855 c79faeb5 Stavros Sachtouris
                return []
856 c79faeb5 Stavros Sachtouris
            common_filter['public'] = self['public']
857 c79faeb5 Stavros Sachtouris
        elif self['private']:
858 c79faeb5 Stavros Sachtouris
            common_filter['public'] = False
859 c79faeb5 Stavros Sachtouris
        if self['dhcp']:
860 c79faeb5 Stavros Sachtouris
            if self['no_dhcp']:
861 c79faeb5 Stavros Sachtouris
                return []
862 c79faeb5 Stavros Sachtouris
            common_filter['dhcp'] = True
863 c79faeb5 Stavros Sachtouris
        elif self['no_dhcp']:
864 c79faeb5 Stavros Sachtouris
            common_filter['dhcp'] = False
865 c79faeb5 Stavros Sachtouris
        if self['user_id'] or self['user_name']:
866 c79faeb5 Stavros Sachtouris
            uuid = self['user_id'] or self._username2uuid(self['user_name'])
867 c79faeb5 Stavros Sachtouris
            common_filter['user_id'] = uuid
868 c79faeb5 Stavros Sachtouris
        for term in ('status', 'gateway', 'gateway6', 'cidr', 'cidr6', 'type'):
869 c79faeb5 Stavros Sachtouris
            if self[term]:
870 c79faeb5 Stavros Sachtouris
                common_filter[term] = self[term]
871 c79faeb5 Stavros Sachtouris
        return filter_dicts_by_dict(networks, common_filter)
872 c79faeb5 Stavros Sachtouris
873 c79faeb5 Stavros Sachtouris
    def _add_name(self, networks, key='user_id'):
874 c79faeb5 Stavros Sachtouris
        uuids = self._uuids2usernames(
875 c79faeb5 Stavros Sachtouris
            list(set([net[key] for net in networks])))
876 c79faeb5 Stavros Sachtouris
        for net in networks:
877 c79faeb5 Stavros Sachtouris
            v = net.get(key, None)
878 c79faeb5 Stavros Sachtouris
            if v:
879 c79faeb5 Stavros Sachtouris
                net[key] += ' (%s)' % uuids[net[key]]
880 c79faeb5 Stavros Sachtouris
        return networks
881 c79faeb5 Stavros Sachtouris
882 5a673575 Stavros Sachtouris
    @errors.generic.all
883 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
884 5a673575 Stavros Sachtouris
    def _run(self):
885 c79faeb5 Stavros Sachtouris
        withcommons = False
886 c79faeb5 Stavros Sachtouris
        for term in (
887 c79faeb5 Stavros Sachtouris
                'status', 'public', 'private', 'user_id', 'user_name', 'type',
888 c79faeb5 Stavros Sachtouris
                'gateway', 'gateway6', 'cidr', 'cidr6', 'dhcp', 'no_dhcp'):
889 c79faeb5 Stavros Sachtouris
            if self[term]:
890 c79faeb5 Stavros Sachtouris
                withcommons = True
891 c79faeb5 Stavros Sachtouris
                break
892 c79faeb5 Stavros Sachtouris
        detail = self['detail'] or withcommons
893 c79faeb5 Stavros Sachtouris
        networks = self.client.list_networks(detail)
894 6d190dd1 Stavros Sachtouris
        networks = self._filter_by_name(networks)
895 6d190dd1 Stavros Sachtouris
        networks = self._filter_by_id(networks)
896 c79faeb5 Stavros Sachtouris
        if withcommons:
897 c79faeb5 Stavros Sachtouris
            networks = self._apply_common_filters(networks)
898 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
899 7ba195e5 Stavros Sachtouris
            remove_from_items(networks, 'links')
900 c79faeb5 Stavros Sachtouris
        if detail and not self['detail']:
901 c79faeb5 Stavros Sachtouris
            for net in networks:
902 c79faeb5 Stavros Sachtouris
                for key in set(net).difference(self.PERMANENTS):
903 c79faeb5 Stavros Sachtouris
                    net.pop(key)
904 c79faeb5 Stavros Sachtouris
        if self['detail'] and not self['json_output']:
905 c79faeb5 Stavros Sachtouris
            self._add_name(networks)
906 c79faeb5 Stavros Sachtouris
            self._add_name(networks, 'tenant_id')
907 545c6c29 Stavros Sachtouris
        kwargs = dict(with_enumeration=self['enum'])
908 ddc0b290 Stavros Sachtouris
        if self['more']:
909 545c6c29 Stavros Sachtouris
            kwargs['page_size'] = self['limit'] or 10
910 0e806947 Stavros Sachtouris
        elif self['limit']:
911 545c6c29 Stavros Sachtouris
            networks = networks[:self['limit']]
912 545c6c29 Stavros Sachtouris
        self._print(networks, **kwargs)
913 7493ccb6 Stavros Sachtouris
914 5a673575 Stavros Sachtouris
    def main(self):
915 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
916 5a673575 Stavros Sachtouris
        self._run()
917 5a673575 Stavros Sachtouris
918 234954d1 Stavros Sachtouris
919 d486baec Stavros Sachtouris
@command(network_cmds)
920 77df3d4a Stavros Sachtouris
class network_create(_init_cyclades, _optional_json, _network_wait):
921 0e806947 Stavros Sachtouris
    """Create an (unconnected) network"""
922 7493ccb6 Stavros Sachtouris
923 93914390 Stavros Sachtouris
    arguments = dict(
924 0e806947 Stavros Sachtouris
        cidr=ValueArgument('explicitly set cidr', '--with-cidr'),
925 0e806947 Stavros Sachtouris
        gateway=ValueArgument('explicitly set gateway', '--with-gateway'),
926 9d1db11e Stavros Sachtouris
        dhcp=FlagArgument('Use dhcp (default: off)', '--with-dhcp'),
927 f6f81cd3 Stavros Sachtouris
        type=ValueArgument(
928 f6f81cd3 Stavros Sachtouris
            'Valid network types are '
929 f6f81cd3 Stavros Sachtouris
            'CUSTOM, IP_LESS_ROUTED, MAC_FILTERED (default), PHYSICAL_VLAN',
930 f6f81cd3 Stavros Sachtouris
            '--with-type',
931 77df3d4a Stavros Sachtouris
            default='MAC_FILTERED'),
932 77df3d4a Stavros Sachtouris
        wait=FlagArgument('Wait network to build', ('-w', '--wait'))
933 93914390 Stavros Sachtouris
    )
934 7493ccb6 Stavros Sachtouris
935 5a673575 Stavros Sachtouris
    @errors.generic.all
936 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
937 5a673575 Stavros Sachtouris
    @errors.cyclades.network_max
938 5a673575 Stavros Sachtouris
    def _run(self, name):
939 77df3d4a Stavros Sachtouris
        r = self.client.create_network(
940 de73876b Stavros Sachtouris
            name,
941 5a673575 Stavros Sachtouris
            cidr=self['cidr'],
942 5a673575 Stavros Sachtouris
            gateway=self['gateway'],
943 5a673575 Stavros Sachtouris
            dhcp=self['dhcp'],
944 77df3d4a Stavros Sachtouris
            type=self['type'])
945 cf115aed Stavros Sachtouris
        _add_name(self, r)
946 77df3d4a Stavros Sachtouris
        self._print(r, print_dict)
947 77df3d4a Stavros Sachtouris
        if self['wait']:
948 77df3d4a Stavros Sachtouris
            self._wait(r['id'], 'PENDING')
949 5a673575 Stavros Sachtouris
950 7493ccb6 Stavros Sachtouris
    def main(self, name):
951 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
952 5a673575 Stavros Sachtouris
        self._run(name)
953 7493ccb6 Stavros Sachtouris
954 234954d1 Stavros Sachtouris
955 d486baec Stavros Sachtouris
@command(network_cmds)
956 1b73b4c1 Stavros Sachtouris
class network_rename(_init_cyclades, _optional_output_cmd):
957 0e806947 Stavros Sachtouris
    """Set the name of a network"""
958 7493ccb6 Stavros Sachtouris
959 5a673575 Stavros Sachtouris
    @errors.generic.all
960 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
961 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
962 5a673575 Stavros Sachtouris
    def _run(self, network_id, new_name):
963 1b73b4c1 Stavros Sachtouris
        self._optional_output(
964 1b73b4c1 Stavros Sachtouris
                self.client.update_network_name(int(network_id), new_name))
965 5a673575 Stavros Sachtouris
966 7493ccb6 Stavros Sachtouris
    def main(self, network_id, new_name):
967 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
968 5a673575 Stavros Sachtouris
        self._run(network_id=network_id, new_name=new_name)
969 7493ccb6 Stavros Sachtouris
970 234954d1 Stavros Sachtouris
971 d486baec Stavros Sachtouris
@command(network_cmds)
972 77df3d4a Stavros Sachtouris
class network_delete(_init_cyclades, _optional_output_cmd, _network_wait):
973 7493ccb6 Stavros Sachtouris
    """Delete a network"""
974 7493ccb6 Stavros Sachtouris
975 77df3d4a Stavros Sachtouris
    arguments = dict(
976 77df3d4a Stavros Sachtouris
        wait=FlagArgument('Wait network to build', ('-w', '--wait'))
977 77df3d4a Stavros Sachtouris
    )
978 77df3d4a Stavros Sachtouris
979 5a673575 Stavros Sachtouris
    @errors.generic.all
980 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
981 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
982 5a673575 Stavros Sachtouris
    @errors.cyclades.network_in_use
983 5a673575 Stavros Sachtouris
    def _run(self, network_id):
984 77df3d4a Stavros Sachtouris
        status = 'DELETED'
985 77df3d4a Stavros Sachtouris
        if self['wait']:
986 77df3d4a Stavros Sachtouris
            r = self.client.get_network_details(network_id)
987 77df3d4a Stavros Sachtouris
            status = r['status']
988 77df3d4a Stavros Sachtouris
            if status in ('DELETED', ):
989 77df3d4a Stavros Sachtouris
                return
990 77df3d4a Stavros Sachtouris
991 77df3d4a Stavros Sachtouris
        r = self.client.delete_network(int(network_id))
992 77df3d4a Stavros Sachtouris
        self._optional_output(r)
993 77df3d4a Stavros Sachtouris
994 77df3d4a Stavros Sachtouris
        if self['wait']:
995 77df3d4a Stavros Sachtouris
            self._wait(network_id, status)
996 5a673575 Stavros Sachtouris
997 7493ccb6 Stavros Sachtouris
    def main(self, network_id):
998 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
999 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
1000 7493ccb6 Stavros Sachtouris
1001 234954d1 Stavros Sachtouris
1002 d486baec Stavros Sachtouris
@command(network_cmds)
1003 1b73b4c1 Stavros Sachtouris
class network_connect(_init_cyclades, _optional_output_cmd):
1004 7493ccb6 Stavros Sachtouris
    """Connect a server to a network"""
1005 7493ccb6 Stavros Sachtouris
1006 5a673575 Stavros Sachtouris
    @errors.generic.all
1007 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
1008 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
1009 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
1010 5a673575 Stavros Sachtouris
    def _run(self, server_id, network_id):
1011 1b73b4c1 Stavros Sachtouris
        self._optional_output(
1012 1b73b4c1 Stavros Sachtouris
                self.client.connect_server(int(server_id), int(network_id)))
1013 5a673575 Stavros Sachtouris
1014 7493ccb6 Stavros Sachtouris
    def main(self, server_id, network_id):
1015 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
1016 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, network_id=network_id)
1017 7493ccb6 Stavros Sachtouris
1018 234954d1 Stavros Sachtouris
1019 d486baec Stavros Sachtouris
@command(network_cmds)
1020 7493ccb6 Stavros Sachtouris
class network_disconnect(_init_cyclades):
1021 0e806947 Stavros Sachtouris
    """Disconnect a nic that connects a server to a network
1022 0e806947 Stavros Sachtouris
    Nic ids are listed as "attachments" in detailed network information
1023 439826ec Stavros Sachtouris
    To get detailed network information: /network info <network id>
1024 0e806947 Stavros Sachtouris
    """
1025 7493ccb6 Stavros Sachtouris
1026 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_format
1027 5a673575 Stavros Sachtouris
    def _server_id_from_nic(self, nic_id):
1028 5a673575 Stavros Sachtouris
        return nic_id.split('-')[1]
1029 5a673575 Stavros Sachtouris
1030 5a673575 Stavros Sachtouris
    @errors.generic.all
1031 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
1032 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
1033 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_id
1034 5a673575 Stavros Sachtouris
    def _run(self, nic_id, server_id):
1035 1b73b4c1 Stavros Sachtouris
        num_of_disconnected = self.client.disconnect_server(server_id, nic_id)
1036 1b73b4c1 Stavros Sachtouris
        if not num_of_disconnected:
1037 5a673575 Stavros Sachtouris
            raise ClientError(
1038 5a673575 Stavros Sachtouris
                'Network Interface %s not found on server %s' % (
1039 5a673575 Stavros Sachtouris
                    nic_id,
1040 5a673575 Stavros Sachtouris
                    server_id),
1041 5a673575 Stavros Sachtouris
                status=404)
1042 1b73b4c1 Stavros Sachtouris
        print('Disconnected %s connections' % num_of_disconnected)
1043 5a673575 Stavros Sachtouris
1044 7493ccb6 Stavros Sachtouris
    def main(self, nic_id):
1045 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
1046 5a673575 Stavros Sachtouris
        server_id = self._server_id_from_nic(nic_id=nic_id)
1047 5a673575 Stavros Sachtouris
        self._run(nic_id=nic_id, server_id=server_id)
1048 9b47150e Stavros Sachtouris
1049 9b47150e Stavros Sachtouris
1050 7b2e4bf1 Stavros Sachtouris
@command(network_cmds)
1051 7b2e4bf1 Stavros Sachtouris
class network_wait(_init_cyclades, _network_wait):
1052 7b2e4bf1 Stavros Sachtouris
    """Wait for server to finish [PENDING, ACTIVE, DELETED]"""
1053 7b2e4bf1 Stavros Sachtouris
1054 7b2e4bf1 Stavros Sachtouris
    @errors.generic.all
1055 7b2e4bf1 Stavros Sachtouris
    @errors.cyclades.connection
1056 7b2e4bf1 Stavros Sachtouris
    @errors.cyclades.network_id
1057 7b2e4bf1 Stavros Sachtouris
    def _run(self, network_id, currect_status):
1058 7b2e4bf1 Stavros Sachtouris
        self._wait(network_id, currect_status)
1059 7b2e4bf1 Stavros Sachtouris
1060 7b2e4bf1 Stavros Sachtouris
    def main(self, network_id, currect_status='PENDING'):
1061 7b2e4bf1 Stavros Sachtouris
        super(self.__class__, self)._run()
1062 7b2e4bf1 Stavros Sachtouris
        self._run(network_id=network_id, currect_status=currect_status)
1063 7b2e4bf1 Stavros Sachtouris
1064 7b2e4bf1 Stavros Sachtouris
1065 8be50626 Stavros Sachtouris
@command(server_cmds)
1066 8be50626 Stavros Sachtouris
class server_ip(_init_cyclades):
1067 8be50626 Stavros Sachtouris
    """Manage floating IPs for the servers"""
1068 8be50626 Stavros Sachtouris
1069 8be50626 Stavros Sachtouris
1070 8be50626 Stavros Sachtouris
@command(server_cmds)
1071 8be50626 Stavros Sachtouris
class server_ip_pools(_init_cyclades, _optional_json):
1072 9b47150e Stavros Sachtouris
    """List all floating pools of floating ips"""
1073 9b47150e Stavros Sachtouris
1074 9b47150e Stavros Sachtouris
    @errors.generic.all
1075 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1076 9b47150e Stavros Sachtouris
    def _run(self):
1077 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ip_pools()
1078 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ip_pools'])
1079 9b47150e Stavros Sachtouris
1080 9b47150e Stavros Sachtouris
    def main(self):
1081 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1082 9b47150e Stavros Sachtouris
        self._run()
1083 9b47150e Stavros Sachtouris
1084 9b47150e Stavros Sachtouris
1085 8be50626 Stavros Sachtouris
@command(server_cmds)
1086 8be50626 Stavros Sachtouris
class server_ip_list(_init_cyclades, _optional_json):
1087 9b47150e Stavros Sachtouris
    """List all floating ips"""
1088 9b47150e Stavros Sachtouris
1089 9b47150e Stavros Sachtouris
    @errors.generic.all
1090 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1091 9b47150e Stavros Sachtouris
    def _run(self):
1092 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ips()
1093 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ips'])
1094 9b47150e Stavros Sachtouris
1095 9b47150e Stavros Sachtouris
    def main(self):
1096 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1097 9b47150e Stavros Sachtouris
        self._run()
1098 9b47150e Stavros Sachtouris
1099 9b47150e Stavros Sachtouris
1100 8be50626 Stavros Sachtouris
@command(server_cmds)
1101 8be50626 Stavros Sachtouris
class server_ip_info(_init_cyclades, _optional_json):
1102 9b47150e Stavros Sachtouris
    """A floating IPs' details"""
1103 9b47150e Stavros Sachtouris
1104 9b47150e Stavros Sachtouris
    @errors.generic.all
1105 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1106 9b47150e Stavros Sachtouris
    def _run(self, ip):
1107 9b47150e Stavros Sachtouris
        self._print(self.client.get_floating_ip(ip), print_dict)
1108 9b47150e Stavros Sachtouris
1109 9b47150e Stavros Sachtouris
    def main(self, ip):
1110 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1111 9b47150e Stavros Sachtouris
        self._run(ip=ip)
1112 9b47150e Stavros Sachtouris
1113 9b47150e Stavros Sachtouris
1114 8be50626 Stavros Sachtouris
@command(server_cmds)
1115 8be50626 Stavros Sachtouris
class server_ip_create(_init_cyclades, _optional_json):
1116 9b47150e Stavros Sachtouris
    """Create a new floating IP"""
1117 9b47150e Stavros Sachtouris
1118 9b47150e Stavros Sachtouris
    arguments = dict(
1119 9b47150e Stavros Sachtouris
        pool=ValueArgument('Source IP pool', ('--pool'), None)
1120 9b47150e Stavros Sachtouris
    )
1121 9b47150e Stavros Sachtouris
1122 9b47150e Stavros Sachtouris
    @errors.generic.all
1123 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1124 9b47150e Stavros Sachtouris
    def _run(self, ip=None):
1125 2e6e03da Stavros Sachtouris
        self._print([self.client.alloc_floating_ip(self['pool'], ip)])
1126 9b47150e Stavros Sachtouris
1127 9b47150e Stavros Sachtouris
    def main(self, requested_address=None):
1128 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1129 9b47150e Stavros Sachtouris
        self._run(ip=requested_address)
1130 9b47150e Stavros Sachtouris
1131 9b47150e Stavros Sachtouris
1132 8be50626 Stavros Sachtouris
@command(server_cmds)
1133 8be50626 Stavros Sachtouris
class server_ip_delete(_init_cyclades, _optional_output_cmd):
1134 9b47150e Stavros Sachtouris
    """Delete a floating ip"""
1135 9b47150e Stavros Sachtouris
1136 9b47150e Stavros Sachtouris
    @errors.generic.all
1137 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1138 9b47150e Stavros Sachtouris
    def _run(self, ip):
1139 9b47150e Stavros Sachtouris
        self._optional_output(self.client.delete_floating_ip(ip))
1140 9b47150e Stavros Sachtouris
1141 9b47150e Stavros Sachtouris
    def main(self, ip):
1142 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1143 9b47150e Stavros Sachtouris
        self._run(ip=ip)
1144 9b47150e Stavros Sachtouris
1145 9b47150e Stavros Sachtouris
1146 9b47150e Stavros Sachtouris
@command(server_cmds)
1147 9b47150e Stavros Sachtouris
class server_ip_attach(_init_cyclades, _optional_output_cmd):
1148 9b47150e Stavros Sachtouris
    """Attach a floating ip to a server with server_id
1149 9b47150e Stavros Sachtouris
    """
1150 9b47150e Stavros Sachtouris
1151 9b47150e Stavros Sachtouris
    @errors.generic.all
1152 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1153 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
1154 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
1155 9b47150e Stavros Sachtouris
        self._optional_output(self.client.attach_floating_ip(server_id, ip))
1156 9b47150e Stavros Sachtouris
1157 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
1158 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1159 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)
1160 9b47150e Stavros Sachtouris
1161 9b47150e Stavros Sachtouris
1162 9b47150e Stavros Sachtouris
@command(server_cmds)
1163 2e6e03da Stavros Sachtouris
class server_ip_detach(_init_cyclades, _optional_output_cmd):
1164 8be50626 Stavros Sachtouris
    """Detach floating IP from server
1165 9b47150e Stavros Sachtouris
    """
1166 9b47150e Stavros Sachtouris
1167 9b47150e Stavros Sachtouris
    @errors.generic.all
1168 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1169 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
1170 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
1171 9b47150e Stavros Sachtouris
        self._optional_output(self.client.detach_floating_ip(server_id, ip))
1172 9b47150e Stavros Sachtouris
1173 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
1174 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1175 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)