Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / cyclades.py @ 16d7b9ff

History | View | Annotate | Download (39.5 kB)

1 a494a741 Stavros Sachtouris
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 7493ccb6 Stavros Sachtouris
#
3 7493ccb6 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 7493ccb6 Stavros Sachtouris
# without modification, are permitted provided that the following
5 7493ccb6 Stavros Sachtouris
# conditions are met:
6 7493ccb6 Stavros Sachtouris
#
7 7493ccb6 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 7493ccb6 Stavros Sachtouris
#      disclaimer.
10 7493ccb6 Stavros Sachtouris
#
11 7493ccb6 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 7493ccb6 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 7493ccb6 Stavros Sachtouris
#      provided with the distribution.
15 7493ccb6 Stavros Sachtouris
#
16 7493ccb6 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 7493ccb6 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 7493ccb6 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 7493ccb6 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 7493ccb6 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 7493ccb6 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 7493ccb6 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 7493ccb6 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 7493ccb6 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 7493ccb6 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 7493ccb6 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 7493ccb6 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 7493ccb6 Stavros Sachtouris
#
29 7493ccb6 Stavros Sachtouris
# The views and conclusions contained in the software and
30 7493ccb6 Stavros Sachtouris
# documentation are those of the authors and should not be
31 7493ccb6 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 7493ccb6 Stavros Sachtouris
# or implied, of GRNET S.A.
33 7493ccb6 Stavros Sachtouris
34 76f58e2e Stavros Sachtouris
from base64 import b64encode
35 76f58e2e Stavros Sachtouris
from os.path import exists
36 76f58e2e Stavros Sachtouris
from io import StringIO
37 76f58e2e Stavros Sachtouris
from pydoc import pager
38 76f58e2e Stavros Sachtouris
39 f3e94e06 Stavros Sachtouris
from kamaki.cli import command
40 d486baec Stavros Sachtouris
from kamaki.cli.command_tree import CommandTree
41 76f58e2e Stavros Sachtouris
from kamaki.cli.utils import remove_from_items, filter_dicts_by_dict
42 8cec3671 Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError, CLISyntaxError, CLIBaseUrlError
43 7493ccb6 Stavros Sachtouris
from kamaki.clients.cyclades import CycladesClient, ClientError
44 57d622b6 Stavros Sachtouris
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
45 bd40efdf Stavros Sachtouris
from kamaki.cli.argument import ProgressBarArgument, DateArgument, IntArgument
46 b4f69041 Stavros Sachtouris
from kamaki.cli.commands import _command_init, errors, addLogSettings
47 6d190dd1 Stavros Sachtouris
from kamaki.cli.commands import (
48 6d190dd1 Stavros Sachtouris
    _optional_output_cmd, _optional_json, _name_filter, _id_filter)
49 5eae854d Stavros Sachtouris
50 234954d1 Stavros Sachtouris
51 a29d2f88 Stavros Sachtouris
server_cmds = CommandTree('server', 'Cyclades/Compute API server commands')
52 a29d2f88 Stavros Sachtouris
flavor_cmds = CommandTree('flavor', 'Cyclades/Compute API flavor commands')
53 a29d2f88 Stavros Sachtouris
network_cmds = CommandTree('network', 'Cyclades/Compute API network commands')
54 8be50626 Stavros Sachtouris
_commands = [server_cmds, flavor_cmds, network_cmds]
55 234954d1 Stavros Sachtouris
56 7493ccb6 Stavros Sachtouris
57 c314fc10 Stavros Sachtouris
about_authentication = '\nUser Authentication:\
58 4018326d Stavros Sachtouris
    \n* to check authentication: /user authenticate\
59 9e5341f5 Stavros Sachtouris
    \n* to set authentication token: /config set cloud.<cloud>.token <token>'
60 18edacfe Stavros Sachtouris
61 d7259dd5 Stavros Sachtouris
howto_personality = [
62 2bd23362 Stavros Sachtouris
    'Defines a file to be injected to virtual servers file system.',
63 3185cd6d Stavros Sachtouris
    'syntax:  PATH,[SERVER_PATH,[OWNER,[GROUP,[MODE]]]]',
64 3185cd6d Stavros Sachtouris
    '  PATH: local file to be injected (relative or absolute)',
65 d7259dd5 Stavros Sachtouris
    '  SERVER_PATH: destination location inside server Image',
66 2bd23362 Stavros Sachtouris
    '  OWNER: virtual servers user id of the remote destination file',
67 2bd23362 Stavros Sachtouris
    '  GROUP: virtual servers group id or name of the destination file',
68 16d7b9ff Stavros Sachtouris
    '  MODEL: permition in octal (e.g., 0777 or o+rwx)']
69 d7259dd5 Stavros Sachtouris
70 18edacfe Stavros Sachtouris
71 3185cd6d Stavros Sachtouris
class _service_wait(object):
72 60c42f9f Stavros Sachtouris
73 60c42f9f Stavros Sachtouris
    wait_arguments = dict(
74 60c42f9f Stavros Sachtouris
        progress_bar=ProgressBarArgument(
75 3185cd6d Stavros Sachtouris
            'do not show progress bar', ('-N', '--no-progress-bar'), False)
76 60c42f9f Stavros Sachtouris
    )
77 60c42f9f Stavros Sachtouris
78 3185cd6d Stavros Sachtouris
    def _wait(self, service, service_id, status_method, currect_status):
79 60c42f9f Stavros Sachtouris
        (progress_bar, wait_cb) = self._safe_progress_bar(
80 3185cd6d Stavros Sachtouris
            '%s %s still in %s mode' % (service, service_id, currect_status))
81 60c42f9f Stavros Sachtouris
82 60c42f9f Stavros Sachtouris
        try:
83 3185cd6d Stavros Sachtouris
            new_mode = status_method(
84 3185cd6d Stavros Sachtouris
                service_id, currect_status, wait_cb=wait_cb)
85 60c42f9f Stavros Sachtouris
        finally:
86 60c42f9f Stavros Sachtouris
            self._safe_progress_bar_finish(progress_bar)
87 60c42f9f Stavros Sachtouris
        if new_mode:
88 3185cd6d Stavros Sachtouris
            self.error('%s %s is now in %s mode' % (
89 3185cd6d Stavros Sachtouris
                service, service_id, new_mode))
90 60c42f9f Stavros Sachtouris
        else:
91 60c42f9f Stavros Sachtouris
            raiseCLIError(None, 'Time out')
92 60c42f9f Stavros Sachtouris
93 60c42f9f Stavros Sachtouris
94 3185cd6d Stavros Sachtouris
class _server_wait(_service_wait):
95 7b2e4bf1 Stavros Sachtouris
96 3185cd6d Stavros Sachtouris
    def _wait(self, server_id, currect_status):
97 3185cd6d Stavros Sachtouris
        super(_server_wait, self)._wait(
98 3185cd6d Stavros Sachtouris
            'Server', server_id, self.client.wait_server, currect_status)
99 7b2e4bf1 Stavros Sachtouris
100 7b2e4bf1 Stavros Sachtouris
101 3185cd6d Stavros Sachtouris
class _network_wait(_service_wait):
102 3185cd6d Stavros Sachtouris
103 3185cd6d Stavros Sachtouris
    def _wait(self, net_id, currect_status):
104 3185cd6d Stavros Sachtouris
        super(_network_wait, self)._wait(
105 3185cd6d Stavros Sachtouris
            'Network', net_id, self.client.wait_network, currect_status)
106 7b2e4bf1 Stavros Sachtouris
107 7b2e4bf1 Stavros Sachtouris
108 5eae854d Stavros Sachtouris
class _init_cyclades(_command_init):
109 b04288f7 Stavros Sachtouris
    @errors.generic.all
110 b4f69041 Stavros Sachtouris
    @addLogSettings
111 236e7d08 Stavros Sachtouris
    def _run(self, service='compute'):
112 b4f69041 Stavros Sachtouris
        if getattr(self, 'cloud', None):
113 3185cd6d Stavros Sachtouris
            base_url = self._custom_url(service) or self._custom_url(
114 3185cd6d Stavros Sachtouris
                'cyclades')
115 b4f69041 Stavros Sachtouris
            if base_url:
116 3185cd6d Stavros Sachtouris
                token = self._custom_token(service) or self._custom_token(
117 3185cd6d Stavros Sachtouris
                    'cyclades') or self.config.get_cloud('token')
118 3185cd6d Stavros Sachtouris
                self.client = CycladesClient(base_url=base_url, token=token)
119 b4f69041 Stavros Sachtouris
                return
120 b4f69041 Stavros Sachtouris
        else:
