Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / cyclades_cli.py @ c314fc10

History | View | Annotate | Download (21.6 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 83c3ba87 Stavros Sachtouris
from kamaki.cli.utils import print_dict, print_list, print_items
37 43ee6ae1 Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError, CLISyntaxError
38 7493ccb6 Stavros Sachtouris
from kamaki.clients.cyclades import CycladesClient, ClientError
39 57d622b6 Stavros Sachtouris
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
40 bd40efdf Stavros Sachtouris
from kamaki.cli.argument import ProgressBarArgument, DateArgument, IntArgument
41 b04288f7 Stavros Sachtouris
from kamaki.cli.commands import _command_init, errors
42 5eae854d Stavros Sachtouris
43 f3e94e06 Stavros Sachtouris
from base64 import b64encode
44 234954d1 Stavros Sachtouris
from os.path import exists
45 234954d1 Stavros Sachtouris
46 234954d1 Stavros Sachtouris
47 d486baec Stavros Sachtouris
server_cmds = CommandTree('server',
48 d486baec Stavros Sachtouris
    'Compute/Cyclades API server commands')
49 d486baec Stavros Sachtouris
flavor_cmds = CommandTree('flavor',
50 d486baec Stavros Sachtouris
    'Compute/Cyclades API flavor commands')
51 d486baec Stavros Sachtouris
image_cmds = CommandTree('image',
52 d486baec Stavros Sachtouris
    'Compute/Cyclades or Glance API image commands')
53 d486baec Stavros Sachtouris
network_cmds = CommandTree('network',
54 d486baec Stavros Sachtouris
    'Compute/Cyclades API network commands')
55 d486baec Stavros Sachtouris
_commands = [server_cmds, flavor_cmds, image_cmds, network_cmds]
56 234954d1 Stavros Sachtouris
57 7493ccb6 Stavros Sachtouris
58 c314fc10 Stavros Sachtouris
about_authentication = '\nUser Authentication:\
59 b04288f7 Stavros Sachtouris
    \n* to check authentication: /astakos authenticate\
60 b04288f7 Stavros Sachtouris
    \n* to set authentication token: /config set token <token>'
61 18edacfe Stavros Sachtouris
62 d7259dd5 Stavros Sachtouris
howto_personality = [
63 d7259dd5 Stavros Sachtouris
    'Defines a file to be injected to VMs personality.',
64 8194b51b Stavros Sachtouris
    'Personality value syntax: PATH,[SERVER_PATH,[OWNER,[GROUP,[MODE]]]]',
65 d7259dd5 Stavros Sachtouris
    '  PATH: of local file to be injected',
66 d7259dd5 Stavros Sachtouris
    '  SERVER_PATH: destination location inside server Image',
67 d7259dd5 Stavros Sachtouris
    '  OWNER: user id of destination file owner',
68 d7259dd5 Stavros Sachtouris
    '  GROUP: group id or name to own destination file',
69 d7259dd5 Stavros Sachtouris
    '  MODEL: permition in octal (e.g. 0777 or o+rwx)']
70 d7259dd5 Stavros Sachtouris
71 18edacfe Stavros Sachtouris
72 5eae854d Stavros Sachtouris
class _init_cyclades(_command_init):
73 b04288f7 Stavros Sachtouris
    @errors.generic.all
74 236e7d08 Stavros Sachtouris
    def _run(self, service='compute'):
75 234954d1 Stavros Sachtouris
        token = self.config.get(service, 'token')\
76 234954d1 Stavros Sachtouris
            or self.config.get('global', 'token')
77 234954d1 Stavros Sachtouris
        base_url = self.config.get(service, 'url')\
78 234954d1 Stavros Sachtouris
            or self.config.get('global', 'url')
79 7493ccb6 Stavros Sachtouris
        self.client = CycladesClient(base_url=base_url, token=token)
80 7493ccb6 Stavros Sachtouris
81 b04288f7 Stavros Sachtouris
    def main(self):
82 b04288f7 Stavros Sachtouris
        self._run()
83 236e7d08 Stavros Sachtouris
84 234954d1 Stavros Sachtouris
85 d486baec Stavros Sachtouris
@command(server_cmds)
86 7493ccb6 Stavros Sachtouris
class server_list(_init_cyclades):
87 c314fc10 Stavros Sachtouris
    """List Virtual Machines accessible by user"""
88 18edacfe Stavros Sachtouris
89 18edacfe Stavros Sachtouris
    __doc__ += about_authentication
90 7493ccb6 Stavros Sachtouris
91 e15d78e2 Stavros Sachtouris
    arguments = dict(
92 a382ea56 Stavros Sachtouris
        detail=FlagArgument('show detailed output', '-l'),
93 67469d65 Stavros Sachtouris
        since=DateArgument(
94 a382ea56 Stavros Sachtouris
            'show only items since date (\' d/m/Y H:M:S \')',
95 a4d0d88a Stavros Sachtouris
            '--since'),
96 a4d0d88a Stavros Sachtouris
        limit=IntArgument('limit the number of VMs to list', '-n'),
97 a4d0d88a Stavros Sachtouris
        more=FlagArgument(
98 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
99 a4d0d88a Stavros Sachtouris
            '--more')
100 e15d78e2 Stavros Sachtouris
    )
101 e15d78e2 Stavros Sachtouris
102 a4d0d88a Stavros Sachtouris
    def _make_results_pretty(self, servers):
103 7493ccb6 Stavros Sachtouris
        for server in servers:
104 a4d0d88a Stavros Sachtouris
            addr_dict = {}
105 a4d0d88a Stavros Sachtouris
            if 'attachments' in server:
106 a4d0d88a Stavros Sachtouris
                for addr in server['attachments']['values']:
107 a4d0d88a Stavros Sachtouris
                    ips = addr.pop('values', [])
108 a4d0d88a Stavros Sachtouris
                    for ip in ips:
109 a4d0d88a Stavros Sachtouris
                        addr['IPv%s' % ip['version']] = ip['addr']
110 a4d0d88a Stavros Sachtouris
                    if 'firewallProfile' in addr:
111 a4d0d88a Stavros Sachtouris
                        addr['firewall'] = addr.pop('firewallProfile')
112 a4d0d88a Stavros Sachtouris
                    addr_dict[addr.pop('id')] = addr
113 a4d0d88a Stavros Sachtouris
                server['attachments'] = addr_dict if addr_dict else None
114 a4d0d88a Stavros Sachtouris
            if 'metadata' in server:
115 a4d0d88a Stavros Sachtouris
                server['metadata'] = server['metadata']['values']
116 7493ccb6 Stavros Sachtouris
117 b04288f7 Stavros Sachtouris
    @errors.generic.all
118 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
119 b04288f7 Stavros Sachtouris
    @errors.cyclades.date
120 b04288f7 Stavros Sachtouris
    def _run(self):
121 b04288f7 Stavros Sachtouris
        servers = self.client.list_servers(self['detail'], self['since'])
122 b04288f7 Stavros Sachtouris
        if self['detail']:
123 b04288f7 Stavros Sachtouris
            self._make_results_pretty(servers)
124 b04288f7 Stavros Sachtouris
125 a4d0d88a Stavros Sachtouris
        if self['more']:
126 a4d0d88a Stavros Sachtouris
            print_items(
127 a4d0d88a Stavros Sachtouris
                servers,
128 a4d0d88a Stavros Sachtouris
                page_size=self['limit'] if self['limit'] else 10)
129 a4d0d88a Stavros Sachtouris
        else:
130 a4d0d88a Stavros Sachtouris
            print_items(
131 a4d0d88a Stavros Sachtouris
                servers[:self['limit'] if self['limit'] else len(servers)])
132 7493ccb6 Stavros Sachtouris
133 b04288f7 Stavros Sachtouris
    def main(self):
134 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
135 b04288f7 Stavros Sachtouris
        self._run()
136 b04288f7 Stavros Sachtouris
137 234954d1 Stavros Sachtouris
138 d486baec Stavros Sachtouris
@command(server_cmds)
139 7493ccb6 Stavros Sachtouris
class server_info(_init_cyclades):
140 67469d65 Stavros Sachtouris
    """Detailed information on a Virtual Machine
141 67469d65 Stavros Sachtouris
    Contains:
142 67469d65 Stavros Sachtouris
    - name, id, status, create/update dates
143 67469d65 Stavros Sachtouris
    - network interfaces
144 67469d65 Stavros Sachtouris
    - metadata (e.g. os, superuser) and diagnostics
145 67469d65 Stavros Sachtouris
    - hardware flavor and os image ids
146 67469d65 Stavros Sachtouris
    """
147 7493ccb6 Stavros Sachtouris
148 234954d1 Stavros Sachtouris
    def _print(self, server):
149 7493ccb6 Stavros Sachtouris
        addr_dict = {}
150 234954d1 Stavros Sachtouris
        if 'attachments' in server:
151 75c3fc42 Stavros Sachtouris
            atts = server.pop('attachments')
152 75c3fc42 Stavros Sachtouris
            for addr in atts['values']:
153 7493ccb6 Stavros Sachtouris
                ips = addr.pop('values', [])
154 7493ccb6 Stavros Sachtouris
                for ip in ips:
155 234954d1 Stavros Sachtouris
                    addr['IPv%s' % ip['version']] = ip['addr']
156 234954d1 Stavros Sachtouris
                if 'firewallProfile' in addr:
157 7493ccb6 Stavros Sachtouris
                    addr['firewall'] = addr.pop('firewallProfile')
158 7493ccb6 Stavros Sachtouris
                addr_dict[addr.pop('id')] = addr
159 75c3fc42 Stavros Sachtouris
            server['attachments'] = addr_dict if addr_dict else None
160 234954d1 Stavros Sachtouris
        if 'metadata' in server:
161 7493ccb6 Stavros Sachtouris
            server['metadata'] = server['metadata']['values']
162 08c63ef5 Stavros Sachtouris
        print_dict(server, ident=1)
163 7493ccb6 Stavros Sachtouris
164 b04288f7 Stavros Sachtouris
    @errors.generic.all
165 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
166 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
167 b04288f7 Stavros Sachtouris
    def _run(self, server_id):
168 b04288f7 Stavros Sachtouris
        server = self.client.get_server_details(server_id)
169 7493ccb6 Stavros Sachtouris
        self._print(server)
170 7493ccb6 Stavros Sachtouris
171 b04288f7 Stavros Sachtouris
    def main(self, server_id):
172 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
173 b04288f7 Stavros Sachtouris
        self._run(server_id=server_id)
174 b04288f7 Stavros Sachtouris
175 234954d1 Stavros Sachtouris
176 57d622b6 Stavros Sachtouris
class PersonalityArgument(KeyValueArgument):
177 234954d1 Stavros Sachtouris
    @property
178 f3e94e06 Stavros Sachtouris
    def value(self):
179 57d622b6 Stavros Sachtouris
        return self._value if hasattr(self, '_value') else []
180 234954d1 Stavros Sachtouris
181 234954d1 Stavros Sachtouris
    @value.setter
182 f3e94e06 Stavros Sachtouris
    def value(self, newvalue):
183 f3e94e06 Stavros Sachtouris
        if newvalue == self.default:
184 f3e94e06 Stavros Sachtouris
            return self.value
185 57d622b6 Stavros Sachtouris
        self._value = []
186 57d622b6 Stavros Sachtouris
        for i, terms in enumerate(newvalue):
187 57d622b6 Stavros Sachtouris
            termlist = terms.split(',')
188 57d622b6 Stavros Sachtouris
            if len(termlist) > 5:
189 d7259dd5 Stavros Sachtouris
                raiseCLIError(
190 d7259dd5 Stavros Sachtouris
                CLISyntaxError('Wrong number of terms (should be 1 to 5)'),
191 d7259dd5 Stavros Sachtouris
                details=howto_personality)
192 57d622b6 Stavros Sachtouris
            path = termlist[0]
193 57d622b6 Stavros Sachtouris
            if not exists(path):
194 8194b51b Stavros Sachtouris
                raiseCLIError(None,
195 8194b51b Stavros Sachtouris
                    '--personality: File %s does not exist' % path,
196 8194b51b Stavros Sachtouris
                    importance=1,
197 8194b51b Stavros Sachtouris
                    details=howto_personality)
198 57d622b6 Stavros Sachtouris
            self._value.append(dict(path=path))
199 57d622b6 Stavros Sachtouris
            with open(path) as f:
200 57d622b6 Stavros Sachtouris
                self._value[i]['contents'] = b64encode(f.read())
201 57d622b6 Stavros Sachtouris
            try:
202 57d622b6 Stavros Sachtouris
                self._value[i]['path'] = termlist[1]
203 57d622b6 Stavros Sachtouris
                self._value[i]['owner'] = termlist[2]
204 57d622b6 Stavros Sachtouris
                self._value[i]['group'] = termlist[3]
205 57d622b6 Stavros Sachtouris
                self._value[i]['mode'] = termlist[4]
206 57d622b6 Stavros Sachtouris
            except IndexError:
207 57d622b6 Stavros Sachtouris
                pass
208 f3e94e06 Stavros Sachtouris
209 234954d1 Stavros Sachtouris
210 d486baec Stavros Sachtouris
@command(server_cmds)
211 7493ccb6 Stavros Sachtouris
class server_create(_init_cyclades):
212 8194b51b Stavros Sachtouris
    """Create a server (aka Virtual Machine)
213 8194b51b Stavros Sachtouris
    Parameters:
214 439826ec Stavros Sachtouris
    - name: (single quoted text)
215 439826ec Stavros Sachtouris
    - flavor id: Hardware flavor. Pick one from: /flavor list
216 439826ec Stavros Sachtouris
    - image id: OS images. Pick one from: /image list
217 8194b51b Stavros Sachtouris
    """
218 7493ccb6 Stavros Sachtouris
219 93914390 Stavros Sachtouris
    arguments = dict(
220 93914390 Stavros Sachtouris
        personality=PersonalityArgument(
221 b04288f7 Stavros Sachtouris
            ' /// '.join(howto_personality),
222 b04288f7 Stavros Sachtouris
            '--personality')
223 93914390 Stavros Sachtouris
    )
224 f3e94e06 Stavros Sachtouris
225 b04288f7 Stavros Sachtouris
    @errors.generic.all
226 b04288f7 Stavros Sachtouris
    @errors.cyclades.connection
227 b04288f7 Stavros Sachtouris
    @errors.plankton.id
228 b04288f7 Stavros Sachtouris
    @errors.cyclades.flavor_id
229 b04288f7 Stavros Sachtouris
    def _run(self, name, flavor_id, image_id):
230 b04288f7 Stavros Sachtouris
        r = self.client.create_server(
231 b04288f7 Stavros Sachtouris
            name,
232 b04288f7 Stavros Sachtouris
            int(flavor_id),
233 b04288f7 Stavros Sachtouris
            image_id,
234 b04288f7 Stavros Sachtouris
            self['personality'])
235 b04288f7 Stavros Sachtouris
        print_dict(r)
236 b04288f7 Stavros Sachtouris
237 7493ccb6 Stavros Sachtouris
    def main(self, name, flavor_id, image_id):
238 b04288f7 Stavros Sachtouris
        super(self.__class__, self)._run()
239 b04288f7 Stavros Sachtouris
        self._run(name=name, flavor_id=flavor_id, image_id=image_id)
240 7493ccb6 Stavros Sachtouris
241 234954d1 Stavros Sachtouris
242 d486baec Stavros Sachtouris
@command(server_cmds)
243 7493ccb6 Stavros Sachtouris
class server_rename(_init_cyclades):
244 22b6f063 Stavros Sachtouris
    """Set/update a server (VM) name
245 5a673575 Stavros Sachtouris
    VM names are not unique, therefore multiple servers may share the same name
246 22b6f063 Stavros Sachtouris
    """
247 7493ccb6 Stavros Sachtouris
248 5a673575 Stavros Sachtouris
    @errors.generic.all
249 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
250 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
251 5a673575 Stavros Sachtouris
    def _run(self, server_id, new_name):
252 5a673575 Stavros Sachtouris
        self.client.update_server_name(int(server_id), new_name)
253 5a673575 Stavros Sachtouris
254 7493ccb6 Stavros Sachtouris
    def main(self, server_id, new_name):
255 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
256 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, new_name=new_name)
257 234954d1 Stavros Sachtouris
258 7493ccb6 Stavros Sachtouris
259 d486baec Stavros Sachtouris
@command(server_cmds)
260 7493ccb6 Stavros Sachtouris
class server_delete(_init_cyclades):
261 22b6f063 Stavros Sachtouris
    """Delete a server (VM)"""
