~ubuntu-branches/ubuntu/quantal/cloud-init/quantal

« back to all changes in this revision

Viewing changes to cloudinit/sources/DataSourceMAAS.py

  • Committer: Package Import Robot
  • Author(s): Scott Moser
  • Date: 2012-09-30 14:29:04 UTC
  • Revision ID: package-import@ubuntu.com-20120930142904-nq8fkve62i0xytqz
* add CloudStack to DataSources listed by dpkg-reconfigure (LP: #1002155)
* New upstream snapshot.
  * 0440 permissions on /etc/sudoers.d files rather than 0644
  * get host ssh keys to the console (LP: #1055688)
  * MAAS DataSource adjust timestamp in oauth header to one based on the
    timestamp in the response of a 403.  This accounts for a bad local
    clock. (LP: #978127)
  * re-start the salt daemon rather than start to ensure config changes
    are taken.
  * allow for python unicode types in yaml that is loaded.
  * cleanup in how config modules get at users and groups.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#    You should have received a copy of the GNU General Public License
19
19
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
20
 
 
21
from email.utils import parsedate
21
22
import errno
22
23
import oauth.oauth as oauth
23
24
import os
46
47
        sources.DataSource.__init__(self, sys_cfg, distro, paths)
47
48
        self.base_url = None
48
49
        self.seed_dir = os.path.join(paths.seed_dir, 'maas')
 
50
        self.oauth_clockskew = None
49
51
 
50
52
    def __str__(self):
51
53
        return "%s [%s]" % (util.obj_name(self), self.base_url)
95
97
                return {}
96
98
 
97
99
        consumer_secret = mcfg.get('consumer_secret', "")
 
100
 
 
101
        timestamp = None
 
102
        if self.oauth_clockskew:
 
103
            timestamp = int(time.time()) + self.oauth_clockskew
 
104
 
98
105
        return oauth_headers(url=url,
99
106
                             consumer_key=mcfg['consumer_key'],
100
107
                             token_key=mcfg['token_key'],
101
108
                             token_secret=mcfg['token_secret'],
102
 
                             consumer_secret=consumer_secret)
 
109
                             consumer_secret=consumer_secret,
 
110
                             timestamp=timestamp)
103
111
 
104
112
    def wait_for_metadata_service(self, url):
105
113
        mcfg = self.ds_cfg
124
132
        check_url = "%s/%s/meta-data/instance-id" % (url, MD_VERSION)
125
133
        urls = [check_url]
126
134
        url = uhelp.wait_for_url(urls=urls, max_wait=max_wait,
127
 
                                 timeout=timeout, status_cb=LOG.warn,
 
135
                                 timeout=timeout, exception_cb=self._except_cb,
128
136
                                 headers_cb=self.md_headers)
129
137
 
130
138
        if url:
135
143
 
136
144
        return bool(url)
137
145
 
 
146
    def _except_cb(self, msg, exception):
 
147
        if not (isinstance(exception, urllib2.HTTPError) and
 
148
                exception.code == 403):
 
149
            return
 
150
        if 'date' not in exception.headers:
 
151
            LOG.warn("date field not in 403 headers")
 
152
            return
 
153
 
 
154
        date = exception.headers['date']
 
155
 
 
156
        try:
 
157
            ret_time = time.mktime(parsedate(date))
 
158
        except:
 
159
            LOG.warn("failed to convert datetime '%s'")
 
160
            return
 
161
 
 
162
        self.oauth_clockskew = int(ret_time - time.time())
 
163
        LOG.warn("set oauth clockskew to %d" % self.oauth_clockskew)
 
164
        return
 
165
 
138
166
 
139
167
def read_maas_seed_dir(seed_d):
140
168
    """
229
257
    return (userdata, md)
230
258
 
231
259
 
232
 
def oauth_headers(url, consumer_key, token_key, token_secret, consumer_secret):
 
260
def oauth_headers(url, consumer_key, token_key, token_secret, consumer_secret,
 
261
                  timestamp=None):
233
262
    consumer = oauth.OAuthConsumer(consumer_key, consumer_secret)
234
263
    token = oauth.OAuthToken(token_key, token_secret)
 
264
 
 
265
    if timestamp is None:
 
266
        ts = int(time.time())
 
267
    else:
 
268
        ts = timestamp
 
269
 
235
270
    params = {
236
271
        'oauth_version': "1.0",
237
272
        'oauth_nonce': oauth.generate_nonce(),
238
 
        'oauth_timestamp': int(time.time()),
 
273
        'oauth_timestamp': ts,
239
274
        'oauth_token': token.key,
240
275
        'oauth_consumer_key': consumer.key,
241
276
    }
301
336
            'token_secret': args.tsec, 'consumer_secret': args.csec}
302
337
 
303
338
        if args.config:
304
 
            import yaml
305
339
            with open(args.config) as fp:
306
 
                cfg = yaml.safe_load(fp)
 
340
                cfg = util.load_yaml(fp.read())
307
341
            if 'datasource' in cfg:
308
342
                cfg = cfg['datasource']['MAAS']
309
343
            for key in creds.keys():