Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / astakos.py @ b37d65b6

History | View | Annotate | Download (35.6 kB)

1 4573f225 Stavros Sachtouris
# Copyright 2011-2014 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.command
33 7493ccb6 Stavros Sachtouris
34 ab863157 Stavros Sachtouris
from json import load, loads
35 c308d73f Stavros Sachtouris
from os.path import abspath
36 c308d73f Stavros Sachtouris
37 c2be5c96 Stavros Sachtouris
from kamaki.cli import command
38 cd42f8d8 Stavros Sachtouris
from kamaki.clients.astakos import LoggedAstakosClient
39 b4f69041 Stavros Sachtouris
from kamaki.cli.commands import (
40 ad696342 Stavros Sachtouris
    _command_init, errors, _optional_json, addLogSettings, _name_filter)
41 be99b6ad Stavros Sachtouris
from kamaki.cli.command_tree import CommandTree
42 b101d9e5 Stavros Sachtouris
from kamaki.cli.errors import (
43 b101d9e5 Stavros Sachtouris
    CLIBaseUrlError, CLISyntaxError, CLIError, CLIInvalidArgument)
44 ab863157 Stavros Sachtouris
from kamaki.cli.argument import (
45 b101d9e5 Stavros Sachtouris
    FlagArgument, ValueArgument, IntArgument, CommaSeparatedListArgument,
46 b101d9e5 Stavros Sachtouris
    KeyValueArgument, DateArgument)
47 ad696342 Stavros Sachtouris
from kamaki.cli.utils import format_size, filter_dicts_by_dict
48 7493ccb6 Stavros Sachtouris
49 25f9a991 Stavros Sachtouris
#  Mandatory
50 25f9a991 Stavros Sachtouris
51 e8d3b957 Stavros Sachtouris
user_commands = CommandTree('user', 'Astakos/Identity API commands')
52 25f9a991 Stavros Sachtouris
quota_commands = CommandTree(
53 25f9a991 Stavros Sachtouris
    'quota', 'Astakos/Account API commands for quotas')
54 25f9a991 Stavros Sachtouris
resource_commands = CommandTree(
55 25f9a991 Stavros Sachtouris
    'resource', 'Astakos/Account API commands for resources')
56 e8d3b957 Stavros Sachtouris
project_commands = CommandTree('project', 'Astakos project API commands')
57 9d84caa4 Stavros Sachtouris
membership_commands = CommandTree(
58 9d84caa4 Stavros Sachtouris
    'membership', 'Astakos project membership API commands')
59 25f9a991 Stavros Sachtouris
60 25f9a991 Stavros Sachtouris
61 25f9a991 Stavros Sachtouris
#  Optional
62 25f9a991 Stavros Sachtouris
63 25f9a991 Stavros Sachtouris
endpoint_commands = CommandTree(
64 25f9a991 Stavros Sachtouris
    'endpoint', 'Astakos/Account API commands for endpoints')
65 25f9a991 Stavros Sachtouris
service_commands = CommandTree('service', 'Astakos API commands for services')
66 25f9a991 Stavros Sachtouris
commission_commands = CommandTree(
67 25f9a991 Stavros Sachtouris
    'commission', 'Astakos API commands for commissions')
68 25f9a991 Stavros Sachtouris
69 25f9a991 Stavros Sachtouris
_commands = [
70 25f9a991 Stavros Sachtouris
    user_commands, quota_commands, resource_commands, project_commands,
71 9d84caa4 Stavros Sachtouris
    service_commands, commission_commands, endpoint_commands,
72 9d84caa4 Stavros Sachtouris
    membership_commands]
73 234954d1 Stavros Sachtouris
74 234954d1 Stavros Sachtouris
75 392d902d Stavros Sachtouris
def with_temp_token(func):
76 392d902d Stavros Sachtouris
    """ Set token to self.client.token, run func, recover old token """
77 ab863157 Stavros Sachtouris
    def wrap(self, *args, **kwargs):
78 ab863157 Stavros Sachtouris
        try:
79 ab863157 Stavros Sachtouris
            token = kwargs.pop('token')
80 ab863157 Stavros Sachtouris
        except KeyError:
81 392d902d Stavros Sachtouris
            raise CLISyntaxError('A token is needed for %s' % func)
82 ab863157 Stavros Sachtouris
        token_bu = self.client.token
83 ab863157 Stavros Sachtouris
        try:
84 fa7d08b6 Stavros Sachtouris
            self.client.token = token or token_bu
85 392d902d Stavros Sachtouris
            return func(self, *args, **kwargs)
86 ab863157 Stavros Sachtouris
        finally:
87 ab863157 Stavros Sachtouris
            self.client.token = token_bu
88 ab863157 Stavros Sachtouris
    return wrap
89 ab863157 Stavros Sachtouris
90 ab863157 Stavros Sachtouris
91 e8d3b957 Stavros Sachtouris
class _init_synnefo_astakosclient(_command_init):
92 85115c12 Stavros Sachtouris
93 a03ade9e Stavros Sachtouris
    @errors.generic.all
94 4018326d Stavros Sachtouris
    @errors.user.load
95 e8d3b957 Stavros Sachtouris
    @errors.user.astakosclient
96 b4f69041 Stavros Sachtouris
    @addLogSettings
97 436bd910 Stavros Sachtouris
    def _run(self):
98 e8d3b957 Stavros Sachtouris
        if getattr(self, 'cloud', None):
99 b4f69041 Stavros Sachtouris
            base_url = self._custom_url('astakos')
100 b4f69041 Stavros Sachtouris
            if base_url:
101 f5ff79d9 Stavros Sachtouris
                token = self._custom_token(
102 ab863157 Stavros Sachtouris
                    'astakos') or self.config.get_cloud(
103 ab863157 Stavros Sachtouris
                    self.cloud, 'token')
104 dc897a7e Stavros Sachtouris
                token = token.split()[0] if ' ' in token else token
105 cd42f8d8 Stavros Sachtouris
                self.client = LoggedAstakosClient(base_url, token)
106 b4f69041 Stavros Sachtouris
                return
107 b4f69041 Stavros Sachtouris
        else:
108 b4f69041 Stavros Sachtouris
            self.cloud = 'default'
109 e8d3b957 Stavros Sachtouris
        if getattr(self, 'auth_base', None):
110 5033585e Stavros Sachtouris
            self.client = self.auth_base.get_client()
111 b4f69041 Stavros Sachtouris
            return
112 b4f69041 Stavros Sachtouris
        raise CLIBaseUrlError(service='astakos')
113 7493ccb6 Stavros Sachtouris
114 436bd910 Stavros Sachtouris
    def main(self):
115 5fdccdec Stavros Sachtouris
        self._run()
116 436bd910 Stavros Sachtouris
117 234954d1 Stavros Sachtouris
118 e8d3b957 Stavros Sachtouris
@command(user_commands)
119 fa7d08b6 Stavros Sachtouris
class user_authenticate(_init_synnefo_astakosclient, _optional_json):
120 fa7d08b6 Stavros Sachtouris
    """Authenticate a user and get all authentication information"""
121 7493ccb6 Stavros Sachtouris
122 a03ade9e Stavros Sachtouris
    @errors.generic.all
123 4018326d Stavros Sachtouris
    @errors.user.authenticate
124 e8d3b957 Stavros Sachtouris
    @errors.user.astakosclient
125 5033585e Stavros Sachtouris
    @with_temp_token
126 5033585e Stavros Sachtouris
    def _run(self):
127 fa7d08b6 Stavros Sachtouris
        self._print(self.client.authenticate(), self.print_dict)
128 3185cd6d Stavros Sachtouris
129 e8d3b957 Stavros Sachtouris
    def main(self, token=None):
130 9a8861d1 Stavros Sachtouris
        super(self.__class__, self)._run()
131 5033585e Stavros Sachtouris
        self._run(token=token)
132 9a8861d1 Stavros Sachtouris
133 9a8861d1 Stavros Sachtouris
134 e8d3b957 Stavros Sachtouris
@command(user_commands)
135 5033585e Stavros Sachtouris
class user_uuid2name(_init_synnefo_astakosclient, _optional_json):
136 5033585e Stavros Sachtouris
    """Get user name(s) from uuid(s)"""
137 9a8861d1 Stavros Sachtouris
138 8b4ba753 Stavros Sachtouris
    #@errors.generic.all
139 8b4ba753 Stavros Sachtouris
    #@errors.user.astakosclient
140 e8d3b957 Stavros Sachtouris
    def _run(self, uuids):
141 e8d3b957 Stavros Sachtouris
        r = self.client.get_usernames(uuids)
142 e8d3b957 Stavros Sachtouris
        self._print(r, self.print_dict)
143 e8d3b957 Stavros Sachtouris
        unresolved = set(uuids).difference(r)
144 e8d3b957 Stavros Sachtouris
        if unresolved:
145 e8d3b957 Stavros Sachtouris
            self.error('Unresolved uuids: %s' % ', '.join(unresolved))
146 e8d3b957 Stavros Sachtouris
147 e8d3b957 Stavros Sachtouris
    def main(self, uuid, *more_uuids):
148 9a8861d1 Stavros Sachtouris
        super(self.__class__, self)._run()
149 e8d3b957 Stavros Sachtouris
        self._run(uuids=((uuid, ) + more_uuids))
150 b91111b9 Stavros Sachtouris
151 b91111b9 Stavros Sachtouris
152 e8d3b957 Stavros Sachtouris
@command(user_commands)
153 5033585e Stavros Sachtouris
class user_name2uuid(_init_synnefo_astakosclient, _optional_json):
154 5033585e Stavros Sachtouris
    """Get user uuid(s) from name(s)"""
