gcloud 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +4 -0
- data/Makefile +4 -0
- data/Manifest +760 -1
- data/bin/gcloud +7 -0
- data/bin/{gcutil → gcutil.symlink} +0 -0
- data/bin/gsutil-symlink +377 -0
- data/gcloud.gemspec +5 -5
- data/packages/gsutil/CHECKSUM +1 -0
- data/packages/gsutil/COPYING +202 -0
- data/packages/gsutil/LICENSE.third_party +295 -0
- data/packages/gsutil/MANIFEST.in +5 -0
- data/packages/gsutil/README +38 -0
- data/packages/gsutil/README.pkg +49 -0
- data/packages/gsutil/ReleaseNotes.txt +780 -0
- data/packages/gsutil/VERSION +1 -0
- data/packages/gsutil/boto/Changelog.rst +35 -0
- data/packages/gsutil/boto/LICENSE +18 -0
- data/packages/gsutil/boto/MANIFEST.in +12 -0
- data/packages/gsutil/boto/README.rst +163 -0
- data/packages/gsutil/boto/bin/asadmin +290 -0
- data/packages/gsutil/boto/bin/bundle_image +27 -0
- data/packages/gsutil/boto/bin/cfadmin +108 -0
- data/packages/gsutil/boto/bin/cq +89 -0
- data/packages/gsutil/boto/bin/cwutil +140 -0
- data/packages/gsutil/boto/bin/elbadmin +284 -0
- data/packages/gsutil/boto/bin/fetch_file +43 -0
- data/packages/gsutil/boto/bin/glacier +154 -0
- data/packages/gsutil/boto/bin/instance_events +145 -0
- data/packages/gsutil/boto/bin/kill_instance +35 -0
- data/packages/gsutil/boto/bin/launch_instance +252 -0
- data/packages/gsutil/boto/bin/list_instances +90 -0
- data/packages/gsutil/boto/bin/lss3 +77 -0
- data/packages/gsutil/boto/bin/mturk +465 -0
- data/packages/gsutil/boto/bin/pyami_sendmail +52 -0
- data/packages/gsutil/boto/bin/route53 +205 -0
- data/packages/gsutil/boto/bin/s3put +374 -0
- data/packages/gsutil/boto/bin/sdbadmin +194 -0
- data/packages/gsutil/boto/bin/taskadmin +116 -0
- data/packages/gsutil/boto/boto/__init__.py +793 -0
- data/packages/gsutil/boto/boto/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/auth.py +682 -0
- data/packages/gsutil/boto/boto/auth.pyc +0 -0
- data/packages/gsutil/boto/boto/auth_handler.py +58 -0
- data/packages/gsutil/boto/boto/auth_handler.pyc +0 -0
- data/packages/gsutil/boto/boto/beanstalk/__init__.py +65 -0
- data/packages/gsutil/boto/boto/beanstalk/exception.py +64 -0
- data/packages/gsutil/boto/boto/beanstalk/layer1.py +1153 -0
- data/packages/gsutil/boto/boto/beanstalk/response.py +703 -0
- data/packages/gsutil/boto/boto/beanstalk/wrapper.py +29 -0
- data/packages/gsutil/boto/boto/cacerts/__init__.py +22 -0
- data/packages/gsutil/boto/boto/cacerts/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/cacerts/cacerts.txt +633 -0
- data/packages/gsutil/boto/boto/cloudformation/__init__.py +68 -0
- data/packages/gsutil/boto/boto/cloudformation/connection.py +364 -0
- data/packages/gsutil/boto/boto/cloudformation/stack.py +360 -0
- data/packages/gsutil/boto/boto/cloudformation/template.py +43 -0
- data/packages/gsutil/boto/boto/cloudfront/__init__.py +324 -0
- data/packages/gsutil/boto/boto/cloudfront/distribution.py +745 -0
- data/packages/gsutil/boto/boto/cloudfront/exception.py +26 -0
- data/packages/gsutil/boto/boto/cloudfront/identity.py +122 -0
- data/packages/gsutil/boto/boto/cloudfront/invalidation.py +216 -0
- data/packages/gsutil/boto/boto/cloudfront/logging.py +38 -0
- data/packages/gsutil/boto/boto/cloudfront/object.py +48 -0
- data/packages/gsutil/boto/boto/cloudfront/origin.py +150 -0
- data/packages/gsutil/boto/boto/cloudfront/signers.py +60 -0
- data/packages/gsutil/boto/boto/cloudsearch/__init__.py +45 -0
- data/packages/gsutil/boto/boto/cloudsearch/document.py +265 -0
- data/packages/gsutil/boto/boto/cloudsearch/domain.py +394 -0
- data/packages/gsutil/boto/boto/cloudsearch/layer1.py +738 -0
- data/packages/gsutil/boto/boto/cloudsearch/layer2.py +67 -0
- data/packages/gsutil/boto/boto/cloudsearch/optionstatus.py +248 -0
- data/packages/gsutil/boto/boto/cloudsearch/search.py +365 -0
- data/packages/gsutil/boto/boto/cloudsearch/sourceattribute.py +75 -0
- data/packages/gsutil/boto/boto/compat.py +28 -0
- data/packages/gsutil/boto/boto/compat.pyc +0 -0
- data/packages/gsutil/boto/boto/connection.py +1081 -0
- data/packages/gsutil/boto/boto/connection.pyc +0 -0
- data/packages/gsutil/boto/boto/contrib/__init__.py +22 -0
- data/packages/gsutil/boto/boto/contrib/ymlmessage.py +52 -0
- data/packages/gsutil/boto/boto/core/README +58 -0
- data/packages/gsutil/boto/boto/core/__init__.py +23 -0
- data/packages/gsutil/boto/boto/core/auth.py +78 -0
- data/packages/gsutil/boto/boto/core/credentials.py +154 -0
- data/packages/gsutil/boto/boto/core/dictresponse.py +178 -0
- data/packages/gsutil/boto/boto/core/service.py +67 -0
- data/packages/gsutil/boto/boto/datapipeline/__init__.py +0 -0
- data/packages/gsutil/boto/boto/datapipeline/exceptions.py +42 -0
- data/packages/gsutil/boto/boto/datapipeline/layer1.py +546 -0
- data/packages/gsutil/boto/boto/dynamodb/__init__.py +66 -0
- data/packages/gsutil/boto/boto/dynamodb/batch.py +262 -0
- data/packages/gsutil/boto/boto/dynamodb/condition.py +170 -0
- data/packages/gsutil/boto/boto/dynamodb/exceptions.py +64 -0
- data/packages/gsutil/boto/boto/dynamodb/item.py +196 -0
- data/packages/gsutil/boto/boto/dynamodb/layer1.py +575 -0
- data/packages/gsutil/boto/boto/dynamodb/layer2.py +798 -0
- data/packages/gsutil/boto/boto/dynamodb/schema.py +112 -0
- data/packages/gsutil/boto/boto/dynamodb/table.py +540 -0
- data/packages/gsutil/boto/boto/dynamodb/types.py +326 -0
- data/packages/gsutil/boto/boto/ec2/__init__.py +96 -0
- data/packages/gsutil/boto/boto/ec2/address.py +103 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/__init__.py +781 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/activity.py +74 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/group.py +337 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/instance.py +60 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/launchconfig.py +209 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/policy.py +166 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/request.py +38 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/scheduled.py +60 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/tag.py +84 -0
- data/packages/gsutil/boto/boto/ec2/blockdevicemapping.py +141 -0
- data/packages/gsutil/boto/boto/ec2/bundleinstance.py +78 -0
- data/packages/gsutil/boto/boto/ec2/buyreservation.py +84 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/__init__.py +603 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/alarm.py +316 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/datapoint.py +40 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/dimension.py +38 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/listelement.py +31 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/metric.py +175 -0
- data/packages/gsutil/boto/boto/ec2/connection.py +3409 -0
- data/packages/gsutil/boto/boto/ec2/ec2object.py +107 -0
- data/packages/gsutil/boto/boto/ec2/elb/__init__.py +553 -0
- data/packages/gsutil/boto/boto/ec2/elb/healthcheck.py +89 -0
- data/packages/gsutil/boto/boto/ec2/elb/instancestate.py +62 -0
- data/packages/gsutil/boto/boto/ec2/elb/listelement.py +36 -0
- data/packages/gsutil/boto/boto/ec2/elb/listener.py +75 -0
- data/packages/gsutil/boto/boto/ec2/elb/loadbalancer.py +324 -0
- data/packages/gsutil/boto/boto/ec2/elb/policies.py +89 -0
- data/packages/gsutil/boto/boto/ec2/elb/securitygroup.py +38 -0
- data/packages/gsutil/boto/boto/ec2/group.py +39 -0
- data/packages/gsutil/boto/boto/ec2/image.py +350 -0
- data/packages/gsutil/boto/boto/ec2/instance.py +661 -0
- data/packages/gsutil/boto/boto/ec2/instanceinfo.py +51 -0
- data/packages/gsutil/boto/boto/ec2/instancestatus.py +207 -0
- data/packages/gsutil/boto/boto/ec2/keypair.py +113 -0
- data/packages/gsutil/boto/boto/ec2/launchspecification.py +105 -0
- data/packages/gsutil/boto/boto/ec2/networkinterface.py +247 -0
- data/packages/gsutil/boto/boto/ec2/placementgroup.py +51 -0
- data/packages/gsutil/boto/boto/ec2/regioninfo.py +34 -0
- data/packages/gsutil/boto/boto/ec2/reservedinstance.py +227 -0
- data/packages/gsutil/boto/boto/ec2/securitygroup.py +357 -0
- data/packages/gsutil/boto/boto/ec2/snapshot.py +170 -0
- data/packages/gsutil/boto/boto/ec2/spotdatafeedsubscription.py +63 -0
- data/packages/gsutil/boto/boto/ec2/spotinstancerequest.py +188 -0
- data/packages/gsutil/boto/boto/ec2/spotpricehistory.py +55 -0
- data/packages/gsutil/boto/boto/ec2/tag.py +87 -0
- data/packages/gsutil/boto/boto/ec2/vmtype.py +58 -0
- data/packages/gsutil/boto/boto/ec2/volume.py +293 -0
- data/packages/gsutil/boto/boto/ec2/volumestatus.py +200 -0
- data/packages/gsutil/boto/boto/ec2/zone.py +80 -0
- data/packages/gsutil/boto/boto/ecs/__init__.py +90 -0
- data/packages/gsutil/boto/boto/ecs/item.py +153 -0
- data/packages/gsutil/boto/boto/elasticache/__init__.py +62 -0
- data/packages/gsutil/boto/boto/elasticache/layer1.py +1252 -0
- data/packages/gsutil/boto/boto/elastictranscoder/__init__.py +62 -0
- data/packages/gsutil/boto/boto/elastictranscoder/exceptions.py +46 -0
- data/packages/gsutil/boto/boto/elastictranscoder/layer1.py +509 -0
- data/packages/gsutil/boto/boto/emr/__init__.py +73 -0
- data/packages/gsutil/boto/boto/emr/bootstrap_action.py +44 -0
- data/packages/gsutil/boto/boto/emr/connection.py +531 -0
- data/packages/gsutil/boto/boto/emr/emrobject.py +176 -0
- data/packages/gsutil/boto/boto/emr/instance_group.py +43 -0
- data/packages/gsutil/boto/boto/emr/step.py +281 -0
- data/packages/gsutil/boto/boto/exception.py +476 -0
- data/packages/gsutil/boto/boto/exception.pyc +0 -0
- data/packages/gsutil/boto/boto/file/README +49 -0
- data/packages/gsutil/boto/boto/file/__init__.py +28 -0
- data/packages/gsutil/boto/boto/file/bucket.py +112 -0
- data/packages/gsutil/boto/boto/file/connection.py +33 -0
- data/packages/gsutil/boto/boto/file/key.py +199 -0
- data/packages/gsutil/boto/boto/file/simpleresultset.py +30 -0
- data/packages/gsutil/boto/boto/fps/__init__.py +21 -0
- data/packages/gsutil/boto/boto/fps/connection.py +369 -0
- data/packages/gsutil/boto/boto/fps/exception.py +344 -0
- data/packages/gsutil/boto/boto/fps/response.py +175 -0
- data/packages/gsutil/boto/boto/glacier/__init__.py +57 -0
- data/packages/gsutil/boto/boto/glacier/concurrent.py +409 -0
- data/packages/gsutil/boto/boto/glacier/exceptions.py +58 -0
- data/packages/gsutil/boto/boto/glacier/job.py +152 -0
- data/packages/gsutil/boto/boto/glacier/layer1.py +637 -0
- data/packages/gsutil/boto/boto/glacier/layer2.py +93 -0
- data/packages/gsutil/boto/boto/glacier/response.py +48 -0
- data/packages/gsutil/boto/boto/glacier/utils.py +163 -0
- data/packages/gsutil/boto/boto/glacier/vault.py +387 -0
- data/packages/gsutil/boto/boto/glacier/writer.py +242 -0
- data/packages/gsutil/boto/boto/gs/__init__.py +22 -0
- data/packages/gsutil/boto/boto/gs/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/acl.py +304 -0
- data/packages/gsutil/boto/boto/gs/acl.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/bucket.py +870 -0
- data/packages/gsutil/boto/boto/gs/bucket.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/bucketlistresultset.py +64 -0
- data/packages/gsutil/boto/boto/gs/bucketlistresultset.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/connection.py +103 -0
- data/packages/gsutil/boto/boto/gs/connection.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/cors.py +169 -0
- data/packages/gsutil/boto/boto/gs/cors.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/key.py +704 -0
- data/packages/gsutil/boto/boto/gs/key.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/resumable_upload_handler.py +659 -0
- data/packages/gsutil/boto/boto/gs/resumable_upload_handler.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/user.py +54 -0
- data/packages/gsutil/boto/boto/gs/user.pyc +0 -0
- data/packages/gsutil/boto/boto/handler.py +44 -0
- data/packages/gsutil/boto/boto/handler.pyc +0 -0
- data/packages/gsutil/boto/boto/https_connection.py +124 -0
- data/packages/gsutil/boto/boto/https_connection.pyc +0 -0
- data/packages/gsutil/boto/boto/iam/__init__.py +74 -0
- data/packages/gsutil/boto/boto/iam/connection.py +1317 -0
- data/packages/gsutil/boto/boto/iam/summarymap.py +42 -0
- data/packages/gsutil/boto/boto/jsonresponse.py +163 -0
- data/packages/gsutil/boto/boto/jsonresponse.pyc +0 -0
- data/packages/gsutil/boto/boto/manage/__init__.py +23 -0
- data/packages/gsutil/boto/boto/manage/cmdshell.py +241 -0
- data/packages/gsutil/boto/boto/manage/propget.py +64 -0
- data/packages/gsutil/boto/boto/manage/server.py +556 -0
- data/packages/gsutil/boto/boto/manage/task.py +175 -0
- data/packages/gsutil/boto/boto/manage/test_manage.py +34 -0
- data/packages/gsutil/boto/boto/manage/volume.py +420 -0
- data/packages/gsutil/boto/boto/mashups/__init__.py +23 -0
- data/packages/gsutil/boto/boto/mashups/interactive.py +97 -0
- data/packages/gsutil/boto/boto/mashups/iobject.py +115 -0
- data/packages/gsutil/boto/boto/mashups/order.py +211 -0
- data/packages/gsutil/boto/boto/mashups/server.py +395 -0
- data/packages/gsutil/boto/boto/mturk/__init__.py +23 -0
- data/packages/gsutil/boto/boto/mturk/connection.py +1027 -0
- data/packages/gsutil/boto/boto/mturk/layoutparam.py +55 -0
- data/packages/gsutil/boto/boto/mturk/notification.py +103 -0
- data/packages/gsutil/boto/boto/mturk/price.py +48 -0
- data/packages/gsutil/boto/boto/mturk/qualification.py +137 -0
- data/packages/gsutil/boto/boto/mturk/question.py +455 -0
- data/packages/gsutil/boto/boto/mws/__init__.py +21 -0
- data/packages/gsutil/boto/boto/mws/connection.py +813 -0
- data/packages/gsutil/boto/boto/mws/exception.py +75 -0
- data/packages/gsutil/boto/boto/mws/response.py +655 -0
- data/packages/gsutil/boto/boto/plugin.py +90 -0
- data/packages/gsutil/boto/boto/plugin.pyc +0 -0
- data/packages/gsutil/boto/boto/provider.py +337 -0
- data/packages/gsutil/boto/boto/provider.pyc +0 -0
- data/packages/gsutil/boto/boto/pyami/__init__.py +22 -0
- data/packages/gsutil/boto/boto/pyami/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/pyami/bootstrap.py +134 -0
- data/packages/gsutil/boto/boto/pyami/config.py +229 -0
- data/packages/gsutil/boto/boto/pyami/config.pyc +0 -0
- data/packages/gsutil/boto/boto/pyami/copybot.cfg +60 -0
- data/packages/gsutil/boto/boto/pyami/copybot.py +97 -0
- data/packages/gsutil/boto/boto/pyami/helloworld.py +28 -0
- data/packages/gsutil/boto/boto/pyami/installers/__init__.py +64 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/__init__.py +22 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/apache.py +43 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/ebs.py +238 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/installer.py +96 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/mysql.py +109 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/trac.py +139 -0
- data/packages/gsutil/boto/boto/pyami/launch_ami.py +178 -0
- data/packages/gsutil/boto/boto/pyami/scriptbase.py +44 -0
- data/packages/gsutil/boto/boto/pyami/startup.py +60 -0
- data/packages/gsutil/boto/boto/rds/__init__.py +1194 -0
- data/packages/gsutil/boto/boto/rds/dbinstance.py +357 -0
- data/packages/gsutil/boto/boto/rds/dbsecuritygroup.py +177 -0
- data/packages/gsutil/boto/boto/rds/dbsnapshot.py +108 -0
- data/packages/gsutil/boto/boto/rds/event.py +49 -0
- data/packages/gsutil/boto/boto/rds/parametergroup.py +201 -0
- data/packages/gsutil/boto/boto/rds/regioninfo.py +32 -0
- data/packages/gsutil/boto/boto/regioninfo.py +63 -0
- data/packages/gsutil/boto/boto/regioninfo.pyc +0 -0
- data/packages/gsutil/boto/boto/resultset.py +169 -0
- data/packages/gsutil/boto/boto/resultset.pyc +0 -0
- data/packages/gsutil/boto/boto/roboto/__init__.py +1 -0
- data/packages/gsutil/boto/boto/roboto/awsqueryrequest.py +504 -0
- data/packages/gsutil/boto/boto/roboto/awsqueryservice.py +121 -0
- data/packages/gsutil/boto/boto/roboto/param.py +147 -0
- data/packages/gsutil/boto/boto/route53/__init__.py +75 -0
- data/packages/gsutil/boto/boto/route53/connection.py +403 -0
- data/packages/gsutil/boto/boto/route53/exception.py +27 -0
- data/packages/gsutil/boto/boto/route53/hostedzone.py +56 -0
- data/packages/gsutil/boto/boto/route53/record.py +306 -0
- data/packages/gsutil/boto/boto/route53/status.py +42 -0
- data/packages/gsutil/boto/boto/route53/zone.py +412 -0
- data/packages/gsutil/boto/boto/s3/__init__.py +84 -0
- data/packages/gsutil/boto/boto/s3/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/acl.py +164 -0
- data/packages/gsutil/boto/boto/s3/acl.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/bucket.py +1634 -0
- data/packages/gsutil/boto/boto/s3/bucket.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/bucketlistresultset.py +139 -0
- data/packages/gsutil/boto/boto/s3/bucketlistresultset.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/bucketlogging.py +83 -0
- data/packages/gsutil/boto/boto/s3/bucketlogging.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/connection.py +540 -0
- data/packages/gsutil/boto/boto/s3/connection.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/cors.py +210 -0
- data/packages/gsutil/boto/boto/s3/cors.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/deletemarker.py +55 -0
- data/packages/gsutil/boto/boto/s3/deletemarker.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/key.py +1712 -0
- data/packages/gsutil/boto/boto/s3/key.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/keyfile.py +134 -0
- data/packages/gsutil/boto/boto/s3/keyfile.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/lifecycle.py +231 -0
- data/packages/gsutil/boto/boto/s3/lifecycle.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/multidelete.py +138 -0
- data/packages/gsutil/boto/boto/s3/multidelete.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/multipart.py +315 -0
- data/packages/gsutil/boto/boto/s3/multipart.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/prefix.py +42 -0
- data/packages/gsutil/boto/boto/s3/prefix.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/resumable_download_handler.py +339 -0
- data/packages/gsutil/boto/boto/s3/resumable_download_handler.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/tagging.py +71 -0
- data/packages/gsutil/boto/boto/s3/tagging.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/user.py +49 -0
- data/packages/gsutil/boto/boto/s3/user.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/website.py +237 -0
- data/packages/gsutil/boto/boto/s3/website.pyc +0 -0
- data/packages/gsutil/boto/boto/sdb/__init__.py +67 -0
- data/packages/gsutil/boto/boto/sdb/connection.py +617 -0
- data/packages/gsutil/boto/boto/sdb/db/__init__.py +20 -0
- data/packages/gsutil/boto/boto/sdb/db/blob.py +75 -0
- data/packages/gsutil/boto/boto/sdb/db/key.py +59 -0
- data/packages/gsutil/boto/boto/sdb/db/manager/__init__.py +85 -0
- data/packages/gsutil/boto/boto/sdb/db/manager/sdbmanager.py +732 -0
- data/packages/gsutil/boto/boto/sdb/db/manager/xmlmanager.py +517 -0
- data/packages/gsutil/boto/boto/sdb/db/model.py +294 -0
- data/packages/gsutil/boto/boto/sdb/db/property.py +703 -0
- data/packages/gsutil/boto/boto/sdb/db/query.py +85 -0
- data/packages/gsutil/boto/boto/sdb/db/sequence.py +226 -0
- data/packages/gsutil/boto/boto/sdb/db/test_db.py +231 -0
- data/packages/gsutil/boto/boto/sdb/domain.py +377 -0
- data/packages/gsutil/boto/boto/sdb/item.py +181 -0
- data/packages/gsutil/boto/boto/sdb/queryresultset.py +92 -0
- data/packages/gsutil/boto/boto/sdb/regioninfo.py +32 -0
- data/packages/gsutil/boto/boto/services/__init__.py +23 -0
- data/packages/gsutil/boto/boto/services/bs.py +179 -0
- data/packages/gsutil/boto/boto/services/message.py +58 -0
- data/packages/gsutil/boto/boto/services/result.py +136 -0
- data/packages/gsutil/boto/boto/services/service.py +161 -0
- data/packages/gsutil/boto/boto/services/servicedef.py +91 -0
- data/packages/gsutil/boto/boto/services/sonofmmm.cfg +43 -0
- data/packages/gsutil/boto/boto/services/sonofmmm.py +81 -0
- data/packages/gsutil/boto/boto/services/submit.py +88 -0
- data/packages/gsutil/boto/boto/ses/__init__.py +54 -0
- data/packages/gsutil/boto/boto/ses/connection.py +521 -0
- data/packages/gsutil/boto/boto/ses/exceptions.py +77 -0
- data/packages/gsutil/boto/boto/sns/__init__.py +78 -0
- data/packages/gsutil/boto/boto/sns/connection.py +431 -0
- data/packages/gsutil/boto/boto/sqs/__init__.py +56 -0
- data/packages/gsutil/boto/boto/sqs/attributes.py +46 -0
- data/packages/gsutil/boto/boto/sqs/batchresults.py +95 -0
- data/packages/gsutil/boto/boto/sqs/connection.py +417 -0
- data/packages/gsutil/boto/boto/sqs/jsonmessage.py +43 -0
- data/packages/gsutil/boto/boto/sqs/message.py +253 -0
- data/packages/gsutil/boto/boto/sqs/queue.py +478 -0
- data/packages/gsutil/boto/boto/sqs/regioninfo.py +32 -0
- data/packages/gsutil/boto/boto/storage_uri.py +835 -0
- data/packages/gsutil/boto/boto/storage_uri.pyc +0 -0
- data/packages/gsutil/boto/boto/sts/__init__.py +55 -0
- data/packages/gsutil/boto/boto/sts/connection.py +207 -0
- data/packages/gsutil/boto/boto/sts/credentials.py +215 -0
- data/packages/gsutil/boto/boto/swf/__init__.py +60 -0
- data/packages/gsutil/boto/boto/swf/exceptions.py +44 -0
- data/packages/gsutil/boto/boto/swf/layer1.py +1512 -0
- data/packages/gsutil/boto/boto/swf/layer1_decisions.py +287 -0
- data/packages/gsutil/boto/boto/swf/layer2.py +342 -0
- data/packages/gsutil/boto/boto/utils.py +927 -0
- data/packages/gsutil/boto/boto/utils.pyc +0 -0
- data/packages/gsutil/boto/boto/vpc/__init__.py +910 -0
- data/packages/gsutil/boto/boto/vpc/customergateway.py +54 -0
- data/packages/gsutil/boto/boto/vpc/dhcpoptions.py +72 -0
- data/packages/gsutil/boto/boto/vpc/internetgateway.py +72 -0
- data/packages/gsutil/boto/boto/vpc/routetable.py +109 -0
- data/packages/gsutil/boto/boto/vpc/subnet.py +57 -0
- data/packages/gsutil/boto/boto/vpc/vpc.py +54 -0
- data/packages/gsutil/boto/boto/vpc/vpnconnection.py +60 -0
- data/packages/gsutil/boto/boto/vpc/vpngateway.py +83 -0
- data/packages/gsutil/boto/docs/BotoCheatSheet.pdf +0 -0
- data/packages/gsutil/boto/docs/Makefile +89 -0
- data/packages/gsutil/boto/docs/make.bat +113 -0
- data/packages/gsutil/boto/docs/source/_templates/layout.html +3 -0
- data/packages/gsutil/boto/docs/source/autoscale_tut.rst +220 -0
- data/packages/gsutil/boto/docs/source/boto_config_tut.rst +125 -0
- data/packages/gsutil/boto/docs/source/boto_theme/static/boto.css_t +239 -0
- data/packages/gsutil/boto/docs/source/boto_theme/static/pygments.css +61 -0
- data/packages/gsutil/boto/docs/source/boto_theme/theme.conf +3 -0
- data/packages/gsutil/boto/docs/source/cloudfront_tut.rst +196 -0
- data/packages/gsutil/boto/docs/source/cloudsearch_tut.rst +411 -0
- data/packages/gsutil/boto/docs/source/cloudwatch_tut.rst +116 -0
- data/packages/gsutil/boto/docs/source/conf.py +32 -0
- data/packages/gsutil/boto/docs/source/contributing.rst +204 -0
- data/packages/gsutil/boto/docs/source/documentation.rst +59 -0
- data/packages/gsutil/boto/docs/source/dynamodb_tut.rst +339 -0
- data/packages/gsutil/boto/docs/source/ec2_tut.rst +86 -0
- data/packages/gsutil/boto/docs/source/elb_tut.rst +257 -0
- data/packages/gsutil/boto/docs/source/emr_tut.rst +108 -0
- data/packages/gsutil/boto/docs/source/index.rst +146 -0
- data/packages/gsutil/boto/docs/source/rds_tut.rst +108 -0
- data/packages/gsutil/boto/docs/source/ref/autoscale.rst +62 -0
- data/packages/gsutil/boto/docs/source/ref/beanstalk.rst +26 -0
- data/packages/gsutil/boto/docs/source/ref/boto.rst +47 -0
- data/packages/gsutil/boto/docs/source/ref/cloudformation.rst +34 -0
- data/packages/gsutil/boto/docs/source/ref/cloudfront.rst +68 -0
- data/packages/gsutil/boto/docs/source/ref/cloudsearch.rst +59 -0
- data/packages/gsutil/boto/docs/source/ref/cloudwatch.rst +27 -0
- data/packages/gsutil/boto/docs/source/ref/contrib.rst +32 -0
- data/packages/gsutil/boto/docs/source/ref/datapipeline.rst +26 -0
- data/packages/gsutil/boto/docs/source/ref/dynamodb.rst +61 -0
- data/packages/gsutil/boto/docs/source/ref/ec2.rst +140 -0
- data/packages/gsutil/boto/docs/source/ref/ecs.rst +19 -0
- data/packages/gsutil/boto/docs/source/ref/elasticache.rst +19 -0
- data/packages/gsutil/boto/docs/source/ref/elastictranscoder.rst +26 -0
- data/packages/gsutil/boto/docs/source/ref/elb.rst +47 -0
- data/packages/gsutil/boto/docs/source/ref/emr.rst +34 -0
- data/packages/gsutil/boto/docs/source/ref/file.rst +34 -0
- data/packages/gsutil/boto/docs/source/ref/fps.rst +19 -0
- data/packages/gsutil/boto/docs/source/ref/glacier.rst +63 -0
- data/packages/gsutil/boto/docs/source/ref/gs.rst +72 -0
- data/packages/gsutil/boto/docs/source/ref/iam.rst +27 -0
- data/packages/gsutil/boto/docs/source/ref/index.rst +40 -0
- data/packages/gsutil/boto/docs/source/ref/manage.rst +47 -0
- data/packages/gsutil/boto/docs/source/ref/mturk.rst +54 -0
- data/packages/gsutil/boto/docs/source/ref/mws.rst +33 -0
- data/packages/gsutil/boto/docs/source/ref/pyami.rst +103 -0
- data/packages/gsutil/boto/docs/source/ref/rds.rst +47 -0
- data/packages/gsutil/boto/docs/source/ref/route53.rst +34 -0
- data/packages/gsutil/boto/docs/source/ref/s3.rst +111 -0
- data/packages/gsutil/boto/docs/source/ref/sdb.rst +45 -0
- data/packages/gsutil/boto/docs/source/ref/sdb_db.rst +83 -0
- data/packages/gsutil/boto/docs/source/ref/services.rst +61 -0
- data/packages/gsutil/boto/docs/source/ref/ses.rst +21 -0
- data/packages/gsutil/boto/docs/source/ref/sns.rst +17 -0
- data/packages/gsutil/boto/docs/source/ref/sqs.rst +61 -0
- data/packages/gsutil/boto/docs/source/ref/sts.rst +25 -0
- data/packages/gsutil/boto/docs/source/ref/swf.rst +22 -0
- data/packages/gsutil/boto/docs/source/ref/vpc.rst +54 -0
- data/packages/gsutil/boto/docs/source/s3_tut.rst +450 -0
- data/packages/gsutil/boto/docs/source/security_groups.rst +82 -0
- data/packages/gsutil/boto/docs/source/ses_tut.rst +171 -0
- data/packages/gsutil/boto/docs/source/simpledb_tut.rst +188 -0
- data/packages/gsutil/boto/docs/source/sqs_tut.rst +246 -0
- data/packages/gsutil/boto/docs/source/vpc_tut.rst +100 -0
- data/packages/gsutil/boto/pylintrc +305 -0
- data/packages/gsutil/boto/requirements.txt +10 -0
- data/packages/gsutil/boto/setup.py +89 -0
- data/packages/gsutil/boto/tests/__init__.py +20 -0
- data/packages/gsutil/boto/tests/db/test_lists.py +96 -0
- data/packages/gsutil/boto/tests/db/test_password.py +128 -0
- data/packages/gsutil/boto/tests/db/test_query.py +152 -0
- data/packages/gsutil/boto/tests/db/test_sequence.py +109 -0
- data/packages/gsutil/boto/tests/devpay/__init__.py +0 -0
- data/packages/gsutil/boto/tests/devpay/test_s3.py +181 -0
- data/packages/gsutil/boto/tests/fps/__init__.py +0 -0
- data/packages/gsutil/boto/tests/fps/test.py +100 -0
- data/packages/gsutil/boto/tests/fps/test_verify_signature.py +12 -0
- data/packages/gsutil/boto/tests/integration/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/beanstalk/test_wrapper.py +209 -0
- data/packages/gsutil/boto/tests/integration/cloudformation/__init__.py +21 -0
- data/packages/gsutil/boto/tests/integration/cloudformation/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/cloudformation/test_connection.py +110 -0
- data/packages/gsutil/boto/tests/integration/cloudsearch/__init__.py +21 -0
- data/packages/gsutil/boto/tests/integration/cloudsearch/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/datapipeline/test_layer1.py +122 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/test_layer1.py +266 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/test_layer2.py +484 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/test_table.py +84 -0
- data/packages/gsutil/boto/tests/integration/ec2/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/ec2/autoscale/__init__.py +21 -0
- data/packages/gsutil/boto/tests/integration/ec2/autoscale/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ec2/autoscale/test_connection.py +167 -0
- data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/test_connection.py +277 -0
- data/packages/gsutil/boto/tests/integration/ec2/elb/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/ec2/elb/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ec2/elb/test_connection.py +130 -0
- data/packages/gsutil/boto/tests/integration/ec2/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ec2/test_connection.py +192 -0
- data/packages/gsutil/boto/tests/integration/ec2/vpc/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/ec2/vpc/test_connection.py +95 -0
- data/packages/gsutil/boto/tests/integration/elasticache/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/elasticache/test_layer1.py +67 -0
- data/packages/gsutil/boto/tests/integration/elastictranscoder/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/elastictranscoder/test_cert_verification.py +35 -0
- data/packages/gsutil/boto/tests/integration/elastictranscoder/test_layer1.py +115 -0
- data/packages/gsutil/boto/tests/integration/emr/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/emr/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/glacier/__init__.py +22 -0
- data/packages/gsutil/boto/tests/integration/glacier/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/glacier/test_layer1.py +44 -0
- data/packages/gsutil/boto/tests/integration/glacier/test_layer2.py +45 -0
- data/packages/gsutil/boto/tests/integration/gs/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/gs/cb_test_harness.py +71 -0
- data/packages/gsutil/boto/tests/integration/gs/test_basic.py +379 -0
- data/packages/gsutil/boto/tests/integration/gs/test_generation_conditionals.py +399 -0
- data/packages/gsutil/boto/tests/integration/gs/test_resumable_downloads.py +358 -0
- data/packages/gsutil/boto/tests/integration/gs/test_resumable_uploads.py +525 -0
- data/packages/gsutil/boto/tests/integration/gs/test_storage_uri.py +125 -0
- data/packages/gsutil/boto/tests/integration/gs/test_versioning.py +268 -0
- data/packages/gsutil/boto/tests/integration/gs/testcase.py +116 -0
- data/packages/gsutil/boto/tests/integration/gs/util.py +63 -0
- data/packages/gsutil/boto/tests/integration/iam/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/iam/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/mws/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/mws/test.py +100 -0
- data/packages/gsutil/boto/tests/integration/rds/__init__.py +21 -0
- data/packages/gsutil/boto/tests/integration/rds/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/route53/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/route53/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/route53/test_zone.py +132 -0
- data/packages/gsutil/boto/tests/integration/s3/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/s3/mock_storage_service.py +589 -0
- data/packages/gsutil/boto/tests/integration/s3/other_cacerts.txt +70 -0
- data/packages/gsutil/boto/tests/integration/s3/test_bucket.py +263 -0
- data/packages/gsutil/boto/tests/integration/s3/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/s3/test_connection.py +245 -0
- data/packages/gsutil/boto/tests/integration/s3/test_cors.py +78 -0
- data/packages/gsutil/boto/tests/integration/s3/test_encryption.py +115 -0
- data/packages/gsutil/boto/tests/integration/s3/test_https_cert_validation.py +141 -0
- data/packages/gsutil/boto/tests/integration/s3/test_key.py +375 -0
- data/packages/gsutil/boto/tests/integration/s3/test_mfa.py +95 -0
- data/packages/gsutil/boto/tests/integration/s3/test_multidelete.py +181 -0
- data/packages/gsutil/boto/tests/integration/s3/test_multipart.py +139 -0
- data/packages/gsutil/boto/tests/integration/s3/test_pool.py +246 -0
- data/packages/gsutil/boto/tests/integration/s3/test_versioning.py +158 -0
- data/packages/gsutil/boto/tests/integration/sdb/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/sdb/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/sdb/test_connection.py +119 -0
- data/packages/gsutil/boto/tests/integration/ses/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/ses/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ses/test_connection.py +38 -0
- data/packages/gsutil/boto/tests/integration/sns/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/sns/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/sqs/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/sqs/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/sqs/test_connection.py +217 -0
- data/packages/gsutil/boto/tests/integration/sts/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/sts/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/sts/test_session_token.py +65 -0
- data/packages/gsutil/boto/tests/integration/swf/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/swf/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/swf/test_layer1.py +246 -0
- data/packages/gsutil/boto/tests/integration/swf/test_layer1_workflow_execution.py +173 -0
- data/packages/gsutil/boto/tests/mturk/__init__.py +0 -0
- data/packages/gsutil/boto/tests/mturk/_init_environment.py +28 -0
- data/packages/gsutil/boto/tests/mturk/all_tests.py +24 -0
- data/packages/gsutil/boto/tests/mturk/cleanup_tests.py +47 -0
- data/packages/gsutil/boto/tests/mturk/common.py +45 -0
- data/packages/gsutil/boto/tests/mturk/create_free_text_question_regex.doctest +100 -0
- data/packages/gsutil/boto/tests/mturk/create_hit.doctest +92 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_binary.doctest +94 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_external.py +21 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_from_hit_type.doctest +103 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_test.py +21 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_with_qualifications.py +16 -0
- data/packages/gsutil/boto/tests/mturk/hit_persistence.py +27 -0
- data/packages/gsutil/boto/tests/mturk/mocks.py +11 -0
- data/packages/gsutil/boto/tests/mturk/reviewable_hits.doctest +129 -0
- data/packages/gsutil/boto/tests/mturk/run-doctest.py +13 -0
- data/packages/gsutil/boto/tests/mturk/search_hits.doctest +16 -0
- data/packages/gsutil/boto/tests/mturk/selenium_support.py +61 -0
- data/packages/gsutil/boto/tests/mturk/support.py +7 -0
- data/packages/gsutil/boto/tests/mturk/test_disable_hit.py +11 -0
- data/packages/gsutil/boto/tests/test.py +59 -0
- data/packages/gsutil/boto/tests/unit/__init__.py +79 -0
- data/packages/gsutil/boto/tests/unit/auth/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/auth/test_sigv4.py +73 -0
- data/packages/gsutil/boto/tests/unit/beanstalk/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/beanstalk/test_layer1.py +128 -0
- data/packages/gsutil/boto/tests/unit/cloudformation/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/cloudformation/test_connection.py +605 -0
- data/packages/gsutil/boto/tests/unit/cloudformation/test_stack.py +63 -0
- data/packages/gsutil/boto/tests/unit/cloudfront/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/cloudfront/test_invalidation_list.py +113 -0
- data/packages/gsutil/boto/tests/unit/cloudfront/test_signed_urls.py +354 -0
- data/packages/gsutil/boto/tests/unit/cloudsearch/__init__.py +1 -0
- data/packages/gsutil/boto/tests/unit/cloudsearch/test_connection.py +241 -0
- data/packages/gsutil/boto/tests/unit/cloudsearch/test_document.py +324 -0
- data/packages/gsutil/boto/tests/unit/cloudsearch/test_search.py +325 -0
- data/packages/gsutil/boto/tests/unit/dynamodb/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/dynamodb/test_batch.py +103 -0
- data/packages/gsutil/boto/tests/unit/dynamodb/test_layer2.py +119 -0
- data/packages/gsutil/boto/tests/unit/dynamodb/test_types.py +82 -0
- data/packages/gsutil/boto/tests/unit/ec2/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/ec2/autoscale/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/ec2/autoscale/test_group.py +162 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_address.py +39 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_blockdevicemapping.py +79 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_connection.py +480 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_instance.py +243 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_networkinterface.py +140 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_volume.py +248 -0
- data/packages/gsutil/boto/tests/unit/emr/test_emr_responses.py +373 -0
- data/packages/gsutil/boto/tests/unit/glacier/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_concurrent.py +120 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_job.py +60 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_layer1.py +98 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_layer2.py +266 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_utils.py +116 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_vault.py +100 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_writer.py +185 -0
- data/packages/gsutil/boto/tests/unit/provider/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/provider/test_provider.py +176 -0
- data/packages/gsutil/boto/tests/unit/rds/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/rds/test_connection.py +131 -0
- data/packages/gsutil/boto/tests/unit/s3/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/s3/test_cors_configuration.py +77 -0
- data/packages/gsutil/boto/tests/unit/s3/test_key.py +75 -0
- data/packages/gsutil/boto/tests/unit/s3/test_keyfile.py +101 -0
- data/packages/gsutil/boto/tests/unit/s3/test_lifecycle.py +97 -0
- data/packages/gsutil/boto/tests/unit/s3/test_tagging.py +47 -0
- data/packages/gsutil/boto/tests/unit/s3/test_uri.py +257 -0
- data/packages/gsutil/boto/tests/unit/s3/test_website.py +188 -0
- data/packages/gsutil/boto/tests/unit/sns/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/sns/test_connection.py +99 -0
- data/packages/gsutil/boto/tests/unit/sqs/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/sqs/test_connection.py +98 -0
- data/packages/gsutil/boto/tests/unit/sqs/test_queue.py +40 -0
- data/packages/gsutil/boto/tests/unit/sts/test_connection.py +74 -0
- data/packages/gsutil/boto/tests/unit/test_connection.py +60 -0
- data/packages/gsutil/boto/tests/unit/utils/test_utils.py +109 -0
- data/packages/gsutil/boto/tox.ini +8 -0
- data/packages/gsutil/gslib/README +5 -0
- data/packages/gsutil/gslib/__init__.py +22 -0
- data/packages/gsutil/gslib/__init__.pyc +0 -0
- data/packages/gsutil/gslib/addlhelp/__init__.py +15 -0
- data/packages/gsutil/gslib/addlhelp/acls.py +234 -0
- data/packages/gsutil/gslib/addlhelp/anon.py +57 -0
- data/packages/gsutil/gslib/addlhelp/command_opts.py +116 -0
- data/packages/gsutil/gslib/addlhelp/dev.py +139 -0
- data/packages/gsutil/gslib/addlhelp/metadata.py +186 -0
- data/packages/gsutil/gslib/addlhelp/naming.py +173 -0
- data/packages/gsutil/gslib/addlhelp/prod.py +160 -0
- data/packages/gsutil/gslib/addlhelp/projects.py +130 -0
- data/packages/gsutil/gslib/addlhelp/subdirs.py +110 -0
- data/packages/gsutil/gslib/addlhelp/support.py +86 -0
- data/packages/gsutil/gslib/addlhelp/versioning.py +242 -0
- data/packages/gsutil/gslib/addlhelp/wildcards.py +170 -0
- data/packages/gsutil/gslib/bucket_listing_ref.py +175 -0
- data/packages/gsutil/gslib/bucket_listing_ref.pyc +0 -0
- data/packages/gsutil/gslib/command.py +722 -0
- data/packages/gsutil/gslib/command.pyc +0 -0
- data/packages/gsutil/gslib/command_runner.py +101 -0
- data/packages/gsutil/gslib/command_runner.pyc +0 -0
- data/packages/gsutil/gslib/commands/__init__.py +15 -0
- data/packages/gsutil/gslib/commands/__init__.pyc +0 -0
- data/packages/gsutil/gslib/commands/cat.py +131 -0
- data/packages/gsutil/gslib/commands/cat.pyc +0 -0
- data/packages/gsutil/gslib/commands/chacl.py +532 -0
- data/packages/gsutil/gslib/commands/chacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/config.py +694 -0
- data/packages/gsutil/gslib/commands/config.pyc +0 -0
- data/packages/gsutil/gslib/commands/cp.py +1818 -0
- data/packages/gsutil/gslib/commands/cp.pyc +0 -0
- data/packages/gsutil/gslib/commands/disablelogging.py +101 -0
- data/packages/gsutil/gslib/commands/disablelogging.pyc +0 -0
- data/packages/gsutil/gslib/commands/enablelogging.py +149 -0
- data/packages/gsutil/gslib/commands/enablelogging.pyc +0 -0
- data/packages/gsutil/gslib/commands/getacl.py +82 -0
- data/packages/gsutil/gslib/commands/getacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/getcors.py +121 -0
- data/packages/gsutil/gslib/commands/getcors.pyc +0 -0
- data/packages/gsutil/gslib/commands/getdefacl.py +86 -0
- data/packages/gsutil/gslib/commands/getdefacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/getlogging.py +137 -0
- data/packages/gsutil/gslib/commands/getlogging.pyc +0 -0
- data/packages/gsutil/gslib/commands/getversioning.py +116 -0
- data/packages/gsutil/gslib/commands/getversioning.pyc +0 -0
- data/packages/gsutil/gslib/commands/getwebcfg.py +122 -0
- data/packages/gsutil/gslib/commands/getwebcfg.pyc +0 -0
- data/packages/gsutil/gslib/commands/help.py +218 -0
- data/packages/gsutil/gslib/commands/help.pyc +0 -0
- data/packages/gsutil/gslib/commands/ls.py +578 -0
- data/packages/gsutil/gslib/commands/ls.pyc +0 -0
- data/packages/gsutil/gslib/commands/mb.py +172 -0
- data/packages/gsutil/gslib/commands/mb.pyc +0 -0
- data/packages/gsutil/gslib/commands/mv.py +159 -0
- data/packages/gsutil/gslib/commands/mv.pyc +0 -0
- data/packages/gsutil/gslib/commands/perfdiag.py +903 -0
- data/packages/gsutil/gslib/commands/perfdiag.pyc +0 -0
- data/packages/gsutil/gslib/commands/rb.py +113 -0
- data/packages/gsutil/gslib/commands/rb.pyc +0 -0
- data/packages/gsutil/gslib/commands/rm.py +239 -0
- data/packages/gsutil/gslib/commands/rm.pyc +0 -0
- data/packages/gsutil/gslib/commands/setacl.py +138 -0
- data/packages/gsutil/gslib/commands/setacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/setcors.py +145 -0
- data/packages/gsutil/gslib/commands/setcors.pyc +0 -0
- data/packages/gsutil/gslib/commands/setdefacl.py +105 -0
- data/packages/gsutil/gslib/commands/setdefacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/setmeta.py +428 -0
- data/packages/gsutil/gslib/commands/setmeta.pyc +0 -0
- data/packages/gsutil/gslib/commands/setversioning.py +114 -0
- data/packages/gsutil/gslib/commands/setversioning.pyc +0 -0
- data/packages/gsutil/gslib/commands/setwebcfg.py +190 -0
- data/packages/gsutil/gslib/commands/setwebcfg.pyc +0 -0
- data/packages/gsutil/gslib/commands/test.py +228 -0
- data/packages/gsutil/gslib/commands/test.pyc +0 -0
- data/packages/gsutil/gslib/commands/update.py +305 -0
- data/packages/gsutil/gslib/commands/update.pyc +0 -0
- data/packages/gsutil/gslib/commands/version.py +150 -0
- data/packages/gsutil/gslib/commands/version.pyc +0 -0
- data/packages/gsutil/gslib/exception.py +76 -0
- data/packages/gsutil/gslib/exception.pyc +0 -0
- data/packages/gsutil/gslib/help_provider.py +81 -0
- data/packages/gsutil/gslib/help_provider.pyc +0 -0
- data/packages/gsutil/gslib/name_expansion.py +550 -0
- data/packages/gsutil/gslib/name_expansion.pyc +0 -0
- data/packages/gsutil/gslib/no_op_auth_plugin.py +30 -0
- data/packages/gsutil/gslib/plurality_checkable_iterator.py +56 -0
- data/packages/gsutil/gslib/plurality_checkable_iterator.pyc +0 -0
- data/packages/gsutil/gslib/project_id.py +67 -0
- data/packages/gsutil/gslib/project_id.pyc +0 -0
- data/packages/gsutil/gslib/storage_uri_builder.py +56 -0
- data/packages/gsutil/gslib/storage_uri_builder.pyc +0 -0
- data/packages/gsutil/gslib/tests/__init__.py +15 -0
- data/packages/gsutil/gslib/tests/__init__.pyc +0 -0
- data/packages/gsutil/gslib/tests/test_chacl.py +236 -0
- data/packages/gsutil/gslib/tests/test_cp.py +267 -0
- data/packages/gsutil/gslib/tests/test_data/test.gif +0 -0
- data/packages/gsutil/gslib/tests/test_data/test.mp3 +0 -0
- data/packages/gsutil/gslib/tests/test_ls.py +66 -0
- data/packages/gsutil/gslib/tests/test_mv.py +69 -0
- data/packages/gsutil/gslib/tests/test_naming.py +989 -0
- data/packages/gsutil/gslib/tests/test_perfdiag.py +41 -0
- data/packages/gsutil/gslib/tests/test_plurality_checkable_iterator.py +67 -0
- data/packages/gsutil/gslib/tests/test_rm.py +143 -0
- data/packages/gsutil/gslib/tests/test_setacl.py +152 -0
- data/packages/gsutil/gslib/tests/test_setcors.py +168 -0
- data/packages/gsutil/gslib/tests/test_setmeta.py +91 -0
- data/packages/gsutil/gslib/tests/test_setversioning.py +44 -0
- data/packages/gsutil/gslib/tests/test_setwebcfg.py +63 -0
- data/packages/gsutil/gslib/tests/test_thread_pool.py +92 -0
- data/packages/gsutil/gslib/tests/test_wildcard_iterator.py +364 -0
- data/packages/gsutil/gslib/tests/testcase/__init__.py +18 -0
- data/packages/gsutil/gslib/tests/testcase/base.py +89 -0
- data/packages/gsutil/gslib/tests/testcase/integration_testcase.py +197 -0
- data/packages/gsutil/gslib/tests/testcase/unit_testcase.py +230 -0
- data/packages/gsutil/gslib/tests/util.py +125 -0
- data/packages/gsutil/gslib/tests/util.pyc +0 -0
- data/packages/gsutil/gslib/thread_pool.py +79 -0
- data/packages/gsutil/gslib/thread_pool.pyc +0 -0
- data/packages/gsutil/gslib/util.py +151 -0
- data/packages/gsutil/gslib/util.pyc +0 -0
- data/packages/gsutil/gslib/wildcard_iterator.py +492 -0
- data/packages/gsutil/gslib/wildcard_iterator.pyc +0 -0
- data/packages/gsutil/gsutil +377 -0
- data/packages/gsutil/gsutil.spec.in +75 -0
- data/packages/gsutil/oauth2_plugin/__init__.py +22 -0
- data/packages/gsutil/oauth2_plugin/__init__.pyc +0 -0
- data/packages/gsutil/oauth2_plugin/oauth2_client.py +642 -0
- data/packages/gsutil/oauth2_plugin/oauth2_client.pyc +0 -0
- data/packages/gsutil/oauth2_plugin/oauth2_client_test.py +374 -0
- data/packages/gsutil/oauth2_plugin/oauth2_helper.py +110 -0
- data/packages/gsutil/oauth2_plugin/oauth2_helper.pyc +0 -0
- data/packages/gsutil/oauth2_plugin/oauth2_plugin.py +24 -0
- data/packages/gsutil/oauth2_plugin/oauth2_plugin.pyc +0 -0
- data/packages/gsutil/pkg_gen.sh +54 -0
- data/packages/gsutil/pkg_util.py +60 -0
- data/packages/gsutil/setup.py +141 -0
- data/packages/gsutil/third_party/__init__.py +0 -0
- data/packages/gsutil/third_party/__init__.pyc +0 -0
- data/packages/gsutil/third_party/fancy_urllib/README +21 -0
- data/packages/gsutil/third_party/fancy_urllib/__init__.py +398 -0
- data/packages/gsutil/third_party/fancy_urllib/__init__.pyc +0 -0
- data/tasks/rubygem.rake +3 -1
- metadata +770 -7
- metadata.gz.sig +0 -0
|
Binary file
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding=utf8
|
|
3
|
+
# Copyright 2011 Google Inc. All Rights Reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
"""Class that runs a named gsutil command."""
|
|
18
|
+
|
|
19
|
+
import boto
|
|
20
|
+
import os
|
|
21
|
+
|
|
22
|
+
from boto.storage_uri import BucketStorageUri
|
|
23
|
+
from gslib.command import Command
|
|
24
|
+
from gslib.command import COMMAND_NAME
|
|
25
|
+
from gslib.command import COMMAND_NAME_ALIASES
|
|
26
|
+
from gslib.exception import CommandException
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class CommandRunner(object):
|
|
30
|
+
|
|
31
|
+
def __init__(self, gsutil_bin_dir, boto_lib_dir, config_file_list,
|
|
32
|
+
gsutil_ver, bucket_storage_uri_class=BucketStorageUri):
|
|
33
|
+
"""
|
|
34
|
+
Args:
|
|
35
|
+
gsutil_bin_dir: Bin dir from which gsutil is running.
|
|
36
|
+
boto_lib_dir: Lib dir where boto runs.
|
|
37
|
+
config_file_list: Config file list returned by _GetBotoConfigFileList().
|
|
38
|
+
gsutil_ver: Version string of currently running gsutil command.
|
|
39
|
+
bucket_storage_uri_class: Class to instantiate for cloud StorageUris.
|
|
40
|
+
Settable for testing/mocking.
|
|
41
|
+
"""
|
|
42
|
+
self.gsutil_bin_dir = gsutil_bin_dir
|
|
43
|
+
self.boto_lib_dir = boto_lib_dir
|
|
44
|
+
self.config_file_list = config_file_list
|
|
45
|
+
self.gsutil_ver = gsutil_ver
|
|
46
|
+
self.bucket_storage_uri_class = bucket_storage_uri_class
|
|
47
|
+
self.command_map = self._LoadCommandMap()
|
|
48
|
+
|
|
49
|
+
def _LoadCommandMap(self):
|
|
50
|
+
"""Returns dict mapping each command_name to implementing class."""
|
|
51
|
+
# Walk gslib/commands and find all commands.
|
|
52
|
+
commands_dir = os.path.join(self.gsutil_bin_dir, 'gslib', 'commands')
|
|
53
|
+
for f in os.listdir(commands_dir):
|
|
54
|
+
# Handles no-extension files, etc.
|
|
55
|
+
(module_name, ext) = os.path.splitext(f)
|
|
56
|
+
if ext == '.py':
|
|
57
|
+
__import__('gslib.commands.%s' % module_name)
|
|
58
|
+
command_map = {}
|
|
59
|
+
# Only include Command subclasses in the dict.
|
|
60
|
+
for command in Command.__subclasses__():
|
|
61
|
+
command_map[command.command_spec[COMMAND_NAME]] = command
|
|
62
|
+
for command_name_aliases in command.command_spec[COMMAND_NAME_ALIASES]:
|
|
63
|
+
command_map[command_name_aliases] = command
|
|
64
|
+
return command_map
|
|
65
|
+
|
|
66
|
+
def RunNamedCommand(self, command_name, args=None, headers=None, debug=0,
|
|
67
|
+
parallel_operations=False, test_method=None):
|
|
68
|
+
"""Runs the named command. Used by gsutil main, commands built atop
|
|
69
|
+
other commands, and tests .
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
command_name: The name of the command being run.
|
|
73
|
+
args: Command-line args (arg0 = actual arg, not command name ala bash).
|
|
74
|
+
headers: Dictionary containing optional HTTP headers to pass to boto.
|
|
75
|
+
debug: Debug level to pass in to boto connection (range 0..3).
|
|
76
|
+
parallel_operations: Should command operations be executed in parallel?
|
|
77
|
+
test_method: Optional general purpose method for testing purposes.
|
|
78
|
+
Application and semantics of this method will vary by
|
|
79
|
+
command and test type.
|
|
80
|
+
|
|
81
|
+
Raises:
|
|
82
|
+
CommandException: if errors encountered.
|
|
83
|
+
"""
|
|
84
|
+
if not args:
|
|
85
|
+
args = []
|
|
86
|
+
|
|
87
|
+
# Include api_version header in all commands.
|
|
88
|
+
api_version = boto.config.get_value('GSUtil', 'default_api_version', '1')
|
|
89
|
+
if not headers:
|
|
90
|
+
headers = {}
|
|
91
|
+
headers['x-goog-api-version'] = api_version
|
|
92
|
+
|
|
93
|
+
if command_name not in self.command_map:
|
|
94
|
+
raise CommandException('Invalid command "%s".' % command_name)
|
|
95
|
+
command_class = self.command_map[command_name]
|
|
96
|
+
command_inst = command_class(self, args, headers, debug,
|
|
97
|
+
parallel_operations, self.gsutil_bin_dir,
|
|
98
|
+
self.boto_lib_dir, self.config_file_list,
|
|
99
|
+
self.gsutil_ver, self.bucket_storage_uri_class,
|
|
100
|
+
test_method)
|
|
101
|
+
return command_inst.RunCommand()
|
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright 2011 Google Inc. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain 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,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Package marker file."""
|
|
Binary file
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Copyright 2011 Google Inc. All Rights Reserved.
|
|
2
|
+
# Copyright 2011, Nexenta Systems Inc.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
from gslib.command import Command
|
|
19
|
+
from gslib.command import COMMAND_NAME
|
|
20
|
+
from gslib.command import COMMAND_NAME_ALIASES
|
|
21
|
+
from gslib.command import CONFIG_REQUIRED
|
|
22
|
+
from gslib.command import FILE_URIS_OK
|
|
23
|
+
from gslib.command import MAX_ARGS
|
|
24
|
+
from gslib.command import MIN_ARGS
|
|
25
|
+
from gslib.command import PROVIDER_URIS_OK
|
|
26
|
+
from gslib.command import SUPPORTED_SUB_ARGS
|
|
27
|
+
from gslib.command import URIS_START_ARG
|
|
28
|
+
from gslib.exception import CommandException
|
|
29
|
+
from gslib.help_provider import HELP_NAME
|
|
30
|
+
from gslib.help_provider import HELP_NAME_ALIASES
|
|
31
|
+
from gslib.help_provider import HELP_ONE_LINE_SUMMARY
|
|
32
|
+
from gslib.help_provider import HELP_TEXT
|
|
33
|
+
from gslib.help_provider import HelpType
|
|
34
|
+
from gslib.help_provider import HELP_TYPE
|
|
35
|
+
from gslib.util import NO_MAX
|
|
36
|
+
from gslib.wildcard_iterator import ContainsWildcard
|
|
37
|
+
|
|
38
|
+
_detailed_help_text = ("""
|
|
39
|
+
<B>SYNOPSIS</B>
|
|
40
|
+
gsutil cat [-h] uri...
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
<B>DESCRIPTION</B>
|
|
44
|
+
The cat command outputs the contents of one or more URIs to stdout.
|
|
45
|
+
It is equivalent to doing:
|
|
46
|
+
|
|
47
|
+
gsutil cp uri... -
|
|
48
|
+
|
|
49
|
+
(The final '-' causes gsutil to stream the output to stdout.)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
<B>OPTIONS</B>
|
|
53
|
+
-h Prints short header for each object. For example:
|
|
54
|
+
gsutil cat -h gs://bucket/meeting_notes/2012_Feb/*.txt
|
|
55
|
+
""")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class CatCommand(Command):
|
|
59
|
+
"""Implementation of gsutil cat command."""
|
|
60
|
+
|
|
61
|
+
# Command specification (processed by parent class).
|
|
62
|
+
command_spec = {
|
|
63
|
+
# Name of command.
|
|
64
|
+
COMMAND_NAME : 'cat',
|
|
65
|
+
# List of command name aliases.
|
|
66
|
+
COMMAND_NAME_ALIASES : [],
|
|
67
|
+
# Min number of args required by this command.
|
|
68
|
+
MIN_ARGS : 0,
|
|
69
|
+
# Max number of args required by this command, or NO_MAX.
|
|
70
|
+
MAX_ARGS : NO_MAX,
|
|
71
|
+
# Getopt-style string specifying acceptable sub args.
|
|
72
|
+
SUPPORTED_SUB_ARGS : 'hv',
|
|
73
|
+
# True if file URIs acceptable for this command.
|
|
74
|
+
FILE_URIS_OK : False,
|
|
75
|
+
# True if provider-only URIs acceptable for this command.
|
|
76
|
+
PROVIDER_URIS_OK : False,
|
|
77
|
+
# Index in args of first URI arg.
|
|
78
|
+
URIS_START_ARG : 0,
|
|
79
|
+
# True if must configure gsutil before running command.
|
|
80
|
+
CONFIG_REQUIRED : True,
|
|
81
|
+
}
|
|
82
|
+
help_spec = {
|
|
83
|
+
# Name of command or auxiliary help info for which this help applies.
|
|
84
|
+
HELP_NAME : 'cat',
|
|
85
|
+
# List of help name aliases.
|
|
86
|
+
HELP_NAME_ALIASES : [],
|
|
87
|
+
# Type of help:
|
|
88
|
+
HELP_TYPE : HelpType.COMMAND_HELP,
|
|
89
|
+
# One line summary of this help.
|
|
90
|
+
HELP_ONE_LINE_SUMMARY : 'Concatenate object content to stdout',
|
|
91
|
+
# The full help text.
|
|
92
|
+
HELP_TEXT : _detailed_help_text,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# Command entry point.
|
|
96
|
+
def RunCommand(self):
|
|
97
|
+
show_header = False
|
|
98
|
+
if self.sub_opts:
|
|
99
|
+
for o, unused_a in self.sub_opts:
|
|
100
|
+
if o == '-h':
|
|
101
|
+
show_header = True
|
|
102
|
+
elif o == '-v':
|
|
103
|
+
self.THREADED_LOGGER.info('WARNING: The %s -v option is no longer'
|
|
104
|
+
' needed, and will eventually be removed.\n'
|
|
105
|
+
% self.command_name)
|
|
106
|
+
|
|
107
|
+
printed_one = False
|
|
108
|
+
# We manipulate the stdout so that all other data other than the Object
|
|
109
|
+
# contents go to stderr.
|
|
110
|
+
cat_outfd = sys.stdout
|
|
111
|
+
sys.stdout = sys.stderr
|
|
112
|
+
did_some_work = False
|
|
113
|
+
|
|
114
|
+
for uri_str in self.args:
|
|
115
|
+
for uri in self.WildcardIterator(uri_str).IterUris():
|
|
116
|
+
if not uri.names_object():
|
|
117
|
+
raise CommandException('"%s" command must specify objects.' %
|
|
118
|
+
self.command_name)
|
|
119
|
+
did_some_work = True
|
|
120
|
+
if show_header:
|
|
121
|
+
if printed_one:
|
|
122
|
+
print
|
|
123
|
+
print '==> %s <==' % uri.__str__()
|
|
124
|
+
printed_one = True
|
|
125
|
+
key = uri.get_key(False, self.headers)
|
|
126
|
+
key.get_file(cat_outfd, self.headers)
|
|
127
|
+
sys.stdout = cat_outfd
|
|
128
|
+
if not did_some_work:
|
|
129
|
+
raise CommandException('No URIs matched')
|
|
130
|
+
|
|
131
|
+
return 0
|
|
Binary file
|
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain 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,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
"""
|
|
15
|
+
This module provides the chacl command to gsutil.
|
|
16
|
+
|
|
17
|
+
This command allows users to easily specify changes to access control lists.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import random
|
|
21
|
+
import re
|
|
22
|
+
import time
|
|
23
|
+
from xml.dom import minidom
|
|
24
|
+
from boto.exception import GSResponseError
|
|
25
|
+
from boto.gs import acl
|
|
26
|
+
from gslib import name_expansion
|
|
27
|
+
from gslib.command import Command
|
|
28
|
+
from gslib.command import COMMAND_NAME
|
|
29
|
+
from gslib.command import COMMAND_NAME_ALIASES
|
|
30
|
+
from gslib.command import CONFIG_REQUIRED
|
|
31
|
+
from gslib.command import FILE_URIS_OK
|
|
32
|
+
from gslib.command import MAX_ARGS
|
|
33
|
+
from gslib.command import MIN_ARGS
|
|
34
|
+
from gslib.command import PROVIDER_URIS_OK
|
|
35
|
+
from gslib.command import SUPPORTED_SUB_ARGS
|
|
36
|
+
from gslib.command import URIS_START_ARG
|
|
37
|
+
from gslib.exception import CommandException
|
|
38
|
+
from gslib.help_provider import HELP_NAME
|
|
39
|
+
from gslib.help_provider import HELP_NAME_ALIASES
|
|
40
|
+
from gslib.help_provider import HELP_ONE_LINE_SUMMARY
|
|
41
|
+
from gslib.help_provider import HELP_TEXT
|
|
42
|
+
from gslib.help_provider import HELP_TYPE
|
|
43
|
+
from gslib.help_provider import HelpType
|
|
44
|
+
from gslib.util import NO_MAX
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ChangeType(object):
|
|
48
|
+
USER = 'User'
|
|
49
|
+
GROUP = 'Group'
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class AclChange(object):
|
|
53
|
+
"""Represents a logical change to an access control list."""
|
|
54
|
+
public_scopes = ['AllAuthenticatedUsers', 'AllUsers']
|
|
55
|
+
id_scopes = ['UserById', 'GroupById']
|
|
56
|
+
email_scopes = ['UserByEmail', 'GroupByEmail']
|
|
57
|
+
domain_scopes = ['GroupByDomain']
|
|
58
|
+
scope_types = public_scopes + id_scopes + email_scopes + domain_scopes
|
|
59
|
+
|
|
60
|
+
permission_shorthand_mapping = {
|
|
61
|
+
'R': 'READ',
|
|
62
|
+
'W': 'WRITE',
|
|
63
|
+
'FC': 'FULL_CONTROL',
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
def __init__(self, acl_change_descriptor, scope_type, logger):
|
|
67
|
+
"""Creates an AclChange object.
|
|
68
|
+
|
|
69
|
+
acl_change_descriptor: An acl change as described in chacl help.
|
|
70
|
+
scope_type: Either ChangeType.USER or ChangeType.GROUP, specifying the
|
|
71
|
+
extent of the scope.
|
|
72
|
+
logger: An instance of ThreadedLogger.
|
|
73
|
+
"""
|
|
74
|
+
self.logger = logger
|
|
75
|
+
self.identifier = ''
|
|
76
|
+
|
|
77
|
+
self.raw_descriptor = acl_change_descriptor
|
|
78
|
+
self._Parse(acl_change_descriptor, scope_type)
|
|
79
|
+
self._Validate()
|
|
80
|
+
|
|
81
|
+
def __str__(self):
|
|
82
|
+
return 'AclChange<{0}|{1}|{2}>'.format(self.scope_type, self.perm,
|
|
83
|
+
self.identifier)
|
|
84
|
+
|
|
85
|
+
def _Parse(self, change_descriptor, scope_type):
|
|
86
|
+
"""Parses an ACL Change descriptor."""
|
|
87
|
+
|
|
88
|
+
def _ClassifyScopeIdentifier(text):
|
|
89
|
+
re_map = {
|
|
90
|
+
'AllAuthenticatedUsers': r'^(AllAuthenticatedUsers|AllAuth)$',
|
|
91
|
+
'AllUsers': '^(AllUsers|All)$',
|
|
92
|
+
'Email': r'^.+@.+\..+$',
|
|
93
|
+
'Id': r'^[0-9A-Fa-f]{64}$',
|
|
94
|
+
'Domain': r'^[^@]+\..+$',
|
|
95
|
+
}
|
|
96
|
+
for type_string, regex in re_map.items():
|
|
97
|
+
if re.match(regex, text, re.IGNORECASE):
|
|
98
|
+
return type_string
|
|
99
|
+
|
|
100
|
+
if change_descriptor.count(':') != 1:
|
|
101
|
+
raise CommandException('{0} is an invalid change description.'
|
|
102
|
+
.format(change_descriptor))
|
|
103
|
+
|
|
104
|
+
scope_string, perm_token = change_descriptor.split(':')
|
|
105
|
+
|
|
106
|
+
perm_token = perm_token.upper()
|
|
107
|
+
if perm_token in self.permission_shorthand_mapping:
|
|
108
|
+
self.perm = self.permission_shorthand_mapping[perm_token]
|
|
109
|
+
else:
|
|
110
|
+
self.perm = perm_token
|
|
111
|
+
|
|
112
|
+
scope_class = _ClassifyScopeIdentifier(scope_string)
|
|
113
|
+
if scope_class == 'Domain':
|
|
114
|
+
# This may produce an invalid UserByDomain scope,
|
|
115
|
+
# which is good because then validate can complain.
|
|
116
|
+
self.scope_type = '{0}ByDomain'.format(scope_type)
|
|
117
|
+
self.identifier = scope_string
|
|
118
|
+
elif scope_class in ['Email', 'Id']:
|
|
119
|
+
self.scope_type = '{0}By{1}'.format(scope_type, scope_class)
|
|
120
|
+
self.identifier = scope_string
|
|
121
|
+
elif scope_class == 'AllAuthenticatedUsers':
|
|
122
|
+
self.scope_type = 'AllAuthenticatedUsers'
|
|
123
|
+
elif scope_class == 'AllUsers':
|
|
124
|
+
self.scope_type = 'AllUsers'
|
|
125
|
+
else:
|
|
126
|
+
# This is just a fallback, so we set it to something
|
|
127
|
+
# and the validate step has something to go on.
|
|
128
|
+
self.scope_type = scope_string
|
|
129
|
+
|
|
130
|
+
def _Validate(self):
|
|
131
|
+
"""Validates a parsed AclChange object."""
|
|
132
|
+
|
|
133
|
+
def _ThrowError(msg):
|
|
134
|
+
raise CommandException('{0} is not a valid ACL change\n{1}'
|
|
135
|
+
.format(self.raw_descriptor, msg))
|
|
136
|
+
|
|
137
|
+
if self.scope_type not in self.scope_types:
|
|
138
|
+
_ThrowError('{0} is not a valid scope type'.format(self.scope_type))
|
|
139
|
+
|
|
140
|
+
if self.scope_type in self.public_scopes and self.identifier:
|
|
141
|
+
_ThrowError('{0} requires no arguments'.format(self.scope_type))
|
|
142
|
+
|
|
143
|
+
if self.scope_type in self.id_scopes and not self.identifier:
|
|
144
|
+
_ThrowError('{0} requires an id'.format(self.scope_type))
|
|
145
|
+
|
|
146
|
+
if self.scope_type in self.email_scopes and not self.identifier:
|
|
147
|
+
_ThrowError('{0} requires an email address'.format(self.scope_type))
|
|
148
|
+
|
|
149
|
+
if self.scope_type in self.domain_scopes and not self.identifier:
|
|
150
|
+
_ThrowError('{0} requires domain'.format(self.scope_type))
|
|
151
|
+
|
|
152
|
+
if self.perm not in self.permission_shorthand_mapping.values():
|
|
153
|
+
perms = ', '.join(self.permission_shorthand_mapping.values())
|
|
154
|
+
_ThrowError('Allowed permissions are {0}'.format(perms))
|
|
155
|
+
|
|
156
|
+
def _YieldMatchingEntries(self, current_acl):
|
|
157
|
+
"""Generator that yields entries that match the change descriptor.
|
|
158
|
+
|
|
159
|
+
current_acl: An instance of bogo.gs.acl.ACL which will be searched
|
|
160
|
+
for matching entries.
|
|
161
|
+
"""
|
|
162
|
+
for entry in current_acl.entries.entry_list:
|
|
163
|
+
if entry.scope.type == self.scope_type:
|
|
164
|
+
if self.scope_type in ['UserById', 'GroupById']:
|
|
165
|
+
if self.identifier == entry.scope.id:
|
|
166
|
+
yield entry
|
|
167
|
+
elif self.scope_type in ['UserByEmail', 'GroupByEmail']:
|
|
168
|
+
if self.identifier == entry.scope.email_address:
|
|
169
|
+
yield entry
|
|
170
|
+
elif self.scope_type == 'GroupByDomain':
|
|
171
|
+
if self.identifier == entry.scope.domain:
|
|
172
|
+
yield entry
|
|
173
|
+
elif self.scope_type in ['AllUsers', 'AllAuthenticatedUsers']:
|
|
174
|
+
yield entry
|
|
175
|
+
else:
|
|
176
|
+
raise CommandException('Found an unrecognized ACL '
|
|
177
|
+
'entry type, aborting.')
|
|
178
|
+
|
|
179
|
+
def _AddEntry(self, current_acl):
|
|
180
|
+
"""Adds an entry to an ACL."""
|
|
181
|
+
if self.scope_type in ['UserById', 'UserById', 'GroupById']:
|
|
182
|
+
entry = acl.Entry(type=self.scope_type, permission=self.perm,
|
|
183
|
+
id=self.identifier)
|
|
184
|
+
elif self.scope_type in ['UserByEmail', 'GroupByEmail']:
|
|
185
|
+
entry = acl.Entry(type=self.scope_type, permission=self.perm,
|
|
186
|
+
email_address=self.identifier)
|
|
187
|
+
elif self.scope_type == 'GroupByDomain':
|
|
188
|
+
entry = acl.Entry(type=self.scope_type, permission=self.perm,
|
|
189
|
+
domain=self.identifier)
|
|
190
|
+
else:
|
|
191
|
+
entry = acl.Entry(type=self.scope_type, permission=self.perm)
|
|
192
|
+
|
|
193
|
+
current_acl.entries.entry_list.append(entry)
|
|
194
|
+
|
|
195
|
+
def Execute(self, uri, current_acl):
|
|
196
|
+
"""Executes the described change on an ACL.
|
|
197
|
+
|
|
198
|
+
uri: The URI object to change.
|
|
199
|
+
current_acl: An instance of boto.gs.acl.ACL to permute.
|
|
200
|
+
"""
|
|
201
|
+
self.logger.debug('Executing {0} on {1}'
|
|
202
|
+
.format(self.raw_descriptor, uri))
|
|
203
|
+
|
|
204
|
+
if self.perm == 'WRITE' and uri.names_object():
|
|
205
|
+
self.logger.warn(
|
|
206
|
+
'Skipping {0} on {1}, as WRITE does not apply to objects'
|
|
207
|
+
.format(self.raw_descriptor, uri))
|
|
208
|
+
return 0
|
|
209
|
+
|
|
210
|
+
matching_entries = list(self._YieldMatchingEntries(current_acl))
|
|
211
|
+
change_count = 0
|
|
212
|
+
if matching_entries:
|
|
213
|
+
for entry in matching_entries:
|
|
214
|
+
if entry.permission != self.perm:
|
|
215
|
+
entry.permission = self.perm
|
|
216
|
+
change_count += 1
|
|
217
|
+
else:
|
|
218
|
+
self._AddEntry(current_acl)
|
|
219
|
+
change_count = 1
|
|
220
|
+
|
|
221
|
+
parsed_acl = minidom.parseString(current_acl.to_xml())
|
|
222
|
+
self.logger.debug('New Acl:\n{0}'.format(parsed_acl.toprettyxml()))
|
|
223
|
+
return change_count
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class AclDel(AclChange):
|
|
227
|
+
"""Represents a logical change from an access control list."""
|
|
228
|
+
scope_regexes = {
|
|
229
|
+
r'All(Users)?': 'AllUsers',
|
|
230
|
+
r'AllAuth(enticatedUsers)?': 'AllAuthenticatedUsers',
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
def __init__(self, identifier, logger):
|
|
234
|
+
self.raw_descriptor = '-d {0}'.format(identifier)
|
|
235
|
+
self.logger = logger
|
|
236
|
+
self.identifier = identifier
|
|
237
|
+
for regex, scope in self.scope_regexes.items():
|
|
238
|
+
if re.match(regex, self.identifier, re.IGNORECASE):
|
|
239
|
+
self.identifier = scope
|
|
240
|
+
self.scope_type = 'Any'
|
|
241
|
+
self.perm = 'NONE'
|
|
242
|
+
|
|
243
|
+
def _YieldMatchingEntries(self, current_acl):
|
|
244
|
+
for entry in current_acl.entries.entry_list:
|
|
245
|
+
if self.identifier == entry.scope.id:
|
|
246
|
+
yield entry
|
|
247
|
+
elif self.identifier == entry.scope.email_address:
|
|
248
|
+
yield entry
|
|
249
|
+
elif self.identifier == entry.scope.domain:
|
|
250
|
+
yield entry
|
|
251
|
+
elif self.identifier == 'AllUsers' and entry.scope.type == 'AllUsers':
|
|
252
|
+
yield entry
|
|
253
|
+
elif (self.identifier == 'AllAuthenticatedUsers'
|
|
254
|
+
and entry.scope.type == 'AllAuthenticatedUsers'):
|
|
255
|
+
yield entry
|
|
256
|
+
|
|
257
|
+
def Execute(self, uri, current_acl):
|
|
258
|
+
self.logger.debug('Executing {0} on {1}'
|
|
259
|
+
.format(self.raw_descriptor, uri))
|
|
260
|
+
matching_entries = list(self._YieldMatchingEntries(current_acl))
|
|
261
|
+
for entry in matching_entries:
|
|
262
|
+
current_acl.entries.entry_list.remove(entry)
|
|
263
|
+
parsed_acl = minidom.parseString(current_acl.to_xml())
|
|
264
|
+
self.logger.debug('New Acl:\n{0}'.format(parsed_acl.toprettyxml()))
|
|
265
|
+
return len(matching_entries)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
_detailed_help_text = ("""
|
|
269
|
+
<B>SYNOPSIS</B>
|
|
270
|
+
gsutil chacl [-R] -u|-g|-d <grant>... uri...
|
|
271
|
+
|
|
272
|
+
where each <grant> is one of the following forms:
|
|
273
|
+
-u <id|email>:<perm>
|
|
274
|
+
-g <id|email|domain|All|AllAuth>:<perm>
|
|
275
|
+
-d <id|email|domain|All|AllAuth>
|
|
276
|
+
|
|
277
|
+
<B>DESCRIPTION</B>
|
|
278
|
+
The chacl command updates access control lists, similar in spirit to the Linux
|
|
279
|
+
chmod command. You can specify multiple access grant additions and deletions
|
|
280
|
+
in a single command run; all changes will be made atomically to each object in
|
|
281
|
+
turn. For example, if the command requests deleting one grant and adding a
|
|
282
|
+
different grant, the ACLs being updated will never be left in an intermediate
|
|
283
|
+
state where one grant has been deleted but the second grant not yet added.
|
|
284
|
+
Each change specifies a user or group grant to add or delete, and for grant
|
|
285
|
+
additions, one of R, W, FC (for the permission to be granted). A more formal
|
|
286
|
+
description is provided in a later section; below we provide examples.
|
|
287
|
+
|
|
288
|
+
Note: If you want to set a simple "canned" ACL on each object (such as
|
|
289
|
+
project-private or public), or if you prefer to edit the XML representation
|
|
290
|
+
for ACLs, you can do that with the setacl command (see 'gsutil help setacl').
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
<B>EXAMPLES</B>
|
|
294
|
+
|
|
295
|
+
Grant the user john.doe@example.com WRITE access to the bucket
|
|
296
|
+
example-bucket:
|
|
297
|
+
|
|
298
|
+
gsutil chacl -u john.doe@example.com:WRITE gs://example-bucket
|
|
299
|
+
|
|
300
|
+
Grant the group admins@example.com FULL_CONTROL access to all jpg files in
|
|
301
|
+
the top level of example-bucket:
|
|
302
|
+
|
|
303
|
+
gsutil chacl -g admins@example.com:FC gs://example-bucket/*.jpg
|
|
304
|
+
|
|
305
|
+
Grant the user with the specified canonical ID READ access to all objects in
|
|
306
|
+
example-bucket that begin with folder/:
|
|
307
|
+
|
|
308
|
+
gsutil chacl -R \\
|
|
309
|
+
-u 84fac329bceSAMPLE777d5d22b8SAMPLE77d85ac2SAMPLE2dfcf7c4adf34da46:R \\
|
|
310
|
+
gs://example-bucket/folder/
|
|
311
|
+
|
|
312
|
+
Grant all users from my-domain.org READ access to the bucket
|
|
313
|
+
gcs.my-domain.org:
|
|
314
|
+
|
|
315
|
+
gsutil chacl -g my-domain.org:R gs://gcs.my-domain.org
|
|
316
|
+
|
|
317
|
+
Remove any current access by john.doe@example.com from the bucket
|
|
318
|
+
example-bucket:
|
|
319
|
+
|
|
320
|
+
gsutil chacl -d john.doe@example.com gs://example-bucket
|
|
321
|
+
|
|
322
|
+
If you have a large number of objects to update, enabling multi-threading with
|
|
323
|
+
the gsutil -m flag can significantly improve performance. The following
|
|
324
|
+
command adds FULL_CONTROL for admin@example.org using multi-threading:
|
|
325
|
+
|
|
326
|
+
gsutil -m chacl -R -u admin@example.org:FC gs://example-bucket
|
|
327
|
+
|
|
328
|
+
Grant READ access to everyone from my-domain.org and to all authenticated
|
|
329
|
+
users, and grant FULL_CONTROL to admin@mydomain.org, for the buckets
|
|
330
|
+
my-bucket and my-other-bucket, with multi-threading enabled:
|
|
331
|
+
|
|
332
|
+
gsutil -m chacl -R -g my-domain.org:R -g AllAuth:R \\
|
|
333
|
+
-u admin@mydomain.org:FC gs://my-bucket/ gs://my-other-bucket
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
<B>SCOPES</B>
|
|
337
|
+
There are four different scopes: Users, Groups, All Authenticated Users, and
|
|
338
|
+
All Users.
|
|
339
|
+
|
|
340
|
+
Users are added with -u and a plain ID or email address, as in
|
|
341
|
+
"-u john-doe@gmail.com:r"
|
|
342
|
+
|
|
343
|
+
Groups are like users, but specified with the -g flag, as in
|
|
344
|
+
"-g power-users@example.com:fc". Groups may also be specified as a full
|
|
345
|
+
domain, as in "-g my-company.com:r".
|
|
346
|
+
|
|
347
|
+
AllAuthenticatedUsers and AllUsers are specified directly, as
|
|
348
|
+
in "-g AllUsers:R" or "-g AllAuthenticatedUsers:FC". These are case
|
|
349
|
+
insensitive, and may be shortened to "all" and "allauth", respectively.
|
|
350
|
+
|
|
351
|
+
Removing permissions is specified with the -d flag and an ID, email
|
|
352
|
+
address, domain, or one of AllUsers or AllAuthenticatedUsers.
|
|
353
|
+
|
|
354
|
+
Many scopes can be specified on the same command line, allowing bundled
|
|
355
|
+
changes to be executed in a single run. This will reduce the number of
|
|
356
|
+
requests made to the server.
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
<B>PERMISSIONS</B>
|
|
360
|
+
You may specify the following permissions with either their shorthand or
|
|
361
|
+
their full name:
|
|
362
|
+
|
|
363
|
+
R: READ
|
|
364
|
+
W: WRITE
|
|
365
|
+
FC: FULL_CONTROL
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
<B>OPTIONS</B>
|
|
369
|
+
-R, -r Performs chacl request recursively, to all objects under the
|
|
370
|
+
specified URI.
|
|
371
|
+
|
|
372
|
+
-u Add or modify a user permission as specified in the SCOPES
|
|
373
|
+
and PERMISSIONS sections.
|
|
374
|
+
|
|
375
|
+
-g Add or modify a group permission as specified in the SCOPES
|
|
376
|
+
and PERMISSIONS sections.
|
|
377
|
+
|
|
378
|
+
-d Remove all permissions associated with the matching argument, as
|
|
379
|
+
specified in the SCOPES and PERMISSIONS sections.
|
|
380
|
+
""")
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
class ChAclCommand(Command):
|
|
384
|
+
"""Implementation of gsutil chacl command."""
|
|
385
|
+
|
|
386
|
+
# Command specification (processed by parent class).
|
|
387
|
+
command_spec = {
|
|
388
|
+
# Name of command.
|
|
389
|
+
COMMAND_NAME : 'chacl',
|
|
390
|
+
# List of command name aliases.
|
|
391
|
+
COMMAND_NAME_ALIASES : [],
|
|
392
|
+
# Min number of args required by this command.
|
|
393
|
+
MIN_ARGS : 1,
|
|
394
|
+
# Max number of args required by this command, or NO_MAX.
|
|
395
|
+
MAX_ARGS : NO_MAX,
|
|
396
|
+
# Getopt-style string specifying acceptable sub args.
|
|
397
|
+
SUPPORTED_SUB_ARGS : 'Rrfg:u:d:',
|
|
398
|
+
# True if file URIs acceptable for this command.
|
|
399
|
+
FILE_URIS_OK : False,
|
|
400
|
+
# True if provider-only URIs acceptable for this command.
|
|
401
|
+
PROVIDER_URIS_OK : False,
|
|
402
|
+
# Index in args of first URI arg.
|
|
403
|
+
URIS_START_ARG : 1,
|
|
404
|
+
# True if must configure gsutil before running command.
|
|
405
|
+
CONFIG_REQUIRED : True,
|
|
406
|
+
}
|
|
407
|
+
help_spec = {
|
|
408
|
+
# Name of command or auxiliary help info for which this help applies.
|
|
409
|
+
HELP_NAME : 'chacl',
|
|
410
|
+
# List of help name aliases.
|
|
411
|
+
HELP_NAME_ALIASES : ['chmod'],
|
|
412
|
+
# Type of help:
|
|
413
|
+
HELP_TYPE : HelpType.COMMAND_HELP,
|
|
414
|
+
# One line summary of this help.
|
|
415
|
+
HELP_ONE_LINE_SUMMARY : 'Add / remove entries on bucket and/or object ACLs',
|
|
416
|
+
# The full help text.
|
|
417
|
+
HELP_TEXT : _detailed_help_text,
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
# Command entry point.
|
|
421
|
+
def RunCommand(self):
|
|
422
|
+
"""This is the point of entry for the chacl command."""
|
|
423
|
+
self.parse_versions = True
|
|
424
|
+
self.changes = []
|
|
425
|
+
|
|
426
|
+
if self.sub_opts:
|
|
427
|
+
for o, a in self.sub_opts:
|
|
428
|
+
if o == '-g':
|
|
429
|
+
self.changes.append(AclChange(a, scope_type=ChangeType.GROUP,
|
|
430
|
+
logger=self.THREADED_LOGGER))
|
|
431
|
+
if o == '-u':
|
|
432
|
+
self.changes.append(AclChange(a, scope_type=ChangeType.USER,
|
|
433
|
+
logger=self.THREADED_LOGGER))
|
|
434
|
+
if o == '-d':
|
|
435
|
+
self.changes.append(AclDel(a, logger=self.THREADED_LOGGER))
|
|
436
|
+
|
|
437
|
+
if not self.changes:
|
|
438
|
+
raise CommandException(
|
|
439
|
+
'Please specify at least one access change '
|
|
440
|
+
'with the -g, -u, or -d flags')
|
|
441
|
+
|
|
442
|
+
storage_uri = self.UrisAreForSingleProvider(self.args)
|
|
443
|
+
if not (storage_uri and storage_uri.get_provider().name == 'google'):
|
|
444
|
+
raise CommandException('The "{0}" command can only be used with gs:// URIs'
|
|
445
|
+
.format(self.command_name))
|
|
446
|
+
|
|
447
|
+
bulk_uris = set()
|
|
448
|
+
for uri_arg in self.args:
|
|
449
|
+
for result in self.WildcardIterator(uri_arg):
|
|
450
|
+
uri = result.uri
|
|
451
|
+
if uri.names_bucket():
|
|
452
|
+
if self.recursion_requested:
|
|
453
|
+
bulk_uris.add(uri.clone_replace_name('*').uri)
|
|
454
|
+
else:
|
|
455
|
+
# If applying to a bucket directly, the threading machinery will
|
|
456
|
+
# break, so we have to apply now, in the main thread.
|
|
457
|
+
self.ApplyAclChanges(uri)
|
|
458
|
+
else:
|
|
459
|
+
bulk_uris.add(uri_arg)
|
|
460
|
+
|
|
461
|
+
try:
|
|
462
|
+
name_expansion_iterator = name_expansion.NameExpansionIterator(
|
|
463
|
+
self.command_name, self.proj_id_handler, self.headers, self.debug,
|
|
464
|
+
self.bucket_storage_uri_class, bulk_uris, self.recursion_requested)
|
|
465
|
+
except CommandException as e:
|
|
466
|
+
# NameExpansionIterator will complain if there are no URIs, but we don't
|
|
467
|
+
# want to throw an error if we handled bucket URIs.
|
|
468
|
+
if e.reason == 'No URIs matched':
|
|
469
|
+
return 0
|
|
470
|
+
else:
|
|
471
|
+
raise e
|
|
472
|
+
|
|
473
|
+
self.everything_set_okay = True
|
|
474
|
+
self.Apply(self.ApplyAclChanges,
|
|
475
|
+
name_expansion_iterator,
|
|
476
|
+
self._ApplyExceptionHandler)
|
|
477
|
+
if not self.everything_set_okay:
|
|
478
|
+
raise CommandException('ACLs for some objects could not be set.')
|
|
479
|
+
|
|
480
|
+
return 0
|
|
481
|
+
|
|
482
|
+
def _ApplyExceptionHandler(self, exception):
|
|
483
|
+
self.THREADED_LOGGER.error('Encountered a problem: {0}'.format(exception))
|
|
484
|
+
self.everything_set_okay = False
|
|
485
|
+
|
|
486
|
+
def ApplyAclChanges(self, uri_or_expansion_result, retry=3):
|
|
487
|
+
"""Applies the changes in self.changes to the provided URI."""
|
|
488
|
+
if isinstance(uri_or_expansion_result, name_expansion.NameExpansionResult):
|
|
489
|
+
uri = self.suri_builder.StorageUri(
|
|
490
|
+
uri_or_expansion_result.expanded_uri_str)
|
|
491
|
+
else:
|
|
492
|
+
uri = uri_or_expansion_result
|
|
493
|
+
|
|
494
|
+
try:
|
|
495
|
+
current_acl = uri.get_acl()
|
|
496
|
+
except GSResponseError as e:
|
|
497
|
+
self.THREADED_LOGGER.warning('Failed to set acl for {0}: {1}'
|
|
498
|
+
.format(uri, e.reason))
|
|
499
|
+
return
|
|
500
|
+
|
|
501
|
+
modification_count = 0
|
|
502
|
+
for change in self.changes:
|
|
503
|
+
modification_count += change.Execute(uri, current_acl)
|
|
504
|
+
if modification_count == 0:
|
|
505
|
+
self.THREADED_LOGGER.info('No changes to {0}'.format(uri))
|
|
506
|
+
return
|
|
507
|
+
|
|
508
|
+
# TODO: Remove the concept of forcing when boto provides access to
|
|
509
|
+
# bucket generation and meta_generation.
|
|
510
|
+
headers = dict(self.headers)
|
|
511
|
+
force = uri.names_bucket()
|
|
512
|
+
if not force:
|
|
513
|
+
key = uri.get_key()
|
|
514
|
+
headers['x-goog-if-generation-match'] = key.generation
|
|
515
|
+
headers['x-goog-if-metageneration-match'] = key.meta_generation
|
|
516
|
+
try:
|
|
517
|
+
uri.set_acl(current_acl, uri.object_name, False, headers)
|
|
518
|
+
self.THREADED_LOGGER.info('Updated ACL on {0}'.format(uri))
|
|
519
|
+
except GSResponseError as response_error:
|
|
520
|
+
# HTTP error 412 is "Precondition Failed".
|
|
521
|
+
if response_error.status == 412:
|
|
522
|
+
if retry <= 0:
|
|
523
|
+
self.THREADED_LOGGER.error(
|
|
524
|
+
'Exhausted retries on {0}, giving up.'.format(uri))
|
|
525
|
+
return
|
|
526
|
+
self.THREADED_LOGGER.warn(
|
|
527
|
+
'Encountered a collision, retrying {0} more times on {1}'
|
|
528
|
+
.format(retry, uri))
|
|
529
|
+
time.sleep(random.uniform(0.5, 1.0))
|
|
530
|
+
return self.ApplyAclChanges(uri, retry - 1)
|
|
531
|
+
else:
|
|
532
|
+
raise response_error
|