Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / volume.py @ 05f1452c

History | View | Annotate | Download (5.2 kB)

1
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from kamaki.cli import command
35
from kamaki.cli.command_tree import CommandTree
36
from kamaki.cli.commands.cyclades import _init_cyclades
37
from kamaki.cli.errors import CLIBaseUrlError
38
from kamaki.cli.argument import (
39
    FlagArgument, ValueArgument, KeyValueArgument, IntArgument)
40
from kamaki.cli.commands import _command_init, errors, addLogSettings
41
from kamaki.cli.commands import _optional_json
42
from kamaki.clients.volume import VolumeClient
43

    
44

    
45
snapshot_cmds = CommandTree('snapshot', 'Server image snapshot operations')
46
volume_cmds = CommandTree('volume', 'Server volume operations')
47
_commands = [snapshot_cmds, volume_cmds]
48

    
49

    
50
class _init_volume(_command_init):
51
    @errors.generic.all
52
    @addLogSettings
53
    def _run(self, service='volume'):
54
        if getattr(self, 'cloud', None):
55
            base_url = self._custom_url(service) or self._custom_url(
56
                'volume')
57
            if base_url:
58
                token = self._custom_token(service) or self._custom_token(
59
                    'volume') or self.config.get_cloud('token')
60
                self.client = VolumeClient(base_url=base_url, token=token)
61
                return
62
        else:
63
            self.cloud = 'default'
64
        if getattr(self, 'auth_base', False):
65
            cyclades_endpoints = self.auth_base.get_service_endpoints(
66
                self._custom_type('volume') or 'volume',
67
                self._custom_version('volume') or '')
68
            base_url = cyclades_endpoints['publicURL']
69
            token = self.auth_base.token
70
            self.client = VolumeClient(base_url=base_url, token=token)
71
        else:
72
            raise CLIBaseUrlError(service='volume')
73

    
74
    def main(self):
75
        self._run()
76

    
77

    
78
@command(volume_cmds)
79
class volume_list(_init_cyclades, _optional_json):
80
    """List a server volume or the volumes for all servers"""
81

    
82
    arguments = dict(
83
        server_id=IntArgument('list volumes of this server', '--server-id')
84
    )
85

    
86
    @errors.generic.all
87
    @errors.cyclades.connection
88
    def _run(self):
89
        servers = [self.client.get_server_details(self['server_id'])] if (
90
            self['server_id']) else self.client.list_servers(detail=True)
91
        volumes = [dict(
92
            server_id=s['id'],
93
            volumes=' '.join('%s' % v for v in s['volumes'])) for s in servers]
94
        self._print(volumes)
95

    
96
    def main(self):
97
        super(self.__class__, self)._run()
98
        self._run()
99

    
100

    
101
@command(snapshot_cmds)
102
class snapshot_create(_init_volume, _optional_json):
103
    """Create a snapshot of a volume"""
104

    
105
    arguments = dict(
106
        name=ValueArgument(
107
            'The snapshot name (otherwise it is created automatically)',
108
            '--name'),
109
        description=ValueArgument('Snapshot description', '--description'),
110
        metadata=KeyValueArgument(
111
            'Snapshot custom metadata (can be repeated)', '--metadata')
112
    )
113

    
114
    @errors.generic.all
115
    @errors.cyclades.connection
116
    def _run(self, volume_id):
117
        self._print(self.client.create_snapshot(
118
            volume_id, self['name'], self['description'], self['metadata']))
119

    
120
    def main(self, volume_id):
121
        super(self.__class__, self)._run()
122
        self._run(volume_id)
123

    
124

    
125
@command(snapshot_cmds)
126
class snapshot_list(_init_cyclades, _optional_json):
127
    """List all snapshots"""
128

    
129
    arguments = dict(
130
        detail=FlagArgument('show detailed output', ('-l', '--details'))
131
    )
132

    
133
    @errors.generic.all
134
    @errors.cyclades.connection
135
    def _run(self):
136
        r = [img for img in self.client.list_images(detail=True) if (
137
            img.get('is_snapshot', False))]
138
        if not self['detail']:
139
            r = [dict(name=img['name'], id=img['id']) for img in r]
140
        self._print(r)
141

    
142
    def main(self):
143
        super(self.__class__, self)._run()
144
        self._run()