155 b91111b9 Stavros Sachtouris
156 b91111b9 Stavros Sachtouris
    @errors.generic.all
157 e8d3b957 Stavros Sachtouris
    @errors.user.astakosclient
158 e8d3b957 Stavros Sachtouris
    def _run(self, usernames):
159 e8d3b957 Stavros Sachtouris
        r = self.client.get_uuids(usernames)
160 e8d3b957 Stavros Sachtouris
        self._print(r, self.print_dict)
161 e8d3b957 Stavros Sachtouris
        unresolved = set(usernames).difference(r)
162 e8d3b957 Stavros Sachtouris
        if unresolved:
163 e8d3b957 Stavros Sachtouris
            self.error('Unresolved usernames: %s' % ', '.join(unresolved))
164 e8d3b957 Stavros Sachtouris
165 e8d3b957 Stavros Sachtouris
    def main(self, username, *more_usernames):
166 b91111b9 Stavros Sachtouris
        super(self.__class__, self)._run()
167 e8d3b957 Stavros Sachtouris
        self._run(usernames=((username, ) + more_usernames))
168 e8d3b957 Stavros Sachtouris
169 e8d3b957 Stavros Sachtouris
170 6893e31c Stavros Sachtouris
class _quota(_init_synnefo_astakosclient, _optional_json):
171 e8d3b957 Stavros Sachtouris
172 e8d3b957 Stavros Sachtouris
    _to_format = set(['cyclades.disk', 'pithos.diskspace', 'cyclades.ram'])
173 fe4940bc Stavros Sachtouris
174 e8d3b957 Stavros Sachtouris
    arguments = dict(
175 e8d3b957 Stavros Sachtouris
        bytes=FlagArgument('Show data size in bytes', '--bytes')
176 e8d3b957 Stavros Sachtouris
    )
177 fe4940bc Stavros Sachtouris
178 e8d3b957 Stavros Sachtouris
    def _print_quotas(self, quotas, *args, **kwargs):
179 e8d3b957 Stavros Sachtouris
        if not self['bytes']:
180 b37d65b6 Stavros Sachtouris
            for project_id, resources in quotas.items():
181 b37d65b6 Stavros Sachtouris
                for r in self._to_format.intersection(resources):
182 b37d65b6 Stavros Sachtouris
                    resources[r] = dict(
183 b37d65b6 Stavros Sachtouris
                        [(k, format_size(v)) for k, v in resources[r].items()])
184 e8d3b957 Stavros Sachtouris
        self.print_dict(quotas, *args, **kwargs)
185 fe4940bc Stavros Sachtouris
186 6893e31c Stavros Sachtouris
187 6893e31c Stavros Sachtouris
@command(quota_commands)
188 6893e31c Stavros Sachtouris
class quota_info(_quota):
189 b37d65b6 Stavros Sachtouris
    """Get quota information"""
190 b37d65b6 Stavros Sachtouris
191 b37d65b6 Stavros Sachtouris
    arguments = dict(
192 b37d65b6 Stavros Sachtouris
        resource=ValueArgument('Quota for this resource', '--resource'),
193 b37d65b6 Stavros Sachtouris
        project_id=ValueArgument('Quota for this project', '--project-id'),
194 b37d65b6 Stavros Sachtouris
        bytes=FlagArgument('Show data size in bytes', '--bytes')
195 b37d65b6 Stavros Sachtouris
    )
196 b37d65b6 Stavros Sachtouris
    required = ['resource', 'project_id']
197 6893e31c Stavros Sachtouris
198 6893e31c Stavros Sachtouris
    @errors.generic.all
199 6893e31c Stavros Sachtouris
    @errors.user.astakosclient
200 b37d65b6 Stavros Sachtouris
    def _run(self):
201 b37d65b6 Stavros Sachtouris
        quotas = self.client.get_quotas()
202 b37d65b6 Stavros Sachtouris
        if self['project_id']:
203 b37d65b6 Stavros Sachtouris
            quotas = {self['project_id']: quotas.get(self['project_id'])}
204 b37d65b6 Stavros Sachtouris
        if self['resource']:
205 b37d65b6 Stavros Sachtouris
            d = dict()
206 b37d65b6 Stavros Sachtouris
            for project_id, resources in quotas.items():
207 b37d65b6 Stavros Sachtouris
                r = dict()
208 b37d65b6 Stavros Sachtouris
                for resource, value in resources.items():
209 b37d65b6 Stavros Sachtouris
                    if (resource.startswith(self['resource'])):
210 b37d65b6 Stavros Sachtouris
                        r[resource] = value
211 b37d65b6 Stavros Sachtouris
                if r:
212 b37d65b6 Stavros Sachtouris
                    d[project_id] = r
213 b37d65b6 Stavros Sachtouris
            quotas = d
214 b37d65b6 Stavros Sachtouris
        self._print(quotas, self._print_quotas)
215 b37d65b6 Stavros Sachtouris
216 b37d65b6 Stavros Sachtouris
    def main(self):
217 6893e31c Stavros Sachtouris
        super(self.__class__, self)._run()
218 b37d65b6 Stavros Sachtouris
        self._run()
219 6893e31c Stavros Sachtouris
220 6893e31c Stavros Sachtouris
221 6893e31c Stavros Sachtouris
@command(quota_commands)
222 6893e31c Stavros Sachtouris
class quota_list(_quota):
223 6893e31c Stavros Sachtouris
    """Get user quotas"""
224 6893e31c Stavros Sachtouris
225 fe4940bc Stavros Sachtouris
    @errors.generic.all
226 e8d3b957 Stavros Sachtouris
    @errors.user.astakosclient
227 e8d3b957 Stavros Sachtouris
    def _run(self):
228 e8d3b957 Stavros Sachtouris
        self._print(self.client.get_quotas(), self._print_quotas)
229 fe4940bc Stavros Sachtouris
230 e8d3b957 Stavros Sachtouris
    def main(self):
231 fe4940bc Stavros Sachtouris
        super(self.__class__, self)._run()
232 e8d3b957 Stavros Sachtouris
        self._run()
233 c308d73f Stavros Sachtouris
234 c308d73f Stavros Sachtouris
235 fa7d08b6 Stavros Sachtouris
#  command user session
236 fa7d08b6 Stavros Sachtouris
237 fa7d08b6 Stavros Sachtouris
238 fa7d08b6 Stavros Sachtouris
@command(user_commands)
239 25f9a991 Stavros Sachtouris
class user_info(_init_synnefo_astakosclient, _optional_json):
240 fa7d08b6 Stavros Sachtouris
    """Get info for (current) session user"""
241 fa7d08b6 Stavros Sachtouris
242 fa7d08b6 Stavros Sachtouris
    arguments = dict(
243 fa7d08b6 Stavros Sachtouris
        uuid=ValueArgument('Query user with uuid', '--uuid'),
244 fa7d08b6 Stavros Sachtouris
        name=ValueArgument('Query user with username/email', '--username')
245 fa7d08b6 Stavros Sachtouris
    )
246 fa7d08b6 Stavros Sachtouris
247 fa7d08b6 Stavros Sachtouris
    @errors.generic.all
248 fa7d08b6 Stavros Sachtouris
    @errors.user.astakosclient
249 fa7d08b6 Stavros Sachtouris
    def _run(self):
250 fa7d08b6 Stavros Sachtouris
        if self['uuid'] and self['name']:
251 fa7d08b6 Stavros Sachtouris
            raise CLISyntaxError(
252 fa7d08b6 Stavros Sachtouris
                'Arguments uuid and username are mutually exclusive',
253 fa7d08b6 Stavros Sachtouris
                details=['Use either uuid OR username OR none, not both'])
254 fa7d08b6 Stavros Sachtouris
        uuid = self['uuid'] or (self._username2uuid(self['name']) if (
255 fa7d08b6 Stavros Sachtouris
            self['name']) else None)
256 fa7d08b6 Stavros Sachtouris
        try:
257 fa7d08b6 Stavros Sachtouris
            token = self.auth_base.get_token(uuid) if uuid else None
258 fa7d08b6 Stavros Sachtouris
        except KeyError:
259 fa7d08b6 Stavros Sachtouris
            msg = ('id %s' % self['uuid']) if (
260 fa7d08b6 Stavros Sachtouris
                self['uuid']) else 'username %s' % self['name']
261 fa7d08b6 Stavros Sachtouris
            raise CLIError(
262 fa7d08b6 Stavros Sachtouris
                'No user with %s in the cached session list' % msg, details=[
263 fa7d08b6 Stavros Sachtouris
                    'To see all cached session users',
264 25f9a991 Stavros Sachtouris
                    '  /user list',
265 fa7d08b6 Stavros Sachtouris
                    'To authenticate and add a new user in the session list',
266 25f9a991 Stavros Sachtouris
                    '  /user add <new token>'])
267 fa7d08b6 Stavros Sachtouris
        self._print(self.auth_base.user_info(token), self.print_dict)
268 fa7d08b6 Stavros Sachtouris
269 fa7d08b6 Stavros Sachtouris
270 fa7d08b6 Stavros Sachtouris
@command(user_commands)
271 25f9a991 Stavros Sachtouris
class user_add(_init_synnefo_astakosclient, _optional_json):
272 25f9a991 Stavros Sachtouris
    """Authenticate a user by token and add to kamaki session (cache)"""
273 fa7d08b6 Stavros Sachtouris
274 fa7d08b6 Stavros Sachtouris
    @errors.generic.all
275 fa7d08b6 Stavros Sachtouris
    @errors.user.astakosclient
276 fa7d08b6 Stavros Sachtouris
    def _run(self, token=None):
