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.
Files changed (401) hide show
  1. awscli/__init__.py +1 -1
  2. awscli/alias.py +3 -3
  3. awscli/argprocess.py +7 -2
  4. awscli/arguments.py +1 -1
  5. awscli/bcdoc/docevents.py +3 -0
  6. awscli/clidocs.py +19 -2
  7. awscli/clidriver.py +57 -10
  8. awscli/compat.py +11 -0
  9. awscli/customizations/argrename.py +1 -3
  10. awscli/customizations/cliinputjson.py +4 -0
  11. awscli/customizations/cloudformation/deploy.py +23 -6
  12. awscli/customizations/cloudformation/deployer.py +2 -2
  13. awscli/customizations/cloudformation/package.py +3 -2
  14. awscli/customizations/cloudfront.py +3 -1
  15. awscli/customizations/cloudtrail/subscribe.py +5 -5
  16. awscli/customizations/cloudtrail/validation.py +32 -11
  17. awscli/customizations/codecommit.py +2 -3
  18. awscli/customizations/codedeploy/deregister.py +5 -2
  19. awscli/customizations/codedeploy/push.py +7 -6
  20. awscli/customizations/codedeploy/register.py +5 -2
  21. awscli/customizations/codedeploy/systems.py +3 -1
  22. awscli/customizations/commands.py +2 -1
  23. awscli/customizations/configservice/getstatus.py +3 -3
  24. awscli/customizations/datapipeline/__init__.py +7 -4
  25. awscli/customizations/datapipeline/createdefaultroles.py +4 -2
  26. awscli/customizations/dlm/createdefaultrole.py +4 -2
  27. awscli/customizations/ec2/bundleinstance.py +2 -1
  28. awscli/customizations/eks/get_token.py +6 -4
  29. awscli/customizations/eks/update_kubeconfig.py +15 -3
  30. awscli/customizations/emr/argumentschema.py +355 -344
  31. awscli/customizations/emr/createcluster.py +520 -282
  32. awscli/customizations/emr/emrutils.py +83 -50
  33. awscli/customizations/emr/helptext.py +132 -74
  34. awscli/customizations/emr/steputils.py +92 -52
  35. awscli/customizations/gamelift/getlog.py +3 -2
  36. awscli/customizations/gamelift/uploadbuild.py +30 -15
  37. awscli/customizations/globalargs.py +169 -0
  38. awscli/customizations/logs/startlivetail.py +3 -3
  39. awscli/customizations/paginate.py +66 -1
  40. awscli/customizations/rds.py +3 -1
  41. awscli/customizations/removals.py +4 -0
  42. awscli/customizations/s3/filegenerator.py +7 -1
  43. awscli/customizations/s3/fileinfo.py +5 -1
  44. awscli/customizations/s3/fileinfobuilder.py +7 -0
  45. awscli/customizations/s3/s3handler.py +11 -0
  46. awscli/customizations/s3/subcommands.py +147 -6
  47. awscli/customizations/s3/syncstrategy/base.py +9 -0
  48. awscli/customizations/s3/syncstrategy/caseconflict.py +96 -0
  49. awscli/customizations/s3/utils.py +25 -0
  50. awscli/customizations/s3uploader.py +18 -8
  51. awscli/customizations/scalarparse.py +48 -9
  52. awscli/customizations/utils.py +2 -1
  53. awscli/customizations/waiters.py +3 -2
  54. awscli/data/cli.json +5 -0
  55. awscli/examples/apigateway/update-vpc-link.rst +47 -0
  56. awscli/examples/apigatewayv2/create-routing-rule.rst +52 -0
  57. awscli/examples/apigatewayv2/delete-routing-rule.rst +11 -0
  58. awscli/examples/apigatewayv2/get-routing-rule.rst +35 -0
  59. awscli/examples/apigatewayv2/list-routing-rules.rst +38 -0
  60. awscli/examples/apigatewayv2/put-routing-rule.rst +52 -0
  61. awscli/examples/application-signals/batch-get-service-level-objective-budget-report.rst +99 -0
  62. awscli/examples/application-signals/create-service-level-objective.rst +88 -0
  63. awscli/examples/application-signals/delete-service-level-objective.rst +10 -0
  64. awscli/examples/application-signals/get-service-level-objective.rst +53 -0
  65. awscli/examples/application-signals/get-service.rst +72 -0
  66. awscli/examples/application-signals/list-service-dependencies.rst +96 -0
  67. awscli/examples/application-signals/list-service-dependents.rst +36 -0
  68. awscli/examples/application-signals/list-service-level-objectives.rst +17 -0
  69. awscli/examples/application-signals/list-service-operations.rst +63 -0
  70. awscli/examples/application-signals/list-services.rst +61 -0
  71. awscli/examples/application-signals/list-tags-for-resource.rst +17 -0
  72. awscli/examples/application-signals/start-discovery.rst +9 -0
  73. awscli/examples/application-signals/tag-resource.rst +11 -0
  74. awscli/examples/application-signals/untag-resource.rst +11 -0
  75. awscli/examples/application-signals/update-service-level-objective.rst +69 -0
  76. awscli/examples/cloudformation/_package_description.rst +4 -4
  77. awscli/examples/cloudformation/create-generated-template.rst +50 -0
  78. awscli/examples/cloudformation/create-stack-refactor.rst +16 -0
  79. awscli/examples/cloudformation/delete-generated-template.rst +10 -0
  80. awscli/examples/cloudformation/describe-generated-template.rst +62 -0
  81. awscli/examples/cloudformation/describe-resource-scan.rst +38 -0
  82. awscli/examples/cloudformation/describe-stack-refactor.rst +20 -0
  83. awscli/examples/cloudformation/execute-stack-refactor.rst +10 -0
  84. awscli/examples/cloudformation/list-generated-templates.rst +41 -0
  85. awscli/examples/cloudformation/list-resource-scan-related-resources.rst +47 -0
  86. awscli/examples/cloudformation/list-resource-scan-resources.rst +30 -0
  87. awscli/examples/cloudformation/list-stack-refactor-actions.rst +71 -0
  88. awscli/examples/cloudformation/start-resource-scan.rst +14 -0
  89. awscli/examples/cloudfront/associate-distribution-tenant-web-acl.rst +18 -0
  90. awscli/examples/cloudfront/associate-distribution-web-acl.rst +18 -0
  91. awscli/examples/cloudfront/create-connection-group.rst +39 -0
  92. awscli/examples/cloudfront/create-distribution-tenant.rst +275 -0
  93. awscli/examples/cloudfront/create-distribution.rst +625 -235
  94. awscli/examples/cloudfront/create-invalidation-for-distribution-tenant.rst +29 -0
  95. awscli/examples/cloudfront/delete-connection-group.rst +11 -0
  96. awscli/examples/cloudfront/delete-distribution-tenant.rst +11 -0
  97. awscli/examples/cloudfront/disassociate-distribution-tenant-web-acl.rst +16 -0
  98. awscli/examples/cloudfront/disassociate-distribution-web-acl.rst +16 -0
  99. awscli/examples/cloudfront/get-connection-group-by-routing-endpoint.rst +26 -0
  100. awscli/examples/cloudfront/get-connection-group.rst +26 -0
  101. awscli/examples/cloudfront/get-distribution-tenant-by-domain.rst +37 -0
  102. awscli/examples/cloudfront/get-distribution-tenant.rst +31 -0
  103. awscli/examples/cloudfront/get-invalidation-for-distribution-tenant.rst +29 -0
  104. awscli/examples/cloudfront/get-managed-certificate-details.rst +25 -0
  105. awscli/examples/cloudfront/list-connection-groups.rst +38 -0
  106. awscli/examples/cloudfront/list-distribution-tenants-by-customization.rst +45 -0
  107. awscli/examples/cloudfront/list-distribution-tenants.rst +90 -0
  108. awscli/examples/cloudfront/list-distributions-by-connection-mode.rst +115 -0
  109. awscli/examples/cloudfront/list-domain-conflicts.rst +22 -0
  110. awscli/examples/cloudfront/list-invalidations-for-distribution-tenant.rst +22 -0
  111. awscli/examples/cloudfront/update-connection-group.rst +29 -0
  112. awscli/examples/cloudfront/update-distribution-tenant.rst +76 -0
  113. awscli/examples/cloudfront/update-domain-association.rst +18 -0
  114. awscli/examples/cloudfront/verify-dns-configuration.rst +20 -0
  115. awscli/examples/ec2/associate-ipam-resource-discovery.rst +1 -1
  116. awscli/examples/ec2/authorize-security-group-ingress.rst +1 -1
  117. awscli/examples/ec2/create-ipam-resource-discovery.rst +1 -1
  118. awscli/examples/ec2/delete-ipam-pool.rst +1 -1
  119. awscli/examples/ec2/describe-addresses-attribute.rst +1 -1
  120. awscli/examples/ec2/get-ipam-discovered-public-addresses.rst +1 -1
  121. awscli/examples/ec2/modify-ipam-resource-discovery.rst +1 -1
  122. awscli/examples/ec2/modify-ipam-scope.rst +1 -1
  123. awscli/examples/ec2/release-ipam-pool-allocation.rst +3 -3
  124. awscli/examples/eks/associate-access-policy.rst +29 -0
  125. awscli/examples/eks/create-access-entry.rst +54 -0
  126. awscli/examples/eks/create-pod-identity-association.rst +59 -0
  127. awscli/examples/eks/delete-access-entry.rst +11 -0
  128. awscli/examples/eks/delete-pod-identity-association.rst +28 -0
  129. awscli/examples/eks/describe-access-entry.rst +25 -0
  130. awscli/examples/eks/describe-insight.rst +36 -0
  131. awscli/examples/eks/describe-pod-identity-association.rst +28 -0
  132. awscli/examples/eks/disassociate-access-policy.rst +12 -0
  133. awscli/examples/eks/list-access-entries.rst +19 -0
  134. awscli/examples/eks/list-access-policies.rst +90 -0
  135. awscli/examples/eks/list-associated-access-policies.rst +27 -0
  136. awscli/examples/eks/list-insights.rst +67 -0
  137. awscli/examples/eks/list-pod-identity-associations.rst +61 -0
  138. awscli/examples/eks/update-access-entry.rst +28 -0
  139. awscli/examples/eks/update-pod-identity-association.rst +29 -0
  140. awscli/examples/elbv2/modify-listener.rst +95 -86
  141. awscli/examples/emr/create-cluster-synopsis.txt +1 -0
  142. awscli/examples/global_options.rst +4 -0
  143. awscli/examples/global_synopsis.rst +1 -0
  144. awscli/examples/guardduty/update-detector.rst +23 -0
  145. awscli/examples/ivs-realtime/create-stage.rst +6 -3
  146. awscli/examples/ivs-realtime/get-composition.rst +7 -4
  147. awscli/examples/ivs-realtime/get-participant.rst +99 -31
  148. awscli/examples/ivs-realtime/get-stage.rst +3 -2
  149. awscli/examples/ivs-realtime/list-participant-events.rst +54 -2
  150. awscli/examples/ivs-realtime/list-participant-replicas.rst +24 -0
  151. awscli/examples/ivs-realtime/list-participants.rst +61 -3
  152. awscli/examples/ivs-realtime/start-composition.rst +88 -3
  153. awscli/examples/ivs-realtime/start-participant-replication.rst +24 -0
  154. awscli/examples/ivs-realtime/stop-participant-replication.rst +24 -0
  155. awscli/examples/ivs-realtime/update-stage.rst +51 -3
  156. awscli/examples/kms/create-key.rst +42 -7
  157. awscli/examples/kms/delete-imported-key-material.rst +8 -2
  158. awscli/examples/kms/describe-key.rst +2 -0
  159. awscli/examples/kms/disable-key.rst +1 -1
  160. awscli/examples/kms/generate-data-key-pair-without-plaintext.rst +1 -0
  161. awscli/examples/kms/generate-data-key-pair.rst +1 -0
  162. awscli/examples/kms/generate-data-key-without-plaintext.rst +2 -1
  163. awscli/examples/kms/generate-data-key.rst +5 -4
  164. awscli/examples/kms/generate-mac.rst +45 -0
  165. awscli/examples/kms/generate-random.rst +1 -1
  166. awscli/examples/kms/get-public-key.rst +2 -3
  167. awscli/examples/kms/import-key-material.rst +6 -1
  168. awscli/examples/kms/re-encrypt.rst +3 -3
  169. awscli/examples/kms/sign.rst +1 -1
  170. awscli/examples/kms/verify-mac.rst +27 -0
  171. awscli/examples/kms/verify.rst +5 -1
  172. awscli/examples/lambda/create-function.rst +4 -4
  173. awscli/examples/lambda/get-function.rst +3 -3
  174. awscli/examples/lambda/list-functions.rst +6 -6
  175. awscli/examples/medical-imaging/create-datastore.rst +19 -2
  176. awscli/examples/medical-imaging/get-datastore.rst +24 -1
  177. awscli/examples/networkmanager/get-vpc-attachment.rst +1 -1
  178. awscli/examples/omics/cancel-run.rst +1 -1
  179. awscli/examples/omics/create-run-group.rst +4 -2
  180. awscli/examples/omics/create-workflow.rst +1 -1
  181. awscli/examples/omics/delete-run-group.rst +1 -1
  182. awscli/examples/omics/delete-run.rst +1 -1
  183. awscli/examples/omics/delete-workflow.rst +1 -1
  184. awscli/examples/omics/get-run-group.rst +1 -1
  185. awscli/examples/omics/get-run-task.rst +1 -1
  186. awscli/examples/omics/get-run.rst +1 -1
  187. awscli/examples/omics/get-workflow.rst +1 -1
  188. awscli/examples/omics/list-run-groups.rst +1 -1
  189. awscli/examples/omics/list-run-tasks.rst +1 -1
  190. awscli/examples/omics/list-runs.rst +1 -1
  191. awscli/examples/omics/list-workflows.rst +1 -1
  192. awscli/examples/omics/start-run.rst +1 -2
  193. awscli/examples/omics/update-workflow.rst +1 -1
  194. awscli/examples/pi/create-performance-analysis-report.rst +17 -0
  195. awscli/examples/pi/delete-performance-analysis-report.rst +12 -0
  196. awscli/examples/pi/describe-dimension-keys.rst +33 -1
  197. awscli/examples/pi/get-dimension-key-details.rst +25 -0
  198. awscli/examples/pi/get-performance-analysis-report.rst +27 -0
  199. awscli/examples/pi/get-resource-metadata.rst +20 -0
  200. awscli/examples/pi/list-available-resource-dimensions.rst +48 -0
  201. awscli/examples/pi/list-available-resource-metrics.rst +29 -0
  202. awscli/examples/pi/list-performance-analysis-reports.rst +44 -0
  203. awscli/examples/pi/list-tags-for-resource.rst +20 -0
  204. awscli/examples/pi/tag-resource.rst +12 -0
  205. awscli/examples/pi/untag-resource.rst +12 -0
  206. awscli/examples/route53domains/get-domain-detail.rst +3 -3
  207. awscli/examples/securityhub/describe-hub.rst +6 -4
  208. awscli/examples/servicediscovery/create-service.rst +50 -10
  209. awscli/examples/servicediscovery/delete-namespace.rst +18 -4
  210. awscli/examples/servicediscovery/delete-service-attributes.rst +15 -3
  211. awscli/examples/servicediscovery/delete-service.rst +13 -3
  212. awscli/examples/servicediscovery/deregister-instance.rst +18 -2
  213. awscli/examples/servicediscovery/discover-instances-revision.rst +18 -1
  214. awscli/examples/servicediscovery/discover-instances.rst +32 -2
  215. awscli/examples/servicediscovery/get-instance.rst +30 -4
  216. awscli/examples/servicediscovery/get-instances-health-status.rst +19 -1
  217. awscli/examples/servicediscovery/get-namespace.rst +40 -9
  218. awscli/examples/servicediscovery/get-operation.rst +32 -6
  219. awscli/examples/servicediscovery/get-service-attributes.rst +25 -3
  220. awscli/examples/servicediscovery/get-service.rst +35 -7
  221. awscli/examples/servicediscovery/list-instances.rst +38 -3
  222. awscli/examples/servicediscovery/list-namespaces.rst +45 -22
  223. awscli/examples/servicediscovery/list-services.rst +30 -2
  224. awscli/examples/servicediscovery/register-instance.rst +18 -2
  225. awscli/examples/servicediscovery/update-http-namespace.rst +22 -5
  226. awscli/examples/servicediscovery/update-instance-custom-health-status.rst +14 -1
  227. awscli/examples/servicediscovery/update-private-dns-namespace.rst +22 -5
  228. awscli/examples/servicediscovery/update-public-dns-namespace.rst +22 -5
  229. awscli/examples/servicediscovery/update-service-attributes.rst +14 -2
  230. awscli/examples/servicediscovery/update-service.rst +20 -4
  231. awscli/examples/ssm/put-parameter.rst +6 -6
  232. awscli/examples/verifiedpermissions/update-policy.rst +10 -78
  233. awscli/examples/workspaces/describe-workspace-directories.rst +1 -2
  234. awscli/examples/workspaces/register-workspace-directory.rst +2 -3
  235. awscli/handlers.py +0 -4
  236. awscli/paramfile.py +21 -4
  237. awscli/testutils.py +22 -4
  238. awscli/topics/config-vars.rst +1 -1
  239. awscli/topics/s3-case-insensitivity.rst +105 -0
  240. awscli/topics/topic-tags.json +16 -0
  241. awscli/utils.py +33 -2
  242. {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/METADATA +18 -3
  243. {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/RECORD +251 -308
  244. awscli/customizations/opsworks.py +0 -543
  245. awscli/customizations/opsworkscm.py +0 -21
  246. awscli/examples/elastictranscoder/cancel-job.rst +0 -8
  247. awscli/examples/elastictranscoder/create-job.rst +0 -94
  248. awscli/examples/elastictranscoder/create-pipeline.rst +0 -94
  249. awscli/examples/elastictranscoder/create-preset.rst +0 -141
  250. awscli/examples/elastictranscoder/delete-pipeline.rst +0 -13
  251. awscli/examples/elastictranscoder/delete-preset.rst +0 -8
  252. awscli/examples/elastictranscoder/list-jobs-by-pipeline.rst +0 -13
  253. awscli/examples/elastictranscoder/list-jobs-by-status.rst +0 -14
  254. awscli/examples/elastictranscoder/list-pipelines.rst +0 -84
  255. awscli/examples/elastictranscoder/list-presets.rst +0 -95
  256. awscli/examples/elastictranscoder/read-job.rst +0 -65
  257. awscli/examples/elastictranscoder/read-pipeline.rst +0 -59
  258. awscli/examples/elastictranscoder/read-preset.rst +0 -100
  259. awscli/examples/elastictranscoder/update-pipeline-notifications.rst +0 -52
  260. awscli/examples/elastictranscoder/update-pipeline-status.rst +0 -53
  261. awscli/examples/elastictranscoder/update-pipeline.rst +0 -95
  262. awscli/examples/opsworks/assign-instance.rst +0 -14
  263. awscli/examples/opsworks/assign-volume.rst +0 -17
  264. awscli/examples/opsworks/associate-elastic-ip.rst +0 -14
  265. awscli/examples/opsworks/attach-elastic-load-balancer.rst +0 -14
  266. awscli/examples/opsworks/create-app.rst +0 -64
  267. awscli/examples/opsworks/create-deployment.rst +0 -66
  268. awscli/examples/opsworks/create-instance.rst +0 -25
  269. awscli/examples/opsworks/create-layer.rst +0 -17
  270. awscli/examples/opsworks/create-server.rst +0 -43
  271. awscli/examples/opsworks/create-stack.rst +0 -25
  272. awscli/examples/opsworks/create-user-profile.rst +0 -24
  273. awscli/examples/opsworks/delete-app.rst +0 -17
  274. awscli/examples/opsworks/delete-instance.rst +0 -15
  275. awscli/examples/opsworks/delete-layer.rst +0 -17
  276. awscli/examples/opsworks/delete-stack.rst +0 -18
  277. awscli/examples/opsworks/delete-user-profile.rst +0 -17
  278. awscli/examples/opsworks/deregister-elastic-ip.rst +0 -13
  279. awscli/examples/opsworks/deregister-instance.rst +0 -14
  280. awscli/examples/opsworks/deregister-rds-db-instance.rst +0 -20
  281. awscli/examples/opsworks/deregister-volume.rst +0 -15
  282. awscli/examples/opsworks/describe-apps.rst +0 -38
  283. awscli/examples/opsworks/describe-commands.rst +0 -43
  284. awscli/examples/opsworks/describe-deployments.rst +0 -52
  285. awscli/examples/opsworks/describe-elastic-ips.rst +0 -24
  286. awscli/examples/opsworks/describe-elastic-load-balancers.rst +0 -37
  287. awscli/examples/opsworks/describe-instances.rst +0 -95
  288. awscli/examples/opsworks/describe-layers.rst +0 -171
  289. awscli/examples/opsworks/describe-load-based-auto-scaling.rst +0 -37
  290. awscli/examples/opsworks/describe-my-user-profile.rst +0 -24
  291. awscli/examples/opsworks/describe-permissions.rst +0 -26
  292. awscli/examples/opsworks/describe-raid-arrays.rst +0 -31
  293. awscli/examples/opsworks/describe-rds-db-instances.rst +0 -29
  294. awscli/examples/opsworks/describe-stack-provisioning-parameters.rst +0 -32
  295. awscli/examples/opsworks/describe-stack-summary.rst +0 -27
  296. awscli/examples/opsworks/describe-stacks.rst +0 -65
  297. awscli/examples/opsworks/describe-timebased-auto-scaling.rst +0 -39
  298. awscli/examples/opsworks/describe-user-profiles.rst +0 -32
  299. awscli/examples/opsworks/describe-volumes.rst +0 -31
  300. awscli/examples/opsworks/detach-elastic-load-balancer.rst +0 -14
  301. awscli/examples/opsworks/disassociate-elastic-ip.rst +0 -14
  302. awscli/examples/opsworks/get-hostname-suggestion.rst +0 -21
  303. awscli/examples/opsworks/reboot-instance.rst +0 -14
  304. awscli/examples/opsworks/register-elastic-ip.rst +0 -19
  305. awscli/examples/opsworks/register-rds-db-instance.rst +0 -15
  306. awscli/examples/opsworks/register-volume.rst +0 -18
  307. awscli/examples/opsworks/register.rst +0 -105
  308. awscli/examples/opsworks/set-load-based-auto-scaling.rst +0 -38
  309. awscli/examples/opsworks/set-permission.rst +0 -23
  310. awscli/examples/opsworks/set-time-based-auto-scaling.rst +0 -33
  311. awscli/examples/opsworks/start-instance.rst +0 -20
  312. awscli/examples/opsworks/start-stack.rst +0 -15
  313. awscli/examples/opsworks/stop-instance.rst +0 -20
  314. awscli/examples/opsworks/stop-stack.rst +0 -15
  315. awscli/examples/opsworks/unassign-instance.rst +0 -14
  316. awscli/examples/opsworks/unassign-volume.rst +0 -16
  317. awscli/examples/opsworks/update-app.rst +0 -14
  318. awscli/examples/opsworks/update-elastic-ip.rst +0 -14
  319. awscli/examples/opsworks/update-instance.rst +0 -14
  320. awscli/examples/opsworks/update-layer.rst +0 -14
  321. awscli/examples/opsworks/update-my-user-profile.rst +0 -16
  322. awscli/examples/opsworks/update-rds-db-instance.rst +0 -18
  323. awscli/examples/opsworks/update-volume.rst +0 -16
  324. awscli/examples/opsworkscm/associate-node.rst +0 -22
  325. awscli/examples/opsworkscm/create-backup.rst +0 -46
  326. awscli/examples/opsworkscm/create-server.rst +0 -48
  327. awscli/examples/opsworkscm/delete-backup.rst +0 -17
  328. awscli/examples/opsworkscm/delete-server.rst +0 -16
  329. awscli/examples/opsworkscm/describe-account-attributes.rst +0 -26
  330. awscli/examples/opsworkscm/describe-backups.rst +0 -44
  331. awscli/examples/opsworkscm/describe-events.rst +0 -21
  332. awscli/examples/opsworkscm/describe-node-association-status.rst +0 -20
  333. awscli/examples/opsworkscm/describe-servers.rst +0 -48
  334. awscli/examples/opsworkscm/disassociate-node.rst +0 -19
  335. awscli/examples/opsworkscm/restore-server.rst +0 -20
  336. awscli/examples/opsworkscm/start-maintenance.rst +0 -39
  337. awscli/examples/opsworkscm/update-server-engine-attributes.rst +0 -43
  338. awscli/examples/opsworkscm/update-server.rst +0 -42
  339. awscli/examples/qldb/cancel-journal-kinesis-stream.rst +0 -15
  340. awscli/examples/qldb/create-ledger.rst +0 -43
  341. awscli/examples/qldb/delete-ledger.rst +0 -10
  342. awscli/examples/qldb/describe-journal-kinesis-stream.rst +0 -29
  343. awscli/examples/qldb/describe-journal-s3-export.rst +0 -30
  344. awscli/examples/qldb/describe-ledger.rst +0 -23
  345. awscli/examples/qldb/export-journal-to-s3.rst +0 -28
  346. awscli/examples/qldb/get-block.rst +0 -55
  347. awscli/examples/qldb/get-digest.rst +0 -17
  348. awscli/examples/qldb/get-revision.rst +0 -57
  349. awscli/examples/qldb/list-journal-kinesis-streams-for-ledger.rst +0 -30
  350. awscli/examples/qldb/list-journal-s3-exports-for-ledger.rst +0 -31
  351. awscli/examples/qldb/list-journal-s3-exports.rst +0 -46
  352. awscli/examples/qldb/list-ledgers.rst +0 -24
  353. awscli/examples/qldb/list-tags-for-resource.rst +0 -17
  354. awscli/examples/qldb/stream-journal-to-kinesis.rst +0 -46
  355. awscli/examples/qldb/tag-resource.rst +0 -11
  356. awscli/examples/qldb/untag-resource.rst +0 -11
  357. awscli/examples/qldb/update-ledger-permissions-mode.rst +0 -34
  358. awscli/examples/qldb/update-ledger.rst +0 -63
  359. awscli/examples/robomaker/batch-describe-simulation-job.rst +0 -150
  360. awscli/examples/robomaker/cancel-simulation-job.rst +0 -6
  361. awscli/examples/robomaker/create-deployment-job.rst +0 -37
  362. awscli/examples/robomaker/create-fleet.rst +0 -18
  363. awscli/examples/robomaker/create-robot-application-version.rst +0 -31
  364. awscli/examples/robomaker/create-robot-application.rst +0 -29
  365. awscli/examples/robomaker/create-robot.rst +0 -20
  366. awscli/examples/robomaker/create-simulation-application-version.rst +0 -39
  367. awscli/examples/robomaker/create-simulation-application.rst +0 -38
  368. awscli/examples/robomaker/create-simulation-job.rst +0 -43
  369. awscli/examples/robomaker/delete-fleet.rst +0 -7
  370. awscli/examples/robomaker/delete-robot-application.rst +0 -7
  371. awscli/examples/robomaker/delete-robot.rst +0 -7
  372. awscli/examples/robomaker/delete-simulation-application.rst +0 -7
  373. awscli/examples/robomaker/deregister-robot.rst +0 -14
  374. awscli/examples/robomaker/describe-deployment-job.rst +0 -38
  375. awscli/examples/robomaker/describe-fleet.rst +0 -28
  376. awscli/examples/robomaker/describe-robot-application.rst +0 -29
  377. awscli/examples/robomaker/describe-robot.rst +0 -21
  378. awscli/examples/robomaker/describe-simulation-application.rst +0 -37
  379. awscli/examples/robomaker/describe-simulation-job.rst +0 -45
  380. awscli/examples/robomaker/list-deployment-jobs.rst +0 -57
  381. awscli/examples/robomaker/list-fleets.rst +0 -22
  382. awscli/examples/robomaker/list-robot-applications.rst +0 -32
  383. awscli/examples/robomaker/list-robots.rst +0 -45
  384. awscli/examples/robomaker/list-simulation-applications.rst +0 -50
  385. awscli/examples/robomaker/list-simulation-jobs.rst +0 -80
  386. awscli/examples/robomaker/list-tags-for-resource.rst +0 -16
  387. awscli/examples/robomaker/register-robot.rst +0 -14
  388. awscli/examples/robomaker/restart-simulation-job.rst +0 -7
  389. awscli/examples/robomaker/sync-deployment-job.rst +0 -30
  390. awscli/examples/robomaker/tag-resource.rst +0 -7
  391. awscli/examples/robomaker/untag-resource.rst +0 -7
  392. awscli/examples/robomaker/update-robot-application.rst +0 -28
  393. awscli/examples/robomaker/update-simulation-application.rst +0 -36
  394. {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws +0 -0
  395. {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws.cmd +0 -0
  396. {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws_bash_completer +0 -0
  397. {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws_completer +0 -0
  398. {awscli-1.40.17.data → awscli-1.44.26.data}/scripts/aws_zsh_completer.sh +0 -0
  399. {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/LICENSE.txt +0 -0
  400. {awscli-1.40.17.dist-info → awscli-1.44.26.dist-info}/WHEEL +0 -0
  401. {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,
@@ -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 = self._session.create_client(
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
- sync_strategies['file_not_at_dest_sync_strategy'] = MissingFileSync()
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):