Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / config.py @ ca5b9261

History | View | Annotate | Download (6.2 kB)

1
# Copyright 2011-2012 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. special case: named cloud remotes.\
54
    \n. E.g. for a cloud "demo":\
55
    \n.   [remote "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 remote.demo.url , remote.demo.token'
59

    
60

    
61
@command(config_cmds)
62
class config_list(_command_init):
63
    """List all configuration options
64
    FAQ:
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
69
    """
70

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

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

    
86

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

    
91
    __doc__ += about_options
92

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

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

    
120

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

    
125
    __doc__ += about_options
126

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

    
146
    def main(self, option, value):
147
        self._run(option, value)
148

    
149

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

    
157
    arguments = dict(
158
        default=FlagArgument(
159
            'Remove default value as well (persists until end of session)',
160
            '--default')
161
    )
162

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

    
179
    def main(self, option):
180
        self._run(option)