262 7493ccb6 Stavros Sachtouris
263 5a673575 Stavros Sachtouris
    @errors.generic.all
264 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
265 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
266 5a673575 Stavros Sachtouris
    def _run(self, server_id):
267 7493ccb6 Stavros Sachtouris
            self.client.delete_server(int(server_id))
268 5a673575 Stavros Sachtouris
269 5a673575 Stavros Sachtouris
    def main(self, server_id):
270 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
271 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
272 234954d1 Stavros Sachtouris
273 7493ccb6 Stavros Sachtouris
274 d486baec Stavros Sachtouris
@command(server_cmds)
275 7493ccb6 Stavros Sachtouris
class server_reboot(_init_cyclades):
276 22b6f063 Stavros Sachtouris
    """Reboot a server (VM)"""
277 18edacfe Stavros Sachtouris
278 93914390 Stavros Sachtouris
    arguments = dict(
279 93914390 Stavros Sachtouris
        hard=FlagArgument('perform a hard reboot', '-f')
280 93914390 Stavros Sachtouris
    )
281 7493ccb6 Stavros Sachtouris
282 5a673575 Stavros Sachtouris
    @errors.generic.all
283 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
284 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
285 5a673575 Stavros Sachtouris
    def _run(self, server_id):
286 5a673575 Stavros Sachtouris
        self.client.reboot_server(int(server_id), self['hard'])