121 b4f69041 Stavros Sachtouris
            self.cloud = 'default'
122 8cec3671 Stavros Sachtouris
        if getattr(self, 'auth_base', False):
123 8cec3671 Stavros Sachtouris
            cyclades_endpoints = self.auth_base.get_service_endpoints(
124 b4f69041 Stavros Sachtouris
                self._custom_type('cyclades') or 'compute',
125 b4f69041 Stavros Sachtouris
                self._custom_version('cyclades') or '')
126 8cec3671 Stavros Sachtouris
            base_url = cyclades_endpoints['publicURL']
127 b4f69041 Stavros Sachtouris
            token = self.auth_base.token
128 b4f69041 Stavros Sachtouris
            self.client = CycladesClient(base_url=base_url, token=token)
129 8cec3671 Stavros Sachtouris
        else:
130 8cec3671 Stavros Sachtouris
            raise CLIBaseUrlError(service='cyclades')
131 8cec3671 Stavros Sachtouris
132 b04288f7 Stavros Sachtouris
    def main(self):
133 b04288f7 Stavros Sachtouris
        self._run()
134 236e7d08 Stavros Sachtouris
135 234954d1 Stavros Sachtouris
136 d486baec Stavros Sachtouris
@command(server_cmds)
137 6d190dd1 Stavros Sachtouris
class server_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
138 f6822a26 Stavros Sachtouris
    """List virtual servers accessible by user
139 16d7b9ff Stavros Sachtouris
    Use filtering arguments (e.g., --name-like) to manage long server lists
140 f6822a26 Stavros Sachtouris
    """
141 18edacfe Stavros Sachtouris
142 89ea97e1 Stavros Sachtouris
    PERMANENTS = ('id', 'name')
143 89ea97e1 Stavros Sachtouris
144 e15d78e2 Stavros Sachtouris
    arguments = dict(
145 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
146 67469d65 Stavros Sachtouris
        since=DateArgument(
147 a382ea56 Stavros Sachtouris
            'show only items since date (\' d/m/Y H:M:S \')',
148 a4d0d88a Stavros Sachtouris
            '--since'),
149 2bd23362 Stavros Sachtouris
        limit=IntArgument(
150 2bd23362 Stavros Sachtouris
            'limit number of listed virtual servers', ('-n', '--number')),
151 a4d0d88a Stavros Sachtouris
        more=FlagArgument(
152 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
153 ed9af02c Stavros Sachtouris
            '--more'),
154 89ea97e1 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
155 89ea97e1 Stavros Sachtouris
        flavor_id=ValueArgument('filter by flavor id', ('--flavor-id')),
156 89ea97e1 Stavros Sachtouris
        image_id=ValueArgument('filter by image id', ('--image-id')),
157 d8ff7b56 Stavros Sachtouris
        user_id=ValueArgument('filter by user id', ('--user-id')),
158 d8ff7b56 Stavros Sachtouris
        user_name=ValueArgument('filter by user name', ('--user-name')),
159 d8ff7b56 Stavros Sachtouris
        status=ValueArgument(
160 d8ff7b56 Stavros Sachtouris
            'filter by status (ACTIVE, STOPPED, REBOOT, ERROR, etc.)',
161 d8ff7b56 Stavros Sachtouris
            ('--status')),
162 89ea97e1 Stavros Sachtouris
        meta=KeyValueArgument('filter by metadata key=values', ('--metadata')),
163 89ea97e1 Stavros Sachtouris
        meta_like=KeyValueArgument(
164 89ea97e1 Stavros Sachtouris
            'print only if in key=value, the value is part of actual value',
165 89ea97e1 Stavros Sachtouris
            ('--metadata-like')),
166 e15d78e2 Stavros Sachtouris
    )
167 e15d78e2 Stavros Sachtouris
168 f00db940 Stavros Sachtouris
    def _add_user_name(self, servers):
169 9d2f656a Stavros Sachtouris
        uuids = self._uuids2usernames(list(set(
170 9d2f656a Stavros Sachtouris
                [srv['user_id'] for srv in servers] +
171 9d2f656a Stavros Sachtouris
                [srv['tenant_id'] for srv in servers])))
172 f00db940 Stavros Sachtouris
        for srv in servers:
173 f00db940 Stavros Sachtouris
            srv['user_id'] += ' (%s)' % uuids[srv['user_id']]
174 9d2f656a Stavros Sachtouris
            srv['tenant_id'] += ' (%s)' % uuids[srv['tenant_id']]
175 f00db940 Stavros Sachtouris
        return servers
176 f00db940 Stavros Sachtouris
177 d8ff7b56 Stavros Sachtouris
    def _apply_common_filters(self, servers):
178 d8ff7b56 Stavros Sachtouris
        common_filters = dict()
179 d8ff7b56 Stavros Sachtouris
        if self['status']:
180 d8ff7b56 Stavros Sachtouris
            common_filters['status'] = self['status']
181 d8ff7b56 Stavros Sachtouris
        if self['user_id'] or self['user_name']:
182 d8ff7b56 Stavros Sachtouris
            uuid = self['user_id'] or self._username2uuid(self['user_name'])
183 d8ff7b56 Stavros Sachtouris
            common_filters['user_id'] = uuid
184 d8ff7b56 Stavros Sachtouris
        return filter_dicts_by_dict(servers, common_filters)
185 d8ff7b56 Stavros Sachtouris
186 6d190dd1 Stavros Sachtouris
    def _filter_by_image(self, servers):
187 89ea97e1 Stavros Sachtouris
        iid = self['image_id']
188 3185cd6d Stavros Sachtouris
        return [srv for srv in servers if srv['image']['id'] == iid]
189 89ea97e1 Stavros Sachtouris
190 6d190dd1 Stavros Sachtouris
    def _filter_by_flavor(self, servers):
191 89ea97e1 Stavros Sachtouris
        fid = self['flavor_id']
192 3185cd6d Stavros Sachtouris
        return [srv for srv in servers if (
193 3185cd6d Stavros Sachtouris
            '%s' % srv['image']['id'] == '%s' % fid)]
194 89ea97e1 Stavros Sachtouris
195 6d190dd1 Stavros Sachtouris
    def _filter_by_metadata(self, servers):
196 89ea97e1 Stavros Sachtouris
        new_servers = []
197 89ea97e1 Stavros Sachtouris
        for srv in servers:
198 89ea97e1 Stavros Sachtouris
            if not 'metadata' in srv:
199 89ea97e1 Stavros Sachtouris
                continue
200 89ea97e1 Stavros Sachtouris
            meta = [dict(srv['metadata'])]
201 89ea97e1 Stavros Sachtouris
            if self['meta']:
202 89ea97e1 Stavros Sachtouris
                meta = filter_dicts_by_dict(meta, self['meta'])
203 89ea97e1 Stavros Sachtouris
            if meta and self['meta_like']:
204 89ea97e1 Stavros Sachtouris
                meta = filter_dicts_by_dict(
205 89ea97e1 Stavros Sachtouris
                    meta, self['meta_like'], exact_match=False)
206 89ea97e1 Stavros Sachtouris
            if meta:
207 89ea97e1 Stavros Sachtouris
                new_servers.append(srv)
208 89ea97e1 Stavros Sachtouris
        return new_servers
209 89ea97e1 Stavros Sachtouris
210 b04288f7 Stavros Sachtouris
    @errors.generic.all
211 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
212 b04288f7 Stavros Sachtouris
    @errors.cyclades.date
213 b04288f7 Stavros Sachtouris
    def _run(self):
214 89ea97e1 Stavros Sachtouris
        withimage = bool(self['image_id'])
215 89ea97e1 Stavros Sachtouris
        withflavor = bool(self['flavor_id'])
216 89ea97e1 Stavros Sachtouris
        withmeta = bool(self['meta'] or self['meta_like'])
217 d8ff7b56 Stavros Sachtouris
        withcommons = bool(
218 d8ff7b56 Stavros Sachtouris
            self['status'] or self['user_id'] or self['user_name'])
219 d8ff7b56 Stavros Sachtouris
        detail = self['detail'] or (
220 d8ff7b56 Stavros Sachtouris
            withimage or withflavor or withmeta or withcommons)
221 89ea97e1 Stavros Sachtouris
        servers = self.client.list_servers(detail, self['since'])
222 89ea97e1 Stavros Sachtouris
223 6d190dd1 Stavros Sachtouris
        servers = self._filter_by_name(servers)
224 6d190dd1 Stavros Sachtouris
        servers = self._filter_by_id(servers)
225 d8ff7b56 Stavros Sachtouris
        servers = self._apply_common_filters(servers)
