| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2010 Mitch Garnaat http://garnaat.org/ | |
| 2 # Copyright 2010 Google Inc. | |
| 3 # Copyright (c) 2010, Eucalyptus Systems, Inc. | |
| 4 # All rights reserved. | |
| 5 # | |
| 6 # Permission is hereby granted, free of charge, to any person obtaining a | |
| 7 # copy of this software and associated documentation files (the | |
| 8 # "Software"), to deal in the Software without restriction, including | |
| 9 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
| 10 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
| 11 # persons to whom the Software is furnished to do so, subject to the fol- | |
| 12 # lowing conditions: | |
| 13 # | |
| 14 # The above copyright notice and this permission notice shall be included | |
| 15 # in all copies or substantial portions of the Software. | |
| 16 # | |
| 17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 18 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
| 19 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
| 20 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
| 21 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
| 23 # IN THE SOFTWARE. | |
| 24 """ | |
| 25 This class encapsulates the provider-specific header differences. | |
| 26 """ | |
| 27 | |
| 28 import os | |
| 29 import boto | |
| 30 from boto import config | |
| 31 from boto.gs.acl import ACL | |
| 32 from boto.gs.acl import CannedACLStrings as CannedGSACLStrings | |
| 33 from boto.s3.acl import CannedACLStrings as CannedS3ACLStrings | |
| 34 from boto.s3.acl import Policy | |
| 35 | |
| 36 HEADER_PREFIX_KEY = 'header_prefix' | |
| 37 METADATA_PREFIX_KEY = 'metadata_prefix' | |
| 38 | |
| 39 AWS_HEADER_PREFIX = 'x-amz-' | |
| 40 GOOG_HEADER_PREFIX = 'x-goog-' | |
| 41 | |
| 42 ACL_HEADER_KEY = 'acl-header' | |
| 43 AUTH_HEADER_KEY = 'auth-header' | |
| 44 COPY_SOURCE_HEADER_KEY = 'copy-source-header' | |
| 45 COPY_SOURCE_VERSION_ID_HEADER_KEY = 'copy-source-version-id-header' | |
| 46 DELETE_MARKER_HEADER_KEY = 'delete-marker-header' | |
| 47 DATE_HEADER_KEY = 'date-header' | |
| 48 METADATA_DIRECTIVE_HEADER_KEY = 'metadata-directive-header' | |
| 49 RESUMABLE_UPLOAD_HEADER_KEY = 'resumable-upload-header' | |
| 50 SECURITY_TOKEN_HEADER_KEY = 'security-token-header' | |
| 51 STORAGE_CLASS_HEADER_KEY = 'storage-class' | |
| 52 MFA_HEADER_KEY = 'mfa-header' | |
| 53 VERSION_ID_HEADER_KEY = 'version-id-header' | |
| 54 | |
| 55 STORAGE_COPY_ERROR = 'StorageCopyError' | |
| 56 STORAGE_CREATE_ERROR = 'StorageCreateError' | |
| 57 STORAGE_DATA_ERROR = 'StorageDataError' | |
| 58 STORAGE_PERMISSIONS_ERROR = 'StoragePermissionsError' | |
| 59 STORAGE_RESPONSE_ERROR = 'StorageResponseError' | |
| 60 | |
| 61 | |
| 62 class Provider(object): | |
| 63 | |
| 64 CredentialMap = { | |
| 65 'aws' : ('aws_access_key_id', 'aws_secret_access_key'), | |
| 66 'google' : ('gs_access_key_id', 'gs_secret_access_key'), | |
| 67 } | |
| 68 | |
| 69 AclClassMap = { | |
| 70 'aws' : Policy, | |
| 71 'google' : ACL | |
| 72 } | |
| 73 | |
| 74 CannedAclsMap = { | |
| 75 'aws' : CannedS3ACLStrings, | |
| 76 'google' : CannedGSACLStrings | |
| 77 } | |
| 78 | |
| 79 HostKeyMap = { | |
| 80 'aws' : 's3', | |
| 81 'google' : 'gs' | |
| 82 } | |
| 83 | |
| 84 HeaderInfoMap = { | |
| 85 'aws' : { | |
| 86 HEADER_PREFIX_KEY : AWS_HEADER_PREFIX, | |
| 87 METADATA_PREFIX_KEY : AWS_HEADER_PREFIX + 'meta-', | |
| 88 ACL_HEADER_KEY : AWS_HEADER_PREFIX + 'acl', | |
| 89 AUTH_HEADER_KEY : 'AWS', | |
| 90 COPY_SOURCE_HEADER_KEY : AWS_HEADER_PREFIX + 'copy-source', | |
| 91 COPY_SOURCE_VERSION_ID_HEADER_KEY : AWS_HEADER_PREFIX + | |
| 92 'copy-source-version-id', | |
| 93 DATE_HEADER_KEY : AWS_HEADER_PREFIX + 'date', | |
| 94 DELETE_MARKER_HEADER_KEY : AWS_HEADER_PREFIX + 'delete-marker', | |
| 95 METADATA_DIRECTIVE_HEADER_KEY : AWS_HEADER_PREFIX + | |
| 96 'metadata-directive', | |
| 97 RESUMABLE_UPLOAD_HEADER_KEY : None, | |
| 98 SECURITY_TOKEN_HEADER_KEY : AWS_HEADER_PREFIX + 'security-token', | |
| 99 VERSION_ID_HEADER_KEY : AWS_HEADER_PREFIX + 'version-id', | |
| 100 STORAGE_CLASS_HEADER_KEY : AWS_HEADER_PREFIX + 'storage-class', | |
| 101 MFA_HEADER_KEY : AWS_HEADER_PREFIX + 'mfa', | |
| 102 }, | |
| 103 'google' : { | |
| 104 HEADER_PREFIX_KEY : GOOG_HEADER_PREFIX, | |
| 105 METADATA_PREFIX_KEY : GOOG_HEADER_PREFIX + 'meta-', | |
| 106 ACL_HEADER_KEY : GOOG_HEADER_PREFIX + 'acl', | |
| 107 AUTH_HEADER_KEY : 'GOOG1', | |
| 108 COPY_SOURCE_HEADER_KEY : GOOG_HEADER_PREFIX + 'copy-source', | |
| 109 COPY_SOURCE_VERSION_ID_HEADER_KEY : GOOG_HEADER_PREFIX + | |
| 110 'copy-source-version-id', | |
| 111 DATE_HEADER_KEY : GOOG_HEADER_PREFIX + 'date', | |
| 112 DELETE_MARKER_HEADER_KEY : GOOG_HEADER_PREFIX + 'delete-marker', | |
| 113 METADATA_DIRECTIVE_HEADER_KEY : GOOG_HEADER_PREFIX + | |
| 114 'metadata-directive', | |
| 115 RESUMABLE_UPLOAD_HEADER_KEY : GOOG_HEADER_PREFIX + 'resumable', | |
| 116 SECURITY_TOKEN_HEADER_KEY : GOOG_HEADER_PREFIX + 'security-token', | |
| 117 # Note that this version header is not to be confused with | |
| 118 # the Google Storage 'x-goog-api-version' header. | |
| 119 VERSION_ID_HEADER_KEY : GOOG_HEADER_PREFIX + 'version-id', | |
| 120 STORAGE_CLASS_HEADER_KEY : None, | |
| 121 MFA_HEADER_KEY : None, | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 ErrorMap = { | |
| 126 'aws' : { | |
| 127 STORAGE_COPY_ERROR : boto.exception.S3CopyError, | |
| 128 STORAGE_CREATE_ERROR : boto.exception.S3CreateError, | |
| 129 STORAGE_DATA_ERROR : boto.exception.S3DataError, | |
| 130 STORAGE_PERMISSIONS_ERROR : boto.exception.S3PermissionsError, | |
| 131 STORAGE_RESPONSE_ERROR : boto.exception.S3ResponseError, | |
| 132 }, | |
| 133 'google' : { | |
| 134 STORAGE_COPY_ERROR : boto.exception.GSCopyError, | |
| 135 STORAGE_CREATE_ERROR : boto.exception.GSCreateError, | |
| 136 STORAGE_DATA_ERROR : boto.exception.GSDataError, | |
| 137 STORAGE_PERMISSIONS_ERROR : boto.exception.GSPermissionsError, | |
| 138 STORAGE_RESPONSE_ERROR : boto.exception.GSResponseError, | |
| 139 } | |
| 140 } | |
| 141 | |
| 142 def __init__(self, name, access_key=None, secret_key=None): | |
| 143 self.host = None | |
| 144 self.access_key = access_key | |
| 145 self.secret_key = secret_key | |
| 146 self.name = name | |
| 147 self.acl_class = self.AclClassMap[self.name] | |
| 148 self.canned_acls = self.CannedAclsMap[self.name] | |
| 149 self.get_credentials(access_key, secret_key) | |
| 150 self.configure_headers() | |
| 151 self.configure_errors() | |
| 152 # allow config file to override default host | |
| 153 host_opt_name = '%s_host' % self.HostKeyMap[self.name] | |
| 154 if config.has_option('Credentials', host_opt_name): | |
| 155 self.host = config.get('Credentials', host_opt_name) | |
| 156 | |
| 157 def get_credentials(self, access_key=None, secret_key=None): | |
| 158 access_key_name, secret_key_name = self.CredentialMap[self.name] | |
| 159 if access_key is not None: | |
| 160 self.access_key = access_key | |
| 161 elif os.environ.has_key(access_key_name.upper()): | |
| 162 self.access_key = os.environ[access_key_name.upper()] | |
| 163 elif config.has_option('Credentials', access_key_name): | |
| 164 self.access_key = config.get('Credentials', access_key_name) | |
| 165 | |
| 166 if secret_key is not None: | |
| 167 self.secret_key = secret_key | |
| 168 elif os.environ.has_key(secret_key_name.upper()): | |
| 169 self.secret_key = os.environ[secret_key_name.upper()] | |
| 170 elif config.has_option('Credentials', secret_key_name): | |
| 171 self.secret_key = config.get('Credentials', secret_key_name) | |
| 172 if isinstance(self.secret_key, unicode): | |
| 173 # the secret key must be bytes and not unicode to work | |
| 174 # properly with hmac.new (see http://bugs.python.org/issue5285) | |
| 175 self.secret_key = str(self.secret_key) | |
| 176 | |
| 177 def configure_headers(self): | |
| 178 header_info_map = self.HeaderInfoMap[self.name] | |
| 179 self.metadata_prefix = header_info_map[METADATA_PREFIX_KEY] | |
| 180 self.header_prefix = header_info_map[HEADER_PREFIX_KEY] | |
| 181 self.acl_header = header_info_map[ACL_HEADER_KEY] | |
| 182 self.auth_header = header_info_map[AUTH_HEADER_KEY] | |
| 183 self.copy_source_header = header_info_map[COPY_SOURCE_HEADER_KEY] | |
| 184 self.copy_source_version_id = header_info_map[ | |
| 185 COPY_SOURCE_VERSION_ID_HEADER_KEY] | |
| 186 self.date_header = header_info_map[DATE_HEADER_KEY] | |
| 187 self.delete_marker = header_info_map[DELETE_MARKER_HEADER_KEY] | |
| 188 self.metadata_directive_header = ( | |
| 189 header_info_map[METADATA_DIRECTIVE_HEADER_KEY]) | |
| 190 self.security_token_header = header_info_map[SECURITY_TOKEN_HEADER_KEY] | |
| 191 self.resumable_upload_header = ( | |
| 192 header_info_map[RESUMABLE_UPLOAD_HEADER_KEY]) | |
| 193 self.storage_class_header = header_info_map[STORAGE_CLASS_HEADER_KEY] | |
| 194 self.version_id = header_info_map[VERSION_ID_HEADER_KEY] | |
| 195 self.mfa_header = header_info_map[MFA_HEADER_KEY] | |
| 196 | |
| 197 def configure_errors(self): | |
| 198 error_map = self.ErrorMap[self.name] | |
| 199 self.storage_copy_error = error_map[STORAGE_COPY_ERROR] | |
| 200 self.storage_create_error = error_map[STORAGE_CREATE_ERROR] | |
| 201 self.storage_data_error = error_map[STORAGE_DATA_ERROR] | |
| 202 self.storage_permissions_error = error_map[STORAGE_PERMISSIONS_ERROR] | |
| 203 self.storage_response_error = error_map[STORAGE_RESPONSE_ERROR] | |
| 204 | |
| 205 def get_provider_name(self): | |
| 206 return self.HostKeyMap[self.name] | |
| 207 | |
| 208 # Static utility method for getting default Provider. | |
| 209 def get_default(): | |
| 210 return Provider('aws') | |
| OLD | NEW |