277 fa7d08b6 Stavros Sachtouris
        ask = token and token not in self.auth_base._uuids
278 fa7d08b6 Stavros Sachtouris
        self._print(self.auth_base.authenticate(token), self.print_dict)
279 fa7d08b6 Stavros Sachtouris
        if ask and self.ask_user(
280 fa7d08b6 Stavros Sachtouris
                'Token is temporarily stored in memory. If it is stored in'
281 fa7d08b6 Stavros Sachtouris
                ' kamaki configuration file, it will be available in later'
282 fa7d08b6 Stavros Sachtouris
                ' sessions. Do you want to permanently store this token?'):
283 fa7d08b6 Stavros Sachtouris
            tokens = self.auth_base._uuids.keys()
284 fa7d08b6 Stavros Sachtouris
            tokens.remove(self.auth_base.token)
285 fa7d08b6 Stavros Sachtouris
            self['config'].set_cloud(
286 fa7d08b6 Stavros Sachtouris
                self.cloud, 'token', ' '.join([self.auth_base.token] + tokens))
287 fa7d08b6 Stavros Sachtouris
            self['config'].write()
288 fa7d08b6 Stavros Sachtouris
289 fa7d08b6 Stavros Sachtouris
    def main(self, new_token=None):
290 fa7d08b6 Stavros Sachtouris
        super(self.__class__, self)._run()
291 fa7d08b6 Stavros Sachtouris
        self._run(token=new_token)
292 fa7d08b6 Stavros Sachtouris
293 fa7d08b6 Stavros Sachtouris
294 fa7d08b6 Stavros Sachtouris
@command(user_commands)
295 25f9a991 Stavros Sachtouris
class user_list(_init_synnefo_astakosclient, _optional_json):
296 25f9a991 Stavros Sachtouris
    """List (cached) session users"""
297 fa7d08b6 Stavros Sachtouris
298 fa7d08b6 Stavros Sachtouris
    arguments = dict(
299 fa7d08b6 Stavros Sachtouris
        detail=FlagArgument('Detailed listing', ('-l', '--detail'))
300 fa7d08b6 Stavros Sachtouris
    )
301 fa7d08b6 Stavros Sachtouris
302 fa7d08b6 Stavros Sachtouris
    @errors.generic.all
303 fa7d08b6 Stavros Sachtouris
    @errors.user.astakosclient
304 fa7d08b6 Stavros Sachtouris
    def _run(self):
305 fa7d08b6 Stavros Sachtouris
        self._print([u if self['detail'] else (dict(
306 fa7d08b6 Stavros Sachtouris
            id=u['id'], name=u['name'])) for u in self.auth_base.list_users()])
307 fa7d08b6 Stavros Sachtouris
308 fa7d08b6 Stavros Sachtouris
    def main(self):
309 fa7d08b6 Stavros Sachtouris
        super(self.__class__, self)._run()
310 fa7d08b6 Stavros Sachtouris
        self._run()
311 fa7d08b6 Stavros Sachtouris
312 fa7d08b6 Stavros Sachtouris
313 fa7d08b6 Stavros Sachtouris
@command(user_commands)
314 25f9a991 Stavros Sachtouris
class user_select(_init_synnefo_astakosclient):
315 25f9a991 Stavros Sachtouris
    """Select a user from the (cached) list as the current session user"""
316 fa7d08b6 Stavros Sachtouris
317 fa7d08b6 Stavros Sachtouris
    @errors.generic.all
318 fa7d08b6 Stavros Sachtouris
    @errors.user.astakosclient
319 fa7d08b6 Stavros Sachtouris
    def _run(self, uuid):
320 fa7d08b6 Stavros Sachtouris
        try:
321 fa7d08b6 Stavros Sachtouris
            first_token = self.auth_base.get_token(uuid)
322 fa7d08b6 Stavros Sachtouris
        except KeyError:
323 fa7d08b6 Stavros Sachtouris
            raise CLIError(
324 fa7d08b6 Stavros Sachtouris
                'No user with uuid %s in the cached session list' % uuid,
325 fa7d08b6 Stavros Sachtouris
                details=[
326 fa7d08b6 Stavros Sachtouris
                    'To see all cached session users',
327 25f9a991 Stavros Sachtouris
                    '  /user list',
328 fa7d08b6 Stavros Sachtouris
                    'To authenticate and add a new user in the session list',
329 25f9a991 Stavros Sachtouris
                    '  /user add <new token>'])
330 fa7d08b6 Stavros Sachtouris
        if self.auth_base.token != first_token:
331 fa7d08b6 Stavros Sachtouris
            self.auth_base.token = first_token
332 fa7d08b6 Stavros Sachtouris
            msg = 'User with id %s is now the current session user.\n' % uuid
333 fa7d08b6 Stavros Sachtouris
            msg += 'Do you want future sessions to also start with this user?'
334 fa7d08b6 Stavros Sachtouris
            if self.ask_user(msg):
335 fa7d08b6 Stavros Sachtouris
                tokens = self.auth_base._uuids.keys()
336 fa7d08b6 Stavros Sachtouris
                tokens.remove(self.auth_base.token)
337 fa7d08b6 Stavros Sachtouris
                tokens.insert(0, self.auth_base.token)
338 fa7d08b6 Stavros Sachtouris
                self['config'].set_cloud(
339 fa7d08b6 Stavros Sachtouris
                    self.cloud, 'token',  ' '.join(tokens))
340 fa7d08b6 Stavros Sachtouris
                self['config'].write()
341 fa7d08b6 Stavros Sachtouris
                self.error('User is selected for next sessions')
342 fa7d08b6 Stavros Sachtouris
            else:
343 fa7d08b6 Stavros Sachtouris
                self.error('User is not permanently selected')
344 fa7d08b6 Stavros Sachtouris
        else:
345 fa7d08b6 Stavros Sachtouris
            self.error('User was already the selected session user')
346 fa7d08b6 Stavros Sachtouris
347 fa7d08b6 Stavros Sachtouris
    def main(self, user_uuid):
348 fa7d08b6 Stavros Sachtouris
        super(self.__class__, self)._run()
349 fa7d08b6 Stavros Sachtouris
        self._run(uuid=user_uuid)
350 fa7d08b6 Stavros Sachtouris
351 fa7d08b6 Stavros Sachtouris
352 fa7d08b6 Stavros Sachtouris
@command(user_commands)
353 25f9a991 Stavros Sachtouris
class user_delete(_init_synnefo_astakosclient):
354 25f9a991 Stavros Sachtouris
    """Delete a user (token) from the (cached) list of session users"""
355 fa7d08b6 Stavros Sachtouris
356 fa7d08b6 Stavros Sachtouris
    @errors.generic.all
357 fa7d08b6 Stavros Sachtouris
    @errors.user.astakosclient
358 fa7d08b6 Stavros Sachtouris
    def _run(self, uuid):
359 fa7d08b6 Stavros Sachtouris
        if uuid == self.auth_base.user_term('id'):
360 fa7d08b6 Stavros Sachtouris
            raise CLIError('Cannot remove current session user', details=[
361 fa7d08b6 Stavros Sachtouris
                'To see all cached session users',
362 25f9a991 Stavros Sachtouris
                '  /user list',
363 fa7d08b6 Stavros Sachtouris
                'To see current session user',
364 25f9a991 Stavros Sachtouris
                '  /user info',
365 fa7d08b6 Stavros Sachtouris
                'To select a different session user',
366 25f9a991 Stavros Sachtouris
                '  /user select <user uuid>'])
367 fa7d08b6 Stavros Sachtouris
        try:
368 fa7d08b6 Stavros Sachtouris
            self.auth_base.remove_user(uuid)
369 fa7d08b6 Stavros Sachtouris
        except KeyError:
370 fa7d08b6 Stavros Sachtouris
            raise CLIError('No user with uuid %s in session list' % uuid,
371 fa7d08b6 Stavros Sachtouris
                details=[
372 fa7d08b6 Stavros Sachtouris
                    'To see all cached session users',
373 25f9a991 Stavros Sachtouris
                    '  /user list',
374 fa7d08b6 Stavros Sachtouris
                    'To authenticate and add a new user in the session list',
375 25f9a991 Stavros Sachtouris
                    '  /user add <new token>'])
376 fa7d08b6 Stavros Sachtouris
        if self.ask_user(
377 fa7d08b6 Stavros Sachtouris
                'User is removed from current session, but will be restored in'
378 fa7d08b6 Stavros Sachtouris
                ' the next session. Remove the user from future sessions?'):
379 fa7d08b6 Stavros Sachtouris
            self['config'].set_cloud(
380 fa7d08b6 Stavros Sachtouris
                self.cloud, 'token', ' '.join(self.auth_base._uuids.keys()))
381 fa7d08b6 Stavros Sachtouris
            self['config'].write()
382 fa7d08b6 Stavros Sachtouris
383 fa7d08b6 Stavros Sachtouris
    def main(self, user_uuid):
384 fa7d08b6 Stavros Sachtouris
        super(self.__class__, self)._run()
385 fa7d08b6 Stavros Sachtouris
        self._run(uuid=user_uuid)
386 fa7d08b6 Stavros Sachtouris
387 fa7d08b6 Stavros Sachtouris
388 ab863157 Stavros Sachtouris
#  command admin
389 ab863157 Stavros Sachtouris
390 25f9a991 Stavros Sachtouris
@command(service_commands)
391 25f9a991 Stavros Sachtouris
class service_list(_init_synnefo_astakosclient, _optional_json):
392 ab863157 Stavros Sachtouris
    """List available services"""
393 ab863157 Stavros Sachtouris
394 ab863157 Stavros Sachtouris
    @errors.generic.all
