Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / config.py @ a9fca388

History | View | Annotate | Download (4.9 kB)

1 7493ccb6 Stavros Sachtouris
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 7493ccb6 Stavros Sachtouris
#
3 7493ccb6 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 7493ccb6 Stavros Sachtouris
# without modification, are permitted provided that the following
5 7493ccb6 Stavros Sachtouris
# conditions are met:
6 7493ccb6 Stavros Sachtouris
#
7 7493ccb6 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 7493ccb6 Stavros Sachtouris
#      disclaimer.
10 7493ccb6 Stavros Sachtouris
#
11 7493ccb6 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 7493ccb6 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 7493ccb6 Stavros Sachtouris
#      provided with the distribution.
15 7493ccb6 Stavros Sachtouris
#
16 7493ccb6 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 7493ccb6 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 7493ccb6 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 7493ccb6 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 7493ccb6 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 7493ccb6 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 7493ccb6 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 7493ccb6 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 7493ccb6 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 7493ccb6 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 7493ccb6 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 7493ccb6 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 7493ccb6 Stavros Sachtouris
#
29 7493ccb6 Stavros Sachtouris
# The views and conclusions contained in the software and
30 7493ccb6 Stavros Sachtouris
# documentation are those of the authors and should not be
31 7493ccb6 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 7493ccb6 Stavros Sachtouris
# or implied, of GRNET S.A.
33 7493ccb6 Stavros Sachtouris
34 7493ccb6 Stavros Sachtouris
import os
35 7493ccb6 Stavros Sachtouris
36 7493ccb6 Stavros Sachtouris
from collections import defaultdict
37 7493ccb6 Stavros Sachtouris
from ConfigParser import RawConfigParser, NoOptionError, NoSectionError
38 7493ccb6 Stavros Sachtouris
39 7493ccb6 Stavros Sachtouris
try:
40 7493ccb6 Stavros Sachtouris
    from collections import OrderedDict
41 7493ccb6 Stavros Sachtouris
except ImportError:
42 a9fca388 Stavros Sachtouris
    from kamaki.clients.commissioning.utils.ordereddict import OrderedDict
43 7493ccb6 Stavros Sachtouris
44 7493ccb6 Stavros Sachtouris
45 7493ccb6 Stavros Sachtouris
# Path to the file that stores the configuration
46 7493ccb6 Stavros Sachtouris
CONFIG_PATH = os.path.expanduser('~/.kamakirc')
47 9f1d1fcf Stavros Sachtouris
HISTORY_PATH = os.path.expanduser('~/.kamaki.history')
48 7493ccb6 Stavros Sachtouris
49 7493ccb6 Stavros Sachtouris
# Name of a shell variable to bypass the CONFIG_PATH value
50 7493ccb6 Stavros Sachtouris
CONFIG_ENV = 'KAMAKI_CONFIG'
51 7493ccb6 Stavros Sachtouris
52 7493ccb6 Stavros Sachtouris
HEADER = """
53 7493ccb6 Stavros Sachtouris
# Kamaki configuration file
54 7493ccb6 Stavros Sachtouris
"""
55 7493ccb6 Stavros Sachtouris
56 7493ccb6 Stavros Sachtouris
DEFAULTS = {
57 7493ccb6 Stavros Sachtouris
    'global': {
58 4f6a21f6 Stavros Sachtouris
        'colors': 'off',
59 d6737e18 Stavros Sachtouris
        'account':  '',
60 7493ccb6 Stavros Sachtouris
        'token': ''
61 7493ccb6 Stavros Sachtouris
    },
62 7493ccb6 Stavros Sachtouris
    'config': {
63 7493ccb6 Stavros Sachtouris
        'cli': 'config_cli',
64 7493ccb6 Stavros Sachtouris
        'description': 'Configuration commands'
65 b46307af Stavros Sachtouris
    },
66 fd5db045 Stavros Sachtouris
    'history': {
67 554d18b0 Stavros Sachtouris
        'cli': 'history_cli',
68 fd5db045 Stavros Sachtouris
        'file': HISTORY_PATH
69 554d18b0 Stavros Sachtouris
    },
70 554d18b0 Stavros Sachtouris
    'store': {
71 554d18b0 Stavros Sachtouris
        'cli': 'pithos_cli',
72 e8bd81eb Stavros Sachtouris
        'url': 'https://pithos.okeanos.grnet.gr/v1'
73 554d18b0 Stavros Sachtouris
    },
74 554d18b0 Stavros Sachtouris
    'compute': {
75 554d18b0 Stavros Sachtouris
        'url': 'https://cyclades.okeanos.grnet.gr/api/v1.1'
76 554d18b0 Stavros Sachtouris
    },
77 554d18b0 Stavros Sachtouris
    'server': {
78 fd5db045 Stavros Sachtouris
        'cli': 'cyclades_cli'
79 554d18b0 Stavros Sachtouris
    },
80 554d18b0 Stavros Sachtouris
    'flavor': {
81 fd5db045 Stavros Sachtouris
        'cli': 'cyclades_cli'
82 554d18b0 Stavros Sachtouris
    },
83 e8bd81eb Stavros Sachtouris
    'network': {
84 fd5db045 Stavros Sachtouris
        'cli': 'cyclades_cli'
85 e8bd81eb Stavros Sachtouris
    },
86 554d18b0 Stavros Sachtouris
    'image': {
87 f7e38cbb Stavros Sachtouris
        'cli': 'image_cli',
88 f7e38cbb Stavros Sachtouris
        'url': 'https://cyclades.okeanos.grnet.gr/plankton'
89 554d18b0 Stavros Sachtouris
    },
90 554d18b0 Stavros Sachtouris
    'astakos': {
91 554d18b0 Stavros Sachtouris
        'cli': 'astakos_cli',
92 b9d07587 Stavros Sachtouris
        'url': 'https://accounts.okeanos.grnet.gr'
93 7493ccb6 Stavros Sachtouris
    }
94 7493ccb6 Stavros Sachtouris
}
95 7493ccb6 Stavros Sachtouris
96 7493ccb6 Stavros Sachtouris
97 7493ccb6 Stavros Sachtouris
class Config(RawConfigParser):
98 7493ccb6 Stavros Sachtouris
    def __init__(self, path=None):
