Revision b4f69041
b/kamaki/cli/commands/__init__.py | ||
---|---|---|
38 | 38 |
log = get_logger(__name__) |
39 | 39 |
|
40 | 40 |
|
41 |
def DontRaiseKeyError(foo): |
|
42 |
def wrap(*args, **kwargs): |
|
43 |
try: |
|
44 |
return foo(*args, **kwargs) |
|
45 |
except KeyError: |
|
46 |
return None |
|
47 |
return wrap |
|
48 |
|
|
49 |
|
|
50 |
def addLogSettings(foo): |
|
51 |
def wrap(self, *args, **kwargs): |
|
52 |
try: |
|
53 |
return foo(self, *args, **kwargs) |
|
54 |
finally: |
|
55 |
self._set_log_params() |
|
56 |
self._update_max_threads |
|
57 |
return wrap |
|
58 |
|
|
59 |
|
|
41 | 60 |
class _command_init(object): |
42 | 61 |
|
43 | 62 |
def __init__(self, arguments={}, auth_base=None, cloud=None): |
... | ... | |
55 | 74 |
self.auth_base = auth_base or getattr(self, 'auth_base', None) |
56 | 75 |
self.cloud = cloud or getattr(self, 'cloud', None) |
57 | 76 |
|
77 |
@DontRaiseKeyError |
|
78 |
def _custom_url(self, service): |
|
79 |
return self.config.get_remote(self.cloud, '%s_url' % service) |
|
80 |
|
|
81 |
@DontRaiseKeyError |
|
82 |
def _custom_token(self, service): |
|
83 |
return self.config.get_remote(self.cloud, '%s_token' % service) |
|
84 |
|
|
85 |
@DontRaiseKeyError |
|
86 |
def _custom_type(self, service): |
|
87 |
return self.config.get_remote(self.cloud, '%s_type' % service) |
|
88 |
|
|
89 |
@DontRaiseKeyError |
|
90 |
def _custom_version(self, service): |
|
91 |
return self.config.get_remote(self.cloud, '%s_version' % service) |
|
92 |
|
|
58 | 93 |
def _set_log_params(self): |
59 | 94 |
try: |
60 | 95 |
self.client.LOG_TOKEN, self.client.LOG_DATA = ( |
... | ... | |
65 | 100 |
'%s\n defaults for token and data logging are off' % e) |
66 | 101 |
|
67 | 102 |
def _update_max_threads(self): |
68 |
try:
|
|
103 |
if getattr(self, 'client', None):
|
|
69 | 104 |
max_threads = int(self['config'].get_global('max_threads')) |
70 | 105 |
assert max_threads > 0 |
71 | 106 |
self.client.MAX_THREADS = max_threads |
72 |
except Exception as e: |
|
73 |
log.warning('Failed to read custom thread settings: ' |
|
74 |
'%s, use default max threads (%s)' % ( |
|
75 |
e, self.client.MAX_THREADS)) |
|
76 | 107 |
|
77 | 108 |
def _safe_progress_bar(self, msg, arg='progress_bar'): |
78 | 109 |
"""Try to get a progress bar, but do not raise errors""" |
b/kamaki/cli/commands/astakos.py | ||
---|---|---|
33 | 33 |
|
34 | 34 |
from kamaki.cli import command |
35 | 35 |
from kamaki.clients.astakos import AstakosClient |
36 |
from kamaki.cli.commands import _command_init, errors, _optional_json |
|
36 |
from kamaki.cli.commands import ( |
|
37 |
_command_init, errors, _optional_json, addLogSettings) |
|
37 | 38 |
from kamaki.cli.command_tree import CommandTree |
38 | 39 |
from kamaki.cli.errors import CLIBaseUrlError |
39 | 40 |
from kamaki.cli.utils import print_dict |
... | ... | |
46 | 47 |
|
47 | 48 |
@errors.generic.all |
48 | 49 |
@errors.user.load |
50 |
@addLogSettings |
|
49 | 51 |
def _run(self): |
52 |
if getattr(self, 'cloud', False): |
|
53 |
base_url = self._custom_url('astakos') |
|
54 |
if base_url: |
|
55 |
token = self._custom_token('astakos')\ |
|
56 |
or self.config.get_remote(self.cloud, 'token') |
|
57 |
self.client = AstakosClient(base_url=base_url, token=token) |
|
58 |
return |
|
59 |
else: |
|
60 |
self.cloud = 'default' |
|
50 | 61 |
if getattr(self, 'auth_base', False): |
51 | 62 |
self.client = self.auth_base |
52 |
else: |
|
53 |
token = self.config.get('user', 'token')\ |
|
54 |
or self.config.get('astakos', 'token')\ |
|
55 |
or self.config.get('global', 'token') |
|
56 |
base_url = self.config.get('user', 'url')\ |
|
57 |
or self.config.get('astakos', 'url') |
|
58 |
if not base_url: |
|
59 |
raise CLIBaseUrlError(service='astakos') |
|
60 |
self.client = AstakosClient(base_url=base_url, token=token) |
|
61 |
|
|
62 |
self._set_log_params() |
|
63 |
self._update_max_threads() |
|
63 |
return |
|
64 |
raise CLIBaseUrlError(service='astakos') |
|
64 | 65 |
|
65 | 66 |
def main(self): |
66 | 67 |
self._run() |
b/kamaki/cli/commands/cyclades.py | ||
---|---|---|
38 | 38 |
from kamaki.clients.cyclades import CycladesClient, ClientError |
39 | 39 |
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument |
40 | 40 |
from kamaki.cli.argument import ProgressBarArgument, DateArgument, IntArgument |
41 |
from kamaki.cli.commands import _command_init, errors |
|
41 |
from kamaki.cli.commands import _command_init, errors, addLogSettings
|
|
42 | 42 |
from kamaki.cli.commands import _optional_output_cmd, _optional_json |
43 | 43 |
|
44 | 44 |
from base64 import b64encode |
... | ... | |
67 | 67 |
|
68 | 68 |
class _init_cyclades(_command_init): |
69 | 69 |
@errors.generic.all |
70 |
@addLogSettings |
|
70 | 71 |
def _run(self, service='compute'): |
71 |
token = self.config.get(service, 'token')\ |
|
72 |
or self.config.get('global', 'token') |
|
73 |
|
|
72 |
if getattr(self, 'cloud', None): |
|
73 |
base_url = self._custom_url(service)\ |
|
74 |
or self._custom_url('cyclades') |
|
75 |
if base_url: |
|
76 |
token = self._custom_token(service)\ |
|
77 |
or self._custom_token('cyclades')\ |
|
78 |
or self.config.get_remote('token') |
|
79 |
self.client = CycladesClient( |
|
80 |
base_url=base_url, token=token) |
|
81 |
return |
|
82 |
else: |
|
83 |
self.cloud = 'default' |
|
74 | 84 |
if getattr(self, 'auth_base', False): |
75 | 85 |
cyclades_endpoints = self.auth_base.get_service_endpoints( |
76 |
self.config.get('cyclades', 'type'),
|
|
77 |
self.config.get('cyclades', 'version'))
|
|
86 |
self._custom_type('cyclades') or 'compute',
|
|
87 |
self._custom_version('cyclades') or '')
|
|
78 | 88 |
base_url = cyclades_endpoints['publicURL'] |
89 |
token = self.auth_base.token |
|
90 |
self.client = CycladesClient(base_url=base_url, token=token) |
|
79 | 91 |
else: |
80 |
base_url = self.config.get('compute', 'url')\ |
|
81 |
or self.config.get('cyclades', 'url') |
|
82 |
if not base_url: |
|
83 | 92 |
raise CLIBaseUrlError(service='cyclades') |
84 | 93 |
|
85 |
self.client = CycladesClient(base_url=base_url, token=token) |
|
86 |
self._set_log_params() |
|
87 |
self._update_max_threads() |
|
88 |
|
|
89 | 94 |
def main(self): |
90 | 95 |
self._run() |
91 | 96 |
|
b/kamaki/cli/commands/image.py | ||
---|---|---|
46 | 46 |
from kamaki.cli.argument import IntArgument |
47 | 47 |
from kamaki.cli.commands.cyclades import _init_cyclades |
48 | 48 |
from kamaki.cli.errors import raiseCLIError, CLIBaseUrlError |
49 |
from kamaki.cli.commands import _command_init, errors |
|
49 |
from kamaki.cli.commands import _command_init, errors, addLogSettings
|
|
50 | 50 |
from kamaki.cli.commands import _optional_output_cmd, _optional_json |
51 | 51 |
|
52 | 52 |
|
... | ... | |
73 | 73 |
|
74 | 74 |
class _init_image(_command_init): |
75 | 75 |
@errors.generic.all |
76 |
@addLogSettings |
|
76 | 77 |
def _run(self): |
77 |
token = self.config.get('image', 'token')\ |
|
78 |
or self.config.get('plankton', 'token')\ |
|
79 |
or self.config.get('global', 'token') |
|
80 |
|
|
78 |
if getattr(self, 'cloud', None): |
|
79 |
img_url = self._custom_url('image') or self._custom_url('plankton') |
|
80 |
if img_url: |
|
81 |
token = self._custom_token('image')\ |
|
82 |
or self._custom_token('plankton')\ |
|
83 |
or self.config.get_remote(self.cloud, 'token') |
|
84 |
self.client = ImageClient(base_url=img_url, token=token) |
|
85 |
return |
|
81 | 86 |
if getattr(self, 'auth_base', False): |
82 | 87 |
plankton_endpoints = self.auth_base.get_service_endpoints( |
83 |
self.config.get('image', 'type'), |
|
84 |
self.config.get('image', 'version')) |
|
88 |
self._custom_type('image')\ |
|
89 |
or self._custom_type('plankton') or 'image', |
|
90 |
self._custom_version('image')\ |
|
91 |
or self._custom_version('plankton') or '') |
|
85 | 92 |
base_url = plankton_endpoints['publicURL'] |
93 |
token = self.auth_base.token |
|
86 | 94 |
else: |
87 |
base_url = self.config.get('image', 'url')\ |
|
88 |
or self.config.get('plankton', 'url') |
|
89 |
if not base_url: |
|
90 | 95 |
raise CLIBaseUrlError(service='plankton') |
91 |
|
|
92 | 96 |
self.client = ImageClient(base_url=base_url, token=token) |
93 |
self._set_log_params() |
|
94 |
self._update_max_threads() |
|
95 | 97 |
|
96 | 98 |
def main(self): |
97 | 99 |
self._run() |
b/kamaki/cli/commands/pithos.py | ||
---|---|---|
45 | 45 |
from kamaki.cli.argument import KeyValueArgument, DateArgument |
46 | 46 |
from kamaki.cli.argument import ProgressBarArgument |
47 | 47 |
from kamaki.cli.commands import _command_init, errors |
48 |
from kamaki.cli.commands import addLogSettings, DontRaiseKeyError |
|
48 | 49 |
from kamaki.cli.commands import _optional_output_cmd, _optional_json |
49 | 50 |
from kamaki.clients.pithos import PithosClient, ClientError |
50 | 51 |
from kamaki.clients.astakos import AstakosClient |
... | ... | |
150 | 151 |
return 'application/directory' == remote_dict.get( |
151 | 152 |
'content_type', remote_dict.get('content-type', '')) |
152 | 153 |
|
154 |
@DontRaiseKeyError |
|
155 |
def _custom_container(self): |
|
156 |
return self.config.get_remote(self.cloud, 'pithos_container') |
|
157 |
|
|
158 |
@DontRaiseKeyError |
|
159 |
def _custom_uuid(self): |
|
160 |
return self.config.get_remote(self.cloud, 'pithos_uuid') |
|
161 |
|
|
162 |
def _set_account(self): |
|
163 |
self.account = self._custom_uuid() |
|
164 |
if self.account: |
|
165 |
return |
|
166 |
if getattr(self, 'auth_base', False): |
|
167 |
self.account = self.auth_base.user_term('id', self.token) |
|
168 |
else: |
|
169 |
astakos_url = self._custom_url('astakos') |
|
170 |
astakos_token = self._custom_token('astakos') or self.token |
|
171 |
if not astakos_url: |
|
172 |
raise CLIBaseUrlError(service='astakos') |
|
173 |
astakos = AstakosClient(astakos_url, astakos_token) |
|
174 |
self.account = astakos.user_term('id') |
|
175 |
|
|
153 | 176 |
@errors.generic.all |
177 |
@addLogSettings |
|
154 | 178 |
def _run(self): |
155 |
self.token = self.config.get('file', 'token')\ |
|
156 |
or self.config.get('global', 'token') |
|
179 |
self.base_url = None |
|
180 |
if getattr(self, 'cloud', None): |
|
181 |
self.base_url = self._custom_url('pithos') |
|
182 |
else: |
|
183 |
self.cloud = 'default' |
|
184 |
self.token = self._custom_token('pithos') |
|
185 |
self.container = self._custom_container() |
|
157 | 186 |
|
158 | 187 |
if getattr(self, 'auth_base', False): |
159 |
pithos_endpoints = self.auth_base.get_service_endpoints( |
|
160 |
self.config.get('pithos', 'type'), |
|
161 |
self.config.get('pithos', 'version')) |
|
162 |
self.base_url = pithos_endpoints['publicURL'] |
|
163 |
else: |
|
164 |
self.base_url = self.config.get('file', 'url')\ |
|
165 |
or self.config.get('store', 'url')\ |
|
166 |
or self.config.get('pithos', 'url') |
|
167 |
if not self.base_url: |
|
188 |
self.token = self.token or self.auth_base.token |
|
189 |
if not self.base_url: |
|
190 |
pithos_endpoints = self.auth_base.get_service_endpoints( |
|
191 |
self._custom_type('pithos') or 'object-store', |
|
192 |
self._custom_version('pithos') or '') |
|
193 |
self.base_url = pithos_endpoints['publicURL'] |
|
194 |
elif not self.base_url: |
|
168 | 195 |
raise CLIBaseUrlError(service='pithos') |
169 | 196 |
|
170 | 197 |
self._set_account() |
171 |
self.container = self.config.get('file', 'container')\ |
|
172 |
or self.config.get('store', 'container')\ |
|
173 |
or self.config.get('pithos', 'container')\ |
|
174 |
or self.config.get('global', 'container') |
|
175 | 198 |
self.client = PithosClient( |
176 | 199 |
base_url=self.base_url, |
177 | 200 |
token=self.token, |
178 | 201 |
account=self.account, |
179 | 202 |
container=self.container) |
180 |
self._set_log_params() |
|
181 |
self._update_max_threads() |
|
182 | 203 |
|
183 | 204 |
def main(self): |
184 | 205 |
self._run() |
185 | 206 |
|
186 |
def _set_account(self): |
|
187 |
if getattr(self, 'auth_base', False): |
|
188 |
self.account = self.auth_base.user_term('id', self.token) |
|
189 |
else: |
|
190 |
astakos_url = self.config.get('user', 'url')\ |
|
191 |
or self.config.get('astakos', 'url') |
|
192 |
if not astakos_url: |
|
193 |
raise CLIBaseUrlError(service='astakos') |
|
194 |
astakos = AstakosClient(astakos_url, self.token) |
|
195 |
self.account = astakos.user_term('id') |
|
196 |
|
|
197 | 207 |
|
198 | 208 |
class _file_account_command(_pithos_init): |
199 | 209 |
"""Base class for account level storage commands""" |
200 | 210 |
|
201 |
def __init__(self, arguments={}, auth_base=None): |
|
202 |
super(_file_account_command, self).__init__(arguments, auth_base) |
|
211 |
def __init__(self, arguments={}, auth_base=None, cloud=None): |
|
212 |
super(_file_account_command, self).__init__( |
|
213 |
arguments, auth_base, cloud) |
|
203 | 214 |
self['account'] = ValueArgument( |
204 | 215 |
'Set user account (not permanent)', ('-A', '--account')) |
205 | 216 |
|
... | ... | |
221 | 232 |
container = None |
222 | 233 |
path = None |
223 | 234 |
|
224 |
def __init__(self, arguments={}, auth_base=None): |
|
225 |
super(_file_container_command, self).__init__(arguments, auth_base) |
|
235 |
def __init__(self, arguments={}, auth_base=None, cloud=None): |
|
236 |
super(_file_container_command, self).__init__( |
|
237 |
arguments, auth_base, cloud) |
|
226 | 238 |
self['container'] = ValueArgument( |
227 | 239 |
'Set container to work with (temporary)', ('-C', '--container')) |
228 | 240 |
|
... | ... | |
531 | 543 |
suffix_replace=ValueArgument('', '--suffix-to-replace', default=''), |
532 | 544 |
) |
533 | 545 |
|
534 |
def __init__(self, arguments={}, auth_base=None): |
|
546 |
def __init__(self, arguments={}, auth_base=None, cloud=None):
|
|
535 | 547 |
self.arguments.update(arguments) |
536 | 548 |
super(_source_destination_command, self).__init__( |
537 |
self.arguments, auth_base) |
|
549 |
self.arguments, auth_base, cloud)
|
|
538 | 550 |
|
539 | 551 |
def _run(self, source_container___path, path_is_optional=False): |
540 | 552 |
super(_source_destination_command, self)._run( |
... | ... | |
1455 | 1467 |
('-R', '--recursive')) |
1456 | 1468 |
) |
1457 | 1469 |
|
1458 |
def __init__(self, arguments={}, auth_base=None): |
|
1459 |
super(self.__class__, self).__init__(arguments, auth_base)
|
|
1470 |
def __init__(self, arguments={}, auth_base=None, cloud=None):
|
|
1471 |
super(self.__class__, self).__init__(arguments, auth_base, cloud)
|
|
1460 | 1472 |
self['delimiter'] = DelimiterArgument( |
1461 | 1473 |
self, |
1462 | 1474 |
parsed_name='--delimiter', |
b/kamaki/cli/commands/snf-astakos.py | ||
---|---|---|
35 | 35 |
|
36 | 36 |
from kamaki.cli import command |
37 | 37 |
from kamaki.cli.errors import CLIBaseUrlError |
38 |
from kamaki.cli.commands import _command_init, errors, _optional_json |
|
38 |
from kamaki.cli.commands import ( |
|
39 |
_command_init, errors, _optional_json, addLogSettings) |
|
39 | 40 |
from kamaki.cli.command_tree import CommandTree |
40 | 41 |
from kamaki.cli.utils import print_dict |
41 | 42 |
from kamaki.cli.argument import FlagArgument, ValueArgument |
... | ... | |
50 | 51 |
|
51 | 52 |
class _astakos_init(_command_init): |
52 | 53 |
|
53 |
def __init__(self, arguments=dict(), auth_base=None): |
|
54 |
super(_astakos_init, self).__init__(arguments, auth_base) |
|
54 |
def __init__(self, arguments=dict(), auth_base=None, cloud=None):
|
|
55 |
super(_astakos_init, self).__init__(arguments, auth_base, cloud)
|
|
55 | 56 |
self['token'] = ValueArgument('Custom token', '--token') |
56 | 57 |
|
57 | 58 |
@errors.generic.all |
58 | 59 |
#@errors.user.load |
60 |
@addLogSettings |
|
59 | 61 |
def _run(self): |
60 |
self.token = self['token']\ |
|
61 |
or self.config.get('astakos', 'token')\ |
|
62 |
or self.config.get('user', 'token')\ |
|
63 |
or self.config.get('global', 'token') |
|
62 |
self.cloud = self.cloud if self.cloud else 'default' |
|
63 |
self.token = self['token'] or self._custom_token('astakos')\ |
|
64 |
or self.config.get_remote(self.cloud, 'token') |
|
64 | 65 |
if getattr(self, 'auth_base', False): |
65 | 66 |
astakos_endpoints = self.auth_base.get_service_endpoints( |
66 |
self.config.get('astakos', 'type'),
|
|
67 |
self.config.get('astakos', 'version'))
|
|
67 |
self._custom_type('astakos') or 'identity',
|
|
68 |
self._custom_version('astakos') or '')
|
|
68 | 69 |
base_url = astakos_endpoints['publicURL'] |
69 | 70 |
else: |
70 |
base_url = self.config.get('astakos', 'url')
|
|
71 |
base_url = self._custom_url('astakos')
|
|
71 | 72 |
if not base_url: |
72 | 73 |
raise CLIBaseUrlError(service='astakos') |
73 | 74 |
self.client = AstakosClient(base_url, logger=log) |
74 |
self._set_log_params() |
|
75 |
self._update_max_threads() |
|
76 | 75 |
|
77 | 76 |
def main(self): |
78 | 77 |
self._run() |
b/kamaki/cli/config.py | ||
---|---|---|
192 | 192 |
'... rescue %s.%s => remote.default.%s_%s' % ( |
193 | 193 |
s, k, trn['serv'], k)) |
194 | 194 |
self.set_remote('default', 'pithos_%s' % k, v) |
195 |
elif (k in ('container', 'uuid')) and ( |
|
196 |
trn['serv'] in ('pithos',)): |
|
197 |
print( |
|
198 |
'... rescue %s.%s => remote.default.pithos_%s' % ( |
|
199 |
s, k, k)) |
|
200 |
self.set_remote('default', 'pithos_%s' % k, v) |
|
195 | 201 |
elif v: |
196 | 202 |
lost_terms.append('%s.%s = %s' % (s, k, v)) |
197 | 203 |
self.remove_section(s) |
Also available in: Unified diff