Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / config.py @ 8e3cbcfe

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 kamaki.cli import command
35
from kamaki.cli.argument import FlagArgument
36
from kamaki.cli.commands import _command_init, errors
37
from kamaki.cli.command_tree import CommandTree
38
from kamaki.cli.errors import CLIError, CLISyntaxError
39

    
40
config_cmds = CommandTree('config', 'Kamaki configurations')
41
_commands = [config_cmds]
42

    
43
about_options = '\nAbout options:\
44
    \n. syntax: [group.]option\
45
    \n. example: global.log_file\
46
    \n. special case: <option> is equivalent to global.<option>\
47
    \n. configuration file syntax:\
48
    \n.   [group]\
49
    \n.   option=value\
50
    \n.   (more options can be set per group)\
51
    \n.\
52
    \n. special case: named clouds.\
53
    \n. example: cloud.demo.url\
54
    \n. E.g. for a cloud "demo":\
55
    \n.   [cloud "demo"]\
56
    \n.   url = <http://single/authentication/url/for/demo/site>\
57
    \n.   token = <auth_token_from_demo_site>'
58

    
59

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

    
70
    @errors.generic.all
71
    def _run(self):
72
        for section in sorted(self.config.sections()):
73
            items = self.config.items(section)
74
            for key, val in sorted(items):
75
                if section in ('cloud',):
76
                    prefix = '%s.%s' % (section, key)
77
                    for k, v in val.items():
78
                        self.writeln('%s.%s = %s' % (prefix, k, v))
79
                else:
80
                    self.writeln('%s.%s = %s' % (section, key, val))
81

    
82
    def main(self):
83
        self._run()
84

    
85

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

    
90
    __doc__ += about_options
91

    
92
    @errors.generic.all
93
    def _run(self, option):
94
        section, sep, key = option.rpartition('.')
95
        if not sep:
96
            match = False
97
            for k in self.config.keys(key):
98
                match = True
99
                if option != 'cloud':
100
                    self.write('%s.%s =' % (option, k))
101
                self._run('%s.%s' % (option, k))
102
            if match:
103
                return
104
            section = 'global'
105
        prefix = 'cloud.'
106
        get, section = (
107
            self.config.get_cloud, section[len(prefix):]) if (
108
                section.startswith(prefix)) else (self.config.get, section)
109
        value = get(section, key)
110
        if isinstance(value, dict):
111
            for k, v in value.items():
112
                self.writeln('%s.%s.%s = %s' % (section, key, k, v))
113
        elif value:
114
            self.writeln(value)
115

    
116
    def main(self, option):
117
        self._run(option)
118

    
119

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

    
124
    __doc__ += about_options
125

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

    
150
    def main(self, option, value):
151
        self._run(option, value)
152

    
153

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

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

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

    
183
    def main(self, option):
184
        self._run(option)