99 7493ccb6 Stavros Sachtouris
        RawConfigParser.__init__(self, dict_type=OrderedDict)
100 7493ccb6 Stavros Sachtouris
        self.path = path or os.environ.get(CONFIG_ENV, CONFIG_PATH)
101 7493ccb6 Stavros Sachtouris
        self._overrides = defaultdict(dict)
102 7493ccb6 Stavros Sachtouris
        self._load_defaults()
103 7493ccb6 Stavros Sachtouris
        self.read(self.path)
104 7493ccb6 Stavros Sachtouris
105 7493ccb6 Stavros Sachtouris
    def _load_defaults(self):
106 7493ccb6 Stavros Sachtouris
        for section, options in DEFAULTS.items():
107 7493ccb6 Stavros Sachtouris
            for option, val in options.items():
108 7493ccb6 Stavros Sachtouris
                self.set(section, option, val)
109 7493ccb6 Stavros Sachtouris
110 8eb8c540 Stavros Sachtouris
    def reload(self):
111 8eb8c540 Stavros Sachtouris
        self = self.__init__(self.path)
112 8eb8c540 Stavros Sachtouris
113 7493ccb6 Stavros Sachtouris
    def apis(self):
114 7493ccb6 Stavros Sachtouris
        return [api for api in self.sections() if api != 'global']
115 7493ccb6 Stavros Sachtouris
116 7493ccb6 Stavros Sachtouris
    def get(self, section, option):
117 7493ccb6 Stavros Sachtouris
        value = self._overrides.get(section, {}).get(option)
118 7493ccb6 Stavros Sachtouris
        if value is not None:
119 7493ccb6 Stavros Sachtouris
            return value
120 7493ccb6 Stavros Sachtouris
121 7493ccb6 Stavros Sachtouris
        try:
122 7493ccb6 Stavros Sachtouris
            return RawConfigParser.get(self, section, option)
123 7493ccb6 Stavros Sachtouris
        except (NoSectionError, NoOptionError):
124 7493ccb6 Stavros Sachtouris
            return DEFAULTS.get(section, {}).get(option)
125 7493ccb6 Stavros Sachtouris
126 7493ccb6 Stavros Sachtouris
    def set(self, section, option, value):
127 7493ccb6 Stavros Sachtouris
        if section not in RawConfigParser.sections(self):
128 7493ccb6 Stavros Sachtouris
            self.add_section(section)
129 7493ccb6 Stavros Sachtouris
        RawConfigParser.set(self, section, option, value)
130 7493ccb6 Stavros Sachtouris
131 3fe56be4 Stavros Sachtouris
    def remove_option(self, section, option, also_remove_default=False):
132 7493ccb6 Stavros Sachtouris
        try:
133 3fe56be4 Stavros Sachtouris
            if also_remove_default:
134 3fe56be4 Stavros Sachtouris
                DEFAULTS[section].pop(option)
135 7493ccb6 Stavros Sachtouris
            RawConfigParser.remove_option(self, section, option)
136 7493ccb6 Stavros Sachtouris
        except NoSectionError:
137 7493ccb6 Stavros Sachtouris
            pass
138 7493ccb6 Stavros Sachtouris
139 57ecec97 Stavros Sachtouris
    def items(self, section, include_defaults=True):
140 26cd03ca Stavros Sachtouris
        try:
141 26cd03ca Stavros Sachtouris
            d = dict(DEFAULTS[section]) if include_defaults else {}
142 26cd03ca Stavros Sachtouris
        except KeyError:
143 26cd03ca Stavros Sachtouris
            d = {}
144 7493ccb6 Stavros Sachtouris
        try:
145 7493ccb6 Stavros Sachtouris
            d.update(RawConfigParser.items(self, section))
146 7493ccb6 Stavros Sachtouris
        except NoSectionError:
147 7493ccb6 Stavros Sachtouris
            pass
148 7493ccb6 Stavros Sachtouris
        return d.items()
149 7493ccb6 Stavros Sachtouris
150 7493ccb6 Stavros Sachtouris
    def override(self, section, option, value):
151 7493ccb6 Stavros Sachtouris
        self._overrides[section][option] = value
152 7493ccb6 Stavros Sachtouris
153 7493ccb6 Stavros Sachtouris
    def write(self):
154 7493ccb6 Stavros Sachtouris
        with open(self.path, 'w') as f:
155 7493ccb6 Stavros Sachtouris
            os.chmod(self.path, 0600)
156 7493ccb6 Stavros Sachtouris
            f.write(HEADER.lstrip())
157 8eb8c540 Stavros Sachtouris
            f.flush()
158 7493ccb6 Stavros Sachtouris
            RawConfigParser.write(self, f)