287 5a673575 Stavros Sachtouris
288 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
289 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
290 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
291 234954d1 Stavros Sachtouris
292 7493ccb6 Stavros Sachtouris
293 d486baec Stavros Sachtouris
@command(server_cmds)
294 7493ccb6 Stavros Sachtouris
class server_start(_init_cyclades):
295 22b6f063 Stavros Sachtouris
    """Start an existing server (VM)"""
296 7493ccb6 Stavros Sachtouris
297 5a673575 Stavros Sachtouris
    @errors.generic.all
298 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
299 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
300 5a673575 Stavros Sachtouris
    def _run(self, server_id):
301 5a673575 Stavros Sachtouris
        self.client.start_server(int(server_id))
302 5a673575 Stavros Sachtouris
303 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
304 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
305 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
306 234954d1 Stavros Sachtouris
307 7493ccb6 Stavros Sachtouris
308 d486baec Stavros Sachtouris
@command(server_cmds)
309 7493ccb6 Stavros Sachtouris
class server_shutdown(_init_cyclades):
310 22b6f063 Stavros Sachtouris
    """Shutdown an active server (VM)"""
311 7493ccb6 Stavros Sachtouris
312 5a673575 Stavros Sachtouris
    @errors.generic.all
313 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
314 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
315 5a673575 Stavros Sachtouris
    def _run(self, server_id):
