summaryrefslogtreecommitdiff
path: root/cloudinit/sources
diff options
context:
space:
mode:
authorScott Moser <smoser@ubuntu.com>2012-09-24 17:13:38 -0400
committerScott Moser <smoser@ubuntu.com>2012-09-24 17:13:38 -0400
commit70cc7536f45a8d7052617ad88e2816291db0a309 (patch)
treef702fe609bd001b45c48ef1c5f06b19c9c55babf /cloudinit/sources
parente3b29659672acd757122bc5f90a13670b96b6952 (diff)
downloadvyos-cloud-init-70cc7536f45a8d7052617ad88e2816291db0a309.tar.gz
vyos-cloud-init-70cc7536f45a8d7052617ad88e2816291db0a309.zip
DataSourceMAAS: if a oauth request fails due to 403 try updating local time
In the event of a 403 (Unauthorized) in oauth, try set a 'oauth_clockskew' variable. In future headers, use a time created by 'time.time() + self.oauth_clockskew'. The idea here is that if the local time is bad (or even if the server time is bad) we will essentially use something that should be similar to the remote clock. This fixes LP: #978127. LP: #978127
Diffstat (limited to 'cloudinit/sources')
-rw-r--r--cloudinit/sources/DataSourceMAAS.py43
1 files changed, 39 insertions, 4 deletions
diff --git a/cloudinit/sources/DataSourceMAAS.py b/cloudinit/sources/DataSourceMAAS.py
index c568d365..581e9a4b 100644
--- a/cloudinit/sources/DataSourceMAAS.py
+++ b/cloudinit/sources/DataSourceMAAS.py
@@ -18,6 +18,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+from email.utils import parsedate
import errno
import oauth.oauth as oauth
import os
@@ -46,6 +47,7 @@ class DataSourceMAAS(sources.DataSource):
sources.DataSource.__init__(self, sys_cfg, distro, paths)
self.base_url = None
self.seed_dir = os.path.join(paths.seed_dir, 'maas')
+ self.oauth_clockskew = None
def __str__(self):
return "%s [%s]" % (util.obj_name(self), self.base_url)
@@ -95,11 +97,17 @@ class DataSourceMAAS(sources.DataSource):
return {}
consumer_secret = mcfg.get('consumer_secret', "")
+
+ timestamp = None
+ if self.oauth_clockskew:
+ timestamp = int(time.time()) + self.oauth_clockskew
+
return oauth_headers(url=url,
consumer_key=mcfg['consumer_key'],
token_key=mcfg['token_key'],
token_secret=mcfg['token_secret'],
- consumer_secret=consumer_secret)
+ consumer_secret=consumer_secret,
+ timestamp=timestamp)
def wait_for_metadata_service(self, url):
mcfg = self.ds_cfg
@@ -124,7 +132,7 @@ class DataSourceMAAS(sources.DataSource):
check_url = "%s/%s/meta-data/instance-id" % (url, MD_VERSION)
urls = [check_url]
url = uhelp.wait_for_url(urls=urls, max_wait=max_wait,
- timeout=timeout, status_cb=LOG.warn,
+ timeout=timeout, exception_cb=self._except_cb,
headers_cb=self.md_headers)
if url:
@@ -135,6 +143,26 @@ class DataSourceMAAS(sources.DataSource):
return bool(url)
+ def _except_cb(self, msg, exception):
+ if not (isinstance(exception, urllib2.HTTPError) and
+ exception.code == 403):
+ return
+ if 'date' not in exception.headers:
+ LOG.warn("date field not in 403 headers")
+ return
+
+ date = exception.headers['date']
+
+ try:
+ ret_time = time.mktime(parsedate(date))
+ except:
+ LOG.warn("failed to convert datetime '%s'")
+ return
+
+ self.oauth_clockskew = int(ret_time - time.time())
+ LOG.warn("set oauth clockskew to %d" % self.oauth_clockskew)
+ return
+
def read_maas_seed_dir(seed_d):
"""
@@ -229,13 +257,20 @@ def check_seed_contents(content, seed):
return (userdata, md)
-def oauth_headers(url, consumer_key, token_key, token_secret, consumer_secret):
+def oauth_headers(url, consumer_key, token_key, token_secret, consumer_secret,
+ timestamp=None):
consumer = oauth.OAuthConsumer(consumer_key, consumer_secret)
token = oauth.OAuthToken(token_key, token_secret)
+
+ if timestamp is None:
+ ts = int(time.time())
+ else:
+ ts = timestamp
+
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
- 'oauth_timestamp': int(time.time()),
+ 'oauth_timestamp': ts,
'oauth_token': token.key,
'oauth_consumer_key': consumer.key,
}