1#
2# Copyright (C) 2018 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import logging
18import os
19
20
21# In fact, all fields are required. The fields listed below are used
22# to check whether the config class has been properly initialized before
23# generating config file
24REQUIRED_KEYS = [
25    'ssh_public_key_path',
26    'ssh_private_key_path',
27    'project',
28    'client_id',
29    'client_secret'
30    ]
31
32
33class ACloudConfig(object):
34    '''For ACloud configuration file operations.
35
36    Attributes:
37        configs: dict of string:string, configuration keys and values.
38        has_error: bool, whether error occurred.
39    '''
40    configs = {}
41    has_error = False
42
43    def Validate(self):
44        '''Validate config class.
45
46        Check whether required fields has been set.
47        Check whether loading configuration file is success.
48
49        Returns:
50            bool, True if validated.
51        '''
52        for key in REQUIRED_KEYS:
53            if key not in self.configs:
54                logging.error('Required key %s is not '
55                              'set for acloud config' % key)
56                return False
57
58        return not self.has_error
59
60    def Load(self, file_path):
61        '''Load configs from a file.
62
63        Args:
64            file_path: string, path to config file.
65        '''
66        if not os.path.isfile(file_path):
67            logging.error('Failed to read acloud config file %s' % file_path)
68            self.has_error = True
69            return
70
71        separator = ': "'
72
73        with open(file_path, 'r') as f:
74            for line in f:
75                line = line.strip()
76                # Skip empty line and comments
77                if not line or line.startswith('#'):
78                    continue
79
80                idx = line.find(separator)
81
82                if idx < 1 or not line.endswith('"'):
83                    logging.error('Error parsing line %s from '
84                                  'acloud config file %s' % (line, file_path))
85                    self.has_error = True
86                    return
87
88                key = line[:idx]
89                val = line[len(separator) + idx : -1]
90
91                self.configs[key] = val
92
93    def Save(self, file_path):
94        '''Save config to a file.
95
96        Args:
97            file_path: string, path to config file.
98        '''
99        separator = ':'
100
101        with open(file_path, 'w') as f:
102            for key in self.configs:
103                f.write(key + separator + '"%s"' % self.configs[key])