316 5a673575 Stavros Sachtouris
        self.client.shutdown_server(int(server_id))
317 5a673575 Stavros Sachtouris
318 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
319 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
320 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
321 234954d1 Stavros Sachtouris
322 7493ccb6 Stavros Sachtouris
323 d486baec Stavros Sachtouris
@command(server_cmds)
324 7493ccb6 Stavros Sachtouris
class server_console(_init_cyclades):
325 22b6f063 Stavros Sachtouris
    """Get a VNC console to access an existing server (VM)
326 22b6f063 Stavros Sachtouris
    Console connection information provided (at least):
327 439826ec Stavros Sachtouris
    - host: (url or address) a VNC host
328 439826ec Stavros Sachtouris
    - port: (int) the gateway to enter VM on host
329 439826ec Stavros Sachtouris
    - password: for VNC authorization
330 22b6f063 Stavros Sachtouris
    """
331 7493ccb6 Stavros Sachtouris
332 5a673575 Stavros Sachtouris
    @errors.generic.all
333 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
334 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
335 5a673575 Stavros Sachtouris
    def _run(self, server_id):
336 5a673575 Stavros Sachtouris
        r = self.client.get_server_console(int(server_id))
337 5a673575 Stavros Sachtouris
        print_dict(r)
338 5a673575 Stavros Sachtouris
339 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
340 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
341 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
342 7493ccb6 Stavros Sachtouris
343 234954d1 Stavros Sachtouris
344 d486baec Stavros Sachtouris
@command(server_cmds)
345 7493ccb6 Stavros Sachtouris
class server_firewall(_init_cyclades):
346 22b6f063 Stavros Sachtouris
    """Set the server (VM) firewall profile on VMs public network
347 22b6f063 Stavros Sachtouris
    Values for profile:
348 439826ec Stavros Sachtouris
    - DISABLED: Shutdown firewall
349 439826ec Stavros Sachtouris
    - ENABLED: Firewall in normal mode
350 439826ec Stavros Sachtouris
    - PROTECTED: Firewall in secure mode
351 22b6f063 Stavros Sachtouris
    """
352 7493ccb6 Stavros Sachtouris
353 5a673575 Stavros Sachtouris
    @errors.generic.all
354 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
355 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
356 5a673575 Stavros Sachtouris
    @errors.cyclades.firewall
