| OLD | NEW |
| 1 # Copyright (c) 2006-2011 Mitch Garnaat http://garnaat.org/ | 1 # Copyright (c) 2006-2011 Mitch Garnaat http://garnaat.org/ |
| 2 # Copyright (c) 2010-2011, Eucalyptus Systems, Inc. | 2 # Copyright (c) 2010-2011, Eucalyptus Systems, Inc. |
| 3 # Copyright (c) 2011, Nexenta Systems Inc. |
| 3 # All rights reserved. | 4 # All rights reserved. |
| 4 # | 5 # |
| 5 # Permission is hereby granted, free of charge, to any person obtaining a | 6 # Permission is hereby granted, free of charge, to any person obtaining a |
| 6 # copy of this software and associated documentation files (the | 7 # copy of this software and associated documentation files (the |
| 7 # "Software"), to deal in the Software without restriction, including | 8 # "Software"), to deal in the Software without restriction, including |
| 8 # without limitation the rights to use, copy, modify, merge, publish, dis- | 9 # 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 # 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 # persons to whom the Software is furnished to do so, subject to the fol- |
| 11 # lowing conditions: | 12 # lowing conditions: |
| 12 # | 13 # |
| 13 # The above copyright notice and this permission notice shall be included | 14 # The above copyright notice and this permission notice shall be included |
| 14 # in all copies or substantial portions of the Software. | 15 # in all copies or substantial portions of the Software. |
| 15 # | 16 # |
| 16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 17 # 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 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
| 18 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | 19 # 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 # 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 # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 22 # IN THE SOFTWARE. | 23 # IN THE SOFTWARE. |
| 23 # | 24 # |
| 24 import boto | |
| 25 from boto.pyami.config import Config, BotoConfigLocations | 25 from boto.pyami.config import Config, BotoConfigLocations |
| 26 from boto.storage_uri import BucketStorageUri, FileStorageUri | 26 from boto.storage_uri import BucketStorageUri, FileStorageUri |
| 27 import boto.plugin | 27 import boto.plugin |
| 28 import os, re, sys | 28 import os, re, sys |
| 29 import logging | 29 import logging |
| 30 import logging.config | 30 import logging.config |
| 31 from boto.exception import InvalidUriError | 31 from boto.exception import InvalidUriError |
| 32 | 32 |
| 33 __version__ = '2.0b4' | 33 __version__ = '2.1.1' |
| 34 Version = __version__ # for backware compatibility | 34 Version = __version__ # for backware compatibility |
| 35 | 35 |
| 36 UserAgent = 'Boto/%s (%s)' % (__version__, sys.platform) | 36 UserAgent = 'Boto/%s (%s)' % (__version__, sys.platform) |
| 37 config = Config() | 37 config = Config() |
| 38 | 38 |
| 39 def init_logging(): | 39 def init_logging(): |
| 40 for file in BotoConfigLocations: | 40 for file in BotoConfigLocations: |
| 41 try: | 41 try: |
| 42 logging.config.fileConfig(os.path.expanduser(file)) | 42 logging.config.fileConfig(os.path.expanduser(file)) |
| 43 except: | 43 except: |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 | 102 |
| 103 :rtype: :class:`boto.s3.connection.S3Connection` | 103 :rtype: :class:`boto.s3.connection.S3Connection` |
| 104 :return: A connection to Amazon's S3 | 104 :return: A connection to Amazon's S3 |
| 105 """ | 105 """ |
| 106 from boto.s3.connection import S3Connection | 106 from boto.s3.connection import S3Connection |
| 107 return S3Connection(aws_access_key_id, aws_secret_access_key, **kwargs) | 107 return S3Connection(aws_access_key_id, aws_secret_access_key, **kwargs) |
| 108 | 108 |
| 109 def connect_gs(gs_access_key_id=None, gs_secret_access_key=None, **kwargs): | 109 def connect_gs(gs_access_key_id=None, gs_secret_access_key=None, **kwargs): |
| 110 """ | 110 """ |
| 111 @type gs_access_key_id: string | 111 @type gs_access_key_id: string |
| 112 @param gs_access_key_id: Your Google Storage Access Key ID | 112 @param gs_access_key_id: Your Google Cloud Storage Access Key ID |
| 113 | 113 |
| 114 @type gs_secret_access_key: string | 114 @type gs_secret_access_key: string |
| 115 @param gs_secret_access_key: Your Google Storage Secret Access Key | 115 @param gs_secret_access_key: Your Google Cloud Storage Secret Access Key |
| 116 | 116 |
| 117 @rtype: L{GSConnection<boto.gs.connection.GSConnection>} | 117 @rtype: L{GSConnection<boto.gs.connection.GSConnection>} |
| 118 @return: A connection to Google's Storage service | 118 @return: A connection to Google's Storage service |
| 119 """ | 119 """ |
| 120 from boto.gs.connection import GSConnection | 120 from boto.gs.connection import GSConnection |
| 121 return GSConnection(gs_access_key_id, gs_secret_access_key, **kwargs) | 121 return GSConnection(gs_access_key_id, gs_secret_access_key, **kwargs) |
| 122 | 122 |
| 123 def connect_ec2(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): | 123 def connect_ec2(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): |
| 124 """ | 124 """ |
| 125 :type aws_access_key_id: string | 125 :type aws_access_key_id: string |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 :rtype: :class:`boto.rds.RDSConnection` | 257 :rtype: :class:`boto.rds.RDSConnection` |
| 258 :return: A connection to RDS | 258 :return: A connection to RDS |
| 259 """ | 259 """ |
| 260 from boto.rds import RDSConnection | 260 from boto.rds import RDSConnection |
| 261 return RDSConnection(aws_access_key_id, aws_secret_access_key, **kwargs) | 261 return RDSConnection(aws_access_key_id, aws_secret_access_key, **kwargs) |
| 262 | 262 |
| 263 def connect_emr(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): | 263 def connect_emr(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): |
| 264 """ | 264 """ |
| 265 :type aws_access_key_id: string | 265 :type aws_access_key_id: string |
| 266 :param aws_access_key_id: Your AWS Access Key ID | 266 :param aws_access_key_id: Your AWS Access Key ID |
| 267 | 267 |
| 268 :type aws_secret_access_key: string | 268 :type aws_secret_access_key: string |
| 269 :param aws_secret_access_key: Your AWS Secret Access Key | 269 :param aws_secret_access_key: Your AWS Secret Access Key |
| 270 | 270 |
| 271 :rtype: :class:`boto.emr.EmrConnection` | 271 :rtype: :class:`boto.emr.EmrConnection` |
| 272 :return: A connection to Elastic mapreduce | 272 :return: A connection to Elastic mapreduce |
| 273 """ | 273 """ |
| 274 from boto.emr import EmrConnection | 274 from boto.emr import EmrConnection |
| 275 return EmrConnection(aws_access_key_id, aws_secret_access_key, **kwargs) | 275 return EmrConnection(aws_access_key_id, aws_secret_access_key, **kwargs) |
| 276 | 276 |
| 277 def connect_sns(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): | 277 def connect_sns(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): |
| 278 """ | 278 """ |
| 279 :type aws_access_key_id: string | 279 :type aws_access_key_id: string |
| 280 :param aws_access_key_id: Your AWS Access Key ID | 280 :param aws_access_key_id: Your AWS Access Key ID |
| (...skipping 29 matching lines...) Expand all Loading... |
| 310 | 310 |
| 311 :type aws_secret_access_key: string | 311 :type aws_secret_access_key: string |
| 312 :param aws_secret_access_key: Your AWS Secret Access Key | 312 :param aws_secret_access_key: Your AWS Secret Access Key |
| 313 | 313 |
| 314 :rtype: :class:`boto.dns.Route53Connection` | 314 :rtype: :class:`boto.dns.Route53Connection` |
| 315 :return: A connection to Amazon's Route53 DNS Service | 315 :return: A connection to Amazon's Route53 DNS Service |
| 316 """ | 316 """ |
| 317 from boto.route53 import Route53Connection | 317 from boto.route53 import Route53Connection |
| 318 return Route53Connection(aws_access_key_id, aws_secret_access_key, **kwargs) | 318 return Route53Connection(aws_access_key_id, aws_secret_access_key, **kwargs) |
| 319 | 319 |
| 320 def connect_euca(host, aws_access_key_id=None, aws_secret_access_key=None, | 320 def connect_euca(host=None, aws_access_key_id=None, aws_secret_access_key=None, |
| 321 port=8773, path='/services/Eucalyptus', is_secure=False, | 321 port=8773, path='/services/Eucalyptus', is_secure=False, |
| 322 **kwargs): | 322 **kwargs): |
| 323 """ | 323 """ |
| 324 Connect to a Eucalyptus service. | 324 Connect to a Eucalyptus service. |
| 325 | 325 |
| 326 :type host: string | 326 :type host: string |
| 327 :param host: the host name or ip address of the Eucalyptus server | 327 :param host: the host name or ip address of the Eucalyptus server |
| 328 | 328 |
| 329 :type aws_access_key_id: string | 329 :type aws_access_key_id: string |
| 330 :param aws_access_key_id: Your AWS Access Key ID | 330 :param aws_access_key_id: Your AWS Access Key ID |
| 331 | 331 |
| 332 :type aws_secret_access_key: string | 332 :type aws_secret_access_key: string |
| 333 :param aws_secret_access_key: Your AWS Secret Access Key | 333 :param aws_secret_access_key: Your AWS Secret Access Key |
| 334 | 334 |
| 335 :rtype: :class:`boto.ec2.connection.EC2Connection` | 335 :rtype: :class:`boto.ec2.connection.EC2Connection` |
| 336 :return: A connection to Eucalyptus server | 336 :return: A connection to Eucalyptus server |
| 337 """ | 337 """ |
| 338 from boto.ec2 import EC2Connection | 338 from boto.ec2 import EC2Connection |
| 339 from boto.ec2.regioninfo import RegionInfo | 339 from boto.ec2.regioninfo import RegionInfo |
| 340 | 340 |
| 341 # Check for values in boto config, if not supplied as args |
| 342 if not aws_access_key_id: |
| 343 aws_access_key_id = config.get('Credentials', |
| 344 'euca_access_key_id', |
| 345 None) |
| 346 if not aws_secret_access_key: |
| 347 aws_secret_access_key = config.get('Credentials', |
| 348 'euca_secret_access_key', |
| 349 None) |
| 350 if not host: |
| 351 host = config.get('Boto', 'eucalyptus_host', None) |
| 352 |
| 341 reg = RegionInfo(name='eucalyptus', endpoint=host) | 353 reg = RegionInfo(name='eucalyptus', endpoint=host) |
| 342 return EC2Connection(aws_access_key_id, aws_secret_access_key, | 354 return EC2Connection(aws_access_key_id, aws_secret_access_key, |
| 343 region=reg, port=port, path=path, | 355 region=reg, port=port, path=path, |
| 344 is_secure=is_secure, **kwargs) | 356 is_secure=is_secure, **kwargs) |
| 345 | 357 |
| 346 def connect_walrus(host, aws_access_key_id=None, aws_secret_access_key=None, | 358 def connect_walrus(host=None, aws_access_key_id=None, aws_secret_access_key=None
, |
| 347 port=8773, path='/services/Walrus', is_secure=False, | 359 port=8773, path='/services/Walrus', is_secure=False, |
| 348 **kwargs): | 360 **kwargs): |
| 349 """ | 361 """ |
| 350 Connect to a Walrus service. | 362 Connect to a Walrus service. |
| 351 | 363 |
| 352 :type host: string | 364 :type host: string |
| 353 :param host: the host name or ip address of the Walrus server | 365 :param host: the host name or ip address of the Walrus server |
| 354 | 366 |
| 355 :type aws_access_key_id: string | 367 :type aws_access_key_id: string |
| 356 :param aws_access_key_id: Your AWS Access Key ID | 368 :param aws_access_key_id: Your AWS Access Key ID |
| 357 | 369 |
| 358 :type aws_secret_access_key: string | 370 :type aws_secret_access_key: string |
| 359 :param aws_secret_access_key: Your AWS Secret Access Key | 371 :param aws_secret_access_key: Your AWS Secret Access Key |
| 360 | 372 |
| 361 :rtype: :class:`boto.s3.connection.S3Connection` | 373 :rtype: :class:`boto.s3.connection.S3Connection` |
| 362 :return: A connection to Walrus | 374 :return: A connection to Walrus |
| 363 """ | 375 """ |
| 364 from boto.s3.connection import S3Connection | 376 from boto.s3.connection import S3Connection |
| 365 from boto.s3.connection import OrdinaryCallingFormat | 377 from boto.s3.connection import OrdinaryCallingFormat |
| 366 | 378 |
| 379 # Check for values in boto config, if not supplied as args |
| 380 if not aws_access_key_id: |
| 381 aws_access_key_id = config.get('Credentials', |
| 382 'euca_access_key_id', |
| 383 None) |
| 384 if not aws_secret_access_key: |
| 385 aws_secret_access_key = config.get('Credentials', |
| 386 'euca_secret_access_key', |
| 387 None) |
| 388 if not host: |
| 389 host = config.get('Boto', 'walrus_host', None) |
| 390 |
| 367 return S3Connection(aws_access_key_id, aws_secret_access_key, | 391 return S3Connection(aws_access_key_id, aws_secret_access_key, |
| 368 host=host, port=port, path=path, | 392 host=host, port=port, path=path, |
| 369 calling_format=OrdinaryCallingFormat(), | 393 calling_format=OrdinaryCallingFormat(), |
| 370 is_secure=is_secure, **kwargs) | 394 is_secure=is_secure, **kwargs) |
| 371 | 395 |
| 372 def connect_ses(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): | 396 def connect_ses(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): |
| 373 """ | 397 """ |
| 374 :type aws_access_key_id: string | 398 :type aws_access_key_id: string |
| 375 :param aws_access_key_id: Your AWS Access Key ID | 399 :param aws_access_key_id: Your AWS Access Key ID |
| 376 | 400 |
| 377 :type aws_secret_access_key: string | 401 :type aws_secret_access_key: string |
| 378 :param aws_secret_access_key: Your AWS Secret Access Key | 402 :param aws_secret_access_key: Your AWS Secret Access Key |
| 379 | 403 |
| 380 :rtype: :class:`boto.ses.SESConnection` | 404 :rtype: :class:`boto.ses.SESConnection` |
| 381 :return: A connection to Amazon's SES | 405 :return: A connection to Amazon's SES |
| 382 """ | 406 """ |
| 383 from boto.ses import SESConnection | 407 from boto.ses import SESConnection |
| 384 return SESConnection(aws_access_key_id, aws_secret_access_key, **kwargs) | 408 return SESConnection(aws_access_key_id, aws_secret_access_key, **kwargs) |
| 385 | 409 |
| 410 def connect_sts(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): |
| 411 """ |
| 412 :type aws_access_key_id: string |
| 413 :param aws_access_key_id: Your AWS Access Key ID |
| 414 |
| 415 :type aws_secret_access_key: string |
| 416 :param aws_secret_access_key: Your AWS Secret Access Key |
| 417 |
| 418 :rtype: :class:`boto.sts.STSConnection` |
| 419 :return: A connection to Amazon's STS |
| 420 """ |
| 421 from boto.sts import STSConnection |
| 422 return STSConnection(aws_access_key_id, aws_secret_access_key, **kwargs) |
| 423 |
| 386 def connect_ia(ia_access_key_id=None, ia_secret_access_key=None, | 424 def connect_ia(ia_access_key_id=None, ia_secret_access_key=None, |
| 387 is_secure=False, **kwargs): | 425 is_secure=False, **kwargs): |
| 388 """ | 426 """ |
| 389 Connect to the Internet Archive via their S3-like API. | 427 Connect to the Internet Archive via their S3-like API. |
| 390 | 428 |
| 391 :type ia_access_key_id: string | 429 :type ia_access_key_id: string |
| 392 :param ia_access_key_id: Your IA Access Key ID. This will also look in your | 430 :param ia_access_key_id: Your IA Access Key ID. This will also look in your |
| 393 boto config file for an entry in the Credentials | 431 boto config file for an entry in the Credentials |
| 394 section called "ia_access_key_id" | 432 section called "ia_access_key_id" |
| 395 | 433 |
| 396 :type ia_secret_access_key: string | 434 :type ia_secret_access_key: string |
| 397 :param ia_secret_access_key: Your IA Secret Access Key. This will also look
in your | 435 :param ia_secret_access_key: Your IA Secret Access Key. This will also |
| 398 boto config file for an entry in the Credential
s | 436 look in your boto config file for an entry |
| 399 section called "ia_secret_access_key" | 437 in the Credentials section called |
| 438 "ia_secret_access_key" |
| 400 | 439 |
| 401 :rtype: :class:`boto.s3.connection.S3Connection` | 440 :rtype: :class:`boto.s3.connection.S3Connection` |
| 402 :return: A connection to the Internet Archive | 441 :return: A connection to the Internet Archive |
| 403 """ | 442 """ |
| 404 from boto.s3.connection import S3Connection | 443 from boto.s3.connection import S3Connection |
| 405 from boto.s3.connection import OrdinaryCallingFormat | 444 from boto.s3.connection import OrdinaryCallingFormat |
| 406 | 445 |
| 407 access_key = config.get('Credentials', 'ia_access_key_id', | 446 access_key = config.get('Credentials', 'ia_access_key_id', |
| 408 ia_access_key_id) | 447 ia_access_key_id) |
| 409 secret_key = config.get('Credentials', 'ia_secret_access_key', | 448 secret_key = config.get('Credentials', 'ia_secret_access_key', |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 path = uri_str | 538 path = uri_str |
| 500 else: | 539 else: |
| 501 scheme = uri_str[0:end_scheme_idx].lower() | 540 scheme = uri_str[0:end_scheme_idx].lower() |
| 502 path = uri_str[end_scheme_idx + 3:] | 541 path = uri_str[end_scheme_idx + 3:] |
| 503 | 542 |
| 504 if scheme not in ['file', 's3', 'gs']: | 543 if scheme not in ['file', 's3', 'gs']: |
| 505 raise InvalidUriError('Unrecognized scheme "%s"' % scheme) | 544 raise InvalidUriError('Unrecognized scheme "%s"' % scheme) |
| 506 if scheme == 'file': | 545 if scheme == 'file': |
| 507 # For file URIs we have no bucket name, and use the complete path | 546 # For file URIs we have no bucket name, and use the complete path |
| 508 # (minus 'file://') as the object name. | 547 # (minus 'file://') as the object name. |
| 509 return FileStorageUri(path, debug) | 548 is_stream = False |
| 549 if path == '-': |
| 550 is_stream = True |
| 551 return FileStorageUri(path, debug, is_stream) |
| 510 else: | 552 else: |
| 511 path_parts = path.split('/', 1) | 553 path_parts = path.split('/', 1) |
| 512 bucket_name = path_parts[0] | 554 bucket_name = path_parts[0] |
| 513 if (validate and bucket_name and | 555 if (validate and bucket_name and |
| 514 # Disallow buckets violating charset or not [3..255] chars total. | 556 # Disallow buckets violating charset or not [3..255] chars total. |
| 515 (not re.match('^[a-z0-9][a-z0-9\._-]{1,253}[a-z0-9]$', bucket_name) | 557 (not re.match('^[a-z0-9][a-z0-9\._-]{1,253}[a-z0-9]$', bucket_name) |
| 516 # Disallow buckets with individual DNS labels longer than 63. | 558 # Disallow buckets with individual DNS labels longer than 63. |
| 517 or re.search('[-_a-z0-9]{64}', bucket_name))): | 559 or re.search('[-_a-z0-9]{64}', bucket_name))): |
| 518 raise InvalidUriError('Invalid bucket name in URI "%s"' % uri_str) | 560 raise InvalidUriError('Invalid bucket name in URI "%s"' % uri_str) |
| 519 # If enabled, ensure the bucket name is valid, to avoid possibly | 561 # If enabled, ensure the bucket name is valid, to avoid possibly |
| (...skipping 13 matching lines...) Expand all Loading... |
| 533 :param key: URI naming bucket + optional object. | 575 :param key: URI naming bucket + optional object. |
| 534 """ | 576 """ |
| 535 if not isinstance(key, boto.s3.key.Key): | 577 if not isinstance(key, boto.s3.key.Key): |
| 536 raise InvalidUriError('Requested key (%s) is not a subclass of ' | 578 raise InvalidUriError('Requested key (%s) is not a subclass of ' |
| 537 'boto.s3.key.Key' % str(type(key))) | 579 'boto.s3.key.Key' % str(type(key))) |
| 538 prov_name = key.bucket.connection.provider.get_provider_name() | 580 prov_name = key.bucket.connection.provider.get_provider_name() |
| 539 uri_str = '%s://%s/%s' % (prov_name, key.bucket.name, key.name) | 581 uri_str = '%s://%s/%s' % (prov_name, key.bucket.name, key.name) |
| 540 return storage_uri(uri_str) | 582 return storage_uri(uri_str) |
| 541 | 583 |
| 542 boto.plugin.load_plugins(config) | 584 boto.plugin.load_plugins(config) |
| OLD | NEW |