blob: 17803782e8c928fcb00db53e616555e71d7538d9 [file] [log] [blame]
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11001# Copyright 2014 Rackspace Australia
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import hmac
16from hashlib import sha1
17from time import time
18import os
19import random
Christian Berendte35b99c2014-06-06 16:57:47 +020020import six
Joshua Hesketh36c3fa52014-01-22 11:40:52 +110021import string
22import swiftclient
23import urlparse
24
25
26class Swift(object):
27 def __init__(self, config):
28 self.config = config
29 self.connection = False
30 if self.config.has_option('swift', 'X-Account-Meta-Temp-Url-Key'):
31 self.secure_key = self.config.get('swift',
32 'X-Account-Meta-Temp-Url-Key')
33 else:
34 self.secure_key = ''.join(
35 random.choice(string.ascii_uppercase + string.digits)
36 for x in range(20)
37 )
38
39 self.connect()
40
41 def connect(self):
42 if self.config.has_section('swift'):
43 # required
44 authurl = self.config.get('swift', 'authurl')
45
46 user = (self.config.get('swift', 'user')
47 if self.config.has_option('swift', 'user') else None)
48 key = (self.config.get('swift', 'key')
49 if self.config.has_option('swift', 'key') else None)
50 retries = (self.config.get('swift', 'retries')
51 if self.config.has_option('swift', 'retries') else 5)
52 preauthurl = (self.config.get('swift', 'preauthurl')
53 if self.config.has_option('swift', 'preauthurl')
54 else None)
55 preauthtoken = (self.config.get('swift', 'preauthtoken')
56 if self.config.has_option('swift', 'preauthtoken')
57 else None)
58 snet = (self.config.get('swift', 'snet')
59 if self.config.has_option('swift', 'snet') else False)
60 starting_backoff = (self.config.get('swift', 'starting_backoff')
61 if self.config.has_option('swift',
62 'starting_backoff')
63 else 1)
64 max_backoff = (self.config.get('swift', 'max_backoff')
65 if self.config.has_option('swift', 'max_backoff')
66 else 64)
67 tenant_name = (self.config.get('swift', 'tenant_name')
68 if self.config.has_option('swift', 'tenant_name')
69 else None)
70 auth_version = (self.config.get('swift', 'auth_version')
71 if self.config.has_option('swift', 'auth_version')
72 else 2.0)
73 cacert = (self.config.get('swift', 'cacert')
74 if self.config.has_option('swift', 'cacert') else None)
75 insecure = (self.config.get('swift', 'insecure')
76 if self.config.has_option('swift', 'insecure')
77 else False)
78 ssl_compression = (self.config.get('swift', 'ssl_compression')
79 if self.config.has_option('swift',
80 'ssl_compression')
81 else True)
82
83 available_os_options = ['tenant_id', 'auth_token', 'service_type',
84 'endpoint_type', 'tenant_name',
85 'object_storage_url', 'region_name']
86
87 os_options = {}
88 for os_option in available_os_options:
89 if self.config.has_option('swift', os_option):
90 os_options[os_option] = self.config.get('swift', os_option)
91
92 self.connection = swiftclient.client.Connection(
93 authurl=authurl, user=user, key=key, retries=retries,
94 preauthurl=preauthurl, preauthtoken=preauthtoken, snet=snet,
95 starting_backoff=starting_backoff, max_backoff=max_backoff,
96 tenant_name=tenant_name, os_options=os_options,
97 auth_version=auth_version, cacert=cacert, insecure=insecure,
98 ssl_compression=ssl_compression)
99
100 # Tell swift of our key
101 headers = {}
102 headers['X-Account-Meta-Temp-Url-Key'] = self.secure_key
103 self.connection.post_account(headers)
104
105 self.storage_url, self.auth_token = self.connection.get_auth()
106
107 def generate_form_post_middleware_params(self, destination_prefix='',
108 **kwargs):
109 """Generate the FormPost middleware params for the given settings"""
110
111 # Define the available settings and their defaults
112 settings = {
113 'container': '',
114 'expiry': 7200,
115 'max_file_size': 104857600,
116 'max_file_count': 10,
117 'file_path_prefix': ''
118 }
119
Christian Berendte35b99c2014-06-06 16:57:47 +0200120 for key, default in six.iteritems(settings):
James E. Blaird6500232014-06-23 15:05:48 -0700121 # TODO(jeblair): Remove the following two lines after a
122 # deprecation period for the underscore variants of the
123 # settings in YAML.
Joshua Hesketh36c3fa52014-01-22 11:40:52 +1100124 if key in kwargs:
125 settings[key] = kwargs[key]
James E. Blaird6500232014-06-23 15:05:48 -0700126 # Since we prefer '-' rather than '_' in YAML, look up
127 # keys there using hyphens. Continue to use underscores
128 # everywhere else.
129 altkey = key.replace('_', '-')
130 if altkey in kwargs:
131 settings[key] = kwargs[altkey]
Joshua Hesketh36c3fa52014-01-22 11:40:52 +1100132 elif self.config.has_option('swift', 'default_' + key):
133 settings[key] = self.config.get('swift', 'default_' + key)
134
135 expires = int(time() + settings['expiry'])
136 redirect = ''
137
138 url = os.path.join(self.storage_url, settings['container'],
139 settings['file_path_prefix'],
140 destination_prefix)
141 u = urlparse.urlparse(url)
142
143 hmac_body = '%s\n%s\n%s\n%s\n%s' % (u.path, redirect,
144 settings['max_file_size'],
145 settings['max_file_count'],
146 expires)
147
148 signature = hmac.new(self.secure_key, hmac_body, sha1).hexdigest()
149
150 return url, hmac_body, signature