357 5a673575 Stavros Sachtouris
    def _run(self, server_id, profile):
358 5a673575 Stavros Sachtouris
        self.client.set_firewall_profile(
359 5a673575 Stavros Sachtouris
            server_id=int(server_id),
360 5a673575 Stavros Sachtouris
            profile=unicode(profile).upper())
361 5a673575 Stavros Sachtouris
362 7493ccb6 Stavros Sachtouris
    def main(self, server_id, profile):
363 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
364 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, profile=profile)
365 234954d1 Stavros Sachtouris
366 f3e94e06 Stavros Sachtouris
367 d486baec Stavros Sachtouris
@command(server_cmds)
368 7493ccb6 Stavros Sachtouris
class server_addr(_init_cyclades):
369 22b6f063 Stavros Sachtouris
    """List the addresses of all network interfaces on a server (VM)"""
370 7493ccb6 Stavros Sachtouris
371 5a673575 Stavros Sachtouris
    @errors.generic.all
372 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
373 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
374 5a673575 Stavros Sachtouris
    def _run(self, server_id):
375 5a673575 Stavros Sachtouris
        reply = self.client.list_server_nics(int(server_id))
376 c17b8bc0 Stavros Sachtouris
        print_list(reply, with_enumeration=len(reply) > 1)
377 7493ccb6 Stavros Sachtouris
378 5a673575 Stavros Sachtouris
    def main(self, server_id):
379 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
380 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
381 5a673575 Stavros Sachtouris
382 234954d1 Stavros Sachtouris
383 d486baec Stavros Sachtouris
@command(server_cmds)
384 7493ccb6 Stavros Sachtouris
class server_meta(_init_cyclades):
385 22b6f063 Stavros Sachtouris
    """Get a server's metadatum
386 22b6f063 Stavros Sachtouris
    Metadata are formed as key:value pairs where key is used to retrieve them
387 22b6f063 Stavros Sachtouris
    """
388 7493ccb6 Stavros Sachtouris
389 5a673575 Stavros Sachtouris
    @errors.generic.all
390 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
391 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
392 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
393 5a673575 Stavros Sachtouris
    def _run(self, server_id, key=''):
394 5a673575 Stavros Sachtouris
        r = self.client.get_server_metadata(int(server_id), key)
395 5a673575 Stavros Sachtouris
        print_dict(r)
396 5a673575 Stavros Sachtouris
397 a34888b4 Stavros Sachtouris
    def main(self, server_id, key=''):
398 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
399 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
400 7493ccb6 Stavros Sachtouris
401 234954d1 Stavros Sachtouris
402 d486baec Stavros Sachtouris
@command(server_cmds)
403 7493ccb6 Stavros Sachtouris
class server_setmeta(_init_cyclades):
404 22b6f063 Stavros Sachtouris
    """set server (VM) metadata
405 22b6f063 Stavros Sachtouris
    Metadata are formed as key:value pairs, both needed to set one
406 22b6f063 Stavros Sachtouris
    """
407 7493ccb6 Stavros Sachtouris
408 5a673575 Stavros Sachtouris
    @errors.generic.all
409 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
410 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
411 5a673575 Stavros Sachtouris
    def _run(self, server_id, key, val):
412 7493ccb6 Stavros Sachtouris
        metadata = {key: val}
413 5a673575 Stavros Sachtouris
        r = self.client.update_server_metadata(int(server_id), **metadata)
414 5a673575 Stavros Sachtouris
        print_dict(r)
415 5a673575 Stavros Sachtouris
416 5a673575 Stavros Sachtouris
    def main(self, server_id, key, val):
417 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
418 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key, val=val)
419 7493ccb6 Stavros Sachtouris
420 234954d1 Stavros Sachtouris
421 d486baec Stavros Sachtouris
@command(server_cmds)
422 7493ccb6 Stavros Sachtouris
class server_delmeta(_init_cyclades):
423 22b6f063 Stavros Sachtouris
    """Delete server (VM) metadata"""
424 7493ccb6 Stavros Sachtouris
425 5a673575 Stavros Sachtouris
    @errors.generic.all
426 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
427 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
428 5a673575 Stavros Sachtouris
    @errors.cyclades.metadata
429 5a673575 Stavros Sachtouris
    def _run(self, server_id, key):
430 5a673575 Stavros Sachtouris
        self.client.delete_server_metadata(int(server_id), key)
431 5a673575 Stavros Sachtouris
432 7493ccb6 Stavros Sachtouris
    def main(self, server_id, key):
433 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
434 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, key=key)
435 234954d1 Stavros Sachtouris
436 7493ccb6 Stavros Sachtouris
437 d486baec Stavros Sachtouris
@command(server_cmds)
438 7493ccb6 Stavros Sachtouris
class server_stats(_init_cyclades):
439 22b6f063 Stavros Sachtouris
    """Get server (VM) statistics"""
440 7493ccb6 Stavros Sachtouris
441 5a673575 Stavros Sachtouris
    @errors.generic.all
442 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
443 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
444 5a673575 Stavros Sachtouris
    def _run(self, server_id):
445 5a673575 Stavros Sachtouris
        r = self.client.get_server_stats(int(server_id))
446 5a673575 Stavros Sachtouris
        print_dict(r, exclude=('serverRef',))
447 5a673575 Stavros Sachtouris
448 7493ccb6 Stavros Sachtouris
    def main(self, server_id):
449 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
450 5a673575 Stavros Sachtouris
        self._run(server_id=server_id)
