awscli 1.40.17__py3-none-any.whl → 1.44.26__py3-none-any.whl
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.
- awscli/__init__.py +1 -1
- awscli/alias.py +3 -3
- awscli/argprocess.py +7 -2
- awscli/arguments.py +1 -1
- awscli/bcdoc/docevents.py +3 -0
- awscli/clidocs.py +19 -2
- awscli/clidriver.py +57 -10
- awscli/compat.py +11 -0
- awscli/customizations/argrename.py +1 -3
- awscli/customizations/cliinputjson.py +4 -0
- awscli/customizations/cloudformation/deploy.py +23 -6
- awscli/customizations/cloudformation/deployer.py +2 -2
- awscli/customizations/cloudformation/package.py +3 -2
- awscli/customizations/cloudfront.py +3 -1
- awscli/customizations/cloudtrail/subscribe.py +5 -5
- awscli/customizations/cloudtrail/validation.py +32 -11
- awscli/customizations/codecommit.py +2 -3
- awscli/customizations/codedeploy/deregister.py +5 -2
- awscli/customizations/codedeploy/push.py +7 -6
- awscli/customizations/codedeploy/register.py +5 -2
- awscli/customizations/codedeploy/systems.py +3 -1
- awscli/customizations/commands.py +2 -1
- awscli/customizations/configservice/getstatus.py +3 -3
- awscli/customizations/datapipeline/__init__.py +7 -4
- awscli/customizations/datapipeline/createdefaultroles.py +4 -2
- awscli/customizations/dlm/createdefaultrole.py +4 -2
- awscli/customizations/ec2/bundleinstance.py +2 -1
- awscli/customizations/eks/get_token.py +6 -4
- awscli/customizations/eks/update_kubeconfig.py +15 -3
- awscli/customizations/emr/argumentschema.py +355 -344
- awscli/customizations/emr/createcluster.py +520 -282
- awscli/customizations/emr/emrutils.py +83 -50
- awscli/customizations/emr/helptext.py +132 -74
- awscli/customizations/emr/steputils.py +92 -52
- awscli/customizations/gamelift/getlog.py +3 -2
- awscli/customizations/gamelift/uploadbuild.py +30 -15
- awscli/customizations/globalargs.py +169 -0
- awscli/customizations/logs/startlivetail.py +3 -3
- awscli/customizations/paginate.py +66 -1
- awscli/customizations/rds.py +3 -1
- awscli/customizations/removals.py +4 -0
- awscli/customizations/s3/filegenerator.py +7 -1
- awscli/customizations/s3/fileinfo.py +5 -1
- awscli/customizations/s3/fileinfobuilder.py +7 -0
- awscli/customizations/s3/s3handler.py +11 -0
- awscli/customizations/s3/subcommands.py +147 -6
- awscli/customizations/s3/syncstrategy/base.py +9 -0
- awscli/customizations/s3/syncstrategy/caseconflict.py +96 -0
- awscli/customizations/s3/utils.py +25 -0
- awscli/customizations/s3uploader.py +18 -8
- awscli/customizations/scalarparse.py +48 -9
- awscli/customizations/utils.py +2 -1
- awscli/customizations/waiters.py +3 -2
- awscli/data/cli.json +5 -0
- awscli/examples/apigateway/update-vpc-link.rst +47 -0
- awscli/examples/apigatewayv2/create-routing-rule.rst +52 -0
- awscli/examples/apigatewayv2/delete-routing-rule.rst +11 -0
- awscli/examples/apigatewayv2/get-routing-rule.rst +35 -0
- awscli/examples/apigatewayv2/list-routing-rules.rst +38 -0
- awscli/examples/apigatewayv2/put-routing-rule.rst +52 -0
- awscli/examples/application-signals/batch-get-service-level-objective-budget-report.rst +99 -0
- awscli/examples/application-signals/create-service-level-objective.rst +88 -0
- awscli/examples/application-signals/delete-service-level-objective.rst +10 -0
- awscli/examples/application-signals/get-service-level-objective.rst +53 -0
- awscli/examples/application-signals/get-service.rst +72 -0
- awscli/examples/application-signals/list-service-dependencies.rst +96 -0
- awscli/examples/application-signals/list-service-dependents.rst +36 -0
- awscli/examples/application-signals/list-service-level-objectives.rst +17 -0
- awscli/examples/application-signals/list-service-operations.rst +63 -0
- awscli/examples/application-signals/list-services.rst +61 -0
- awscli/examples/application-signals/list-tags-for-resource.rst +17 -0
- awscli/examples/application-signals/start-discovery.rst +9 -0
- awscli/examples/application-signals/tag-resource.rst +11 -0
- awscli/examples/application-signals/untag-resource.rst +11 -0
- awscli/examples/application-signals/update-service-level-objective.rst +69 -0
- awscli/examples/cloudformation/_package_description.rst +4 -4
- awscli/examples/cloudformation/create-generated-template.rst +50 -0
- awscli/examples/cloudformation/create-stack-refactor.rst +16 -0
- awscli/examples/cloudformation/delete-generated-template.rst +10 -0
- awscli/examples/cloudformation/describe-generated-template.rst +62 -0
- awscli/examples/cloudformation/describe-resource-scan.rst +38 -0
- awscli/examples/cloudformation/describe-stack-refactor.rst +20 -0
- awscli/examples/cloudformation/execute-stack-refactor.rst +10 -0
- awscli/examples/cloudformation/list-generated-templates.rst +41 -0
- awscli/examples/cloudformation/list-resource-scan-related-resources.rst +47 -0
- awscli/examples/cloudformation/list-resource-scan-resources.rst +30 -0
- awscli/examples/cloudformation/list-stack-refactor-actions.rst +71 -0
- awscli/examples/cloudformation/start-resource-scan.rst +14 -0
- awscli/examples/cloudfront/associate-distribution-tenant-web-acl.rst +18 -0
- awscli/examples/cloudfront/associate-distribution-web-acl.rst +18 -0
- awscli/examples/cloudfront/create-connection-group.rst +39 -0
- awscli/examples/cloudfront/create-distribution-tenant.rst +275 -0
- awscli/examples/cloudfront/create-distribution.rst +625 -235
- awscli/examples/cloudfront/create-invalidation-for-distribution-tenant.rst +29 -0
- awscli/examples/cloudfront/delete-connection-group.rst +11 -0
- awscli/examples/cloudfront/delete-distribution-tenant.rst +11 -0
- awscli/examples/cloudfront/disassociate-distribution-tenant-web-acl.rst +16 -0
- awscli/examples/cloudfront/disassociate-distribution-web-acl.rst +16 -0
- awscli/examples/cloudfront/get-connection-group-by-routing-endpoint.rst +26 -0
- awscli/examples/cloudfront/get-connection-group.rst +26 -0
- awscli/examples/cloudfront/get-distribution-tenant-by-domain.rst +37 -0
- awscli/examples/cloudfront/get-distribution-tenant.rst +31 -0
- awscli/examples/cloudfront/get-invalidation-for-distribution-tenant.rst +29 -0
- awscli/examples/cloudfront/get-managed-certificate-details.rst +25 -0
- awscli/examples/cloudfront/list-connection-groups.rst +38 -0
- awscli/examples/cloudfront/list-distribution-tenants-by-customization.rst +45 -0
- awscli/examples/cloudfront/list-distribution-tenants.rst +90 -0
- awscli/examples/cloudfront/list-distributions-by-connection-mode.rst +115 -0
- awscli/examples/cloudfront/list-domain-conflicts.rst +22 -0
- awscli/examples/cloudfront/list-invalidations-for-distribution-tenant.rst +22 -0
- awscli/examples/cloudfront/update-connection-group.rst +29 -0
- awscli/examples/cloudfront/update-distribution-tenant.rst +76 -0
- awscli/examples/cloudfront/update-domain-association.rst +18 -0
- awscli/examples/cloudfront/verify-dns-configuration.rst +20 -0
- awscli/examples/ec2/associate-ipam-resource-discovery.rst +1 -1
- awscli/examples/ec2/authorize-security-group-ingress.rst +1 -1
- awscli/examples/ec2/create-ipam-resource-discovery.rst +1 -1
- awscli/examples/ec2/delete-ipam-pool.rst +1 -1
- awscli/examples/ec2/describe-addresses-attribute.rst +1 -1
- awscli/examples/ec2/get-ipam-discovered-public-addresses.rst +1 -1
- awscli/examples/ec2/modify-ipam-resource-discovery.rst +1 -1
- awscli/examples/ec2/modify-ipam-scope.rst +1 -1
- awscli/examples/ec2/release-ipam-pool-allocation.rst +3 -3
- awscli/examples/eks/associate-access-policy.rst +29 -0
- awscli/examples/eks/create-access-entry.rst +54 -0
- awscli/examples/eks/create-pod-identity-association.rst +59 -0
- awscli/examples/eks/delete-access-entry.rst +11 -0
- awscli/examples/eks/delete-pod-identity-association.rst +28 -0
- awscli/examples/eks/describe-access-entry.rst +25 -0
- awscli/examples/eks/describe-insight.rst +36 -0
- awscli/examples/eks/describe-pod-identity-association.rst +28 -0
- awscli/examples/eks/disassociate-access-policy.rst +12 -0
- awscli/examples/eks/list-access-entries.rst +19 -0
- awscli/examples/eks/list-access-policies.rst +90 -0
- awscli/examples/eks/list-associated-access-policies.rst +27 -0
- awscli/examples/eks/list-insights.rst +67 -0
- awscli/examples/eks/list-pod-identity-associations.rst +61 -0
- awscli/examples/eks/update-access-entry.rst +28 -0
- awscli/examples/eks/update-pod-identity-association.rst +29 -0
- awscli/examples/elbv2/modify-listener.rst +95 -86
- awscli/examples/emr/create-cluster-synopsis.txt +1 -0
- awscli/examples/global_options.rst +4 -0
- awscli/examples/global_synopsis.rst +1 -0
- awscli/examples/guardduty/update-detector.rst +23 -0
- awscli/examples/ivs-realtime/create-stage.rst +6 -3
- awscli/examples/ivs-realtime/get-composition.rst +7 -4
- awscli/examples/ivs-realtime/get-participant.rst +99 -31
- awscli/examples/ivs-realtime/get-stage.rst +3 -2
- awscli/examples/ivs-realtime/list-participant-events.rst +54 -2
- awscli/examples/ivs-realtime/list-participant-replicas.rst +24 -0
- awscli/examples/ivs-realtime/list-participants.rst +61 -3
- awscli/examples/ivs-realtime/start-composition.rst +88 -3
- awscli/examples/ivs-realtime/start-participant-replication.rst +24 -0
- awscli/examples/ivs-realtime/stop-participant-replication.rst +24 -0
- awscli/examples/ivs-realtime/update-stage.rst +51 -3
- awscli/examples/kms/create-key.rst +42 -7
- awscli/examples/kms/delete-imported-key-material.rst +8 -2
- awscli/examples/kms/describe-key.rst +2 -0
- awscli/examples/kms/disable-key.rst +1 -1
- awscli/examples/kms/generate-data-key-pair-without-plaintext.rst +1 -0
- awscli/examples/kms/generate-data-key-pair.rst +1 -0
- awscli/examples/kms/generate-data-key-without-plaintext.rst +2 -1
- awscli/examples/kms/generate-data-key.rst +5 -4
- awscli/examples/kms/generate-mac.rst +45 -0
- awscli/examples/kms/generate-random.rst +1 -1
- awscli/examples/kms/get-public-key.rst +2 -3
- awscli/examples/kms/import-key-material.rst +6 -1
- awscli/examples/kms/re-encrypt.rst +3 -3
- awscli/examples/kms/sign.rst +1 -1
- awscli/examples/kms/verify-mac.rst +27 -0
- awscli/examples/kms/verify.rst +5 -1
- awscli/examples/lambda/create-function.rst +4 -4
- awscli/examples/lambda/get-function.rst +3 -3
- awscli/examples/lambda/list-functions.rst +6 -6
- awscli/examples/medical-imaging/create-datastore.rst +19 -2
- awscli/examples/medical-imaging/get-datastore.rst +24 -1
- awscli/examples/networkmanager/get-vpc-attachment.rst +1 -1
- awscli/examples/omics/cancel-run.rst +1 -1
- awscli/examples/omics/create-run-group.rst +4 -2
- awscli/examples/omics/create-workflow.rst +1 -1
- awscli/examples/omics/delete-run-group.rst +1 -1
- awscli/examples/omics/delete-run.rst +1 -1
- awscli/examples/omics/delete-workflow.rst +1 -1
- awscli/examples/omics/get-run-group.rst +1 -1
- awscli/examples/omics/get-run-task.rst +1 -1
- awscli/examples/omics/get-run.rst +1 -1
- awscli/examples/omics/get-workflow.rst +1 -1
- awscli/examples/omics/list-run-groups.rst +1 -1
- awscli/examples/omics/list-run-tasks.rst +1 -1
- awscli/examples/omics/list-runs.rst +1 -1
- awscli/examples/omics/list-workflows.rst +1 -1
- awscli/examples/omics/start-run.rst +1 -2
- awscli/examples/omics/update-workflow.rst +1 -1
- awscli/examples/pi/create-performance-analysis-report.rst +17 -0
- awscli/examples/pi/delete-performance-analysis-report.rst +12 -0
- awscli/examples/pi/describe-dimension-keys.rst +33 -1
- awscli/examples/pi/get-dimension-key-details.rst +25 -0
- awscli/examples/pi/get-performance-analysis-report.rst +27 -0
- awscli/examples/pi/get-resource-metadata.rst +20 -0
- awscli/examples/pi/list-available-resource-dimensions.rst +48 -0
- awscli/examples/pi/list-available-resource-metrics.rst +29 -0
- awscli/examples/pi/list-performance-analysis-reports.rst +44 -0
- awscli/examples/pi/list-tags-for-resource.rst +20 -0
- awscli/examples/pi/tag-resource.rst +12 -0
- awscli/examples/pi/untag-resource.rst +12 -0
- awscli/examples/route53domains/get-domain-detail.rst +3 -3
- awscli/examples/securityhub/describe-hub.rst +6 -4
- awscli/examples/servicediscovery/create-service.rst +50 -10
- awscli/examples/servicediscovery/delete-namespace.rst +18 -4
- awscli/examples/servicediscovery/delete-service-attributes.rst +15 -3
- awscli/examples/servicediscovery/delete-service.rst +13 -3
- awscli/examples/servicediscovery/deregister-instance.rst +18 -2
- awscli/examples/servicediscovery/discover-instances-revision.rst +18 -1
- awscli/examples/servicediscovery/discover-instances.rst +32 -2
- awscli/examples/servicediscovery/get-instance.rst +30 -4
- awscli/examples/servicediscovery/get-instances-health-status.rst +19 -1
- awscli/examples/servicediscovery/get-namespace.rst +40 -9
- awscli/examples/servicediscovery/get-operation.rst +32 -6
- awscli/examples/servicediscovery/get-service-attributes.rst +25 -3
- awscli/examples/servicediscovery/get-service.rst +35 -7
- awscli/examples/servicediscovery/list-instances.rst +38 -3
- awscli/examples/servicediscovery/list-namespaces.rst +45 -22
- awscli/examples/servicediscovery/list-services.rst +30 -2
- awscli/examples/servicediscovery/register-instance.rst +18 -2
- awscli/examples/servicediscovery/update-http-namespace.rst +22 -5
- awscli/examples/servicediscovery/update-instance-custom-health-status.rst +14 -1
- awscli/examples/servicediscovery/update-private-dns-namespace.rst +22 -5
- awscli/examples/servicediscovery/update-public-dns-namespace.rst +22 -5
- awscli/examples/servicediscovery/update-service-attributes.rst +14 -2
- awscli/examples/servicediscovery/update-service.rst +20 -4
- awscli/examples/ssm/put-parameter.rst +6 -6
- awscli/examples/verifiedpermissions/update-policy.rst +10 -78
- awscli/examples/workspaces/describe-workspace-directories.rst +1 -2
- awscli/examples/workspaces/register-workspace-directory.rst +2 -3
- awscli/handlers.py +0 -4
- awscli/paramfile.py +21 -4
- awscli/testutils.py +22 -4
- awscli/topics/config-vars.rst +1 -1
- awscli/topics/s3-case-insensitivity.rst +105 -0
- awscli/topics/topic-tags.json +16 -0
- awscli/utils.py +33 -2
- {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/METADATA +18 -3
- {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/RECORD +251 -308
- awscli/customizations/opsworks.py +0 -543
- awscli/customizations/opsworkscm.py +0 -21
- awscli/examples/elastictranscoder/cancel-job.rst +0 -8
- awscli/examples/elastictranscoder/create-job.rst +0 -94
- awscli/examples/elastictranscoder/create-pipeline.rst +0 -94
- awscli/examples/elastictranscoder/create-preset.rst +0 -141
- awscli/examples/elastictranscoder/delete-pipeline.rst +0 -13
- awscli/examples/elastictranscoder/delete-preset.rst +0 -8
- awscli/examples/elastictranscoder/list-jobs-by-pipeline.rst +0 -13
- awscli/examples/elastictranscoder/list-jobs-by-status.rst +0 -14
- awscli/examples/elastictranscoder/list-pipelines.rst +0 -84
- awscli/examples/elastictranscoder/list-presets.rst +0 -95
- awscli/examples/elastictranscoder/read-job.rst +0 -65
- awscli/examples/elastictranscoder/read-pipeline.rst +0 -59
- awscli/examples/elastictranscoder/read-preset.rst +0 -100
- awscli/examples/elastictranscoder/update-pipeline-notifications.rst +0 -52
- awscli/examples/elastictranscoder/update-pipeline-status.rst +0 -53
- awscli/examples/elastictranscoder/update-pipeline.rst +0 -95
- awscli/examples/opsworks/assign-instance.rst +0 -14
- awscli/examples/opsworks/assign-volume.rst +0 -17
- awscli/examples/opsworks/associate-elastic-ip.rst +0 -14
- awscli/examples/opsworks/attach-elastic-load-balancer.rst +0 -14
- awscli/examples/opsworks/create-app.rst +0 -64
- awscli/examples/opsworks/create-deployment.rst +0 -66
- awscli/examples/opsworks/create-instance.rst +0 -25
- awscli/examples/opsworks/create-layer.rst +0 -17
- awscli/examples/opsworks/create-server.rst +0 -43
- awscli/examples/opsworks/create-stack.rst +0 -25
- awscli/examples/opsworks/create-user-profile.rst +0 -24
- awscli/examples/opsworks/delete-app.rst +0 -17
- awscli/examples/opsworks/delete-instance.rst +0 -15
- awscli/examples/opsworks/delete-layer.rst +0 -17
- awscli/examples/opsworks/delete-stack.rst +0 -18
- awscli/examples/opsworks/delete-user-profile.rst +0 -17
- awscli/examples/opsworks/deregister-elastic-ip.rst +0 -13
- awscli/examples/opsworks/deregister-instance.rst +0 -14
- awscli/examples/opsworks/deregister-rds-db-instance.rst +0 -20
- awscli/examples/opsworks/deregister-volume.rst +0 -15
- awscli/examples/opsworks/describe-apps.rst +0 -38
- awscli/examples/opsworks/describe-commands.rst +0 -43
- awscli/examples/opsworks/describe-deployments.rst +0 -52
- awscli/examples/opsworks/describe-elastic-ips.rst +0 -24
- awscli/examples/opsworks/describe-elastic-load-balancers.rst +0 -37
- awscli/examples/opsworks/describe-instances.rst +0 -95
- awscli/examples/opsworks/describe-layers.rst +0 -171
- awscli/examples/opsworks/describe-load-based-auto-scaling.rst +0 -37
- awscli/examples/opsworks/describe-my-user-profile.rst +0 -24
- awscli/examples/opsworks/describe-permissions.rst +0 -26
- awscli/examples/opsworks/describe-raid-arrays.rst +0 -31
- awscli/examples/opsworks/describe-rds-db-instances.rst +0 -29
- awscli/examples/opsworks/describe-stack-provisioning-parameters.rst +0 -32
- awscli/examples/opsworks/describe-stack-summary.rst +0 -27
- awscli/examples/opsworks/describe-stacks.rst +0 -65
- awscli/examples/opsworks/describe-timebased-auto-scaling.rst +0 -39
- awscli/examples/opsworks/describe-user-profiles.rst +0 -32
- awscli/examples/opsworks/describe-volumes.rst +0 -31
- awscli/examples/opsworks/detach-elastic-load-balancer.rst +0 -14
- awscli/examples/opsworks/disassociate-elastic-ip.rst +0 -14
- awscli/examples/opsworks/get-hostname-suggestion.rst +0 -21
- awscli/examples/opsworks/reboot-instance.rst +0 -14
- awscli/examples/opsworks/register-elastic-ip.rst +0 -19
- awscli/examples/opsworks/register-rds-db-instance.rst +0 -15
- awscli/examples/opsworks/register-volume.rst +0 -18
- awscli/examples/opsworks/register.rst +0 -105
- awscli/examples/opsworks/set-load-based-auto-scaling.rst +0 -38
- awscli/examples/opsworks/set-permission.rst +0 -23
- awscli/examples/opsworks/set-time-based-auto-scaling.rst +0 -33
- awscli/examples/opsworks/start-instance.rst +0 -20
- awscli/examples/opsworks/start-stack.rst +0 -15
- awscli/examples/opsworks/stop-instance.rst +0 -20
- awscli/examples/opsworks/stop-stack.rst +0 -15
- awscli/examples/opsworks/unassign-instance.rst +0 -14
- awscli/examples/opsworks/unassign-volume.rst +0 -16
- awscli/examples/opsworks/update-app.rst +0 -14
- awscli/examples/opsworks/update-elastic-ip.rst +0 -14
- awscli/examples/opsworks/update-instance.rst +0 -14
- awscli/examples/opsworks/update-layer.rst +0 -14
- awscli/examples/opsworks/update-my-user-profile.rst +0 -16
- awscli/examples/opsworks/update-rds-db-instance.rst +0 -18
- awscli/examples/opsworks/update-volume.rst +0 -16
- awscli/examples/opsworkscm/associate-node.rst +0 -22
- awscli/examples/opsworkscm/create-backup.rst +0 -46
- awscli/examples/opsworkscm/create-server.rst +0 -48
- awscli/examples/opsworkscm/delete-backup.rst +0 -17
- awscli/examples/opsworkscm/delete-server.rst +0 -16
- awscli/examples/opsworkscm/describe-account-attributes.rst +0 -26
- awscli/examples/opsworkscm/describe-backups.rst +0 -44
- awscli/examples/opsworkscm/describe-events.rst +0 -21
- awscli/examples/opsworkscm/describe-node-association-status.rst +0 -20
- awscli/examples/opsworkscm/describe-servers.rst +0 -48
- awscli/examples/opsworkscm/disassociate-node.rst +0 -19
- awscli/examples/opsworkscm/restore-server.rst +0 -20
- awscli/examples/opsworkscm/start-maintenance.rst +0 -39
- awscli/examples/opsworkscm/update-server-engine-attributes.rst +0 -43
- awscli/examples/opsworkscm/update-server.rst +0 -42
- awscli/examples/qldb/cancel-journal-kinesis-stream.rst +0 -15
- awscli/examples/qldb/create-ledger.rst +0 -43
- awscli/examples/qldb/delete-ledger.rst +0 -10
- awscli/examples/qldb/describe-journal-kinesis-stream.rst +0 -29
- awscli/examples/qldb/describe-journal-s3-export.rst +0 -30
- awscli/examples/qldb/describe-ledger.rst +0 -23
- awscli/examples/qldb/export-journal-to-s3.rst +0 -28
- awscli/examples/qldb/get-block.rst +0 -55
- awscli/examples/qldb/get-digest.rst +0 -17
- awscli/examples/qldb/get-revision.rst +0 -57
- awscli/examples/qldb/list-journal-kinesis-streams-for-ledger.rst +0 -30
- awscli/examples/qldb/list-journal-s3-exports-for-ledger.rst +0 -31
- awscli/examples/qldb/list-journal-s3-exports.rst +0 -46
- awscli/examples/qldb/list-ledgers.rst +0 -24
- awscli/examples/qldb/list-tags-for-resource.rst +0 -17
- awscli/examples/qldb/stream-journal-to-kinesis.rst +0 -46
- awscli/examples/qldb/tag-resource.rst +0 -11
- awscli/examples/qldb/untag-resource.rst +0 -11
- awscli/examples/qldb/update-ledger-permissions-mode.rst +0 -34
- awscli/examples/qldb/update-ledger.rst +0 -63
- awscli/examples/robomaker/batch-describe-simulation-job.rst +0 -150
- awscli/examples/robomaker/cancel-simulation-job.rst +0 -6
- awscli/examples/robomaker/create-deployment-job.rst +0 -37
- awscli/examples/robomaker/create-fleet.rst +0 -18
- awscli/examples/robomaker/create-robot-application-version.rst +0 -31
- awscli/examples/robomaker/create-robot-application.rst +0 -29
- awscli/examples/robomaker/create-robot.rst +0 -20
- awscli/examples/robomaker/create-simulation-application-version.rst +0 -39
- awscli/examples/robomaker/create-simulation-application.rst +0 -38
- awscli/examples/robomaker/create-simulation-job.rst +0 -43
- awscli/examples/robomaker/delete-fleet.rst +0 -7
- awscli/examples/robomaker/delete-robot-application.rst +0 -7
- awscli/examples/robomaker/delete-robot.rst +0 -7
- awscli/examples/robomaker/delete-simulation-application.rst +0 -7
- awscli/examples/robomaker/deregister-robot.rst +0 -14
- awscli/examples/robomaker/describe-deployment-job.rst +0 -38
- awscli/examples/robomaker/describe-fleet.rst +0 -28
- awscli/examples/robomaker/describe-robot-application.rst +0 -29
- awscli/examples/robomaker/describe-robot.rst +0 -21
- awscli/examples/robomaker/describe-simulation-application.rst +0 -37
- awscli/examples/robomaker/describe-simulation-job.rst +0 -45
- awscli/examples/robomaker/list-deployment-jobs.rst +0 -57
- awscli/examples/robomaker/list-fleets.rst +0 -22
- awscli/examples/robomaker/list-robot-applications.rst +0 -32
- awscli/examples/robomaker/list-robots.rst +0 -45
- awscli/examples/robomaker/list-simulation-applications.rst +0 -50
- awscli/examples/robomaker/list-simulation-jobs.rst +0 -80
- awscli/examples/robomaker/list-tags-for-resource.rst +0 -16
- awscli/examples/robomaker/register-robot.rst +0 -14
- awscli/examples/robomaker/restart-simulation-job.rst +0 -7
- awscli/examples/robomaker/sync-deployment-job.rst +0 -30
- awscli/examples/robomaker/tag-resource.rst +0 -7
- awscli/examples/robomaker/untag-resource.rst +0 -7
- awscli/examples/robomaker/update-robot-application.rst +0 -28
- awscli/examples/robomaker/update-simulation-application.rst +0 -36
- {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws +0 -0
- {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws.cmd +0 -0
- {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws_bash_completer +0 -0
- {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws_completer +0 -0
- {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws_zsh_completer.sh +0 -0
- {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/LICENSE.txt +0 -0
- {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/WHEEL +0 -0
- {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/top_level.txt +0 -0
|
@@ -33,7 +33,7 @@ from botocore.exceptions import DataNotFoundError, PaginationError
|
|
|
33
33
|
from botocore import model
|
|
34
34
|
|
|
35
35
|
from awscli.arguments import BaseCLIArgument
|
|
36
|
-
|
|
36
|
+
from awscli.utils import resolve_v2_debug_mode
|
|
37
37
|
|
|
38
38
|
logger = logging.getLogger(__name__)
|
|
39
39
|
|
|
@@ -135,6 +135,9 @@ def unify_paging_params(argument_table, operation_model, event_name,
|
|
|
135
135
|
_remove_existing_paging_arguments(argument_table, paginator_config)
|
|
136
136
|
parsed_args_event = event_name.replace('building-argument-table.',
|
|
137
137
|
'operation-args-parsed.')
|
|
138
|
+
call_parameters_event = event_name.replace(
|
|
139
|
+
'building-argument-table', 'calling-command'
|
|
140
|
+
)
|
|
138
141
|
shadowed_args = {}
|
|
139
142
|
add_paging_argument(argument_table, 'starting-token',
|
|
140
143
|
PageArgument('starting-token', STARTING_TOKEN_HELP,
|
|
@@ -168,6 +171,14 @@ def unify_paging_params(argument_table, operation_model, event_name,
|
|
|
168
171
|
partial(check_should_enable_pagination,
|
|
169
172
|
list(_get_all_cli_input_tokens(paginator_config)),
|
|
170
173
|
shadowed_args, argument_table))
|
|
174
|
+
session.register(
|
|
175
|
+
call_parameters_event,
|
|
176
|
+
partial(
|
|
177
|
+
check_should_enable_pagination_call_parameters,
|
|
178
|
+
session,
|
|
179
|
+
list(_get_all_input_tokens(paginator_config)),
|
|
180
|
+
),
|
|
181
|
+
)
|
|
171
182
|
|
|
172
183
|
|
|
173
184
|
def add_paging_argument(argument_table, arg_name, argument, shadowed_args):
|
|
@@ -240,6 +251,18 @@ def _get_all_cli_input_tokens(pagination_config):
|
|
|
240
251
|
yield cli_name
|
|
241
252
|
|
|
242
253
|
|
|
254
|
+
# Get all tokens but return them in API namespace rather than CLI namespace
|
|
255
|
+
def _get_all_input_tokens(pagination_config):
|
|
256
|
+
# Get all input tokens including the limit_key
|
|
257
|
+
# if it exists.
|
|
258
|
+
tokens = _get_input_tokens(pagination_config)
|
|
259
|
+
for token_name in tokens:
|
|
260
|
+
yield token_name
|
|
261
|
+
if 'limit_key' in pagination_config:
|
|
262
|
+
key_name = pagination_config['limit_key']
|
|
263
|
+
yield key_name
|
|
264
|
+
|
|
265
|
+
|
|
243
266
|
def _get_input_tokens(pagination_config):
|
|
244
267
|
tokens = pagination_config['input_token']
|
|
245
268
|
if not isinstance(tokens, list):
|
|
@@ -253,6 +276,48 @@ def _get_cli_name(param_objects, token_name):
|
|
|
253
276
|
return param.cli_name.lstrip('-')
|
|
254
277
|
|
|
255
278
|
|
|
279
|
+
def check_should_enable_pagination_call_parameters(
|
|
280
|
+
session,
|
|
281
|
+
input_tokens,
|
|
282
|
+
call_parameters,
|
|
283
|
+
parsed_args,
|
|
284
|
+
parsed_globals,
|
|
285
|
+
**kwargs
|
|
286
|
+
):
|
|
287
|
+
"""
|
|
288
|
+
Check for pagination args in the actual calling arguments passed to
|
|
289
|
+
the function.
|
|
290
|
+
|
|
291
|
+
If the user is using the --cli-input-json parameter to provide JSON
|
|
292
|
+
parameters they are all in the API naming space rather than the CLI
|
|
293
|
+
naming space and would be missed by the processing above. This function
|
|
294
|
+
gets called on the calling-command event.
|
|
295
|
+
"""
|
|
296
|
+
if resolve_v2_debug_mode(parsed_globals):
|
|
297
|
+
cli_input_json_data = session.emit_first_non_none_response(
|
|
298
|
+
f"get-cli-input-json-data",
|
|
299
|
+
)
|
|
300
|
+
if cli_input_json_data is None:
|
|
301
|
+
cli_input_json_data = {}
|
|
302
|
+
pagination_params_in_input_tokens = [
|
|
303
|
+
param for param in cli_input_json_data if param in input_tokens
|
|
304
|
+
]
|
|
305
|
+
if pagination_params_in_input_tokens:
|
|
306
|
+
uni_print(
|
|
307
|
+
'\nAWS CLI v2 UPGRADE WARNING: In AWS CLI v2, if you specify '
|
|
308
|
+
'pagination parameters by using a file with the '
|
|
309
|
+
'`--cli-input-json` parameter, automatic pagination will be '
|
|
310
|
+
'turned off. This is different from v1 behavior, where '
|
|
311
|
+
'pagination parameters specified via the `--cli-input-json` '
|
|
312
|
+
'parameter are ignored. To retain AWS CLI v1 behavior in '
|
|
313
|
+
'AWS CLI v2, remove all pagination parameters from the input '
|
|
314
|
+
'JSON. See https://docs.aws.amazon.com/cli/latest/userguide/'
|
|
315
|
+
'cliv2-migration-changes.html'
|
|
316
|
+
'#cliv2-migration-skeleton-paging.\n',
|
|
317
|
+
out_file=sys.stderr
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
|
|
256
321
|
class PageArgument(BaseCLIArgument):
|
|
257
322
|
type_map = {
|
|
258
323
|
'string': str,
|
awscli/customizations/rds.py
CHANGED
|
@@ -29,6 +29,7 @@ from awscli.clidriver import CLIOperationCaller
|
|
|
29
29
|
from awscli.customizations import utils
|
|
30
30
|
from awscli.customizations.commands import BasicCommand
|
|
31
31
|
from awscli.customizations.utils import uni_print
|
|
32
|
+
from awscli.utils import create_nested_client
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
def register_rds_modify_split(cli):
|
|
@@ -95,7 +96,8 @@ class GenerateDBAuthTokenCommand(BasicCommand):
|
|
|
95
96
|
]
|
|
96
97
|
|
|
97
98
|
def _run_main(self, parsed_args, parsed_globals):
|
|
98
|
-
rds =
|
|
99
|
+
rds = create_nested_client(
|
|
100
|
+
self._session,
|
|
99
101
|
'rds',
|
|
100
102
|
region_name=parsed_globals.region,
|
|
101
103
|
endpoint_url=parsed_globals.endpoint_url,
|
|
@@ -60,10 +60,14 @@ def register_removals(event_handler):
|
|
|
60
60
|
'invoke-inline-agent',
|
|
61
61
|
'optimize-prompt',
|
|
62
62
|
'retrieve-and-generate-stream'])
|
|
63
|
+
cmd_remover.remove(on_event='building-command-table.bedrock-agentcore',
|
|
64
|
+
remove_commands=['invoke-code-interpreter'])
|
|
63
65
|
cmd_remover.remove(on_event='building-command-table.qbusiness',
|
|
64
66
|
remove_commands=['chat'])
|
|
65
67
|
cmd_remover.remove(on_event='building-command-table.iotsitewise',
|
|
66
68
|
remove_commands=['invoke-assistant'])
|
|
69
|
+
cmd_remover.remove(on_event='building-command-table.logs',
|
|
70
|
+
remove_commands=['get-log-object'])
|
|
67
71
|
|
|
68
72
|
|
|
69
73
|
class CommandRemover(object):
|
|
@@ -94,7 +94,8 @@ class FileDecodingError(Exception):
|
|
|
94
94
|
class FileStat(object):
|
|
95
95
|
def __init__(self, src, dest=None, compare_key=None, size=None,
|
|
96
96
|
last_update=None, src_type=None, dest_type=None,
|
|
97
|
-
operation_name=None, response_data=None
|
|
97
|
+
operation_name=None, response_data=None, etag=None,
|
|
98
|
+
case_conflict_submitted=None, case_conflict_key=None,):
|
|
98
99
|
self.src = src
|
|
99
100
|
self.dest = dest
|
|
100
101
|
self.compare_key = compare_key
|
|
@@ -104,6 +105,9 @@ class FileStat(object):
|
|
|
104
105
|
self.dest_type = dest_type
|
|
105
106
|
self.operation_name = operation_name
|
|
106
107
|
self.response_data = response_data
|
|
108
|
+
self.etag = etag
|
|
109
|
+
self.case_conflict_submitted = case_conflict_submitted
|
|
110
|
+
self.case_conflict_key = case_conflict_key
|
|
107
111
|
|
|
108
112
|
|
|
109
113
|
class FileGenerator(object):
|
|
@@ -152,6 +156,7 @@ class FileGenerator(object):
|
|
|
152
156
|
src_type = file_stat_kwargs['src_type']
|
|
153
157
|
file_stat_kwargs['size'] = extra_information['Size']
|
|
154
158
|
file_stat_kwargs['last_update'] = extra_information['LastModified']
|
|
159
|
+
file_stat_kwargs['etag'] = extra_information.get('ETag')
|
|
155
160
|
|
|
156
161
|
# S3 objects require the response data retrieved from HeadObject
|
|
157
162
|
# and ListObject
|
|
@@ -366,4 +371,5 @@ class FileGenerator(object):
|
|
|
366
371
|
response['Size'] = int(response.pop('ContentLength'))
|
|
367
372
|
last_update = parse(response['LastModified'])
|
|
368
373
|
response['LastModified'] = last_update.astimezone(tzlocal())
|
|
374
|
+
response['ETag'] = response.pop('ETag', None)
|
|
369
375
|
return s3_path, response
|
|
@@ -42,7 +42,8 @@ class FileInfo(object):
|
|
|
42
42
|
last_update=None, src_type=None, dest_type=None,
|
|
43
43
|
operation_name=None, client=None, parameters=None,
|
|
44
44
|
source_client=None, is_stream=False,
|
|
45
|
-
associated_response_data=None
|
|
45
|
+
associated_response_data=None, etag=None,
|
|
46
|
+
case_conflict_submitted=None, case_conflict_key=None,):
|
|
46
47
|
self.src = src
|
|
47
48
|
self.src_type = src_type
|
|
48
49
|
self.operation_name = operation_name
|
|
@@ -59,6 +60,9 @@ class FileInfo(object):
|
|
|
59
60
|
self.source_client = source_client
|
|
60
61
|
self.is_stream = is_stream
|
|
61
62
|
self.associated_response_data = associated_response_data
|
|
63
|
+
self.etag = etag
|
|
64
|
+
self.case_conflict_submitted = case_conflict_submitted
|
|
65
|
+
self.case_conflict_key = case_conflict_key
|
|
62
66
|
|
|
63
67
|
def is_glacier_compatible(self):
|
|
64
68
|
"""Determines if a file info object is glacier compatible
|
|
@@ -45,6 +45,13 @@ class FileInfoBuilder(object):
|
|
|
45
45
|
file_info_attr['parameters'] = self._parameters
|
|
46
46
|
file_info_attr['is_stream'] = self._is_stream
|
|
47
47
|
file_info_attr['associated_response_data'] = file_base.response_data
|
|
48
|
+
file_info_attr['etag'] = file_base.etag
|
|
49
|
+
file_info_attr['case_conflict_submitted'] = getattr(
|
|
50
|
+
file_base, 'case_conflict_submitted', None
|
|
51
|
+
)
|
|
52
|
+
file_info_attr['case_conflict_key'] = getattr(
|
|
53
|
+
file_base, 'case_conflict_key', None
|
|
54
|
+
)
|
|
48
55
|
|
|
49
56
|
# This is a bit quirky. The below conditional hinges on the --delete
|
|
50
57
|
# flag being set, which only occurs during a sync command. The source
|
|
@@ -39,6 +39,7 @@ from awscli.customizations.s3.results import CommandResultRecorder
|
|
|
39
39
|
from awscli.customizations.s3.utils import RequestParamsMapper
|
|
40
40
|
from awscli.customizations.s3.utils import StdoutBytesWriter
|
|
41
41
|
from awscli.customizations.s3.utils import ProvideSizeSubscriber
|
|
42
|
+
from awscli.customizations.s3.utils import ProvideETagSubscriber
|
|
42
43
|
from awscli.customizations.s3.utils import ProvideUploadContentTypeSubscriber
|
|
43
44
|
from awscli.customizations.s3.utils import ProvideCopyContentTypeSubscriber
|
|
44
45
|
from awscli.customizations.s3.utils import ProvideLastModifiedTimeSubscriber
|
|
@@ -46,6 +47,7 @@ from awscli.customizations.s3.utils import DirectoryCreatorSubscriber
|
|
|
46
47
|
from awscli.customizations.s3.utils import DeleteSourceFileSubscriber
|
|
47
48
|
from awscli.customizations.s3.utils import DeleteSourceObjectSubscriber
|
|
48
49
|
from awscli.customizations.s3.utils import DeleteCopySourceObjectSubscriber
|
|
50
|
+
from awscli.customizations.s3.utils import CaseConflictCleanupSubscriber
|
|
49
51
|
from awscli.compat import get_binary_stdin
|
|
50
52
|
|
|
51
53
|
|
|
@@ -395,12 +397,20 @@ class DownloadRequestSubmitter(BaseTransferRequestSubmitter):
|
|
|
395
397
|
|
|
396
398
|
def _add_additional_subscribers(self, subscribers, fileinfo):
|
|
397
399
|
subscribers.append(ProvideSizeSubscriber(fileinfo.size))
|
|
400
|
+
subscribers.append(ProvideETagSubscriber(fileinfo.etag))
|
|
398
401
|
subscribers.append(DirectoryCreatorSubscriber())
|
|
399
402
|
subscribers.append(ProvideLastModifiedTimeSubscriber(
|
|
400
403
|
fileinfo.last_update, self._result_queue))
|
|
401
404
|
if self._cli_params.get('is_move', False):
|
|
402
405
|
subscribers.append(DeleteSourceObjectSubscriber(
|
|
403
406
|
fileinfo.source_client))
|
|
407
|
+
if fileinfo.case_conflict_submitted is not None:
|
|
408
|
+
subscribers.append(
|
|
409
|
+
CaseConflictCleanupSubscriber(
|
|
410
|
+
fileinfo.case_conflict_submitted,
|
|
411
|
+
fileinfo.case_conflict_key,
|
|
412
|
+
)
|
|
413
|
+
)
|
|
404
414
|
|
|
405
415
|
def _submit_transfer_request(self, fileinfo, extra_args, subscribers):
|
|
406
416
|
bucket, key = find_bucket_key(fileinfo.src)
|
|
@@ -431,6 +441,7 @@ class CopyRequestSubmitter(BaseTransferRequestSubmitter):
|
|
|
431
441
|
|
|
432
442
|
def _add_additional_subscribers(self, subscribers, fileinfo):
|
|
433
443
|
subscribers.append(ProvideSizeSubscriber(fileinfo.size))
|
|
444
|
+
subscribers.append(ProvideETagSubscriber(fileinfo.etag))
|
|
434
445
|
if self._should_inject_content_type():
|
|
435
446
|
subscribers.append(ProvideCopyContentTypeSubscriber())
|
|
436
447
|
if self._cli_params.get('is_move', False):
|
|
@@ -34,9 +34,10 @@ from awscli.customizations.s3.utils import find_bucket_key, AppendFilter, \
|
|
|
34
34
|
S3PathResolver
|
|
35
35
|
from awscli.customizations.utils import uni_print
|
|
36
36
|
from awscli.customizations.s3.syncstrategy.base import MissingFileSync, \
|
|
37
|
-
SizeAndLastModifiedSync, NeverSync
|
|
37
|
+
SizeAndLastModifiedSync, NeverSync, AlwaysSync
|
|
38
|
+
from awscli.customizations.s3.syncstrategy.caseconflict import CaseConflictSync
|
|
38
39
|
from awscli.customizations.s3 import transferconfig
|
|
39
|
-
|
|
40
|
+
from awscli.utils import resolve_v2_debug_mode
|
|
40
41
|
|
|
41
42
|
LOGGER = logging.getLogger(__name__)
|
|
42
43
|
|
|
@@ -482,6 +483,33 @@ BUCKET_REGION = {
|
|
|
482
483
|
)
|
|
483
484
|
}
|
|
484
485
|
|
|
486
|
+
CASE_CONFLICT = {
|
|
487
|
+
'name': 'case-conflict',
|
|
488
|
+
'choices': [
|
|
489
|
+
'ignore',
|
|
490
|
+
'skip',
|
|
491
|
+
'warn',
|
|
492
|
+
'error',
|
|
493
|
+
],
|
|
494
|
+
'default': 'ignore',
|
|
495
|
+
'help_text': (
|
|
496
|
+
"Configures behavior when attempting to download multiple objects "
|
|
497
|
+
"whose keys differ only by case, which can cause undefined behavior "
|
|
498
|
+
"on case-insensitive filesystems. "
|
|
499
|
+
"This parameter only applies for commands that perform multiple S3 "
|
|
500
|
+
"to local downloads. "
|
|
501
|
+
f"See <a href='{CaseConflictSync.DOC_URI}'>Handling case "
|
|
502
|
+
"conflicts</a> for details. Valid values are: "
|
|
503
|
+
"<ul>"
|
|
504
|
+
"<li>``error`` - Raise an error and abort downloads.</li>"
|
|
505
|
+
"<li>``warn`` - Emit a warning and download the object.</li>"
|
|
506
|
+
"<li>``skip`` - Skip downloading the object.</li>"
|
|
507
|
+
"<li>``ignore`` - The default value. Ignore the conflict and "
|
|
508
|
+
"download the object.</li>"
|
|
509
|
+
"</ul>"
|
|
510
|
+
),
|
|
511
|
+
}
|
|
512
|
+
|
|
485
513
|
TRANSFER_ARGS = [DRYRUN, QUIET, INCLUDE, EXCLUDE, ACL,
|
|
486
514
|
FOLLOW_SYMLINKS, NO_FOLLOW_SYMLINKS, NO_GUESS_MIME_TYPE,
|
|
487
515
|
SSE, SSE_C, SSE_C_KEY, SSE_KMS_KEY_ID, SSE_C_COPY_SOURCE,
|
|
@@ -767,6 +795,7 @@ class S3TransferCommand(S3Command):
|
|
|
767
795
|
cmd_params.add_verify_ssl(parsed_globals)
|
|
768
796
|
cmd_params.add_page_size(parsed_args)
|
|
769
797
|
cmd_params.add_paths(parsed_args.paths)
|
|
798
|
+
cmd_params.add_v2_debug(parsed_globals)
|
|
770
799
|
|
|
771
800
|
runtime_config = transferconfig.RuntimeConfig().build_config(
|
|
772
801
|
**self._session.get_scoped_config().get('s3', {}))
|
|
@@ -806,7 +835,8 @@ class CpCommand(S3TransferCommand):
|
|
|
806
835
|
"or <S3Uri> <S3Uri>"
|
|
807
836
|
ARG_TABLE = [{'name': 'paths', 'nargs': 2, 'positional_arg': True,
|
|
808
837
|
'synopsis': USAGE}] + TRANSFER_ARGS + \
|
|
809
|
-
[METADATA, METADATA_DIRECTIVE, EXPECTED_SIZE, RECURSIVE
|
|
838
|
+
[METADATA, METADATA_DIRECTIVE, EXPECTED_SIZE, RECURSIVE,
|
|
839
|
+
CASE_CONFLICT]
|
|
810
840
|
|
|
811
841
|
|
|
812
842
|
class MvCommand(S3TransferCommand):
|
|
@@ -816,7 +846,8 @@ class MvCommand(S3TransferCommand):
|
|
|
816
846
|
"or <S3Uri> <S3Uri>"
|
|
817
847
|
ARG_TABLE = [{'name': 'paths', 'nargs': 2, 'positional_arg': True,
|
|
818
848
|
'synopsis': USAGE}] + TRANSFER_ARGS +\
|
|
819
|
-
[METADATA, METADATA_DIRECTIVE, RECURSIVE, VALIDATE_SAME_S3_PATHS
|
|
849
|
+
[METADATA, METADATA_DIRECTIVE, RECURSIVE, VALIDATE_SAME_S3_PATHS,
|
|
850
|
+
CASE_CONFLICT]
|
|
820
851
|
|
|
821
852
|
|
|
822
853
|
class RmCommand(S3TransferCommand):
|
|
@@ -838,7 +869,7 @@ class SyncCommand(S3TransferCommand):
|
|
|
838
869
|
"<LocalPath> or <S3Uri> <S3Uri>"
|
|
839
870
|
ARG_TABLE = [{'name': 'paths', 'nargs': 2, 'positional_arg': True,
|
|
840
871
|
'synopsis': USAGE}] + TRANSFER_ARGS + \
|
|
841
|
-
[METADATA, METADATA_DIRECTIVE]
|
|
872
|
+
[METADATA, METADATA_DIRECTIVE, CASE_CONFLICT]
|
|
842
873
|
|
|
843
874
|
|
|
844
875
|
class MbCommand(S3Command):
|
|
@@ -1003,7 +1034,16 @@ class CommandArchitecture(object):
|
|
|
1003
1034
|
# Set the default strategies.
|
|
1004
1035
|
sync_strategies['file_at_src_and_dest_sync_strategy'] = \
|
|
1005
1036
|
SizeAndLastModifiedSync()
|
|
1006
|
-
|
|
1037
|
+
if self._should_handle_case_conflicts():
|
|
1038
|
+
sync_strategies['file_not_at_dest_sync_strategy'] = (
|
|
1039
|
+
CaseConflictSync(
|
|
1040
|
+
on_case_conflict=self.parameters['case_conflict']
|
|
1041
|
+
)
|
|
1042
|
+
)
|
|
1043
|
+
else:
|
|
1044
|
+
sync_strategies['file_not_at_dest_sync_strategy'] = (
|
|
1045
|
+
MissingFileSync()
|
|
1046
|
+
)
|
|
1007
1047
|
sync_strategies['file_not_at_src_sync_strategy'] = NeverSync()
|
|
1008
1048
|
|
|
1009
1049
|
# Determine what strategies to override if any.
|
|
@@ -1056,6 +1096,24 @@ class CommandArchitecture(object):
|
|
|
1056
1096
|
result_queue = queue.Queue()
|
|
1057
1097
|
operation_name = cmd_translation[paths_type]
|
|
1058
1098
|
|
|
1099
|
+
if self.parameters['v2_debug']:
|
|
1100
|
+
if operation_name == 'copy':
|
|
1101
|
+
uni_print(
|
|
1102
|
+
'\nAWS CLI v2 UPGRADE WARNING: In AWS CLI v2, object '
|
|
1103
|
+
'properties will be copied from the source in multipart '
|
|
1104
|
+
'copies between S3 buckets initiated via `aws s3` '
|
|
1105
|
+
'commands, resulting in additional S3 API calls to '
|
|
1106
|
+
'transfer the metadata. Note that the principal must '
|
|
1107
|
+
'have permission to call these APIs, or the command may '
|
|
1108
|
+
'fail. This is different from v1 behavior, where metadata '
|
|
1109
|
+
'is not copied. For guidance on retaining v1 behavior in '
|
|
1110
|
+
'AWS CLI v2, or for more details, see '
|
|
1111
|
+
'https://docs.aws.amazon.com/cli/latest/userguide/'
|
|
1112
|
+
'cliv2-migration-changes.html'
|
|
1113
|
+
'#cliv2-migration-s3-copy-metadata.\n\n',
|
|
1114
|
+
out_file=sys.stderr
|
|
1115
|
+
)
|
|
1116
|
+
|
|
1059
1117
|
fgen_kwargs = {
|
|
1060
1118
|
'client': self._source_client, 'operation_name': operation_name,
|
|
1061
1119
|
'follow_symlinks': self.parameters['follow_symlinks'],
|
|
@@ -1119,6 +1177,12 @@ class CommandArchitecture(object):
|
|
|
1119
1177
|
'filters': [create_filter(self.parameters)],
|
|
1120
1178
|
'file_info_builder': [file_info_builder],
|
|
1121
1179
|
's3_handler': [s3_transfer_handler]}
|
|
1180
|
+
if self._should_handle_case_conflicts():
|
|
1181
|
+
self._handle_case_conflicts(
|
|
1182
|
+
command_dict,
|
|
1183
|
+
rev_files,
|
|
1184
|
+
rev_generator,
|
|
1185
|
+
)
|
|
1122
1186
|
elif self.cmd == 'rm':
|
|
1123
1187
|
command_dict = {'setup': [files],
|
|
1124
1188
|
'file_generator': [file_generator],
|
|
@@ -1131,6 +1195,12 @@ class CommandArchitecture(object):
|
|
|
1131
1195
|
'filters': [create_filter(self.parameters)],
|
|
1132
1196
|
'file_info_builder': [file_info_builder],
|
|
1133
1197
|
's3_handler': [s3_transfer_handler]}
|
|
1198
|
+
if self._should_handle_case_conflicts():
|
|
1199
|
+
self._handle_case_conflicts(
|
|
1200
|
+
command_dict,
|
|
1201
|
+
rev_files,
|
|
1202
|
+
rev_generator,
|
|
1203
|
+
)
|
|
1134
1204
|
|
|
1135
1205
|
files = command_dict['setup']
|
|
1136
1206
|
while self.instructions:
|
|
@@ -1196,6 +1266,74 @@ class CommandArchitecture(object):
|
|
|
1196
1266
|
}
|
|
1197
1267
|
)
|
|
1198
1268
|
|
|
1269
|
+
def _should_handle_case_conflicts(self):
|
|
1270
|
+
return (
|
|
1271
|
+
self.cmd in {'sync', 'cp', 'mv'}
|
|
1272
|
+
and self.parameters.get('paths_type') == 's3local'
|
|
1273
|
+
and self.parameters['case_conflict'] != 'ignore'
|
|
1274
|
+
and self.parameters.get('dir_op')
|
|
1275
|
+
)
|
|
1276
|
+
|
|
1277
|
+
def _handle_case_conflicts(self, command_dict, rev_files, rev_generator):
|
|
1278
|
+
# Objects are not returned in lexicographical order when
|
|
1279
|
+
# operated on S3 Express directory buckets. This is required
|
|
1280
|
+
# for sync operations to behave correctly, which is what
|
|
1281
|
+
# recursive copies and moves fall back to so potential case
|
|
1282
|
+
# conflicts can be detected and handled.
|
|
1283
|
+
if not is_s3express_bucket(
|
|
1284
|
+
split_s3_bucket_key(self.parameters['src'])[0]
|
|
1285
|
+
):
|
|
1286
|
+
self._modify_instructions_for_case_conflicts(
|
|
1287
|
+
command_dict, rev_files, rev_generator
|
|
1288
|
+
)
|
|
1289
|
+
return
|
|
1290
|
+
# `skip` and `error` are not valid choices in this case because
|
|
1291
|
+
# it's not possible to detect case conflicts.
|
|
1292
|
+
if self.parameters['case_conflict'] not in {'ignore', 'warn'}:
|
|
1293
|
+
raise ValueError(
|
|
1294
|
+
f"`{self.parameters['case_conflict']}` is not a valid value "
|
|
1295
|
+
"for `--case-conflict` when operating on S3 Express "
|
|
1296
|
+
"directory buckets. Valid values: `warn`, `ignore`."
|
|
1297
|
+
)
|
|
1298
|
+
msg = (
|
|
1299
|
+
"warning: Recursive copies/moves from an S3 Express "
|
|
1300
|
+
"directory bucket to a case-insensitive local filesystem "
|
|
1301
|
+
"may result in undefined behavior if there are "
|
|
1302
|
+
"S3 object key names that differ only by case. To disable "
|
|
1303
|
+
"this warning, set the `--case-conflict` parameter to `ignore`. "
|
|
1304
|
+
f"For more information, see {CaseConflictSync.DOC_URI}."
|
|
1305
|
+
)
|
|
1306
|
+
uni_print(msg, sys.stderr)
|
|
1307
|
+
|
|
1308
|
+
def _modify_instructions_for_case_conflicts(
|
|
1309
|
+
self, command_dict, rev_files, rev_generator
|
|
1310
|
+
):
|
|
1311
|
+
# Command will perform recursive S3 to local downloads.
|
|
1312
|
+
# Checking for potential case conflicts requires knowledge
|
|
1313
|
+
# of local files. Instead of writing a separate validation
|
|
1314
|
+
# mechanism for recursive downloads, we modify the instructions
|
|
1315
|
+
# to mimic a sync command.
|
|
1316
|
+
sync_strategies = {
|
|
1317
|
+
# Local filename exists with exact case match. Always sync
|
|
1318
|
+
# because it's a copy operation.
|
|
1319
|
+
'file_at_src_and_dest_sync_strategy': AlwaysSync(),
|
|
1320
|
+
# Local filename either doesn't exist or differs only by case.
|
|
1321
|
+
# Let `CaseConflictSync` determine which it is and handle it
|
|
1322
|
+
# according to configured `--case-conflict` parameter.
|
|
1323
|
+
'file_not_at_dest_sync_strategy': CaseConflictSync(
|
|
1324
|
+
on_case_conflict=self.parameters['case_conflict']
|
|
1325
|
+
),
|
|
1326
|
+
# Copy is one-way so never sync if not at source.
|
|
1327
|
+
'file_not_at_src_sync_strategy': NeverSync(),
|
|
1328
|
+
}
|
|
1329
|
+
command_dict['setup'].append(rev_files)
|
|
1330
|
+
command_dict['file_generator'].append(rev_generator)
|
|
1331
|
+
command_dict['filters'].append(create_filter(self.parameters))
|
|
1332
|
+
command_dict['comparator'] = [Comparator(**sync_strategies)]
|
|
1333
|
+
self.instructions.insert(
|
|
1334
|
+
self.instructions.index('file_info_builder'), 'comparator'
|
|
1335
|
+
)
|
|
1336
|
+
|
|
1199
1337
|
|
|
1200
1338
|
class CommandParameters(object):
|
|
1201
1339
|
"""
|
|
@@ -1447,6 +1585,9 @@ class CommandParameters(object):
|
|
|
1447
1585
|
def add_page_size(self, parsed_args):
|
|
1448
1586
|
self.parameters['page_size'] = getattr(parsed_args, 'page_size', None)
|
|
1449
1587
|
|
|
1588
|
+
def add_v2_debug(self, parsed_globals):
|
|
1589
|
+
self.parameters['v2_debug'] = resolve_v2_debug_mode(parsed_globals)
|
|
1590
|
+
|
|
1450
1591
|
def _validate_sse_c_args(self):
|
|
1451
1592
|
self._validate_sse_c_arg()
|
|
1452
1593
|
self._validate_sse_c_arg('sse_c_copy_source')
|
|
@@ -254,3 +254,12 @@ class MissingFileSync(BaseSync):
|
|
|
254
254
|
LOG.debug("syncing: %s -> %s, file does not exist at destination",
|
|
255
255
|
src_file.src, src_file.dest)
|
|
256
256
|
return True
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class AlwaysSync(BaseSync):
|
|
260
|
+
def __init__(self, sync_type='file_at_src_and_dest'):
|
|
261
|
+
super(AlwaysSync, self).__init__(sync_type)
|
|
262
|
+
|
|
263
|
+
def determine_should_sync(self, src_file, dest_file):
|
|
264
|
+
LOG.debug(f"syncing: {src_file.src} -> {src_file.dest}")
|
|
265
|
+
return True
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from awscli.customizations.s3.syncstrategy.base import BaseSync
|
|
8
|
+
from awscli.customizations.utils import uni_print
|
|
9
|
+
|
|
10
|
+
LOG = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CaseConflictException(Exception):
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CaseConflictSync(BaseSync):
|
|
18
|
+
DOC_URI = (
|
|
19
|
+
"https://docs.aws.amazon.com/cli/v1/topic/"
|
|
20
|
+
"s3-case-insensitivity.html"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
sync_type='file_not_at_dest',
|
|
26
|
+
on_case_conflict='ignore',
|
|
27
|
+
submitted=None,
|
|
28
|
+
):
|
|
29
|
+
super().__init__(sync_type)
|
|
30
|
+
self._on_case_conflict = on_case_conflict
|
|
31
|
+
if submitted is None:
|
|
32
|
+
submitted = set()
|
|
33
|
+
self._submitted = submitted
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def submitted(self):
|
|
37
|
+
return self._submitted
|
|
38
|
+
|
|
39
|
+
def determine_should_sync(self, src_file, dest_file):
|
|
40
|
+
# `src_file.compare_key` and `dest_file.compare_key` are not equal.
|
|
41
|
+
# This could mean that they're completely different or differ
|
|
42
|
+
# only by case. eg, `/tmp/a` and `/tmp/b` versus `/tmp/a` and `/tmp/A`.
|
|
43
|
+
# If the source file's destination already exists, that means it
|
|
44
|
+
# differs only by case and the conflict needs to be handled.
|
|
45
|
+
should_sync = True
|
|
46
|
+
# Normalize compare key for case sensitivity.
|
|
47
|
+
lower_compare_key = src_file.compare_key.lower()
|
|
48
|
+
if lower_compare_key in self._submitted or os.path.exists(
|
|
49
|
+
src_file.dest
|
|
50
|
+
):
|
|
51
|
+
handler = getattr(self, f"_handle_{self._on_case_conflict}")
|
|
52
|
+
should_sync = handler(src_file)
|
|
53
|
+
if should_sync:
|
|
54
|
+
LOG.debug(f"syncing: {src_file.src} -> {src_file.dest}")
|
|
55
|
+
self._submitted.add(lower_compare_key)
|
|
56
|
+
# Set properties so that a subscriber can be created
|
|
57
|
+
# that removes the key from the set after download finishes.
|
|
58
|
+
src_file.case_conflict_submitted = self._submitted
|
|
59
|
+
src_file.case_conflict_key = lower_compare_key
|
|
60
|
+
return should_sync
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def _handle_ignore(src_file):
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
@staticmethod
|
|
67
|
+
def _handle_skip(src_file):
|
|
68
|
+
msg = (
|
|
69
|
+
f"warning: Skipping {src_file.src} -> {src_file.dest} "
|
|
70
|
+
"because a file whose name differs only by case either exists "
|
|
71
|
+
"or is being downloaded.\n"
|
|
72
|
+
)
|
|
73
|
+
uni_print(msg, sys.stderr)
|
|
74
|
+
return False
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def _handle_warn(src_file):
|
|
78
|
+
msg = (
|
|
79
|
+
f"warning: Downloading {src_file.src} -> {src_file.dest} "
|
|
80
|
+
"despite a file whose name differs only by case either existing "
|
|
81
|
+
"or being downloaded. This behavior is not defined on "
|
|
82
|
+
"case-insensitive filesystems and may result in overwriting "
|
|
83
|
+
"existing files or race conditions between concurrent downloads. "
|
|
84
|
+
f"For more information, see {CaseConflictSync.DOC_URI}.\n"
|
|
85
|
+
)
|
|
86
|
+
uni_print(msg, sys.stderr)
|
|
87
|
+
return True
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def _handle_error(src_file):
|
|
91
|
+
msg = (
|
|
92
|
+
f"Failed to download {src_file.src} -> {src_file.dest} "
|
|
93
|
+
"because a file whose name differs only by case either exists "
|
|
94
|
+
"or is being downloaded."
|
|
95
|
+
)
|
|
96
|
+
raise CaseConflictException(msg)
|
|
@@ -649,6 +649,17 @@ class ProvideSizeSubscriber(BaseSubscriber):
|
|
|
649
649
|
future.meta.provide_transfer_size(self.size)
|
|
650
650
|
|
|
651
651
|
|
|
652
|
+
class ProvideETagSubscriber(BaseSubscriber):
|
|
653
|
+
"""
|
|
654
|
+
A subscriber which provides the object ETag before it's queued.
|
|
655
|
+
"""
|
|
656
|
+
def __init__(self, etag):
|
|
657
|
+
self.etag = etag
|
|
658
|
+
|
|
659
|
+
def on_queued(self, future, **kwargs):
|
|
660
|
+
future.meta.provide_object_etag(self.etag)
|
|
661
|
+
|
|
662
|
+
|
|
652
663
|
# TODO: Eventually port this down to the BaseSubscriber or a new subscriber
|
|
653
664
|
# class in s3transfer. The functionality is very convenient but may need
|
|
654
665
|
# some further design decisions to make it a feature in s3transfer.
|
|
@@ -679,6 +690,20 @@ class OnDoneFilteredSubscriber(BaseSubscriber):
|
|
|
679
690
|
pass
|
|
680
691
|
|
|
681
692
|
|
|
693
|
+
class CaseConflictCleanupSubscriber(BaseSubscriber):
|
|
694
|
+
"""
|
|
695
|
+
A subscriber which removes object compare key from case conflict set
|
|
696
|
+
when download finishes.
|
|
697
|
+
"""
|
|
698
|
+
|
|
699
|
+
def __init__(self, submitted, case_conflict_key):
|
|
700
|
+
self._submitted = submitted
|
|
701
|
+
self._key = case_conflict_key
|
|
702
|
+
|
|
703
|
+
def on_done(self, future, **kwargs):
|
|
704
|
+
self._submitted.discard(self._key)
|
|
705
|
+
|
|
706
|
+
|
|
682
707
|
class DeleteSourceSubscriber(OnDoneFilteredSubscriber):
|
|
683
708
|
"""A subscriber which deletes the source of the transfer."""
|
|
684
709
|
def _on_success(self, future):
|