226 89ea97e1 Stavros Sachtouris
        if withimage:
227 6d190dd1 Stavros Sachtouris
            servers = self._filter_by_image(servers)
228 89ea97e1 Stavros Sachtouris
        if withflavor:
229 6d190dd1 Stavros Sachtouris
            servers = self._filter_by_flavor(servers)
230 89ea97e1 Stavros Sachtouris
        if withmeta:
231 6d190dd1 Stavros Sachtouris
            servers = self._filter_by_metadata(servers)
232 89ea97e1 Stavros Sachtouris
233 f00db940 Stavros Sachtouris
        if self['detail'] and not self['json_output']:
234 f00db940 Stavros Sachtouris
            servers = self._add_user_name(servers)
235 f00db940 Stavros Sachtouris
        elif not (self['detail'] or self['json_output']):
236 7ba195e5 Stavros Sachtouris
            remove_from_items(servers, 'links')
237 89ea97e1 Stavros Sachtouris
        if detail and not self['detail']:
238 89ea97e1 Stavros Sachtouris
            for srv in servers:
239 89ea97e1 Stavros Sachtouris
                for key in set(srv).difference(self.PERMANENTS):
240 89ea97e1 Stavros Sachtouris
                    srv.pop(key)
241 545c6c29 Stavros Sachtouris
        kwargs = dict(with_enumeration=self['enum'])
242 a4d0d88a Stavros Sachtouris
        if self['more']:
243 6430d3a0 Stavros Sachtouris
            kwargs['out'] = StringIO()
244 6430d3a0 Stavros Sachtouris
            kwargs['title'] = ()
245 6430d3a0 Stavros Sachtouris
        if self['limit']:
246 545c6c29 Stavros Sachtouris
            servers = servers[:self['limit']]
247 545c6c29 Stavros Sachtouris
        self._print(servers, **kwargs)
248 6430d3a0 Stavros Sachtouris
        if self['more']:
249 6430d3a0 Stavros Sachtouris
            pager(kwargs['out'].getvalue())
250 7493ccb6 Stavros Sachtouris
251 b04288f7 Stavros Sachtouris
    def main(self):
252 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
253 b04288f7 Stavros Sachtouris
        self._run()
254 b04288f7 Stavros Sachtouris
255 234954d1 Stavros Sachtouris
256 d486baec Stavros Sachtouris
@command(server_cmds)
257 545c6c29 Stavros Sachtouris
class server_info(_init_cyclades, _optional_json):
258 67469d65 Stavros Sachtouris
    """Detailed information on a Virtual Machine
259 67469d65 Stavros Sachtouris
    Contains:
260 67469d65 Stavros Sachtouris
    - name, id, status, create/update dates
261 67469d65 Stavros Sachtouris
    - network interfaces
262 16d7b9ff Stavros Sachtouris
    - metadata (e.g., os, superuser) and diagnostics
263 67469d65 Stavros Sachtouris
    - hardware flavor and os image ids
264 67469d65 Stavros Sachtouris
    """
265 7493ccb6 Stavros Sachtouris
266 b04288f7 Stavros Sachtouris
    @errors.generic.all
267 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
268 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
269 b04288f7 Stavros Sachtouris
    def _run(self, server_id):
270 cf115aed Stavros Sachtouris
        vm = self.client.get_server_details(server_id)
271 cf115aed Stavros Sachtouris
        uuids = self._uuids2usernames([vm['user_id'], vm['tenant_id']])
272 cf115aed Stavros Sachtouris
        vm['user_id'] += ' (%s)' % uuids[vm['user_id']]
273 cf115aed Stavros Sachtouris
        vm['tenant_id'] += ' (%s)' % uuids[vm['tenant_id']]
274 76f58e2e Stavros Sachtouris
        self._print(vm, self.print_dict)
275 7493ccb6 Stavros Sachtouris
276 b04288f7 Stavros Sachtouris
    def main(self, server_id):
277 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
278 b04288f7 Stavros Sachtouris
        self._run(server_id=server_id)
279 b04288f7 Stavros Sachtouris
280 234954d1 Stavros Sachtouris
281 57d622b6 Stavros Sachtouris
class PersonalityArgument(KeyValueArgument):
282 234954d1 Stavros Sachtouris
    @property
283 f3e94e06 Stavros Sachtouris
    def value(self):
284 57d622b6 Stavros Sachtouris
        return self._value if hasattr(self, '_value') else []
285 234954d1 Stavros Sachtouris
286 234954d1 Stavros Sachtouris
    @value.setter
287 f3e94e06 Stavros Sachtouris
    def value(self, newvalue):
288 f3e94e06 Stavros Sachtouris
        if newvalue == self.default:
289 f3e94e06 Stavros Sachtouris
            return self.value
290 57d622b6 Stavros Sachtouris
        self._value = []
291 57d622b6 Stavros Sachtouris
        for i, terms in enumerate(newvalue):
292 57d622b6 Stavros Sachtouris
            termlist = terms.split(',')
293 57d622b6 Stavros Sachtouris
            if len(termlist) > 5:
294 de73876b Stavros Sachtouris
                msg = 'Wrong number of terms (should be 1 to 5)'
295 de73876b Stavros Sachtouris
                raiseCLIError(CLISyntaxError(msg), details=howto_personality)
296 57d622b6 Stavros Sachtouris
            path = termlist[0]
297 57d622b6 Stavros Sachtouris
            if not exists(path):
298 de73876b Stavros Sachtouris
                raiseCLIError(
299 de73876b Stavros Sachtouris
                    None,
300 8194b51b Stavros Sachtouris
                    '--personality: File %s does not exist' % path,
301 3185cd6d Stavros Sachtouris
                    importance=1, details=howto_personality)
302 57d622b6 Stavros Sachtouris
            self._value.append(dict(path=path))
303 57d622b6 Stavros Sachtouris
            with open(path) as f:
304 57d622b6 Stavros Sachtouris
                self._value[i]['contents'] = b64encode(f.read())
305 57d622b6 Stavros Sachtouris
            try:
306 57d622b6 Stavros Sachtouris
                self._value[i]['path'] = termlist[1]
307 57d622b6 Stavros Sachtouris
                self._value[i]['owner'] = termlist[2]
308 57d622b6 Stavros Sachtouris
                self._value[i]['group'] = termlist[3]
309 57d622b6 Stavros Sachtouris
                self._value[i]['mode'] = termlist[4]
310 57d622b6 Stavros Sachtouris
            except IndexError:
311 57d622b6 Stavros Sachtouris
                pass
312 f3e94e06 Stavros Sachtouris
313 234954d1 Stavros Sachtouris
314 d486baec Stavros Sachtouris
@command(server_cmds)
315 60c42f9f Stavros Sachtouris
class server_create(_init_cyclades, _optional_json, _server_wait):
316 8194b51b Stavros Sachtouris
    """Create a server (aka Virtual Machine)
317 8194b51b Stavros Sachtouris
    Parameters:
318 439826ec Stavros Sachtouris
    - name: (single quoted text)
319 439826ec Stavros Sachtouris
    - flavor id: Hardware flavor. Pick one from: /flavor list
320 439826ec Stavros Sachtouris
    - image id: OS images. Pick one from: /image list
321 8194b51b Stavros Sachtouris
    """
322 7493ccb6 Stavros Sachtouris
323 93914390 Stavros Sachtouris
    arguments = dict(
324 93914390 Stavros Sachtouris
        personality=PersonalityArgument(
325 60c42f9f Stavros Sachtouris
            (80 * ' ').join(howto_personality), ('-p', '--personality')),
326 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to build', ('-w', '--wait'))
327 93914390 Stavros Sachtouris
    )
328 f3e94e06 Stavros Sachtouris
329 b04288f7 Stavros Sachtouris
    @errors.generic.all
330 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
331 b04288f7 Stavros Sachtouris
    @errors.plankton.id
332 b04288f7 Stavros Sachtouris
    @errors.cyclades.flavor_id
333 b04288f7 Stavros Sachtouris
    def _run(self, name, flavor_id, image_id):
334 60c42f9f Stavros Sachtouris
        r = self.client.create_server(
335 07fdc00c Stavros Sachtouris
            name, int(flavor_id), image_id, personality=self['personality'])
336 cf115aed Stavros Sachtouris
        usernames = self._uuids2usernames([r['user_id'], r['tenant_id']])
337 cf115aed Stavros Sachtouris
        r['user_id'] += ' (%s)' % usernames[r['user_id']]
338 cf115aed Stavros Sachtouris
        r['tenant_id'] += ' (%s)' % usernames[r['tenant_id']]