451 7493ccb6 Stavros Sachtouris
452 234954d1 Stavros Sachtouris
453 d486baec Stavros Sachtouris
@command(server_cmds)
454 fd1f1d96 Stavros Sachtouris
class server_wait(_init_cyclades):
455 fd1f1d96 Stavros Sachtouris
    """Wait for server to finish [BUILD, STOPPED, REBOOT, ACTIVE]"""
456 fd1f1d96 Stavros Sachtouris
457 93914390 Stavros Sachtouris
    arguments = dict(
458 93914390 Stavros Sachtouris
        progress_bar=ProgressBarArgument(
459 93914390 Stavros Sachtouris
            'do not show progress bar',
460 93914390 Stavros Sachtouris
            '--no-progress-bar',
461 93914390 Stavros Sachtouris
            False
462 93914390 Stavros Sachtouris
        )
463 93914390 Stavros Sachtouris
    )
464 fd1f1d96 Stavros Sachtouris
465 5a673575 Stavros Sachtouris
    @errors.generic.all
466 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
467 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
468 5a673575 Stavros Sachtouris
    def _run(self, server_id, currect_status):
469 5a673575 Stavros Sachtouris
        (progress_bar, wait_cb) = self._safe_progress_bar(
470 5a673575 Stavros Sachtouris
            'Server %s still in %s mode' % (server_id, currect_status))
471 5a673575 Stavros Sachtouris
472 6cdfdcf3 Stavros Sachtouris
        try:
473 5a673575 Stavros Sachtouris
            new_mode = self.client.wait_server(
474 5a673575 Stavros Sachtouris
                server_id,
475 6cdfdcf3 Stavros Sachtouris
                currect_status,
476 6cdfdcf3 Stavros Sachtouris
                wait_cb=wait_cb)
477 5a673575 Stavros Sachtouris
        except Exception:
478 5a673575 Stavros Sachtouris
            self._safe_progress_bar_finish(progress_bar)
479 5a673575 Stavros Sachtouris
            raise
480 5a673575 Stavros Sachtouris
        finally:
481 5a673575 Stavros Sachtouris
            self._safe_progress_bar_finish(progress_bar)
482 fd1f1d96 Stavros Sachtouris
        if new_mode:
483 a10f5561 Stavros Sachtouris
            print('Server %s is now in %s mode' % (server_id, new_mode))
484 fd1f1d96 Stavros Sachtouris
        else:
485 43ee6ae1 Stavros Sachtouris
            raiseCLIError(None, 'Time out')
486 fd1f1d96 Stavros Sachtouris
487 5a673575 Stavros Sachtouris
    def main(self, server_id, currect_status='BUILD'):
488 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
489 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, currect_status=currect_status)
490 5a673575 Stavros Sachtouris
491 fd1f1d96 Stavros Sachtouris
492 d486baec Stavros Sachtouris
@command(flavor_cmds)
493 7493ccb6 Stavros Sachtouris
class flavor_list(_init_cyclades):
494 bd40efdf Stavros Sachtouris
    """List available hardware flavors"""
495 7493ccb6 Stavros Sachtouris
496 93914390 Stavros Sachtouris
    arguments = dict(
497 bd40efdf Stavros Sachtouris
        detail=FlagArgument('show detailed output', '-l'),
498 bd40efdf Stavros Sachtouris
        limit=IntArgument('limit the number of flavors to list', '-n'),
499 bd40efdf Stavros Sachtouris
        more=FlagArgument(
500 ddc0b290 Stavros Sachtouris
        'output results in pages (-n to set items per page, default 10)',
501 ddc0b290 Stavros Sachtouris
        '--more')
502 93914390 Stavros Sachtouris
    )
503 7493ccb6 Stavros Sachtouris
504 5a673575 Stavros Sachtouris
    @errors.generic.all
505 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
506 5a673575 Stavros Sachtouris
    def _run(self):
507 5a673575 Stavros Sachtouris
        flavors = self.client.list_flavors(self['detail'])
508 5a673575 Stavros Sachtouris
        pg_size = 10 if self['more'] and not self['limit'] else self['limit']
509 5a673575 Stavros Sachtouris
        print_items(flavors, with_redundancy=self['detail'], page_size=pg_size)
510 5a673575 Stavros Sachtouris
511 7493ccb6 Stavros Sachtouris
    def main(self):
512 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
513 5a673575 Stavros Sachtouris
        self._run()
514 7493ccb6 Stavros Sachtouris
515 234954d1 Stavros Sachtouris
516 d486baec Stavros Sachtouris
@command(flavor_cmds)
517 7493ccb6 Stavros Sachtouris
class flavor_info(_init_cyclades):
518 769dbf53 Stavros Sachtouris
    """Detailed information on a hardware flavor
519 ddc0b290 Stavros Sachtouris
    To get a list of available flavors and flavor ids, try /flavor list
520 ddc0b290 Stavros Sachtouris
    """
521 7493ccb6 Stavros Sachtouris
522 5a673575 Stavros Sachtouris
    @errors.generic.all
523 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
524 5a673575 Stavros Sachtouris
    @errors.cyclades.flavor_id
525 5a673575 Stavros Sachtouris
    def _run(self, flavor_id):
526 5a673575 Stavros Sachtouris
        flavor = self.client.get_flavor_details(int(flavor_id))
527 7493ccb6 Stavros Sachtouris
        print_dict(flavor)
528 7493ccb6 Stavros Sachtouris
529 5a673575 Stavros Sachtouris
    def main(self, flavor_id):