395 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
396 ab863157 Stavros Sachtouris
    def _run(self):
397 ab863157 Stavros Sachtouris
        self._print(self.client.get_services())
398 ab863157 Stavros Sachtouris
399 ab863157 Stavros Sachtouris
    def main(self):
400 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
401 ab863157 Stavros Sachtouris
        self._run()
402 ab863157 Stavros Sachtouris
403 ab863157 Stavros Sachtouris
404 25f9a991 Stavros Sachtouris
@command(service_commands)
405 25f9a991 Stavros Sachtouris
class service_uuid2username(_init_synnefo_astakosclient, _optional_json):
406 ab863157 Stavros Sachtouris
    """Get service username(s) from uuid(s)"""
407 ab863157 Stavros Sachtouris
408 ab863157 Stavros Sachtouris
    @errors.generic.all
409 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
410 ab863157 Stavros Sachtouris
    @with_temp_token
411 ab863157 Stavros Sachtouris
    def _run(self, uuids):
412 ab863157 Stavros Sachtouris
        if 1 == len(uuids):
413 ab863157 Stavros Sachtouris
            self._print(self.client.service_get_username(uuids[0]))
414 ab863157 Stavros Sachtouris
        else:
415 ab863157 Stavros Sachtouris
            self._print(
416 ab863157 Stavros Sachtouris
                self.client.service_get_usernames(uuids),
417 ab863157 Stavros Sachtouris
                self.print_dict)
418 ab863157 Stavros Sachtouris
419 ab863157 Stavros Sachtouris
    def main(self, service_token, uuid, *more_uuids):
420 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
421 ab863157 Stavros Sachtouris
        self._run([uuid] + list(more_uuids), token=service_token)
422 ab863157 Stavros Sachtouris
423 ab863157 Stavros Sachtouris
424 25f9a991 Stavros Sachtouris
@command(service_commands)
425 25f9a991 Stavros Sachtouris
class service_username2uuid(_init_synnefo_astakosclient, _optional_json):
426 ab863157 Stavros Sachtouris
    """Get service uuid(s) from username(s)"""
427 ab863157 Stavros Sachtouris
428 ab863157 Stavros Sachtouris
    @errors.generic.all
429 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
430 ab863157 Stavros Sachtouris
    @with_temp_token
431 ab863157 Stavros Sachtouris
    def _run(self, usernames):
432 ab863157 Stavros Sachtouris
        if 1 == len(usernames):
433 ab863157 Stavros Sachtouris
            self._print(self.client.service_get_uuid(usernames[0]))
434 ab863157 Stavros Sachtouris
        else:
435 ab863157 Stavros Sachtouris
            self._print(
436 ab863157 Stavros Sachtouris
                self.client.service_get_uuids(usernames),
437 ab863157 Stavros Sachtouris
                self.print_dict)
438 ab863157 Stavros Sachtouris
439 ab863157 Stavros Sachtouris
    def main(self, service_token, usernames, *more_usernames):
440 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
441 ab863157 Stavros Sachtouris
        self._run([usernames] + list(more_usernames), token=service_token)
442 ab863157 Stavros Sachtouris
443 ab863157 Stavros Sachtouris
444 25f9a991 Stavros Sachtouris
@command(service_commands)
445 25f9a991 Stavros Sachtouris
class service_quotas(_init_synnefo_astakosclient, _optional_json):
446 ab863157 Stavros Sachtouris
    """Get service quotas"""
447 ab863157 Stavros Sachtouris
448 ab863157 Stavros Sachtouris
    arguments = dict(
449 ab863157 Stavros Sachtouris
        uuid=ValueArgument('A user uuid to get quotas for', '--uuid')
450 ab863157 Stavros Sachtouris
    )
451 ab863157 Stavros Sachtouris
452 ab863157 Stavros Sachtouris
    @errors.generic.all
453 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
454 ab863157 Stavros Sachtouris
    @with_temp_token
455 ab863157 Stavros Sachtouris
    def _run(self):
456 ab863157 Stavros Sachtouris
        self._print(self.client.service_get_quotas(self['uuid']))
457 ab863157 Stavros Sachtouris
458 ab863157 Stavros Sachtouris
    def main(self, service_token):
459 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
460 ab863157 Stavros Sachtouris
        self._run(token=service_token)
461 ab863157 Stavros Sachtouris
462 ab863157 Stavros Sachtouris
463 25f9a991 Stavros Sachtouris
@command(commission_commands)
464 25f9a991 Stavros Sachtouris
class commission_pending(_init_synnefo_astakosclient, _optional_json):
465 ab863157 Stavros Sachtouris
    """List pending commissions (special privileges required)"""
466 ab863157 Stavros Sachtouris
467 ab863157 Stavros Sachtouris
    @errors.generic.all
468 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
469 ab863157 Stavros Sachtouris
    def _run(self):
470 ab863157 Stavros Sachtouris
        self._print(self.client.get_pending_commissions())
471 ab863157 Stavros Sachtouris
472 ab863157 Stavros Sachtouris
    def main(self):
473 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
474 ab863157 Stavros Sachtouris
        self._run()
475 ab863157 Stavros Sachtouris
476 ab863157 Stavros Sachtouris
477 25f9a991 Stavros Sachtouris
@command(commission_commands)
478 25f9a991 Stavros Sachtouris
class commission_info(_init_synnefo_astakosclient, _optional_json):
479 ab863157 Stavros Sachtouris
    """Get commission info (special privileges required)"""
480 ab863157 Stavros Sachtouris
481 ab863157 Stavros Sachtouris
    @errors.generic.all
482 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
483 ab863157 Stavros Sachtouris
    def _run(self, commission_id):
484 ab863157 Stavros Sachtouris
        commission_id = int(commission_id)
485 ab863157 Stavros Sachtouris
        self._print(
486 ab863157 Stavros Sachtouris
            self.client.get_commission_info(commission_id), self.print_dict)
487 ab863157 Stavros Sachtouris
488 ab863157 Stavros Sachtouris
    def main(self, commission_id):
489 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
490 ab863157 Stavros Sachtouris
        self._run(commission_id)
491 ab863157 Stavros Sachtouris
492 ab863157 Stavros Sachtouris
493 25f9a991 Stavros Sachtouris
@command(commission_commands)
494 25f9a991 Stavros Sachtouris
class commission_accept(_init_synnefo_astakosclient):
495 ab863157 Stavros Sachtouris
    """Accept a pending commission  (special privileges required)"""
496 ab863157 Stavros Sachtouris
497 ab863157 Stavros Sachtouris
    @errors.generic.all
498 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
499 ab863157 Stavros Sachtouris
    def _run(self, commission_id):
500 ab863157 Stavros Sachtouris
        commission_id = int(commission_id)
501 ab863157 Stavros Sachtouris
        self.client.accept_commission(commission_id)
502 ab863157 Stavros Sachtouris
503 ab863157 Stavros Sachtouris
    def main(self, commission_id):
504 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
505 ab863157 Stavros Sachtouris
        self._run(commission_id)
506 ab863157 Stavros Sachtouris
507 ab863157 Stavros Sachtouris
508 25f9a991 Stavros Sachtouris
@command(commission_commands)
509 25f9a991 Stavros Sachtouris
class commission_reject(_init_synnefo_astakosclient):
510 ab863157 Stavros Sachtouris
    """Reject a pending commission (special privileges required)"""
511 ab863157 Stavros Sachtouris
512 ab863157 Stavros Sachtouris
    @errors.generic.all
513 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
514 ab863157 Stavros Sachtouris
    def _run(self, commission_id):
515 ab863157 Stavros Sachtouris
        commission_id = int(commission_id)
516 ab863157 Stavros Sachtouris
        self.client.reject_commission(commission_id)
517 ab863157 Stavros Sachtouris
518 ab863157 Stavros Sachtouris
    def main(self, commission_id):
519 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
520 ab863157 Stavros Sachtouris
        self._run(commission_id)
521 ab863157 Stavros Sachtouris
522 ab863157 Stavros Sachtouris
523 25f9a991 Stavros Sachtouris
@command(commission_commands)
524 25f9a991 Stavros Sachtouris
class commission_resolve(_init_synnefo_astakosclient, _optional_json):
525 ab863157 Stavros Sachtouris
    """Resolve multiple commissions (special privileges required)"""
526 ab863157 Stavros Sachtouris
527 ab863157 Stavros Sachtouris
    arguments = dict(
528 ab863157 Stavros Sachtouris
        accept=CommaSeparatedListArgument(
529 ab863157 Stavros Sachtouris
            'commission ids to accept (e.g., --accept=11,12,13,...',
530 ab863157 Stavros Sachtouris
            '--accept'),
531 ab863157 Stavros Sachtouris
        reject=CommaSeparatedListArgument(
532 ab863157 Stavros Sachtouris
            'commission ids to reject (e.g., --reject=11,12,13,...',
533 ab863157 Stavros Sachtouris
            '--reject')
534 ab863157 Stavros Sachtouris
    )
535 ab863157 Stavros Sachtouris
536 ab863157 Stavros Sachtouris
    @errors.generic.all
537 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
538 ab863157 Stavros Sachtouris
    def _run(self):
539 ab863157 Stavros Sachtouris
        self.writeln('accepted ', self['accept'])
540 ab863157 Stavros Sachtouris
        self.writeln('rejected ', self['reject'])
541 ab863157 Stavros Sachtouris
        self._print(
542 ab863157 Stavros Sachtouris
            self.client.resolve_commissions(self['accept'], self['reject']),
543 ab863157 Stavros Sachtouris
            self.print_dict)
544 ab863157 Stavros Sachtouris
545 ab863157 Stavros Sachtouris
    def main(self):