339 76f58e2e Stavros Sachtouris
        self._print(r, self.print_dict)
340 60c42f9f Stavros Sachtouris
        if self['wait']:
341 60c42f9f Stavros Sachtouris
            self._wait(r['id'], r['status'])
342 b04288f7 Stavros Sachtouris
343 7493ccb6 Stavros Sachtouris
    def main(self, name, flavor_id, image_id):
344 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
345 b04288f7 Stavros Sachtouris
        self._run(name=name, flavor_id=flavor_id, image_id=image_id)
346 7493ccb6 Stavros Sachtouris
347 234954d1 Stavros Sachtouris
348 d486baec Stavros Sachtouris
@command(server_cmds)
349 cd295a1d Stavros Sachtouris
class server_rename(_init_cyclades, _optional_output_cmd):
350 2bd23362 Stavros Sachtouris
    """Set/update a virtual server name
351 2bd23362 Stavros Sachtouris
    virtual server names are not unique, therefore multiple servers may share
352 2bd23362 Stavros Sachtouris
    the same name
353 22b6f063 Stavros Sachtouris
    """
354 7493ccb6 Stavros Sachtouris
355 5a673575 Stavros Sachtouris
    @errors.generic.all
356 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
357 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
358 5a673575 Stavros Sachtouris
    def _run(self, server_id, new_name):
359 cd295a1d Stavros Sachtouris
        self._optional_output(
360 cd295a1d Stavros Sachtouris
            self.client.update_server_name(int(server_id), new_name))
361 5a673575 Stavros Sachtouris
362 7493ccb6 Stavros Sachtouris
    def main(self, server_id, new_name):
363 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
364 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, new_name=new_name)
365 234954d1 Stavros Sachtouris
366 7493ccb6 Stavros Sachtouris
367 d486baec Stavros Sachtouris
@command(server_cmds)
368 60c42f9f Stavros Sachtouris
class server_delete(_init_cyclades, _optional_output_cmd, _server_wait):
369 2bd23362 Stavros Sachtouris
    """Delete a virtual server"""
370 7493ccb6 Stavros Sachtouris
371 60c42f9f Stavros Sachtouris
    arguments = dict(
372 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
373 60c42f9f Stavros Sachtouris
    )
374 60c42f9f Stavros Sachtouris
375 5a673575 Stavros Sachtouris
    @errors.generic.all
376 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
377 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
378 5a673575 Stavros Sachtouris
    def _run(self, server_id):
379 60c42f9f Stavros Sachtouris
            status = 'DELETED'
380 60c42f9f Stavros Sachtouris
            if self['wait']:
381 60c42f9f Stavros Sachtouris
                details = self.client.get_server_details(server_id)
382 60c42f9f Stavros Sachtouris
                status = details['status']
383 60c42f9f Stavros Sachtouris
384 60c42f9f Stavros Sachtouris
            r = self.client.delete_server(int(server_id))
385 60c42f9f Stavros Sachtouris
            self._optional_output(r)
386 60c42f9f Stavros Sachtouris
387 60c42f9f Stavros Sachtouris
            if self['wait']:
388 60c42f9f Stavros Sachtouris
                self._wait(server_id, status)
389 5a673575 Stavros Sachtouris
390 5a673575 Stavros Sachtouris
    def main(self, server_id):
391 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
392 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
393 234954d1 Stavros Sachtouris
394 7493ccb6 Stavros Sachtouris
395 d486baec Stavros Sachtouris
@command(server_cmds)
396 60c42f9f Stavros Sachtouris
class server_reboot(_init_cyclades, _optional_output_cmd, _server_wait):
397 2bd23362 Stavros Sachtouris
    """Reboot a virtual server"""
398 18edacfe Stavros Sachtouris
399 93914390 Stavros Sachtouris
    arguments = dict(
400 a1dc95ac Stavros Sachtouris
        hard=FlagArgument(
401 a1dc95ac Stavros Sachtouris
            'perform a hard reboot (deprecated)', ('-f', '--force')),
402 a1dc95ac Stavros Sachtouris
        type=ValueArgument('SOFT or HARD - default: SOFT', ('--type')),
403 60c42f9f Stavros Sachtouris
        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
404 93914390 Stavros Sachtouris
    )
405 7493ccb6 Stavros Sachtouris
406 5a673575 Stavros Sachtouris
    @errors.generic.all
407 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
408 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
409 5a673575 Stavros Sachtouris
    def _run(self, server_id):
410 a1dc95ac Stavros Sachtouris
        hard_reboot = self['hard']
411 a1dc95ac Stavros Sachtouris
        if hard_reboot:
412 a1dc95ac Stavros Sachtouris
            self.error(
413 a1dc95ac Stavros Sachtouris
                'WARNING: -f/--force will be deprecated in version 0.12\n'
414 a1dc95ac Stavros Sachtouris
                '\tIn the future, please use --type=hard instead')
415 a1dc95ac Stavros Sachtouris
        if self['type']:
416 a1dc95ac Stavros Sachtouris
            if self['type'].lower() in ('soft', ):
417 a1dc95ac Stavros Sachtouris
                hard_reboot = False
418 a1dc95ac Stavros Sachtouris
            elif self['type'].lower() in ('hard', ):
419 a1dc95ac Stavros Sachtouris
                hard_reboot = True
420 a1dc95ac Stavros Sachtouris
            else:
421 a1dc95ac Stavros Sachtouris
                raise CLISyntaxError(
422 a1dc95ac Stavros Sachtouris
                    'Invalid reboot type %s' % self['type'],
423 a1dc95ac Stavros Sachtouris
                    importance=2, details=[
424 a1dc95ac Stavros Sachtouris
                        '--type values are either SOFT (default) or HARD'])