530 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
531 5a673575 Stavros Sachtouris
        self._run(flavor_id=flavor_id)
532 5a673575 Stavros Sachtouris
533 234954d1 Stavros Sachtouris
534 d486baec Stavros Sachtouris
@command(network_cmds)
535 c17b8bc0 Stavros Sachtouris
class network_info(_init_cyclades):
536 ddc0b290 Stavros Sachtouris
    """Detailed information on a network
537 ddc0b290 Stavros Sachtouris
    To get a list of available networks and network ids, try /network list
538 ddc0b290 Stavros Sachtouris
    """
539 c17b8bc0 Stavros Sachtouris
540 c17b8bc0 Stavros Sachtouris
    @classmethod
541 ddc0b290 Stavros Sachtouris
    def _make_result_pretty(self, net):
542 c17b8bc0 Stavros Sachtouris
        if 'attachments' in net:
543 c17b8bc0 Stavros Sachtouris
            att = net['attachments']['values']
544 c17b8bc0 Stavros Sachtouris
            count = len(att)
545 c17b8bc0 Stavros Sachtouris
            net['attachments'] = att if count else None
546 c17b8bc0 Stavros Sachtouris
547 5a673575 Stavros Sachtouris
    @errors.generic.all
548 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
549 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
550 5a673575 Stavros Sachtouris
    def _run(self, network_id):
551 5a673575 Stavros Sachtouris
        network = self.client.get_network_details(int(network_id))
552 5a673575 Stavros Sachtouris
        self._make_result_pretty(network)
553 5a673575 Stavros Sachtouris
        print_dict(network, exclude=('id'))
554 5a673575 Stavros Sachtouris
555 c17b8bc0 Stavros Sachtouris
    def main(self, network_id):
556 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
557 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
558 c17b8bc0 Stavros Sachtouris
559 c17b8bc0 Stavros Sachtouris
560 c17b8bc0 Stavros Sachtouris
@command(network_cmds)
561 7493ccb6 Stavros Sachtouris
class network_list(_init_cyclades):
562 7493ccb6 Stavros Sachtouris
    """List networks"""
563 7493ccb6 Stavros Sachtouris
564 93914390 Stavros Sachtouris
    arguments = dict(
565 ddc0b290 Stavros Sachtouris
        detail=FlagArgument('show detailed output', '-l'),
566 ddc0b290 Stavros Sachtouris
        limit=IntArgument('limit the number of networks in list', '-n'),
567 ddc0b290 Stavros Sachtouris
        more=FlagArgument(
568 ddc0b290 Stavros Sachtouris
            'output results in pages (-n to set items per page, default 10)',
569 ddc0b290 Stavros Sachtouris
            '--more')
570 93914390 Stavros Sachtouris
    )
571 7493ccb6 Stavros Sachtouris
572 ddc0b290 Stavros Sachtouris
    def _make_results_pretty(self, nets):
573 7493ccb6 Stavros Sachtouris
        for net in nets:
574 ddc0b290 Stavros Sachtouris
            network_info._make_result_pretty(net)
575 7493ccb6 Stavros Sachtouris
576 5a673575 Stavros Sachtouris
    @errors.generic.all
577 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
578 5a673575 Stavros Sachtouris
    def _run(self):
579 5a673575 Stavros Sachtouris
        networks = self.client.list_networks(self['detail'])
580 5a673575 Stavros Sachtouris
        if self['detail']:
581 5a673575 Stavros Sachtouris
            self._make_results_pretty(networks)
582 ddc0b290 Stavros Sachtouris
        if self['more']:
583 ddc0b290 Stavros Sachtouris
            print_items(networks,
584 ddc0b290 Stavros Sachtouris
                page_size=self['limit'] if self['limit'] else 10)
585 0e806947 Stavros Sachtouris
        elif self['limit']:
586 0e806947 Stavros Sachtouris
            print_items(networks[:self['limit']])
587 0e806947 Stavros Sachtouris
        else:
588 0e806947 Stavros Sachtouris
            print_items(networks)
589 7493ccb6 Stavros Sachtouris
590 5a673575 Stavros Sachtouris
    def main(self):
591 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
592 5a673575 Stavros Sachtouris
        self._run()
593 5a673575 Stavros Sachtouris
594 234954d1 Stavros Sachtouris
595 d486baec Stavros Sachtouris
@command(network_cmds)
596 7493ccb6 Stavros Sachtouris
class network_create(_init_cyclades):
597 0e806947 Stavros Sachtouris
    """Create an (unconnected) network"""
598 7493ccb6 Stavros Sachtouris
599 93914390 Stavros Sachtouris
    arguments = dict(
600 0e806947 Stavros Sachtouris
        cidr=ValueArgument('explicitly set cidr', '--with-cidr'),
601 0e806947 Stavros Sachtouris
        gateway=ValueArgument('explicitly set gateway', '--with-gateway'),
602 0e806947 Stavros Sachtouris
        dhcp=ValueArgument('explicitly set dhcp', '--with-dhcp'),
603 0e806947 Stavros Sachtouris
        type=ValueArgument('explicitly set type', '--with-type')
604 93914390 Stavros Sachtouris
    )
605 7493ccb6 Stavros Sachtouris
606 5a673575 Stavros Sachtouris
    @errors.generic.all
607 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
608 5a673575 Stavros Sachtouris
    @errors.cyclades.network_max
609 5a673575 Stavros Sachtouris
    def _run(self, name):