546 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
547 ab863157 Stavros Sachtouris
        self._run()
548 ab863157 Stavros Sachtouris
549 ab863157 Stavros Sachtouris
550 25f9a991 Stavros Sachtouris
@command(commission_commands)
551 25f9a991 Stavros Sachtouris
class commission_issue(_init_synnefo_astakosclient, _optional_json):
552 ab863157 Stavros Sachtouris
    """Issue commissions as a json string (special privileges required)
553 ab863157 Stavros Sachtouris
    Parameters:
554 ab863157 Stavros Sachtouris
    holder      -- user's id (string)
555 ab863157 Stavros Sachtouris
    source      -- commission's source (ex system) (string)
556 ab863157 Stavros Sachtouris
    provisions  -- resources with their quantity (json-dict from string to int)
557 ab863157 Stavros Sachtouris
    name        -- description of the commission (string)
558 ab863157 Stavros Sachtouris
    """
559 ab863157 Stavros Sachtouris
560 ab863157 Stavros Sachtouris
    arguments = dict(
561 ab863157 Stavros Sachtouris
        force=FlagArgument('Force commission', '--force'),
562 ab863157 Stavros Sachtouris
        accept=FlagArgument('Do not wait for verification', '--accept')
563 ab863157 Stavros Sachtouris
    )
564 ab863157 Stavros Sachtouris
565 ab863157 Stavros Sachtouris
    @errors.generic.all
566 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
567 ab863157 Stavros Sachtouris
    def _run(self, holder, source, provisions, name=''):
568 ab863157 Stavros Sachtouris
        provisions = loads(provisions)
569 ab863157 Stavros Sachtouris
        self._print(self.client.issue_one_commission(
570 ab863157 Stavros Sachtouris
            holder, source, provisions, name,
571 ab863157 Stavros Sachtouris
            self['force'], self['accept']))
572 ab863157 Stavros Sachtouris
573 ab863157 Stavros Sachtouris
    def main(self, user_uuid, source, provisions_file, name=''):
574 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
575 ab863157 Stavros Sachtouris
        self._run(user_uuid, source, provisions_file, name)
576 ab863157 Stavros Sachtouris
577 ab863157 Stavros Sachtouris
578 25f9a991 Stavros Sachtouris
@command(resource_commands)
579 25f9a991 Stavros Sachtouris
class resource_list(_init_synnefo_astakosclient, _optional_json):
580 ab863157 Stavros Sachtouris
    """List user resources"""
581 ab863157 Stavros Sachtouris
582 ab863157 Stavros Sachtouris
    @errors.generic.all
583 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
584 ab863157 Stavros Sachtouris
    def _run(self):
585 ab863157 Stavros Sachtouris
        self._print(self.client.get_resources(), self.print_dict)
586 ab863157 Stavros Sachtouris
587 ab863157 Stavros Sachtouris
    def main(self):
588 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
589 ab863157 Stavros Sachtouris
        self._run()
590 ab863157 Stavros Sachtouris
591 ab863157 Stavros Sachtouris
592 25f9a991 Stavros Sachtouris
@command(endpoint_commands)
593 ad696342 Stavros Sachtouris
class endpoint_list(
594 ad696342 Stavros Sachtouris
        _init_synnefo_astakosclient, _optional_json, _name_filter):
595 ab863157 Stavros Sachtouris
    """Get endpoints service endpoints"""
596 ab863157 Stavros Sachtouris
597 ad696342 Stavros Sachtouris
    arguments = dict(endpoint_type=ValueArgument('Filter by type', '--type'))
598 ad696342 Stavros Sachtouris
599 ab863157 Stavros Sachtouris
    @errors.generic.all
600 ab863157 Stavros Sachtouris
    @errors.user.astakosclient
601 ab863157 Stavros Sachtouris
    def _run(self):
602 ad696342 Stavros Sachtouris
        r = self.client.get_endpoints()['access']['serviceCatalog']
603 ad696342 Stavros Sachtouris
        r = self._filter_by_name(r)
604 ad696342 Stavros Sachtouris
        if self['endpoint_type']:
605 ad696342 Stavros Sachtouris
            r = filter_dicts_by_dict(r, dict(type=self['endpoint_type']))
606 ad696342 Stavros Sachtouris
        self._print(r)
607 ab863157 Stavros Sachtouris
608 ab863157 Stavros Sachtouris
    def main(self):
609 ab863157 Stavros Sachtouris
        super(self.__class__, self)._run()
610 ab863157 Stavros Sachtouris
        self._run()
611 ab863157 Stavros Sachtouris
612 ab863157 Stavros Sachtouris
613 c308d73f Stavros Sachtouris
#  command project
614 c308d73f Stavros Sachtouris
615 c308d73f Stavros Sachtouris
616 6893e31c Stavros Sachtouris
_project_specs = """{
617 6893e31c Stavros Sachtouris
    "name": name,
618 b101d9e5 Stavros Sachtouris
    "owner": uuid,  # if omitted, request user assumed
619 b101d9e5 Stavros Sachtouris
    "homepage": homepage,  # optional
620 b101d9e5 Stavros Sachtouris
    "description": description,  # optional
621 b101d9e5 Stavros Sachtouris
    "comments": comments,  # optional
622 4573f225 Stavros Sachtouris
    "max_members": max_members,  # optional
623 4573f225 Stavros Sachtouris
    "private": true | false,  # optional
624 b101d9e5 Stavros Sachtouris
    "start_date": date,  # optional
625 6893e31c Stavros Sachtouris
    "end_date": date,
626 6893e31c Stavros Sachtouris
    "join_policy": "auto" | "moderated" | "closed",  # default: "moderated"
627 b101d9e5 Stavros Sachtouris
    "leave_policy": "auto" | "moderated" | "closed",  # default: "auto"
628 b101d9e5 Stavros Sachtouris
    "resources": {
629 b101d9e5 Stavros Sachtouris
    "cyclades.vm": {"project_capacity": int, "member_capacity": int
630 b101d9e5 Stavros Sachtouris
    }}}"""
631 c308d73f Stavros Sachtouris
632 c308d73f Stavros Sachtouris
633 392d902d Stavros Sachtouris
def apply_notification(func):
634 c308d73f Stavros Sachtouris
    def wrap(self, *args, **kwargs):
635 392d902d Stavros Sachtouris
        r = func(self, *args, **kwargs)
636 c308d73f Stavros Sachtouris
        self.writeln('Application is submitted successfully')
637 c308d73f Stavros Sachtouris
        return r
638 c308d73f Stavros Sachtouris
    return wrap
639 c308d73f Stavros Sachtouris
640 c308d73f Stavros Sachtouris
641 c308d73f Stavros Sachtouris
@command(project_commands)
642 c308d73f Stavros Sachtouris
class project_list(_init_synnefo_astakosclient, _optional_json):
643 c308d73f Stavros Sachtouris
    """List all projects"""
644 c308d73f Stavros Sachtouris
645 c308d73f Stavros Sachtouris
    arguments = dict(
646 95f1b265 Stavros Sachtouris
        details=FlagArgument('Show details', ('-l', '--details')),
647 c308d73f Stavros Sachtouris
        name=ValueArgument('Filter by name', ('--with-name', )),
648 c308d73f Stavros Sachtouris
        state=ValueArgument('Filter by state', ('--with-state', )),
649 c308d73f Stavros Sachtouris
        owner=ValueArgument('Filter by owner', ('--with-owner', ))
650 c308d73f Stavros Sachtouris
    )
651 c308d73f Stavros Sachtouris
652 c308d73f Stavros Sachtouris
    @errors.generic.all
653 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
654 c308d73f Stavros Sachtouris
    def _run(self):
655 95f1b265 Stavros Sachtouris
        r = self.client.get_projects(
656 95f1b265 Stavros Sachtouris
            self['name'], self['state'], self['owner'])
657 95f1b265 Stavros Sachtouris
        if not (self['details'] or self['output_format']):
658 95f1b265 Stavros Sachtouris
            r = [dict(
659 95f1b265 Stavros Sachtouris
                id=i['id'],
660 95f1b265 Stavros Sachtouris
                name=i['name'],
661 95f1b265 Stavros Sachtouris
                description=i['description']) for i in r]
662 95f1b265 Stavros Sachtouris
        self._print(r)
663 c308d73f Stavros Sachtouris
664 c308d73f Stavros Sachtouris
    def main(self):
665 c308d73f Stavros Sachtouris
        super(self.__class__, self)._run()
666 c308d73f Stavros Sachtouris
        self._run()
667 c308d73f Stavros Sachtouris
668 c308d73f Stavros Sachtouris
669 c308d73f Stavros Sachtouris
@command(project_commands)
670 c308d73f Stavros Sachtouris
class project_info(_init_synnefo_astakosclient, _optional_json):
671 c308d73f Stavros Sachtouris
    """Get details for a project"""
672 c308d73f Stavros Sachtouris
673 c308d73f Stavros Sachtouris
    @errors.generic.all
674 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
675 c308d73f Stavros Sachtouris
    def _run(self, project_id):
676 c308d73f Stavros Sachtouris
        self._print(
677 c308d73f Stavros Sachtouris
            self.client.get_project(project_id), self.print_dict)
678 c308d73f Stavros Sachtouris
679 c308d73f Stavros Sachtouris
    def main(self, project_id):
680 c308d73f Stavros Sachtouris
        super(self.__class__, self)._run()
681 c308d73f Stavros Sachtouris
        self._run(project_id)
682 c308d73f Stavros Sachtouris
683 c308d73f Stavros Sachtouris
684 b101d9e5 Stavros Sachtouris
class PolicyArgument(ValueArgument):
685 b101d9e5 Stavros Sachtouris
    """A Policy argument"""
