Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / config.py @ 3185cd6d

History | View | Annotate | Download (6.3 kB)

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

    
34
from sys import stdout
35

    
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
41

    
42
config_cmds = CommandTree('config', 'Kamaki configurations')
43
_commands = [config_cmds]
44

    
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:\
50
    \n.   [group]\
51
    \n.   option=value\
52
    \n.   (more options can be set per group)\
53
    \n.\
54
    \n. special case: named clouds.\
55
    \n. example: cloud.demo.url\
56
    \n. E.g. for a cloud "demo":\
57
    \n.   [cloud "demo"]\
58
    \n.   url = <http://single/authentication/url/for/demo/site>\
59
    \n.   token = <auth_token_from_demo_site>'
60

    
61

    
62
@command(config_cmds)
63
class config_list(_command_init):
64
    """List all configuration options
65
    FAQ:
66
    Q: I haven't set any options!
67
    A: Defaults are used (override with /config set )
68
    Q: There are more options than I have set
69
    A: Default options remain if not explicitly replaced or deleted
70
    """
71

    
72
    @errors.generic.all
73
    def _run(self):
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
                        self.writeln('%s.%s = %s' % (prefix, k, v))
81
                else:
82
                    self.writeln('%s.%s = %s' % (section, key, val))
83

    
84
    def main(self):
85
        self._run()
86

    
87

    
88
@command(config_cmds)
89
class config_get(_command_init):
90
    """Show a configuration option"""
91

    
92
    __doc__ += about_options
93

    
94
    @errors.generic.all
95
    def _run(self, option):
96
        section, sep, key = option.rpartition('.')
97
        if not sep:
98
            match = False
99
            for k in self.config.keys(key):
100
                match = True
101
                if option != 'cloud':
102
                    self.write('%s.%s =' % (option, k))
103
                self._run('%s.%s' % (option, k))
104
            if match:
105
                return
106
            section = 'global'
107
        prefix = 'cloud.'
108
        get, section = (
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
                self.writeln('%s.%s.%s = %s' % (section, key, k, v))
115
        elif value:
116
            self.writeln(value)
117

    
118
    def main(self, option):
119
        self._run(option)
120

    
121

    
122
@command(config_cmds)
123
class config_set(_command_init):
124
    """Set a configuration option"""
125

    
126
    __doc__ += about_options
127

    
128
    @errors.generic.all
129
    def _run(self, option, value):
130
        section, sep, key = option.rpartition('.')
131
        prefix = 'cloud.'
132
        if section.startswith(prefix):
133
            cloudname = section[len(prefix):]
134
            if cloudname:
135
                self.config.set_cloud(cloudname, key, value)
136
            else:
137
                raise CLISyntaxError(
138
                    'Empty cloud alias (%s)' % option, importance=2)
139
        elif section in ('cloud',):
140
            raise CLISyntaxError(
141
                'Invalid syntax for cloud definition', importance=2, details=[
142
                    'To define a cloud "%s"' % key,
143
                    'set the cloud\'s authentication url and token:',
144
                    '  /config set cloud.%s.url <URL>' % key,
145
                    '  /config set cloud.%s.token <t0k3n>' % key])
146
        else:
147
            section = section or 'global'
148
            self.config.set(section, key, value)
149
        self.config.write()
150
        self.config.reload()
151

    
152
    def main(self, option, value):
153
        self._run(option, value)
154

    
155

    
156
@command(config_cmds)
157
class config_delete(_command_init):
158
    """Delete a configuration option
159
    Default values are not removed by default. To alter this behavior in a
160
    session, use --default.
161
    """
162

    
163
    arguments = dict(
164
        default=FlagArgument(
165
            'Remove default value as well (persists until end of session)',
166
            '--default')
167
    )
168

    
169
    @errors.generic.all
170
    def _run(self, option):
171
        section, sep, key = option.rpartition('.')
172
        section = section or 'global'
173
        prefix = 'cloud.'
174
        if section.startswith(prefix):
175
            cloud = section[len(prefix):]
176
            try:
177
                self.config.remove_from_cloud(cloud, key)
178
            except KeyError:
179
                raise CLIError('Field %s does not exist' % option)
180
        else:
181
            self.config.remove_option(section, key, self['default'])
182
        self.config.write()
183
        self.config.reload()
184

    
185
    def main(self, option):
186
        self._run(option)