425 a1dc95ac Stavros Sachtouris
426 a1dc95ac Stavros Sachtouris
        r = self.client.reboot_server(int(server_id), hard_reboot)
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 2bd23362 Stavros Sachtouris
    """Start an existing virtual server"""
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 2bd23362 Stavros Sachtouris
    """Shutdown an active virtual server"""
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 2bd23362 Stavros Sachtouris
    """Get a VNC console to access an existing virtual server
500 22b6f063 Stavros Sachtouris
    Console connection information provided (at least):
501 439826ec Stavros Sachtouris
    - host: (url or address) a VNC host
502 2bd23362 Stavros Sachtouris
    - port: (int) the gateway to enter virtual server 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 76f58e2e Stavros Sachtouris
            self.client.get_server_console(int(server_id)), self.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 2bd23362 Stavros Sachtouris
    """Manage virtual server 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 2bd23362 Stavros Sachtouris
    """Set the firewall profile on virtual server 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 2bd23362 Stavros Sachtouris
    """Get the firewall profile for a virtual servers' 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 3185cd6d Stavros Sachtouris
        self.writeln(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 2bd23362 Stavros Sachtouris
    """List the addresses of all network interfaces on a virtual server"""
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 3185cd6d Stavros Sachtouris
        self._print(reply, with_enumeration=self['enum'] and (reply) > 1)
594 7493ccb6 Stavros Sachtouris
595 5a673575 Stavros Sachtouris
    def main(self, server_id):
596 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
597 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
598 5a673575 Stavros Sachtouris
599 234954d1 Stavros Sachtouris
600 d486baec Stavros Sachtouris
@command(server_cmds)
601 cd295a1d Stavros Sachtouris
class server_metadata(_init_cyclades):
602 cd295a1d Stavros Sachtouris
    """Manage Server metadata (key:value pairs of server attributes)"""
603 cd295a1d Stavros Sachtouris
604 cd295a1d Stavros Sachtouris
605 cd295a1d Stavros Sachtouris
@command(server_cmds)
606 545c6c29 Stavros Sachtouris
class server_metadata_list(_init_cyclades, _optional_json):
607 cd295a1d Stavros Sachtouris
    """Get server metadata"""
608 7493ccb6 Stavros Sachtouris
609 5a673575 Stavros Sachtouris
    @errors.generic.all
610 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
611 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
612 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
613 5a673575 Stavros Sachtouris
    def _run(self, server_id, key=''):
614 545c6c29 Stavros Sachtouris
        self._print(
615 76f58e2e Stavros Sachtouris
            self.client.get_server_metadata(int(server_id), key),
616 76f58e2e Stavros Sachtouris
            self.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 2bd23362 Stavros Sachtouris
    """Set / update virtual server 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 76f58e2e Stavros Sachtouris
            self.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 2bd23362 Stavros Sachtouris
    """Delete virtual server 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 2bd23362 Stavros Sachtouris
    """Get virtual server 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 76f58e2e Stavros Sachtouris
        self._print(
684 76f58e2e Stavros Sachtouris
            self.client.get_server_stats(int(server_id)), self.print_dict)
685 5a673575 Stavros Sachtouris
686 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
687 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
688 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
689 7493ccb6 Stavros Sachtouris
690 234954d1 Stavros Sachtouris
691 d486baec Stavros Sachtouris
@command(server_cmds)
692 60c42f9f Stavros Sachtouris
class server_wait(_init_cyclades, _server_wait):
693 fd1f1d96 Stavros Sachtouris
    """Wait for server to finish [BUILD, STOPPED, REBOOT, ACTIVE]"""
694 fd1f1d96 Stavros Sachtouris
695 5a673575 Stavros Sachtouris
    @errors.generic.all
696 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
697 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
698 5a673575 Stavros Sachtouris
    def _run(self, server_id, currect_status):
699 60c42f9f Stavros Sachtouris
        self._wait(server_id, currect_status)
700 fd1f1d96 Stavros Sachtouris
701 5a673575 Stavros Sachtouris
    def main(self, server_id, currect_status='BUILD'):
702 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
703 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, currect_status=currect_status)
704 5a673575 Stavros Sachtouris
705 fd1f1d96 Stavros Sachtouris
706 d486baec Stavros Sachtouris
@command(flavor_cmds)
707 6d190dd1 Stavros Sachtouris
class flavor_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
708 bd40efdf Stavros Sachtouris
    """List available hardware flavors"""
709 7493ccb6 Stavros Sachtouris
710 d8ff7b56 Stavros Sachtouris
    PERMANENTS = ('id', 'name')
711 d8ff7b56 Stavros Sachtouris
712 93914390 Stavros Sachtouris
    arguments = dict(
713 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
714 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed flavors', ('-n', '--number')),
715 bd40efdf Stavros Sachtouris
        more=FlagArgument(
716 de73876b Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
717 ed9af02c Stavros Sachtouris
            '--more'),
718 d8ff7b56 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
719 d8ff7b56 Stavros Sachtouris
        ram=ValueArgument('filter by ram', ('--ram')),
720 d8ff7b56 Stavros Sachtouris
        vcpus=ValueArgument('filter by number of VCPUs', ('--vcpus')),
721 d8ff7b56 Stavros Sachtouris
        disk=ValueArgument('filter by disk size in GB', ('--disk')),
722 d8ff7b56 Stavros Sachtouris
        disk_template=ValueArgument(
723 d8ff7b56 Stavros Sachtouris
            'filter by disk_templace', ('--disk-template'))
724 93914390 Stavros Sachtouris
    )
725 7493ccb6 Stavros Sachtouris
726 d8ff7b56 Stavros Sachtouris
    def _apply_common_filters(self, flavors):
727 d8ff7b56 Stavros Sachtouris
        common_filters = dict()
728 d8ff7b56 Stavros Sachtouris
        if self['ram']:
729 d8ff7b56 Stavros Sachtouris
            common_filters['ram'] = self['ram']
730 d8ff7b56 Stavros Sachtouris
        if self['vcpus']:
731 d8ff7b56 Stavros Sachtouris
            common_filters['vcpus'] = self['vcpus']
732 d8ff7b56 Stavros Sachtouris
        if self['disk']:
733 d8ff7b56 Stavros Sachtouris
            common_filters['disk'] = self['disk']
734 d8ff7b56 Stavros Sachtouris
        if self['disk_template']:
735 d8ff7b56 Stavros Sachtouris
            common_filters['SNF:disk_template'] = self['disk_template']
736 d8ff7b56 Stavros Sachtouris
        return filter_dicts_by_dict(flavors, common_filters)
737 d8ff7b56 Stavros Sachtouris
738 5a673575 Stavros Sachtouris
    @errors.generic.all
739 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
740 5a673575 Stavros Sachtouris
    def _run(self):
741 d8ff7b56 Stavros Sachtouris
        withcommons = self['ram'] or self['vcpus'] or (
742 d8ff7b56 Stavros Sachtouris
            self['disk'] or self['disk_template'])
743 d8ff7b56 Stavros Sachtouris
        detail = self['detail'] or withcommons
744 d8ff7b56 Stavros Sachtouris
        flavors = self.client.list_flavors(detail)
745 6d190dd1 Stavros Sachtouris
        flavors = self._filter_by_name(flavors)
746 6d190dd1 Stavros Sachtouris
        flavors = self._filter_by_id(flavors)
747 d8ff7b56 Stavros Sachtouris
        if withcommons:
748 d8ff7b56 Stavros Sachtouris
            flavors = self._apply_common_filters(flavors)
749 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
750 7ba195e5 Stavros Sachtouris
            remove_from_items(flavors, 'links')
751 d8ff7b56 Stavros Sachtouris
        if detail and not self['detail']:
752 d8ff7b56 Stavros Sachtouris
            for flv in flavors:
753 d8ff7b56 Stavros Sachtouris
                for key in set(flv).difference(self.PERMANENTS):
754 d8ff7b56 Stavros Sachtouris
                    flv.pop(key)
755 6430d3a0 Stavros Sachtouris
        kwargs = dict(out=StringIO(), title=()) if self['more'] else {}
756 545c6c29 Stavros Sachtouris
        self._print(
757 ed9af02c Stavros Sachtouris
            flavors,
758 6430d3a0 Stavros Sachtouris
            with_redundancy=self['detail'], with_enumeration=self['enum'],
759 6430d3a0 Stavros Sachtouris
            **kwargs)
760 6430d3a0 Stavros Sachtouris
        if self['more']:
761 6430d3a0 Stavros Sachtouris
            pager(kwargs['out'].getvalue())
762 5a673575 Stavros Sachtouris
763 7493ccb6 Stavros Sachtouris
    def main(self):
764 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
765 5a673575 Stavros Sachtouris
        self._run()
766 7493ccb6 Stavros Sachtouris
767 234954d1 Stavros Sachtouris
768 d486baec Stavros Sachtouris
@command(flavor_cmds)
769 545c6c29 Stavros Sachtouris
class flavor_info(_init_cyclades, _optional_json):
770 769dbf53 Stavros Sachtouris
    """Detailed information on a hardware flavor
771 ddc0b290 Stavros Sachtouris
    To get a list of available flavors and flavor ids, try /flavor list
772 ddc0b290 Stavros Sachtouris
    """
773 7493ccb6 Stavros Sachtouris
774 5a673575 Stavros Sachtouris
    @errors.generic.all
775 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
776 5a673575 Stavros Sachtouris
    @errors.cyclades.flavor_id
777 5a673575 Stavros Sachtouris
    def _run(self, flavor_id):
778 bcef3ac9 Stavros Sachtouris
        self._print(
779 76f58e2e Stavros Sachtouris
            self.client.get_flavor_details(int(flavor_id)), self.print_dict)
780 7493ccb6 Stavros Sachtouris
781 5a673575 Stavros Sachtouris
    def main(self, flavor_id):
782 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
783 5a673575 Stavros Sachtouris
        self._run(flavor_id=flavor_id)
784 5a673575 Stavros Sachtouris
785 234954d1 Stavros Sachtouris
786 cf115aed Stavros Sachtouris
def _add_name(self, net):
787 cf115aed Stavros Sachtouris
        user_id, tenant_id, uuids = net['user_id'], net['tenant_id'], []
788 cf115aed Stavros Sachtouris
        if user_id:
789 cf115aed Stavros Sachtouris
            uuids.append(user_id)
790 cf115aed Stavros Sachtouris
        if tenant_id:
791 cf115aed Stavros Sachtouris
            uuids.append(tenant_id)
792 cf115aed Stavros Sachtouris
        if uuids:
793 cf115aed Stavros Sachtouris
            usernames = self._uuids2usernames(uuids)
794 cf115aed Stavros Sachtouris
            if user_id:
795 cf115aed Stavros Sachtouris
                net['user_id'] += ' (%s)' % usernames[user_id]
796 cf115aed Stavros Sachtouris
            if tenant_id:
797 cf115aed Stavros Sachtouris
                net['tenant_id'] += ' (%s)' % usernames[tenant_id]
798 cf115aed Stavros Sachtouris
799 cf115aed Stavros Sachtouris
800 d486baec Stavros Sachtouris
@command(network_cmds)
801 545c6c29 Stavros Sachtouris
class network_info(_init_cyclades, _optional_json):
802 ddc0b290 Stavros Sachtouris
    """Detailed information on a network
803 ddc0b290 Stavros Sachtouris
    To get a list of available networks and network ids, try /network list
804 ddc0b290 Stavros Sachtouris
    """
805 c17b8bc0 Stavros Sachtouris
806 5a673575 Stavros Sachtouris
    @errors.generic.all
807 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
808 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
809 5a673575 Stavros Sachtouris
    def _run(self, network_id):
810 5a673575 Stavros Sachtouris
        network = self.client.get_network_details(int(network_id))
811 cf115aed Stavros Sachtouris
        _add_name(self, network)
812 76f58e2e Stavros Sachtouris
        self._print(network, self.print_dict, exclude=('id'))
813 5a673575 Stavros Sachtouris
814 c17b8bc0 Stavros Sachtouris
    def main(self, network_id):
815 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
816 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
817 c17b8bc0 Stavros Sachtouris
818 c17b8bc0 Stavros Sachtouris
819 c17b8bc0 Stavros Sachtouris
@command(network_cmds)
820 6d190dd1 Stavros Sachtouris
class network_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
821 7493ccb6 Stavros Sachtouris
    """List networks"""
822 7493ccb6 Stavros Sachtouris
823 c79faeb5 Stavros Sachtouris
    PERMANENTS = ('id', 'name')
824 c79faeb5 Stavros Sachtouris
825 93914390 Stavros Sachtouris
    arguments = dict(
826 f40f0cb7 Stavros Sachtouris
        detail=FlagArgument('show detailed output', ('-l', '--details')),
827 f40f0cb7 Stavros Sachtouris
        limit=IntArgument('limit # of listed networks', ('-n', '--number')),
828 ddc0b290 Stavros Sachtouris
        more=FlagArgument(
829 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
830 ed9af02c Stavros Sachtouris
            '--more'),
831 c79faeb5 Stavros Sachtouris
        enum=FlagArgument('Enumerate results', '--enumerate'),
832 c79faeb5 Stavros Sachtouris
        status=ValueArgument('filter by status', ('--status')),
833 c79faeb5 Stavros Sachtouris
        public=FlagArgument('only public networks', ('--public')),
834 c79faeb5 Stavros Sachtouris
        private=FlagArgument('only private networks', ('--private')),
835 c79faeb5 Stavros Sachtouris
        dhcp=FlagArgument('show networks with dhcp', ('--with-dhcp')),
836 c79faeb5 Stavros Sachtouris
        no_dhcp=FlagArgument('show networks without dhcp', ('--without-dhcp')),
837 c79faeb5 Stavros Sachtouris
        user_id=ValueArgument('filter by user id', ('--user-id')),
838 c79faeb5 Stavros Sachtouris
        user_name=ValueArgument('filter by user name', ('--user-name')),
839 c79faeb5 Stavros Sachtouris
        gateway=ValueArgument('filter by gateway (IPv4)', ('--gateway')),
840 c79faeb5 Stavros Sachtouris
        gateway6=ValueArgument('filter by gateway (IPv6)', ('--gateway6')),
841 c79faeb5 Stavros Sachtouris
        cidr=ValueArgument('filter by cidr (IPv4)', ('--cidr')),
842 c79faeb5 Stavros Sachtouris
        cidr6=ValueArgument('filter by cidr (IPv6)', ('--cidr6')),
843 c79faeb5 Stavros Sachtouris
        type=ValueArgument('filter by type', ('--type')),
844 93914390 Stavros Sachtouris
    )
845 7493ccb6 Stavros Sachtouris
846 c79faeb5 Stavros Sachtouris
    def _apply_common_filters(self, networks):
847 c79faeb5 Stavros Sachtouris
        common_filter = dict()
848 c79faeb5 Stavros Sachtouris
        if self['public']:
849 c79faeb5 Stavros Sachtouris
            if self['private']:
850 c79faeb5 Stavros Sachtouris
                return []
851 c79faeb5 Stavros Sachtouris
            common_filter['public'] = self['public']
852 c79faeb5 Stavros Sachtouris
        elif self['private']:
853 c79faeb5 Stavros Sachtouris
            common_filter['public'] = False
854 c79faeb5 Stavros Sachtouris
        if self['dhcp']:
855 c79faeb5 Stavros Sachtouris
            if self['no_dhcp']:
856 c79faeb5 Stavros Sachtouris
                return []
857 c79faeb5 Stavros Sachtouris
            common_filter['dhcp'] = True
858 c79faeb5 Stavros Sachtouris
        elif self['no_dhcp']:
859 c79faeb5 Stavros Sachtouris
            common_filter['dhcp'] = False
860 c79faeb5 Stavros Sachtouris
        if self['user_id'] or self['user_name']:
861 c79faeb5 Stavros Sachtouris
            uuid = self['user_id'] or self._username2uuid(self['user_name'])
862 c79faeb5 Stavros Sachtouris
            common_filter['user_id'] = uuid
863 c79faeb5 Stavros Sachtouris
        for term in ('status', 'gateway', 'gateway6', 'cidr', 'cidr6', 'type'):
864 c79faeb5 Stavros Sachtouris
            if self[term]:
865 c79faeb5 Stavros Sachtouris
                common_filter[term] = self[term]
866 c79faeb5 Stavros Sachtouris
        return filter_dicts_by_dict(networks, common_filter)
867 c79faeb5 Stavros Sachtouris
868 c79faeb5 Stavros Sachtouris
    def _add_name(self, networks, key='user_id'):
869 c79faeb5 Stavros Sachtouris
        uuids = self._uuids2usernames(
870 c79faeb5 Stavros Sachtouris
            list(set([net[key] for net in networks])))
871 c79faeb5 Stavros Sachtouris
        for net in networks:
872 c79faeb5 Stavros Sachtouris
            v = net.get(key, None)
873 c79faeb5 Stavros Sachtouris
            if v:
874 3185cd6d Stavros Sachtouris
                net[key] += ' (%s)' % uuids[v]
875 c79faeb5 Stavros Sachtouris
        return networks
876 c79faeb5 Stavros Sachtouris
877 5a673575 Stavros Sachtouris
    @errors.generic.all
878 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
879 5a673575 Stavros Sachtouris
    def _run(self):
880 c79faeb5 Stavros Sachtouris
        withcommons = False
881 c79faeb5 Stavros Sachtouris
        for term in (
882 c79faeb5 Stavros Sachtouris
                'status', 'public', 'private', 'user_id', 'user_name', 'type',
883 c79faeb5 Stavros Sachtouris
                'gateway', 'gateway6', 'cidr', 'cidr6', 'dhcp', 'no_dhcp'):
884 c79faeb5 Stavros Sachtouris
            if self[term]:
885 c79faeb5 Stavros Sachtouris
                withcommons = True
886 c79faeb5 Stavros Sachtouris
                break
887 c79faeb5 Stavros Sachtouris
        detail = self['detail'] or withcommons
888 c79faeb5 Stavros Sachtouris
        networks = self.client.list_networks(detail)
889 6d190dd1 Stavros Sachtouris
        networks = self._filter_by_name(networks)
890 6d190dd1 Stavros Sachtouris
        networks = self._filter_by_id(networks)
891 c79faeb5 Stavros Sachtouris
        if withcommons:
892 c79faeb5 Stavros Sachtouris
            networks = self._apply_common_filters(networks)
893 7ba195e5 Stavros Sachtouris
        if not (self['detail'] or self['json_output']):
894 7ba195e5 Stavros Sachtouris
            remove_from_items(networks, 'links')
895 c79faeb5 Stavros Sachtouris
        if detail and not self['detail']:
896 c79faeb5 Stavros Sachtouris
            for net in networks:
897 c79faeb5 Stavros Sachtouris
                for key in set(net).difference(self.PERMANENTS):
898 c79faeb5 Stavros Sachtouris
                    net.pop(key)
899 c79faeb5 Stavros Sachtouris
        if self['detail'] and not self['json_output']:
900 c79faeb5 Stavros Sachtouris
            self._add_name(networks)
901 c79faeb5 Stavros Sachtouris
            self._add_name(networks, 'tenant_id')
902 545c6c29 Stavros Sachtouris
        kwargs = dict(with_enumeration=self['enum'])
903 ddc0b290 Stavros Sachtouris
        if self['more']:
904 6430d3a0 Stavros Sachtouris
            kwargs['out'] = StringIO()
905 6430d3a0 Stavros Sachtouris
            kwargs['title'] = ()
906 6430d3a0 Stavros Sachtouris
        if self['limit']:
907 545c6c29 Stavros Sachtouris
            networks = networks[:self['limit']]
908 545c6c29 Stavros Sachtouris
        self._print(networks, **kwargs)
909 6430d3a0 Stavros Sachtouris
        if self['more']:
910 6430d3a0 Stavros Sachtouris
            pager(kwargs['out'].getvalue())
911 7493ccb6 Stavros Sachtouris
912 5a673575 Stavros Sachtouris
    def main(self):
913 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
914 5a673575 Stavros Sachtouris
        self._run()
915 5a673575 Stavros Sachtouris
916 234954d1 Stavros Sachtouris
917 d486baec Stavros Sachtouris
@command(network_cmds)
918 77df3d4a Stavros Sachtouris
class network_create(_init_cyclades, _optional_json, _network_wait):
919 0e806947 Stavros Sachtouris
    """Create an (unconnected) network"""
920 7493ccb6 Stavros Sachtouris
921 93914390 Stavros Sachtouris
    arguments = dict(
922 0e806947 Stavros Sachtouris
        cidr=ValueArgument('explicitly set cidr', '--with-cidr'),
923 0e806947 Stavros Sachtouris
        gateway=ValueArgument('explicitly set gateway', '--with-gateway'),
924 9d1db11e Stavros Sachtouris
        dhcp=FlagArgument('Use dhcp (default: off)', '--with-dhcp'),
925 f6f81cd3 Stavros Sachtouris
        type=ValueArgument(
926 f6f81cd3 Stavros Sachtouris
            'Valid network types are '
927 f6f81cd3 Stavros Sachtouris
            'CUSTOM, IP_LESS_ROUTED, MAC_FILTERED (default), PHYSICAL_VLAN',
928 f6f81cd3 Stavros Sachtouris
            '--with-type',
929 77df3d4a Stavros Sachtouris
            default='MAC_FILTERED'),
930 77df3d4a Stavros Sachtouris
        wait=FlagArgument('Wait network to build', ('-w', '--wait'))
931 93914390 Stavros Sachtouris
    )
932 7493ccb6 Stavros Sachtouris
933 5a673575 Stavros Sachtouris
    @errors.generic.all
934 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
935 5a673575 Stavros Sachtouris
    @errors.cyclades.network_max
936 5a673575 Stavros Sachtouris
    def _run(self, name):
937 77df3d4a Stavros Sachtouris
        r = self.client.create_network(
938 de73876b Stavros Sachtouris
            name,
939 5a673575 Stavros Sachtouris
            cidr=self['cidr'],
940 5a673575 Stavros Sachtouris
            gateway=self['gateway'],
941 5a673575 Stavros Sachtouris
            dhcp=self['dhcp'],
942 77df3d4a Stavros Sachtouris
            type=self['type'])
943 cf115aed Stavros Sachtouris
        _add_name(self, r)
944 76f58e2e Stavros Sachtouris
        self._print(r, self.print_dict)
945 77df3d4a Stavros Sachtouris
        if self['wait']:
946 77df3d4a Stavros Sachtouris
            self._wait(r['id'], 'PENDING')
947 5a673575 Stavros Sachtouris
948 7493ccb6 Stavros Sachtouris
    def main(self, name):
949 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
950 5a673575 Stavros Sachtouris
        self._run(name)
951 7493ccb6 Stavros Sachtouris
952 234954d1 Stavros Sachtouris
953 d486baec Stavros Sachtouris
@command(network_cmds)
954 1b73b4c1 Stavros Sachtouris
class network_rename(_init_cyclades, _optional_output_cmd):
955 0e806947 Stavros Sachtouris
    """Set the name of a network"""
956 7493ccb6 Stavros Sachtouris
957 5a673575 Stavros Sachtouris
    @errors.generic.all
958 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
959 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
960 5a673575 Stavros Sachtouris
    def _run(self, network_id, new_name):
961 1b73b4c1 Stavros Sachtouris
        self._optional_output(
962 1b73b4c1 Stavros Sachtouris
                self.client.update_network_name(int(network_id), new_name))
963 5a673575 Stavros Sachtouris
964 7493ccb6 Stavros Sachtouris
    def main(self, network_id, new_name):
965 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
966 5a673575 Stavros Sachtouris
        self._run(network_id=network_id, new_name=new_name)
967 7493ccb6 Stavros Sachtouris
968 234954d1 Stavros Sachtouris
969 d486baec Stavros Sachtouris
@command(network_cmds)
970 77df3d4a Stavros Sachtouris
class network_delete(_init_cyclades, _optional_output_cmd, _network_wait):
971 7493ccb6 Stavros Sachtouris
    """Delete a network"""
972 7493ccb6 Stavros Sachtouris
973 77df3d4a Stavros Sachtouris
    arguments = dict(
974 77df3d4a Stavros Sachtouris
        wait=FlagArgument('Wait network to build', ('-w', '--wait'))
975 77df3d4a Stavros Sachtouris
    )
976 77df3d4a Stavros Sachtouris
977 5a673575 Stavros Sachtouris
    @errors.generic.all
978 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
979 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
980 5a673575 Stavros Sachtouris
    @errors.cyclades.network_in_use
981 5a673575 Stavros Sachtouris
    def _run(self, network_id):
982 77df3d4a Stavros Sachtouris
        status = 'DELETED'
983 77df3d4a Stavros Sachtouris
        if self['wait']:
984 77df3d4a Stavros Sachtouris
            r = self.client.get_network_details(network_id)
985 77df3d4a Stavros Sachtouris
            status = r['status']
986 77df3d4a Stavros Sachtouris
            if status in ('DELETED', ):
987 77df3d4a Stavros Sachtouris
                return
988 77df3d4a Stavros Sachtouris
989 77df3d4a Stavros Sachtouris
        r = self.client.delete_network(int(network_id))
990 77df3d4a Stavros Sachtouris
        self._optional_output(r)
991 77df3d4a Stavros Sachtouris
992 77df3d4a Stavros Sachtouris
        if self['wait']:
993 77df3d4a Stavros Sachtouris
            self._wait(network_id, status)
994 5a673575 Stavros Sachtouris
995 7493ccb6 Stavros Sachtouris
    def main(self, network_id):
996 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
997 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
998 7493ccb6 Stavros Sachtouris
999 234954d1 Stavros Sachtouris
1000 d486baec Stavros Sachtouris
@command(network_cmds)
1001 1b73b4c1 Stavros Sachtouris
class network_connect(_init_cyclades, _optional_output_cmd):
1002 7493ccb6 Stavros Sachtouris
    """Connect a server to a network"""
1003 7493ccb6 Stavros Sachtouris
1004 5a673575 Stavros Sachtouris
    @errors.generic.all
1005 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
1006 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
1007 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
1008 5a673575 Stavros Sachtouris
    def _run(self, server_id, network_id):
1009 1b73b4c1 Stavros Sachtouris
        self._optional_output(
1010 1b73b4c1 Stavros Sachtouris
                self.client.connect_server(int(server_id), int(network_id)))
1011 5a673575 Stavros Sachtouris
1012 7493ccb6 Stavros Sachtouris
    def main(self, server_id, network_id):
1013 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
1014 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, network_id=network_id)
1015 7493ccb6 Stavros Sachtouris
1016 234954d1 Stavros Sachtouris
1017 d486baec Stavros Sachtouris
@command(network_cmds)
1018 7493ccb6 Stavros Sachtouris
class network_disconnect(_init_cyclades):
1019 0e806947 Stavros Sachtouris
    """Disconnect a nic that connects a server to a network
1020 0e806947 Stavros Sachtouris
    Nic ids are listed as "attachments" in detailed network information
1021 439826ec Stavros Sachtouris
    To get detailed network information: /network info <network id>
1022 0e806947 Stavros Sachtouris
    """
1023 7493ccb6 Stavros Sachtouris
1024 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_format
1025 5a673575 Stavros Sachtouris
    def _server_id_from_nic(self, nic_id):
1026 5a673575 Stavros Sachtouris
        return nic_id.split('-')[1]
1027 5a673575 Stavros Sachtouris
1028 5a673575 Stavros Sachtouris
    @errors.generic.all
1029 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
1030 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
1031 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_id
1032 5a673575 Stavros Sachtouris
    def _run(self, nic_id, server_id):
1033 1b73b4c1 Stavros Sachtouris
        num_of_disconnected = self.client.disconnect_server(server_id, nic_id)
1034 1b73b4c1 Stavros Sachtouris
        if not num_of_disconnected:
1035 5a673575 Stavros Sachtouris
            raise ClientError(
1036 5a673575 Stavros Sachtouris
                'Network Interface %s not found on server %s' % (
1037 3185cd6d Stavros Sachtouris
                    nic_id, server_id),
1038 5a673575 Stavros Sachtouris
                status=404)
1039 1b73b4c1 Stavros Sachtouris
        print('Disconnected %s connections' % num_of_disconnected)
1040 5a673575 Stavros Sachtouris
1041 7493ccb6 Stavros Sachtouris
    def main(self, nic_id):
1042 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
1043 5a673575 Stavros Sachtouris
        server_id = self._server_id_from_nic(nic_id=nic_id)
1044 5a673575 Stavros Sachtouris
        self._run(nic_id=nic_id, server_id=server_id)
1045 9b47150e Stavros Sachtouris
1046 9b47150e Stavros Sachtouris
1047 7b2e4bf1 Stavros Sachtouris
@command(network_cmds)
1048 7b2e4bf1 Stavros Sachtouris
class network_wait(_init_cyclades, _network_wait):
1049 7b2e4bf1 Stavros Sachtouris
    """Wait for server to finish [PENDING, ACTIVE, DELETED]"""
1050 7b2e4bf1 Stavros Sachtouris
1051 7b2e4bf1 Stavros Sachtouris
    @errors.generic.all
1052 7b2e4bf1 Stavros Sachtouris
    @errors.cyclades.connection
1053 7b2e4bf1 Stavros Sachtouris
    @errors.cyclades.network_id
1054 7b2e4bf1 Stavros Sachtouris
    def _run(self, network_id, currect_status):
1055 7b2e4bf1 Stavros Sachtouris
        self._wait(network_id, currect_status)
1056 7b2e4bf1 Stavros Sachtouris
1057 7b2e4bf1 Stavros Sachtouris
    def main(self, network_id, currect_status='PENDING'):
1058 7b2e4bf1 Stavros Sachtouris
        super(self.__class__, self)._run()
1059 7b2e4bf1 Stavros Sachtouris
        self._run(network_id=network_id, currect_status=currect_status)
1060 7b2e4bf1 Stavros Sachtouris
1061 7b2e4bf1 Stavros Sachtouris
1062 8be50626 Stavros Sachtouris
@command(server_cmds)
1063 8be50626 Stavros Sachtouris
class server_ip(_init_cyclades):
1064 8be50626 Stavros Sachtouris
    """Manage floating IPs for the servers"""
1065 8be50626 Stavros Sachtouris
1066 8be50626 Stavros Sachtouris
1067 8be50626 Stavros Sachtouris
@command(server_cmds)
1068 8be50626 Stavros Sachtouris
class server_ip_pools(_init_cyclades, _optional_json):
1069 9b47150e Stavros Sachtouris
    """List all floating pools of floating ips"""
1070 9b47150e Stavros Sachtouris
1071 9b47150e Stavros Sachtouris
    @errors.generic.all
1072 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1073 9b47150e Stavros Sachtouris
    def _run(self):
1074 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ip_pools()
1075 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ip_pools'])
1076 9b47150e Stavros Sachtouris
1077 9b47150e Stavros Sachtouris
    def main(self):
1078 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1079 9b47150e Stavros Sachtouris
        self._run()
1080 9b47150e Stavros Sachtouris
1081 9b47150e Stavros Sachtouris
1082 8be50626 Stavros Sachtouris
@command(server_cmds)
1083 8be50626 Stavros Sachtouris
class server_ip_list(_init_cyclades, _optional_json):
1084 9b47150e Stavros Sachtouris
    """List all floating ips"""
1085 9b47150e Stavros Sachtouris
1086 9b47150e Stavros Sachtouris
    @errors.generic.all
1087 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1088 9b47150e Stavros Sachtouris
    def _run(self):
1089 9b47150e Stavros Sachtouris
        r = self.client.get_floating_ips()
1090 9b47150e Stavros Sachtouris
        self._print(r if self['json_output'] else r['floating_ips'])
1091 9b47150e Stavros Sachtouris
1092 9b47150e Stavros Sachtouris
    def main(self):
1093 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1094 9b47150e Stavros Sachtouris
        self._run()
1095 9b47150e Stavros Sachtouris
1096 9b47150e Stavros Sachtouris
1097 8be50626 Stavros Sachtouris
@command(server_cmds)
1098 8be50626 Stavros Sachtouris
class server_ip_info(_init_cyclades, _optional_json):
1099 9b47150e Stavros Sachtouris
    """A floating IPs' details"""
1100 9b47150e Stavros Sachtouris
1101 9b47150e Stavros Sachtouris
    @errors.generic.all
1102 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1103 9b47150e Stavros Sachtouris
    def _run(self, ip):
1104 76f58e2e Stavros Sachtouris
        self._print(self.client.get_floating_ip(ip), self.print_dict)
1105 9b47150e Stavros Sachtouris
1106 9b47150e Stavros Sachtouris
    def main(self, ip):
1107 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1108 9b47150e Stavros Sachtouris
        self._run(ip=ip)
1109 9b47150e Stavros Sachtouris
1110 9b47150e Stavros Sachtouris
1111 8be50626 Stavros Sachtouris
@command(server_cmds)
1112 8be50626 Stavros Sachtouris
class server_ip_create(_init_cyclades, _optional_json):
1113 9b47150e Stavros Sachtouris
    """Create a new floating IP"""
1114 9b47150e Stavros Sachtouris
1115 3185cd6d Stavros Sachtouris
    arguments = dict(pool=ValueArgument('Source IP pool', ('--pool'), None))
1116 9b47150e Stavros Sachtouris
1117 9b47150e Stavros Sachtouris
    @errors.generic.all
1118 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1119 9b47150e Stavros Sachtouris
    def _run(self, ip=None):
1120 2e6e03da Stavros Sachtouris
        self._print([self.client.alloc_floating_ip(self['pool'], ip)])
1121 9b47150e Stavros Sachtouris
1122 9b47150e Stavros Sachtouris
    def main(self, requested_address=None):
1123 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1124 9b47150e Stavros Sachtouris
        self._run(ip=requested_address)
1125 9b47150e Stavros Sachtouris
1126 9b47150e Stavros Sachtouris
1127 8be50626 Stavros Sachtouris
@command(server_cmds)
1128 8be50626 Stavros Sachtouris
class server_ip_delete(_init_cyclades, _optional_output_cmd):
1129 9b47150e Stavros Sachtouris
    """Delete a floating ip"""
1130 9b47150e Stavros Sachtouris
1131 9b47150e Stavros Sachtouris
    @errors.generic.all
1132 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1133 9b47150e Stavros Sachtouris
    def _run(self, ip):
1134 9b47150e Stavros Sachtouris
        self._optional_output(self.client.delete_floating_ip(ip))
1135 9b47150e Stavros Sachtouris
1136 9b47150e Stavros Sachtouris
    def main(self, ip):
1137 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1138 9b47150e Stavros Sachtouris
        self._run(ip=ip)
1139 9b47150e Stavros Sachtouris
1140 9b47150e Stavros Sachtouris
1141 9b47150e Stavros Sachtouris
@command(server_cmds)
1142 9b47150e Stavros Sachtouris
class server_ip_attach(_init_cyclades, _optional_output_cmd):
1143 9b47150e Stavros Sachtouris
    """Attach a floating ip to a server with server_id
1144 9b47150e Stavros Sachtouris
    """
1145 9b47150e Stavros Sachtouris
1146 9b47150e Stavros Sachtouris
    @errors.generic.all
1147 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1148 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
1149 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
1150 9b47150e Stavros Sachtouris
        self._optional_output(self.client.attach_floating_ip(server_id, ip))
1151 9b47150e Stavros Sachtouris
1152 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
1153 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1154 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)
1155 9b47150e Stavros Sachtouris
1156 9b47150e Stavros Sachtouris
1157 9b47150e Stavros Sachtouris
@command(server_cmds)
1158 2e6e03da Stavros Sachtouris
class server_ip_detach(_init_cyclades, _optional_output_cmd):
1159 8be50626 Stavros Sachtouris
    """Detach floating IP from server
1160 9b47150e Stavros Sachtouris
    """
1161 9b47150e Stavros Sachtouris
1162 9b47150e Stavros Sachtouris
    @errors.generic.all
1163 9b47150e Stavros Sachtouris
    @errors.cyclades.connection
1164 9b47150e Stavros Sachtouris
    @errors.cyclades.server_id
1165 9b47150e Stavros Sachtouris
    def _run(self, server_id, ip):
1166 9b47150e Stavros Sachtouris
        self._optional_output(self.client.detach_floating_ip(server_id, ip))
1167 9b47150e Stavros Sachtouris
1168 9b47150e Stavros Sachtouris
    def main(self, server_id, ip):
1169 9b47150e Stavros Sachtouris
        super(self.__class__, self)._run()
1170 9b47150e Stavros Sachtouris
        self._run(server_id=server_id, ip=ip)