686 b101d9e5 Stavros Sachtouris
    policies = ('auto', 'moderated', 'closed')
687 b101d9e5 Stavros Sachtouris
688 b101d9e5 Stavros Sachtouris
    @property
689 b101d9e5 Stavros Sachtouris
    def value(self):
690 b101d9e5 Stavros Sachtouris
        return getattr(self, '_value', None)
691 b101d9e5 Stavros Sachtouris
692 b101d9e5 Stavros Sachtouris
    @value.setter
693 b101d9e5 Stavros Sachtouris
    def value(self, new_policy):
694 b101d9e5 Stavros Sachtouris
        if new_policy:
695 b101d9e5 Stavros Sachtouris
            if new_policy.lower() in self.policies:
696 b101d9e5 Stavros Sachtouris
                self._value = new_policy.lower()
697 b101d9e5 Stavros Sachtouris
            else:
698 b101d9e5 Stavros Sachtouris
                raise CLIInvalidArgument(
699 b101d9e5 Stavros Sachtouris
                    'Invalid value for %s' % self.lvalue, details=[
700 b101d9e5 Stavros Sachtouris
                    'Valid values: %s' % ', '.join(self.policies)])
701 b101d9e5 Stavros Sachtouris
702 b101d9e5 Stavros Sachtouris
703 b101d9e5 Stavros Sachtouris
class ProjectResourceArgument(KeyValueArgument):
704 b101d9e5 Stavros Sachtouris
    """"A <resource>=<member_capacity>,<project_capacity> argument  e.g.,
705 4573f225 Stavros Sachtouris
    --resource cyclades.cpu=5,1
706 4573f225 Stavros Sachtouris
    """
707 b101d9e5 Stavros Sachtouris
    @property
708 b101d9e5 Stavros Sachtouris
    def value(self):
709 b101d9e5 Stavros Sachtouris
        return super(ProjectResourceArgument, self).value
710 b101d9e5 Stavros Sachtouris
711 b101d9e5 Stavros Sachtouris
    @value.setter
712 b101d9e5 Stavros Sachtouris
    def value(self, key_value_pairs):
713 b101d9e5 Stavros Sachtouris
        if key_value_pairs:
714 b101d9e5 Stavros Sachtouris
            super(ProjectResourceArgument, self.__class__).value.fset(
715 b101d9e5 Stavros Sachtouris
                self, key_value_pairs)
716 b101d9e5 Stavros Sachtouris
            d = dict(self._value)
717 b101d9e5 Stavros Sachtouris
            for key, value in d.items():
718 b101d9e5 Stavros Sachtouris
                try:
719 b101d9e5 Stavros Sachtouris
                    member_capacity, project_capacity = value.split(',')
720 b101d9e5 Stavros Sachtouris
                    member_capacity = int(member_capacity)
721 b101d9e5 Stavros Sachtouris
                    project_capacity = int(project_capacity)
722 b101d9e5 Stavros Sachtouris
                    assert member_capacity <= project_capacity
723 b101d9e5 Stavros Sachtouris
                except Exception as e:
724 b101d9e5 Stavros Sachtouris
                    raise CLIInvalidArgument(
725 b101d9e5 Stavros Sachtouris
                        'Invalid resource value %s' % value, details=[
726 b101d9e5 Stavros Sachtouris
                        'Usage:',
727 b101d9e5 Stavros Sachtouris
                        '  %s %s=<member_capacity>,<project_capacity>' % (
728 b101d9e5 Stavros Sachtouris
                            self.lvalue, key),
729 b101d9e5 Stavros Sachtouris
                        'where both capacities are integers',
730 b101d9e5 Stavros Sachtouris
                        'and member_capacity <= project_capacity', '',
731 b101d9e5 Stavros Sachtouris
                        '(%s)' % e])
732 b101d9e5 Stavros Sachtouris
                self._value[key] = dict(
733 b101d9e5 Stavros Sachtouris
                    member_capacity=member_capacity,
734 b101d9e5 Stavros Sachtouris
                    project_capacity=project_capacity)
735 b101d9e5 Stavros Sachtouris
736 b101d9e5 Stavros Sachtouris
737 c308d73f Stavros Sachtouris
@command(project_commands)
738 c308d73f Stavros Sachtouris
class project_create(_init_synnefo_astakosclient, _optional_json):
739 b101d9e5 Stavros Sachtouris
    """Apply for a new project"""
740 c308d73f Stavros Sachtouris
741 c308d73f Stavros Sachtouris
    arguments = dict(
742 c308d73f Stavros Sachtouris
        specs_path=ValueArgument(
743 b101d9e5 Stavros Sachtouris
            'Specification file (contents in json)', '--spec-file'),
744 b101d9e5 Stavros Sachtouris
        project_name=ValueArgument('Name the project', '--name'),
745 b101d9e5 Stavros Sachtouris
        owner_uuid=ValueArgument('Project owner', '--owner'),
746 b101d9e5 Stavros Sachtouris
        homepage_url=ValueArgument('Project homepage', '--homepage'),
747 b101d9e5 Stavros Sachtouris
        description=ValueArgument('Describe the project', '--description'),
748 4573f225 Stavros Sachtouris
        max_members=IntArgument('Maximum subscribers', '--max-members'),
749 4573f225 Stavros Sachtouris
        private=FlagArgument('Set if the project is private', '--private'),
750 b101d9e5 Stavros Sachtouris
        start_date=DateArgument('When to start the project', '--start-date'),
751 b101d9e5 Stavros Sachtouris
        end_date=DateArgument('When to end the project', '--end-date'),
752 b101d9e5 Stavros Sachtouris
        join_policy=PolicyArgument(
753 b101d9e5 Stavros Sachtouris
            'Set join policy (%s)' % ', '.join(PolicyArgument.policies),
754 b101d9e5 Stavros Sachtouris
            '--join-policy'),
755 b101d9e5 Stavros Sachtouris
        leave_policy=PolicyArgument(
756 b101d9e5 Stavros Sachtouris
            'Set leave policy (%s)' % ', '.join(PolicyArgument.policies),
757 b101d9e5 Stavros Sachtouris
            '--leave-policy'),
758 b101d9e5 Stavros Sachtouris
        resource_capacities=ProjectResourceArgument(
759 b101d9e5 Stavros Sachtouris
            'Set the member and project capacities for resources (repeatable) '
760 b101d9e5 Stavros Sachtouris
            'e.g., --resource cyclades.cpu=1,5    means "members will have at '
761 b101d9e5 Stavros Sachtouris
            'most 1 cpu but the project will have at most 5"       To see all '
762 b101d9e5 Stavros Sachtouris
            'resources:   kamaki resource list',
763 b101d9e5 Stavros Sachtouris
            '--resource')
764 c308d73f Stavros Sachtouris
    )
765 b101d9e5 Stavros Sachtouris
    required = ['specs_path', 'project_name', 'end_date']
766 c308d73f Stavros Sachtouris
767 c308d73f Stavros Sachtouris
    @errors.generic.all
768 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
769 c308d73f Stavros Sachtouris
    @apply_notification
770 c308d73f Stavros Sachtouris
    def _run(self):
771 b101d9e5 Stavros Sachtouris
        specs = dict()
772 b101d9e5 Stavros Sachtouris
        if self['specs_path']:
773 b101d9e5 Stavros Sachtouris
            with open(abspath(self['specs_path'])) as f:
774 b101d9e5 Stavros Sachtouris
                specs = load(f)
775 b101d9e5 Stavros Sachtouris
        for key, arg in (
776 b101d9e5 Stavros Sachtouris
                ('name', self['project_name']),
777 b101d9e5 Stavros Sachtouris
                ('owner', self['owner_uuid']),
778 b101d9e5 Stavros Sachtouris
                ('homepage', self['homepage_url']),
779 b101d9e5 Stavros Sachtouris
                ('description', self['description']),
780 4573f225 Stavros Sachtouris
                ('max_members', self['max_members']),
781 4573f225 Stavros Sachtouris
                ('private', self['private']),
782 b101d9e5 Stavros Sachtouris
                ('start_date', self['start_date']),
783 b101d9e5 Stavros Sachtouris
                ('end_date', self['end_date']),
784 b101d9e5 Stavros Sachtouris
                ('join_policy', self['join_policy']),
785 b101d9e5 Stavros Sachtouris
                ('leave_policy', self['leave_policy']),
786 b101d9e5 Stavros Sachtouris
                ('resources', self['resource_capacities'])):
787 b101d9e5 Stavros Sachtouris
            if arg:
788 b101d9e5 Stavros Sachtouris
                specs[key] = arg
789 b101d9e5 Stavros Sachtouris
790 b101d9e5 Stavros Sachtouris
        self._print(self.client.create_project(specs), self.print_dict)
791 c308d73f Stavros Sachtouris
792 c308d73f Stavros Sachtouris
    def main(self):
793 c308d73f Stavros Sachtouris
        super(self.__class__, self)._run()
794 b101d9e5 Stavros Sachtouris
        self._req2 = [arg for arg in self.required if arg != 'specs_path']
795 b101d9e5 Stavros Sachtouris
        if not (self['specs_path'] or all(self[arg] for arg in self._req2)):
796 b101d9e5 Stavros Sachtouris
            raise CLIInvalidArgument('Insufficient arguments', details=[
797 b101d9e5 Stavros Sachtouris
                'Both of the following arguments are needed:',
798 b101d9e5 Stavros Sachtouris
                ', '.join([self.arguments[arg].lvalue for arg in self._req2]),
799 b101d9e5 Stavros Sachtouris
                'OR provide a spec file (json) with %s' % self.arguments[
800 b101d9e5 Stavros Sachtouris
                    'specs_path'].lvalue,
801 b101d9e5 Stavros Sachtouris
                'OR combine arguments (higher priority) with a file'])
