Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / config.py @ e8bd81eb

History | View | Annotate | Download (4.6 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 INTERRUPTION) 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
import os
35

    
36
from collections import defaultdict
37
from ConfigParser import RawConfigParser, NoOptionError, NoSectionError
38

    
39
try:
40
    from collections import OrderedDict
41
except ImportError:
42
    from ordereddict import OrderedDict
43

    
44

    
45
# Path to the file that stores the configuration
46
CONFIG_PATH = os.path.expanduser('~/.kamakirc')
47

    
48
# Name of a shell variable to bypass the CONFIG_PATH value
49
CONFIG_ENV = 'KAMAKI_CONFIG'
50

    
51
HEADER = """
52
# Kamaki configuration file
53
"""
54

    
55
DEFAULTS = {
56
    'global': {
57
        'colors': 'on',
58
        'token': ''
59
    },
60
    'config': {
61
        'cli': 'config_cli',
62
        'description': 'Configuration commands'
63
    },
64
    'history':{
65
        'cli': 'history_cli',
66
        'file':'.kamaki.history'
67
    },
68
    'store': {
69
        'cli': 'pithos_cli',
70
        'url': 'https://pithos.okeanos.grnet.gr/v1'
71
    },
72
    'compute': {
73
        'url': 'https://cyclades.okeanos.grnet.gr/api/v1.1'
74
    },
75
    'server': {
76
        'cli':'cyclades_cli'
77
    },
78
    'flavor': {
79
        'cli':'cyclades_cli'
80
    },
81
    'network': {
82
        'cli':'cyclades_cli'
83
    },
84
    'image': {
85
        'cli':'image_cli',
86
        'url': 'https://plankton.okeanos.grnet.gr'
87
    },
88
    'astakos': {
89
        'cli': 'astakos_cli',
90
        'url': 'url = https://accounts.okeanos.grnet.gr'
91
    }
92
}
93

    
94

    
95
class Config(RawConfigParser):
96
    def __init__(self, path=None):
97
        RawConfigParser.__init__(self, dict_type=OrderedDict)
98
        self.path = path or os.environ.get(CONFIG_ENV, CONFIG_PATH)
99
        self._overrides = defaultdict(dict)
100
        self._load_defaults()
101
        self.read(self.path)
102

    
103
    def _load_defaults(self):
104
        for section, options in DEFAULTS.items():
105
            for option, val in options.items():
106
                self.set(section, option, val)
107

    
108
    def apis(self):
109
        return [api for api in self.sections() if api != 'global']
110

    
111
    def get(self, section, option):
112
        value = self._overrides.get(section, {}).get(option)
113
        if value is not None:
114
            return value
115

    
116
        try:
117
            return RawConfigParser.get(self, section, option)
118
        except (NoSectionError, NoOptionError):
119
            return DEFAULTS.get(section, {}).get(option)
120

    
121
    def set(self, section, option, value):
122
        if section not in RawConfigParser.sections(self):
123
            self.add_section(section)
124
        RawConfigParser.set(self, section, option, value)
125

    
126
    def remove_option(self, section, option):
127
        try:
128
            RawConfigParser.remove_option(self, section, option)
129
        except NoSectionError:
130
            pass
131

    
132
    def items(self, section, include_defaults=False):
133
        try:
134
            d = dict(DEFAULTS[section]) if include_defaults else {}
135
        except KeyError:
136
            d = {}
137
        try:
138
            d.update(RawConfigParser.items(self, section))
139
        except NoSectionError:
140
            pass
141
        return d.items()
142

    
143
    def override(self, section, option, value):
144
        self._overrides[section][option] = value
145

    
146
    def write(self):
147
        with open(self.path, 'w') as f:
148
            os.chmod(self.path, 0600)
149
            f.write(HEADER.lstrip())
150
            RawConfigParser.write(self, f)