610 5a673575 Stavros Sachtouris
        r = self.client.create_network(name,
611 5a673575 Stavros Sachtouris
            cidr=self['cidr'],
612 5a673575 Stavros Sachtouris
            gateway=self['gateway'],
613 5a673575 Stavros Sachtouris
            dhcp=self['dhcp'],
614 5a673575 Stavros Sachtouris
            type=self['type'])
615 5a673575 Stavros Sachtouris
        print_items([r])
616 5a673575 Stavros Sachtouris
617 7493ccb6 Stavros Sachtouris
    def main(self, name):
618 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
619 5a673575 Stavros Sachtouris
        self._run(name)
620 7493ccb6 Stavros Sachtouris
621 234954d1 Stavros Sachtouris
622 d486baec Stavros Sachtouris
@command(network_cmds)
623 7493ccb6 Stavros Sachtouris
class network_rename(_init_cyclades):
624 0e806947 Stavros Sachtouris
    """Set the name of a network"""
625 7493ccb6 Stavros Sachtouris
626 5a673575 Stavros Sachtouris
    @errors.generic.all
627 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
628 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
629 5a673575 Stavros Sachtouris
    def _run(self, network_id, new_name):
630 5a673575 Stavros Sachtouris
        self.client.update_network_name(int(network_id), new_name)
631 5a673575 Stavros Sachtouris
632 7493ccb6 Stavros Sachtouris
    def main(self, network_id, new_name):
633 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
634 5a673575 Stavros Sachtouris
        self._run(network_id=network_id, new_name=new_name)
635 7493ccb6 Stavros Sachtouris
636 234954d1 Stavros Sachtouris
637 d486baec Stavros Sachtouris
@command(network_cmds)
638 7493ccb6 Stavros Sachtouris
class network_delete(_init_cyclades):
639 7493ccb6 Stavros Sachtouris
    """Delete a network"""
640 7493ccb6 Stavros Sachtouris
641 5a673575 Stavros Sachtouris
    @errors.generic.all
642 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
643 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
644 5a673575 Stavros Sachtouris
    @errors.cyclades.network_in_use
645 5a673575 Stavros Sachtouris
    def _run(self, network_id):
646 5a673575 Stavros Sachtouris
        self.client.delete_network(int(network_id))
647 5a673575 Stavros Sachtouris
648 7493ccb6 Stavros Sachtouris
    def main(self, network_id):
649 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
650 5a673575 Stavros Sachtouris
        self._run(network_id=network_id)
651 7493ccb6 Stavros Sachtouris
652 234954d1 Stavros Sachtouris
653 d486baec Stavros Sachtouris
@command(network_cmds)
654 7493ccb6 Stavros Sachtouris
class network_connect(_init_cyclades):
655 7493ccb6 Stavros Sachtouris
    """Connect a server to a network"""
656 7493ccb6 Stavros Sachtouris
657 5a673575 Stavros Sachtouris
    @errors.generic.all
658 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
659 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
660 5a673575 Stavros Sachtouris
    @errors.cyclades.network_id
661 5a673575 Stavros Sachtouris
    def _run(self, server_id, network_id):
662 5a673575 Stavros Sachtouris
        self.client.connect_server(int(server_id), int(network_id))
663 5a673575 Stavros Sachtouris
664 7493ccb6 Stavros Sachtouris
    def main(self, server_id, network_id):
665 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
666 5a673575 Stavros Sachtouris
        self._run(server_id=server_id, network_id=network_id)
667 7493ccb6 Stavros Sachtouris
668 234954d1 Stavros Sachtouris
669 d486baec Stavros Sachtouris
@command(network_cmds)
670 7493ccb6 Stavros Sachtouris
class network_disconnect(_init_cyclades):
671 0e806947 Stavros Sachtouris
    """Disconnect a nic that connects a server to a network
672 0e806947 Stavros Sachtouris
    Nic ids are listed as "attachments" in detailed network information
673 439826ec Stavros Sachtouris
    To get detailed network information: /network info <network id>
674 0e806947 Stavros Sachtouris
    """
675 7493ccb6 Stavros Sachtouris
676 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_format
677 5a673575 Stavros Sachtouris
    def _server_id_from_nic(self, nic_id):
678 5a673575 Stavros Sachtouris
        return nic_id.split('-')[1]
679 5a673575 Stavros Sachtouris
680 5a673575 Stavros Sachtouris
    @errors.generic.all
681 5a673575 Stavros Sachtouris
    @errors.cyclades.connection
682 5a673575 Stavros Sachtouris
    @errors.cyclades.server_id
683 5a673575 Stavros Sachtouris
    @errors.cyclades.nic_id
684 5a673575 Stavros Sachtouris
    def _run(self, nic_id, server_id):
685 5a673575 Stavros Sachtouris
        if not self.client.disconnect_server(server_id, nic_id):
686 5a673575 Stavros Sachtouris
            raise ClientError(
687 5a673575 Stavros Sachtouris
                'Network Interface %s not found on server %s' % (
688 5a673575 Stavros Sachtouris
                    nic_id,
689 5a673575 Stavros Sachtouris
                    server_id),
690 5a673575 Stavros Sachtouris
                status=404)
691 5a673575 Stavros Sachtouris
692 7493ccb6 Stavros Sachtouris
    def main(self, nic_id):
693 5a673575 Stavros Sachtouris
        super(self.__class__, self)._run()
694 5a673575 Stavros Sachtouris
        server_id = self._server_id_from_nic(nic_id=nic_id)
695 5a673575 Stavros Sachtouris
        self._run(nic_id=nic_id, server_id=server_id)