802 c308d73f Stavros Sachtouris
        self._run()
803 c308d73f Stavros Sachtouris
804 c308d73f Stavros Sachtouris
805 c308d73f Stavros Sachtouris
@command(project_commands)
806 c308d73f Stavros Sachtouris
class project_modify(_init_synnefo_astakosclient, _optional_json):
807 4573f225 Stavros Sachtouris
    """Modify properties of a project"""
808 c308d73f Stavros Sachtouris
809 c308d73f Stavros Sachtouris
    __doc__ += _project_specs
810 c308d73f Stavros Sachtouris
811 c308d73f Stavros Sachtouris
    arguments = dict(
812 c308d73f Stavros Sachtouris
        specs_path=ValueArgument(
813 6755b804 Stavros Sachtouris
            'Specification file (contents in json)', '--spec-file'),
814 6755b804 Stavros Sachtouris
        project_name=ValueArgument('Name the project', '--name'),
815 6755b804 Stavros Sachtouris
        owner_uuid=ValueArgument('Project owner', '--owner'),
816 6755b804 Stavros Sachtouris
        homepage_url=ValueArgument('Project homepage', '--homepage'),
817 6755b804 Stavros Sachtouris
        description=ValueArgument('Describe the project', '--description'),
818 4573f225 Stavros Sachtouris
        max_members=IntArgument('Maximum subscribers', '--max-members'),
819 4573f225 Stavros Sachtouris
        private=FlagArgument('Set if the project is private', '--private'),
820 6755b804 Stavros Sachtouris
        start_date=DateArgument('When to start the project', '--start-date'),
821 6755b804 Stavros Sachtouris
        end_date=DateArgument('When to end the project', '--end-date'),
822 6755b804 Stavros Sachtouris
        join_policy=PolicyArgument(
823 6755b804 Stavros Sachtouris
            'Set join policy (%s)' % ', '.join(PolicyArgument.policies),
824 6755b804 Stavros Sachtouris
            '--join-policy'),
825 6755b804 Stavros Sachtouris
        leave_policy=PolicyArgument(
826 6755b804 Stavros Sachtouris
            'Set leave policy (%s)' % ', '.join(PolicyArgument.policies),
827 6755b804 Stavros Sachtouris
            '--leave-policy'),
828 6755b804 Stavros Sachtouris
        resource_capacities=ProjectResourceArgument(
829 6755b804 Stavros Sachtouris
            'Set the member and project capacities for resources (repeatable) '
830 6755b804 Stavros Sachtouris
            'e.g., --resource cyclades.cpu=1,5    means "members will have at '
831 6755b804 Stavros Sachtouris
            'most 1 cpu but the project will have at most 5"       To see all '
832 6755b804 Stavros Sachtouris
            'resources:   kamaki resource list',
833 6755b804 Stavros Sachtouris
            '--resource')
834 c308d73f Stavros Sachtouris
    )
835 6755b804 Stavros Sachtouris
    required = [
836 6755b804 Stavros Sachtouris
        'specs_path', 'owner_uuid', 'homepage_url', 'description',
837 6755b804 Stavros Sachtouris
        'project_name', 'start_date', 'end_date', 'join_policy',
838 4573f225 Stavros Sachtouris
        'leave_policy', 'resource_capacities', 'max_members', 'private']
839 c308d73f Stavros Sachtouris
840 c308d73f Stavros Sachtouris
    @errors.generic.all
841 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
842 c308d73f Stavros Sachtouris
    @apply_notification
843 c308d73f Stavros Sachtouris
    def _run(self, project_id):
844 6755b804 Stavros Sachtouris
        specs = dict()
845 6755b804 Stavros Sachtouris
        if self['specs_path']:
846 6755b804 Stavros Sachtouris
            with open(abspath(self['specs_path'])) as f:
847 6755b804 Stavros Sachtouris
                specs = load(f)
848 6755b804 Stavros Sachtouris
        for key, arg in (
849 6755b804 Stavros Sachtouris
                ('name', self['project_name']),
850 6755b804 Stavros Sachtouris
                ('owner', self['owner_uuid']),
851 6755b804 Stavros Sachtouris
                ('homepage', self['homepage_url']),
852 6755b804 Stavros Sachtouris
                ('description', self['description']),
853 4573f225 Stavros Sachtouris
                ('max_members', self['max_members']),
854 4573f225 Stavros Sachtouris
                ('private', self['private']),
855 6755b804 Stavros Sachtouris
                ('start_date', self['start_date']),
856 6755b804 Stavros Sachtouris
                ('end_date', self['end_date']),
857 6755b804 Stavros Sachtouris
                ('join_policy', self['join_policy']),
858 6755b804 Stavros Sachtouris
                ('leave_policy', self['leave_policy']),
859 6755b804 Stavros Sachtouris
                ('resources', self['resource_capacities'])):
860 6755b804 Stavros Sachtouris
            if arg:
861 6755b804 Stavros Sachtouris
                specs[key] = arg
862 6755b804 Stavros Sachtouris
863 c308d73f Stavros Sachtouris
        self._print(
864 6755b804 Stavros Sachtouris
            self.client.modify_project(project_id, specs), self.print_dict)
865 c308d73f Stavros Sachtouris
866 c308d73f Stavros Sachtouris
    def main(self, project_id):
867 c308d73f Stavros Sachtouris
        super(self.__class__, self)._run()
868 c308d73f Stavros Sachtouris
        self._run(project_id)
869 c308d73f Stavros Sachtouris
870 c308d73f Stavros Sachtouris
871 c308d73f Stavros Sachtouris
class _project_action(_init_synnefo_astakosclient):
872 c308d73f Stavros Sachtouris
873 c308d73f Stavros Sachtouris
    action = ''
874 c308d73f Stavros Sachtouris
875 95f1b265 Stavros Sachtouris
    arguments = dict(
876 95f1b265 Stavros Sachtouris
        reason=ValueArgument('Quote a reason for this action', '--reason'),
877 95f1b265 Stavros Sachtouris
    )
878 95f1b265 Stavros Sachtouris
879 c308d73f Stavros Sachtouris
    @errors.generic.all
880 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
881 c308d73f Stavros Sachtouris
    def _run(self, project_id, quote_a_reason):
882 c308d73f Stavros Sachtouris
        self.client.project_action(project_id, self.action, quote_a_reason)
883 c308d73f Stavros Sachtouris
884 95f1b265 Stavros Sachtouris
    def main(self, project_id):
885 c308d73f Stavros Sachtouris
        super(_project_action, self)._run()
886 95f1b265 Stavros Sachtouris
        self._run(project_id, self['reason'] or '')
887 c308d73f Stavros Sachtouris
888 c308d73f Stavros Sachtouris
889 c308d73f Stavros Sachtouris
@command(project_commands)
890 c308d73f Stavros Sachtouris
class project_suspend(_project_action):
891 c308d73f Stavros Sachtouris
    """Suspend a project (special privileges needed)"""
892 c308d73f Stavros Sachtouris
    action = 'suspend'
893 c308d73f Stavros Sachtouris
894 c308d73f Stavros Sachtouris
895 c308d73f Stavros Sachtouris
@command(project_commands)
896 c308d73f Stavros Sachtouris
class project_unsuspend(_project_action):
897 c308d73f Stavros Sachtouris
    """Resume a suspended project (special privileges needed)"""
898 c308d73f Stavros Sachtouris
    action = 'unsuspend'
899 c308d73f Stavros Sachtouris
900 c308d73f Stavros Sachtouris
901 c308d73f Stavros Sachtouris
@command(project_commands)
902 c308d73f Stavros Sachtouris
class project_terminate(_project_action):
903 c308d73f Stavros Sachtouris
    """Terminate a project (special privileges needed)"""
904 c308d73f Stavros Sachtouris
    action = 'terminate'
905 c308d73f Stavros Sachtouris
906 c308d73f Stavros Sachtouris
907 c308d73f Stavros Sachtouris
@command(project_commands)
908 c308d73f Stavros Sachtouris
class project_reinstate(_project_action):
909 c308d73f Stavros Sachtouris
    """Reinstate a terminated project (special privileges needed)"""
910 c308d73f Stavros Sachtouris
    action = 'reinstate'
911 c308d73f Stavros Sachtouris
912 c308d73f Stavros Sachtouris
913 95f1b265 Stavros Sachtouris
class _application_action(_init_synnefo_astakosclient):
914 c308d73f Stavros Sachtouris
915 95f1b265 Stavros Sachtouris
    action = ''
916 c308d73f Stavros Sachtouris
917 c308d73f Stavros Sachtouris
    arguments = dict(
918 95f1b265 Stavros Sachtouris
        app_id=ValueArgument('The application ID', '--app-id'),
919 95f1b265 Stavros Sachtouris
        reason=ValueArgument('Quote a reason for this action', '--reason'),
920 c308d73f Stavros Sachtouris
    )
921 95f1b265 Stavros Sachtouris
    required = ('app_id', )
922 c308d73f Stavros Sachtouris
923 c308d73f Stavros Sachtouris
    @errors.generic.all
924 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
925 95f1b265 Stavros Sachtouris
    def _run(self, project_id, app_id, quote_a_reason):
926 95f1b265 Stavros Sachtouris
        self.client.application_action(
927 95f1b265 Stavros Sachtouris
            project_id, app_id, self.action, quote_a_reason)
928 c308d73f Stavros Sachtouris
929 95f1b265 Stavros Sachtouris
    def main(self, project_id):
