Mercurial > repos > bcclaywell > argo_navis
comparison venv/lib/python2.7/site-packages/boto/regioninfo.py @ 0:d67268158946 draft
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
author | bcclaywell |
---|---|
date | Mon, 12 Oct 2015 17:43:33 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d67268158946 |
---|---|
1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ | |
2 # Copyright (c) 2010, Eucalyptus Systems, Inc. | |
3 # All rights reserved. | |
4 # | |
5 # Permission is hereby granted, free of charge, to any person obtaining a | |
6 # copy of this software and associated documentation files (the | |
7 # "Software"), to deal in the Software without restriction, including | |
8 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
9 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
10 # persons to whom the Software is furnished to do so, subject to the fol- | |
11 # lowing conditions: | |
12 # | |
13 # The above copyright notice and this permission notice shall be included | |
14 # in all copies or substantial portions of the Software. | |
15 # | |
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
17 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
18 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
19 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
20 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
22 # IN THE SOFTWARE. | |
23 import os | |
24 | |
25 import boto | |
26 from boto.compat import json | |
27 from boto.exception import BotoClientError | |
28 | |
29 | |
30 def load_endpoint_json(path): | |
31 """ | |
32 Loads a given JSON file & returns it. | |
33 | |
34 :param path: The path to the JSON file | |
35 :type path: string | |
36 | |
37 :returns: The loaded data | |
38 """ | |
39 with open(path, 'r') as endpoints_file: | |
40 return json.load(endpoints_file) | |
41 | |
42 | |
43 def merge_endpoints(defaults, additions): | |
44 """ | |
45 Given an existing set of endpoint data, this will deep-update it with | |
46 any similarly structured data in the additions. | |
47 | |
48 :param defaults: The existing endpoints data | |
49 :type defaults: dict | |
50 | |
51 :param defaults: The additional endpoints data | |
52 :type defaults: dict | |
53 | |
54 :returns: The modified endpoints data | |
55 :rtype: dict | |
56 """ | |
57 # We can't just do an ``defaults.update(...)`` here, as that could | |
58 # *overwrite* regions if present in both. | |
59 # We'll iterate instead, essentially doing a deeper merge. | |
60 for service, region_info in additions.items(): | |
61 # Set the default, if not present, to an empty dict. | |
62 defaults.setdefault(service, {}) | |
63 defaults[service].update(region_info) | |
64 | |
65 return defaults | |
66 | |
67 | |
68 def load_regions(): | |
69 """ | |
70 Actually load the region/endpoint information from the JSON files. | |
71 | |
72 By default, this loads from the default included ``boto/endpoints.json`` | |
73 file. | |
74 | |
75 Users can override/extend this by supplying either a ``BOTO_ENDPOINTS`` | |
76 environment variable or a ``endpoints_path`` config variable, either of | |
77 which should be an absolute path to the user's JSON file. | |
78 | |
79 :returns: The endpoints data | |
80 :rtype: dict | |
81 """ | |
82 # Load the defaults first. | |
83 endpoints = load_endpoint_json(boto.ENDPOINTS_PATH) | |
84 additional_path = None | |
85 | |
86 # Try the ENV var. If not, check the config file. | |
87 if os.environ.get('BOTO_ENDPOINTS'): | |
88 additional_path = os.environ['BOTO_ENDPOINTS'] | |
89 elif boto.config.get('Boto', 'endpoints_path'): | |
90 additional_path = boto.config.get('Boto', 'endpoints_path') | |
91 | |
92 # If there's a file provided, we'll load it & additively merge it into | |
93 # the endpoints. | |
94 if additional_path: | |
95 additional = load_endpoint_json(additional_path) | |
96 endpoints = merge_endpoints(endpoints, additional) | |
97 | |
98 return endpoints | |
99 | |
100 | |
101 def get_regions(service_name, region_cls=None, connection_cls=None): | |
102 """ | |
103 Given a service name (like ``ec2``), returns a list of ``RegionInfo`` | |
104 objects for that service. | |
105 | |
106 This leverages the ``endpoints.json`` file (+ optional user overrides) to | |
107 configure/construct all the objects. | |
108 | |
109 :param service_name: The name of the service to construct the ``RegionInfo`` | |
110 objects for. Ex: ``ec2``, ``s3``, ``sns``, etc. | |
111 :type service_name: string | |
112 | |
113 :param region_cls: (Optional) The class to use when constructing. By | |
114 default, this is ``RegionInfo``. | |
115 :type region_cls: class | |
116 | |
117 :param connection_cls: (Optional) The connection class for the | |
118 ``RegionInfo`` object. Providing this allows the ``connect`` method on | |
119 the ``RegionInfo`` to work. Default is ``None`` (no connection). | |
120 :type connection_cls: class | |
121 | |
122 :returns: A list of configured ``RegionInfo`` objects | |
123 :rtype: list | |
124 """ | |
125 endpoints = load_regions() | |
126 | |
127 if service_name not in endpoints: | |
128 raise BotoClientError( | |
129 "Service '%s' not found in endpoints." % service_name | |
130 ) | |
131 | |
132 if region_cls is None: | |
133 region_cls = RegionInfo | |
134 | |
135 region_objs = [] | |
136 | |
137 for region_name, endpoint in endpoints.get(service_name, {}).items(): | |
138 region_objs.append( | |
139 region_cls( | |
140 name=region_name, | |
141 endpoint=endpoint, | |
142 connection_cls=connection_cls | |
143 ) | |
144 ) | |
145 | |
146 return region_objs | |
147 | |
148 | |
149 class RegionInfo(object): | |
150 """ | |
151 Represents an AWS Region | |
152 """ | |
153 | |
154 def __init__(self, connection=None, name=None, endpoint=None, | |
155 connection_cls=None): | |
156 self.connection = connection | |
157 self.name = name | |
158 self.endpoint = endpoint | |
159 self.connection_cls = connection_cls | |
160 | |
161 def __repr__(self): | |
162 return 'RegionInfo:%s' % self.name | |
163 | |
164 def startElement(self, name, attrs, connection): | |
165 return None | |
166 | |
167 def endElement(self, name, value, connection): | |
168 if name == 'regionName': | |
169 self.name = value | |
170 elif name == 'regionEndpoint': | |
171 self.endpoint = value | |
172 else: | |
173 setattr(self, name, value) | |
174 | |
175 def connect(self, **kw_params): | |
176 """ | |
177 Connect to this Region's endpoint. Returns an connection | |
178 object pointing to the endpoint associated with this region. | |
179 You may pass any of the arguments accepted by the connection | |
180 class's constructor as keyword arguments and they will be | |
181 passed along to the connection object. | |
182 | |
183 :rtype: Connection object | |
184 :return: The connection to this regions endpoint | |
185 """ | |
186 if self.connection_cls: | |
187 return self.connection_cls(region=self, **kw_params) |