OLD | NEW |
1 # Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/ | 1 # Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/ |
| 2 # Copyright (c) 2011 Chris Moyer http://coredumped.org/ |
2 # | 3 # |
3 # Permission is hereby granted, free of charge, to any person obtaining a | 4 # Permission is hereby granted, free of charge, to any person obtaining a |
4 # copy of this software and associated documentation files (the | 5 # copy of this software and associated documentation files (the |
5 # "Software"), to deal in the Software without restriction, including | 6 # "Software"), to deal in the Software without restriction, including |
6 # without limitation the rights to use, copy, modify, merge, publish, dis- | 7 # without limitation the rights to use, copy, modify, merge, publish, dis- |
7 # tribute, sublicense, and/or sell copies of the Software, and to permit | 8 # tribute, sublicense, and/or sell copies of the Software, and to permit |
8 # persons to whom the Software is furnished to do so, subject to the fol- | 9 # persons to whom the Software is furnished to do so, subject to the fol- |
9 # lowing conditions: | 10 # lowing conditions: |
10 # | 11 # |
11 # The above copyright notice and this permission notice shall be included | 12 # The above copyright notice and this permission notice shall be included |
12 # in all copies or substantial portions of the Software. | 13 # in all copies or substantial portions of the Software. |
13 # | 14 # |
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | 16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | 17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | 18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
20 # IN THE SOFTWARE. | 21 # IN THE SOFTWARE. |
21 # | 22 # |
22 import StringIO, os, re | 23 import StringIO, os, re |
| 24 import warnings |
23 import ConfigParser | 25 import ConfigParser |
24 import boto | 26 import boto |
25 | 27 |
| 28 # If running in Google App Engine there is no "user" and |
| 29 # os.path.expanduser() will fail. Attempt to detect this case and use a |
| 30 # no-op expanduser function in this case. |
| 31 try: |
| 32 os.path.expanduser('~') |
| 33 expanduser = os.path.expanduser |
| 34 except (AttributeError, ImportError): |
| 35 # This is probably running on App Engine. |
| 36 expanduser = (lambda x: x) |
| 37 |
| 38 # By default we use two locations for the boto configurations, |
| 39 # /etc/boto.cfg and ~/.boto (which works on Windows and Unix). |
26 BotoConfigPath = '/etc/boto.cfg' | 40 BotoConfigPath = '/etc/boto.cfg' |
27 BotoConfigLocations = [BotoConfigPath] | 41 BotoConfigLocations = [BotoConfigPath] |
| 42 UserConfigPath = os.path.join(expanduser('~'), '.boto') |
| 43 BotoConfigLocations.append(UserConfigPath) |
| 44 |
| 45 # If there's a BOTO_CONFIG variable set, we load ONLY |
| 46 # that variable |
28 if 'BOTO_CONFIG' in os.environ: | 47 if 'BOTO_CONFIG' in os.environ: |
29 BotoConfigLocations = [os.path.expanduser(os.environ['BOTO_CONFIG'])] | 48 BotoConfigLocations = [expanduser(os.environ['BOTO_CONFIG'])] |
30 elif 'HOME' in os.environ: | 49 |
31 UserConfigPath = os.path.expanduser('~/.boto') | 50 # If there's a BOTO_PATH variable set, we use anything there |
32 BotoConfigLocations.append(UserConfigPath) | 51 # as the current configuration locations, split with colons |
33 else: | 52 elif 'BOTO_PATH' in os.environ: |
34 UserConfigPath = None | 53 BotoConfigLocations = [] |
| 54 for path in os.environ['BOTO_PATH'].split(":"): |
| 55 BotoConfigLocations.append(expanduser(path)) |
| 56 |
35 | 57 |
36 class Config(ConfigParser.SafeConfigParser): | 58 class Config(ConfigParser.SafeConfigParser): |
37 | 59 |
38 def __init__(self, path=None, fp=None, do_load=True): | 60 def __init__(self, path=None, fp=None, do_load=True): |
39 ConfigParser.SafeConfigParser.__init__(self, {'working_dir' : '/mnt/pyam
i', | 61 ConfigParser.SafeConfigParser.__init__(self, {'working_dir' : '/mnt/pyam
i', |
40 'debug' : '0'}) | 62 'debug' : '0'}) |
41 if do_load: | 63 if do_load: |
42 if path: | 64 if path: |
43 self.load_from_path(path) | 65 self.load_from_path(path) |
44 elif fp: | 66 elif fp: |
45 self.readfp(fp) | 67 self.readfp(fp) |
46 else: | 68 else: |
47 self.read(BotoConfigLocations) | 69 self.read(BotoConfigLocations) |
48 if "AWS_CREDENTIAL_FILE" in os.environ: | 70 if "AWS_CREDENTIAL_FILE" in os.environ: |
49 self.load_credential_file(os.path.expanduser(os.environ['AWS_CRE
DENTIAL_FILE'])) | 71 full_path = expanduser(os.environ['AWS_CREDENTIAL_FILE']) |
| 72 try: |
| 73 self.load_credential_file(full_path) |
| 74 except IOError: |
| 75 warnings.warn('Unable to load AWS_CREDENTIAL_FILE (%s)' % fu
ll_path) |
50 | 76 |
51 def load_credential_file(self, path): | 77 def load_credential_file(self, path): |
52 """Load a credential file as is setup like the Java utilities""" | 78 """Load a credential file as is setup like the Java utilities""" |
53 c_data = StringIO.StringIO() | 79 c_data = StringIO.StringIO() |
54 c_data.write("[Credentials]\n") | 80 c_data.write("[Credentials]\n") |
55 for line in open(path, "r").readlines(): | 81 for line in open(path, "r").readlines(): |
56 c_data.write(line.replace("AWSAccessKeyId", "aws_access_key_id").rep
lace("AWSSecretKey", "aws_secret_access_key")) | 82 c_data.write(line.replace("AWSAccessKeyId", "aws_access_key_id").rep
lace("AWSSecretKey", "aws_secret_access_key")) |
57 c_data.seek(0) | 83 c_data.seek(0) |
58 self.readfp(c_data) | 84 self.readfp(c_data) |
59 | 85 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 fp = StringIO.StringIO() | 189 fp = StringIO.StringIO() |
164 for section in self.sections(): | 190 for section in self.sections(): |
165 fp.write('[%s]\n' % section) | 191 fp.write('[%s]\n' % section) |
166 for option in self.options(section): | 192 for option in self.options(section): |
167 if option == 'aws_secret_access_key': | 193 if option == 'aws_secret_access_key': |
168 fp.write('%s = xxxxxxxxxxxxxxxxxx\n' % option) | 194 fp.write('%s = xxxxxxxxxxxxxxxxxx\n' % option) |
169 else: | 195 else: |
170 fp.write('%s = %s\n' % (option, self.get(section, option))) | 196 fp.write('%s = %s\n' % (option, self.get(section, option))) |
171 | 197 |
172 def dump_to_sdb(self, domain_name, item_name): | 198 def dump_to_sdb(self, domain_name, item_name): |
173 import simplejson | 199 try: |
| 200 import simplejson as json |
| 201 except ImportError: |
| 202 import json |
| 203 |
174 sdb = boto.connect_sdb() | 204 sdb = boto.connect_sdb() |
175 domain = sdb.lookup(domain_name) | 205 domain = sdb.lookup(domain_name) |
176 if not domain: | 206 if not domain: |
177 domain = sdb.create_domain(domain_name) | 207 domain = sdb.create_domain(domain_name) |
178 item = domain.new_item(item_name) | 208 item = domain.new_item(item_name) |
179 item.active = False | 209 item.active = False |
180 for section in self.sections(): | 210 for section in self.sections(): |
181 d = {} | 211 d = {} |
182 for option in self.options(section): | 212 for option in self.options(section): |
183 d[option] = self.get(section, option) | 213 d[option] = self.get(section, option) |
184 item[section] = simplejson.dumps(d) | 214 item[section] = json.dumps(d) |
185 item.save() | 215 item.save() |
186 | 216 |
187 def load_from_sdb(self, domain_name, item_name): | 217 def load_from_sdb(self, domain_name, item_name): |
188 import simplejson | 218 try: |
| 219 import json |
| 220 except ImportError: |
| 221 import simplejson as json |
| 222 |
189 sdb = boto.connect_sdb() | 223 sdb = boto.connect_sdb() |
190 domain = sdb.lookup(domain_name) | 224 domain = sdb.lookup(domain_name) |
191 item = domain.get_item(item_name) | 225 item = domain.get_item(item_name) |
192 for section in item.keys(): | 226 for section in item.keys(): |
193 if not self.has_section(section): | 227 if not self.has_section(section): |
194 self.add_section(section) | 228 self.add_section(section) |
195 d = simplejson.loads(item[section]) | 229 d = json.loads(item[section]) |
196 for attr_name in d.keys(): | 230 for attr_name in d.keys(): |
197 attr_value = d[attr_name] | 231 attr_value = d[attr_name] |
198 if attr_value == None: | 232 if attr_value == None: |
199 attr_value = 'None' | 233 attr_value = 'None' |
200 if isinstance(attr_value, bool): | 234 if isinstance(attr_value, bool): |
201 self.setbool(section, attr_name, attr_value) | 235 self.setbool(section, attr_name, attr_value) |
202 else: | 236 else: |
203 self.set(section, attr_name, attr_value) | 237 self.set(section, attr_name, attr_value) |
OLD | NEW |