930 c308d73f Stavros Sachtouris
        super(_application_action, self)._run()
931 dbe345ac Stavros Sachtouris
        self._run(project_id, self['app_id'], self['reason'] or '')
932 c308d73f Stavros Sachtouris
933 c308d73f Stavros Sachtouris
934 c308d73f Stavros Sachtouris
@command(project_commands)
935 95f1b265 Stavros Sachtouris
class project_approve(_application_action):
936 c308d73f Stavros Sachtouris
    """Approve an application (special privileges needed)"""
937 c308d73f Stavros Sachtouris
    action = 'approve'
938 c308d73f Stavros Sachtouris
939 c308d73f Stavros Sachtouris
940 c308d73f Stavros Sachtouris
@command(project_commands)
941 95f1b265 Stavros Sachtouris
class project_deny(_application_action):
942 c308d73f Stavros Sachtouris
    """Deny an application (special privileges needed)"""
943 c308d73f Stavros Sachtouris
    action = 'deny'
944 c308d73f Stavros Sachtouris
945 c308d73f Stavros Sachtouris
946 c308d73f Stavros Sachtouris
@command(project_commands)
947 95f1b265 Stavros Sachtouris
class project_dismiss(_application_action):
948 c308d73f Stavros Sachtouris
    """Dismiss your denied application"""
949 c308d73f Stavros Sachtouris
    action = 'dismiss'
950 c308d73f Stavros Sachtouris
951 c308d73f Stavros Sachtouris
952 c308d73f Stavros Sachtouris
@command(project_commands)
953 95f1b265 Stavros Sachtouris
class project_cancel(_application_action):
954 c308d73f Stavros Sachtouris
    """Cancel your application"""
955 c308d73f Stavros Sachtouris
    action = 'cancel'
956 c308d73f Stavros Sachtouris
957 c308d73f Stavros Sachtouris
958 9d84caa4 Stavros Sachtouris
@command(membership_commands)
959 9d84caa4 Stavros Sachtouris
class membership(_init_synnefo_astakosclient):
960 c308d73f Stavros Sachtouris
    """Project membership management commands"""
961 c308d73f Stavros Sachtouris
962 c308d73f Stavros Sachtouris
963 9d84caa4 Stavros Sachtouris
@command(membership_commands)
964 9d84caa4 Stavros Sachtouris
class membership_list(_init_synnefo_astakosclient, _optional_json):
965 c308d73f Stavros Sachtouris
    """List all memberships"""
966 c308d73f Stavros Sachtouris
967 c308d73f Stavros Sachtouris
    arguments = dict(
968 4573f225 Stavros Sachtouris
        project=IntArgument('Filter by project id', '--project-id')
969 c308d73f Stavros Sachtouris
    )
970 c308d73f Stavros Sachtouris
971 c308d73f Stavros Sachtouris
    @errors.generic.all
972 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
973 c308d73f Stavros Sachtouris
    def _run(self):
974 c308d73f Stavros Sachtouris
        self._print(self.client.get_memberships(self['project']))
975 c308d73f Stavros Sachtouris
976 c308d73f Stavros Sachtouris
    def main(self):
977 c308d73f Stavros Sachtouris
        super(self.__class__, self)._run()
978 c308d73f Stavros Sachtouris
        self._run()
979 c308d73f Stavros Sachtouris
980 c308d73f Stavros Sachtouris
981 9d84caa4 Stavros Sachtouris
@command(membership_commands)
982 9d84caa4 Stavros Sachtouris
class membership_info(_init_synnefo_astakosclient, _optional_json):
983 c308d73f Stavros Sachtouris
    """Details on a membership"""
984 c308d73f Stavros Sachtouris
985 c308d73f Stavros Sachtouris
    @errors.generic.all
986 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
987 c308d73f Stavros Sachtouris
    def _run(self, memb_id):
988 c308d73f Stavros Sachtouris
        self._print(
989 c308d73f Stavros Sachtouris
            self.client.get_membership(memb_id), self.print_dict)
990 c308d73f Stavros Sachtouris
991 c308d73f Stavros Sachtouris
    def main(self, membership_id):
992 c308d73f Stavros Sachtouris
        super(self.__class__, self)._run()
993 4573f225 Stavros Sachtouris
        self._run(memb_id=membership_id)
994 c308d73f Stavros Sachtouris
995 c308d73f Stavros Sachtouris
996 c308d73f Stavros Sachtouris
class _membership_action(_init_synnefo_astakosclient, _optional_json):
997 c308d73f Stavros Sachtouris
998 c308d73f Stavros Sachtouris
    action = ''
999 4573f225 Stavros Sachtouris
    arguments = dict(reason=ValueArgument('Reason for the action', '--reason'))
1000 c308d73f Stavros Sachtouris
1001 c308d73f Stavros Sachtouris
    @errors.generic.all
1002 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
1003 c308d73f Stavros Sachtouris
    def _run(self, memb_id, quote_a_reason):
1004 c308d73f Stavros Sachtouris
        self._print(self.client.membership_action(
1005 c308d73f Stavros Sachtouris
            memb_id, self.action, quote_a_reason))
1006 c308d73f Stavros Sachtouris
1007 4573f225 Stavros Sachtouris
    def main(self, membership_id):
1008 c308d73f Stavros Sachtouris
        super(_membership_action, self)._run()
1009 4573f225 Stavros Sachtouris
        self._run(membership_id, self['reason'] or '')
1010 c308d73f Stavros Sachtouris
1011 c308d73f Stavros Sachtouris
1012 9d84caa4 Stavros Sachtouris
@command(membership_commands)
1013 9d84caa4 Stavros Sachtouris
class membership_leave(_membership_action):
1014 c308d73f Stavros Sachtouris
    """Leave a project you have membership to"""
1015 c308d73f Stavros Sachtouris
    action = 'leave'
1016 c308d73f Stavros Sachtouris
1017 c308d73f Stavros Sachtouris
1018 9d84caa4 Stavros Sachtouris
@command(membership_commands)
1019 9d84caa4 Stavros Sachtouris
class membership_cancel(_membership_action):
1020 c308d73f Stavros Sachtouris
    """Cancel your (probably pending) membership to a project"""
1021 c308d73f Stavros Sachtouris
    action = 'cancel'
1022 c308d73f Stavros Sachtouris
1023 c308d73f Stavros Sachtouris
1024 9d84caa4 Stavros Sachtouris
@command(membership_commands)
1025 9d84caa4 Stavros Sachtouris
class membership_accept(_membership_action):
1026 c308d73f Stavros Sachtouris
    """Accept a membership for a project you manage"""
1027 c308d73f Stavros Sachtouris
    action = 'accept'
1028 c308d73f Stavros Sachtouris
1029 c308d73f Stavros Sachtouris
1030 9d84caa4 Stavros Sachtouris
@command(membership_commands)
1031 9d84caa4 Stavros Sachtouris
class membership_reject(_membership_action):
1032 c308d73f Stavros Sachtouris
    """Reject a membership for a project you manage"""
1033 c308d73f Stavros Sachtouris
    action = 'reject'
1034 c308d73f Stavros Sachtouris
1035 c308d73f Stavros Sachtouris
1036 9d84caa4 Stavros Sachtouris
@command(membership_commands)
1037 9d84caa4 Stavros Sachtouris
class membership_remove(_membership_action):
1038 c308d73f Stavros Sachtouris
    """Remove a membership for a project you manage"""
1039 c308d73f Stavros Sachtouris
    action = 'remove'
1040 c308d73f Stavros Sachtouris
1041 c308d73f Stavros Sachtouris
1042 4573f225 Stavros Sachtouris
@command(project_commands)
1043 4573f225 Stavros Sachtouris
class project_join(_init_synnefo_astakosclient):
1044 c308d73f Stavros Sachtouris
    """Join a project"""
1045 c308d73f Stavros Sachtouris
1046 c308d73f Stavros Sachtouris
    @errors.generic.all
1047 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
1048 c308d73f Stavros Sachtouris
    def _run(self, project_id):
1049 c308d73f Stavros Sachtouris
        self.writeln(self.client.join_project(project_id))
1050 c308d73f Stavros Sachtouris
1051 c308d73f Stavros Sachtouris
    def main(self, project_id):
1052 4573f225 Stavros Sachtouris
        super(project_join, self)._run()
1053 c308d73f Stavros Sachtouris
        self._run(project_id)
1054 c308d73f Stavros Sachtouris
1055 c308d73f Stavros Sachtouris
1056 4573f225 Stavros Sachtouris
@command(project_commands)
1057 4573f225 Stavros Sachtouris
class project_enroll(_init_synnefo_astakosclient):
1058 4573f225 Stavros Sachtouris
    """Enroll a user to a project"""
1059 4573f225 Stavros Sachtouris
1060 4573f225 Stavros Sachtouris
    arguments = dict(email=ValueArgument('User e-mail', '--email'))
1061 4573f225 Stavros Sachtouris
    required = ('email', )
1062 c308d73f Stavros Sachtouris
1063 c308d73f Stavros Sachtouris
    @errors.generic.all
1064 c308d73f Stavros Sachtouris
    @errors.user.astakosclient
1065 c308d73f Stavros Sachtouris
    def _run(self, project_id, email):
1066 c308d73f Stavros Sachtouris
        self.writeln(self.client.enroll_member(project_id, email))
1067 c308d73f Stavros Sachtouris
1068 4573f225 Stavros Sachtouris
    def main(self, project_id):
1069 4573f225 Stavros Sachtouris
        super(project_enroll, self)._run()
1070 4573f225 Stavros Sachtouris
        self._run(project_id, self['email'])