1 # Copyright 2011-2012 GRNET S.A. All rights reserved.
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
7 # 1. Redistributions of source code must retain the above
8 # copyright notice, this list of conditions and the following
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.
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 INTERaUPTION) 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.
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.
34 from sys import stdout
36 from kamaki.cli import command
37 from kamaki.cli.argument import FlagArgument
38 from kamaki.cli.commands import _command_init, errors
39 from kamaki.cli.command_tree import CommandTree
40 from kamaki.cli.errors import CLIError, CLISyntaxError
42 config_cmds = CommandTree('config', 'Kamaki configurations')
43 _commands = [config_cmds]
45 about_options = '\nAbout options:\
46 \n. syntax: [group.]option\
47 \n. example: global.log_file\
48 \n. special case: <option> is equivalent to global.<option>\
49 \n. configuration file syntax:\
52 \n. (more options can be set per group)\
53 \n. special case: named clouds.\
54 \n. E.g. for a cloud "demo":\
56 \n. url = <http://single/authentication/url/for/demo/site>\
57 \n. token = <auth_token_from_demo_site>\
58 \n. which are referenced as cloud.demo.url , cloud.demo.token'
62 class config_list(_command_init):
63 """List all configuration options
65 Q: I haven't set any options!
66 A: Defaults are used (override with /config set )
67 Q: There are more options than I have set
68 A: Default options remain if not explicitly replaced or deleted
73 print 'ANY PROBLEMOS?'
74 for section in sorted(self.config.sections()):
75 items = self.config.items(section)
76 for key, val in sorted(items):
77 if section in ('cloud',):
78 prefix = '%s.%s' % (section, key)
79 for k, v in val.items():
80 print('%s.%s = %s' % (prefix, k, v))
82 print('%s.%s = %s' % (section, key, val))
89 class config_get(_command_init):
90 """Show a configuration option"""
92 __doc__ += about_options
95 def _run(self, option):
96 section, sep, key = option.rpartition('.')
99 for k in self.config.keys(key):
101 if option != 'cloud':
102 stdout.write('%s.%s =' % (option, k))
103 self._run('%s.%s' % (option, k))
109 self.config.get_cloud, section[len(prefix):]) if (
110 section.startswith(prefix)) else (self.config.get, section)
111 value = get(section, key)
112 if isinstance(value, dict):
113 for k, v in value.items():
114 print('%s.%s.%s = %s' % (section, key, k, v))
118 def main(self, option):
122 @command(config_cmds)
123 class config_set(_command_init):
124 """Set a configuration option"""
126 __doc__ += about_options
129 def _run(self, option, value):
130 section, sep, key = option.rpartition('.')
132 if section.startswith(prefix):
133 self.config.set_cloud(section[len(prefix):], key, value)
134 elif section in ('cloud',):
135 raise CLISyntaxError(
136 'Invalid syntax for cloud definition', importance=2, details=[
137 'To define a cloud "%s"' % key,
138 'set the cloud\'s authentication url and token:',
139 ' /config set cloud.%s.url <URL>' % key,
140 ' /config set cloud.%s.token <t0k3n>' % key])
142 section = section or 'global'
143 self.config.set(section, key, value)
147 def main(self, option, value):
148 self._run(option, value)
151 @command(config_cmds)
152 class config_delete(_command_init):
153 """Delete a configuration option
154 Default values are not removed by default. To alter this behavior in a
155 session, use --default.
159 default=FlagArgument(
160 'Remove default value as well (persists until end of session)',
165 def _run(self, option):
166 section, sep, key = option.rpartition('.')
167 section = section or 'global'
169 if section.startswith(prefix):
170 cloud = section[len(prefix):]
172 self.config.remove_from_cloud(cloud, key)
174 raise CLIError('Field %s does not exist' % option)
176 self.config.remove_option(section, key, self['default'])
180 def main(self, option):