From 6b7f379a1b3469e26800de4d1e1c06ac7675c158 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 20 Feb 2024 12:51:19 +0000 Subject: [PATCH 01/12] dependencies: updating to v0.25.1 of `github.com/tombuildsstuff/giovanni` --- go.mod | 4 +- go.sum | 36 +-- vendor/github.com/google/uuid/CHANGELOG.md | 11 + vendor/github.com/google/uuid/CONTRIBUTING.md | 2 +- vendor/github.com/google/uuid/uuid.go | 26 ++- .../sdk/client/dataplane/client.go | 27 +++ .../sdk/client/dataplane/storage/client.go | 73 ++++++ .../2020-08-04/blob/accounts/README.md | 1 - .../2020-08-04/blob/accounts/client.go | 25 +- .../blob/accounts/get_service_properties.go | 83 ++----- .../2020-08-04/blob/accounts/models.go | 6 - .../2020-08-04/blob/accounts/resource_id.go | 155 +++++++++++++ .../accounts/service_properties_shared.go | 26 +++ .../blob/accounts/set_service_properties.go | 74 ++---- .../2020-08-04/blob/accounts/version.go | 14 +- .../storage/2020-08-04/blob/blobs/README.md | 20 +- .../storage/2020-08-04/blob/blobs/api.go | 68 +++--- .../2020-08-04/blob/blobs/append_block.go | 168 ++++++-------- .../storage/2020-08-04/blob/blobs/client.go | 25 +- .../storage/2020-08-04/blob/blobs/copy.go | 157 ++++++------- .../2020-08-04/blob/blobs/copy_abort.go | 106 ++++----- .../2020-08-04/blob/blobs/copy_and_wait.go | 39 ++-- .../blob/blobs/copy_and_wait_poller.go | 48 ++++ .../storage/2020-08-04/blob/blobs/delete.go | 95 ++++---- .../2020-08-04/blob/blobs/delete_snapshot.go | 102 ++++---- .../2020-08-04/blob/blobs/delete_snapshots.go | 95 ++++---- .../storage/2020-08-04/blob/blobs/get.go | 111 ++++----- .../2020-08-04/blob/blobs/get_block_list.go | 140 +++++------ .../2020-08-04/blob/blobs/get_page_ranges.go | 144 ++++++------ .../blob/blobs/incremental_copy_blob.go | 115 ++++----- .../2020-08-04/blob/blobs/lease_acquire.go | 125 +++++----- .../2020-08-04/blob/blobs/lease_break.go | 104 ++++----- .../2020-08-04/blob/blobs/lease_change.go | 116 ++++------ .../2020-08-04/blob/blobs/lease_release.go | 109 ++++----- .../2020-08-04/blob/blobs/lease_renew.go | 109 ++++----- .../2020-08-04/blob/blobs/metadata_set.go | 106 ++++----- .../2020-08-04/blob/blobs/properties_get.go | 219 ++++++++---------- .../2020-08-04/blob/blobs/properties_set.go | 140 +++++------ .../2020-08-04/blob/blobs/put_append_blob.go | 127 +++++----- .../2020-08-04/blob/blobs/put_block.go | 122 +++++----- .../2020-08-04/blob/blobs/put_block_blob.go | 140 +++++------ .../blob/blobs/put_block_blob_file.go | 8 +- .../2020-08-04/blob/blobs/put_block_list.go | 143 +++++------- .../2020-08-04/blob/blobs/put_block_url.go | 129 +++++------ .../2020-08-04/blob/blobs/put_page_blob.go | 153 ++++++------ .../2020-08-04/blob/blobs/put_page_clear.go | 108 ++++----- .../2020-08-04/blob/blobs/put_page_update.go | 164 +++++++------ .../2020-08-04/blob/blobs/resource_id.go | 73 ++++-- .../storage/2020-08-04/blob/blobs/set_tier.go | 102 ++++---- .../storage/2020-08-04/blob/blobs/snapshot.go | 131 +++++------ .../blob/blobs/snapshot_get_properties.go | 156 +++++++++---- .../storage/2020-08-04/blob/blobs/undelete.go | 90 +++---- .../storage/2020-08-04/blob/blobs/version.go | 13 +- .../2020-08-04/blob/containers/README.md | 23 +- .../storage/2020-08-04/blob/containers/api.go | 27 +-- .../2020-08-04/blob/containers/client.go | 34 +-- .../2020-08-04/blob/containers/create.go | 115 ++++----- .../2020-08-04/blob/containers/delete.go | 82 ++----- .../blob/containers/get_properties.go | 147 +++++------- .../blob/containers/lease_acquire.go | 114 ++++----- .../2020-08-04/blob/containers/lease_break.go | 125 +++++----- .../blob/containers/lease_change.go | 114 ++++----- .../blob/containers/lease_release.go | 105 ++++----- .../2020-08-04/blob/containers/lease_renew.go | 105 ++++----- .../2020-08-04/blob/containers/list_blobs.go | 144 ++++++------ .../2020-08-04/blob/containers/models.go | 4 - .../2020-08-04/blob/containers/options.go | 35 +++ .../2020-08-04/blob/containers/resource_id.go | 72 ++++-- .../2020-08-04/blob/containers/set_acl.go | 112 ++++----- .../blob/containers/set_metadata.go | 113 ++++----- .../2020-08-04/blob/containers/version.go | 14 +- .../datalakestore/filesystems/README.md | 56 ++--- .../datalakestore/filesystems/client.go | 28 ++- .../datalakestore/filesystems/create.go | 95 ++++---- .../datalakestore/filesystems/delete.go | 86 ++----- .../datalakestore/filesystems/options.go | 32 +++ .../filesystems/properties_get.go | 92 ++------ .../filesystems/properties_set.go | 106 ++++----- .../datalakestore/filesystems/resource_id.go | 79 +++++-- .../datalakestore/filesystems/version.go | 14 +- .../2020-08-04/datalakestore/paths/client.go | 25 +- .../2020-08-04/datalakestore/paths/create.go | 95 +++----- .../2020-08-04/datalakestore/paths/delete.go | 82 ++----- .../datalakestore/paths/properties_get.go | 135 +++++------ .../datalakestore/paths/properties_set.go | 115 ++++----- .../datalakestore/paths/resource_id.go | 87 ++++--- .../2020-08-04/datalakestore/paths/version.go | 14 +- .../2020-08-04/file/directories/README.md | 27 ++- .../2020-08-04/file/directories/api.go | 13 +- .../2020-08-04/file/directories/client.go | 40 ++-- .../2020-08-04/file/directories/create.go | 118 ++++------ .../2020-08-04/file/directories/delete.go | 90 ++----- .../2020-08-04/file/directories/get.go | 97 +++----- .../file/directories/metadata_get.go | 104 ++++----- .../file/directories/metadata_set.go | 112 ++++----- .../2020-08-04/file/directories/options.go | 24 ++ .../file/directories/resource_id.go | 80 ++++--- .../2020-08-04/file/directories/version.go | 13 +- .../storage/2020-08-04/file/files/README.md | 23 +- .../storage/2020-08-04/file/files/api.go | 34 ++- .../storage/2020-08-04/file/files/client.go | 40 ++-- .../storage/2020-08-04/file/files/copy.go | 124 +++++----- .../2020-08-04/file/files/copy_abort.go | 118 +++++----- .../file/files/copy_and_wait_poller.go | 48 ++++ .../2020-08-04/file/files/copy_wait.go | 46 +--- .../storage/2020-08-04/file/files/create.go | 137 +++++------ .../storage/2020-08-04/file/files/delete.go | 92 +++----- .../2020-08-04/file/files/metadata_get.go | 110 ++++----- .../2020-08-04/file/files/metadata_set.go | 115 ++++----- .../2020-08-04/file/files/properties_get.go | 139 ++++------- .../2020-08-04/file/files/properties_set.go | 137 +++++------ .../2020-08-04/file/files/range_clear.go | 115 ++++----- .../2020-08-04/file/files/range_get.go | 122 +++++----- .../2020-08-04/file/files/range_get_file.go | 37 +-- .../2020-08-04/file/files/range_put.go | 125 +++++----- .../2020-08-04/file/files/range_put_file.go | 18 +- .../2020-08-04/file/files/ranges_list.go | 108 ++++----- .../2020-08-04/file/files/resource_id.go | 89 ++++--- .../storage/2020-08-04/file/files/version.go | 14 +- .../storage/2020-08-04/file/shares/README.md | 23 +- .../storage/2020-08-04/file/shares/acl_get.go | 96 +++----- .../storage/2020-08-04/file/shares/acl_set.go | 112 ++++----- .../storage/2020-08-04/file/shares/api.go | 27 +-- .../storage/2020-08-04/file/shares/client.go | 25 +- .../storage/2020-08-04/file/shares/create.go | 117 ++++------ .../storage/2020-08-04/file/shares/delete.go | 103 ++++---- .../2020-08-04/file/shares/metadata_get.go | 99 +++----- .../2020-08-04/file/shares/metadata_set.go | 105 ++++----- .../storage/2020-08-04/file/shares/options.go | 24 ++ .../2020-08-04/file/shares/properties_get.go | 120 +++------- .../2020-08-04/file/shares/properties_set.go | 108 ++++----- .../2020-08-04/file/shares/resource_id.go | 76 ++++-- .../2020-08-04/file/shares/snapshot_create.go | 109 ++++----- .../2020-08-04/file/shares/snapshot_delete.go | 98 ++++---- .../2020-08-04/file/shares/snapshot_get.go | 113 ++++----- .../storage/2020-08-04/file/shares/stats.go | 97 +++----- .../storage/2020-08-04/file/shares/version.go | 14 +- .../storage/2020-08-04/queue/queues/README.md | 26 ++- .../storage/2020-08-04/queue/queues/api.go | 16 +- .../storage/2020-08-04/queue/queues/client.go | 27 ++- .../storage/2020-08-04/queue/queues/create.go | 99 ++++---- .../storage/2020-08-04/queue/queues/delete.go | 81 ++----- .../2020-08-04/queue/queues/metadata_get.go | 99 +++----- .../2020-08-04/queue/queues/metadata_set.go | 105 ++++----- .../storage/2020-08-04/queue/queues/models.go | 2 +- .../2020-08-04/queue/queues/properties_get.go | 89 +++---- .../2020-08-04/queue/queues/properties_set.go | 95 ++++---- .../2020-08-04/queue/queues/resource_id.go | 75 ++++-- .../2020-08-04/queue/queues/version.go | 13 +- .../2020-08-04/table/entities/README.md | 23 +- .../storage/2020-08-04/table/entities/api.go | 15 +- .../2020-08-04/table/entities/client.go | 26 +-- .../2020-08-04/table/entities/delete.go | 91 +++----- .../storage/2020-08-04/table/entities/get.go | 104 ++++----- .../2020-08-04/table/entities/insert.go | 102 ++++---- .../table/entities/insert_or_merge.go | 98 ++++---- .../table/entities/insert_or_replace.go | 98 ++++---- .../2020-08-04/table/entities/query.go | 160 ++++++------- .../2020-08-04/table/entities/resource_id.go | 156 ++++++++----- .../2020-08-04/table/entities/version.go | 14 +- .../storage/2020-08-04/table/tables/README.md | 22 +- .../2020-08-04/table/tables/acl_get.go | 96 +++----- .../2020-08-04/table/tables/acl_set.go | 93 +++----- .../storage/2020-08-04/table/tables/api.go | 16 +- .../storage/2020-08-04/table/tables/client.go | 26 +-- .../storage/2020-08-04/table/tables/create.go | 89 +++---- .../storage/2020-08-04/table/tables/delete.go | 79 +++---- .../storage/2020-08-04/table/tables/exists.go | 85 +++---- .../storage/2020-08-04/table/tables/query.go | 91 ++++---- .../2020-08-04/table/tables/resource_id.go | 101 +++++--- .../2020-08-04/table/tables/version.go | 14 +- .../storage/internal/endpoints/endpoints.go | 39 ---- .../storage/internal/metadata/parse.go | 7 +- .../giovanni/storage/internal/metadata/set.go | 16 +- .../giovanni/version/version.go | 3 - vendor/modules.txt | 10 +- 176 files changed, 6248 insertions(+), 7437 deletions(-) create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/client.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage/client.go create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/resource_id.go create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/service_properties_shared.go create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait_poller.go create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/options.go create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/options.go create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/options.go create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_and_wait_poller.go create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/options.go delete mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/internal/endpoints/endpoints.go delete mode 100644 vendor/github.com/tombuildsstuff/giovanni/version/version.go diff --git a/go.mod b/go.mod index a11f8bfe4f9f..e225415eebae 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/gofrs/uuid v4.4.0+incompatible github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/go-cmp v0.5.9 - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/hashicorp/go-azure-helpers v0.66.2 github.com/hashicorp/go-azure-sdk/resource-manager v0.20240228.1142829 github.com/hashicorp/go-azure-sdk/sdk v0.20240228.1142829 @@ -29,7 +29,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/rickb777/date v1.12.5-0.20200422084442-6300e543c4d9 github.com/sergi/go-diff v1.2.0 - github.com/tombuildsstuff/giovanni v0.20.0 + github.com/tombuildsstuff/giovanni v0.25.1 github.com/tombuildsstuff/kermit v0.20240122.1123108 golang.org/x/crypto v0.18.0 golang.org/x/tools v0.13.0 diff --git a/go.sum b/go.sum index 254f093e2411..fae14d6ced12 100644 --- a/go.sum +++ b/go.sum @@ -1,36 +1,23 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Azure/azure-sdk-for-go v45.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v56.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v66.0.0+incompatible h1:bmmC38SlE8/E81nNADlgmVGurPWMHDX2YNXVQMrBpEE= github.com/Azure/azure-sdk-for-go v66.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.3/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= @@ -67,16 +54,11 @@ github.com/dave/jennifer v1.6.0/go.mod h1:AxTG893FiZKqxy3FP1kL80VMshSMuz2G+Egvsz github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= @@ -104,15 +86,13 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-azure-helpers v0.12.0/go.mod h1:Zc3v4DNeX6PDdy7NljlYpnrdac1++qNW0I4U+ofGwpg= github.com/hashicorp/go-azure-helpers v0.66.2 h1:+Pzuo7pdKl0hBXXr5ymmhs4Q40tHAo2nAvHq4WgSjx8= github.com/hashicorp/go-azure-helpers v0.66.2/go.mod h1:kJxXrFtJKJdOEqvad8pllAe7dhP4DbN8J6sqFZe47+4= github.com/hashicorp/go-azure-sdk/resource-manager v0.20240228.1142829 h1:hvfN48POr1yZXJSzW71ynTVGfMQgLmX4NDJ3lPkiwgs= @@ -130,7 +110,6 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.5.1 h1:oGm7cWBaYIp3lJpx1RUEfLWophprE2EV/KUeqBYo+6k= @@ -200,7 +179,6 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -244,10 +222,11 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/tombuildsstuff/giovanni v0.20.0 h1:IM/I/iNWMXnPYwcSq8uxV7TKDlv7Nejq0bRK9i6O/C0= -github.com/tombuildsstuff/giovanni v0.20.0/go.mod h1:66KVLYma2whJhEdxPSPL3GQHkulhK+C5CluKfHGfPF4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tombuildsstuff/giovanni v0.25.1 h1:GP3Q+LAs7Uwf1ZXogOyq7bG4v0A7ROtuU2UKBzIxLK0= +github.com/tombuildsstuff/giovanni v0.25.1/go.mod h1:U5QCrP5ATt9csJfaceJaqV96ZDCn1yWLhzw04oIaYE8= github.com/tombuildsstuff/kermit v0.20240122.1123108 h1:icQaxsv/ANv/KC4Sr0V1trrWA/XIL+3QAVBDpiSTgj8= github.com/tombuildsstuff/kermit v0.20240122.1123108/go.mod h1:T3YBVFhRV4qA7SbnRaNE6eapIMpKDA9rG/V7Ocsjlno= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -267,9 +246,6 @@ github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgr golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= diff --git a/vendor/github.com/google/uuid/CHANGELOG.md b/vendor/github.com/google/uuid/CHANGELOG.md index 2bd78667afbb..7ed347d3ad73 100644 --- a/vendor/github.com/google/uuid/CHANGELOG.md +++ b/vendor/github.com/google/uuid/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26) + + +### Features + +* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4)) + +### Fixes + +* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior) + ## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18) diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md index 5566888726d9..a502fdc515ac 100644 --- a/vendor/github.com/google/uuid/CONTRIBUTING.md +++ b/vendor/github.com/google/uuid/CONTRIBUTING.md @@ -11,7 +11,7 @@ please explain why in the pull request description. ### Releasing -Commits that would precipitate a SemVer change, as desrcibed in the Conventional +Commits that would precipitate a SemVer change, as described in the Conventional Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action) to create a release candidate pull request. Once submitted, `release-please` will create a release. diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index a56138cc4bd0..dc75f7d99091 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -56,11 +56,15 @@ func IsInvalidLengthError(err error) bool { return ok } -// Parse decodes s into a UUID or returns an error. Both the standard UUID -// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the -// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex -// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. +// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both +// the standard UUID forms defined in RFC 4122 +// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition, +// Parse accepts non-standard strings such as the raw hex encoding +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings, +// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are +// examined in the latter case. Parse should not be used to validate strings as +// it parses non-standard encodings as indicated above. func Parse(s string) (UUID, error) { var uuid UUID switch len(s) { @@ -294,3 +298,15 @@ func DisableRandPool() { poolMu.Lock() poolPos = randPoolSize } + +// UUIDs is a slice of UUID types. +type UUIDs []UUID + +// Strings returns a string slice containing the string form of each UUID in uuids. +func (uuids UUIDs) Strings() []string { + var uuidStrs = make([]string, len(uuids)) + for i, uuid := range uuids { + uuidStrs[i] = uuid.String() + } + return uuidStrs +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/client.go b/vendor/github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/client.go new file mode 100644 index 000000000000..5e0dd27d9f07 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/client.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package dataplane + +import ( + "github.com/hashicorp/go-azure-sdk/sdk/client" +) + +var _ client.BaseClient = &Client{} + +type Client struct { + *client.Client + + // ApiVersion specifies the version of the API being used, which (by design) will be consistent across a client + // as we intentionally split out multiple API Versions into different clients, rather than using composite API + // Versions/packages which can cause confusion about which version is being used. + ApiVersion string +} + +func NewDataPlaneClient(baseUri string, serviceName, apiVersion string) *Client { + client := &Client{ + Client: client.NewClient(baseUri, serviceName, apiVersion), + ApiVersion: apiVersion, + } + return client +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage/client.go b/vendor/github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage/client.go new file mode 100644 index 000000000000..27dedf17c000 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage/client.go @@ -0,0 +1,73 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package storage + +import ( + "context" + "fmt" + "net/url" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane" +) + +var _ client.BaseClient = &Client{} + +var storageDefaultRetryFunctions = []client.RequestRetryFunc{ + // TODO: stuff n tings +} + +type Client struct { + *dataplane.Client +} + +func NewStorageClient(baseUri string, componentName, apiVersion string) (*Client, error) { + // NOTE: both the domain name _and_ the domain format can change entirely depending on the type of storage account being used + // when provisioned in an edge zone, and when AzureDNSZone is used, as such we require the baseUri is provided here + return &Client{ + Client: dataplane.NewDataPlaneClient(baseUri, fmt.Sprintf("storage/%s", componentName), apiVersion), + }, nil +} + +func (c *Client) NewRequest(ctx context.Context, input client.RequestOptions) (*client.Request, error) { + // TODO move these validations to base client method + if _, ok := ctx.Deadline(); !ok { + return nil, fmt.Errorf("internal-error: the context used must have a deadline attached for polling purposes, but got no deadline") + } + if err := input.Validate(); err != nil { + return nil, fmt.Errorf("internal-error: pre-validating request payload: %+v", err) + } + + req, err := c.Client.Client.NewRequest(ctx, input) + if err != nil { + return nil, fmt.Errorf("building %s request: %+v", input.HttpMethod, err) + } + + req.Client = c + req.Header.Add("x-ms-version", c.Client.ApiVersion) + + query := url.Values{} + if input.OptionsObject != nil { + if h := input.OptionsObject.ToHeaders(); h != nil { + for k, v := range h.Headers() { + req.Header[k] = v + } + } + + if q := input.OptionsObject.ToQuery(); q != nil { + query = q.Values() + } + + if o := input.OptionsObject.ToOData(); o != nil { + req.Header = o.AppendHeaders(req.Header) + query = o.AppendValues(query) + } + } + + req.URL.RawQuery = query.Encode() + req.RetryFunc = client.RequestRetryAny(append(storageDefaultRetryFunctions, input.RetryFunc)...) + req.ValidStatusCodes = input.ExpectedStatusCodes + + return req, nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/README.md index 5fa24a74e9bb..fd69cf79e810 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/README.md @@ -16,7 +16,6 @@ import ( "fmt" "time" - "github.com/Azure/go-autorest/autorest" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/client.go index 0162ebbb0c33..df5fa1d722ea 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/client.go @@ -1,25 +1,22 @@ package accounts import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for Blob Storage Blobs. type Client struct { - autorest.Client - BaseURI string -} - -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) + Client *storage.Client } -// NewWithBaseURI creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/get_service_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/get_service_properties.go index e622fff3ba46..0c9a51a41117 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/get_service_properties.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/get_service_properties.go @@ -2,82 +2,47 @@ package accounts import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) type GetServicePropertiesResult struct { - autorest.Response - - ContentType string - StorageServiceProperties *StorageServiceProperties -} - -// GetServicePropertiesPreparer prepares the GetServiceProperties request. -func (client Client) GetServicePropertiesPreparer(ctx context.Context, accountName string) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "restype": "service", - "comp": "properties", - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -func (client Client) GetServicePropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) + HttpResponse *client.Response + Model *StorageServiceProperties } -func (client Client) GetServicePropertiesResponder(resp *http.Response) (result GetServicePropertiesResult, err error) { - if resp != nil && resp.Header != nil { - result.ContentType = resp.Header.Get("Content-Type") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result.StorageServiceProperties), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -func (client Client) GetServiceProperties(ctx context.Context, accountName string) (result GetServicePropertiesResult, err error) { +func (c Client) GetServiceProperties(ctx context.Context, accountName string) (resp GetServicePropertiesResult, err error) { if accountName == "" { - return result, validation.NewError("accounts.Client", "GetServiceProperties", "`accountName` cannot be an empty string.") + return resp, fmt.Errorf("`accountName` cannot be an empty string") } - req, err := client.GetServicePropertiesPreparer(ctx, accountName) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: servicePropertiesOptions{}, + Path: "/", + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "accounts.Client", "GetServiceProperties", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - - resp, err := client.GetServicePropertiesSender(req) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "accounts.Client", "GetServiceProperties", resp, "Failure sending request") + err = fmt.Errorf("executing request: %+v", err) return } - result, err = client.GetServicePropertiesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "accounts.Client", "GetServiceProperties", resp, "Failure responding to request") - return + if resp.HttpResponse != nil { + if err = resp.HttpResponse.Unmarshal(&resp.Model); err != nil { + err = fmt.Errorf("unmarshaling response: %+v", err) + return + } } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/models.go index 3a2891439bee..c36d45ecb8c5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/models.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/models.go @@ -1,11 +1,5 @@ package accounts -import "github.com/Azure/go-autorest/autorest" - -type SetServicePropertiesResult struct { - autorest.Response -} - type StorageServiceProperties struct { // Cors - Specifies CORS rules for the Blob service. You can include up to five CorsRule elements in the request. If no CorsRule elements are included in the request body, all CORS rules will be deleted, and CORS will be disabled for the Blob service. Cors *CorsRules `xml:"Cors,omitempty"` diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/resource_id.go new file mode 100644 index 000000000000..e6c6303f9f79 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/resource_id.go @@ -0,0 +1,155 @@ +package accounts + +import ( + "fmt" + "net/url" + "strings" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type SubDomainType string + +const ( + BlobSubDomainType SubDomainType = "blob" + DataLakeStoreSubDomainType SubDomainType = "dfs" + FileSubDomainType SubDomainType = "file" + QueueSubDomainType SubDomainType = "queue" + TableSubDomainType SubDomainType = "table" +) + +func PossibleValuesForSubDomainType() []SubDomainType { + return []SubDomainType{ + BlobSubDomainType, + DataLakeStoreSubDomainType, + FileSubDomainType, + QueueSubDomainType, + TableSubDomainType, + } +} + +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = AccountId{} + +type AccountId struct { + AccountName string + ZoneName *string + SubDomainType SubDomainType + DomainSuffix string + IsEdgeZone bool +} + +func (a AccountId) ID() string { + components := []string{ + a.AccountName, + } + if a.IsEdgeZone { + // Storage Accounts hosted in an Edge Zone + // `{accountname}.{component}.{edgezone}.edgestorage.azure.net` + components = append(components, string(a.SubDomainType)) + if a.ZoneName != nil { + components = append(components, *a.ZoneName) + } + } else { + // Storage Accounts using a DNS Zone + // `{accountname}.{dnszone}.{component}.storage.azure.net` + // or a Regular Storage Account + // `{accountname}.{component}.core.windows.net` + if a.ZoneName != nil { + components = append(components, *a.ZoneName) + } + components = append(components, string(a.SubDomainType)) + } + components = append(components, a.DomainSuffix) + return fmt.Sprintf("https://%s", strings.Join(components, ".")) +} + +func (a AccountId) String() string { + components := []string{ + fmt.Sprintf("IsEdgeZone %t", a.IsEdgeZone), + fmt.Sprintf("ZoneName %q", pointer.From(a.ZoneName)), + fmt.Sprintf("Subdomain Type %q", string(a.SubDomainType)), + fmt.Sprintf("DomainSuffix %q", a.DomainSuffix), + } + return fmt.Sprintf("Account %q (%s)", a.AccountName, strings.Join(components, " / ")) +} + +func ParseAccountID(input, domainSuffix string) (*AccountId, error) { + uri, err := url.Parse(input) + if err != nil { + return nil, fmt.Errorf("parsing %q as a URL: %s", input, err) + } + + if !strings.HasSuffix(uri.Host, domainSuffix) { + return nil, fmt.Errorf("expected the account %q to use a domain suffix of %q", uri.Host, domainSuffix) + } + + // There's 3 different types of Storage Account ID: + // 1. Regular ol' Storage Accounts + // `{name}.{component}.core.windows.net` (e.g. `example1.blob.core.windows.net`) + // 2. Storage Accounts using a DNS Zone + // `{accountname}.{dnszone}.{component}.storage.azure.net` + // 3. Storage Accounts hosted in an Edge Zone + // `{accountname}.{component}.{edgezone}.edgestorage.azure.net` + // since both `dnszone` and `edgezone` are the only two identifiers, we need to check if `domainSuffix` includes `edge` + // to know how to treat these + + hostName := strings.TrimSuffix(uri.Host, fmt.Sprintf(".%s", domainSuffix)) + components := strings.Split(hostName, ".") + accountId := AccountId{ + DomainSuffix: domainSuffix, + IsEdgeZone: strings.Contains(strings.ToLower(domainSuffix), "edge"), + } + + if len(components) == 2 { + // this will be a regular Storage Account (e.g. `example1.blob.core.windows.net`) + accountId.AccountName = components[0] + subDomainType, err := parseSubDomainType(components[1]) + if err != nil { + return nil, err + } + accountId.SubDomainType = *subDomainType + return &accountId, nil + } + + if len(components) == 3 { + // This can either be a Zone'd Storage Account or a Storage Account within an Edge Zone + accountName := "" + subDomainTypeRaw := "" + zone := "" + if accountId.IsEdgeZone { + // `{accountname}.{component}.{edgezone}.edgestorage.azure.net` + accountName = components[0] + subDomainTypeRaw = components[1] + zone = components[2] + } else { + // `{accountname}.{dnszone}.{component}.storage.azure.net` + accountName = components[0] + zone = components[1] + subDomainTypeRaw = components[2] + } + + accountId.AccountName = accountName + subDomainType, err := parseSubDomainType(subDomainTypeRaw) + if err != nil { + return nil, err + } + accountId.SubDomainType = *subDomainType + accountId.ZoneName = pointer.To(zone) + return &accountId, nil + } + + return nil, fmt.Errorf("unknown storage account domain type %q", input) +} + +func parseSubDomainType(input string) (*SubDomainType, error) { + for _, k := range PossibleValuesForSubDomainType() { + if strings.EqualFold(input, string(k)) { + return pointer.To(k), nil + } + } + + return nil, fmt.Errorf("expected the subdomain type to be one of [%+v] but got %q", PossibleValuesForSubDomainType(), input) +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/service_properties_shared.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/service_properties_shared.go new file mode 100644 index 000000000000..3019155f9183 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/service_properties_shared.go @@ -0,0 +1,26 @@ +package accounts + +import ( + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +var _ client.Options = servicePropertiesOptions{} + +type servicePropertiesOptions struct { +} + +func (servicePropertiesOptions) ToHeaders() *client.Headers { + return nil +} + +func (servicePropertiesOptions) ToOData() *odata.Query { + return nil +} + +func (servicePropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "properties") + out.Append("restype", "service") + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/set_service_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/set_service_properties.go index 17b7bcc7e763..0be703217d99 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/set_service_properties.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/set_service_properties.go @@ -2,74 +2,42 @@ package accounts import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) -// SetServicePropertiesSender sends the SetServiceProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetServicePropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +type SetServicePropertiesResult struct { + HttpResponse *client.Response } -// SetServicePropertiesPreparer prepares the SetServiceProperties request. -func (client Client) SetServicePropertiesPreparer(ctx context.Context, accountName string, input StorageServiceProperties) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "restype": "service", - "comp": "properties", - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithHeaders(headers), - autorest.WithXML(input), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// SetServicePropertiesResponder handles the response to the SetServiceProperties request. The method always -// closes the http.Response Body. -func (client Client) SetServicePropertiesResponder(resp *http.Response) (result SetServicePropertiesResult, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -func (client Client) SetServiceProperties(ctx context.Context, accountName string, input StorageServiceProperties) (result SetServicePropertiesResult, err error) { +func (c Client) SetServiceProperties(ctx context.Context, accountName string, input StorageServiceProperties) (resp SetServicePropertiesResult, err error) { if accountName == "" { - return result, validation.NewError("accounts.Client", "SetServiceProperties", "`accountName` cannot be an empty string.") + return resp, fmt.Errorf("`accountName` cannot be an empty string") } - req, err := client.SetServicePropertiesPreparer(ctx, accountName, input) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: servicePropertiesOptions{}, + Path: "/", + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "accounts.Client", "SetServiceProperties", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - - resp, err := client.SetServicePropertiesSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "accounts.Client", "SetServiceProperties", resp, "Failure sending request") + if err = req.Marshal(&input); err != nil { + err = fmt.Errorf("marshaling request: %+v", err) return } - - result, err = client.SetServicePropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "accounts.Client", "SetServiceProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/version.go index 3d6d01147003..d575c4f40957 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/version.go @@ -1,14 +1,4 @@ package accounts -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - -// APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "blob/accounts" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md index 19218cf9fd85..aa5ebd16da14 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md @@ -17,7 +17,7 @@ import ( "fmt" "time" - "github.com/Azure/go-autorest/autorest" + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" ) @@ -25,18 +25,26 @@ func Example() error { accountName := "storageaccount1" storageAccountKey := "ABC123...." containerName := "mycontainer" + domainSuffix := "core.windows.net" fileName := "example-large-file.iso" - - storageAuth := autorest.NewSharedKeyLiteAuthorizer(accountName, storageAccountKey) - blobClient := blobs.New() - blobClient.Client.Authorizer = storageAuth + + blobClient, err := blobs.NewWithBaseUri(fmt.Sprintf("https://%s.blob.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building client for environment: %+v", err) + } + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + blobClient.Client.SetAuthorizer(auth) ctx := context.TODO() copyInput := blobs.CopyInput{ CopySource: "http://releases.ubuntu.com/14.04/ubuntu-14.04.6-desktop-amd64.iso", } refreshInterval := 5 * time.Second - if err := blobClient.CopyAndWait(ctx, accountName, containerName, fileName, copyInput, refreshInterval); err != nil { + if err := blobClient.CopyAndWait(ctx, containerName, fileName, copyInput, refreshInterval); err != nil { return fmt.Errorf("Error copying: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/api.go index 7e4f6494c2d1..167240825039 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/api.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/api.go @@ -3,43 +3,39 @@ package blobs import ( "context" "os" - "time" - - "github.com/Azure/go-autorest/autorest" ) type StorageBlob interface { - AppendBlock(ctx context.Context, accountName, containerName, blobName string, input AppendBlockInput) (result AppendBlockResult, err error) - Copy(ctx context.Context, accountName, containerName, blobName string, input CopyInput) (result CopyResult, err error) - AbortCopy(ctx context.Context, accountName, containerName, blobName string, input AbortCopyInput) (result autorest.Response, err error) - CopyAndWait(ctx context.Context, accountName, containerName, blobName string, input CopyInput, pollingInterval time.Duration) error - Delete(ctx context.Context, accountName, containerName, blobName string, input DeleteInput) (result autorest.Response, err error) - DeleteSnapshot(ctx context.Context, accountName, containerName, blobName string, input DeleteSnapshotInput) (result autorest.Response, err error) - DeleteSnapshots(ctx context.Context, accountName, containerName, blobName string, input DeleteSnapshotsInput) (result autorest.Response, err error) - Get(ctx context.Context, accountName, containerName, blobName string, input GetInput) (result GetResult, err error) - GetBlockList(ctx context.Context, accountName, containerName, blobName string, input GetBlockListInput) (result GetBlockListResult, err error) - GetPageRanges(ctx context.Context, accountName, containerName, blobName string, input GetPageRangesInput) (result GetPageRangesResult, err error) - IncrementalCopyBlob(ctx context.Context, accountName, containerName, blobName string, input IncrementalCopyBlobInput) (result autorest.Response, err error) - AcquireLease(ctx context.Context, accountName, containerName, blobName string, input AcquireLeaseInput) (result AcquireLeaseResult, err error) - BreakLease(ctx context.Context, accountName, containerName, blobName string, input BreakLeaseInput) (result autorest.Response, err error) - ChangeLease(ctx context.Context, accountName, containerName, blobName string, input ChangeLeaseInput) (result ChangeLeaseResponse, err error) - ReleaseLease(ctx context.Context, accountName, containerName, blobName, leaseID string) (result autorest.Response, err error) - RenewLease(ctx context.Context, accountName, containerName, blobName, leaseID string) (result autorest.Response, err error) - SetMetaData(ctx context.Context, accountName, containerName, blobName string, input SetMetaDataInput) (result autorest.Response, err error) - GetProperties(ctx context.Context, accountName, containerName, blobName string, input GetPropertiesInput) (result GetPropertiesResult, err error) - SetProperties(ctx context.Context, accountName, containerName, blobName string, input SetPropertiesInput) (result SetPropertiesResult, err error) - PutAppendBlob(ctx context.Context, accountName, containerName, blobName string, input PutAppendBlobInput) (result autorest.Response, err error) - PutBlock(ctx context.Context, accountName, containerName, blobName string, input PutBlockInput) (result PutBlockResult, err error) - PutBlockBlob(ctx context.Context, accountName, containerName, blobName string, input PutBlockBlobInput) (result autorest.Response, err error) - PutBlockBlobFromFile(ctx context.Context, accountName, containerName, blobName string, file *os.File, input PutBlockBlobInput) error - PutBlockList(ctx context.Context, accountName, containerName, blobName string, input PutBlockListInput) (result PutBlockListResult, err error) - PutBlockFromURL(ctx context.Context, accountName, containerName, blobName string, input PutBlockFromURLInput) (result PutBlockFromURLResult, err error) - PutPageBlob(ctx context.Context, accountName, containerName, blobName string, input PutPageBlobInput) (result autorest.Response, err error) - PutPageClear(ctx context.Context, accountName, containerName, blobName string, input PutPageClearInput) (result autorest.Response, err error) - PutPageUpdate(ctx context.Context, accountName, containerName, blobName string, input PutPageUpdateInput) (result PutPageUpdateResult, err error) - GetResourceID(accountName, containerName, blobName string) string - SetTier(ctx context.Context, accountName, containerName, blobName string, tier AccessTier) (result autorest.Response, err error) - Snapshot(ctx context.Context, accountName, containerName, blobName string, input SnapshotInput) (result SnapshotResult, err error) - GetSnapshotProperties(ctx context.Context, accountName, containerName, blobName string, input GetSnapshotPropertiesInput) (result GetPropertiesResult, err error) - Undelete(ctx context.Context, accountName, containerName, blobName string) (result autorest.Response, err error) + AppendBlock(ctx context.Context, containerName string, blobName string, input AppendBlockInput) (AppendBlockResponse, error) + Copy(ctx context.Context, containerName string, blobName string, input CopyInput) (CopyResponse, error) + AbortCopy(ctx context.Context, containerName string, blobName string, input AbortCopyInput) (CopyAbortResponse, error) + CopyAndWait(ctx context.Context, containerName string, blobName string, input CopyInput) error + Delete(ctx context.Context, containerName string, blobName string, input DeleteInput) (DeleteResponse, error) + DeleteSnapshot(ctx context.Context, containerName string, blobName string, input DeleteSnapshotInput) (DeleteSnapshotResponse, error) + DeleteSnapshots(ctx context.Context, containerName string, blobName string, input DeleteSnapshotsInput) (DeleteSnapshotsResponse, error) + Get(ctx context.Context, containerName string, blobName string, input GetInput) (GetResponse, error) + GetBlockList(ctx context.Context, containerName string, blobName string, input GetBlockListInput) (GetBlockListResponse, error) + GetPageRanges(ctx context.Context, containerName, blobName string, input GetPageRangesInput) (GetPageRangesResponse, error) + IncrementalCopyBlob(ctx context.Context, containerName string, blobName string, input IncrementalCopyBlobInput) (IncrementalCopyBlob, error) + AcquireLease(ctx context.Context, containerName string, blobName string, input AcquireLeaseInput) (AcquireLeaseResponse, error) + BreakLease(ctx context.Context, containerName string, blobName string, input BreakLeaseInput) (BreakLeaseResponse, error) + ChangeLease(ctx context.Context, containerName string, blobName string, input ChangeLeaseInput) (ChangeLeaseResponse, error) + ReleaseLease(ctx context.Context, containerName string, blobName string, input ReleaseLeaseInput) (ReleaseLeaseResponse, error) + RenewLease(ctx context.Context, containerName string, blobName string, input RenewLeaseInput) (RenewLeaseResponse, error) + SetMetaData(ctx context.Context, containerName string, blobName string, input SetMetaDataInput) (SetMetaDataResponse, error) + GetProperties(ctx context.Context, containerName string, blobName string, input GetPropertiesInput) (GetPropertiesResponse, error) + SetProperties(ctx context.Context, containerName string, blobName string, input SetPropertiesInput) (SetPropertiesResponse, error) + PutAppendBlob(ctx context.Context, containerName string, blobName string, input PutAppendBlobInput) (PutAppendBlobResponse, error) + PutBlock(ctx context.Context, containerName string, blobName string, input PutBlockInput) (PutBlockResponse, error) + PutBlockBlob(ctx context.Context, containerName string, blobName string, input PutBlockBlobInput) (PutBlockBlobResponse, error) + PutBlockBlobFromFile(ctx context.Context, containerName string, blobName string, file *os.File, input PutBlockBlobInput) error + PutBlockList(ctx context.Context, containerName string, blobName string, input PutBlockListInput) (PutBlockListResponse, error) + PutBlockFromURL(ctx context.Context, containerName string, blobName string, input PutBlockFromURLInput) (PutBlockFromURLResponse, error) + PutPageBlob(ctx context.Context, containerName string, blobName string, input PutPageBlobInput) (PutPageBlobResponse, error) + PutPageClear(ctx context.Context, containerName string, blobName string, input PutPageClearInput) (PutPageClearResponse, error) + PutPageUpdate(ctx context.Context, containerName string, blobName string, input PutPageUpdateInput) (PutPageUpdateResponse, error) + SetTier(ctx context.Context, containerName string, blobName string, input SetTierInput) (SetTierResponse, error) + Snapshot(ctx context.Context, containerName string, blobName string, input SnapshotInput) (SnapshotResponse, error) + GetSnapshotProperties(ctx context.Context, containerName string, blobName string, input GetSnapshotPropertiesInput) (GetPropertiesResponse, error) + Undelete(ctx context.Context, containerName string, blobName string) (UndeleteResponse, error) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go index b7705c202518..a1068d459c5c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go @@ -1,16 +1,16 @@ package blobs import ( + "bytes" "context" "fmt" + "io" "net/http" "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type AppendBlockInput struct { @@ -45,8 +45,8 @@ type AppendBlockInput struct { LeaseID *string } -type AppendBlockResult struct { - autorest.Response +type AppendBlockResponse struct { + HttpResponse *client.Response BlobAppendOffset string BlobCommittedBlockCount int64 @@ -56,125 +56,105 @@ type AppendBlockResult struct { } // AppendBlock commits a new block of data to the end of an existing append blob. -func (client Client) AppendBlock(ctx context.Context, accountName, containerName, blobName string, input AppendBlockInput) (result AppendBlockResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "AppendBlock", "`accountName` cannot be an empty string.") - } +func (c Client) AppendBlock(ctx context.Context, containerName, blobName string, input AppendBlockInput) (resp AppendBlockResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "AppendBlock", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "AppendBlock", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "AppendBlock", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.Content != nil && len(*input.Content) > (4*1024*1024) { - return result, validation.NewError("files.Client", "PutByteRange", "`input.Content` must be at most 4MB.") + return resp, fmt.Errorf("`input.Content` must be at most 4MB") } - req, err := client.AppendBlockPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "AppendBlock", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: appendBlockOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.AppendBlockSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "AppendBlock", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.AppendBlockResponder(resp) + if input.Content != nil { + req.Body = io.NopCloser(bytes.NewReader(*input.Content)) + } + + req.ContentLength = int64(len(*input.Content)) + + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "AppendBlock", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.BlobAppendOffset = resp.HttpResponse.Header.Get("x-ms-blob-append-offset") + resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") + resp.ETag = resp.HttpResponse.Header.Get("ETag") + resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") + + if v := resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count"); v != "" { + i, innerErr := strconv.Atoi(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + return + } + resp.BlobCommittedBlockCount = int64(i) + } -// AppendBlockPreparer prepares the AppendBlock request. -func (client Client) AppendBlockPreparer(ctx context.Context, accountName, containerName, blobName string, input AppendBlockInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), + } } - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "appendblock"), - } + return +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type appendBlockOptions struct { + input AppendBlockInput +} - if input.BlobConditionAppendPosition != nil { - headers["x-ms-blob-condition-appendpos"] = *input.BlobConditionAppendPosition +func (a appendBlockOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if a.input.BlobConditionAppendPosition != nil { + headers.Append("x-ms-blob-condition-appendpos", strconv.Itoa(int(*a.input.BlobConditionAppendPosition))) } - if input.BlobConditionMaxSize != nil { - headers["x-ms-blob-condition-maxsize"] = *input.BlobConditionMaxSize + if a.input.BlobConditionMaxSize != nil { + headers.Append("x-ms-blob-condition-maxsize", strconv.Itoa(int(*a.input.BlobConditionMaxSize))) } - if input.ContentMD5 != nil { - headers["x-ms-blob-content-md5"] = *input.ContentMD5 + if a.input.ContentMD5 != nil { + headers.Append("x-ms-blob-content-md5", *a.input.ContentMD5) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID - } - if input.Content != nil { - headers["Content-Length"] = int(len(*input.Content)) + if a.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *a.input.LeaseID) } - - decorators := []autorest.PrepareDecorator{ - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers), - } - - if input.Content != nil { - decorators = append(decorators, autorest.WithBytes(input.Content)) + if a.input.Content != nil { + headers.Append("Content-Length", strconv.Itoa(len(*a.input.Content))) } - - preparer := autorest.CreatePreparer(decorators...) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// AppendBlockSender sends the AppendBlock request. The method will close the -// http.Response Body if it receives an error. -func (client Client) AppendBlockSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (a appendBlockOptions) ToOData() *odata.Query { + return nil } -// AppendBlockResponder handles the response to the AppendBlock request. The method always -// closes the http.Response Body. -func (client Client) AppendBlockResponder(resp *http.Response) (result AppendBlockResult, err error) { - if resp != nil && resp.Header != nil { - result.BlobAppendOffset = resp.Header.Get("x-ms-blob-append-offset") - result.ContentMD5 = resp.Header.Get("ETag") - result.ETag = resp.Header.Get("ETag") - result.LastModified = resp.Header.Get("Last-Modified") - - if v := resp.Header.Get("x-ms-blob-committed-block-count"); v != "" { - i, innerErr := strconv.Atoi(v) - if innerErr != nil { - err = fmt.Errorf("Error parsing %q as an integer: %s", v, innerErr) - return - } - - result.BlobCommittedBlockCount = int64(i) - } - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (a appendBlockOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "appendblock") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/client.go index db20391922bb..4bb762b5d18c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/client.go @@ -1,25 +1,22 @@ package blobs import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for Blob Storage Blobs. type Client struct { - autorest.Client - BaseURI string -} - -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) + Client *storage.Client } -// NewWithBaseURI creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go index febaab5f9a91..2ff309cc75da 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -106,130 +105,126 @@ type CopyInput struct { SourceIfUnmodifiedSince *string } -type CopyResult struct { - autorest.Response +type CopyResponse struct { + HttpResponse *client.Response CopyID string CopyStatus string } // Copy copies a blob to a destination within the storage account asynchronously. -func (client Client) Copy(ctx context.Context, accountName, containerName, blobName string, input CopyInput) (result CopyResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "Copy", "`accountName` cannot be an empty string.") - } +func (c Client) Copy(ctx context.Context, containerName, blobName string, input CopyInput) (resp CopyResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "Copy", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "Copy", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "Copy", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.CopySource == "" { - return result, validation.NewError("blobs.Client", "Copy", "`input.CopySource` cannot be an empty string.") + return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") } - req, err := client.CopyPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Copy", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: copyOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.CopySender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "Copy", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.CopyResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Copy", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") + resp.CopyStatus = resp.HttpResponse.Header.Get("x-ms-copy-status") + } + } + return } -// CopyPreparer prepares the Copy request. -func (client Client) CopyPreparer(ctx context.Context, accountName, containerName, blobName string, input CopyInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type copyOptions struct { + input CopyInput +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-copy-source": autorest.Encode("header", input.CopySource), - } +func (c copyOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-copy-source", c.input.CopySource) - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if c.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *c.input.LeaseID) } - if input.SourceLeaseID != nil { - headers["x-ms-source-lease-id"] = *input.SourceLeaseID + + if c.input.SourceLeaseID != nil { + headers.Append("x-ms-source-lease-id", *c.input.SourceLeaseID) } - if input.AccessTier != nil { - headers["x-ms-access-tier"] = string(*input.AccessTier) + + if c.input.AccessTier != nil { + headers.Append("x-ms-access-tier", string(*c.input.AccessTier)) } - if input.IfMatch != nil { - headers["If-Match"] = *input.IfMatch + if c.input.IfMatch != nil { + headers.Append("If-Match", *c.input.IfMatch) } - if input.IfNoneMatch != nil { - headers["If-None-Match"] = *input.IfNoneMatch + + if c.input.IfNoneMatch != nil { + headers.Append("If-None-Match", *c.input.IfNoneMatch) } - if input.IfUnmodifiedSince != nil { - headers["If-Unmodified-Since"] = *input.IfUnmodifiedSince + + if c.input.IfUnmodifiedSince != nil { + headers.Append("If-Unmodified-Since", *c.input.IfUnmodifiedSince) } - if input.IfModifiedSince != nil { - headers["If-Modified-Since"] = *input.IfModifiedSince + + if c.input.IfModifiedSince != nil { + headers.Append("If-Modified-Since", *c.input.IfModifiedSince) } - if input.SourceIfMatch != nil { - headers["x-ms-source-if-match"] = *input.SourceIfMatch + if c.input.SourceIfMatch != nil { + headers.Append("x-ms-source-if-match", *c.input.SourceIfMatch) } - if input.SourceIfNoneMatch != nil { - headers["x-ms-source-if-none-match"] = *input.SourceIfNoneMatch + + if c.input.SourceIfNoneMatch != nil { + headers.Append("x-ms-source-if-none-match", *c.input.SourceIfNoneMatch) } - if input.SourceIfModifiedSince != nil { - headers["x-ms-source-if-modified-since"] = *input.SourceIfModifiedSince + + if c.input.SourceIfModifiedSince != nil { + headers.Append("x-ms-source-if-modified-since", *c.input.SourceIfModifiedSince) } - if input.SourceIfUnmodifiedSince != nil { - headers["x-ms-source-if-unmodified-since"] = *input.SourceIfUnmodifiedSince + + if c.input.SourceIfUnmodifiedSince != nil { + headers.Append("x-ms-source-if-unmodified-since", *c.input.SourceIfUnmodifiedSince) } - headers = metadata.SetIntoHeaders(headers, input.MetaData) + headers.Merge(metadata.SetMetaDataHeaders(c.input.MetaData)) - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// CopySender sends the Copy request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CopySender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c copyOptions) ToOData() *odata.Query { + return nil } -// CopyResponder handles the response to the Copy request. The method always -// closes the http.Response Body. -func (client Client) CopyResponder(resp *http.Response) (result CopyResult, err error) { - if resp != nil && resp.Header != nil { - result.CopyID = resp.Header.Get("x-ms-copy-id") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return +func (c copyOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go index a992ff199bb1..064c56f09ab8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type AbortCopyInput struct { @@ -20,91 +19,76 @@ type AbortCopyInput struct { LeaseID *string } +type CopyAbortResponse struct { + HttpResponse *client.Response +} + // AbortCopy aborts a pending Copy Blob operation, and leaves a destination blob with zero length and full metadata. -func (client Client) AbortCopy(ctx context.Context, accountName, containerName, blobName string, input AbortCopyInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "AbortCopy", "`accountName` cannot be an empty string.") - } +func (c Client) AbortCopy(ctx context.Context, containerName, blobName string, input AbortCopyInput) (resp CopyAbortResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "AbortCopy", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "AbortCopy", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "AbortCopy", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.CopyID == "" { - return result, validation.NewError("blobs.Client", "AbortCopy", "`input.CopyID` cannot be an empty string.") + return resp, fmt.Errorf("`input.CopyID` cannot be an empty string") } - req, err := client.AbortCopyPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "AbortCopy", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodPut, + OptionsObject: copyAbortOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.AbortCopySender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "AbortCopy", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.AbortCopyResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "AbortCopy", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// AbortCopyPreparer prepares the AbortCopy request. -func (client Client) AbortCopyPreparer(ctx context.Context, accountName, containerName, blobName string, input AbortCopyInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "copy"), - "copyid": autorest.Encode("query", input.CopyID), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-copy-action": "abort", - } +type copyAbortOptions struct { + input AbortCopyInput +} - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID +func (c copyAbortOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-copy-action", "abort") + if c.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *c.input.LeaseID) } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// AbortCopySender sends the AbortCopy request. The method will close the -// http.Response Body if it receives an error. -func (client Client) AbortCopySender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c copyAbortOptions) ToOData() *odata.Query { + return nil } -// AbortCopyResponder handles the response to the AbortCopy request. The method always -// closes the http.Response Body. -func (client Client) AbortCopyResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return +func (c copyAbortOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "copy") + out.Append("copyid", c.input.CopyID) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait.go index a1e7fa453dc0..5ec7c239fe32 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait.go @@ -4,38 +4,25 @@ import ( "context" "fmt" "time" + + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" ) // CopyAndWait copies a blob to a destination within the storage account and waits for it to finish copying. -func (client Client) CopyAndWait(ctx context.Context, accountName, containerName, blobName string, input CopyInput, pollingInterval time.Duration) error { - if _, err := client.Copy(ctx, accountName, containerName, blobName, input); err != nil { - return fmt.Errorf("Error copying: %s", err) +func (c Client) CopyAndWait(ctx context.Context, containerName, blobName string, input CopyInput) error { + if _, err := c.Copy(ctx, containerName, blobName, input); err != nil { + return fmt.Errorf("error copying: %s", err) } - for true { - getInput := GetPropertiesInput{ - LeaseID: input.LeaseID, - } - getResult, err := client.GetProperties(ctx, accountName, containerName, blobName, getInput) - if err != nil { - return fmt.Errorf("") - } - - switch getResult.CopyStatus { - case Aborted: - return fmt.Errorf("Copy was aborted: %s", getResult.CopyStatusDescription) - - case Failed: - return fmt.Errorf("Copy failed: %s", getResult.CopyStatusDescription) - - case Success: - return nil + getInput := GetPropertiesInput{ + LeaseID: input.LeaseID, + } - case Pending: - time.Sleep(pollingInterval) - continue - } + pollerType := NewCopyAndWaitPoller(&c, containerName, blobName, getInput) + poller := pollers.NewPoller(pollerType, 10*time.Second, pollers.DefaultNumberOfDroppedConnectionsToAllow) + if err := poller.PollUntilDone(ctx); err != nil { + return fmt.Errorf("waiting for file to copy: %+v", err) } - return fmt.Errorf("Unexpected error waiting for the copy to complete") + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait_poller.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait_poller.go new file mode 100644 index 000000000000..313f4863206e --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait_poller.go @@ -0,0 +1,48 @@ +package blobs + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" +) + +var _ pollers.PollerType = ©AndWaitPoller{} + +func NewCopyAndWaitPoller(client *Client, containerName, blobName string, getPropertiesInput GetPropertiesInput) *copyAndWaitPoller { + return ©AndWaitPoller{ + client: client, + containerName: containerName, + blobName: blobName, + getPropertiesInput: getPropertiesInput, + } +} + +type copyAndWaitPoller struct { + client *Client + containerName string + blobName string + getPropertiesInput GetPropertiesInput +} + +func (p *copyAndWaitPoller) Poll(ctx context.Context) (*pollers.PollResult, error) { + props, err := p.client.GetProperties(ctx, p.containerName, p.blobName, p.getPropertiesInput) + if err != nil { + return nil, fmt.Errorf("retrieving properties (container: %s blob: %s) : %+v", p.containerName, p.blobName, err) + } + + if strings.EqualFold(string(props.CopyStatus), string(Success)) { + return &pollers.PollResult{ + Status: pollers.PollingStatusSucceeded, + PollInterval: 10 * time.Second, + }, nil + } + + // Processing + return &pollers.PollResult{ + Status: pollers.PollingStatusInProgress, + PollInterval: 10 * time.Second, + }, nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go index c1c642d7d781..e13aaa599fe6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type DeleteInput struct { @@ -21,85 +20,73 @@ type DeleteInput struct { LeaseID *string } +type DeleteResponse struct { + HttpResponse *client.Response +} + // Delete marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. -func (client Client) Delete(ctx context.Context, accountName, containerName, blobName string, input DeleteInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, containerName, blobName string, input DeleteInput) (resp DeleteResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "Delete", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "Delete", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "Delete", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - req, err := client.DeletePreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: deleteOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Delete", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName, containerName, blobName string, input DeleteInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type deleteOptions struct { + input DeleteInput +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +func (d deleteOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if d.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *d.input.LeaseID) } - if input.DeleteSnapshots { - headers["x-ms-delete-snapshots"] = "include" + if d.input.DeleteSnapshots { + headers.Append("x-ms-delete-snapshots", "include") } - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (d deleteOptions) ToOData() *odata.Query { + return nil } -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return +func (d deleteOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go index 18c3d4cffe3f..0407eb1f7829 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type DeleteSnapshotInput struct { @@ -20,89 +19,74 @@ type DeleteSnapshotInput struct { SnapshotDateTime string } +type DeleteSnapshotResponse struct { + HttpResponse *client.Response +} + // DeleteSnapshot marks a single Snapshot of a Blob for Deletion based on it's DateTime, which will be deleted during the next Garbage Collection cycle. -func (client Client) DeleteSnapshot(ctx context.Context, accountName, containerName, blobName string, input DeleteSnapshotInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "DeleteSnapshot", "`accountName` cannot be an empty string.") - } +func (c Client) DeleteSnapshot(ctx context.Context, containerName, blobName string, input DeleteSnapshotInput) (resp DeleteSnapshotResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "DeleteSnapshot", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "DeleteSnapshot", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "DeleteSnapshot", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.SnapshotDateTime == "" { - return result, validation.NewError("blobs.Client", "DeleteSnapshot", "`input.SnapshotDateTime` cannot be an empty string.") + return resp, fmt.Errorf("`input.SnapshotDateTime` cannot be an empty string") } - req, err := client.DeleteSnapshotPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "DeleteSnapshot", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: deleteSnapshotOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.DeleteSnapshotSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "DeleteSnapshot", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteSnapshotResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "DeleteSnapshot", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// DeleteSnapshotPreparer prepares the DeleteSnapshot request. -func (client Client) DeleteSnapshotPreparer(ctx context.Context, accountName, containerName, blobName string, input DeleteSnapshotInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "snapshot": autorest.Encode("query", input.SnapshotDateTime), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type deleteSnapshotOptions struct { + input DeleteSnapshotInput +} - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID +func (d deleteSnapshotOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if d.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *d.input.LeaseID) } - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// DeleteSnapshotSender sends the DeleteSnapshot request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSnapshotSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (d deleteSnapshotOptions) ToOData() *odata.Query { + return nil } -// DeleteSnapshotResponder handles the response to the DeleteSnapshot request. The method always -// closes the http.Response Body. -func (client Client) DeleteSnapshotResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return +func (d deleteSnapshotOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("snapshot", d.input.SnapshotDateTime) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go index e7e2b664d74d..34b3beb623a8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type DeleteSnapshotsInput struct { @@ -17,83 +16,69 @@ type DeleteSnapshotsInput struct { LeaseID *string } +type DeleteSnapshotsResponse struct { + HttpResponse *client.Response +} + // DeleteSnapshots marks all Snapshots of a Blob for Deletion, which will be deleted during the next Garbage Collection Cycle. -func (client Client) DeleteSnapshots(ctx context.Context, accountName, containerName, blobName string, input DeleteSnapshotsInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "DeleteSnapshots", "`accountName` cannot be an empty string.") - } +func (c Client) DeleteSnapshots(ctx context.Context, containerName, blobName string, input DeleteSnapshotsInput) (resp DeleteSnapshotsResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "DeleteSnapshots", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "DeleteSnapshots", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "DeleteSnapshots", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - req, err := client.DeleteSnapshotsPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "DeleteSnapshots", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: deleteSnapshotsOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.DeleteSnapshotsSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "DeleteSnapshots", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteSnapshotsResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "DeleteSnapshots", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// DeleteSnapshotsPreparer prepares the DeleteSnapshots request. -func (client Client) DeleteSnapshotsPreparer(ctx context.Context, accountName, containerName, blobName string, input DeleteSnapshotsInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type deleteSnapshotsOptions struct { + input DeleteSnapshotsInput +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - // only delete the snapshots but leave the blob as-is - "x-ms-delete-snapshots": "only", - } +func (d deleteSnapshotsOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-delete-snapshots", "only") - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if d.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *d.input.LeaseID) } - - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// DeleteSnapshotsSender sends the DeleteSnapshots request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSnapshotsSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (d deleteSnapshotsOptions) ToOData() *odata.Query { + return nil } -// DeleteSnapshotsResponder handles the response to the DeleteSnapshots request. The method always -// closes the http.Response Body. -func (client Client) DeleteSnapshotsResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return +func (d deleteSnapshotsOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go index 7e0d6ee9fbd5..0f5572a8b9c2 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go @@ -6,10 +6,8 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type GetInput struct { @@ -18,99 +16,86 @@ type GetInput struct { EndByte *int64 } -type GetResult struct { - autorest.Response +type GetResponse struct { + HttpResponse *client.Response Contents []byte } // Get reads or downloads a blob from the system, including its metadata and properties. -func (client Client) Get(ctx context.Context, accountName, containerName, blobName string, input GetInput) (result GetResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "Get", "`accountName` cannot be an empty string.") - } +func (c Client) Get(ctx context.Context, containerName, blobName string, input GetInput) (resp GetResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "Get", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "Get", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "Get", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.LeaseID != nil && *input.LeaseID == "" { - return result, validation.NewError("blobs.Client", "Get", "`input.LeaseID` should either be specified or nil, not an empty string.") + return resp, fmt.Errorf("`input.LeaseID` should either be specified or nil, not an empty string") } + if (input.StartByte != nil && input.EndByte == nil) || input.StartByte == nil && input.EndByte != nil { - return result, validation.NewError("blobs.Client", "Get", "`input.StartByte` and `input.EndByte` must both be specified, or both be nil.") + return resp, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") } - req, err := client.GetPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Get", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + http.StatusPartialContent, + }, + HttpMethod: http.MethodGet, + OptionsObject: getOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.GetSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "Get", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Get", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + err = resp.HttpResponse.Unmarshal(&resp.Contents) + if err != nil { + return resp, fmt.Errorf("unmarshalling response: %v", err) + } + } + return } -// GetPreparer prepares the Get request. -func (client Client) GetPreparer(ctx context.Context, accountName, containerName, blobName string, input GetInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type getOptions struct { + input GetInput +} - if input.StartByte != nil && input.EndByte != nil { - headers["x-ms-range"] = fmt.Sprintf("bytes=%d-%d", *input.StartByte, *input.EndByte) +func (g getOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if g.input.StartByte != nil && g.input.EndByte != nil { + headers.Append("x-ms-range", fmt.Sprintf("bytes=%d-%d", *g.input.StartByte, *g.input.EndByte)) } + return headers - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) } -// GetSender sends the Get request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g getOptions) ToOData() *odata.Query { + return nil } -// GetResponder handles the response to the Get request. The method always -// closes the http.Response Body. -func (client Client) GetResponder(resp *http.Response) (result GetResult, err error) { - if resp != nil && int(resp.ContentLength) > 0 { - result.Contents = make([]byte, resp.ContentLength) - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusPartialContent), - autorest.ByUnmarshallingBytes(&result.Contents), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (g getOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go index 9f8120c6c8c3..9a783cb6ebac 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go @@ -7,10 +7,8 @@ import ( "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type GetBlockListInput struct { @@ -18,11 +16,11 @@ type GetBlockListInput struct { LeaseID *string } -type GetBlockListResult struct { - autorest.Response +type GetBlockListResponse struct { + HttpResponse *client.Response // The size of the blob in bytes - ContentLength *int64 + BlobContentLength *int64 // The Content Type of the blob ContentType string @@ -38,103 +36,87 @@ type GetBlockListResult struct { } // GetBlockList retrieves the list of blocks that have been uploaded as part of a block blob. -func (client Client) GetBlockList(ctx context.Context, accountName, containerName, blobName string, input GetBlockListInput) (result GetBlockListResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "GetBlockList", "`accountName` cannot be an empty string.") - } +func (c Client) GetBlockList(ctx context.Context, containerName, blobName string, input GetBlockListInput) (resp GetBlockListResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "GetBlockList", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "GetBlockList", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "GetBlockList", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - req, err := client.GetBlockListPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "GetBlockList", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getBlockListOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.GetBlockListSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "GetBlockList", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetBlockListResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "GetBlockList", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetBlockListPreparer prepares the GetBlockList request. -func (client Client) GetBlockListPreparer(ctx context.Context, accountName, containerName, blobName string, input GetBlockListInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "blocklisttype": autorest.Encode("query", string(input.BlockListType)), - "comp": autorest.Encode("query", "blocklist"), - } + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") + resp.ETag = resp.HttpResponse.Header.Get("ETag") - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } + if v := resp.HttpResponse.Header.Get("x-ms-blob-content-length"); v != "" { + i, innerErr := strconv.Atoi(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + return + } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + i64 := int64(i) + resp.BlobContentLength = &i64 + } + } + err = resp.HttpResponse.Unmarshal(&resp) + if err != nil { + return resp, fmt.Errorf("unmarshalling response: %v", err) + } } - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return } -// GetBlockListSender sends the GetBlockList request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetBlockListSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +type getBlockListOptions struct { + input GetBlockListInput } -// GetBlockListResponder handles the response to the GetBlockList request. The method always -// closes the http.Response Body. -func (client Client) GetBlockListResponder(resp *http.Response) (result GetBlockListResult, err error) { - if resp != nil && resp.Header != nil { - result.ContentType = resp.Header.Get("Content-Type") - result.ETag = resp.Header.Get("ETag") - - if v := resp.Header.Get("x-ms-blob-content-length"); v != "" { - i, innerErr := strconv.Atoi(v) - if innerErr != nil { - err = fmt.Errorf("Error parsing %q as an integer: %s", v, innerErr) - return - } - - i64 := int64(i) - result.ContentLength = &i64 - } +func (g getBlockListOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if g.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *g.input.LeaseID) } + return headers +} - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return +func (g getBlockListOptions) ToOData() *odata.Query { + return nil +} + +func (g getBlockListOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("blocklisttype", string(g.input.BlockListType)) + out.Append("comp", "blocklist") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go index 37abf631a28a..6d0f54163eaa 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go @@ -7,10 +7,8 @@ import ( "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type GetPageRangesInput struct { @@ -20,8 +18,8 @@ type GetPageRangesInput struct { EndByte *int64 } -type GetPageRangesResult struct { - autorest.Response +type GetPageRangesResponse struct { + HttpResponse *client.Response // The size of the blob in bytes ContentLength *int64 @@ -44,109 +42,97 @@ type PageRange struct { } // GetPageRanges returns the list of valid page ranges for a page blob or snapshot of a page blob. -func (client Client) GetPageRanges(ctx context.Context, accountName, containerName, blobName string, input GetPageRangesInput) (result GetPageRangesResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "GetPageRanges", "`accountName` cannot be an empty string.") - } +func (c Client) GetPageRanges(ctx context.Context, containerName, blobName string, input GetPageRangesInput) (resp GetPageRangesResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "GetPageRanges", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "GetPageRanges", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "GetPageRanges", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if (input.StartByte != nil && input.EndByte == nil) || input.StartByte == nil && input.EndByte != nil { - return result, validation.NewError("blobs.Client", "GetPageRanges", "`input.StartByte` and `input.EndByte` must both be specified, or both be nil.") + return resp, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") } - req, err := client.GetPageRangesPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "GetPageRanges", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getPageRangesOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.GetPageRangesSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "GetPageRanges", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetPageRangesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "GetPageRanges", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") + resp.ETag = resp.HttpResponse.Header.Get("ETag") -// GetPageRangesPreparer prepares the GetPageRanges request. -func (client Client) GetPageRangesPreparer(ctx context.Context, accountName, containerName, blobName string, input GetPageRangesInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } + if v := resp.HttpResponse.Header.Get("x-ms-blob-content-length"); v != "" { + i, innerErr := strconv.Atoi(v) + if innerErr != nil { + err = fmt.Errorf("Error parsing %q as an integer: %s", v, innerErr) + return + } - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "pagelist"), - } + i64 := int64(i) + resp.ContentLength = &i64 + } + } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + err = resp.HttpResponse.Unmarshal(&resp) + if err != nil { + return resp, fmt.Errorf("unmarshalling response: %s", err) + } } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + return +} + +type getPageRangesOptions struct { + input GetPageRangesInput +} + +func (g getPageRangesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + + if g.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *g.input.LeaseID) } - if input.StartByte != nil && input.EndByte != nil { - headers["x-ms-range"] = fmt.Sprintf("bytes=%d-%d", *input.StartByte, *input.EndByte) + if g.input.StartByte != nil && g.input.EndByte != nil { + headers.Append("x-ms-range", fmt.Sprintf("bytes=%d-%d", *g.input.StartByte, *g.input.EndByte)) } - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// GetPageRangesSender sends the GetPageRanges request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetPageRangesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g getPageRangesOptions) ToOData() *odata.Query { + return nil } -// GetPageRangesResponder handles the response to the GetPageRanges request. The method always -// closes the http.Response Body. -func (client Client) GetPageRangesResponder(resp *http.Response) (result GetPageRangesResult, err error) { - if resp != nil && resp.Header != nil { - result.ContentType = resp.Header.Get("Content-Type") - result.ETag = resp.Header.Get("ETag") - - if v := resp.Header.Get("x-ms-blob-content-length"); v != "" { - i, innerErr := strconv.Atoi(v) - if innerErr != nil { - err = fmt.Errorf("Error parsing %q as an integer: %s", v, innerErr) - return - } - - i64 := int64(i) - result.ContentLength = &i64 - } - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return +func (g getPageRangesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "pagelist") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go index 7fb7e6b55489..d059f11e2bc7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type IncrementalCopyBlobInput struct { @@ -19,102 +18,88 @@ type IncrementalCopyBlobInput struct { IfNoneMatch *string } +type IncrementalCopyBlob struct { + HttpResponse *client.Response +} + // IncrementalCopyBlob copies a snapshot of the source page blob to a destination page blob. // The snapshot is copied such that only the differential changes between the previously copied // snapshot are transferred to the destination. // The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual. -func (client Client) IncrementalCopyBlob(ctx context.Context, accountName, containerName, blobName string, input IncrementalCopyBlobInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "IncrementalCopyBlob", "`accountName` cannot be an empty string.") - } +func (c Client) IncrementalCopyBlob(ctx context.Context, containerName, blobName string, input IncrementalCopyBlobInput) (resp IncrementalCopyBlob, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "IncrementalCopyBlob", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "IncrementalCopyBlob", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "IncrementalCopyBlob", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.CopySource == "" { - return result, validation.NewError("blobs.Client", "IncrementalCopyBlob", "`input.CopySource` cannot be an empty string.") + return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") } - req, err := client.IncrementalCopyBlobPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "IncrementalCopyBlob", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: incrementalCopyBlobOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.IncrementalCopyBlobSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "IncrementalCopyBlob", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.IncrementalCopyBlobResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "IncrementalCopyBlob", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// IncrementalCopyBlobPreparer prepares the IncrementalCopyBlob request. -func (client Client) IncrementalCopyBlobPreparer(ctx context.Context, accountName, containerName, blobName string, input IncrementalCopyBlobInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type incrementalCopyBlobOptions struct { + input IncrementalCopyBlobInput +} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "incrementalcopy"), - } +func (i incrementalCopyBlobOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-copy-source": input.CopySource, - } + headers.Append("x-ms-copy-source", i.input.CopySource) - if input.IfModifiedSince != nil { - headers["If-Modified-Since"] = *input.IfModifiedSince + if i.input.IfModifiedSince != nil { + headers.Append("If-Modified-Since", *i.input.IfModifiedSince) } - if input.IfUnmodifiedSince != nil { - headers["If-Unmodified-Since"] = *input.IfUnmodifiedSince + if i.input.IfUnmodifiedSince != nil { + headers.Append("If-Unmodified-Since", *i.input.IfUnmodifiedSince) } - if input.IfMatch != nil { - headers["If-Match"] = *input.IfMatch + if i.input.IfMatch != nil { + headers.Append("If-Match", *i.input.IfMatch) } - if input.IfNoneMatch != nil { - headers["If-None-Match"] = *input.IfNoneMatch + if i.input.IfNoneMatch != nil { + headers.Append("If-None-Match", *i.input.IfNoneMatch) } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// IncrementalCopyBlobSender sends the IncrementalCopyBlob request. The method will close the -// http.Response Body if it receives an error. -func (client Client) IncrementalCopyBlobSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (i incrementalCopyBlobOptions) ToOData() *odata.Query { + return nil } -// IncrementalCopyBlobResponder handles the response to the IncrementalCopyBlob request. The method always -// closes the http.Response Body. -func (client Client) IncrementalCopyBlobResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return +func (i incrementalCopyBlobOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "incrementalcopy") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go index c4b49d73ae71..214808ca0713 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go @@ -2,13 +2,13 @@ package blobs import ( "context" + "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type AcquireLeaseInput struct { @@ -23,113 +23,98 @@ type AcquireLeaseInput struct { ProposedLeaseID *string } -type AcquireLeaseResult struct { - autorest.Response +type AcquireLeaseResponse struct { + HttpResponse *client.Response LeaseID string } // AcquireLease establishes and manages a lock on a blob for write and delete operations. -func (client Client) AcquireLease(ctx context.Context, accountName, containerName, blobName string, input AcquireLeaseInput) (result AcquireLeaseResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "AcquireLease", "`accountName` cannot be an empty string.") - } +func (c Client) AcquireLease(ctx context.Context, containerName, blobName string, input AcquireLeaseInput) (resp AcquireLeaseResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "AcquireLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "AcquireLease", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "AcquireLease", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.LeaseID != nil && *input.LeaseID == "" { - return result, validation.NewError("blobs.Client", "AcquireLease", "`input.LeaseID` cannot be an empty string, if specified.") + return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string, if specified") } + if input.ProposedLeaseID != nil && *input.ProposedLeaseID == "" { - return result, validation.NewError("blobs.Client", "AcquireLease", "`input.ProposedLeaseID` cannot be an empty string, if specified.") + return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string, if specified") } // An infinite lease duration is -1 seconds. A non-infinite lease can be between 15 and 60 seconds if input.LeaseDuration != -1 && (input.LeaseDuration <= 15 || input.LeaseDuration >= 60) { - return result, validation.NewError("blobs.Client", "AcquireLease", "`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds.") + return resp, fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") } - req, err := client.AcquireLeasePreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "AcquireLease", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: acquireLeaseOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.AcquireLeaseSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "AcquireLease", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.AcquireLeaseResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "AcquireLease", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.LeaseID = resp.HttpResponse.Header.Get("x-ms-lease-id") + } + } + return } -// AcquireLeasePreparer prepares the AcquireLease request. -func (client Client) AcquireLeasePreparer(ctx context.Context, accountName, containerName, blobName string, input AcquireLeaseInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type acquireLeaseOptions struct { + input AcquireLeaseInput +} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "lease"), - } +func (a acquireLeaseOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "acquire", - "x-ms-lease-duration": input.LeaseDuration, - } + headers.Append("x-ms-lease-action", "acquire") + headers.Append("x-ms-lease-duration", strconv.Itoa(a.input.LeaseDuration)) - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if a.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *a.input.LeaseID) } - if input.ProposedLeaseID != nil { - headers["x-ms-proposed-lease-id"] = *input.ProposedLeaseID + if a.input.ProposedLeaseID != nil { + headers.Append("x-ms-proposed-lease-id", *a.input.ProposedLeaseID) } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// AcquireLeaseSender sends the AcquireLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) AcquireLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (a acquireLeaseOptions) ToOData() *odata.Query { + return nil } -// AcquireLeaseResponder handles the response to the AcquireLease request. The method always -// closes the http.Response Body. -func (client Client) AcquireLeaseResponder(resp *http.Response) (result AcquireLeaseResult, err error) { - if resp != nil && resp.Header != nil { - result.LeaseID = resp.Header.Get("x-ms-lease-id") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (a acquireLeaseOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "lease") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go index d5642045d20d..858c3061793f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go @@ -2,13 +2,13 @@ package blobs import ( "context" + "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type BreakLeaseInput struct { @@ -26,7 +26,7 @@ type BreakLeaseInput struct { } type BreakLeaseResponse struct { - autorest.Response + HttpResponse *client.Response // Approximate time remaining in the lease period, in seconds. // If the break is immediate, 0 is returned. @@ -34,91 +34,73 @@ type BreakLeaseResponse struct { } // BreakLease breaks an existing lock on a blob using the LeaseID. -func (client Client) BreakLease(ctx context.Context, accountName, containerName, blobName string, input BreakLeaseInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "BreakLease", "`accountName` cannot be an empty string.") - } +func (c Client) BreakLease(ctx context.Context, containerName, blobName string, input BreakLeaseInput) (resp BreakLeaseResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "BreakLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "BreakLease", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "BreakLease", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.LeaseID == "" { - return result, validation.NewError("blobs.Client", "BreakLease", "`input.LeaseID` cannot be an empty string.") + return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") } - req, err := client.BreakLeasePreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "BreakLease", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: breakLeaseOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.BreakLeaseSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "BreakLease", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.BreakLeaseResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "BreakLease", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// BreakLeasePreparer prepares the BreakLease request. -func (client Client) BreakLeasePreparer(ctx context.Context, accountName, containerName, blobName string, input BreakLeaseInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type breakLeaseOptions struct { + input BreakLeaseInput +} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "lease"), - } +func (b breakLeaseOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "break", - "x-ms-lease-id": input.LeaseID, - } + headers.Append("x-ms-lease-action", "break") + headers.Append("x-ms-lease-id", b.input.LeaseID) - if input.BreakPeriod != nil { - headers["x-ms-lease-break-period"] = *input.BreakPeriod + if b.input.BreakPeriod != nil { + headers.Append("x-ms-lease-break-period", strconv.Itoa(*b.input.BreakPeriod)) } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// BreakLeaseSender sends the BreakLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) BreakLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (b breakLeaseOptions) ToOData() *odata.Query { + return nil } -// BreakLeaseResponder handles the response to the BreakLease request. The method always -// closes the http.Response Body. -func (client Client) BreakLeaseResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (b breakLeaseOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "lease") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go index c57f9db875b0..c69d05483b89 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type ChangeLeaseInput struct { @@ -17,101 +16,84 @@ type ChangeLeaseInput struct { } type ChangeLeaseResponse struct { - autorest.Response + HttpResponse *client.Response LeaseID string } // ChangeLease changes an existing lock on a blob for another lock. -func (client Client) ChangeLease(ctx context.Context, accountName, containerName, blobName string, input ChangeLeaseInput) (result ChangeLeaseResponse, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "ChangeLease", "`accountName` cannot be an empty string.") - } +func (c Client) ChangeLease(ctx context.Context, containerName, blobName string, input ChangeLeaseInput) (resp ChangeLeaseResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "ChangeLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "ChangeLease", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "ChangeLease", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.ExistingLeaseID == "" { - return result, validation.NewError("blobs.Client", "ChangeLease", "`input.ExistingLeaseID` cannot be an empty string.") + return resp, fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") } + if input.ProposedLeaseID == "" { - return result, validation.NewError("blobs.Client", "ChangeLease", "`input.ProposedLeaseID` cannot be an empty string.") + return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") } - req, err := client.ChangeLeasePreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "ChangeLease", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: changeLeaseOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.ChangeLeaseSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "ChangeLease", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.ChangeLeaseResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "ChangeLease", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// ChangeLeasePreparer prepares the ChangeLease request. -func (client Client) ChangeLeasePreparer(ctx context.Context, accountName, containerName, blobName string, input ChangeLeaseInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "lease"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "change", - "x-ms-lease-id": input.ExistingLeaseID, - "x-ms-proposed-lease-id": input.ProposedLeaseID, + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.LeaseID = resp.HttpResponse.Header.Get("x-ms-lease-id") + } } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return } -// ChangeLeaseSender sends the ChangeLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) ChangeLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +type changeLeaseOptions struct { + input ChangeLeaseInput } -// ChangeLeaseResponder handles the response to the ChangeLease request. The method always -// closes the http.Response Body. -func (client Client) ChangeLeaseResponder(resp *http.Response) (result ChangeLeaseResponse, err error) { - if resp != nil && resp.Header != nil { - result.LeaseID = resp.Header.Get("x-ms-lease-id") - } +func (c changeLeaseOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-lease-action", "change") + headers.Append("x-ms-lease-id", c.input.ExistingLeaseID) + headers.Append("x-ms-proposed-lease-id", c.input.ProposedLeaseID) + return headers +} - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (c changeLeaseOptions) ToOData() *odata.Query { + return nil +} - return +func (c changeLeaseOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "lease") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go index 0226cdf37552..350493da229b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go @@ -2,97 +2,84 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type ReleaseLeaseResponse struct { + HttpResponse *client.Response +} + +type ReleaseLeaseInput struct { + LeaseID string +} + // ReleaseLease releases a lock based on the Lease ID. -func (client Client) ReleaseLease(ctx context.Context, accountName, containerName, blobName, leaseID string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "ReleaseLease", "`accountName` cannot be an empty string.") - } +func (c Client) ReleaseLease(ctx context.Context, containerName, blobName string, input ReleaseLeaseInput) (resp ReleaseLeaseResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "ReleaseLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "ReleaseLease", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "ReleaseLease", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - if leaseID == "" { - return result, validation.NewError("blobs.Client", "ReleaseLease", "`leaseID` cannot be an empty string.") + + if input.LeaseID == "" { + return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") } - req, err := client.ReleaseLeasePreparer(ctx, accountName, containerName, blobName, leaseID) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "ReleaseLease", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: releaseLeaseOptions{ + leaseID: input.LeaseID, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.ReleaseLeaseSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "ReleaseLease", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.ReleaseLeaseResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "ReleaseLease", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// ReleaseLeasePreparer prepares the ReleaseLease request. -func (client Client) ReleaseLeasePreparer(ctx context.Context, accountName, containerName, blobName, leaseID string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "lease"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "release", - "x-ms-lease-id": leaseID, - } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type releaseLeaseOptions struct { + leaseID string } -// ReleaseLeaseSender sends the ReleaseLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) ReleaseLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (r releaseLeaseOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-lease-action", "release") + headers.Append("x-ms-lease-id", r.leaseID) + return headers } -// ReleaseLeaseResponder handles the response to the ReleaseLease request. The method always -// closes the http.Response Body. -func (client Client) ReleaseLeaseResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (r releaseLeaseOptions) ToOData() *odata.Query { + return nil +} - return +func (r releaseLeaseOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "lease") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go index 69c495bd9898..2a82a0af2a9e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go @@ -2,96 +2,83 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) -func (client Client) RenewLease(ctx context.Context, accountName, containerName, blobName, leaseID string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "RenewLease", "`accountName` cannot be an empty string.") - } +type RenewLeaseResponse struct { + HttpResponse *client.Response +} + +type RenewLeaseInput struct { + LeaseID string +} + +func (c Client) RenewLease(ctx context.Context, containerName, blobName string, input RenewLeaseInput) (resp RenewLeaseResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "RenewLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "RenewLease", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "RenewLease", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - if leaseID == "" { - return result, validation.NewError("blobs.Client", "RenewLease", "`leaseID` cannot be an empty string.") + + if input.LeaseID == "" { + return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") } - req, err := client.RenewLeasePreparer(ctx, accountName, containerName, blobName, leaseID) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "RenewLease", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: renewLeaseOptions{ + leaseID: input.LeaseID, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.RenewLeaseSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "RenewLease", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.RenewLeaseResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "RenewLease", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// RenewLeasePreparer prepares the RenewLease request. -func (client Client) RenewLeasePreparer(ctx context.Context, accountName, containerName, blobName, leaseID string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "lease"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "renew", - "x-ms-lease-id": leaseID, - } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type renewLeaseOptions struct { + leaseID string } -// RenewLeaseSender sends the RenewLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) RenewLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (r renewLeaseOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-lease-action", "renew") + headers.Append("x-ms-lease-id", r.leaseID) + return headers } -// RenewLeaseResponder handles the response to the RenewLease request. The method always -// closes the http.Response Body. -func (client Client) RenewLeaseResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (r renewLeaseOptions) ToOData() *odata.Query { + return nil +} - return +func (r renewLeaseOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "lease") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go index ec69152a5f98..604e7a7bd31d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go @@ -6,10 +6,8 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -22,92 +20,74 @@ type SetMetaDataInput struct { MetaData map[string]string } +type SetMetaDataResponse struct { + HttpResponse *client.Response +} + // SetMetaData marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. -func (client Client) SetMetaData(ctx context.Context, accountName, containerName, blobName string, input SetMetaDataInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "GetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) SetMetaData(ctx context.Context, containerName, blobName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "GetProperties", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "GetProperties", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "GetProperties", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("blobs.Client", "GetProperties", fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) } - req, err := client.SetMetaDataPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "SetMetaData", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: setMetadataOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.SetMetaDataSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "SetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "SetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetMetaDataPreparer prepares the SetMetaData request. -func (client Client) SetMetaDataPreparer(ctx context.Context, accountName, containerName, blobName string, input SetMetaDataInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "metadata"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type setMetadataOptions struct { + input SetMetaDataInput +} - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID +func (s setMetadataOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if s.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *s.input.LeaseID) } - - headers = metadata.SetIntoHeaders(headers, input.MetaData) - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + headers.Merge(metadata.SetMetaDataHeaders(s.input.MetaData)) + return headers } -// SetMetaDataSender sends the SetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s setMetadataOptions) ToOData() *odata.Query { + return nil } -// SetMetaDataResponder handles the response to the SetMetaData request. The method always -// closes the http.Response Body. -func (client Client) SetMetaDataResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (s setMetadataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go index 5640687d6d92..86b7c1100bd5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go @@ -7,10 +7,8 @@ import ( "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -20,8 +18,8 @@ type GetPropertiesInput struct { LeaseID *string } -type GetPropertiesResult struct { - autorest.Response +type GetPropertiesResponse struct { + HttpResponse *client.Response // The tier of page blob on a premium storage account or tier of block blob on blob storage or general purpose v2 account. AccessTier AccessTier @@ -163,148 +161,127 @@ type GetPropertiesResult struct { } // GetProperties returns all user-defined metadata, standard HTTP properties, and system properties for the blob -func (client Client) GetProperties(ctx context.Context, accountName, containerName, blobName string, input GetPropertiesInput) (result GetPropertiesResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "GetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) GetProperties(ctx context.Context, containerName, blobName string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "GetProperties", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "GetProperties", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return result, validation.NewError("blobs.Client", "GetProperties", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - req, err := client.GetPropertiesPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "GetProperties", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: getPropertiesOptions{ + leaseID: input.LeaseID, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.GetPropertiesSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "GetProperties", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetPropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "GetProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetPropertiesPreparer prepares the GetProperties request. -func (client Client) GetPropertiesPreparer(ctx context.Context, accountName, containerName, blobName string, input GetPropertiesInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID - } - - preparer := autorest.CreatePreparer( - autorest.AsHead(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetPropertiesSender sends the GetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// GetPropertiesResponder handles the response to the GetProperties request. The method always -// closes the http.Response Body. -func (client Client) GetPropertiesResponder(resp *http.Response) (result GetPropertiesResult, err error) { - if resp != nil && resp.Header != nil { - result.AccessTier = AccessTier(resp.Header.Get("x-ms-access-tier")) - result.AccessTierChangeTime = resp.Header.Get(" x-ms-access-tier-change-time") - result.ArchiveStatus = ArchiveStatus(resp.Header.Get(" x-ms-archive-status")) - result.BlobCommittedBlockCount = resp.Header.Get("x-ms-blob-committed-block-count") - result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") - result.BlobType = BlobType(resp.Header.Get("x-ms-blob-type")) - result.CacheControl = resp.Header.Get("Cache-Control") - result.ContentDisposition = resp.Header.Get("Content-Disposition") - result.ContentEncoding = resp.Header.Get("Content-Encoding") - result.ContentLanguage = resp.Header.Get("Content-Language") - result.ContentMD5 = resp.Header.Get("Content-MD5") - result.ContentType = resp.Header.Get("Content-Type") - result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time") - result.CopyDestinationSnapshot = resp.Header.Get("x-ms-copy-destination-snapshot") - result.CopyID = resp.Header.Get("x-ms-copy-id") - result.CopyProgress = resp.Header.Get("x-ms-copy-progress") - result.CopySource = resp.Header.Get("x-ms-copy-source") - result.CopyStatus = CopyStatus(resp.Header.Get("x-ms-copy-status")) - result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description") - result.CreationTime = resp.Header.Get("x-ms-creation-time") - result.ETag = resp.Header.Get("Etag") - result.LastModified = resp.Header.Get("Last-Modified") - result.LeaseDuration = LeaseDuration(resp.Header.Get("x-ms-lease-duration")) - result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state")) - result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status")) - result.MetaData = metadata.ParseFromHeaders(resp.Header) - - if v := resp.Header.Get("x-ms-access-tier-inferred"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("Error parsing %q as a bool: %s", v, innerErr) - return + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.AccessTier = AccessTier(resp.HttpResponse.Header.Get("x-ms-access-tier")) + resp.AccessTierChangeTime = resp.HttpResponse.Header.Get("x-ms-access-tier-change-time") + resp.ArchiveStatus = ArchiveStatus(resp.HttpResponse.Header.Get("x-ms-archive-status")) + resp.BlobCommittedBlockCount = resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count") + resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") + resp.BlobType = BlobType(resp.HttpResponse.Header.Get("x-ms-blob-type")) + resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") + resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") + resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") + resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") + resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") + resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") + resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") + resp.CopyDestinationSnapshot = resp.HttpResponse.Header.Get("x-ms-copy-destination-snapshot") + resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") + resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") + resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") + resp.CopyStatus = CopyStatus(resp.HttpResponse.Header.Get("x-ms-copy-status")) + resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") + resp.CreationTime = resp.HttpResponse.Header.Get("x-ms-creation-time") + resp.ETag = resp.HttpResponse.Header.Get("Etag") + resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") + resp.LeaseDuration = LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) + resp.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) + resp.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + + if v := resp.HttpResponse.Header.Get("x-ms-access-tier-inferred"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + return + } + resp.AccessTierInferred = b } - result.AccessTierInferred = b - } + if v := resp.HttpResponse.Header.Get("Content-Length"); v != "" { + i, innerErr := strconv.Atoi(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + } + resp.ContentLength = int64(i) + } - if v := resp.Header.Get("Content-Length"); v != "" { - i, innerErr := strconv.Atoi(v) - if innerErr != nil { - err = fmt.Errorf("Error parsing %q as an integer: %s", v, innerErr) + if v := resp.HttpResponse.Header.Get("x-ms-incremental-copy"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + return + } + resp.IncrementalCopy = b } - result.ContentLength = int64(i) + if v := resp.HttpResponse.Header.Get("x-ms-server-encrypted"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + return + } + resp.ServerEncrypted = b + } } + } - if v := resp.Header.Get("x-ms-incremental-copy"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("Error parsing %q as a bool: %s", v, innerErr) - return - } + return +} - result.IncrementalCopy = b - } +type getPropertiesOptions struct { + leaseID *string +} - if v := resp.Header.Get("x-ms-server-encrypted"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("Error parsing %q as a bool: %s", v, innerErr) - return - } +func (g getPropertiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - result.IncrementalCopy = b - } + if g.leaseID != nil { + headers.Append("x-ms-lease-id", *g.leaseID) } + return headers +} - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return +func (g getPropertiesOptions) ToOData() *odata.Query { + return nil +} + +func (g getPropertiesOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go index a8c0ed8cba95..ebe098556ded 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go @@ -2,13 +2,13 @@ package blobs import ( "context" + "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type SetPropertiesInput struct { @@ -24,44 +24,48 @@ type SetPropertiesInput struct { BlobSequenceNumber *string } -type SetPropertiesResult struct { - autorest.Response +type SetPropertiesResponse struct { + HttpResponse *client.Response BlobSequenceNumber string Etag string } // SetProperties sets system properties on the blob. -func (client Client) SetProperties(ctx context.Context, accountName, containerName, blobName string, input SetPropertiesInput) (result SetPropertiesResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "SetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) SetProperties(ctx context.Context, containerName, blobName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "SetProperties", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "SetProperties", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "SetProperties", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - req, err := client.SetPropertiesPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "SetProperties", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: setPropertiesOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.SetPropertiesSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "SetProperties", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetPropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "SetProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } @@ -76,81 +80,53 @@ var ( Update SequenceNumberAction = "update" ) -// SetPropertiesPreparer prepares the SetProperties request. -func (client Client) SetPropertiesPreparer(ctx context.Context, accountName, containerName, blobName string, input SetPropertiesInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "properties"), - } +type setPropertiesOptions struct { + input SetPropertiesInput +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +func (s setPropertiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - if input.CacheControl != nil { - headers["x-ms-blob-cache-control"] = *input.CacheControl + if s.input.CacheControl != nil { + headers.Append("x-ms-blob-cache-control", *s.input.CacheControl) } - if input.ContentDisposition != nil { - headers["x-ms-blob-content-disposition"] = *input.ContentDisposition + if s.input.ContentDisposition != nil { + headers.Append("x-ms-blob-content-disposition", *s.input.ContentDisposition) } - if input.ContentEncoding != nil { - headers["x-ms-blob-content-encoding"] = *input.ContentEncoding + if s.input.ContentEncoding != nil { + headers.Append("x-ms-blob-content-encoding", *s.input.ContentEncoding) } - if input.ContentLanguage != nil { - headers["x-ms-blob-content-language"] = *input.ContentLanguage + if s.input.ContentLanguage != nil { + headers.Append("x-ms-blob-content-language", *s.input.ContentLanguage) } - if input.ContentMD5 != nil { - headers["x-ms-blob-content-md5"] = *input.ContentMD5 + if s.input.ContentMD5 != nil { + headers.Append("x-ms-blob-content-md5", *s.input.ContentMD5) } - if input.ContentType != nil { - headers["x-ms-blob-content-type"] = *input.ContentType + if s.input.ContentType != nil { + headers.Append("x-ms-blob-content-type", *s.input.ContentType) } - if input.ContentLength != nil { - headers["x-ms-blob-content-length"] = *input.ContentLength + if s.input.ContentLength != nil { + headers.Append("x-ms-blob-content-length", strconv.Itoa(int(*s.input.ContentLength))) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if s.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *s.input.LeaseID) } - if input.SequenceNumberAction != nil { - headers["x-ms-sequence-number-action"] = string(*input.SequenceNumberAction) + if s.input.SequenceNumberAction != nil { + headers.Append("x-ms-sequence-number-action", string(*s.input.SequenceNumberAction)) } - if input.BlobSequenceNumber != nil { - headers["x-ms-blob-sequence-number"] = *input.BlobSequenceNumber + if s.input.BlobSequenceNumber != nil { + headers.Append("x-ms-blob-sequence-number", *s.input.BlobSequenceNumber) } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetPropertiesSender sends the SetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s setPropertiesOptions) ToOData() *odata.Query { + return nil } -// SetPropertiesResponder handles the response to the SetProperties request. The method always -// closes the http.Response Body. -func (client Client) SetPropertiesResponder(resp *http.Response) (result SetPropertiesResult, err error) { - if resp != nil && resp.Header != nil { - result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") - result.Etag = resp.Header.Get("Etag") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return +func (s setPropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "properties") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go index ef2c5025d606..0f3aa30733a5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go @@ -6,10 +6,8 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -24,111 +22,96 @@ type PutAppendBlobInput struct { MetaData map[string]string } +type PutAppendBlobResponse struct { + HttpResponse *client.Response +} + // PutAppendBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new append blob, or updates the content of an existing blob. -func (client Client) PutAppendBlob(ctx context.Context, accountName, containerName, blobName string, input PutAppendBlobInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "PutAppendBlob", "`accountName` cannot be an empty string.") - } +func (c Client) PutAppendBlob(ctx context.Context, containerName, blobName string, input PutAppendBlobInput) (resp PutAppendBlobResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "PutAppendBlob", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "PutAppendBlob", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "PutAppendBlob", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("blobs.Client", "PutAppendBlob", fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) } - req, err := client.PutAppendBlobPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutAppendBlob", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: putAppendBlobOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.PutAppendBlobSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "PutAppendBlob", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.PutAppendBlobResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutAppendBlob", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// PutAppendBlobPreparer prepares the PutAppendBlob request. -func (client Client) PutAppendBlobPreparer(ctx context.Context, accountName, containerName, blobName string, input PutAppendBlobInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type putAppendBlobOptions struct { + input PutAppendBlobInput +} - headers := map[string]interface{}{ - "x-ms-blob-type": string(AppendBlob), - "x-ms-version": APIVersion, +func (p putAppendBlobOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - // For a page blob or an append blob, the value of this header must be set to zero, - // as Put Blob is used only to initialize the blob - "Content-Length": 0, - } + headers.Append("x-ms-blob-type", string(AppendBlob)) + headers.Append("Content-Length", "0") - if input.CacheControl != nil { - headers["x-ms-blob-cache-control"] = *input.CacheControl + if p.input.CacheControl != nil { + headers.Append("x-ms-blob-cache-control", *p.input.CacheControl) } - if input.ContentDisposition != nil { - headers["x-ms-blob-content-disposition"] = *input.ContentDisposition + if p.input.ContentDisposition != nil { + headers.Append("x-ms-blob-content-disposition", *p.input.ContentDisposition) } - if input.ContentEncoding != nil { - headers["x-ms-blob-content-encoding"] = *input.ContentEncoding + if p.input.ContentEncoding != nil { + headers.Append("x-ms-blob-content-encoding", *p.input.ContentEncoding) } - if input.ContentLanguage != nil { - headers["x-ms-blob-content-language"] = *input.ContentLanguage + if p.input.ContentLanguage != nil { + headers.Append("x-ms-blob-content-language", *p.input.ContentLanguage) } - if input.ContentMD5 != nil { - headers["x-ms-blob-content-md5"] = *input.ContentMD5 + if p.input.ContentMD5 != nil { + headers.Append("x-ms-blob-content-md5", *p.input.ContentMD5) } - if input.ContentType != nil { - headers["x-ms-blob-content-type"] = *input.ContentType + if p.input.ContentType != nil { + headers.Append("x-ms-blob-content-type", *p.input.ContentType) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if p.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *p.input.LeaseID) } - headers = metadata.SetIntoHeaders(headers, input.MetaData) - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) + return headers } -// PutAppendBlobSender sends the PutAppendBlob request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutAppendBlobSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p putAppendBlobOptions) ToOData() *odata.Query { + return nil } -// PutAppendBlobResponder handles the response to the PutAppendBlob request. The method always -// closes the http.Response Body. -func (client Client) PutAppendBlobResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (p putAppendBlobOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go index 6d41bda13b55..a6059c4aed27 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go @@ -2,13 +2,13 @@ package blobs import ( "context" + "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type PutBlockInput struct { @@ -18,109 +18,91 @@ type PutBlockInput struct { LeaseID *string } -type PutBlockResult struct { - autorest.Response +type PutBlockResponse struct { + HttpResponse *client.Response ContentMD5 string } // PutBlock creates a new block to be committed as part of a blob. -func (client Client) PutBlock(ctx context.Context, accountName, containerName, blobName string, input PutBlockInput) (result PutBlockResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "PutBlock", "`accountName` cannot be an empty string.") - } +func (c Client) PutBlock(ctx context.Context, containerName, blobName string, input PutBlockInput) (resp PutBlockResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "PutBlock", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "PutBlock", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "PutBlock", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.BlockID == "" { - return result, validation.NewError("blobs.Client", "PutBlock", "`input.BlockID` cannot be an empty string.") + return resp, fmt.Errorf("`input.BlockID` cannot be an empty string") } + if len(input.Content) == 0 { - return result, validation.NewError("blobs.Client", "PutBlock", "`input.Content` cannot be empty.") + return resp, fmt.Errorf("`input.Content` cannot be empty") + } + + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: putBlockOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - req, err := client.PutBlockPreparer(ctx, accountName, containerName, blobName, input) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlock", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.PutBlockSender(req) + err = req.Marshal(&input.Content) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlock", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request: %v", err) } - result, err = client.PutBlockResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlock", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// PutBlockPreparer prepares the PutBlock request. -func (client Client) PutBlockPreparer(ctx context.Context, accountName, containerName, blobName string, input PutBlockInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "block"), - "blockid": autorest.Encode("query", input.BlockID), - } +type putBlockOptions struct { + input PutBlockInput +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "Content-Length": int(len(input.Content)), - } +func (p putBlockOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Content-Length", strconv.Itoa(len(p.input.Content))) - if input.ContentMD5 != nil { - headers["x-ms-blob-content-md5"] = *input.ContentMD5 + if p.input.ContentMD5 != nil { + headers.Append("x-ms-blob-content-md5", *p.input.ContentMD5) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if p.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *p.input.LeaseID) } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers), - autorest.WithBytes(&input.Content)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// PutBlockSender sends the PutBlock request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutBlockSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p putBlockOptions) ToOData() *odata.Query { + return nil } -// PutBlockResponder handles the response to the PutBlock request. The method always -// closes the http.Response Body. -func (client Client) PutBlockResponder(resp *http.Response) (result PutBlockResult, err error) { - if resp != nil && resp.Header != nil { - result.ContentMD5 = resp.Header.Get("Content-MD5") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (p putBlockOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "block") + out.Append("blockid", p.input.BlockID) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go index f5c1a971b306..462ea17272a0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go @@ -4,12 +4,11 @@ import ( "context" "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -25,120 +24,107 @@ type PutBlockBlobInput struct { MetaData map[string]string } +type PutBlockBlobResponse struct { + HttpResponse *client.Response +} + // PutBlockBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new block append blob, or updates the content of an existing block blob. -func (client Client) PutBlockBlob(ctx context.Context, accountName, containerName, blobName string, input PutBlockBlobInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "PutBlockBlob", "`accountName` cannot be an empty string.") - } +func (c Client) PutBlockBlob(ctx context.Context, containerName, blobName string, input PutBlockBlobInput) (resp PutBlockBlobResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "PutBlockBlob", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "PutBlockBlob", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "PutBlockBlob", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.Content != nil && len(*input.Content) == 0 { - return result, validation.NewError("blobs.Client", "PutBlockBlob", "`input.Content` must either be nil or not empty.") + return resp, fmt.Errorf("`input.Content` must either be nil or not empty") } + if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("blobs.Client", "PutBlockBlob", fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + } + + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: putBlockBlobOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - req, err := client.PutBlockBlobPreparer(ctx, accountName, containerName, blobName, input) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockBlob", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.PutBlockBlobSender(req) + err = req.Marshal(&input.Content) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockBlob", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request: %v", err) } - result, err = client.PutBlockBlobResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockBlob", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// PutBlockBlobPreparer prepares the PutBlockBlob request. -func (client Client) PutBlockBlobPreparer(ctx context.Context, accountName, containerName, blobName string, input PutBlockBlobInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type putBlockBlobOptions struct { + input PutBlockBlobInput +} - headers := map[string]interface{}{ - "x-ms-blob-type": string(BlockBlob), - "x-ms-version": APIVersion, - } +func (p putBlockBlobOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-blob-type", string(BlockBlob)) - if input.CacheControl != nil { - headers["x-ms-blob-cache-control"] = *input.CacheControl - } - if input.ContentDisposition != nil { - headers["x-ms-blob-content-disposition"] = *input.ContentDisposition + if p.input.CacheControl != nil { + headers.Append("x-ms-blob-cache-control", *p.input.CacheControl) } - if input.ContentEncoding != nil { - headers["x-ms-blob-content-encoding"] = *input.ContentEncoding + if p.input.ContentDisposition != nil { + headers.Append("x-ms-blob-content-disposition", *p.input.ContentDisposition) } - if input.ContentLanguage != nil { - headers["x-ms-blob-content-language"] = *input.ContentLanguage + if p.input.ContentEncoding != nil { + headers.Append("x-ms-blob-content-encoding", *p.input.ContentEncoding) } - if input.ContentMD5 != nil { - headers["x-ms-blob-content-md5"] = *input.ContentMD5 + if p.input.ContentLanguage != nil { + headers.Append("x-ms-blob-content-language", *p.input.ContentLanguage) } - if input.ContentType != nil { - headers["x-ms-blob-content-type"] = *input.ContentType + if p.input.ContentMD5 != nil { + headers.Append("x-ms-blob-content-md5", *p.input.ContentMD5) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if p.input.ContentType != nil { + headers.Append("x-ms-blob-content-type", *p.input.ContentType) } - if input.Content != nil { - headers["Content-Length"] = int(len(*input.Content)) + if p.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *p.input.LeaseID) } - - headers = metadata.SetIntoHeaders(headers, input.MetaData) - - decorators := []autorest.PrepareDecorator{ - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), + if p.input.Content != nil { + headers.Append("Content-Length", strconv.Itoa(len(*p.input.Content))) } - if input.Content != nil { - decorators = append(decorators, autorest.WithBytes(input.Content)) - } + headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) - preparer := autorest.CreatePreparer(decorators...) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// PutBlockBlobSender sends the PutBlockBlob request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutBlockBlobSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p putBlockBlobOptions) ToOData() *odata.Query { + return nil } -// PutBlockBlobResponder handles the response to the PutBlockBlob request. The method always -// closes the http.Response Body. -func (client Client) PutBlockBlobResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (p putBlockBlobOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go index b7499498aeca..932fb320607d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go @@ -8,10 +8,10 @@ import ( ) // PutBlockBlobFromFile is a helper method which takes a file, and automatically chunks it up, rather than having to do this yourself -func (client Client) PutBlockBlobFromFile(ctx context.Context, accountName, containerName, blobName string, file *os.File, input PutBlockBlobInput) error { +func (c Client) PutBlockBlobFromFile(ctx context.Context, containerName, blobName string, file *os.File, input PutBlockBlobInput) error { fileInfo, err := file.Stat() if err != nil { - return fmt.Errorf("Error loading file info: %s", err) + return fmt.Errorf("error loading file info: %s", err) } fileSize := fileInfo.Size() @@ -26,8 +26,8 @@ func (client Client) PutBlockBlobFromFile(ctx context.Context, accountName, cont input.Content = &bytes - if _, err = client.PutBlockBlob(ctx, accountName, containerName, blobName, input); err != nil { - return fmt.Errorf("Error putting bytes: %s", err) + if _, err = c.PutBlockBlob(ctx, containerName, blobName, input); err != nil { + return fmt.Errorf("error putting bytes: %s", err) } return nil diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go index f80524790be5..bfe451b941c9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -34,8 +33,8 @@ type PutBlockListInput struct { LeaseID *string } -type PutBlockListResult struct { - autorest.Response +type PutBlockListResponse struct { + HttpResponse *client.Response ContentMD5 string ETag string @@ -45,113 +44,99 @@ type PutBlockListResult struct { // PutBlockList writes a blob by specifying the list of block IDs that make up the blob. // In order to be written as part of a blob, a block must have been successfully written // to the server in a prior Put Block operation. -func (client Client) PutBlockList(ctx context.Context, accountName, containerName, blobName string, input PutBlockListInput) (result PutBlockListResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "PutBlockList", "`accountName` cannot be an empty string.") - } +func (c Client) PutBlockList(ctx context.Context, containerName, blobName string, input PutBlockListInput) (resp PutBlockListResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "PutBlockList", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "PutBlockList", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "PutBlockList", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - req, err := client.PutBlockListPreparer(ctx, accountName, containerName, blobName, input) + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: putBlockListOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockList", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.PutBlockListSender(req) + err = req.Marshal(&input.BlockList) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockList", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request: %v", err) } - result, err = client.PutBlockListResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockList", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") + resp.ETag = resp.HttpResponse.Header.Get("ETag") + resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") + } + } + return } -// PutBlockListPreparer prepares the PutBlockList request. -func (client Client) PutBlockListPreparer(ctx context.Context, accountName, containerName, blobName string, input PutBlockListInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "blocklist"), - } +type putBlockListOptions struct { + input PutBlockListInput +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +func (p putBlockListOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - if input.CacheControl != nil { - headers["x-ms-blob-cache-control"] = *input.CacheControl + if p.input.CacheControl != nil { + headers.Append("x-ms-blob-cache-control", *p.input.CacheControl) } - if input.ContentDisposition != nil { - headers["x-ms-blob-content-disposition"] = *input.ContentDisposition + if p.input.ContentDisposition != nil { + headers.Append("x-ms-blob-content-disposition", *p.input.ContentDisposition) } - if input.ContentEncoding != nil { - headers["x-ms-blob-content-encoding"] = *input.ContentEncoding + if p.input.ContentEncoding != nil { + headers.Append("x-ms-blob-content-encoding", *p.input.ContentEncoding) } - if input.ContentLanguage != nil { - headers["x-ms-blob-content-language"] = *input.ContentLanguage + if p.input.ContentLanguage != nil { + headers.Append("x-ms-blob-content-language", *p.input.ContentLanguage) } - if input.ContentMD5 != nil { - headers["x-ms-blob-content-md5"] = *input.ContentMD5 + if p.input.ContentMD5 != nil { + headers.Append("x-ms-blob-content-md5", *p.input.ContentMD5) } - if input.ContentType != nil { - headers["x-ms-blob-content-type"] = *input.ContentType + if p.input.ContentType != nil { + headers.Append("x-ms-blob-content-type", *p.input.ContentType) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if p.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *p.input.LeaseID) } - headers = metadata.SetIntoHeaders(headers, input.MetaData) + headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers), - autorest.WithXML(input.BlockList)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// PutBlockListSender sends the PutBlockList request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutBlockListSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p putBlockListOptions) ToOData() *odata.Query { + return nil } -// PutBlockListResponder handles the response to the PutBlockList request. The method always -// closes the http.Response Body. -func (client Client) PutBlockListResponder(resp *http.Response) (result PutBlockListResult, err error) { - if resp != nil && resp.Header != nil { - result.ContentMD5 = resp.Header.Get("Content-MD5") - result.ETag = resp.Header.Get("ETag") - result.LastModified = resp.Header.Get("Last-Modified") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (p putBlockListOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "blocklist") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go index 95ad974698bd..cd8487c5c265 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go @@ -2,13 +2,12 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type PutBlockFromURLInput struct { @@ -20,110 +19,94 @@ type PutBlockFromURLInput struct { Range *string } -type PutBlockFromURLResult struct { - autorest.Response - ContentMD5 string +type PutBlockFromURLResponse struct { + HttpResponse *client.Response + ContentMD5 string } // PutBlockFromURL creates a new block to be committed as part of a blob where the contents are read from a URL -func (client Client) PutBlockFromURL(ctx context.Context, accountName, containerName, blobName string, input PutBlockFromURLInput) (result PutBlockFromURLResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "PutBlockFromURL", "`accountName` cannot be an empty string.") - } +func (c Client) PutBlockFromURL(ctx context.Context, containerName, blobName string, input PutBlockFromURLInput) (resp PutBlockFromURLResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "PutBlockFromURL", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "PutBlockFromURL", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "PutBlockFromURL", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.BlockID == "" { - return result, validation.NewError("blobs.Client", "PutBlockFromURL", "`input.BlockID` cannot be an empty string.") + return resp, fmt.Errorf("`input.BlockID` cannot be an empty string") } + if input.CopySource == "" { - return result, validation.NewError("blobs.Client", "PutBlockFromURL", "`input.CopySource` cannot be an empty string.") + return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") } - req, err := client.PutBlockFromURLPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockFromURL", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: putBlockUrlOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.PutBlockFromURLSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockFromURL", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.PutBlockFromURLResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutBlockFromURL", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") + } + } + return } -// PutBlockFromURLPreparer prepares the PutBlockFromURL request. -func (client Client) PutBlockFromURLPreparer(ctx context.Context, accountName, containerName, blobName string, input PutBlockFromURLInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type putBlockUrlOptions struct { + input PutBlockFromURLInput +} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "block"), - "blockid": autorest.Encode("query", input.BlockID), - } +func (p putBlockUrlOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-copy-source": input.CopySource, - } + headers.Append("x-ms-copy-source", p.input.CopySource) - if input.ContentMD5 != nil { - headers["x-ms-source-content-md5"] = *input.ContentMD5 + if p.input.ContentMD5 != nil { + headers.Append("x-ms-source-content-md5", *p.input.ContentMD5) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if p.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *p.input.LeaseID) } - if input.Range != nil { - headers["x-ms-source-range"] = *input.Range + if p.input.Range != nil { + headers.Append("x-ms-source-range", *p.input.Range) } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// PutBlockFromURLSender sends the PutBlockFromURL request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutBlockFromURLSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p putBlockUrlOptions) ToOData() *odata.Query { + return nil } -// PutBlockFromURLResponder handles the response to the PutBlockFromURL request. The method always -// closes the http.Response Body. -func (client Client) PutBlockFromURLResponder(resp *http.Response) (result PutBlockFromURLResult, err error) { - if resp != nil && resp.Header != nil { - result.ContentMD5 = resp.Header.Get("Content-MD5") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (p putBlockUrlOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "block") + out.Append("blockid", p.input.BlockID) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go index 4cfba95ae37b..2b733c4c1311 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go @@ -2,13 +2,13 @@ package blobs import ( "context" + "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -27,122 +27,117 @@ type PutPageBlobInput struct { AccessTier *AccessTier } +type PutPageBlobResponse struct { + HttpResponse *client.Response +} + // PutPageBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new block blob, or updates the content of an existing page blob. -func (client Client) PutPageBlob(ctx context.Context, accountName, containerName, blobName string, input PutPageBlobInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "PutPageBlob", "`accountName` cannot be an empty string.") - } +func (c Client) PutPageBlob(ctx context.Context, containerName, blobName string, input PutPageBlobInput) (resp PutPageBlobResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "PutPageBlob", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "PutPageBlob", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "PutPageBlob", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.BlobContentLengthBytes == 0 || input.BlobContentLengthBytes%512 != 0 { - return result, validation.NewError("blobs.Client", "PutPageBlob", "`input.BlobContentLengthBytes` must be aligned to a 512-byte boundary.") + return resp, fmt.Errorf("`input.BlobContentLengthBytes` must be aligned to a 512-byte boundary") } - req, err := client.PutPageBlobPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageBlob", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: putPageBlobOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.PutPageBlobSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageBlob", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.PutPageBlobResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageBlob", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// PutPageBlobPreparer prepares the PutPageBlob request. -func (client Client) PutPageBlobPreparer(ctx context.Context, accountName, containerName, blobName string, input PutPageBlobInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type putPageBlobOptions struct { + input PutPageBlobInput +} - headers := map[string]interface{}{ - "x-ms-blob-type": string(PageBlob), - "x-ms-version": APIVersion, +func (p putPageBlobOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - // For a page blob or an page blob, the value of this header must be set to zero, - // as Put Blob is used only to initialize the blob - "Content-Length": 0, + headers.Append("x-ms-blob-type", string(PageBlob)) - // This header specifies the maximum size for the page blob, up to 8 TB. - // The page blob size must be aligned to a 512-byte boundary. - "x-ms-blob-content-length": input.BlobContentLengthBytes, - } + // For a page blob or an page blob, the value of this header must be set to zero, + // as Put Blob is used only to initialize the blob + headers.Append("Content-Length", "0") - if input.AccessTier != nil { - headers["x-ms-access-tier"] = string(*input.AccessTier) - } - if input.BlobSequenceNumber != nil { - headers["x-ms-blob-sequence-number"] = *input.BlobSequenceNumber + // This header specifies the maximum size for the page blob, up to 8 TB. + // The page blob size must be aligned to a 512-byte boundary. + headers.Append("x-ms-blob-content-length", strconv.Itoa(int(p.input.BlobContentLengthBytes))) + + if p.input.AccessTier != nil { + headers.Append("x-ms-access-tier", string(*p.input.AccessTier)) } - if input.CacheControl != nil { - headers["x-ms-blob-cache-control"] = *input.CacheControl + if p.input.BlobSequenceNumber != nil { + headers.Append("x-ms-blob-sequence-number", strconv.Itoa(int(*p.input.BlobSequenceNumber))) } - if input.ContentDisposition != nil { - headers["x-ms-blob-content-disposition"] = *input.ContentDisposition + + if p.input.CacheControl != nil { + headers.Append("x-ms-blob-cache-control", *p.input.CacheControl) } - if input.ContentEncoding != nil { - headers["x-ms-blob-content-encoding"] = *input.ContentEncoding + + if p.input.ContentDisposition != nil { + headers.Append("x-ms-blob-content-disposition", *p.input.ContentDisposition) } - if input.ContentLanguage != nil { - headers["x-ms-blob-content-language"] = *input.ContentLanguage + + if p.input.ContentEncoding != nil { + headers.Append("x-ms-blob-content-encoding", *p.input.ContentEncoding) } - if input.ContentMD5 != nil { - headers["x-ms-blob-content-md5"] = *input.ContentMD5 + + if p.input.ContentLanguage != nil { + headers.Append("x-ms-blob-content-language", *p.input.ContentLanguage) } - if input.ContentType != nil { - headers["x-ms-blob-content-type"] = *input.ContentType + + if p.input.ContentMD5 != nil { + headers.Append("x-ms-blob-content-md5", *p.input.ContentMD5) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + + if p.input.ContentType != nil { + headers.Append("x-ms-blob-content-type", *p.input.ContentType) } - headers = metadata.SetIntoHeaders(headers, input.MetaData) + if p.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *p.input.LeaseID) + } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) + return headers } -// PutPageBlobSender sends the PutPageBlob request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutPageBlobSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p putPageBlobOptions) ToOData() *odata.Query { + return nil } -// PutPageBlobResponder handles the response to the PutPageBlob request. The method always -// closes the http.Response Body. -func (client Client) PutPageBlobResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (p putPageBlobOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go index 59feaa5d93d0..1a995138d166 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go @@ -6,10 +6,8 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type PutPageClearInput struct { @@ -19,95 +17,81 @@ type PutPageClearInput struct { LeaseID *string } +type PutPageClearResponse struct { + HttpResponse *client.Response +} + // PutPageClear clears a range of pages within a page blob. -func (client Client) PutPageClear(ctx context.Context, accountName, containerName, blobName string, input PutPageClearInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "PutPageClear", "`accountName` cannot be an empty string.") - } +func (c Client) PutPageClear(ctx context.Context, containerName, blobName string, input PutPageClearInput) (resp PutPageClearResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "PutPageClear", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "PutPageClear", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "PutPageClear", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.StartByte < 0 { - return result, validation.NewError("blobs.Client", "PutPageClear", "`input.StartByte` must be greater than or equal to 0.") + return resp, fmt.Errorf("`input.StartByte` must be greater than or equal to 0") } + if input.EndByte <= 0 { - return result, validation.NewError("blobs.Client", "PutPageClear", "`input.EndByte` must be greater than 0.") + return resp, fmt.Errorf("`input.EndByte` must be greater than 0") } - req, err := client.PutPageClearPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageClear", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: putPageClearOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.PutPageClearSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageClear", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.PutPageClearResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageClear", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// PutPageClearPreparer prepares the PutPageClear request. -func (client Client) PutPageClearPreparer(ctx context.Context, accountName, containerName, blobName string, input PutPageClearInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type putPageClearOptions struct { + input PutPageClearInput +} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "page"), - } +func (p putPageClearOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-page-write": "clear", - "x-ms-range": fmt.Sprintf("bytes=%d-%d", input.StartByte, input.EndByte), - } + headers.Append("x-ms-page-write", "clear") + headers.Append("x-ms-range", fmt.Sprintf("bytes=%d-%d", p.input.StartByte, p.input.EndByte)) - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if p.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *p.input.LeaseID) } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// PutPageClearSender sends the PutPageClear request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutPageClearSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p putPageClearOptions) ToOData() *odata.Query { + return nil } -// PutPageClearResponder handles the response to the PutPageClear request. The method always -// closes the http.Response Body. -func (client Client) PutPageClearResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (p putPageClearOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "page") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go index 3799381e5525..448fe343d903 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go @@ -1,15 +1,16 @@ package blobs import ( + "bytes" "context" "fmt" + "io" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type PutPageUpdateInput struct { @@ -27,8 +28,8 @@ type PutPageUpdateInput struct { LeaseID *string } -type PutPageUpdateResult struct { - autorest.Response +type PutPageUpdateResponse struct { + HttpResponse *client.Response BlobSequenceNumber string ContentMD5 string @@ -36,129 +37,120 @@ type PutPageUpdateResult struct { } // PutPageUpdate writes a range of pages to a page blob. -func (client Client) PutPageUpdate(ctx context.Context, accountName, containerName, blobName string, input PutPageUpdateInput) (result PutPageUpdateResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "PutPageUpdate", "`accountName` cannot be an empty string.") - } +func (c Client) PutPageUpdate(ctx context.Context, containerName, blobName string, input PutPageUpdateInput) (resp PutPageUpdateResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "PutPageUpdate", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "PutPageUpdate", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "PutPageUpdate", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.StartByte < 0 { - return result, validation.NewError("blobs.Client", "PutPageUpdate", "`input.StartByte` must be greater than or equal to 0.") + return resp, fmt.Errorf("`input.StartByte` must be greater than or equal to 0") } + if input.EndByte <= 0 { - return result, validation.NewError("blobs.Client", "PutPageUpdate", "`input.EndByte` must be greater than 0.") + return resp, fmt.Errorf("`input.EndByte` must be greater than 0") } expectedSize := (input.EndByte - input.StartByte) + 1 actualSize := int64(len(input.Content)) if expectedSize != actualSize { - return result, validation.NewError("blobs.Client", "PutPageUpdate", fmt.Sprintf("Content Size was defined as %d but got %d.", expectedSize, actualSize)) + return resp, fmt.Errorf(fmt.Sprintf("Content Size was defined as %d but got %d.", expectedSize, actualSize)) } - req, err := client.PutPageUpdatePreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageUpdate", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: putPageUpdateOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.PutPageUpdateSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageUpdate", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.PutPageUpdateResponder(resp) + req.Body = io.NopCloser(bytes.NewReader(input.Content)) + req.ContentLength = int64(len(input.Content)) + + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "PutPageUpdate", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil && resp.HttpResponse.Header != nil { + resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") + resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") + resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") + } + return } -// PutPageUpdatePreparer prepares the PutPageUpdate request. -func (client Client) PutPageUpdatePreparer(ctx context.Context, accountName, containerName, blobName string, input PutPageUpdateInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type putPageUpdateOptions struct { + input PutPageUpdateInput +} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "page"), - } +func (p putPageUpdateOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-page-write", "update") + headers.Append("x-ms-range", fmt.Sprintf("bytes=%d-%d", p.input.StartByte, p.input.EndByte)) + headers.Append("Content-Length", strconv.Itoa(len(p.input.Content))) - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-page-write": "update", - "x-ms-range": fmt.Sprintf("bytes=%d-%d", input.StartByte, input.EndByte), - "Content-Length": int(len(input.Content)), + if p.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *p.input.LeaseID) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID - } - if input.IfSequenceNumberEQ != nil { - headers["x-ms-if-sequence-number-eq"] = *input.IfSequenceNumberEQ + if p.input.IfSequenceNumberEQ != nil { + headers.Append("x-ms-if-sequence-number-eq", *p.input.IfSequenceNumberEQ) } - if input.IfSequenceNumberLE != nil { - headers["x-ms-if-sequence-number-le"] = *input.IfSequenceNumberLE + + if p.input.IfSequenceNumberLE != nil { + headers.Append("x-ms-if-sequence-number-le", *p.input.IfSequenceNumberLE) } - if input.IfSequenceNumberLT != nil { - headers["x-ms-if-sequence-number-lt"] = *input.IfSequenceNumberLT + + if p.input.IfSequenceNumberLT != nil { + headers.Append("x-ms-if-sequence-number-lt", *p.input.IfSequenceNumberLT) } - if input.IfModifiedSince != nil { - headers["If-Modified-Since"] = *input.IfModifiedSince + + if p.input.IfModifiedSince != nil { + headers.Append("If-Modified-Since", *p.input.IfModifiedSince) } - if input.IfUnmodifiedSince != nil { - headers["If-Unmodified-Since"] = *input.IfUnmodifiedSince + + if p.input.IfUnmodifiedSince != nil { + headers.Append("If-Unmodified-Since", *p.input.IfUnmodifiedSince) } - if input.IfMatch != nil { - headers["If-Match"] = *input.IfMatch + + if p.input.IfMatch != nil { + headers.Append("If-Match", *p.input.IfMatch) } - if input.IfNoneMatch != nil { - headers["If-None-Match"] = *input.IfNoneMatch + + if p.input.IfNoneMatch != nil { + headers.Append("If-None-Match", *p.input.IfNoneMatch) } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers), - autorest.WithBytes(&input.Content)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// PutPageUpdateSender sends the PutPageUpdate request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutPageUpdateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p putPageUpdateOptions) ToOData() *odata.Query { + return nil } -// PutPageUpdateResponder handles the response to the PutPageUpdate request. The method always -// closes the http.Response Body. -func (client Client) PutPageUpdateResponder(resp *http.Response) (result PutPageUpdateResult, err error) { - if resp != nil && resp.Header != nil { - result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") - result.ContentMD5 = resp.Header.Get("Content-MD5") - result.LastModified = resp.Header.Get("Last-Modified") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (p putPageUpdateOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "page") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go index 4057cf275676..a31673f4e25a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go @@ -5,51 +5,78 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given Blob -// This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, containerName, blobName string) string { - domain := endpoints.GetBlobEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s/%s", domain, containerName, blobName) -} +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = BlobId{} + +type BlobId struct { + // AccountId specifies the ID of the Storage Account where this Blob exists. + AccountId accounts.AccountId -type ResourceID struct { - AccountName string + // ContainerName specifies the name of the Container within this Storage Account where this + // Blob exists. ContainerName string - BlobName string + + // BlobName specifies the name of this Blob. + BlobName string +} + +func NewBlobID(accountId accounts.AccountId, containerName, blobName string) BlobId { + return BlobId{ + AccountId: accountId, + ContainerName: containerName, + BlobName: blobName, + } } -// ParseResourceID parses the Resource ID and returns an object which can be used -// to interact with the Blob Resource -func ParseResourceID(id string) (*ResourceID, error) { +func (b BlobId) ID() string { + return fmt.Sprintf("%s/%s/%s", b.AccountId.ID(), b.ContainerName, b.BlobName) +} + +func (b BlobId) String() string { + components := []string{ + fmt.Sprintf("Account %q", b.AccountId.String()), + fmt.Sprintf("Container Name %q", b.ContainerName), + } + return fmt.Sprintf("Blob %q (%s)", b.BlobName, strings.Join(components, " / ")) +} + +// ParseBlobID parses `input` into a Blob ID using a known `domainSuffix` +func ParseBlobID(input, domainSuffix string) (*BlobId, error) { // example: https://foo.blob.core.windows.net/Bar/example.vhd - if id == "" { - return nil, fmt.Errorf("`id` was empty") + if input == "" { + return nil, fmt.Errorf("`input` was empty") } - uri, err := url.Parse(id) + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) + } + + if account.SubDomainType != accounts.BlobSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.BlobSubDomainType), string(account.SubDomainType)) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) } path := strings.TrimPrefix(uri.Path, "/") segments := strings.Split(path, "/") - if len(segments) == 0 { - return nil, fmt.Errorf("Expected the path to contain segments but got none") + if len(segments) != 2 { + return nil, fmt.Errorf("expected the path to contain 2 segments but got %d", len(segments)) } containerName := segments[0] blobName := strings.TrimPrefix(path, containerName) blobName = strings.TrimPrefix(blobName, "/") - return &ResourceID{ - AccountName: *accountName, + return &BlobId{ + AccountId: *account, ContainerName: containerName, BlobName: blobName, }, nil diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go index dd0f0b8782b1..35cca5b8d7f9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go @@ -2,92 +2,80 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type SetTierInput struct { + Tier AccessTier +} + +type SetTierResponse struct { + HttpResponse *client.Response +} + // SetTier sets the tier on a blob. -func (client Client) SetTier(ctx context.Context, accountName, containerName, blobName string, tier AccessTier) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "SetTier", "`accountName` cannot be an empty string.") - } +func (c Client) SetTier(ctx context.Context, containerName, blobName string, input SetTierInput) (resp SetTierResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "SetTier", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "SetTier", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "SetTier", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - req, err := client.SetTierPreparer(ctx, accountName, containerName, blobName, tier) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "SetTier", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: setTierOptions{ + tier: input.Tier, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.SetTierSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "SetTier", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetTierResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "SetTier", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetTierPreparer prepares the SetTier request. -func (client Client) SetTierPreparer(ctx context.Context, accountName, containerName, blobName string, tier AccessTier) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("path", "tier"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-access-tier": string(tier), - } +type setTierOptions struct { + tier AccessTier +} - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (s setTierOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-access-tier", string(s.tier)) + return headers } -// SetTierSender sends the SetTier request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetTierSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s setTierOptions) ToOData() *odata.Query { + return nil } -// SetTierResponder handles the response to the SetTier request. The method always -// closes the http.Response Body. -func (client Client) SetTierResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return +func (s setTierOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "tier") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go index 180070b29469..8a90dcdaf204 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go @@ -6,10 +6,8 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -42,8 +40,8 @@ type SnapshotInput struct { IfNoneMatch *string } -type SnapshotResult struct { - autorest.Response +type SnapshotResponse struct { + HttpResponse *client.Response // The ETag of the snapshot ETag string @@ -55,109 +53,92 @@ type SnapshotResult struct { } // Snapshot captures a Snapshot of a given Blob -func (client Client) Snapshot(ctx context.Context, accountName, containerName, blobName string, input SnapshotInput) (result SnapshotResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "Snapshot", "`accountName` cannot be an empty string.") - } +func (c Client) Snapshot(ctx context.Context, containerName, blobName string, input SnapshotInput) (resp SnapshotResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "Snapshot", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "Snapshot", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "Snapshot", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("blobs.Client", "Snapshot", fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) } - req, err := client.SnapshotPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Snapshot", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: snapshotOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.SnapshotSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "Snapshot", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SnapshotResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Snapshot", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil && resp.HttpResponse.Header != nil { + resp.ETag = resp.HttpResponse.Header.Get("ETag") + resp.SnapshotDateTime = resp.HttpResponse.Header.Get("x-ms-snapshot") + } + return } -// SnapshotPreparer prepares the Snapshot request. -func (client Client) SnapshotPreparer(ctx context.Context, accountName, containerName, blobName string, input SnapshotInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } +type snapshotOptions struct { + input SnapshotInput +} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "snapshot"), - } +func (s snapshotOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + if s.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *s.input.LeaseID) } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + if s.input.IfModifiedSince != nil { + headers.Append("If-Modified-Since", *s.input.IfModifiedSince) } - if input.IfModifiedSince != nil { - headers["If-Modified-Since"] = *input.IfModifiedSince - } - if input.IfUnmodifiedSince != nil { - headers["If-Unmodified-Since"] = *input.IfUnmodifiedSince + if s.input.IfUnmodifiedSince != nil { + headers.Append("If-Unmodified-Since", *s.input.IfUnmodifiedSince) } - if input.IfMatch != nil { - headers["If-Match"] = *input.IfMatch - } - if input.IfNoneMatch != nil { - headers["If-None-Match"] = *input.IfNoneMatch + + if s.input.IfMatch != nil { + headers.Append("If-Match", *s.input.IfMatch) } - headers = metadata.SetIntoHeaders(headers, input.MetaData) + if s.input.IfNoneMatch != nil { + headers.Append("If-None-Match", *s.input.IfNoneMatch) + } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + headers.Merge(metadata.SetMetaDataHeaders(s.input.MetaData)) + return headers } -// SnapshotSender sends the Snapshot request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SnapshotSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s snapshotOptions) ToOData() *odata.Query { + return nil } -// SnapshotResponder handles the response to the Snapshot request. The method always -// closes the http.Response Body. -func (client Client) SnapshotResponder(resp *http.Response) (result SnapshotResult, err error) { - if resp != nil && resp.Header != nil { - result.ETag = resp.Header.Get("ETag") - result.SnapshotDateTime = resp.Header.Get("x-ms-snapshot") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (s snapshotOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "snapshot") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go index fe1be63ab216..57a02f34e819 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go @@ -2,12 +2,14 @@ package blobs import ( "context" + "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) type GetSnapshotPropertiesInput struct { @@ -21,70 +23,138 @@ type GetSnapshotPropertiesInput struct { // GetSnapshotProperties returns all user-defined metadata, standard HTTP properties, and system properties for // the specified snapshot of a blob -func (client Client) GetSnapshotProperties(ctx context.Context, accountName, containerName, blobName string, input GetSnapshotPropertiesInput) (result GetPropertiesResult, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "GetSnapshotProperties", "`accountName` cannot be an empty string.") - } +func (c Client) GetSnapshotProperties(ctx context.Context, containerName, blobName string, input GetSnapshotPropertiesInput) (resp GetPropertiesResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "GetSnapshotProperties", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "GetSnapshotProperties", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "GetSnapshotProperties", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } + if input.SnapshotID == "" { - return result, validation.NewError("blobs.Client", "GetSnapshotProperties", "`input.SnapshotID` cannot be an empty string.") + return resp, fmt.Errorf("`input.SnapshotID` cannot be an empty string") } - req, err := client.GetSnapshotPropertiesPreparer(ctx, accountName, containerName, blobName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "GetSnapshotProperties", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: snapshotGetPropertiesOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - // we re-use the GetProperties methods since this is otherwise the same - resp, err := client.GetPropertiesSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "GetSnapshotProperties", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetPropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "GetSnapshotProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.AccessTier = AccessTier(resp.HttpResponse.Header.Get("x-ms-access-tier")) + resp.AccessTierChangeTime = resp.HttpResponse.Header.Get("x-ms-access-tier-change-time") + resp.ArchiveStatus = ArchiveStatus(resp.HttpResponse.Header.Get("x-ms-archive-status")) + resp.BlobCommittedBlockCount = resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count") + resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") + resp.BlobType = BlobType(resp.HttpResponse.Header.Get("x-ms-blob-type")) + resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") + resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") + resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") + resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") + resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") + resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") + resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") + resp.CopyDestinationSnapshot = resp.HttpResponse.Header.Get("x-ms-copy-destination-snapshot") + resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") + resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") + resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") + resp.CopyStatus = CopyStatus(resp.HttpResponse.Header.Get("x-ms-copy-status")) + resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") + resp.CreationTime = resp.HttpResponse.Header.Get("x-ms-creation-time") + resp.ETag = resp.HttpResponse.Header.Get("Etag") + resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") + resp.LeaseDuration = LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) + resp.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) + resp.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) -// GetSnapshotPreparer prepares the GetSnapshot request. -func (client Client) GetSnapshotPropertiesPreparer(ctx context.Context, accountName, containerName, blobName string, input GetSnapshotPropertiesInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } + if v := resp.HttpResponse.Header.Get("x-ms-access-tier-inferred"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + return + } - queryParameters := map[string]interface{}{ - "snapshot": autorest.Encode("query", input.SnapshotID), - } + resp.AccessTierInferred = b + } + + if v := resp.HttpResponse.Header.Get("Content-Length"); v != "" { + i, innerErr := strconv.Atoi(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + resp.ContentLength = int64(i) + } + + if v := resp.HttpResponse.Header.Get("x-ms-incremental-copy"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + return + } + + resp.IncrementalCopy = b + } + + if v := resp.HttpResponse.Header.Get("x-ms-server-encrypted"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + return + } + + resp.ServerEncrypted = b + } + } } - if input.LeaseID != nil { - headers["x-ms-lease-id"] = *input.LeaseID + return +} + +type snapshotGetPropertiesOptions struct { + input GetSnapshotPropertiesInput +} + +func (s snapshotGetPropertiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if s.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *s.input.LeaseID) } + return headers +} + +func (s snapshotGetPropertiesOptions) ToOData() *odata.Query { + return nil +} - preparer := autorest.CreatePreparer( - autorest.AsHead(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (s snapshotGetPropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("snapshot", s.input.SnapshotID) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go index 9be2f81a66f2..e46277c77af1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go @@ -2,91 +2,69 @@ package blobs import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type UndeleteResponse struct { + HttpResponse *client.Response +} + // Undelete restores the contents and metadata of soft deleted blob and any associated soft deleted snapshots. -func (client Client) Undelete(ctx context.Context, accountName, containerName, blobName string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("blobs.Client", "Undelete", "`accountName` cannot be an empty string.") - } +func (c Client) Undelete(ctx context.Context, containerName, blobName string) (resp UndeleteResponse, err error) { + if containerName == "" { - return result, validation.NewError("blobs.Client", "Undelete", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } + if strings.ToLower(containerName) != containerName { - return result, validation.NewError("blobs.Client", "Undelete", "`containerName` must be a lower-cased string.") + return resp, fmt.Errorf("`containerName` must be a lower-cased string") } + if blobName == "" { - return result, validation.NewError("blobs.Client", "Undelete", "`blobName` cannot be an empty string.") + return resp, fmt.Errorf("`blobName` cannot be an empty string") } - req, err := client.UndeletePreparer(ctx, accountName, containerName, blobName) - if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Undelete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: undeleteOptions{}, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), } - resp, err := client.UndeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "blobs.Client", "Undelete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.UndeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "blobs.Client", "Undelete", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// UndeletePreparer prepares the Undelete request. -func (client Client) UndeletePreparer(ctx context.Context, accountName, containerName, blobName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - "blobName": autorest.Encode("path", blobName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("path", "undelete"), - } +type undeleteOptions struct{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (u undeleteOptions) ToHeaders() *client.Headers { + return nil } -// UndeleteSender sends the Undelete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) UndeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (u undeleteOptions) ToOData() *odata.Query { + return nil } -// UndeleteResponder handles the response to the Undelete request. The method always -// closes the http.Response Body. -func (client Client) UndeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return +func (u undeleteOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "undelete") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go index b6d69e2233b5..414d3405774a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go @@ -1,14 +1,5 @@ package blobs -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - // APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "blob/blobs" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md index 9d375483ee8e..c93528771d6e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md @@ -17,9 +17,8 @@ package main import ( "context" "fmt" - "time" - - "github.com/Azure/go-autorest/autorest" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" ) @@ -27,16 +26,24 @@ func Example() error { accountName := "storageaccount1" storageAccountKey := "ABC123...." containerName := "mycontainer" - - storageAuth := autorest.NewSharedKeyLiteAuthorizer(accountName, storageAccountKey) - containersClient := containers.New() - containersClient.Client.Authorizer = storageAuth + domainSuffix := "core.windows.net" + + containersClient, err := containers.NewWithBaseUri(fmt.Sprintf("https://%s.blob.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building client for environment: %+v", err) + } + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + containersClient.Client.SetAuthorizer(auth) ctx := context.TODO() createInput := containers.CreateInput{ AccessLevel: containers.Private, } - if _, err := containersClient.Create(ctx, accountName, containerName, createInput); err != nil { + if _, err := containersClient.Create(ctx, containerName, createInput); err != nil { return fmt.Errorf("Error creating Container: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/api.go index 622f2b00eed7..0c6b65a274b5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/api.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/api.go @@ -2,24 +2,19 @@ package containers import ( "context" - - "github.com/Azure/go-autorest/autorest" ) type StorageContainer interface { - Create(ctx context.Context, accountName, containerName string, input CreateInput) (result CreateResponse, err error) - Delete(ctx context.Context, accountName, containerName string) (result autorest.Response, err error) - GetProperties(ctx context.Context, accountName, containerName string) (ContainerProperties, error) - GetPropertiesWithLeaseID(ctx context.Context, accountName, containerName, leaseID string) (result ContainerProperties, err error) - AcquireLease(ctx context.Context, accountName, containerName string, input AcquireLeaseInput) (result AcquireLeaseResponse, err error) - BreakLease(ctx context.Context, accountName, containerName string, input BreakLeaseInput) (result BreakLeaseResponse, err error) - ChangeLease(ctx context.Context, accountName, containerName string, input ChangeLeaseInput) (result ChangeLeaseResponse, err error) - ReleaseLease(ctx context.Context, accountName, containerName, leaseID string) (result autorest.Response, err error) - RenewLease(ctx context.Context, accountName, containerName, leaseID string) (result autorest.Response, err error) - ListBlobs(ctx context.Context, accountName, containerName string, input ListBlobsInput) (result ListBlobsResult, err error) + Create(ctx context.Context, containerName string, input CreateInput) (CreateResponse, error) + Delete(ctx context.Context, containerName string) (DeleteResponse, error) + GetProperties(ctx context.Context, containerName string, input GetPropertiesInput) (GetPropertiesResponse, error) + AcquireLease(ctx context.Context, containerName string, input AcquireLeaseInput) (AcquireLeaseResponse, error) + BreakLease(ctx context.Context, containerName string, input BreakLeaseInput) (BreakLeaseResponse, error) + ChangeLease(ctx context.Context, containerName string, input ChangeLeaseInput) (ChangeLeaseResponse, error) + ReleaseLease(ctx context.Context, containerName string, input ReleaseLeaseInput) (ReleaseLeaseResponse, error) + RenewLease(ctx context.Context, containerName string, input RenewLeaseInput) (RenewLeaseResponse, error) + ListBlobs(ctx context.Context, containerName string, input ListBlobsInput) (ListBlobsResponse, error) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, containerName string) string - SetAccessControl(ctx context.Context, accountName, containerName string, level AccessLevel) (autorest.Response, error) - SetAccessControlWithLeaseID(ctx context.Context, accountName, containerName, leaseID string, level AccessLevel) (result autorest.Response, err error) - SetMetaData(ctx context.Context, accountName, containerName string, metaData map[string]string) (autorest.Response, error) - SetMetaDataWithLeaseID(ctx context.Context, accountName, containerName, leaseID string, metaData map[string]string) (result autorest.Response, err error) + SetAccessControl(ctx context.Context, containerName string, input SetAccessControlInput) (SetAccessControlResponse, error) + SetMetaData(ctx context.Context, containerName string, metaData SetMetaDataInput) (SetMetaDataResponse, error) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/client.go index 7bf494734484..ae8c43a21d22 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/client.go @@ -1,34 +1,22 @@ package containers import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for Blob Storage Containers. type Client struct { - autorest.Client - BaseURI string -} - -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) + Client *storage.Client } -// NewWithBaseURI creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } -} - -func (client Client) setAccessLevelIntoHeaders(headers map[string]interface{}, level AccessLevel) map[string]interface{} { - // If this header is not included in the request, container data is private to the account owner. - if level != Private { - headers["x-ms-blob-public-access"] = string(level) - } - - return headers + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go index 84c2887d7d1a..1acbae869d91 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go @@ -5,10 +5,8 @@ import ( "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -21,103 +19,70 @@ type CreateInput struct { } type CreateResponse struct { - autorest.Response - Error *ErrorResponse `xml:"Error"` + HttpResponse *client.Response + Error *ErrorResponse `xml:"Error"` } // Create creates a new container under the specified account. // If the container with the same name already exists, the operation fails. -func (client Client) Create(ctx context.Context, accountName, containerName string, input CreateInput) (result CreateResponse, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "Create", "`accountName` cannot be an empty string.") - } +func (c Client) Create(ctx context.Context, containerName string, input CreateInput) (resp CreateResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "Create", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("containers.Client", "Create", fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return resp, fmt.Errorf("`input.MetaData` is not valid: %+v", err) } - req, err := client.CreatePreparer(ctx, accountName, containerName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "Create", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: createOptions{ + accessLevel: input.AccessLevel, + metaData: input.MetaData, + }, + Path: fmt.Sprintf("/%s", containerName), } - - resp, err := client.CreateSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "Create", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.CreateResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "Create", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// CreatePreparer prepares the Create request. -func (client Client) CreatePreparer(ctx context.Context, accountName string, containerName string, input CreateInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = createOptions{} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "container"), - } +type createOptions struct { + accessLevel AccessLevel + metaData map[string]string +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +func (o createOptions) ToHeaders() *client.Headers { + headers := containerOptions{ + metaData: o.metaData, + }.ToHeaders() - headers = client.setAccessLevelIntoHeaders(headers, input.AccessLevel) - headers = metadata.SetIntoHeaders(headers, input.MetaData) + // If this header is not included in the request, container data is private to the account owner. + if o.accessLevel != Private { + headers.Append("x-ms-blob-public-access", string(o.accessLevel)) + } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// CreateSender sends the Create request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (createOptions) ToOData() *odata.Query { + return nil } -// CreateResponder handles the response to the Create request. The method always -// closes the http.Response Body. -func (client Client) CreateResponder(resp *http.Response) (result CreateResponse, err error) { - successfulStatusCodes := []int{ - http.StatusCreated, - } - if autorest.ResponseHasStatusCode(resp, successfulStatusCodes...) { - // when successful there's no response - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(successfulStatusCodes...), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - } else { - // however when there's an error the error's in the response - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(successfulStatusCodes...), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - } - - return +func (createOptions) ToQuery() *client.QueryParams { + return containerOptions{}.ToQuery() } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go index 30958295388e..0aea0ed7f1df 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go @@ -2,84 +2,42 @@ package containers import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) +type DeleteResponse struct { + HttpResponse *client.Response +} + // Delete marks the specified container for deletion. // The container and any blobs contained within it are later deleted during garbage collection. -func (client Client) Delete(ctx context.Context, accountName, containerName string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, containerName string) (resp DeleteResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "Delete", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } - req, err := client.DeletePreparer(ctx, accountName, containerName) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: containerOptions{}, + Path: fmt.Sprintf("/%s", containerName), } - - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "Delete", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } - -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName string, containerName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "container"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go index 1e308da67c55..2655b0ba89e1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go @@ -2,123 +2,100 @@ package containers import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -// GetProperties returns the properties for this Container without a Lease -func (client Client) GetProperties(ctx context.Context, accountName, containerName string) (ContainerProperties, error) { - // If specified, Get Container Properties only succeeds if the container’s lease is active and matches this ID. - // If there is no active lease or the ID does not match, 412 (Precondition Failed) is returned. - return client.GetPropertiesWithLeaseID(ctx, accountName, containerName, "") +type GetPropertiesInput struct { + LeaseId string } -// GetPropertiesWithLeaseID returns the properties for this Container using the specified LeaseID -func (client Client) GetPropertiesWithLeaseID(ctx context.Context, accountName, containerName, leaseID string) (result ContainerProperties, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "GetPropertiesWithLeaseID", "`accountName` cannot be an empty string.") - } +type GetPropertiesResponse struct { + HttpResponse *client.Response + Model *ContainerProperties +} + +// GetProperties returns the properties for this Container without a Lease +func (c Client) GetProperties(ctx context.Context, containerName string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "GetPropertiesWithLeaseID", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } - req, err := client.GetPropertiesWithLeaseIDPreparer(ctx, accountName, containerName, leaseID) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getPropertiesOptions{ + leaseId: input.LeaseId, + }, + Path: fmt.Sprintf("/%s", containerName), + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "GetProperties", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - - resp, err := client.GetPropertiesWithLeaseIDSender(req) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "GetProperties", resp, "Failure sending request") + err = fmt.Errorf("executing request: %+v", err) return } - result, err = client.GetPropertiesWithLeaseIDResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "GetProperties", resp, "Failure responding to request") - return + if resp.HttpResponse != nil { + resp.Model = &ContainerProperties{} + resp.Model.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) + resp.Model.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) + if resp.Model.LeaseStatus == Locked { + duration := LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) + resp.Model.LeaseDuration = &duration + } + + // If this header is not returned in the response, the container is private to the account owner. + accessLevel := resp.HttpResponse.Header.Get("x-ms-blob-public-access") + if accessLevel != "" { + resp.Model.AccessLevel = AccessLevel(accessLevel) + } else { + resp.Model.AccessLevel = Private + } + + // we can't necessarily use strconv.ParseBool here since this could be nil (only in some API versions) + resp.Model.HasImmutabilityPolicy = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-has-immutability-policy"), "true") + resp.Model.HasLegalHold = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-has-legal-hold"), "true") + resp.Model.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) } return } -// GetPropertiesWithLeaseIDPreparer prepares the GetPropertiesWithLeaseID request. -func (client Client) GetPropertiesWithLeaseIDPreparer(ctx context.Context, accountName, containerName, leaseID string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = getPropertiesOptions{} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "container"), - } +type getPropertiesOptions struct { + leaseId string +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +func (o getPropertiesOptions) ToHeaders() *client.Headers { + headers := containerOptions{}.ToHeaders() // If specified, Get Container Properties only succeeds if the container’s lease is active and matches this ID. // If there is no active lease or the ID does not match, 412 (Precondition Failed) is returned. - if leaseID != "" { - headers["x-ms-lease-id"] = leaseID + if o.leaseId != "" { + headers.Append("x-ms-lease-id", o.leaseId) } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// GetPropertiesWithLeaseIDSender sends the GetPropertiesWithLeaseID request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetPropertiesWithLeaseIDSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (getPropertiesOptions) ToOData() *odata.Query { + return nil } -// GetPropertiesWithLeaseIDResponder handles the response to the GetPropertiesWithLeaseID request. The method always -// closes the http.Response Body. -func (client Client) GetPropertiesWithLeaseIDResponder(resp *http.Response) (result ContainerProperties, err error) { - if resp != nil { - result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status")) - result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state")) - if result.LeaseStatus == Locked { - duration := LeaseDuration(resp.Header.Get("x-ms-lease-duration")) - result.LeaseDuration = &duration - } - - // If this header is not returned in the response, the container is private to the account owner. - accessLevel := resp.Header.Get("x-ms-blob-public-access") - if accessLevel != "" { - result.AccessLevel = AccessLevel(accessLevel) - } else { - result.AccessLevel = Private - } - - // we can't necessarily use strconv.ParseBool here since this could be nil (only in some API versions) - result.HasImmutabilityPolicy = strings.EqualFold(resp.Header.Get("x-ms-has-immutability-policy"), "true") - result.HasLegalHold = strings.EqualFold(resp.Header.Get("x-ms-has-legal-hold"), "true") - - result.MetaData = metadata.ParseFromHeaders(resp.Header) - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (getPropertiesOptions) ToQuery() *client.QueryParams { + return containerOptions{}.ToQuery() } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go index 061c863c43f9..409f15a47172 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go @@ -2,12 +2,11 @@ package containers import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type AcquireLeaseInput struct { @@ -19,97 +18,82 @@ type AcquireLeaseInput struct { } type AcquireLeaseResponse struct { - autorest.Response + HttpResponse *client.Response + Model *AcquireLeaseModel +} +type AcquireLeaseModel struct { LeaseID string } // AcquireLease establishes and manages a lock on a container for delete operations. -func (client Client) AcquireLease(ctx context.Context, accountName, containerName string, input AcquireLeaseInput) (result AcquireLeaseResponse, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "AcquireLease", "`accountName` cannot be an empty string.") - } +func (c Client) AcquireLease(ctx context.Context, containerName string, input AcquireLeaseInput) (resp AcquireLeaseResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "AcquireLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } // An infinite lease duration is -1 seconds. A non-infinite lease can be between 15 and 60 seconds if input.LeaseDuration != -1 && (input.LeaseDuration <= 15 || input.LeaseDuration >= 60) { - return result, validation.NewError("containers.Client", "AcquireLease", "`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds.") + return resp, fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") } - req, err := client.AcquireLeasePreparer(ctx, accountName, containerName, input) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: acquireLeaseOptions{ + leaseDuration: input.LeaseDuration, + proposedLeaseId: input.ProposedLeaseID, + }, + Path: fmt.Sprintf("/%s", containerName), + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "AcquireLease", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - - resp, err := client.AcquireLeaseSender(req) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "AcquireLease", resp, "Failure sending request") + err = fmt.Errorf("executing request: %+v", err) return } - result, err = client.AcquireLeaseResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "AcquireLease", resp, "Failure responding to request") - return + if resp.HttpResponse != nil { + resp.Model = &AcquireLeaseModel{ + LeaseID: resp.HttpResponse.Header.Get("x-ms-lease-id"), + } } return } -// AcquireLeasePreparer prepares the AcquireLease request. -func (client Client) AcquireLeasePreparer(ctx context.Context, accountName string, containerName string, input AcquireLeaseInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = acquireLeaseOptions{} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "container"), - "comp": autorest.Encode("path", "lease"), - } +type acquireLeaseOptions struct { + leaseDuration int + proposedLeaseId string +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "acquire", - "x-ms-lease-duration": input.LeaseDuration, - } +func (o acquireLeaseOptions) ToHeaders() *client.Headers { + headers := containerOptions{}.ToHeaders() - if input.ProposedLeaseID != "" { - headers["x-ms-proposed-lease-id"] = input.ProposedLeaseID + headers.Append("x-ms-lease-action", "acquire") + headers.Append("x-ms-lease-duration", fmt.Sprintf("%d", o.leaseDuration)) + + if o.proposedLeaseId != "" { + headers.Append("x-ms-proposed-lease-id", o.proposedLeaseId) } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// AcquireLeaseSender sends the AcquireLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) AcquireLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (o acquireLeaseOptions) ToOData() *odata.Query { + return nil } -// AcquireLeaseResponder handles the response to the AcquireLease request. The method always -// closes the http.Response Body. -func (client Client) AcquireLeaseResponder(resp *http.Response) (result AcquireLeaseResponse, err error) { - if resp != nil { - result.LeaseID = resp.Header.Get("x-ms-lease-id") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (o acquireLeaseOptions) ToQuery() *client.QueryParams { + query := containerOptions{}.ToQuery() + query.Append("comp", "lease") + return query } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go index 08acfb7a3116..0ede9a818a0f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go @@ -2,13 +2,12 @@ package containers import ( "context" + "fmt" "net/http" "strconv" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type BreakLeaseInput struct { @@ -26,104 +25,88 @@ type BreakLeaseInput struct { } type BreakLeaseResponse struct { - autorest.Response + HttpResponse *client.Response + Model *BreakLeaseModel +} +type BreakLeaseModel struct { // Approximate time remaining in the lease period, in seconds. // If the break is immediate, 0 is returned. LeaseTime int } // BreakLease breaks a lock based on it's Lease ID -func (client Client) BreakLease(ctx context.Context, accountName, containerName string, input BreakLeaseInput) (result BreakLeaseResponse, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "BreakLease", "`accountName` cannot be an empty string.") - } +func (c Client) BreakLease(ctx context.Context, containerName string, input BreakLeaseInput) (resp BreakLeaseResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "BreakLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } if input.LeaseID == "" { - return result, validation.NewError("containers.Client", "BreakLease", "`input.LeaseID` cannot be an empty string.") + return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") } - req, err := client.BreakLeasePreparer(ctx, accountName, containerName, input) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: breakLeaseOptions{ + breakPeriod: input.BreakPeriod, + leaseId: input.LeaseID, + }, + Path: fmt.Sprintf("/%s", containerName), + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "BreakLease", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - - resp, err := client.BreakLeaseSender(req) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "BreakLease", resp, "Failure sending request") + err = fmt.Errorf("executing request: %+v", err) return } - result, err = client.BreakLeaseResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "BreakLease", resp, "Failure responding to request") - return + if resp.HttpResponse != nil { + leaseRaw := resp.HttpResponse.Header.Get("x-ms-lease-time") + if leaseRaw != "" { + if i, err := strconv.Atoi(leaseRaw); err == nil { + resp.Model = &BreakLeaseModel{ + LeaseTime: i, + } + } + } } return } -// BreakLeasePreparer prepares the BreakLease request. -func (client Client) BreakLeasePreparer(ctx context.Context, accountName string, containerName string, input BreakLeaseInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = breakLeaseOptions{} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "container"), - "comp": autorest.Encode("path", "lease"), - } +type breakLeaseOptions struct { + breakPeriod *int + leaseId string +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "break", - "x-ms-lease-id": input.LeaseID, - } +func (o breakLeaseOptions) ToHeaders() *client.Headers { + headers := containerOptions{}.ToHeaders() + + headers.Append("x-ms-lease-action", "break") + headers.Append("x-ms-lease-id", o.leaseId) - if input.BreakPeriod != nil { - headers["x-ms-lease-break-period"] = *input.BreakPeriod + if o.breakPeriod != nil { + headers.Append("x-ms-lease-break-period", fmt.Sprintf("%d", *o.breakPeriod)) } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// BreakLeaseSender sends the BreakLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) BreakLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (o breakLeaseOptions) ToOData() *odata.Query { + return nil } -// BreakLeaseResponder handles the response to the BreakLease request. The method always -// closes the http.Response Body. -func (client Client) BreakLeaseResponder(resp *http.Response) (result BreakLeaseResponse, err error) { - if resp != nil { - leaseRaw := resp.Header.Get("x-ms-lease-time") - if leaseRaw != "" { - i, err := strconv.Atoi(leaseRaw) - if err == nil { - result.LeaseTime = i - } - } - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (o breakLeaseOptions) ToQuery() *client.QueryParams { + query := containerOptions{}.ToQuery() + query.Append("comp", "lease") + return query } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go index dfbcb132dae3..6326507707ee 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go @@ -2,12 +2,11 @@ package containers import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type ChangeLeaseInput struct { @@ -16,96 +15,81 @@ type ChangeLeaseInput struct { } type ChangeLeaseResponse struct { - autorest.Response + HttpResponse *client.Response + Model *ChangeLeaseModel +} +type ChangeLeaseModel struct { LeaseID string } // ChangeLease changes the lock from one Lease ID to another Lease ID -func (client Client) ChangeLease(ctx context.Context, accountName, containerName string, input ChangeLeaseInput) (result ChangeLeaseResponse, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "ChangeLease", "`accountName` cannot be an empty string.") - } +func (c Client) ChangeLease(ctx context.Context, containerName string, input ChangeLeaseInput) (resp ChangeLeaseResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "ChangeLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } if input.ExistingLeaseID == "" { - return result, validation.NewError("containers.Client", "ChangeLease", "`input.ExistingLeaseID` cannot be an empty string.") + return resp, fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") } if input.ProposedLeaseID == "" { - return result, validation.NewError("containers.Client", "ChangeLease", "`input.ProposedLeaseID` cannot be an empty string.") + return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") } - req, err := client.ChangeLeasePreparer(ctx, accountName, containerName, input) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: changeLeaseOptions{ + existingLeaseId: input.ExistingLeaseID, + proposedLeaseId: input.ProposedLeaseID, + }, + Path: fmt.Sprintf("/%s", containerName), + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "ChangeLease", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - - resp, err := client.ChangeLeaseSender(req) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "ChangeLease", resp, "Failure sending request") + err = fmt.Errorf("executing request: %+v", err) return } - result, err = client.ChangeLeaseResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "ChangeLease", resp, "Failure responding to request") - return + if resp.HttpResponse != nil { + resp.Model = &ChangeLeaseModel{ + LeaseID: resp.HttpResponse.Header.Get("x-ms-lease-id"), + } } return } -// ChangeLeasePreparer prepares the ChangeLease request. -func (client Client) ChangeLeasePreparer(ctx context.Context, accountName string, containerName string, input ChangeLeaseInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = changeLeaseOptions{} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "container"), - "comp": autorest.Encode("path", "lease"), - } +type changeLeaseOptions struct { + existingLeaseId string + proposedLeaseId string +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "change", - "x-ms-lease-id": input.ExistingLeaseID, - "x-ms-proposed-lease-id": input.ProposedLeaseID, - } +func (o changeLeaseOptions) ToHeaders() *client.Headers { + headers := containerOptions{}.ToHeaders() - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} + headers.Append("x-ms-lease-action", "change") + headers.Append("x-ms-lease-id", o.existingLeaseId) + headers.Append("x-ms-proposed-lease-id", o.proposedLeaseId) -// ChangeLeaseSender sends the ChangeLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) ChangeLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) + return headers } -// ChangeLeaseResponder handles the response to the ChangeLease request. The method always -// closes the http.Response Body. -func (client Client) ChangeLeaseResponder(resp *http.Response) (result ChangeLeaseResponse, err error) { - if resp != nil { - result.LeaseID = resp.Header.Get("x-ms-lease-id") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (o changeLeaseOptions) ToOData() *odata.Query { + return nil +} - return +func (o changeLeaseOptions) ToQuery() *client.QueryParams { + query := containerOptions{}.ToQuery() + query.Append("comp", "lease") + return query } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go index fafcf98f1e67..8a2cf4114e00 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go @@ -2,91 +2,76 @@ package containers import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type ReleaseLeaseInput struct { + LeaseId string +} + +type ReleaseLeaseResponse struct { + HttpResponse *client.Response +} + // ReleaseLease releases the lock based on the Lease ID -func (client Client) ReleaseLease(ctx context.Context, accountName, containerName, leaseID string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "ReleaseLease", "`accountName` cannot be an empty string.") - } +func (c Client) ReleaseLease(ctx context.Context, containerName string, input ReleaseLeaseInput) (resp ReleaseLeaseResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "ReleaseLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } - if leaseID == "" { - return result, validation.NewError("containers.Client", "ReleaseLease", "`leaseID` cannot be an empty string.") + if input.LeaseId == "" { + return resp, fmt.Errorf("`input.LeaseId` cannot be an empty string") } - req, err := client.ReleaseLeasePreparer(ctx, accountName, containerName, leaseID) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "ReleaseLease", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: releaseLeaseOptions{ + leaseId: input.LeaseId, + }, + Path: fmt.Sprintf("/%s", containerName), } - - resp, err := client.ReleaseLeaseSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "ReleaseLease", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.ReleaseLeaseResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "ReleaseLease", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// ReleaseLeasePreparer prepares the ReleaseLease request. -func (client Client) ReleaseLeasePreparer(ctx context.Context, accountName string, containerName string, leaseID string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = releaseLeaseOptions{} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "container"), - "comp": autorest.Encode("path", "lease"), - } +type releaseLeaseOptions struct { + leaseId string +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "release", - "x-ms-lease-id": leaseID, - } +func (o releaseLeaseOptions) ToHeaders() *client.Headers { + headers := containerOptions{}.ToHeaders() - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} + headers.Append("x-ms-lease-action", "release") + headers.Append("x-ms-lease-id", o.leaseId) -// ReleaseLeaseSender sends the ReleaseLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) ReleaseLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) + return headers } -// ReleaseLeaseResponder handles the response to the ReleaseLease request. The method always -// closes the http.Response Body. -func (client Client) ReleaseLeaseResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (o releaseLeaseOptions) ToOData() *odata.Query { + return nil +} - return +func (o releaseLeaseOptions) ToQuery() *client.QueryParams { + query := containerOptions{}.ToQuery() + query.Append("comp", "lease") + return query } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go index cab50bff9d21..eda202989f23 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go @@ -2,91 +2,76 @@ package containers import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type RenewLeaseInput struct { + LeaseId string +} + +type RenewLeaseResponse struct { + HttpResponse *client.Response +} + // RenewLease renews the lock based on the Lease ID -func (client Client) RenewLease(ctx context.Context, accountName, containerName, leaseID string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "RenewLease", "`accountName` cannot be an empty string.") - } +func (c Client) RenewLease(ctx context.Context, containerName string, input RenewLeaseInput) (resp RenewLeaseResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "RenewLease", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } - if leaseID == "" { - return result, validation.NewError("containers.Client", "RenewLease", "`leaseID` cannot be an empty string.") + if input.LeaseId == "" { + return resp, fmt.Errorf("`input.LeaseId` cannot be an empty string") } - req, err := client.RenewLeasePreparer(ctx, accountName, containerName, leaseID) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "RenewLease", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: renewLeaseOptions{ + leaseId: input.LeaseId, + }, + Path: fmt.Sprintf("/%s", containerName), } - - resp, err := client.RenewLeaseSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "RenewLease", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.RenewLeaseResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "RenewLease", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// RenewLeasePreparer prepares the RenewLease request. -func (client Client) RenewLeasePreparer(ctx context.Context, accountName string, containerName string, leaseID string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = renewLeaseOptions{} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "container"), - "comp": autorest.Encode("path", "lease"), - } +type renewLeaseOptions struct { + leaseId string +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-lease-action": "renew", - "x-ms-lease-id": leaseID, - } +func (o renewLeaseOptions) ToHeaders() *client.Headers { + headers := containerOptions{}.ToHeaders() - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} + headers.Append("x-ms-lease-action", "renew") + headers.Append("x-ms-lease-id", o.leaseId) -// RenewLeaseSender sends the RenewLease request. The method will close the -// http.Response Body if it receives an error. -func (client Client) RenewLeaseSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) + return headers } -// RenewLeaseResponder handles the response to the RenewLease request. The method always -// closes the http.Response Body. -func (client Client) RenewLeaseResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (o renewLeaseOptions) ToOData() *odata.Query { + return nil +} - return +func (o renewLeaseOptions) ToQuery() *client.QueryParams { + query := containerOptions{}.ToQuery() + query.Append("comp", "lease") + return query } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go index 82797d091d36..f3bd4674d30d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go @@ -2,13 +2,12 @@ package containers import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type ListBlobsInput struct { @@ -19,9 +18,12 @@ type ListBlobsInput struct { Prefix *string } -type ListBlobsResult struct { - autorest.Response +type ListBlobsResponse struct { + HttpResponse *client.Response + Model *ListBlobsResult +} +type ListBlobsResult struct { Delimiter string `xml:"Delimiter"` Marker string `xml:"Marker"` MaxResults int `xml:"MaxResults"` @@ -78,102 +80,90 @@ type BlobPrefix struct { } // ListBlobs lists the blobs matching the specified query within the specified Container -func (client Client) ListBlobs(ctx context.Context, accountName, containerName string, input ListBlobsInput) (result ListBlobsResult, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "ListBlobs", "`accountName` cannot be an empty string.") - } +func (c Client) ListBlobs(ctx context.Context, containerName string, input ListBlobsInput) (resp ListBlobsResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "ListBlobs", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } if input.MaxResults != nil && (*input.MaxResults <= 0 || *input.MaxResults > 5000) { - return result, validation.NewError("containers.Client", "ListBlobs", "`input.MaxResults` can either be nil or between 0 and 5000.") + return resp, fmt.Errorf("`input.MaxResults` can either be nil or between 0 and 5000") } - - req, err := client.ListBlobsPreparer(ctx, accountName, containerName, input) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: listBlobsOptions{ + delimiter: input.Delimiter, + include: input.Include, + marker: input.Marker, + maxResults: input.MaxResults, + prefix: input.Prefix, + }, + Path: fmt.Sprintf("/%s", containerName), + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "ListBlobs", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - - resp, err := client.ListBlobsSender(req) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "ListBlobs", resp, "Failure sending request") + err = fmt.Errorf("executing request: %+v", err) return } - result, err = client.ListBlobsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "ListBlobs", resp, "Failure responding to request") - return + if resp.HttpResponse != nil { + if err = resp.HttpResponse.Unmarshal(&resp.Model); err != nil { + err = fmt.Errorf("unmarshaling response: %+v", err) + return + } } return } -// ListBlobsPreparer prepares the ListBlobs request. -func (client Client) ListBlobsPreparer(ctx context.Context, accountName, containerName string, input ListBlobsInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = listBlobsOptions{} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "list"), - "restype": autorest.Encode("query", "container"), - } +type listBlobsOptions struct { + delimiter *string + include *[]Dataset + marker *string + maxResults *int + prefix *string +} - if input.Delimiter != nil { - queryParameters["delimiter"] = autorest.Encode("query", *input.Delimiter) +func (o listBlobsOptions) ToHeaders() *client.Headers { + return nil +} + +func (o listBlobsOptions) ToOData() *odata.Query { + return nil +} + +func (o listBlobsOptions) ToQuery() *client.QueryParams { + query := containerOptions{}.ToQuery() + query.Append("comp", "list") + + if o.delimiter != nil { + query.Append("delimiter", *o.delimiter) } - if input.Include != nil { + if o.include != nil { vals := make([]string, 0) - for _, v := range *input.Include { + for _, v := range *o.include { vals = append(vals, string(v)) } include := strings.Join(vals, ",") - queryParameters["include"] = autorest.Encode("query", include) + query.Append("include", include) } - if input.Marker != nil { - queryParameters["marker"] = autorest.Encode("query", *input.Marker) + if o.marker != nil { + query.Append("marker", *o.marker) } - if input.MaxResults != nil { - queryParameters["maxresults"] = autorest.Encode("query", *input.MaxResults) + if o.maxResults != nil { + query.Append("maxresults", fmt.Sprintf("%d", *o.maxResults)) } - if input.Prefix != nil { - queryParameters["prefix"] = autorest.Encode("query", *input.Prefix) + if o.prefix != nil { + query.Append("prefix", *o.prefix) } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListBlobsSender sends the ListBlobs request. The method will close the -// http.Response Body if it receives an error. -func (client Client) ListBlobsSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// ListBlobsResponder handles the response to the ListBlobs request. The method always -// closes the http.Response Body. -func (client Client) ListBlobsResponder(resp *http.Response) (result ListBlobsResult, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return + return query } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go index adba36818aa1..ddfe1953aae6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go @@ -1,7 +1,5 @@ package containers -import "github.com/Azure/go-autorest/autorest" - type AccessLevel string var ( @@ -21,8 +19,6 @@ var ( ) type ContainerProperties struct { - autorest.Response - AccessLevel AccessLevel LeaseStatus LeaseStatus LeaseState LeaseState diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/options.go new file mode 100644 index 000000000000..73fadf16ae8f --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/options.go @@ -0,0 +1,35 @@ +package containers + +import ( + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/tombuildsstuff/giovanni/storage/internal/metadata" +) + +var _ client.Options = containerOptions{} + +type containerOptions struct { + metaData map[string]string +} + +func (o containerOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + + metaDataHeaders := make(map[string]interface{}) + metadata.SetIntoHeaders(metaDataHeaders, o.metaData) + for k, v := range metaDataHeaders { + headers.Append(k, v.(string)) + } + + return headers +} + +func (containerOptions) ToOData() *odata.Query { + return nil +} + +func (containerOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "container") + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go index d35674a7868d..321ea60e4a29 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go @@ -5,49 +5,77 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given Container -// This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, containerName string) string { - domain := endpoints.GetBlobEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s", domain, containerName) -} - // GetResourceManagerResourceID returns the Resource Manager specific // ResourceID for a specific Storage Container -func (client Client) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, containerName string) string { +func (c Client) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, containerName string) string { fmtStr := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/blobServices/default/containers/%s" return fmt.Sprintf(fmtStr, subscriptionID, resourceGroup, accountName, containerName) } -type ResourceID struct { - AccountName string +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = ContainerId{} + +type ContainerId struct { + // AccountId specifies the ID of the Storage Account where this Container exists. + AccountId accounts.AccountId + + // ContainerName specifies the name of this Container. ContainerName string } -// ParseResourceID parses the Resource ID and returns an object which can be used -// to interact with the Container Resource -func ParseResourceID(id string) (*ResourceID, error) { +func NewContainerID(accountId accounts.AccountId, containerName string) ContainerId { + return ContainerId{ + AccountId: accountId, + ContainerName: containerName, + } +} + +func (b ContainerId) ID() string { + return fmt.Sprintf("%s/%s", b.AccountId.ID(), b.ContainerName) +} + +func (b ContainerId) String() string { + components := []string{ + fmt.Sprintf("Account %q", b.AccountId.String()), + } + return fmt.Sprintf("Container %q (%s)", b.ContainerName, strings.Join(components, " / ")) +} + +// ParseContainerID parses `input` into a Container ID using a known `domainSuffix` +func ParseContainerID(input, domainSuffix string) (*ContainerId, error) { // example: https://foo.blob.core.windows.net/Bar - if id == "" { - return nil, fmt.Errorf("`id` was empty") + if input == "" { + return nil, fmt.Errorf("`input` was empty") } - uri, err := url.Parse(id) + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + if account.SubDomainType != accounts.BlobSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.BlobSubDomainType), string(account.SubDomainType)) + } + + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) + } + + path := strings.TrimPrefix(uri.Path, "/") + segments := strings.Split(path, "/") + if len(segments) != 1 { + return nil, fmt.Errorf("expected the path to contain 1 segment but got %d", len(segments)) } containerName := strings.TrimPrefix(uri.Path, "/") - return &ResourceID{ - AccountName: *accountName, + return &ContainerId{ + AccountId: *account, ContainerName: containerName, }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go index fcf4e1056fa4..642053735ff4 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go @@ -2,99 +2,85 @@ package containers import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) -// SetAccessControl sets the Access Control for a Container without a Lease ID -func (client Client) SetAccessControl(ctx context.Context, accountName, containerName string, level AccessLevel) (autorest.Response, error) { - return client.SetAccessControlWithLeaseID(ctx, accountName, containerName, "", level) +type SetAccessControlInput struct { + AccessLevel AccessLevel + LeaseId string } -// SetAccessControlWithLeaseID sets the Access Control for a Container using the specified Lease ID -func (client Client) SetAccessControlWithLeaseID(ctx context.Context, accountName, containerName, leaseID string, level AccessLevel) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "SetAccessControl", "`accountName` cannot be an empty string.") - } +type SetAccessControlResponse struct { + HttpResponse *client.Response +} + +// SetAccessControl sets the Access Control for a Container without a Lease ID +// NOTE: The SetAccessControl operation only supports Shared Key authorization. +func (c Client) SetAccessControl(ctx context.Context, containerName string, input SetAccessControlInput) (resp SetAccessControlResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "SetAccessControl", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } - req, err := client.SetAccessControlWithLeaseIDPreparer(ctx, accountName, containerName, leaseID, level) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "SetAccessControl", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: setAccessControlListOptions{ + accessLevel: input.AccessLevel, + leaseId: input.LeaseId, + }, + Path: fmt.Sprintf("/%s", containerName), } - - resp, err := client.SetAccessControlWithLeaseIDSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "SetAccessControl", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.SetAccessControlWithLeaseIDResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "SetAccessControl", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetAccessControlWithLeaseIDPreparer prepares the SetAccessControlWithLeaseID request. -func (client Client) SetAccessControlWithLeaseIDPreparer(ctx context.Context, accountName, containerName, leaseID string, level AccessLevel) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } +var _ client.Options = setAccessControlListOptions{} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("path", "acl"), - "restype": autorest.Encode("path", "container"), - } +type setAccessControlListOptions struct { + accessLevel AccessLevel + leaseId string +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +func (o setAccessControlListOptions) ToHeaders() *client.Headers { + headers := containerOptions{}.ToHeaders() - headers = client.setAccessLevelIntoHeaders(headers, level) + // If this header is not included in the request, container data is private to the account owner. + if o.accessLevel != Private { + headers.Append("x-ms-blob-public-access", string(o.accessLevel)) + } // If specified, Get Container Properties only succeeds if the container’s lease is active and matches this ID. // If there is no active lease or the ID does not match, 412 (Precondition Failed) is returned. - if leaseID != "" { - headers["x-ms-lease-id"] = leaseID + if o.leaseId != "" { + headers.Append("x-ms-lease-id", o.leaseId) } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetAccessControlWithLeaseIDSender sends the SetAccessControlWithLeaseID request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetAccessControlWithLeaseIDSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (o setAccessControlListOptions) ToOData() *odata.Query { + return nil } -// SetAccessControlWithLeaseIDResponder handles the response to the SetAccessControlWithLeaseID request. The method always -// closes the http.Response Body. -func (client Client) SetAccessControlWithLeaseIDResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (o setAccessControlListOptions) ToQuery() *client.QueryParams { + query := containerOptions{}.ToQuery() + query.Append("comp", "acl") + return query } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go index fb9e07fdefa9..578c9a169558 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go @@ -5,101 +5,82 @@ import ( "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -// SetMetaData sets the specified MetaData on the Container without a Lease ID -func (client Client) SetMetaData(ctx context.Context, accountName, containerName string, metaData map[string]string) (autorest.Response, error) { - return client.SetMetaDataWithLeaseID(ctx, accountName, containerName, "", metaData) +type SetMetaDataInput struct { + MetaData map[string]string + LeaseId string } -// SetMetaDataWithLeaseID sets the specified MetaData on the Container using the specified Lease ID -func (client Client) SetMetaDataWithLeaseID(ctx context.Context, accountName, containerName, leaseID string, metaData map[string]string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("containers.Client", "SetMetaData", "`accountName` cannot be an empty string.") - } +type SetMetaDataResponse struct { + HttpResponse *client.Response +} + +// SetMetaData sets the specified MetaData on the Container without a Lease ID +func (c Client) SetMetaData(ctx context.Context, containerName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { if containerName == "" { - return result, validation.NewError("containers.Client", "SetMetaData", "`containerName` cannot be an empty string.") + return resp, fmt.Errorf("`containerName` cannot be an empty string") } - if err := metadata.Validate(metaData); err != nil { - return result, validation.NewError("containers.Client", "SetMetaData", fmt.Sprintf("`metaData` is not valid: %s.", err)) + if err := metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) } - req, err := client.SetMetaDataWithLeaseIDPreparer(ctx, accountName, containerName, leaseID, metaData) - if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "SetMetaData", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: setMetaDataOptions{ + metaData: input.MetaData, + leaseId: input.LeaseId, + }, + Path: fmt.Sprintf("/%s", containerName), } - - resp, err := client.SetMetaDataWithLeaseIDSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "containers.Client", "SetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.SetMetaDataWithLeaseIDResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "containers.Client", "SetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetMetaDataWithLeaseIDPreparer prepares the SetMetaDataWithLeaseID request. -func (client Client) SetMetaDataWithLeaseIDPreparer(ctx context.Context, accountName, containerName, leaseID string, metaData map[string]string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "containerName": autorest.Encode("path", containerName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("path", "metadata"), - "restype": autorest.Encode("path", "container"), - } +var _ client.Options = setMetaDataOptions{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type setMetaDataOptions struct { + metaData map[string]string + leaseId string +} - headers = metadata.SetIntoHeaders(headers, metaData) +func (o setMetaDataOptions) ToHeaders() *client.Headers { + headers := containerOptions{ + metaData: o.metaData, + }.ToHeaders() // If specified, Get Container Properties only succeeds if the container’s lease is active and matches this ID. // If there is no active lease or the ID does not match, 412 (Precondition Failed) is returned. - if leaseID != "" { - headers["x-ms-lease-id"] = leaseID + if o.leaseId != "" { + headers.Append("x-ms-lease-id", o.leaseId) } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{containerName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetMetaDataWithLeaseIDSender sends the SetMetaDataWithLeaseID request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetMetaDataWithLeaseIDSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (o setMetaDataOptions) ToOData() *odata.Query { + return nil } -// SetMetaDataWithLeaseIDResponder handles the response to the SetMetaDataWithLeaseID request. The method always -// closes the http.Response Body. -func (client Client) SetMetaDataWithLeaseIDResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (o setMetaDataOptions) ToQuery() *client.QueryParams { + query := containerOptions{}.ToQuery() + query.Append("comp", "metadata") + return query } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go index d3138cb35875..d55e9ee67f88 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go @@ -1,14 +1,4 @@ package containers -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - -// APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "blob/containers" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md index be6fb76139d5..df369cc10c47 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md @@ -15,67 +15,37 @@ import ( "context" "fmt" "os" - "time" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/adal" - "github.com/Azure/go-autorest/autorest/azure" "github.com/hashicorp/go-azure-helpers/authentication" "github.com/hashicorp/go-azure-helpers/sender" + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" ) func Example() error { accountName := "storageaccount1" fileSystemName := "filesystem1" + storageAccountKey := "ABC123...." + domainSuffix := "core.windows.net" + - builder := &authentication.Builder{ - SubscriptionID: os.Getenv("ARM_SUBSCRIPTION_ID"), - ClientID: os.Getenv("ARM_CLIENT_ID"), - ClientSecret: os.Getenv("ARM_CLIENT_SECRET"), - TenantID: os.Getenv("ARM_TENANT_ID"), - Environment: os.Getenv("ARM_ENVIRONMENT"), - - // Feature Toggles - SupportsClientSecretAuth: true, - } - - c, err := builder.Build() - if err != nil { - return fmt.Errorf("Error building AzureRM Client: %s", err) - } - - env, err := authentication.DetermineEnvironment(c.Environment) - if err != nil { - return err - } - - oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, c.TenantID) + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) if err != nil { - return err - } - - // OAuthConfigForTenant returns a pointer, which can be nil. - if oauthConfig == nil { - return fmt.Errorf("Unable to configure OAuthConfig for tenant %s", c.TenantID) + return fmt.Errorf("building SharedKey authorizer: %+v", err) } - - sender := sender.BuildSender("AzureRM") - ctx := context.Background() - - storageAuth, err := config.GetAuthorizationToken(sender, oauthConfig, "https://storage.azure.com/") + + fileSystemsClient, err := filesystems.NewWithBaseUri(fmt.Sprintf("https://%s.dfs.%s", accountName, domainSuffix)) if err != nil { - return fmt.Errorf("Error retrieving Authorization Token") + return fmt.Errorf("building client for environment: %+v", err) } - - - fileSystemsClient := filesystems.NewWithEnvironment(env) - fileSystemsClient.Client.Authorizer = storageAuth + fileSystemsClient.Client.SetAuthorizer(auth) input := filesystems.CreateInput{ Properties: map[string]string{}, } - if _, err = fileSystemsClient.Create(ctx, accountName, fileSystemName, input); err != nil { + + ctx := context.Background() + if _, err = fileSystemsClient.Create(ctx, fileSystemName, input); err != nil { return fmt.Errorf("Error creating: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/client.go index 91d3fe1cf45e..a1217334bdcc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/client.go @@ -1,25 +1,23 @@ package filesystems import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) -// Client is the base client for Data Lake Storage FileSystem +// Client is the base client for Data Lake Store Filesystems. type Client struct { - autorest.Client - BaseURI string -} - -// New creates an instance of the Data Lake Storage FileSystem client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) + Client *storage.Client } -// NewWithEnvironment creates an instance of the Data Lake Storage FileSystem client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } + + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go index 4217cb80af0e..d0d4bab6321e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go @@ -2,12 +2,11 @@ package filesystems import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type CreateInput struct { @@ -18,77 +17,63 @@ type CreateInput struct { Properties map[string]string } +type CreateResponse struct { + HttpResponse *client.Response +} + // Create creates a Data Lake Store Gen2 FileSystem within a Storage Account -func (client Client) Create(ctx context.Context, accountName string, fileSystemName string, input CreateInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("datalakestore.Client", "Create", "`accountName` cannot be an empty string.") - } +func (c Client) Create(ctx context.Context, fileSystemName string, input CreateInput) (resp CreateResponse, err error) { + if fileSystemName == "" { - return result, validation.NewError("datalakestore.Client", "Create", "`fileSystemName` cannot be an empty string.") + return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") } - req, err := client.CreatePreparer(ctx, accountName, fileSystemName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Create", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: createOptions{ + properties: input.Properties, + }, + + Path: fmt.Sprintf("/%s", fileSystemName), } - resp, err := client.CreateSender(req) + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Create", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.CreateResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Create", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) + return } return } -// CreatePreparer prepares the Create request. -func (client Client) CreatePreparer(ctx context.Context, accountName string, fileSystemName string, input CreateInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "fileSystemName": autorest.Encode("path", fileSystemName), - } - - queryParameters := map[string]interface{}{ - "resource": autorest.Encode("query", "filesystem"), - } +type createOptions struct { + properties map[string]string +} - headers := map[string]interface{}{ - "x-ms-properties": buildProperties(input.Properties), - "x-ms-version": APIVersion, +func (o createOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + props := buildProperties(o.properties) + if props != "" { + headers.Append("x-ms-properties", props) } - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{fileSystemName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// CreateSender sends the Create request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (createOptions) ToOData() *odata.Query { + return nil } -// CreateResponder handles the response to the Create request. The method always -// closes the http.Response Body. -func (client Client) CreateResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (createOptions) ToQuery() *client.QueryParams { + return fileSystemOptions{}.ToQuery() } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go index fabc589da940..a6d33b332801 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go @@ -2,84 +2,42 @@ package filesystems import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) +type DeleteResponse struct { + HttpResponse *client.Response +} + // Delete deletes a Data Lake Store Gen2 FileSystem within a Storage Account -func (client Client) Delete(ctx context.Context, accountName string, fileSystemName string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("datalakestore.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, fileSystemName string) (resp DeleteResponse, err error) { + if fileSystemName == "" { - return result, validation.NewError("datalakestore.Client", "Delete", "`fileSystemName` cannot be an empty string.") + return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") } - req, err := client.DeletePreparer(ctx, accountName, fileSystemName) - if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: fileSystemOptions{}, + Path: fmt.Sprintf("/%s", fileSystemName), } - - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Delete", resp, "Failure responding to request") - } - - return -} - -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName string, fileSystemName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "fileSystemName": autorest.Encode("path", fileSystemName), - } - - queryParameters := map[string]interface{}{ - "resource": autorest.Encode("query", "filesystem"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + err = fmt.Errorf("executing request: %+v", err) + return } - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{fileSystemName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/options.go new file mode 100644 index 000000000000..aee33a0c4595 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/options.go @@ -0,0 +1,32 @@ +package filesystems + +import ( + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +var _ client.Options = fileSystemOptions{} + +type fileSystemOptions struct { + properties map[string]string +} + +func (o fileSystemOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + props := buildProperties(o.properties) + if props != "" { + headers.Append("x-ms-properties", props) + } + + return headers +} + +func (fileSystemOptions) ToOData() *odata.Query { + return nil +} + +func (fileSystemOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("resource", "filesystem") + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go index 0b96c95edd52..e8e4a67d0a05 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go @@ -2,17 +2,15 @@ package filesystems import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) type GetPropertiesResponse struct { - autorest.Response + HttpResponse *client.Response // A map of base64-encoded strings to store as user-defined properties with the File System // Note that items may only contain ASCII characters in the ISO-8859-1 character set. @@ -25,88 +23,46 @@ type GetPropertiesResponse struct { } // GetProperties gets the properties for a Data Lake Store Gen2 FileSystem within a Storage Account -func (client Client) GetProperties(ctx context.Context, accountName string, fileSystemName string) (result GetPropertiesResponse, err error) { - if accountName == "" { - return result, validation.NewError("datalakestore.Client", "GetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) GetProperties(ctx context.Context, fileSystemName string) (resp GetPropertiesResponse, err error) { + if fileSystemName == "" { - return result, validation.NewError("datalakestore.Client", "GetProperties", "`fileSystemName` cannot be an empty string.") + return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") } - req, err := client.GetPropertiesPreparer(ctx, accountName, fileSystemName) - if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "GetProperties", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: fileSystemOptions{}, + Path: fmt.Sprintf("/%s", fileSystemName), } - resp, err := client.GetPropertiesSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "datalakestore.Client", "GetProperties", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetPropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "GetProperties", resp, "Failure responding to request") - } - - return -} - -// GetPropertiesPreparer prepares the GetProperties request. -func (client Client) GetPropertiesPreparer(ctx context.Context, accountName string, fileSystemName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "fileSystemName": autorest.Encode("path", fileSystemName), - } - - queryParameters := map[string]interface{}{ - "resource": autorest.Encode("query", "filesystem"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + err = fmt.Errorf("executing request: %+v", err) + return } - preparer := autorest.CreatePreparer( - autorest.AsHead(), - autorest.WithBaseURL(endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{fileSystemName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) + if resp.HttpResponse != nil { - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetPropertiesSender sends the GetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// GetPropertiesResponder handles the response to the GetProperties request. The method always -// closes the http.Response Body. -func (client Client) GetPropertiesResponder(resp *http.Response) (result GetPropertiesResponse, err error) { - if resp != nil && resp.Header != nil { - - propertiesRaw := resp.Header.Get("x-ms-properties") + propertiesRaw := resp.HttpResponse.Header.Get("x-ms-properties") var properties *map[string]string properties, err = parseProperties(propertiesRaw) if err != nil { return } - result.Properties = *properties - result.NamespaceEnabled = strings.EqualFold(resp.Header.Get("x-ms-namespace-enabled"), "tru") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} + resp.Properties = *properties + resp.NamespaceEnabled = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-namespace-enabled"), "true") + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go index dde02a4455b9..82c259a236e8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go @@ -2,12 +2,11 @@ package filesystems import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type SetPropertiesInput struct { @@ -26,84 +25,75 @@ type SetPropertiesInput struct { IfUnmodifiedSince *string } +type SetPropertiesResponse struct { + HttpResponse *client.Response +} + // SetProperties sets the Properties for a Data Lake Store Gen2 FileSystem within a Storage Account -func (client Client) SetProperties(ctx context.Context, accountName string, fileSystemName string, input SetPropertiesInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("datalakestore.Client", "SetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) SetProperties(ctx context.Context, fileSystemName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { + if fileSystemName == "" { - return result, validation.NewError("datalakestore.Client", "SetProperties", "`fileSystemName` cannot be an empty string.") + return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") } - req, err := client.SetPropertiesPreparer(ctx, accountName, fileSystemName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "SetProperties", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPatch, + OptionsObject: setPropertiesOptions{ + properties: input.Properties, + ifUnmodifiedSince: input.IfUnmodifiedSince, + ifModifiedSince: input.IfModifiedSince, + }, + + Path: fmt.Sprintf("/%s", fileSystemName), } - resp, err := client.SetPropertiesSender(req) + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "datalakestore.Client", "SetProperties", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.SetPropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "SetProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) + return } return } -// SetPropertiesPreparer prepares the SetProperties request. -func (client Client) SetPropertiesPreparer(ctx context.Context, accountName string, fileSystemName string, input SetPropertiesInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "fileSystemName": autorest.Encode("path", fileSystemName), - } +type setPropertiesOptions struct { + properties map[string]string + ifModifiedSince *string + ifUnmodifiedSince *string +} - queryParameters := map[string]interface{}{ - "resource": autorest.Encode("query", "filesystem"), - } +func (o setPropertiesOptions) ToHeaders() *client.Headers { - headers := map[string]interface{}{ - "x-ms-properties": buildProperties(input.Properties), - "x-ms-version": APIVersion, + headers := &client.Headers{} + props := buildProperties(o.properties) + if props != "" { + headers.Append("x-ms-properties", props) } - if input.IfModifiedSince != nil { - headers["If-Modified-Since"] = *input.IfModifiedSince + if o.ifModifiedSince != nil { + headers.Append("If-Modified-Since", *o.ifModifiedSince) } - if input.IfUnmodifiedSince != nil { - headers["If-Unmodified-Since"] = *input.IfUnmodifiedSince + if o.ifUnmodifiedSince != nil { + headers.Append("If-Unmodified-Since", *o.ifUnmodifiedSince) } - preparer := autorest.CreatePreparer( - autorest.AsPatch(), - autorest.WithBaseURL(endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{fileSystemName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetPropertiesSender sends the SetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (setPropertiesOptions) ToOData() *odata.Query { + return nil } -// SetPropertiesResponder handles the response to the SetProperties request. The method always -// closes the http.Response Body. -func (client Client) SetPropertiesResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (setPropertiesOptions) ToQuery() *client.QueryParams { + return fileSystemOptions{}.ToQuery() } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go index 34797b20b7a9..a2664ac47590 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go @@ -5,42 +5,77 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given Data Lake Storage FileSystem -// This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, shareName string) string { - domain := endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s", domain, shareName) +// GetResourceManagerResourceID returns the Resource Manager specific +// ResourceID for a specific Data Lake FileSystem +func (c Client) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, fileSystemName string) string { + fmtStr := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/blobServices/default/containers/%s" + return fmt.Sprintf(fmtStr, subscriptionID, resourceGroup, accountName, fileSystemName) } -type ResourceID struct { - AccountName string - DirectoryName string +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = FileSystemId{} + +type FileSystemId struct { + // AccountId specifies the ID of the Storage Account where this Data Lake FileSystem exists. + AccountId accounts.AccountId + + // FileSystemName specifies the name of this Data Lake FileSystem. + FileSystemName string +} + +func NewFileSystemID(accountId accounts.AccountId, fileSystemName string) FileSystemId { + return FileSystemId{ + AccountId: accountId, + FileSystemName: fileSystemName, + } +} + +func (b FileSystemId) ID() string { + return fmt.Sprintf("%s/%s", b.AccountId.ID(), b.FileSystemName) } -// ParseResourceID parses the specified Resource ID and returns an object -// which can be used to interact with the Data Lake Storage FileSystem API's -func ParseResourceID(id string) (*ResourceID, error) { +func (b FileSystemId) String() string { + components := []string{ + fmt.Sprintf("Account %q", b.AccountId.String()), + } + return fmt.Sprintf("File System %q (%s)", b.FileSystemName, strings.Join(components, " / ")) +} + +// ParseFileSystemID parses `input` into a File System ID using a known `domainSuffix` +func ParseFileSystemID(input, domainSuffix string) (*FileSystemId, error) { // example: https://foo.dfs.core.windows.net/Bar - if id == "" { - return nil, fmt.Errorf("`id` was empty") + if input == "" { + return nil, fmt.Errorf("`input` was empty") } - uri, err := url.Parse(id) + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + if account.SubDomainType != accounts.DataLakeStoreSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.DataLakeStoreSubDomainType), string(account.SubDomainType)) + } + + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) + } + + path := strings.TrimPrefix(uri.Path, "/") + segments := strings.Split(path, "/") + if len(segments) != 1 { + return nil, fmt.Errorf("expected the path to contain 1 segment but got %d", len(segments)) } - directoryName := strings.TrimPrefix(uri.Path, "/") - return &ResourceID{ - AccountName: *accountName, - DirectoryName: directoryName, + fileSystemName := segments[0] + return &FileSystemId{ + AccountId: *account, + FileSystemName: fileSystemName, }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go index 7447ea9ade09..ff22a87f4eca 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go @@ -1,14 +1,4 @@ package filesystems -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - -// APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "datalakestore/filesystems" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/client.go index 3fb087bf8c8d..e0cb42776bf5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/client.go @@ -1,25 +1,22 @@ package paths import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for Data Lake Storage Path type Client struct { - autorest.Client - BaseURI string + Client *storage.Client } -// New creates an instance of the Data Lake Storage Path client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) -} - -// NewWithEnvironment creates an instance of the Data Lake Storage Path client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } + + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go index 600bd75a9a87..c95ea17ba1a5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go @@ -2,12 +2,11 @@ package paths import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type PathResource string @@ -19,77 +18,55 @@ type CreateInput struct { Resource PathResource } +type CreateResponse struct { + HttpResponse *client.Response +} + // Create creates a Data Lake Store Gen2 Path within a Storage Account -func (client Client) Create(ctx context.Context, accountName string, fileSystemName string, path string, input CreateInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("datalakestore.Client", "Create", "`accountName` cannot be an empty string.") - } +func (c Client) Create(ctx context.Context, fileSystemName string, path string, input CreateInput) (resp CreateResponse, err error) { + if fileSystemName == "" { - return result, validation.NewError("datalakestore.Client", "Create", "`fileSystemName` cannot be an empty string.") + return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") } - req, err := client.CreatePreparer(ctx, accountName, fileSystemName, path, input) - if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Create", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: CreateInput{ + Resource: input.Resource, + }, + + Path: fmt.Sprintf("/%s/%s", fileSystemName, path), } - resp, err := client.CreateSender(req) + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Create", resp, "Failure sending request") - return + err = fmt.Errorf("building request: %+v", err) + return resp, err } - - result, err = client.CreateResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Create", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) + return resp, err } return } -// CreatePreparer prepares the Create request. -func (client Client) CreatePreparer(ctx context.Context, accountName string, fileSystemName string, path string, input CreateInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "fileSystemName": autorest.Encode("path", fileSystemName), - "path": autorest.Encode("path", path), - } - - queryParameters := map[string]interface{}{ - "resource": autorest.Encode("query", input.Resource), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{fileSystemName}/{path}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (c CreateInput) ToHeaders() *client.Headers { + return nil } -// CreateSender sends the Create request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c CreateInput) ToOData() *odata.Query { + return nil } -// CreateResponder handles the response to the Create request. The method always -// closes the http.Response Body. -func (client Client) CreateResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (c CreateInput) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("resource", string(c.Resource)) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go index 078be57915af..4ea6e9312cdb 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go @@ -2,80 +2,42 @@ package paths import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) +type DeleteResponse struct { + HttpResponse *client.Response +} + // Delete deletes a Data Lake Store Gen2 FileSystem within a Storage Account -func (client Client) Delete(ctx context.Context, accountName string, fileSystemName string, path string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("datalakestore.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, fileSystemName string, path string) (resp DeleteResponse, err error) { + if fileSystemName == "" { - return result, validation.NewError("datalakestore.Client", "Delete", "`fileSystemName` cannot be an empty string.") + return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") } - req, err := client.DeletePreparer(ctx, accountName, fileSystemName, path) - if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodDelete, + OptionsObject: nil, + Path: fmt.Sprintf("/%s/%s", fileSystemName, path), } - - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "Delete", resp, "Failure responding to request") - } - - return -} - -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName string, fileSystemName string, path string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "fileSystemName": autorest.Encode("path", fileSystemName), - "path": autorest.Encode("path", path), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + err = fmt.Errorf("executing request: %+v", err) + return } - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{fileSystemName}/{path}", pathParameters), - autorest.WithHeaders(headers)) - - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go index 263dc53ed95b..2bb81afc574f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go @@ -2,17 +2,16 @@ package paths import ( "context" + "fmt" "net/http" "time" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type GetPropertiesResponse struct { - autorest.Response + HttpResponse *client.Response ETag string LastModified time.Time @@ -24,6 +23,10 @@ type GetPropertiesResponse struct { ACL string } +type GetPropertiesInput struct { + action GetPropertiesAction +} + type GetPropertiesAction string const ( @@ -32,103 +35,69 @@ const ( ) // GetProperties gets the properties for a Data Lake Store Gen2 Path in a FileSystem within a Storage Account -func (client Client) GetProperties(ctx context.Context, accountName string, fileSystemName string, path string, action GetPropertiesAction) (result GetPropertiesResponse, err error) { - if accountName == "" { - return result, validation.NewError("datalakestore.Client", "GetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) GetProperties(ctx context.Context, fileSystemName string, path string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { if fileSystemName == "" { - return result, validation.NewError("datalakestore.Client", "GetProperties", "`fileSystemName` cannot be an empty string.") + return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") } - req, err := client.GetPropertiesPreparer(ctx, accountName, fileSystemName, path, action) - if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "GetProperties", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: getPropertyOptions{ + action: input.action, + }, + Path: fmt.Sprintf("/%s/%s", fileSystemName, path), } - resp, err := client.GetPropertiesSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "datalakestore.Client", "GetProperties", resp, "Failure sending request") - return - } + req, err := c.Client.NewRequest(ctx, opts) - result, err = client.GetPropertiesResponder(resp) if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "GetProperties", resp, "Failure responding to request") - } - - return -} - -// GetPropertiesPreparer prepares the GetProperties request. -func (client Client) GetPropertiesPreparer(ctx context.Context, accountName string, fileSystemName string, path string, action GetPropertiesAction) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "fileSystemName": autorest.Encode("path", fileSystemName), - "path": autorest.Encode("path", path), - } - - queryParameters := map[string]interface{}{ - "action": autorest.Encode("query", string(action)), + err = fmt.Errorf("building request: %+v", err) + return resp, err } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + resp.HttpResponse, err = req.Execute(ctx) + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return resp, err } - preparer := autorest.CreatePreparer( - autorest.AsHead(), - autorest.WithBaseURL(endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{fileSystemName}/{path}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} + if resp.HttpResponse != nil { + resp.ResourceType = PathResource(resp.HttpResponse.Header.Get("x-ms-resource-type")) + resp.ETag = resp.HttpResponse.Header.Get("ETag") -// GetPropertiesSender sends the GetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// GetPropertiesResponder handles the response to the GetProperties request. The method always -// closes the http.Response Body. -func (client Client) GetPropertiesResponder(resp *http.Response) (result GetPropertiesResponse, err error) { - result = GetPropertiesResponse{} - if resp != nil && resp.Header != nil { - - resourceTypeRaw := resp.Header.Get("x-ms-resource-type") - var resourceType PathResource - if resourceTypeRaw != "" { - resourceType, err = parsePathResource(resourceTypeRaw) - if err != nil { - return GetPropertiesResponse{}, err - } - result.ResourceType = resourceType - } - result.ETag = resp.Header.Get("ETag") - - if lastModifiedRaw := resp.Header.Get("Last-Modified"); lastModifiedRaw != "" { + if lastModifiedRaw := resp.HttpResponse.Header.Get("Last-Modified"); lastModifiedRaw != "" { lastModified, err := time.Parse(time.RFC1123, lastModifiedRaw) if err != nil { return GetPropertiesResponse{}, err } - result.LastModified = lastModified + resp.LastModified = lastModified } - result.Owner = resp.Header.Get("x-ms-owner") - result.Group = resp.Header.Get("x-ms-group") - result.ACL = resp.Header.Get("x-ms-acl") + resp.Owner = resp.HttpResponse.Header.Get("x-ms-owner") + resp.Group = resp.HttpResponse.Header.Get("x-ms-group") + resp.ACL = resp.HttpResponse.Header.Get("x-ms-acl") } - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), + return +} + +type getPropertyOptions struct { + action GetPropertiesAction +} - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (g getPropertyOptions) ToHeaders() *client.Headers { + return nil +} + +func (g getPropertyOptions) ToOData() *odata.Query { + return nil +} - return result, err +func (g getPropertyOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("action", string(g.action)) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go index 7c0d677647d0..055f199cbc87 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go @@ -2,12 +2,11 @@ package paths import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type SetAccessControlInput struct { @@ -24,93 +23,81 @@ type SetAccessControlInput struct { IfUnmodifiedSince *string } +type SetPropertiesResponse struct { + HttpResponse *client.Response +} + // SetProperties sets the access control properties for a Data Lake Store Gen2 Path within a Storage Account File System -func (client Client) SetAccessControl(ctx context.Context, accountName string, fileSystemName string, path string, input SetAccessControlInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("datalakestore.Client", "SetAccessControl", "`accountName` cannot be an empty string.") - } +func (c Client) SetAccessControl(ctx context.Context, fileSystemName string, path string, input SetAccessControlInput) (resp SetPropertiesResponse, err error) { + if fileSystemName == "" { - return result, validation.NewError("datalakestore.Client", "SetAccessControl", "`fileSystemName` cannot be an empty string.") + return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") } - req, err := client.SetAccessControlPreparer(ctx, accountName, fileSystemName, path, input) - if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "SetAccessControl", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPatch, + OptionsObject: setPropertyOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", fileSystemName, path), } - resp, err := client.SetAccessControlSender(req) + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "datalakestore.Client", "SetAccessControl", resp, "Failure sending request") - return + err = fmt.Errorf("building request: %+v", err) + return resp, err } - result, err = client.SetAccessControlResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "datalakestore.Client", "SetAccessControl", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) + return resp, err } return } -// SetAccessControlPreparer prepares the SetAccessControl request. -func (client Client) SetAccessControlPreparer(ctx context.Context, accountName string, fileSystemName string, path string, input SetAccessControlInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "fileSystemName": autorest.Encode("path", fileSystemName), - "path": autorest.Encode("path", path), - } +type setPropertyOptions struct { + input SetAccessControlInput +} - queryParameters := map[string]interface{}{ - "action": autorest.Encode("query", "setAccessControl"), - } +func (s setPropertyOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + if s.input.ACL != nil { + headers.Append("x-ms-acl", *s.input.ACL) } - if input.Owner != nil { - headers["x-ms-owner"] = *input.Owner - } - if input.Group != nil { - headers["x-ms-group"] = *input.Group - } - if input.ACL != nil { - headers["x-ms-acl"] = *input.ACL + if s.input.Owner != nil { + headers.Append("x-ms-owner", *s.input.Owner) } - if input.IfModifiedSince != nil { - headers["If-Modified-Since"] = *input.IfModifiedSince + if s.input.Group != nil { + headers.Append("x-ms-group", *s.input.Group) } - if input.IfUnmodifiedSince != nil { - headers["If-Unmodified-Since"] = *input.IfUnmodifiedSince + + if s.input.IfModifiedSince != nil { + headers.Append("If-Modified-Since", *s.input.IfModifiedSince) } - preparer := autorest.CreatePreparer( - autorest.AsPatch(), - autorest.WithBaseURL(endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{fileSystemName}/{path}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) + if s.input.IfUnmodifiedSince != nil { + headers.Append("If-Unmodified-Since", *s.input.IfUnmodifiedSince) + } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetAccessControlSender sends the SetAccessControl request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetAccessControlSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s setPropertyOptions) ToOData() *odata.Query { + return nil } -// SetAccessControlResponder handles the response to the SetAccessControl request. The method always -// closes the http.Response Body. -func (client Client) SetAccessControlResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return +func (s setPropertyOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("action", "setAccessControl") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go index c32841877067..61022090e774 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go @@ -5,53 +5,76 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given Data Lake Storage FileSystem -// This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, fileSystemName, path string) string { - domain := endpoints.GetDataLakeStoreEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s/%s", domain, fileSystemName, path) -} +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = PathId{} + +type PathId struct { + // AccountId specifies the ID of the Storage Account where this path exists. + AccountId accounts.AccountId -type ResourceID struct { - AccountName string + // FileSystemName specifies the name of the Data Lake FileSystem where this Path exists. FileSystemName string - Path string + + // Path specifies the path in question. + Path string +} + +func NewPathID(accountId accounts.AccountId, fileSystemName, path string) PathId { + return PathId{ + AccountId: accountId, + FileSystemName: fileSystemName, + Path: path, + } } -// ParseResourceID parses the specified Resource ID and returns an object -// which can be used to interact with the Data Lake Storage FileSystem API's -func ParseResourceID(id string) (*ResourceID, error) { - // example: https://foo.dfs.core.windows.net/Bar - if id == "" { - return nil, fmt.Errorf("`id` was empty") +func (b PathId) ID() string { + return fmt.Sprintf("%s/%s/%s", b.AccountId.ID(), b.FileSystemName, b.Path) +} + +func (b PathId) String() string { + components := []string{ + fmt.Sprintf("File System %q", b.FileSystemName), + fmt.Sprintf("Account %q", b.AccountId.String()), } + return fmt.Sprintf("Path %q (%s)", b.Path, strings.Join(components, " / ")) +} - uri, err := url.Parse(id) +// ParsePathID parses `input` into a Path ID using a known `domainSuffix` +func ParsePathID(input, domainSuffix string) (*PathId, error) { + // example: https://foo.dfs.core.windows.net/Bar/some/path + if input == "" { + return nil, fmt.Errorf("`input` was empty") + } + + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) + } + + if account.SubDomainType != accounts.DataLakeStoreSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.DataLakeStoreSubDomainType), string(account.SubDomainType)) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) } - fileSystemAndPath := strings.TrimPrefix(uri.Path, "/") - separatorIndex := strings.Index(fileSystemAndPath, "/") - var fileSystem, path string - if separatorIndex < 0 { - fileSystem = fileSystemAndPath - path = "" - } else { - fileSystem = fileSystemAndPath[0:separatorIndex] - path = fileSystemAndPath[separatorIndex+1:] + uriPath := strings.TrimPrefix(uri.Path, "/") + segments := strings.Split(uriPath, "/") + if len(segments) < 2 { + return nil, fmt.Errorf("expected the path to contain at least 2 segments but got %d", len(segments)) } - return &ResourceID{ - AccountName: *accountName, - FileSystemName: fileSystem, + fileSystemName := segments[0] + path := strings.Join(segments[1:], "/") + return &PathId{ + AccountId: *account, + FileSystemName: fileSystemName, Path: path, }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go index 3ca5674ec31e..bd06c2d4d15c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go @@ -1,14 +1,4 @@ package paths -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - -// APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "datalakestore/paths" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md index 25474c8bc44d..602f0a6d9910 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md @@ -19,9 +19,8 @@ package main import ( "context" "fmt" - "time" - - "github.com/Azure/go-autorest/autorest" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" ) @@ -30,16 +29,28 @@ func Example() error { storageAccountKey := "ABC123...." shareName := "myshare" directoryName := "myfiles" - - storageAuth := autorest.NewSharedKeyLiteAuthorizer(accountName, storageAccountKey) - directoriesClient := directories.New() - directoriesClient.Client.Authorizer = storageAuth + domainSuffix := "core.windows.net" + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + + directoriesClient, err := directories.NewWithBaseUri(fmt.Sprintf("https://%s.dfs.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building client for environment: %+v", err) + } + directoriesClient.Client.SetAuthorizer(auth) ctx := context.TODO() metadata := map[string]string{ "hello": "world", } - if _, err := directoriesClient.Create(ctx, accountName, shareName, directoryName, metadata); err != nil { + + input := directories.CreateDirectoryInput{ + MetaData: metadata, + } + if _, err := directoriesClient.Create(ctx, shareName, directoryName, input); err != nil { return fmt.Errorf("Error creating Directory: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/api.go index 2699e668022d..e46265705c07 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/api.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/api.go @@ -2,15 +2,12 @@ package directories import ( "context" - - "github.com/Azure/go-autorest/autorest" ) type StorageDirectory interface { - Delete(ctx context.Context, accountName, shareName, path string) (result autorest.Response, err error) - GetMetaData(ctx context.Context, accountName, shareName, path string) (result GetMetaDataResult, err error) - SetMetaData(ctx context.Context, accountName, shareName, path string, metaData map[string]string) (result autorest.Response, err error) - Create(ctx context.Context, accountName, shareName, path string, input CreateDirectoryInput) (result autorest.Response, err error) - GetResourceID(accountName, shareName, directoryName string) string - Get(ctx context.Context, accountName, shareName, path string) (result GetResult, err error) + Delete(ctx context.Context, shareName, path string) (resp DeleteResponse, err error) + GetMetaData(ctx context.Context, shareName, path string) (resp GetMetaDataResponse, err error) + SetMetaData(ctx context.Context, shareName, path string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) + Create(ctx context.Context, shareName, path string, input CreateDirectoryInput) (resp CreateDirectoryResponse, err error) + Get(ctx context.Context, shareName, path string) (resp GetResponse, err error) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/client.go index bf2d315a524d..9f6af5a1d43f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/client.go @@ -1,25 +1,39 @@ package directories import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for File Storage Shares. type Client struct { - autorest.Client - BaseURI string + Client *storage.Client } -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) -} +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) + } -// NewWithEnvironment creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, + baseClient.Client.AuthorizeRequest = func(ctx context.Context, req *http.Request, authorizer auth.Authorizer) error { + if err := auth.SetAuthHeader(ctx, req, authorizer); err != nil { + return fmt.Errorf("authorizing request: %+v", err) + } + + // Only set this header if OAuth is being used (i.e. not shared key authentication) + if _, ok := authorizer.(*auth.SharedKeyAuthorizer); !ok { + req.Header.Set("x-ms-file-request-intent", "backup") + } + + return nil } + + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go index 37298319be85..7f63f9f87737 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go @@ -7,10 +7,8 @@ import ( "strings" "time" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -29,103 +27,89 @@ type CreateDirectoryInput struct { MetaData map[string]string } +type CreateDirectoryResponse struct { + HttpResponse *client.Response +} + // Create creates a new directory under the specified share or parent directory. -func (client Client) Create(ctx context.Context, accountName, shareName, path string, input CreateDirectoryInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("directories.Client", "Create", "`accountName` cannot be an empty string.") - } +func (c Client) Create(ctx context.Context, shareName, path string, input CreateDirectoryInput) (resp CreateDirectoryResponse, err error) { + if shareName == "" { - return result, validation.NewError("directories.Client", "Create", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("directories.Client", "Create", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - if path == "" { - return result, validation.NewError("directories.Client", "Create", "`path` cannot be an empty string.") + + if err = metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) } - if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("directories.Client", "Create", fmt.Sprintf("`metadata` is not valid: %s.", err)) + + if path == "" { + return resp, fmt.Errorf("`path` cannot be an empty string") } - req, err := client.CreatePreparer(ctx, accountName, shareName, path, input) - if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "Create", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: CreateOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", shareName, path), } - resp, err := client.CreateSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "directories.Client", "Create", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.CreateResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "Create", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// CreatePreparer prepares the Create request. -func (client Client) CreatePreparer(ctx context.Context, accountName, shareName, path string, input CreateDirectoryInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - } +type CreateOptions struct { + input CreateDirectoryInput +} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "directory"), +func (c CreateOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + + if len(c.input.MetaData) > 0 { + headers.Merge(metadata.SetMetaDataHeaders(c.input.MetaData)) } var coalesceDate = func(input *time.Time, defaultVal string) string { if input == nil { return defaultVal } - return input.Format(time.RFC1123) } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + // ... Yes I know these say File not Directory, I didn't design the API. + headers.Append("x-ms-file-permission", "inherit") // TODO: expose this in future + headers.Append("x-ms-file-attributes", "None") // TODO: expose this in future + headers.Append("x-ms-file-creation-time", coalesceDate(c.input.CreatedAt, "now")) + headers.Append("x-ms-file-last-write-time", coalesceDate(c.input.LastModified, "now")) - // ... Yes I know these say File not Directory, I didn't design the API. - "x-ms-file-permission": "inherit", // TODO: expose this in future - "x-ms-file-attributes": "None", // TODO: expose this in future - "x-ms-file-creation-time": coalesceDate(input.CreatedAt, "now"), - "x-ms-file-last-write-time": coalesceDate(input.LastModified, "now"), - } - - headers = metadata.SetIntoHeaders(headers, input.MetaData) - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// CreateSender sends the Create request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c CreateOptions) ToOData() *odata.Query { + return nil } -// CreateResponder handles the response to the Create request. The method always -// closes the http.Response Body. -func (client Client) CreateResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (c CreateOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "directory") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go index 9443c2592983..fb96108862e4 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go @@ -2,94 +2,54 @@ package directories import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) +type DeleteResponse struct { + HttpResponse *client.Response +} + // Delete removes the specified empty directory // Note that the directory must be empty before it can be deleted. -func (client Client) Delete(ctx context.Context, accountName, shareName, path string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("directories.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, shareName, path string) (resp DeleteResponse, err error) { + if shareName == "" { - return result, validation.NewError("directories.Client", "Delete", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("directories.Client", "Delete", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if path == "" { - return result, validation.NewError("directories.Client", "Delete", "`path` cannot be an empty string.") + return resp, fmt.Errorf("`path` cannot be an empty string") } - req, err := client.DeletePreparer(ctx, accountName, shareName, path) - if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: directoriesOptions{}, + Path: fmt.Sprintf("/%s/%s", shareName, path), } - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "directories.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "Delete", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } - -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName, shareName, path string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "directory"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go index 817d680b3fca..5c900c4d10ff 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go @@ -2,18 +2,16 @@ package directories import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -type GetResult struct { - autorest.Response +type GetResponse struct { + HttpResponse *client.Response // A set of name-value pairs that contain metadata for the directory. MetaData map[string]string @@ -25,88 +23,47 @@ type GetResult struct { // Get returns all system properties for the specified directory, // and can also be used to check the existence of a directory. -func (client Client) Get(ctx context.Context, accountName, shareName, path string) (result GetResult, err error) { - if accountName == "" { - return result, validation.NewError("directories.Client", "Get", "`accountName` cannot be an empty string.") - } +func (c Client) Get(ctx context.Context, shareName, path string) (resp GetResponse, err error) { if shareName == "" { - return result, validation.NewError("directories.Client", "Get", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("directories.Client", "Get", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if path == "" { - return result, validation.NewError("directories.Client", "Get", "`path` cannot be an empty string.") + return resp, fmt.Errorf("`path` cannot be an empty string") } - req, err := client.GetPreparer(ctx, accountName, shareName, path) - if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "Get", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: directoriesOptions{}, + Path: fmt.Sprintf("/%s/%s", shareName, path), } - resp, err := client.GetSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "directories.Client", "Get", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "Get", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetPreparer prepares the Get request. -func (client Client) GetPreparer(ctx context.Context, accountName, shareName, path string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "directory"), + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + } + resp.DirectoryMetaDataEncrypted = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-server-encrypted"), "true") } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetSender sends the Get request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// GetResponder handles the response to the Get request. The method always -// closes the http.Response Body. -func (client Client) GetResponder(resp *http.Response) (result GetResult, err error) { - if resp != nil && resp.Header != nil { - result.MetaData = metadata.ParseFromHeaders(resp.Header) - result.DirectoryMetaDataEncrypted = strings.EqualFold(resp.Header.Get("x-ms-server-encrypted"), "true") - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go index 173716de7400..1911d39616f4 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go @@ -2,105 +2,79 @@ package directories import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -type GetMetaDataResult struct { - autorest.Response +type GetMetaDataResponse struct { + HttpResponse *client.Response MetaData map[string]string } // GetMetaData returns all user-defined metadata for the specified directory -func (client Client) GetMetaData(ctx context.Context, accountName, shareName, path string) (result GetMetaDataResult, err error) { - if accountName == "" { - return result, validation.NewError("directories.Client", "GetMetaData", "`accountName` cannot be an empty string.") - } +func (c Client) GetMetaData(ctx context.Context, shareName, path string) (resp GetMetaDataResponse, err error) { if shareName == "" { - return result, validation.NewError("directories.Client", "GetMetaData", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("directories.Client", "GetMetaData", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if path == "" { - return result, validation.NewError("directories.Client", "GetMetaData", "`path` cannot be an empty string.") + return resp, fmt.Errorf("`path` cannot be an empty string") } - req, err := client.GetMetaDataPreparer(ctx, accountName, shareName, path) - if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "GetMetaData", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: GetMetaDataOptions{}, + Path: fmt.Sprintf("/%s/%s", shareName, path), } - resp, err := client.GetMetaDataSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "directories.Client", "GetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "GetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetMetaDataPreparer prepares the GetMetaData request. -func (client Client) GetMetaDataPreparer(ctx context.Context, accountName, shareName, path string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + } } - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "directory"), - "comp": autorest.Encode("query", "metadata"), - } + return +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type GetMetaDataOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (g GetMetaDataOptions) ToHeaders() *client.Headers { + return nil } -// GetMetaDataSender sends the GetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g GetMetaDataOptions) ToOData() *odata.Query { + return nil } -// GetMetaDataResponder handles the response to the GetMetaData request. The method always -// closes the http.Response Body. -func (client Client) GetMetaDataResponder(resp *http.Response) (result GetMetaDataResult, err error) { - if resp != nil && resp.Header != nil { - result.MetaData = metadata.ParseFromHeaders(resp.Header) - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (g GetMetaDataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "directory") + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go index cb133127da00..965f5ffef12a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go @@ -6,97 +6,85 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) +type SetMetaDataResponse struct { + HttpResponse *client.Response +} + +type SetMetaDataInput struct { + MetaData map[string]string +} + // SetMetaData updates user defined metadata for the specified directory -func (client Client) SetMetaData(ctx context.Context, accountName, shareName, path string, metaData map[string]string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("directories.Client", "SetMetaData", "`accountName` cannot be an empty string.") - } +func (c Client) SetMetaData(ctx context.Context, shareName, path string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { + if shareName == "" { - return result, validation.NewError("directories.Client", "SetMetaData", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("directories.Client", "SetMetaData", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - if path == "" { - return result, validation.NewError("directories.Client", "SetMetaData", "`path` cannot be an empty string.") + + if err := metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`metadata` is not valid: %s", err) } - if err := metadata.Validate(metaData); err != nil { - return result, validation.NewError("directories.Client", "SetMetaData", fmt.Sprintf("`metaData` is not valid: %s.", err)) + + if path == "" { + return resp, fmt.Errorf("`path` cannot be an empty string") } - req, err := client.SetMetaDataPreparer(ctx, accountName, shareName, path, metaData) - if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "SetMetaData", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: SetMetaDataOptions{ + metaData: input.MetaData, + }, + Path: fmt.Sprintf("/%s/%s", shareName, path), } - resp, err := client.SetMetaDataSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "directories.Client", "SetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "directories.Client", "SetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetMetaDataPreparer prepares the SetMetaData request. -func (client Client) SetMetaDataPreparer(ctx context.Context, accountName, shareName, path string, metaData map[string]string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - } +type SetMetaDataOptions struct { + metaData map[string]string +} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "directory"), - "comp": autorest.Encode("query", "metadata"), - } +func (s SetMetaDataOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + if len(s.metaData) > 0 { + headers.Merge(metadata.SetMetaDataHeaders(s.metaData)) } - - headers = metadata.SetIntoHeaders(headers, metaData) - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetMetaDataSender sends the SetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s SetMetaDataOptions) ToOData() *odata.Query { + return nil } -// SetMetaDataResponder handles the response to the SetMetaData request. The method always -// closes the http.Response Body. -func (client Client) SetMetaDataResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (s SetMetaDataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "directory") + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/options.go new file mode 100644 index 000000000000..9b324d54fbed --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/options.go @@ -0,0 +1,24 @@ +package directories + +import ( + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +var _ client.Options = directoriesOptions{} + +type directoriesOptions struct{} + +func (o directoriesOptions) ToHeaders() *client.Headers { + return &client.Headers{} +} + +func (directoriesOptions) ToOData() *odata.Query { + return nil +} + +func (directoriesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "directory") + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go index 712ed3a00c39..26b0d4ca3f43 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go @@ -5,52 +5,76 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given Directory -// This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, shareName, directoryName string) string { - domain := endpoints.GetFileEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s/%s", domain, shareName, directoryName) +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = DirectoryId{} + +type DirectoryId struct { + // AccountId specifies the ID of the Storage Account where this Directory exists. + AccountId accounts.AccountId + + // ShareName specifies the name of the File Share containing this Directory. + ShareName string + + // DirectoryPath specifies the path representing this Directory. + DirectoryPath string +} + +func NewDirectoryID(accountId accounts.AccountId, shareName, directoryPath string) DirectoryId { + return DirectoryId{ + AccountId: accountId, + ShareName: shareName, + DirectoryPath: directoryPath, + } } -type ResourceID struct { - AccountName string - DirectoryName string - ShareName string +func (b DirectoryId) ID() string { + return fmt.Sprintf("%s/%s/%s", b.AccountId.ID(), b.ShareName, b.DirectoryPath) } -// ParseResourceID parses the Resource ID into an Object -// which can be used to interact with the Directory within the File Share -func ParseResourceID(id string) (*ResourceID, error) { - // example: https://foo.file.core.windows.net/Bar/Folder - if id == "" { - return nil, fmt.Errorf("`id` was empty") +func (b DirectoryId) String() string { + components := []string{ + fmt.Sprintf("Share Name %q", b.ShareName), + fmt.Sprintf("Account %q", b.AccountId.String()), + } + return fmt.Sprintf("Directory Path %q (%s)", b.DirectoryPath, strings.Join(components, " / ")) +} + +// ParseDirectoryID parses `input` into a Directory ID using a known `domainSuffix` +func ParseDirectoryID(input, domainSuffix string) (*DirectoryId, error) { + // example: https://foo.file.core.windows.net/Bar/some/directory + if input == "" { + return nil, fmt.Errorf("`input` was empty") } - uri, err := url.Parse(id) + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + if account.SubDomainType != accounts.FileSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.FileSubDomainType), string(account.SubDomainType)) + } + + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) } path := strings.TrimPrefix(uri.Path, "/") segments := strings.Split(path, "/") - if len(segments) == 0 { - return nil, fmt.Errorf("Expected the path to contain segments but got none") + if len(segments) < 2 { + return nil, fmt.Errorf("expected the path to contain at least 2 segments but got %d", len(segments)) } - shareName := segments[0] - directoryName := strings.TrimPrefix(path, shareName) - directoryName = strings.TrimPrefix(directoryName, "/") - return &ResourceID{ - AccountName: *accountName, + directoryPath := strings.Join(segments[1:], "/") + return &DirectoryId{ + AccountId: *account, ShareName: shareName, - DirectoryName: directoryName, + DirectoryPath: directoryPath, }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go index 8446be29ebb2..508cbe75c3fe 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go @@ -1,14 +1,5 @@ package directories -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - // APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "file/directories" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md index 6ce6bbb13f96..dc8df5ff3af1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md @@ -19,9 +19,8 @@ package main import ( "context" "fmt" - "time" - - "github.com/Azure/go-autorest/autorest" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" ) @@ -31,14 +30,22 @@ func Example() error { shareName := "myshare" directoryName := "myfiles" fileName := "example.txt" - - storageAuth := autorest.NewSharedKeyLiteAuthorizer(accountName, storageAccountKey) - filesClient := files.New() - filesClient.Client.Authorizer = storageAuth + domainSuffix := "core.windows.net" + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + + filesClient, err := files.NewWithBaseUri(fmt.Sprintf("https://%s.file.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building client for environment: %+v", err) + } + filesClient.Client.SetAuthorizer(auth) ctx := context.TODO() input := files.CreateInput{} - if _, err := filesClient.Create(ctx, accountName, shareName, directoryName, fileName, input); err != nil { + if _, err := filesClient.Create(ctx, shareName, directoryName, fileName, input); err != nil { return fmt.Errorf("Error creating File: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/api.go index 96a0491e70da..f28a708ded3a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/api.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/api.go @@ -3,26 +3,22 @@ package files import ( "context" "os" - "time" - - "github.com/Azure/go-autorest/autorest" ) type StorageFile interface { - PutByteRange(ctx context.Context, accountName, shareName, path, fileName string, input PutByteRangeInput) (result autorest.Response, err error) - GetByteRange(ctx context.Context, accountName, shareName, path, fileName string, input GetByteRangeInput) (result GetByteRangeResult, err error) - ClearByteRange(ctx context.Context, accountName, shareName, path, fileName string, input ClearByteRangeInput) (result autorest.Response, err error) - SetProperties(ctx context.Context, accountName, shareName, path, fileName string, input SetPropertiesInput) (result autorest.Response, err error) - PutFile(ctx context.Context, accountName, shareName, path, fileName string, file *os.File, parallelism int) error - Copy(ctx context.Context, accountName, shareName, path, fileName string, input CopyInput) (result CopyResult, err error) - SetMetaData(ctx context.Context, accountName, shareName, path, fileName string, metaData map[string]string) (result autorest.Response, err error) - GetMetaData(ctx context.Context, accountName, shareName, path, fileName string) (result GetMetaDataResult, err error) - AbortCopy(ctx context.Context, accountName, shareName, path, fileName, copyID string) (result autorest.Response, err error) - GetFile(ctx context.Context, accountName, shareName, path, fileName string, parallelism int) (result autorest.Response, outputBytes []byte, err error) - GetResourceID(accountName, shareName, directoryName, filePath string) string - ListRanges(ctx context.Context, accountName, shareName, path, fileName string) (result ListRangesResult, err error) - GetProperties(ctx context.Context, accountName, shareName, path, fileName string) (result GetResult, err error) - Delete(ctx context.Context, accountName, shareName, path, fileName string) (result autorest.Response, err error) - Create(ctx context.Context, accountName, shareName, path, fileName string, input CreateInput) (result autorest.Response, err error) - CopyAndWait(ctx context.Context, accountName, shareName, path, fileName string, input CopyInput, pollDuration time.Duration) (result CopyResult, err error) + PutByteRange(ctx context.Context, shareName string, path string, fileName string, input PutByteRangeInput) (PutRangeResponse, error) + GetByteRange(ctx context.Context, shareName string, path string, fileName string, input GetByteRangeInput) (GetByteRangeResponse, error) + ClearByteRange(ctx context.Context, shareName string, path string, fileName string, input ClearByteRangeInput) (ClearByteRangeResponse, error) + SetProperties(ctx context.Context, shareName string, path string, fileName string, input SetPropertiesInput) (SetPropertiesResponse, error) + PutFile(ctx context.Context, shareName string, path string, fileName string, file *os.File, parallelism int) error + Copy(ctx context.Context, shareName, path, fileName string, input CopyInput) (CopyResponse, error) + SetMetaData(ctx context.Context, shareName string, path string, fileName string, input SetMetaDataInput) (SetMetaDataResponse, error) + GetMetaData(ctx context.Context, shareName string, path string, fileName string) (GetMetaDataResponse, error) + AbortCopy(ctx context.Context, shareName string, path string, fileName string, input CopyAbortInput) (CopyAbortResponse, error) + GetFile(ctx context.Context, shareName string, path string, fileName string, input GetFileInput) (GetFileResponse, error) + ListRanges(ctx context.Context, shareName, path, fileName string) (ListRangesResponse, error) + GetProperties(ctx context.Context, shareName string, path string, fileName string) (GetResponse, error) + Delete(ctx context.Context, shareName string, path string, fileName string) (DeleteResponse, error) + Create(ctx context.Context, shareName string, path string, fileName string, input CreateInput) (CreateResponse, error) + CopyAndWait(ctx context.Context, shareName, path, fileName string, input CopyInput) (CopyResponse, error) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/client.go index ecca81586b5a..39b02e7f2782 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/client.go @@ -1,25 +1,39 @@ package files import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for File Storage Shares. type Client struct { - autorest.Client - BaseURI string + Client *storage.Client } -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) -} +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) + } -// NewWithEnvironment creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, + baseClient.Client.AuthorizeRequest = func(ctx context.Context, req *http.Request, authorizer auth.Authorizer) error { + if err := auth.SetAuthHeader(ctx, req, authorizer); err != nil { + return fmt.Errorf("authorizing request: %+v", err) + } + + // Only set this header if OAuth is being used (i.e. not shared key authentication) + if _, ok := authorizer.(*auth.SharedKeyAuthorizer); !ok { + req.Header.Set("x-ms-file-request-intent", "backup") + } + + return nil } + + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go index 31768b3d52b7..577f95d60e30 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go @@ -6,10 +6,8 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -26,8 +24,8 @@ type CopyInput struct { MetaData map[string]string } -type CopyResult struct { - autorest.Response +type CopyResponse struct { + HttpResponse *client.Response // The CopyID, which can be passed to AbortCopy to abort the copy. CopyID string @@ -37,96 +35,82 @@ type CopyResult struct { } // Copy copies a blob or file to a destination file within the storage account asynchronously. -func (client Client) Copy(ctx context.Context, accountName, shareName, path, fileName string, input CopyInput) (result CopyResult, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "Copy", "`accountName` cannot be an empty string.") - } +func (c Client) Copy(ctx context.Context, shareName, path, fileName string, input CopyInput) (resp CopyResponse, err error) { + if shareName == "" { - return result, validation.NewError("files.Client", "Copy", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "Copy", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "Copy", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } + if input.CopySource == "" { - return result, validation.NewError("files.Client", "Copy", "`input.CopySource` cannot be an empty string.") + return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") } - if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("files.Client", "Copy", fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + + if err = metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) } - req, err := client.CopyPreparer(ctx, accountName, shareName, path, fileName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "Copy", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("%s/", path) } - resp, err := client.CopySender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "Copy", resp, "Failure sending request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: CopyOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s%s", shareName, path, fileName), } - result, err = client.CopyResponder(resp) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "Copy", resp, "Failure responding to request") + err = fmt.Errorf("building request: %+v", err) return } - - return -} - -// CopyPreparer prepares the Copy request. -func (client Client) CopyPreparer(ctx context.Context, accountName, shareName, path, fileName string, input CopyInput) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), + resp.HttpResponse, err = req.Execute(ctx) + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-copy-source": input.CopySource, + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") + resp.CopySuccess = resp.HttpResponse.Header.Get("x-ms-copy-status") + } } - headers = metadata.SetIntoHeaders(headers, input.MetaData) - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return } -// CopySender sends the Copy request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CopySender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +type CopyOptions struct { + input CopyInput } -// CopyResponder handles the response to the Copy request. The method always -// closes the http.Response Body. -func (client Client) CopyResponder(resp *http.Response) (result CopyResult, err error) { - if resp != nil && resp.Header != nil { - result.CopyID = resp.Header.Get("x-ms-copy-id") - result.CopySuccess = resp.Header.Get("x-ms-copy-status") +func (c CopyOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if len(c.input.MetaData) > 0 { + headers.Merge(metadata.SetMetaDataHeaders(c.input.MetaData)) } + headers.Append("x-ms-copy-source", c.input.CopySource) + return headers +} - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (c CopyOptions) ToOData() *odata.Query { + return nil +} - return +func (c CopyOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go index 2f0913185888..55611602d37e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go @@ -6,99 +6,85 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type CopyAbortInput struct { + copyID string +} + +type CopyAbortResponse struct { + HttpResponse *client.Response +} + // AbortCopy aborts a pending Copy File operation, and leaves a destination file with zero length and full metadata -func (client Client) AbortCopy(ctx context.Context, accountName, shareName, path, fileName, copyID string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "AbortCopy", "`accountName` cannot be an empty string.") - } +func (c Client) AbortCopy(ctx context.Context, shareName, path, fileName string, input CopyAbortInput) (resp CopyAbortResponse, err error) { + if shareName == "" { - return result, validation.NewError("files.Client", "AbortCopy", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "AbortCopy", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "AbortCopy", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } - if copyID == "" { - return result, validation.NewError("files.Client", "AbortCopy", "`copyID` cannot be an empty string.") + + if input.copyID == "" { + return resp, fmt.Errorf("`copyID` cannot be an empty string") } - req, err := client.AbortCopyPreparer(ctx, accountName, shareName, path, fileName, copyID) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "AbortCopy", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("%s/", path) } - resp, err := client.AbortCopySender(req) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodPut, + OptionsObject: CopyAbortOptions{ + copyId: input.copyID, + }, + Path: fmt.Sprintf("/%s/%s%s", shareName, path, fileName), + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "AbortCopy", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.AbortCopyResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "AbortCopy", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// AbortCopyPreparer prepares the AbortCopy request. -func (client Client) AbortCopyPreparer(ctx context.Context, accountName, shareName, path, fileName, copyID string) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "copy"), - "copyid": autorest.Encode("query", copyID), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-copy-action": "abort", - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type CopyAbortOptions struct { + copyId string } -// AbortCopySender sends the AbortCopy request. The method will close the -// http.Response Body if it receives an error. -func (client Client) AbortCopySender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c CopyAbortOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-copy-action", "abort") + return headers } -// AbortCopyResponder handles the response to the AbortCopy request. The method always -// closes the http.Response Body. -func (client Client) AbortCopyResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (c CopyAbortOptions) ToOData() *odata.Query { + return nil +} - return +func (c CopyAbortOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "copy") + out.Append("copyid", c.copyId) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_and_wait_poller.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_and_wait_poller.go new file mode 100644 index 000000000000..9d6e8afcfcfb --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_and_wait_poller.go @@ -0,0 +1,48 @@ +package files + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" +) + +var _ pollers.PollerType = ©AndWaitPoller{} + +func NewCopyAndWaitPoller(client *Client, shareName, path, fileName string) *copyAndWaitPoller { + return ©AndWaitPoller{ + client: client, + shareName: shareName, + path: path, + fileName: fileName, + } +} + +type copyAndWaitPoller struct { + client *Client + shareName string + path string + fileName string +} + +func (p *copyAndWaitPoller) Poll(ctx context.Context) (*pollers.PollResult, error) { + props, err := p.client.GetProperties(ctx, p.shareName, p.path, p.fileName) + if err != nil { + return nil, fmt.Errorf("retrieving copy (shareName: %s path: %s fileName: %s) : %+v", p.shareName, p.path, p.fileName, err) + } + + if strings.EqualFold(props.CopyStatus, "success") { + return &pollers.PollResult{ + Status: pollers.PollingStatusSucceeded, + PollInterval: 10 * time.Second, + }, nil + } + + // Processing + return &pollers.PollResult{ + Status: pollers.PollingStatusInProgress, + PollInterval: 10 * time.Second, + }, nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go index e6a646b1017b..1ccb5f31e635 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go @@ -3,52 +3,26 @@ package files import ( "context" "fmt" - "strings" "time" - "github.com/Azure/go-autorest/autorest" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" ) -type CopyAndWaitResult struct { - autorest.Response - - CopyID string -} - -const DefaultCopyPollDuration = 15 * time.Second - // CopyAndWait is a convenience method which doesn't exist in the API, which copies the file and then waits for the copy to complete -func (client Client) CopyAndWait(ctx context.Context, accountName, shareName, path, fileName string, input CopyInput, pollDuration time.Duration) (result CopyResult, err error) { - copy, e := client.Copy(ctx, accountName, shareName, path, fileName, input) +func (c Client) CopyAndWait(ctx context.Context, shareName, path, fileName string, input CopyInput) (resp CopyResponse, err error) { + copy, e := c.Copy(ctx, shareName, path, fileName, input) if err != nil { - result.Response = copy.Response - err = fmt.Errorf("Error copying: %s", e) + resp.HttpResponse = copy.HttpResponse + err = fmt.Errorf("error copying: %s", e) return } - result.CopyID = copy.CopyID - - // since the API doesn't return a LRO, this is a hack which also polls every 10s, but should be sufficient - for true { - props, e := client.GetProperties(ctx, accountName, shareName, path, fileName) - if e != nil { - result.Response = copy.Response - err = fmt.Errorf("Error waiting for copy: %s", e) - return - } - - switch strings.ToLower(props.CopyStatus) { - case "pending": - time.Sleep(pollDuration) - continue - - case "success": - return + resp.CopyID = copy.CopyID - default: - err = fmt.Errorf("Unexpected CopyState %q", e) - return - } + pollerType := NewCopyAndWaitPoller(&c, shareName, path, fileName) + poller := pollers.NewPoller(pollerType, 10*time.Second, pollers.DefaultNumberOfDroppedConnectionsToAllow) + if err := poller.PollUntilDone(ctx); err != nil { + return resp, fmt.Errorf("waiting for file to copy: %+v", err) } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go index d2b4ff358120..7c08a85bc1f1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go @@ -4,13 +4,12 @@ import ( "context" "fmt" "net/http" + "strconv" "strings" "time" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -51,56 +50,65 @@ type CreateInput struct { MetaData map[string]string } +type CreateResponse struct { + HttpResponse *client.Response +} + // Create creates a new file or replaces a file. -func (client Client) Create(ctx context.Context, accountName, shareName, path, fileName string, input CreateInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "Create", "`accountName` cannot be an empty string.") - } +func (c Client) Create(ctx context.Context, shareName, path, fileName string, input CreateInput) (resp CreateResponse, err error) { if shareName == "" { - return result, validation.NewError("files.Client", "Create", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "Create", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "Create", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") + } + + if err = metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) } - if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("files.Client", "Create", "`input.MetaData` cannot be an empty string.") + + if path != "" { + path = fmt.Sprintf("%s/", path) } - req, err := client.CreatePreparer(ctx, accountName, shareName, path, fileName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "Create", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: CreateOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s%s", shareName, path, fileName), } - resp, err := client.CreateSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "Create", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.CreateResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "Create", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// CreatePreparer prepares the Create request. -func (client Client) CreatePreparer(ctx context.Context, accountName, shareName, path, fileName string, input CreateInput) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), - } +type CreateOptions struct { + input CreateInput +} + +func (c CreateOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} var coalesceDate = func(input *time.Time, defaultVal string) string { if input == nil { @@ -110,60 +118,41 @@ func (client Client) CreatePreparer(ctx context.Context, accountName, shareName, return input.Format(time.RFC1123) } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-content-length": input.ContentLength, - "x-ms-type": "file", - - "x-ms-file-permission": "inherit", // TODO: expose this in future - "x-ms-file-attributes": "None", // TODO: expose this in future - "x-ms-file-creation-time": coalesceDate(input.CreatedAt, "now"), - "x-ms-file-last-write-time": coalesceDate(input.LastModified, "now"), + if len(c.input.MetaData) > 0 { + headers.Merge(metadata.SetMetaDataHeaders(c.input.MetaData)) } - if input.ContentDisposition != nil { - headers["x-ms-content-disposition"] = *input.ContentDisposition - } + headers.Append("x-ms-content-length", strconv.Itoa(int(c.input.ContentLength))) + headers.Append("x-ms-type", "file") + + headers.Append("x-ms-file-permission", "inherit") // TODO: expose this in future + headers.Append("x-ms-file-attributes", "None") // TODO: expose this in future + headers.Append("x-ms-file-creation-time", coalesceDate(c.input.CreatedAt, "now")) + headers.Append("x-ms-file-last-write-time", coalesceDate(c.input.LastModified, "now")) - if input.ContentEncoding != nil { - headers["x-ms-content-encoding"] = *input.ContentEncoding + if c.input.ContentDisposition != nil { + headers.Append("x-ms-content-disposition", *c.input.ContentDisposition) } - if input.ContentMD5 != nil { - headers["x-ms-content-md5"] = *input.ContentMD5 + if c.input.ContentEncoding != nil { + headers.Append("x-ms-content-encoding", *c.input.ContentEncoding) } - if input.ContentType != nil { - headers["x-ms-content-type"] = *input.ContentType + if c.input.ContentMD5 != nil { + headers.Append("x-ms-content-md5", *c.input.ContentMD5) } - headers = metadata.SetIntoHeaders(headers, input.MetaData) + if c.input.ContentType != nil { + headers.Append("x-ms-content-type", *c.input.ContentType) + } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// CreateSender sends the Create request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c CreateOptions) ToOData() *odata.Query { + return nil } -// CreateResponder handles the response to the Create request. The method always -// closes the http.Response Body. -func (client Client) CreateResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (c CreateOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go index 5debd767d1fd..d5e32405038f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go @@ -6,89 +6,53 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) +type DeleteResponse struct { + HttpResponse *client.Response +} + // Delete immediately deletes the file from the File Share. -func (client Client) Delete(ctx context.Context, accountName, shareName, path, fileName string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, shareName, path, fileName string) (resp DeleteResponse, err error) { + if shareName == "" { - return result, validation.NewError("files.Client", "Delete", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "Delete", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "Delete", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } - req, err := client.DeletePreparer(ctx, accountName, shareName, path, fileName) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "Delete", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("/%s/", path) } - resp, err := client.DeleteSender(req) - if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "Delete", resp, "Failure sending request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: nil, + Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), } - result, err = client.DeleteResponder(resp) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "Delete", resp, "Failure responding to request") + err = fmt.Errorf("building request: %+v", err) return } - return -} - -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName, shareName, path, fileName string) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + resp.HttpResponse, err = req.Execute(ctx) + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go index fd62f90aec8f..3e0fbad008ad 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go @@ -6,106 +6,78 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -type GetMetaDataResult struct { - autorest.Response +type GetMetaDataResponse struct { + HttpResponse *client.Response MetaData map[string]string } // GetMetaData returns the MetaData for the specified File. -func (client Client) GetMetaData(ctx context.Context, accountName, shareName, path, fileName string) (result GetMetaDataResult, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "GetMetaData", "`accountName` cannot be an empty string.") - } +func (c Client) GetMetaData(ctx context.Context, shareName, path, fileName string) (resp GetMetaDataResponse, err error) { if shareName == "" { - return result, validation.NewError("files.Client", "GetMetaData", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "GetMetaData", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "GetMetaData", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } - req, err := client.GetMetaDataPreparer(ctx, accountName, shareName, path, fileName) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "GetMetaData", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("%s/", path) + } + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: GetMetadataOptions{}, + Path: fmt.Sprintf("/%s/%s%s", shareName, path, fileName), } - resp, err := client.GetMetaDataSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "GetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "GetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetMetaDataPreparer prepares the GetMetaData request. -func (client Client) GetMetaDataPreparer(ctx context.Context, accountName, shareName, path, fileName string) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + } } - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "metadata"), - } + return +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type GetMetadataOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (m GetMetadataOptions) ToHeaders() *client.Headers { + return nil } -// GetMetaDataSender sends the GetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (m GetMetadataOptions) ToOData() *odata.Query { + return nil } -// GetMetaDataResponder handles the response to the GetMetaData request. The method always -// closes the http.Response Body. -func (client Client) GetMetaDataResponder(resp *http.Response) (result GetMetaDataResult, err error) { - if resp != nil && resp.Header != nil { - result.MetaData = metadata.ParseFromHeaders(resp.Header) - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - //metadata.ByParsingFromHeaders(&result.MetaData), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (m GetMetadataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go index 41e3ffcb8ff9..4087ef58fdc7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go @@ -6,100 +6,87 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) +type SetMetaDataResponse struct { + HttpResponse *client.Response +} + +type SetMetaDataInput struct { + MetaData map[string]string +} + // SetMetaData updates the specified File to have the specified MetaData. -func (client Client) SetMetaData(ctx context.Context, accountName, shareName, path, fileName string, metaData map[string]string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "SetMetaData", "`accountName` cannot be an empty string.") - } +func (c Client) SetMetaData(ctx context.Context, shareName, path, fileName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { if shareName == "" { - return result, validation.NewError("files.Client", "SetMetaData", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "SetMetaData", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "SetMetaData", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } - if err := metadata.Validate(metaData); err != nil { - return result, validation.NewError("files.Client", "SetMetaData", fmt.Sprintf("`metaData` is not valid: %s.", err)) + + if err = metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) } - req, err := client.SetMetaDataPreparer(ctx, accountName, shareName, path, fileName, metaData) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "SetMetaData", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("/%s/", path) } - resp, err := client.SetMetaDataSender(req) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: SetMetaDataOptions{ + metaData: input.MetaData, + }, + Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "SetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "SetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetMetaDataPreparer prepares the SetMetaData request. -func (client Client) SetMetaDataPreparer(ctx context.Context, accountName, shareName, path, fileName string, metaData map[string]string) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), - } +type SetMetaDataOptions struct { + metaData map[string]string +} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "metadata"), - } +func (s SetMetaDataOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + if len(s.metaData) > 0 { + headers.Merge(metadata.SetMetaDataHeaders(s.metaData)) } - - headers = metadata.SetIntoHeaders(headers, metaData) - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetMetaDataSender sends the SetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s SetMetaDataOptions) ToOData() *odata.Query { + return nil } -// SetMetaDataResponder handles the response to the SetMetaData request. The method always -// closes the http.Response Body. -func (client Client) SetMetaDataResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (s SetMetaDataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go index 0300b1ce5ec6..6a21f7784940 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go @@ -7,15 +7,12 @@ import ( "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -type GetResult struct { - autorest.Response +type GetResponse struct { + HttpResponse *client.Response CacheControl string ContentDisposition string @@ -36,109 +33,73 @@ type GetResult struct { } // GetProperties returns the Properties for the specified file -func (client Client) GetProperties(ctx context.Context, accountName, shareName, path, fileName string) (result GetResult, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "GetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) GetProperties(ctx context.Context, shareName, path, fileName string) (resp GetResponse, err error) { if shareName == "" { - return result, validation.NewError("files.Client", "GetProperties", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "GetProperties", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "GetProperties", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } - req, err := client.GetPropertiesPreparer(ctx, accountName, shareName, path, fileName) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "GetProperties", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("/%s/", path) } - resp, err := client.GetPropertiesSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "GetProperties", resp, "Failure sending request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: nil, + Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), } - result, err = client.GetPropertiesResponder(resp) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "GetProperties", resp, "Failure responding to request") + err = fmt.Errorf("building request: %+v", err) return } - return -} - -// GetPropertiesPreparer prepares the GetProperties request. -func (client Client) GetPropertiesPreparer(ctx context.Context, accountName, shareName, path, fileName string) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, + resp.HttpResponse, err = req.Execute(ctx) + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsHead(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetPropertiesSender sends the GetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// GetPropertiesResponder handles the response to the GetProperties request. The method always -// closes the http.Response Body. -func (client Client) GetPropertiesResponder(resp *http.Response) (result GetResult, err error) { - if resp != nil && resp.Header != nil { - result.CacheControl = resp.Header.Get("Cache-Control") - result.ContentDisposition = resp.Header.Get("Content-Disposition") - result.ContentEncoding = resp.Header.Get("Content-Encoding") - result.ContentLanguage = resp.Header.Get("Content-Language") - result.ContentMD5 = resp.Header.Get("Content-MD5") - result.ContentType = resp.Header.Get("Content-Type") - result.CopyID = resp.Header.Get("x-ms-copy-id") - result.CopyProgress = resp.Header.Get("x-ms-copy-progress") - result.CopySource = resp.Header.Get("x-ms-copy-source") - result.CopyStatus = resp.Header.Get("x-ms-copy-status") - result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description") - result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time") - result.Encrypted = strings.EqualFold(resp.Header.Get("x-ms-server-encrypted"), "true") - result.MetaData = metadata.ParseFromHeaders(resp.Header) - - contentLengthRaw := resp.Header.Get("Content-Length") - if contentLengthRaw != "" { - contentLength, err := strconv.Atoi(contentLengthRaw) - if err != nil { - return result, fmt.Errorf("Error parsing %q for Content-Length as an integer: %s", contentLengthRaw, err) + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") + resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") + resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") + resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") + resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") + resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") + resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") + resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") + resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") + resp.CopyStatus = resp.HttpResponse.Header.Get("x-ms-copy-status") + resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") + resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") + resp.Encrypted = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-server-encrypted"), "true") + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + + contentLengthRaw := resp.HttpResponse.Header.Get("Content-Length") + if contentLengthRaw != "" { + contentLength, err := strconv.Atoi(contentLengthRaw) + if err != nil { + return resp, fmt.Errorf("error parsing %q for Content-Length as an integer: %s", contentLengthRaw, err) + } + contentLengthI64 := int64(contentLength) + resp.ContentLength = &contentLengthI64 } - contentLengthI64 := int64(contentLength) - result.ContentLength = &contentLengthI64 } } - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go index 521b1bba7be7..0e2c547a8d96 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go @@ -4,13 +4,12 @@ import ( "context" "fmt" "net/http" + "strconv" "strings" "time" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -68,54 +67,61 @@ type SetPropertiesInput struct { MetaData map[string]string } +type SetPropertiesResponse struct { + HttpResponse *client.Response +} + // SetProperties sets the specified properties on the specified File -func (client Client) SetProperties(ctx context.Context, accountName, shareName, path, fileName string, input SetPropertiesInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "SetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) SetProperties(ctx context.Context, shareName, path, fileName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { if shareName == "" { - return result, validation.NewError("files.Client", "SetProperties", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "SetProperties", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "SetProperties", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } - req, err := client.SetPropertiesPreparer(ctx, accountName, shareName, path, fileName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "SetProperties", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("/%s/", path) + } + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: SetPropertiesOptions{ + input: input, + }, + Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), } - resp, err := client.SetPropertiesSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "SetProperties", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetPropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "SetProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetPropertiesPreparer prepares the SetProperties request. -func (client Client) SetPropertiesPreparer(ctx context.Context, accountName, shareName, path, fileName string, input SetPropertiesInput) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), - } +type SetPropertiesOptions struct { + input SetPropertiesInput +} +func (s SetPropertiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} var coalesceDate = func(input *time.Time, defaultVal string) string { if input == nil { return defaultVal @@ -124,63 +130,44 @@ func (client Client) SetPropertiesPreparer(ctx context.Context, accountName, sha return input.Format(time.RFC1123) } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-type": "file", + headers.Append("x-ms-type", "file") - "x-ms-content-length": input.ContentLength, - "x-ms-file-permission": "inherit", // TODO: expose this in future - "x-ms-file-attributes": "None", // TODO: expose this in future - "x-ms-file-creation-time": coalesceDate(input.CreatedAt, "now"), - "x-ms-file-last-write-time": coalesceDate(input.LastModified, "now"), - } + headers.Append("x-ms-content-length", strconv.Itoa(int(s.input.ContentLength))) + headers.Append("x-ms-file-permission", "inherit") // TODO: expose this in future + headers.Append("x-ms-file-attributes", "None") // TODO: expose this in future + headers.Append("x-ms-file-creation-time", coalesceDate(s.input.CreatedAt, "now")) + headers.Append("x-ms-file-last-write-time", coalesceDate(s.input.LastModified, "now")) - if input.ContentControl != nil { - headers["x-ms-cache-control"] = *input.ContentControl + if s.input.ContentControl != nil { + headers.Append("x-ms-cache-control", *s.input.ContentControl) } - if input.ContentDisposition != nil { - headers["x-ms-content-disposition"] = *input.ContentDisposition + if s.input.ContentDisposition != nil { + headers.Append("x-ms-content-disposition", *s.input.ContentDisposition) } - if input.ContentEncoding != nil { - headers["x-ms-content-encoding"] = *input.ContentEncoding + if s.input.ContentEncoding != nil { + headers.Append("x-ms-content-encoding", *s.input.ContentEncoding) } - if input.ContentLanguage != nil { - headers["x-ms-content-language"] = *input.ContentLanguage + if s.input.ContentLanguage != nil { + headers.Append("x-ms-content-language", *s.input.ContentLanguage) } - if input.ContentMD5 != nil { - headers["x-ms-content-md5"] = *input.ContentMD5 + if s.input.ContentMD5 != nil { + headers.Append("x-ms-content-md5", *s.input.ContentMD5) } - if input.ContentType != nil { - headers["x-ms-content-type"] = *input.ContentType + if s.input.ContentType != nil { + headers.Append("x-ms-content-type", *s.input.ContentType) } - headers = metadata.SetIntoHeaders(headers, input.MetaData) + if len(s.input.MetaData) > 0 { + headers.Merge(metadata.SetMetaDataHeaders(s.input.MetaData)) + } - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetPropertiesSender sends the SetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s SetPropertiesOptions) ToOData() *odata.Query { + return nil } -// SetPropertiesResponder handles the response to the SetProperties request. The method always -// closes the http.Response Body. -func (client Client) SetPropertiesResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (s SetPropertiesOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go index 5d8145fae422..c2391a1c9c04 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go @@ -6,10 +6,8 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type ClearByteRangeInput struct { @@ -17,96 +15,81 @@ type ClearByteRangeInput struct { EndBytes int64 } +type ClearByteRangeResponse struct { + HttpResponse *client.Response +} + // ClearByteRange clears the specified Byte Range from within the specified File -func (client Client) ClearByteRange(ctx context.Context, accountName, shareName, path, fileName string, input ClearByteRangeInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "ClearByteRange", "`accountName` cannot be an empty string.") - } +func (c Client) ClearByteRange(ctx context.Context, shareName, path, fileName string, input ClearByteRangeInput) (resp ClearByteRangeResponse, err error) { + if shareName == "" { - return result, validation.NewError("files.Client", "ClearByteRange", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "ClearByteRange", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "ClearByteRange", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } + if input.StartBytes < 0 { - return result, validation.NewError("files.Client", "ClearByteRange", "`input.StartBytes` must be greater or equal to 0.") + return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") } + if input.EndBytes <= 0 { - return result, validation.NewError("files.Client", "ClearByteRange", "`input.EndBytes` must be greater than 0.") + return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") } - req, err := client.ClearByteRangePreparer(ctx, accountName, shareName, path, fileName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "ClearByteRange", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("%s/", path) } - resp, err := client.ClearByteRangeSender(req) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: ClearByteRangeOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s%s", shareName, path, fileName), + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "ClearByteRange", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.ClearByteRangeResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "ClearByteRange", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// ClearByteRangePreparer prepares the ClearByteRange request. -func (client Client) ClearByteRangePreparer(ctx context.Context, accountName, shareName, path, fileName string, input ClearByteRangeInput) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "range"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-write": "clear", - "x-ms-range": fmt.Sprintf("bytes=%d-%d", input.StartBytes, input.EndBytes), - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type ClearByteRangeOptions struct { + input ClearByteRangeInput } -// ClearByteRangeSender sends the ClearByteRange request. The method will close the -// http.Response Body if it receives an error. -func (client Client) ClearByteRangeSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c ClearByteRangeOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-write", "clear") + headers.Append("x-ms-range", fmt.Sprintf("bytes=%d-%d", c.input.StartBytes, c.input.EndBytes)) + return headers } -// ClearByteRangeResponder handles the response to the ClearByteRange request. The method always -// closes the http.Response Body. -func (client Client) ClearByteRangeResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (c ClearByteRangeOptions) ToOData() *odata.Query { + return nil +} - return +func (c ClearByteRangeOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "range") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go index 733d3f525105..90a1089b3798 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go @@ -3,13 +3,12 @@ package files import ( "context" "fmt" + "io" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type GetByteRangeInput struct { @@ -17,105 +16,96 @@ type GetByteRangeInput struct { EndBytes int64 } -type GetByteRangeResult struct { - autorest.Response +type GetByteRangeResponse struct { + HttpResponse *client.Response Contents []byte } // GetByteRange returns the specified Byte Range from the specified File. -func (client Client) GetByteRange(ctx context.Context, accountName, shareName, path, fileName string, input GetByteRangeInput) (result GetByteRangeResult, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "GetByteRange", "`accountName` cannot be an empty string.") - } +func (c Client) GetByteRange(ctx context.Context, shareName, path, fileName string, input GetByteRangeInput) (resp GetByteRangeResponse, err error) { + if shareName == "" { - return result, validation.NewError("files.Client", "GetByteRange", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "GetByteRange", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "GetByteRange", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } + if input.StartBytes < 0 { - return result, validation.NewError("files.Client", "GetByteRange", "`input.StartBytes` must be greater or equal to 0.") + return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") } + if input.EndBytes <= 0 { - return result, validation.NewError("files.Client", "GetByteRange", "`input.EndBytes` must be greater than 0.") + return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") } + expectedBytes := input.EndBytes - input.StartBytes if expectedBytes < (4 * 1024) { - return result, validation.NewError("files.Client", "GetByteRange", "Requested Byte Range must be at least 4KB.") + return resp, fmt.Errorf("requested Byte Range must be at least 4KB") } if expectedBytes > (4 * 1024 * 1024) { - return result, validation.NewError("files.Client", "GetByteRange", "Requested Byte Range must be at most 4MB.") + return resp, fmt.Errorf("requested Byte Range must be at most 4MB") } - req, err := client.GetByteRangePreparer(ctx, accountName, shareName, path, fileName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "GetByteRange", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("%s/", path) } - resp, err := client.GetByteRangeSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "GetByteRange", resp, "Failure sending request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + http.StatusPartialContent, + }, + HttpMethod: http.MethodGet, + OptionsObject: GetByteRangeOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s%s", shareName, path, fileName), } - result, err = client.GetByteRangeResponder(resp, expectedBytes) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "GetByteRange", resp, "Failure responding to request") + err = fmt.Errorf("building request: %+v", err) return } - return -} - -// GetByteRangePreparer prepares the GetByteRange request. -func (client Client) GetByteRangePreparer(ctx context.Context, accountName, shareName, path, fileName string, input GetByteRangeInput) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), + resp.HttpResponse, err = req.Execute(ctx) + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-range": fmt.Sprintf("bytes=%d-%d", input.StartBytes, input.EndBytes-1), + if resp.HttpResponse != nil { + bytes, err := io.ReadAll(resp.HttpResponse.Body) + if err != nil { + return resp, fmt.Errorf("reading response body: %v", err) + } + resp.Contents = bytes } - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return } -// GetByteRangeSender sends the GetByteRange request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetByteRangeSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +type GetByteRangeOptions struct { + input GetByteRangeInput } -// GetByteRangeResponder handles the response to the GetByteRange request. The method always -// closes the http.Response Body. -func (client Client) GetByteRangeResponder(resp *http.Response, length int64) (result GetByteRangeResult, err error) { - result.Contents = make([]byte, length) +func (g GetByteRangeOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-range", fmt.Sprintf("bytes=%d-%d", g.input.StartBytes, g.input.EndBytes-1)) + return headers +} - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusPartialContent), - autorest.ByUnmarshallingBytes(&result.Contents), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (g GetByteRangeOptions) ToOData() *odata.Query { + return nil +} - return +func (g GetByteRangeOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go index 9e5be17f85fc..f81852604283 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go @@ -8,35 +8,46 @@ import ( "runtime" "sync" - "github.com/Azure/go-autorest/autorest" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) +type GetFileInput struct { + Parallelism int +} + +type GetFileResponse struct { + HttpResponse *client.Response + + OutputBytes []byte +} + // GetFile is a helper method to download a file by chunking it automatically -func (client Client) GetFile(ctx context.Context, accountName, shareName, path, fileName string, parallelism int) (result autorest.Response, outputBytes []byte, err error) { +func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, input GetFileInput) (resp GetFileResponse, err error) { // first look up the file and check out how many bytes it is - file, e := client.GetProperties(ctx, accountName, shareName, path, fileName) + file, e := c.GetProperties(ctx, shareName, path, fileName) if err != nil { - result = file.Response + resp.HttpResponse = file.HttpResponse err = e return } if file.ContentLength == nil { - err = fmt.Errorf("Content-Length was nil!") + err = fmt.Errorf("Content-Length was nil") return } - length := int64(*file.ContentLength) + resp.HttpResponse = file.HttpResponse + length := *file.ContentLength chunkSize := int64(4 * 1024 * 1024) // 4MB if chunkSize > length { chunkSize = length } - // then split that up into chunks and retrieve it retrieve it into the 'results' set + // then split that up into chunks and retrieve it into the 'results' set chunks := int(math.Ceil(float64(length) / float64(chunkSize))) - workerCount := parallelism * runtime.NumCPU() + workerCount := input.Parallelism * runtime.NumCPU() if workerCount > chunks { workerCount = chunks } @@ -57,7 +68,7 @@ func (client Client) GetFile(ctx context.Context, accountName, shareName, path, fileSize: length, } - result, err := client.downloadFileChunk(ctx, accountName, shareName, path, fileName, dfci) + result, err := c.downloadFileChunk(ctx, shareName, path, fileName, dfci) if err != nil { errors <- err waitGroup.Done() @@ -84,7 +95,7 @@ func (client Client) GetFile(ctx context.Context, accountName, shareName, path, copy(output[v.startBytes:v.endBytes], v.bytes) } - outputBytes = output + resp.OutputBytes = output return } @@ -100,7 +111,7 @@ type downloadFileChunkResult struct { bytes []byte } -func (client Client) downloadFileChunk(ctx context.Context, accountName, shareName, path, fileName string, input downloadFileChunkInput) (*downloadFileChunkResult, error) { +func (c Client) downloadFileChunk(ctx context.Context, shareName, path, fileName string, input downloadFileChunkInput) (*downloadFileChunkResult, error) { startBytes := input.chunkSize * int64(input.thisChunk) endBytes := startBytes + input.chunkSize @@ -114,9 +125,9 @@ func (client Client) downloadFileChunk(ctx context.Context, accountName, shareNa StartBytes: startBytes, EndBytes: endBytes, } - result, err := client.GetByteRange(ctx, accountName, shareName, path, fileName, getInput) + result, err := c.GetByteRange(ctx, shareName, path, fileName, getInput) if err != nil { - return nil, fmt.Errorf("Error putting bytes: %s", err) + return nil, fmt.Errorf("error putting bytes: %s", err) } output := downloadFileChunkResult{ diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go index 20e4d398d590..7588f8b4131e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go @@ -1,15 +1,16 @@ package files import ( + "bytes" "context" "fmt" + "io" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type PutByteRangeInput struct { @@ -21,107 +22,93 @@ type PutByteRangeInput struct { Content []byte } +type PutRangeResponse struct { + HttpResponse *client.Response +} + // PutByteRange puts the specified Byte Range in the specified File. -func (client Client) PutByteRange(ctx context.Context, accountName, shareName, path, fileName string, input PutByteRangeInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "PutByteRange", "`accountName` cannot be an empty string.") - } +func (c Client) PutByteRange(ctx context.Context, shareName, path, fileName string, input PutByteRangeInput) (resp PutRangeResponse, err error) { + if shareName == "" { - return result, validation.NewError("files.Client", "PutByteRange", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "PutByteRange", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if fileName == "" { - return result, validation.NewError("files.Client", "PutByteRange", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } + if input.StartBytes < 0 { - return result, validation.NewError("files.Client", "PutByteRange", "`input.StartBytes` must be greater or equal to 0.") + return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") } if input.EndBytes <= 0 { - return result, validation.NewError("files.Client", "PutByteRange", "`input.EndBytes` must be greater than 0.") + return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") } expectedBytes := input.EndBytes - input.StartBytes actualBytes := len(input.Content) if expectedBytes != int64(actualBytes) { - return result, validation.NewError("files.Client", "PutByteRange", fmt.Sprintf("The specified byte-range (%d) didn't match the content size (%d).", expectedBytes, actualBytes)) + return resp, fmt.Errorf(fmt.Sprintf("The specified byte-range (%d) didn't match the content size (%d).", expectedBytes, actualBytes)) } if expectedBytes > (4 * 1024 * 1024) { - return result, validation.NewError("files.Client", "PutByteRange", "Specified Byte Range must be at most 4MB.") + return resp, fmt.Errorf("specified Byte Range must be at most 4MB") } - req, err := client.PutByteRangePreparer(ctx, accountName, shareName, path, fileName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "PutByteRange", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("/%s/", path) + } + + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: PutRangeOptions{ + input: input, + }, + Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), } - resp, err := client.PutByteRangeSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "PutByteRange", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.PutByteRangeResponder(resp) + req.Body = io.NopCloser(bytes.NewReader(input.Content)) + req.ContentLength = int64(len(input.Content)) + + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "PutByteRange", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// PutByteRangePreparer prepares the PutByteRange request. -func (client Client) PutByteRangePreparer(ctx context.Context, accountName, shareName, path, fileName string, input PutByteRangeInput) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "range"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-write": "update", - "x-ms-range": fmt.Sprintf("bytes=%d-%d", input.StartBytes, input.EndBytes-1), - "Content-Length": int(len(input.Content)), - } - - preparer := autorest.CreatePreparer( - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters), - autorest.WithBytes(&input.Content)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type PutRangeOptions struct { + input PutByteRangeInput } -// PutByteRangeSender sends the PutByteRange request. The method will close the -// http.Response Body if it receives an error. -func (client Client) PutByteRangeSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (p PutRangeOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("x-ms-write", "update") + headers.Append("x-ms-range", fmt.Sprintf("bytes=%d-%d", p.input.StartBytes, p.input.EndBytes-1)) + headers.Append("Content-Length", strconv.Itoa(len(p.input.Content))) + return headers } -// PutByteRangeResponder handles the response to the PutByteRange request. The method always -// closes the http.Response Body. -func (client Client) PutByteRangeResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (p PutRangeOptions) ToOData() *odata.Query { + return nil +} - return +func (p PutRangeOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "range") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go index a74845dd61ca..16cb68719311 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go @@ -8,15 +8,17 @@ import ( "math" "os" "sync" - - "github.com/Azure/go-autorest/autorest" ) // PutFile is a helper method which takes a file, and automatically chunks it up, rather than having to do this yourself -func (client Client) PutFile(ctx context.Context, accountName, shareName, path, fileName string, file *os.File, parallelism int) error { +func (c Client) PutFile(ctx context.Context, shareName, path, fileName string, file *os.File, parallelism int) error { fileInfo, err := file.Stat() if err != nil { - return fmt.Errorf("Error loading file info: %s", err) + return fmt.Errorf("error loading file info: %s", err) + } + + if fileInfo.Size() == 0 { + return fmt.Errorf("file is empty which is not supported") } fileSize := fileInfo.Size() @@ -48,7 +50,7 @@ func (client Client) PutFile(ctx context.Context, accountName, shareName, path, fileSize: fileSize, } - _, err := client.uploadChunk(ctx, accountName, shareName, path, fileName, uci, file) + _, err := c.uploadChunk(ctx, shareName, path, fileName, uci, file) if err != nil { errors <- err } @@ -77,7 +79,7 @@ type uploadChunkInput struct { fileSize int64 } -func (client Client) uploadChunk(ctx context.Context, accountName, shareName, path, fileName string, input uploadChunkInput, file *os.File) (result autorest.Response, err error) { +func (c Client) uploadChunk(ctx context.Context, shareName, path, fileName string, input uploadChunkInput, file *os.File) (result PutRangeResponse, err error) { startBytes := int64(input.chunkSize * input.thisChunk) endBytes := startBytes + int64(input.chunkSize) @@ -102,9 +104,9 @@ func (client Client) uploadChunk(ctx context.Context, accountName, shareName, pa EndBytes: endBytes, Content: bytes, } - result, err = client.PutByteRange(ctx, accountName, shareName, path, fileName, putBytesInput) + result, err = c.PutByteRange(ctx, shareName, path, fileName, putBytesInput) if err != nil { - return result, fmt.Errorf("Error putting bytes: %s", err) + return result, fmt.Errorf("error putting bytes: %s", err) } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go index ea309f97ddb2..9a67cab82857 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go @@ -6,14 +6,12 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) -type ListRangesResult struct { - autorest.Response +type ListRangesResponse struct { + HttpResponse *client.Response Ranges []Range `xml:"Range"` } @@ -24,91 +22,69 @@ type Range struct { } // ListRanges returns the list of valid ranges for the specified File. -func (client Client) ListRanges(ctx context.Context, accountName, shareName, path, fileName string) (result ListRangesResult, err error) { - if accountName == "" { - return result, validation.NewError("files.Client", "ListRanges", "`accountName` cannot be an empty string.") - } +func (c Client) ListRanges(ctx context.Context, shareName, path, fileName string) (resp ListRangesResponse, err error) { + if shareName == "" { - return result, validation.NewError("files.Client", "ListRanges", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("files.Client", "ListRanges", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if path == "" { - return result, validation.NewError("files.Client", "ListRanges", "`path` cannot be an empty string.") + return resp, fmt.Errorf("`path` cannot be an empty string") } + if fileName == "" { - return result, validation.NewError("files.Client", "ListRanges", "`fileName` cannot be an empty string.") + return resp, fmt.Errorf("`fileName` cannot be an empty string") } - req, err := client.ListRangesPreparer(ctx, accountName, shareName, path, fileName) - if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "ListRanges", nil, "Failure preparing request") - return + if path != "" { + path = fmt.Sprintf("%s/", path) } - resp, err := client.ListRangesSender(req) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: ListRangeOptions{}, + Path: fmt.Sprintf("/%s/%s%s", shareName, path, fileName), + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "files.Client", "ListRanges", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.ListRangesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "files.Client", "ListRanges", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// ListRangesPreparer prepares the ListRanges request. -func (client Client) ListRangesPreparer(ctx context.Context, accountName, shareName, path, fileName string) (*http.Request, error) { - if path != "" { - path = fmt.Sprintf("%s/", path) - } - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - "directory": autorest.Encode("path", path), - "fileName": autorest.Encode("path", fileName), + if resp.HttpResponse != nil { + resp.HttpResponse.Unmarshal(&resp) } - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "rangelist"), - } + return +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type ListRangeOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}/{directory}{fileName}", pathParameters), - autorest.WithHeaders(headers), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (l ListRangeOptions) ToHeaders() *client.Headers { + return nil } -// ListRangesSender sends the ListRanges request. The method will close the -// http.Response Body if it receives an error. -func (client Client) ListRangesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (l ListRangeOptions) ToOData() *odata.Query { + return nil } -// ListRangesResponder handles the response to the ListRanges request. The method always -// closes the http.Response Body. -func (client Client) ListRangesResponder(resp *http.Response) (result ListRangesResult, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (l ListRangeOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "rangelist") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go index f18e702e81d9..b29471c87e32 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go @@ -5,60 +5,83 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given File -// This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, shareName, directoryName, filePath string) string { - domain := endpoints.GetFileEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s/%s/%s", domain, shareName, directoryName, filePath) +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = FileId{} + +type FileId struct { + // AccountId specifies the ID of the Storage Account where this File exists. + AccountId accounts.AccountId + + // ShareName specifies the name of the File Share containing this File. + ShareName string + + // DirectoryPath specifies the path representing the Directory where this File exists. + DirectoryPath string + + // FileName specifies the name of the File. + FileName string } -type ResourceID struct { - AccountName string - DirectoryName string - FileName string - ShareName string +func NewFileID(accountId accounts.AccountId, shareName, directoryPath, fileName string) FileId { + return FileId{ + AccountId: accountId, + ShareName: shareName, + DirectoryPath: directoryPath, + FileName: fileName, + } } -// ParseResourceID parses the specified Resource ID and returns an object -// which can be used to interact with Files within a Storage Share. -func ParseResourceID(id string) (*ResourceID, error) { - // example: https://account1.file.core.chinacloudapi.cn/share1/directory1/file1.txt - // example: https://account1.file.core.chinacloudapi.cn/share1/directory1/directory2/file1.txt +func (b FileId) ID() string { + return fmt.Sprintf("%s/%s/%s/%s", b.AccountId.ID(), b.ShareName, b.DirectoryPath, b.FileName) +} - if id == "" { - return nil, fmt.Errorf("`id` was empty") +func (b FileId) String() string { + components := []string{ + fmt.Sprintf("Directory Path %q", b.DirectoryPath), + fmt.Sprintf("Share Name %q", b.ShareName), + fmt.Sprintf("Account %q", b.AccountId.String()), + } + return fmt.Sprintf("File %q (%s)", b.FileName, strings.Join(components, " / ")) +} + +// ParseFileID parses `input` into a File ID using a known `domainSuffix` +func ParseFileID(input, domainSuffix string) (*FileId, error) { + // example: https://foo.file.core.windows.net/Bar/some/directory/some-file.txt + if input == "" { + return nil, fmt.Errorf("`input` was empty") } - uri, err := url.Parse(id) + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + if account.SubDomainType != accounts.FileSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.FileSubDomainType), string(account.SubDomainType)) + } + + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) } path := strings.TrimPrefix(uri.Path, "/") segments := strings.Split(path, "/") - if len(segments) == 0 { - return nil, fmt.Errorf("Expected the path to contain segments but got none") + if len(segments) < 3 { + return nil, fmt.Errorf("expected the path to contain at least 3 segments but got %d", len(segments)) } - shareName := segments[0] + directoryPath := strings.Join(segments[1:len(segments)-1], "/") fileName := segments[len(segments)-1] - - directoryName := strings.TrimPrefix(path, shareName) - directoryName = strings.TrimPrefix(directoryName, "/") - directoryName = strings.TrimSuffix(directoryName, fileName) - directoryName = strings.TrimSuffix(directoryName, "/") - return &ResourceID{ - AccountName: *accountName, + return &FileId{ + AccountId: *account, ShareName: shareName, - DirectoryName: directoryName, + DirectoryPath: directoryPath, FileName: fileName, }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go index 7c8231033703..5b70f293ad01 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go @@ -1,14 +1,4 @@ package files -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - -// APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "file/files" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md index ecc0f13ae9bb..68b41e2d5e49 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md @@ -15,9 +15,8 @@ package main import ( "context" "fmt" - "time" - - "github.com/Azure/go-autorest/autorest" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" ) @@ -25,16 +24,24 @@ func Example() error { accountName := "storageaccount1" storageAccountKey := "ABC123...." shareName := "myshare" - - storageAuth := autorest.NewSharedKeyLiteAuthorizer(accountName, storageAccountKey) - sharesClient := shares.New() - sharesClient.Client.Authorizer = storageAuth + domainSuffix := "core.windows.net" + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + + sharesClient, err := shares.NewWithBaseUri(fmt.Sprintf("https://%s.file.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + sharesClient.Client.SetAuthorizer(auth) ctx := context.TODO() input := shares.CreateInput{ QuotaInGB: 2, } - if _, err := sharesClient.Create(ctx, accountName, shareName, input); err != nil { + if _, err := sharesClient.Create(ctx, shareName, input); err != nil { return fmt.Errorf("Error creating Share: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go index ea6ff4c2dd26..56aa6413d4b8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go @@ -2,97 +2,75 @@ package shares import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type GetACLResult struct { - autorest.Response + HttpResponse *client.Response SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` } // GetACL get the Access Control List for the specified Storage Share -func (client Client) GetACL(ctx context.Context, accountName, shareName string) (result GetACLResult, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "GetACL", "`accountName` cannot be an empty string.") - } +func (c Client) GetACL(ctx context.Context, shareName string) (resp GetACLResult, err error) { + if shareName == "" { - return result, validation.NewError("shares.Client", "GetACL", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "GetACL", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - req, err := client.GetACLPreparer(ctx, accountName, shareName) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetACL", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getAclOptions{}, + Path: fmt.Sprintf("/%s", shareName), } - resp, err := client.GetACLSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "GetACL", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetACLResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetACL", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + err = resp.HttpResponse.Unmarshal(&resp) + if err != nil { + return resp, fmt.Errorf("unmarshalling response: %v", err) + } + } return } -// GetACLPreparer prepares the GetACL request. -func (client Client) GetACLPreparer(ctx context.Context, accountName, shareName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "share"), - "comp": autorest.Encode("query", "acl"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type getAclOptions struct { } -// GetACLSender sends the GetACL request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetACLSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g getAclOptions) ToHeaders() *client.Headers { + return nil } -// GetACLResponder handles the response to the GetACL request. The method always -// closes the http.Response Body. -func (client Client) GetACLResponder(resp *http.Response) (result GetACLResult, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (g getAclOptions) ToOData() *odata.Query { + return nil +} - return +func (g getAclOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("comp", "acl") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go index 18d1788a2ee4..33b7c84a47d0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go @@ -1,103 +1,89 @@ package shares import ( + "bytes" "context" "encoding/xml" + "fmt" + "io" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) -type setAcl struct { +type SetAclResponse struct { + HttpResponse *client.Response +} + +type SetAclInput struct { SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` XMLName xml.Name `xml:"SignedIdentifiers"` } // SetACL sets the specified Access Control List on the specified Storage Share -func (client Client) SetACL(ctx context.Context, accountName, shareName string, acls []SignedIdentifier) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "SetACL", "`accountName` cannot be an empty string.") - } +func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) (resp SetAclResponse, err error) { + if shareName == "" { - return result, validation.NewError("shares.Client", "SetACL", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "SetACL", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - req, err := client.SetACLPreparer(ctx, accountName, shareName, acls) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: setAclOptions{}, + Path: fmt.Sprintf("/%s", shareName), + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "SetACL", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.SetACLSender(req) + b, err := xml.Marshal(&input) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "SetACL", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling input: %v", err) } + withHeader := xml.Header + string(b) + bytesWithHeader := []byte(withHeader) + req.ContentLength = int64(len(bytesWithHeader)) + req.Header.Set("Content-Length", strconv.Itoa(len(bytesWithHeader))) + req.Body = io.NopCloser(bytes.NewReader(bytesWithHeader)) - result, err = client.SetACLResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "SetACL", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return } -// SetACLPreparer prepares the SetACL request. -func (client Client) SetACLPreparer(ctx context.Context, accountName, shareName string, acls []SignedIdentifier) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "share"), - "comp": autorest.Encode("query", "acl"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - input := setAcl{ - SignedIdentifiers: acls, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers), - autorest.WithXML(&input)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type setAclOptions struct { + SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` } -// SetACLSender sends the SetACL request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetACLSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s setAclOptions) ToHeaders() *client.Headers { + return nil } -// SetACLResponder handles the response to the SetACL request. The method always -// closes the http.Response Body. -func (client Client) SetACLResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (s setAclOptions) ToOData() *odata.Query { + return nil +} - return +func (s setAclOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("comp", "acl") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/api.go index 91645912dfb6..553fb4899e46 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/api.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/api.go @@ -2,23 +2,20 @@ package shares import ( "context" - - "github.com/Azure/go-autorest/autorest" ) type StorageShare interface { - SetACL(ctx context.Context, accountName, shareName string, acls []SignedIdentifier) (result autorest.Response, err error) - GetSnapshot(ctx context.Context, accountName, shareName, snapshotShare string) (result GetSnapshotPropertiesResult, err error) - GetStats(ctx context.Context, accountName, shareName string) (result GetStatsResult, err error) - GetACL(ctx context.Context, accountName, shareName string) (result GetACLResult, err error) - SetMetaData(ctx context.Context, accountName, shareName string, metaData map[string]string) (result autorest.Response, err error) - GetMetaData(ctx context.Context, accountName, shareName string) (result GetMetaDataResult, err error) - SetProperties(ctx context.Context, accountName, shareName string, properties ShareProperties) (result autorest.Response, err error) - DeleteSnapshot(ctx context.Context, accountName, shareName string, shareSnapshot string) (result autorest.Response, err error) - CreateSnapshot(ctx context.Context, accountName, shareName string, input CreateSnapshotInput) (result CreateSnapshotResult, err error) - GetResourceID(accountName, shareName string) string + SetACL(ctx context.Context, shareName string, input SetAclInput) (SetAclResponse, error) + GetSnapshot(ctx context.Context, shareName string, input GetSnapshotPropertiesInput) (GetSnapshotPropertiesResponse, error) + GetStats(ctx context.Context, shareName string) (GetStatsResponse, error) + GetACL(ctx context.Context, shareName string) (GetACLResult, error) + SetMetaData(ctx context.Context, shareName string, input SetMetaDataInput) (SetMetaDataResponse, error) + GetMetaData(ctx context.Context, shareName string) (GetMetaDataResponse, error) + SetProperties(ctx context.Context, shareName string, properties ShareProperties) (SetPropertiesResponse, error) + DeleteSnapshot(ctx context.Context, accountName string, shareName string, shareSnapshot string) (DeleteSnapshotResponse, error) + CreateSnapshot(ctx context.Context, shareName string, input CreateSnapshotInput) (CreateSnapshotResponse, error) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, shareName string) string - GetProperties(ctx context.Context, accountName, shareName string) (result GetPropertiesResult, err error) - Delete(ctx context.Context, accountName, shareName string, deleteSnapshots bool) (result autorest.Response, err error) - Create(ctx context.Context, accountName, shareName string, input CreateInput) (result autorest.Response, err error) + GetProperties(ctx context.Context, shareName string) (GetPropertiesResult, error) + Delete(ctx context.Context, shareName string, input DeleteInput) (DeleteResponse, error) + Create(ctx context.Context, shareName string, input CreateInput) (CreateResponse, error) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/client.go index 4f3a6f9f99d0..7d6516f76ed8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/client.go @@ -1,25 +1,22 @@ package shares import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for File Storage Shares. type Client struct { - autorest.Client - BaseURI string -} - -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) + Client *storage.Client } -// NewWithEnvironment creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go index 10a1148f0368..b0184600af0e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go @@ -4,12 +4,11 @@ import ( "context" "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -36,99 +35,85 @@ type CreateInput struct { AccessTier *AccessTier } +type CreateResponse struct { + HttpResponse *client.Response +} + // Create creates the specified Storage Share within the specified Storage Account -func (client Client) Create(ctx context.Context, accountName, shareName string, input CreateInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "Create", "`accountName` cannot be an empty string.") - } +func (c Client) Create(ctx context.Context, shareName string, input CreateInput) (resp CreateResponse, err error) { + if shareName == "" { - return result, validation.NewError("shares.Client", "Create", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "Create", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if input.QuotaInGB <= 0 || input.QuotaInGB > 102400 { - return result, validation.NewError("shares.Client", "Create", "`input.QuotaInGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") - } - if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("shares.Client", "Create", fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return resp, fmt.Errorf("`input.QuotaInGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") } - req, err := client.CreatePreparer(ctx, accountName, shareName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "Create", nil, "Failure preparing request") - return + if err = metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) } - resp, err := client.CreateSender(req) + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: CreateOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s", shareName), + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "Create", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - - result, err = client.CreateResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "Create", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return } -// CreatePreparer prepares the Create request. -func (client Client) CreatePreparer(ctx context.Context, accountName, shareName string, input CreateInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } +type CreateOptions struct { + input CreateInput +} - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "share"), - } +func (c CreateOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "x-ms-share-quota": input.QuotaInGB, + if len(c.input.MetaData) > 0 { + headers.Merge(metadata.SetMetaDataHeaders(c.input.MetaData)) } protocol := SMB - if input.EnabledProtocol != "" { - protocol = input.EnabledProtocol + if c.input.EnabledProtocol != "" { + protocol = c.input.EnabledProtocol } - headers["x-ms-enabled-protocols"] = protocol + headers.Append("x-ms-enabled-protocols", string(protocol)) - if input.AccessTier != nil { - headers["x-ms-access-tier"] = string(*input.AccessTier) + if c.input.AccessTier != nil { + headers.Append("x-ms-access-tier", string(*c.input.AccessTier)) } - headers = metadata.SetIntoHeaders(headers, input.MetaData) + headers.Append("x-ms-share-quota", strconv.Itoa(c.input.QuotaInGB)) - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// CreateSender sends the Create request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c CreateOptions) ToOData() *odata.Query { + return nil } -// CreateResponder handles the response to the Create request. The method always -// closes the http.Response Body. -func (client Client) CreateResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (c CreateOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go index 70ef985d23bb..7ae11b3dbef3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go @@ -2,93 +2,76 @@ package shares import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type DeleteResponse struct { + HttpResponse *client.Response +} + +type DeleteInput struct { + DeleteSnapshots bool +} + // Delete deletes the specified Storage Share from within a Storage Account -func (client Client) Delete(ctx context.Context, accountName, shareName string, deleteSnapshots bool) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, shareName string, input DeleteInput) (resp DeleteResponse, err error) { if shareName == "" { - return result, validation.NewError("shares.Client", "Delete", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "Delete", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - req, err := client.DeletePreparer(ctx, accountName, shareName, deleteSnapshots) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: DeleteOptions{ + deleteSnapshots: input.DeleteSnapshots, + }, + Path: fmt.Sprintf("/%s", shareName), } - - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "Delete", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName, shareName string, deleteSnapshots bool) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "share"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type DeleteOptions struct { + deleteSnapshots bool +} - if deleteSnapshots { - headers["x-ms-delete-snapshots"] = "include" +func (d DeleteOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if d.deleteSnapshots { + headers.Append("x-ms-delete-snapshots", "include") } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (d DeleteOptions) ToOData() *odata.Query { + return nil } -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (d DeleteOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go index 9fa4d9f07ed8..e31762bd2d8a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go @@ -2,101 +2,74 @@ package shares import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -type GetMetaDataResult struct { - autorest.Response +type GetMetaDataResponse struct { + HttpResponse *client.Response MetaData map[string]string } // GetMetaData returns the MetaData associated with the specified Storage Share -func (client Client) GetMetaData(ctx context.Context, accountName, shareName string) (result GetMetaDataResult, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "GetMetaData", "`accountName` cannot be an empty string.") - } +func (c Client) GetMetaData(ctx context.Context, shareName string) (resp GetMetaDataResponse, err error) { if shareName == "" { - return result, validation.NewError("shares.Client", "GetMetaData", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "GetMetaData", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - req, err := client.GetMetaDataPreparer(ctx, accountName, shareName) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetMetaData", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: GetMetaDataOptions{}, + Path: fmt.Sprintf("/%s", shareName), } - resp, err := client.GetMetaDataSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "GetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetMetaDataPreparer prepares the GetMetaData request. -func (client Client) GetMetaDataPreparer(ctx context.Context, accountName, shareName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + } } - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "share"), - "comp": autorest.Encode("query", "metadata"), - } + return +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type GetMetaDataOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (g GetMetaDataOptions) ToHeaders() *client.Headers { + return nil } -// GetMetaDataSender sends the GetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g GetMetaDataOptions) ToOData() *odata.Query { + return nil } -// GetMetaDataResponder handles the response to the GetMetaData request. The method always -// closes the http.Response Body. -func (client Client) GetMetaDataResponder(resp *http.Response) (result GetMetaDataResult, err error) { - if resp.Header != nil { - result.MetaData = metadata.ParseFromHeaders(resp.Header) - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (g GetMetaDataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go index 7e64e60aca15..3a23d90e780f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go @@ -6,92 +6,77 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) +type SetMetaDataResponse struct { + HttpResponse *client.Response +} + +type SetMetaDataInput struct { + MetaData map[string]string +} + // SetMetaData sets the MetaData on the specified Storage Share -func (client Client) SetMetaData(ctx context.Context, accountName, shareName string, metaData map[string]string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "SetMetaData", "`accountName` cannot be an empty string.") - } +func (c Client) SetMetaData(ctx context.Context, shareName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { + if shareName == "" { - return result, validation.NewError("shares.Client", "SetMetaData", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "SetMetaData", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - if err := metadata.Validate(metaData); err != nil { - return result, validation.NewError("shares.Client", "SetMetaData", fmt.Sprintf("`metadata` is not valid: %s.", err)) + + if err := metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`metadata` is not valid: %v", err) } - req, err := client.SetMetaDataPreparer(ctx, accountName, shareName, metaData) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "SetMetaData", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: SetMetaDataOptions{ + metaData: input.MetaData, + }, + Path: fmt.Sprintf("/%s", shareName), } - resp, err := client.SetMetaDataSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "SetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "SetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetMetaDataPreparer prepares the SetMetaData request. -func (client Client) SetMetaDataPreparer(ctx context.Context, accountName, shareName string, metaData map[string]string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "share"), - "comp": autorest.Encode("query", "metadata"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - headers = metadata.SetIntoHeaders(headers, metaData) - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type SetMetaDataOptions struct { + metaData map[string]string } -// SetPropertiesSetMetaDataSender sends the SetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s SetMetaDataOptions) ToHeaders() *client.Headers { + headers := metadata.SetMetaDataHeaders(s.metaData) + return &headers } -// SetMetaDataResponder handles the response to the SetMetaData request. The method always -// closes the http.Response Body. -func (client Client) SetMetaDataResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (s SetMetaDataOptions) ToOData() *odata.Query { + return nil +} - return +func (s SetMetaDataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/options.go new file mode 100644 index 000000000000..e2c1d5c9b4cd --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/options.go @@ -0,0 +1,24 @@ +package shares + +import ( + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +var _ client.Options = sharesOptions{} + +type sharesOptions struct{} + +func (o sharesOptions) ToHeaders() *client.Headers { + return &client.Headers{} +} + +func (sharesOptions) ToOData() *odata.Query { + return nil +} + +func (sharesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go index 28e36e6d3eaf..763584ef648b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go @@ -7,15 +7,12 @@ import ( "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) type GetPropertiesResult struct { - autorest.Response + HttpResponse *client.Response MetaData map[string]string QuotaInGB int @@ -24,103 +21,62 @@ type GetPropertiesResult struct { } // GetProperties returns the properties about the specified Storage Share -func (client Client) GetProperties(ctx context.Context, accountName, shareName string) (result GetPropertiesResult, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "GetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) GetProperties(ctx context.Context, shareName string) (resp GetPropertiesResult, err error) { if shareName == "" { - return result, validation.NewError("shares.Client", "GetProperties", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "GetProperties", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - req, err := client.GetPropertiesPreparer(ctx, accountName, shareName) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetProperties", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: sharesOptions{}, + Path: fmt.Sprintf("/%s", shareName), } - resp, err := client.GetPropertiesSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "GetProperties", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetPropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetPropertiesPreparer prepares the GetProperties request. -func (client Client) GetPropertiesPreparer(ctx context.Context, accountName, shareName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "share"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetPropertiesSender sends the GetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// GetPropertiesResponder handles the response to the GetProperties request. The method always -// closes the http.Response Body. -func (client Client) GetPropertiesResponder(resp *http.Response) (result GetPropertiesResult, err error) { - if resp.Header != nil { - result.MetaData = metadata.ParseFromHeaders(resp.Header) - - quotaRaw := resp.Header.Get("x-ms-share-quota") - if quotaRaw != "" { - quota, e := strconv.Atoi(quotaRaw) - if e != nil { - return result, fmt.Errorf("Error converting %q to an integer: %s", quotaRaw, err) + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + + quotaRaw := resp.HttpResponse.Header.Get("x-ms-share-quota") + if quotaRaw != "" { + quota, e := strconv.Atoi(quotaRaw) + if e != nil { + return resp, fmt.Errorf("error converting %q to an integer: %s", quotaRaw, err) + } + resp.QuotaInGB = quota } - result.QuotaInGB = quota - } - protocol := SMB - if protocolRaw := resp.Header.Get("x-ms-enabled-protocols"); protocolRaw != "" { - protocol = ShareProtocol(protocolRaw) - } + protocol := SMB + if protocolRaw := resp.HttpResponse.Header.Get("x-ms-enabled-protocols"); protocolRaw != "" { + protocol = ShareProtocol(protocolRaw) + } - if accessTierRaw := resp.Header.Get("x-ms-access-tier"); accessTierRaw != "" { - tier := AccessTier(accessTierRaw) - result.AccessTier = &tier + if accessTierRaw := resp.HttpResponse.Header.Get("x-ms-access-tier"); accessTierRaw != "" { + tier := AccessTier(accessTierRaw) + resp.AccessTier = &tier + } + resp.EnabledProtocol = protocol } - result.EnabledProtocol = protocol } - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go index 70953c73e102..ef3854af6de9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go @@ -2,13 +2,13 @@ package shares import ( "context" + "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type ShareProperties struct { @@ -16,91 +16,75 @@ type ShareProperties struct { AccessTier *AccessTier } +type SetPropertiesResponse struct { + HttpResponse *client.Response +} + // SetProperties lets you update the Quota for the specified Storage Share -func (client Client) SetProperties(ctx context.Context, accountName, shareName string, properties ShareProperties) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "SetProperties", "`accountName` cannot be an empty string.") - } +func (c Client) SetProperties(ctx context.Context, shareName string, properties ShareProperties) (resp SetPropertiesResponse, err error) { + if shareName == "" { - return result, validation.NewError("shares.Client", "SetProperties", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "SetProperties", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if newQuotaGB := properties.QuotaInGb; newQuotaGB != nil && (*newQuotaGB <= 0 || *newQuotaGB > 102400) { - return result, validation.NewError("shares.Client", "SetProperties", "`newQuotaGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") + return resp, fmt.Errorf("`newQuotaGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") } - req, err := client.SetPropertiesPreparer(ctx, accountName, shareName, properties) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "SetProperties", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPut, + OptionsObject: SetPropertiesOptions{ + input: properties, + }, + Path: fmt.Sprintf("/%s", shareName), } - resp, err := client.SetPropertiesSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "SetProperties", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetPropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "SetProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetPropertiesPreparer prepares the SetProperties request. -func (client Client) SetPropertiesPreparer(ctx context.Context, accountName, shareName string, properties ShareProperties) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "share"), - "comp": autorest.Encode("query", "properties"), - } +type SetPropertiesOptions struct { + input ShareProperties +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - if properties.QuotaInGb != nil { - headers["x-ms-share-quota"] = *properties.QuotaInGb +func (s SetPropertiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if s.input.QuotaInGb != nil { + headers.Append("x-ms-share-quota", strconv.Itoa(*s.input.QuotaInGb)) } - if properties.AccessTier != nil { - headers["x-ms-access-tier"] = string(*properties.AccessTier) + if s.input.AccessTier != nil { + headers.Append("x-ms-access-tier", string(*s.input.AccessTier)) } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return headers } -// SetPropertiesSender sends the SetProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetPropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s SetPropertiesOptions) ToOData() *odata.Query { + return nil } -// SetPropertiesResponder handles the response to the SetProperties request. The method always -// closes the http.Response Body. -func (client Client) SetPropertiesResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (s SetPropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("comp", "properties") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go index c51d399ca062..73b93bd70768 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go @@ -5,49 +5,77 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given File Share -// This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, shareName string) string { - domain := endpoints.GetFileEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s", domain, shareName) -} - // GetResourceManagerResourceID returns the Resource Manager specific // ResourceID for a specific Storage Share -func (client Client) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, shareName string) string { +func (c Client) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, shareName string) string { fmtStr := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/fileServices/default/shares/%s" return fmt.Sprintf(fmtStr, subscriptionID, resourceGroup, accountName, shareName) } -type ResourceID struct { - AccountName string - ShareName string +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = ShareId{} + +type ShareId struct { + // AccountId specifies the ID of the Storage Account where this File Share exists. + AccountId accounts.AccountId + + // ShareName specifies the name of this File Share. + ShareName string +} + +func NewShareID(accountId accounts.AccountId, shareName string) ShareId { + return ShareId{ + AccountId: accountId, + ShareName: shareName, + } +} + +func (b ShareId) ID() string { + return fmt.Sprintf("%s/%s", b.AccountId.ID(), b.ShareName) +} + +func (b ShareId) String() string { + components := []string{ + fmt.Sprintf("Account %q", b.AccountId.String()), + } + return fmt.Sprintf("File Share %q (%s)", b.ShareName, strings.Join(components, " / ")) } -// ParseResourceID parses the specified Resource ID and returns an object -// which can be used to interact with the Storage Shares SDK -func ParseResourceID(id string) (*ResourceID, error) { +// ParseShareID parses `input` into a Share ID using a known `domainSuffix` +func ParseShareID(input, domainSuffix string) (*ShareId, error) { // example: https://foo.file.core.windows.net/Bar - if id == "" { - return nil, fmt.Errorf("`id` was empty") + if input == "" { + return nil, fmt.Errorf("`input` was empty") } - uri, err := url.Parse(id) + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + if account.SubDomainType != accounts.FileSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.FileSubDomainType), string(account.SubDomainType)) + } + + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) + } + + path := strings.TrimPrefix(uri.Path, "/") + segments := strings.Split(path, "/") + if len(segments) == 0 { + return nil, fmt.Errorf("Expected the path to contain segments but got none") } shareName := strings.TrimPrefix(uri.Path, "/") - return &ResourceID{ - AccountName: *accountName, - ShareName: shareName, + return &ShareId{ + AccountId: *account, + ShareName: shareName, }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go index 0ded38b1975a..8ba7a07c7b4a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go @@ -6,10 +6,8 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) @@ -17,8 +15,8 @@ type CreateSnapshotInput struct { MetaData map[string]string } -type CreateSnapshotResult struct { - autorest.Response +type CreateSnapshotResponse struct { + HttpResponse *client.Response // This header is a DateTime value that uniquely identifies the share snapshot. // The value of this header may be used in subsequent requests to access the share snapshot. @@ -29,87 +27,68 @@ type CreateSnapshotResult struct { // CreateSnapshot creates a read-only snapshot of the share // A share can support creation of 200 share snapshots. Attempting to create more than 200 share snapshots fails with 409 (Conflict). // Attempting to create a share snapshot while a previous Snapshot Share operation is in progress fails with 409 (Conflict). -func (client Client) CreateSnapshot(ctx context.Context, accountName, shareName string, input CreateSnapshotInput) (result CreateSnapshotResult, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "CreateSnapshot", "`accountName` cannot be an empty string.") - } +func (c Client) CreateSnapshot(ctx context.Context, shareName string, input CreateSnapshotInput) (resp CreateSnapshotResponse, err error) { + if shareName == "" { - return result, validation.NewError("shares.Client", "CreateSnapshot", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "CreateSnapshot", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - if err := metadata.Validate(input.MetaData); err != nil { - return result, validation.NewError("shares.Client", "CreateSnapshot", fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + + if err = metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`input.MetaData` is not valid: %v", err) } - req, err := client.CreateSnapshotPreparer(ctx, accountName, shareName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "CreateSnapshot", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: snapShotCreateOptions{ + metaData: input.MetaData, + }, + Path: fmt.Sprintf("/%s", shareName), } - resp, err := client.CreateSnapshotSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "CreateSnapshot", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.CreateSnapshotResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "CreateSnapshot", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.SnapshotDateTime = resp.HttpResponse.Header.Get("x-ms-snapshot") + } + } return } -// CreateSnapshotPreparer prepares the CreateSnapshot request. -func (client Client) CreateSnapshotPreparer(ctx context.Context, accountName, shareName string, input CreateSnapshotInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "snapshot"), - "restype": autorest.Encode("query", "share"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - headers = metadata.SetIntoHeaders(headers, input.MetaData) - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type snapShotCreateOptions struct { + metaData map[string]string } -// CreateSnapshotSender sends the CreateSnapshot request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSnapshotSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s snapShotCreateOptions) ToHeaders() *client.Headers { + headers := metadata.SetMetaDataHeaders(s.metaData) + return &headers } -// CreateSnapshotResponder handles the response to the CreateSnapshot request. The method always -// closes the http.Response Body. -func (client Client) CreateSnapshotResponder(resp *http.Response) (result CreateSnapshotResult, err error) { - result.SnapshotDateTime = resp.Header.Get("x-ms-snapshot") - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (s snapShotCreateOptions) ToOData() *odata.Query { + return nil +} - return +func (s snapShotCreateOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("comp", "snapshot") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go index 1f5d665cb104..bf3ccd6719a6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go @@ -2,93 +2,75 @@ package shares import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type DeleteSnapshotResponse struct { + HttpResponse *client.Response +} + // DeleteSnapshot deletes the specified Snapshot of a Storage Share -func (client Client) DeleteSnapshot(ctx context.Context, accountName, shareName string, shareSnapshot string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "DeleteSnapshot", "`accountName` cannot be an empty string.") - } +func (c Client) DeleteSnapshot(ctx context.Context, accountName, shareName string, shareSnapshot string) (resp DeleteSnapshotResponse, err error) { + if shareName == "" { - return result, validation.NewError("shares.Client", "DeleteSnapshot", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "DeleteSnapshot", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } + if shareSnapshot == "" { - return result, validation.NewError("shares.Client", "DeleteSnapshot", "`shareSnapshot` cannot be an empty string.") + return resp, fmt.Errorf("`shareSnapshot` cannot be an empty string") } - req, err := client.DeleteSnapshotPreparer(ctx, accountName, shareName, shareSnapshot) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "DeleteSnapshot", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodDelete, + OptionsObject: snapShotDeleteOptions{ + shareSnapShot: shareSnapshot, + }, + Path: fmt.Sprintf("/%s", shareName), } - resp, err := client.DeleteSnapshotSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "DeleteSnapshot", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteSnapshotResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "DeleteSnapshot", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// DeleteSnapshotPreparer prepares the DeleteSnapshot request. -func (client Client) DeleteSnapshotPreparer(ctx context.Context, accountName, shareName string, shareSnapshot string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("path", "share"), - "sharesnapshot": autorest.Encode("query", shareSnapshot), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type snapShotDeleteOptions struct { + shareSnapShot string } -// DeleteSnapshotSender sends the DeleteSnapshot request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSnapshotSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s snapShotDeleteOptions) ToHeaders() *client.Headers { + return nil } -// DeleteSnapshotResponder handles the response to the DeleteSnapshot request. The method always -// closes the http.Response Body. -func (client Client) DeleteSnapshotResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (s snapShotDeleteOptions) ToOData() *odata.Query { + return nil +} - return +func (s snapShotDeleteOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("sharesnapshot", s.shareSnapShot) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go index 2cf5f16f618e..f4a12e9f0cdc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go @@ -2,104 +2,87 @@ package shares import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -type GetSnapshotPropertiesResult struct { - autorest.Response +type GetSnapshotPropertiesResponse struct { + HttpResponse *client.Response MetaData map[string]string } +type GetSnapshotPropertiesInput struct { + snapshotShare string +} + // GetSnapshot gets information about the specified Snapshot of the specified Storage Share -func (client Client) GetSnapshot(ctx context.Context, accountName, shareName, snapshotShare string) (result GetSnapshotPropertiesResult, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "GetSnapshot", "`accountName` cannot be an empty string.") - } +func (c Client) GetSnapshot(ctx context.Context, shareName string, input GetSnapshotPropertiesInput) (resp GetSnapshotPropertiesResponse, err error) { if shareName == "" { - return result, validation.NewError("shares.Client", "GetSnapshot", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "GetSnapshot", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - if snapshotShare == "" { - return result, validation.NewError("shares.Client", "GetSnapshot", "`snapshotShare` cannot be an empty string.") + + if input.snapshotShare == "" { + return resp, fmt.Errorf("`snapshotShare` cannot be an empty string") } - req, err := client.GetSnapshotPreparer(ctx, accountName, shareName, snapshotShare) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetSnapshot", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: snapShotGetOptions{ + snapshotShare: input.snapshotShare, + }, + Path: fmt.Sprintf("/%s", shareName), } - resp, err := client.GetSnapshotSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "GetSnapshot", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetSnapshotResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetSnapshot", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetSnapshotPreparer prepares the GetSnapshot request. -func (client Client) GetSnapshotPreparer(ctx context.Context, accountName, shareName, snapshotShare string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + } } - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "share"), - "snapshot": autorest.Encode("query", snapshotShare), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + return } -// GetSnapshotSender sends the GetSnapshot request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetSnapshotSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +type snapShotGetOptions struct { + snapshotShare string } -// GetSnapshotResponder handles the response to the GetSnapshot request. The method always -// closes the http.Response Body. -func (client Client) GetSnapshotResponder(resp *http.Response) (result GetSnapshotPropertiesResult, err error) { - if resp.Header != nil { - result.MetaData = metadata.ParseFromHeaders(resp.Header) - } +func (s snapShotGetOptions) ToHeaders() *client.Headers { + return nil +} - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (s snapShotGetOptions) ToOData() *odata.Query { + return nil +} - return +func (s snapShotGetOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("snapshot", s.snapshotShare) + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go index 3539eccbcd0e..23e48afe4043 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go @@ -2,17 +2,16 @@ package shares import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) -type GetStatsResult struct { - autorest.Response +type GetStatsResponse struct { + HttpResponse *client.Response // The approximate size of the data stored on the share. // Note that this value may not include all recently created or recently resized files. @@ -20,81 +19,59 @@ type GetStatsResult struct { } // GetStats returns information about the specified Storage Share -func (client Client) GetStats(ctx context.Context, accountName, shareName string) (result GetStatsResult, err error) { - if accountName == "" { - return result, validation.NewError("shares.Client", "GetStats", "`accountName` cannot be an empty string.") - } +func (c Client) GetStats(ctx context.Context, shareName string) (resp GetStatsResponse, err error) { if shareName == "" { - return result, validation.NewError("shares.Client", "GetStats", "`shareName` cannot be an empty string.") + return resp, fmt.Errorf("`shareName` cannot be an empty string") } + if strings.ToLower(shareName) != shareName { - return result, validation.NewError("shares.Client", "GetStats", "`shareName` must be a lower-cased string.") + return resp, fmt.Errorf("`shareName` must be a lower-cased string") } - req, err := client.GetStatsPreparer(ctx, accountName, shareName) - if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetStats", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: statsOptions{}, + Path: shareName, } - resp, err := client.GetStatsSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "shares.Client", "GetStats", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetStatsResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "shares.Client", "GetStats", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + err = resp.HttpResponse.Unmarshal(&resp) + if err != nil { + return resp, fmt.Errorf("unmarshalling response: %v", err) + } + } return } -// GetStatsPreparer prepares the GetStats request. -func (client Client) GetStatsPreparer(ctx context.Context, accountName, shareName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "shareName": autorest.Encode("path", shareName), - } - - queryParameters := map[string]interface{}{ - "restype": autorest.Encode("query", "share"), - "comp": autorest.Encode("query", "stats"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type statsOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetFileEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{shareName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (s statsOptions) ToHeaders() *client.Headers { + return nil } -// GetStatsSender sends the GetStats request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetStatsSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s statsOptions) ToOData() *odata.Query { + return nil } -// GetStatsResponder handles the response to the GetStats request. The method always -// closes the http.Response Body. -func (client Client) GetStatsResponder(resp *http.Response) (result GetStatsResult, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (s statsOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "share") + out.Append("comp", "stats") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go index 653693959b6f..a3c5b6d50170 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go @@ -1,14 +1,4 @@ package shares -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - -// APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "file/shares" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md index b8b84a3799a8..7c9fd1a3c6ec 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md @@ -15,9 +15,8 @@ package main import ( "context" "fmt" - "time" - - "github.com/Azure/go-autorest/autorest" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" ) @@ -25,16 +24,27 @@ func Example() error { accountName := "storageaccount1" storageAccountKey := "ABC123...." queueName := "myqueue" - - storageAuth := autorest.NewSharedKeyLiteAuthorizer(accountName, storageAccountKey) - queuesClient := queues.New() - queuesClient.Client.Authorizer = storageAuth + domainSuffix := "core.windows.net" + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + + queuesClient, err := queues.NewWithBaseUri(fmt.Sprintf("https://%s.queue.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building client for environment: %+v", err) + } + queuesClient.Client.SetAuthorizer(auth) ctx := context.TODO() metadata := map[string]string{ "hello": "world", } - if _, err := queuesClient.Create(ctx, accountName, queueName, metadata); err != nil { + input := queues.CreateInput{ + Metadata: metadata, + } + if _, err := queuesClient.Create(ctx, queueName, input); err != nil { return fmt.Errorf("Error creating Queue: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/api.go index e4c14220b68c..e051453e47f0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/api.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/api.go @@ -2,16 +2,14 @@ package queues import ( "context" - - "github.com/Azure/go-autorest/autorest" ) type StorageQueue interface { - Delete(ctx context.Context, accountName, queueName string) (result autorest.Response, err error) - GetMetaData(ctx context.Context, accountName, queueName string) (result GetMetaDataResult, err error) - SetMetaData(ctx context.Context, accountName, queueName string, metaData map[string]string) (result autorest.Response, err error) - Create(ctx context.Context, accountName, queueName string, metaData map[string]string) (result autorest.Response, err error) - GetResourceID(accountName, queueName string) string - SetServiceProperties(ctx context.Context, accountName string, properties StorageServiceProperties) (result autorest.Response, err error) - GetServiceProperties(ctx context.Context, accountName string) (result StorageServicePropertiesResponse, err error) + Delete(ctx context.Context, queueName string) (DeleteResponse, error) + GetMetaData(ctx context.Context, queueName string) (GetMetaDataResponse, error) + SetMetaData(ctx context.Context, queueName string, input SetMetaDataInput) (SetMetaDataResponse, error) + Create(ctx context.Context, queueName string, input CreateInput) (CreateResponse, error) + GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, queueName string) string + SetServiceProperties(ctx context.Context, input SetStorageServicePropertiesInput) (SetStorageServicePropertiesResponse, error) + GetServiceProperties(ctx context.Context) (GetStorageServicePropertiesResponse, error) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/client.go index 2f8008582b93..4497f0eb748c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/client.go @@ -1,25 +1,24 @@ package queues import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for Queue Storage Shares. -type Client struct { - autorest.Client - BaseURI string -} -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) +// Client is the base client for Messages. +type Client struct { + Client *storage.Client } -// NewWithEnvironment creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go index f18910a88d9e..d156052ca70d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go @@ -6,87 +6,78 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) +type CreateInput struct { + MetaData map[string]string +} + +type CreateResponse struct { + HttpResponse *client.Response +} + // Create creates the specified Queue within the specified Storage Account -func (client Client) Create(ctx context.Context, accountName, queueName string, metaData map[string]string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("queues.Client", "Create", "`accountName` cannot be an empty string.") - } +func (c Client) Create(ctx context.Context, queueName string, input CreateInput) (resp CreateResponse, err error) { + if queueName == "" { - return result, validation.NewError("queues.Client", "Create", "`queueName` cannot be an empty string.") + return resp, fmt.Errorf("`queueName` cannot be an empty string") } + if strings.ToLower(queueName) != queueName { - return result, validation.NewError("queues.Client", "Create", "`queueName` must be a lower-cased string.") + return resp, fmt.Errorf("`queueName` must be a lower-cased string") } - if err := metadata.Validate(metaData); err != nil { - return result, validation.NewError("queues.Client", "Create", fmt.Sprintf("`metadata` is not valid: %s.", err)) + + if err := metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`metadata` is not valid: %s", err) } - req, err := client.CreatePreparer(ctx, accountName, queueName, metaData) - if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "Create", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: createOptions{ + metadata: input.MetaData, + }, + Path: fmt.Sprintf("/%s", queueName), } - resp, err := client.CreateSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "queues.Client", "Create", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.CreateResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "Create", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// CreatePreparer prepares the Create request. -func (client Client) CreatePreparer(ctx context.Context, accountName string, queueName string, metaData map[string]string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "queueName": autorest.Encode("path", queueName), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type createOptions struct { + metadata map[string]string +} - headers = metadata.SetIntoHeaders(headers, metaData) +func (c createOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetQueueEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{queueName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + if len(c.metadata) > 0 { + headers.Merge(metadata.SetMetaDataHeaders(c.metadata)) + } + return headers } -// CreateSender sends the Create request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c createOptions) ToOData() *odata.Query { + return nil } -// CreateResponder handles the response to the Create request. The method always -// closes the http.Response Body. -func (client Client) CreateResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusCreated), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (c createOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go index 5f705959c446..39d5d64fa059 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go @@ -2,84 +2,49 @@ package queues import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" ) +type DeleteResponse struct { + HttpResponse *client.Response +} + // Delete deletes the specified Queue within the specified Storage Account -func (client Client) Delete(ctx context.Context, accountName, queueName string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("queues.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, queueName string) (resp DeleteResponse, err error) { + if queueName == "" { - return result, validation.NewError("queues.Client", "Delete", "`queueName` cannot be an empty string.") + return resp, fmt.Errorf("`queueName` cannot be an empty string") } + if strings.ToLower(queueName) != queueName { - return result, validation.NewError("queues.Client", "Delete", "`queueName` must be a lower-cased string.") + return resp, fmt.Errorf("`queueName` must be a lower-cased string") } - req, err := client.DeletePreparer(ctx, accountName, queueName) - if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodDelete, + OptionsObject: nil, + Path: fmt.Sprintf("/%s", queueName), } - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "queues.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "Delete", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } - -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName string, queueName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "queueName": autorest.Encode("path", queueName), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetQueueEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{queueName}", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go index 9c230b613ad3..14c32d64d0f5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go @@ -2,100 +2,75 @@ package queues import ( "context" + "fmt" "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) -type GetMetaDataResult struct { - autorest.Response +type GetMetaDataResponse struct { + HttpResponse *client.Response MetaData map[string]string } // GetMetaData returns the metadata for this Queue -func (client Client) GetMetaData(ctx context.Context, accountName, queueName string) (result GetMetaDataResult, err error) { - if accountName == "" { - return result, validation.NewError("queues.Client", "GetMetaData", "`accountName` cannot be an empty string.") - } +func (c Client) GetMetaData(ctx context.Context, queueName string) (resp GetMetaDataResponse, err error) { + if queueName == "" { - return result, validation.NewError("queues.Client", "GetMetaData", "`queueName` cannot be an empty string.") + return resp, fmt.Errorf("`queueName` cannot be an empty string") } + if strings.ToLower(queueName) != queueName { - return result, validation.NewError("queues.Client", "GetMetaData", "`queueName` must be a lower-cased string.") + return resp, fmt.Errorf("`queueName` must be a lower-cased string") } - req, err := client.GetMetaDataPreparer(ctx, accountName, queueName) - if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "GetMetaData", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getMetaDataOptions{}, + Path: fmt.Sprintf("/%s", queueName), } - resp, err := client.GetMetaDataSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "queues.Client", "GetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "GetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetMetaDataPreparer prepares the GetMetaData request. -func (client Client) GetMetaDataPreparer(ctx context.Context, accountName, queueName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "queueName": autorest.Encode("path", queueName), + if resp.HttpResponse != nil { + if resp.HttpResponse.Header != nil { + resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + } } - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("path", "metadata"), - } + return +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type getMetaDataOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetQueueEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{queueName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (g getMetaDataOptions) ToHeaders() *client.Headers { + return nil } -// GetMetaDataSender sends the GetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g getMetaDataOptions) ToOData() *odata.Query { + return nil } -// GetMetaDataResponder handles the response to the GetMetaData request. The method always -// closes the http.Response Body. -func (client Client) GetMetaDataResponder(resp *http.Response) (result GetMetaDataResult, err error) { - if resp != nil { - result.MetaData = metadata.ParseFromHeaders(resp.Header) - } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (g getMetaDataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go index 51154a5c4334..ea8eac3192da 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go @@ -6,92 +6,77 @@ import ( "net/http" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" ) +type SetMetaDataResponse struct { + HttpResponse *client.Response +} + +type SetMetaDataInput struct { + MetaData map[string]string +} + // SetMetaData returns the metadata for this Queue -func (client Client) SetMetaData(ctx context.Context, accountName, queueName string, metaData map[string]string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("queues.Client", "SetMetaData", "`accountName` cannot be an empty string.") - } +func (c Client) SetMetaData(ctx context.Context, queueName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { + if queueName == "" { - return result, validation.NewError("queues.Client", "SetMetaData", "`queueName` cannot be an empty string.") + return resp, fmt.Errorf("`queueName` cannot be an empty string") } + if strings.ToLower(queueName) != queueName { - return result, validation.NewError("queues.Client", "SetMetaData", "`queueName` must be a lower-cased string.") + return resp, fmt.Errorf("`queueName` must be a lower-cased string") } - if err := metadata.Validate(metaData); err != nil { - return result, validation.NewError("queues.Client", "SetMetaData", fmt.Sprintf("`metadata` is not valid: %s.", err)) + + if err := metadata.Validate(input.MetaData); err != nil { + return resp, fmt.Errorf("`metadata` is not valid: %v", err) } - req, err := client.SetMetaDataPreparer(ctx, accountName, queueName, metaData) - if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "SetMetaData", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodPut, + OptionsObject: setMetaDataOptions{ + metadata: input.MetaData, + }, + Path: fmt.Sprintf("/%s", queueName), } - resp, err := client.SetMetaDataSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "queues.Client", "SetMetaData", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.SetMetaDataResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "SetMetaData", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetMetaDataPreparer prepares the SetMetaData request. -func (client Client) SetMetaDataPreparer(ctx context.Context, accountName, queueName string, metaData map[string]string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "queueName": autorest.Encode("path", queueName), - } - - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("path", "metadata"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - headers = metadata.SetIntoHeaders(headers, metaData) - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetQueueEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{queueName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type setMetaDataOptions struct { + metadata map[string]string } -// SetMetaDataSender sends the SetMetaData request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetMetaDataSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s setMetaDataOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Merge(metadata.SetMetaDataHeaders(s.metadata)) + return headers } -// SetMetaDataResponder handles the response to the SetMetaData request. The method always -// closes the http.Response Body. -func (client Client) SetMetaDataResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (s setMetaDataOptions) ToOData() *odata.Query { + return nil +} - return +func (s setMetaDataOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "metadata") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/models.go index 2195244fa44b..fbbbce9634c4 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/models.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/models.go @@ -36,7 +36,7 @@ type Cors struct { type CorsRule struct { AllowedOrigins string `xml:"AllowedOrigins"` AllowedMethods string `xml:"AllowedMethods"` - AllowedHeaders string `xml:"AllowedHeaders` + AllowedHeaders string `xml:"AllowedHeaders"` ExposedHeaders string `xml:"ExposedHeaders"` MaxAgeInSeconds int `xml:"MaxAgeInSeconds"` } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go index a0e51ad34354..b2ea774e5534 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go @@ -2,85 +2,66 @@ package queues import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) -type StorageServicePropertiesResponse struct { +type GetStorageServicePropertiesResponse struct { StorageServiceProperties - autorest.Response + HttpResponse *client.Response } -// SetServiceProperties gets the properties for this queue -func (client Client) GetServiceProperties(ctx context.Context, accountName string) (result StorageServicePropertiesResponse, err error) { - if accountName == "" { - return result, validation.NewError("queues.Client", "GetServiceProperties", "`accountName` cannot be an empty string.") +// GetServiceProperties gets the properties for this queue +func (c Client) GetServiceProperties(ctx context.Context) (resp GetStorageServicePropertiesResponse, err error) { + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getStorageServicePropertiesOptions{}, + Path: "/", } - req, err := client.GetServicePropertiesPreparer(ctx, accountName) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "GetServiceProperties", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.GetServicePropertiesSender(req) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "queues.Client", "GetServiceProperties", resp, "Failure sending request") + err = fmt.Errorf("executing request: %+v", err) return } - result, err = client.GetServicePropertiesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "GetServiceProperties", resp, "Failure responding to request") - return + if resp.HttpResponse != nil { + err = resp.HttpResponse.Unmarshal(&resp) + if err != nil { + return resp, fmt.Errorf("unmarshalling respnse: %v", err) + } } return } -// GetServicePropertiesPreparer prepares the GetServiceProperties request. -func (client Client) GetServicePropertiesPreparer(ctx context.Context, accountName string) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("path", "properties"), - "restype": autorest.Encode("path", "service"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type getStorageServicePropertiesOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetQueueEndpoint(client.BaseURI, accountName)), - autorest.WithPath("/"), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (g getStorageServicePropertiesOptions) ToHeaders() *client.Headers { + return nil } -// GetServicePropertiesSender sends the GetServiceProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetServicePropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g getStorageServicePropertiesOptions) ToOData() *odata.Query { + return nil } -// GetServicePropertiesResponder handles the response to the GetServiceProperties request. The method always -// closes the http.Response Body. -func (client Client) GetServicePropertiesResponder(resp *http.Response) (result StorageServicePropertiesResponse, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (g getStorageServicePropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "properties") + out.Append("restype", "service") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go index 33dd40b3da1f..744bd9767ed1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go @@ -1,81 +1,76 @@ package queues import ( + "bytes" "context" + "encoding/xml" + "fmt" + "io" "net/http" + "strconv" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type SetStorageServicePropertiesResponse struct { + HttpResponse *client.Response +} + +type SetStorageServicePropertiesInput struct { + Properties StorageServiceProperties +} + // SetServiceProperties sets the properties for this queue -func (client Client) SetServiceProperties(ctx context.Context, accountName string, properties StorageServiceProperties) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("queues.Client", "SetServiceProperties", "`accountName` cannot be an empty string.") +func (c Client) SetServiceProperties(ctx context.Context, input SetStorageServicePropertiesInput) (resp SetStorageServicePropertiesResponse, err error) { + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: setStorageServicePropertiesOptions{}, + Path: "/", } - req, err := client.SetServicePropertiesPreparer(ctx, accountName, properties) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "SetServiceProperties", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.SetServicePropertiesSender(req) + marshalledProps, err := xml.Marshal(&input.Properties) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "queues.Client", "SetServiceProperties", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request: %v", err) } + body := xml.Header + string(marshalledProps) + req.Body = io.NopCloser(bytes.NewReader([]byte(body))) + req.ContentLength = int64(len(body)) + req.Header.Set("Content-Length", strconv.Itoa(len(body))) - result, err = client.SetServicePropertiesResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "queues.Client", "SetServiceProperties", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetServicePropertiesPreparer prepares the SetServiceProperties request. -func (client Client) SetServicePropertiesPreparer(ctx context.Context, accountName string, properties StorageServiceProperties) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("path", "properties"), - "restype": autorest.Encode("path", "service"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type setStorageServicePropertiesOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetQueueEndpoint(client.BaseURI, accountName)), - autorest.WithPath("/"), - autorest.WithQueryParameters(queryParameters), - autorest.WithXML(properties), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (s setStorageServicePropertiesOptions) ToHeaders() *client.Headers { + return nil } -// SetServicePropertiesSender sends the SetServiceProperties request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetServicePropertiesSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s setStorageServicePropertiesOptions) ToOData() *odata.Query { + return nil } -// SetServicePropertiesResponder handles the response to the SetServiceProperties request. The method always -// closes the http.Response Body. -func (client Client) SetServicePropertiesResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusAccepted), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (s setStorageServicePropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("restype", "service") + out.Append("comp", "properties") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go index 912923abca0d..455319a23308 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go @@ -5,42 +5,77 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given Queue +// GetResourceManagerResourceID returns the Resource Manager ID for the given Queue // This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, queueName string) string { - domain := endpoints.GetQueueEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s", domain, queueName) +func (c Client) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, queueName string) string { + fmtStr := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/queueServices/default/queues/%s" + return fmt.Sprintf(fmtStr, subscriptionID, resourceGroup, accountName, queueName) } -type ResourceID struct { - AccountName string - QueueName string +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = QueueId{} + +type QueueId struct { + // AccountId specifies the ID of the Storage Account where this Queue exists. + AccountId accounts.AccountId + + // QueueName specifies the name of this Queue. + QueueName string +} + +func NewQueueID(accountId accounts.AccountId, queueName string) QueueId { + return QueueId{ + AccountId: accountId, + QueueName: queueName, + } +} + +func (b QueueId) ID() string { + return fmt.Sprintf("%s/%s", b.AccountId.ID(), b.QueueName) } -// ParseResourceID parses the Resource ID and returns an Object which -// can be used to interact with a Queue within a Storage Account -func ParseResourceID(id string) (*ResourceID, error) { +func (b QueueId) String() string { + components := []string{ + fmt.Sprintf("Account %q", b.AccountId.String()), + } + return fmt.Sprintf("Queue %q (%s)", b.QueueName, strings.Join(components, " / ")) +} + +// ParseQueueID parses `input` into a Queue ID using a known `domainSuffix` +func ParseQueueID(input, domainSuffix string) (*QueueId, error) { // example: https://foo.queue.core.windows.net/Bar - if id == "" { - return nil, fmt.Errorf("`id` was empty") + if input == "" { + return nil, fmt.Errorf("`input` was empty") } - uri, err := url.Parse(id) + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + if account.SubDomainType != accounts.QueueSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.QueueSubDomainType), string(account.SubDomainType)) + } + + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) + } + + path := strings.TrimPrefix(uri.Path, "/") + segments := strings.Split(path, "/") + if len(segments) != 1 { + return nil, fmt.Errorf("expected the path to contain 1 segment but got %d", len(segments)) } queueName := strings.TrimPrefix(uri.Path, "/") - return &ResourceID{ - AccountName: *accountName, - QueueName: queueName, + return &QueueId{ + AccountId: *account, + QueueName: queueName, }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go index 9d3e68949fec..10937c5727d3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go @@ -1,14 +1,5 @@ package queues -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - // APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "queue/queues" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/README.md index e59b5a28335a..e98e21e68eeb 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/README.md @@ -14,9 +14,8 @@ package main import ( "context" "fmt" - "time" - - "github.com/Azure/go-autorest/autorest" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" ) @@ -24,10 +23,18 @@ func Example() error { accountName := "storageaccount1" storageAccountKey := "ABC123...." tableName := "mytable" - - storageAuth := autorest.NewSharedKeyLiteTableAuthorizer(accountName, storageAccountKey) - entitiesClient := entities.New() - entitiesClient.Client.Authorizer = storageAuth + domainSuffix := "core.windows.net" + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKeyTable) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + + entitiesClient, err := entities.NewWithBaseUri(fmt.Sprintf("https://%s.table.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building client for environment: %+v", err) + } + entitiesClient.Client.SetAuthorizer(auth) ctx := context.TODO() input := entities.InsertEntityInput{ @@ -39,7 +46,7 @@ func Example() error { "artist": "Sigrid", }, } - if _, err := entitiesClient.Insert(ctx, accountName, tableName, input); err != nil { + if _, err := entitiesClient.Insert(ctx, tableName, input); err != nil { return fmt.Errorf("Error creating Entity: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/api.go index d4d20a723457..bb0e9809e3c9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/api.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/api.go @@ -2,16 +2,13 @@ package entities import ( "context" - - "github.com/Azure/go-autorest/autorest" ) type StorageTableEntity interface { - Delete(ctx context.Context, accountName, tableName string, input DeleteEntityInput) (result autorest.Response, err error) - Insert(ctx context.Context, accountName, tableName string, input InsertEntityInput) (result autorest.Response, err error) - InsertOrReplace(ctx context.Context, accountName, tableName string, input InsertOrReplaceEntityInput) (result autorest.Response, err error) - InsertOrMerge(ctx context.Context, accountName, tableName string, input InsertOrMergeEntityInput) (result autorest.Response, err error) - Query(ctx context.Context, accountName, tableName string, input QueryEntitiesInput) (result QueryEntitiesResult, err error) - Get(ctx context.Context, accountName, tableName string, input GetEntityInput) (result GetEntityResult, err error) - GetResourceID(accountName, tableName, partitionKey, rowKey string) string + Delete(ctx context.Context, tableName string, input DeleteEntityInput) (resp DeleteEntityResponse, err error) + Insert(ctx context.Context, tableName string, input InsertEntityInput) (resp InsertResponse, err error) + InsertOrReplace(ctx context.Context, tableName string, input InsertOrReplaceEntityInput) (resp InsertOrReplaceResponse, err error) + InsertOrMerge(ctx context.Context, tableName string, input InsertOrMergeEntityInput) (resp InsertOrMergeResponse, err error) + Query(ctx context.Context, tableName string, input QueryEntitiesInput) (resp QueryEntitiesResponse, err error) + Get(ctx context.Context, tableName string, input GetEntityInput) (resp GetEntityResponse, err error) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/client.go index 17e9d759fb9e..e190af69d108 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/client.go @@ -1,25 +1,23 @@ package entities import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for Table Storage Shares. type Client struct { - autorest.Client - BaseURI string -} - -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) + Client *storage.Client } -// NewWithEnvironment creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } + + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/delete.go index 83e9188e5e9e..05d09b3ce32e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/delete.go @@ -2,12 +2,11 @@ package entities import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type DeleteEntityInput struct { @@ -20,80 +19,62 @@ type DeleteEntityInput struct { PartitionKey string } +type DeleteEntityResponse struct { + HttpResponse *client.Response +} + // Delete deletes an existing entity in a table. -func (client Client) Delete(ctx context.Context, accountName, tableName string, input DeleteEntityInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("entities.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, tableName string, input DeleteEntityInput) (resp DeleteEntityResponse, err error) { + if tableName == "" { - return result, validation.NewError("entities.Client", "Delete", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } + if input.PartitionKey == "" { - return result, validation.NewError("entities.Client", "Delete", "`input.PartitionKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } + if input.RowKey == "" { - return result, validation.NewError("entities.Client", "Delete", "`input.RowKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") } - req, err := client.DeletePreparer(ctx, accountName, tableName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodDelete, + OptionsObject: deleteEntitiesOptions{}, + Path: fmt.Sprintf("/%s(PartitionKey='%s', RowKey='%s')", tableName, input.PartitionKey, input.RowKey), } - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "entities.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "Delete", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return } -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName, tableName string, input DeleteEntityInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - "partitionKey": autorest.Encode("path", input.PartitionKey), - "rowKey": autorest.Encode("path", input.RowKey), - } +type deleteEntitiesOptions struct{} - headers := map[string]interface{}{ - // TODO: support for eTags - "If-Match": "*", - } - - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{tableName}(PartitionKey='{partitionKey}', RowKey='{rowKey}')", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (d deleteEntitiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json") + headers.Append("If-Match", "*") + return headers } -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (d deleteEntitiesOptions) ToOData() *odata.Query { + return nil } -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (d deleteEntitiesOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/get.go index bdb40180b54d..14cd5ad38d04 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/get.go @@ -5,10 +5,8 @@ import ( "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type GetEntityInput struct { @@ -19,90 +17,76 @@ type GetEntityInput struct { MetaDataLevel MetaDataLevel } -type GetEntityResult struct { - autorest.Response +type GetEntityResponse struct { + HttpResponse *client.Response Entity map[string]interface{} } // Get queries entities in a table and includes the $filter and $select options. -func (client Client) Get(ctx context.Context, accountName, tableName string, input GetEntityInput) (result GetEntityResult, err error) { - if accountName == "" { - return result, validation.NewError("entities.Client", "Get", "`accountName` cannot be an empty string.") - } +func (c Client) Get(ctx context.Context, tableName string, input GetEntityInput) (resp GetEntityResponse, err error) { if tableName == "" { - return result, validation.NewError("entities.Client", "Get", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } + if input.PartitionKey == "" { - return result, validation.NewError("entities.Client", "Get", "`input.PartitionKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } + if input.RowKey == "" { - return result, validation.NewError("entities.Client", "Get", "`input.RowKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") } - req, err := client.GetPreparer(ctx, accountName, tableName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "Get", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getEntitiesOptions{ + MetaDataLevel: input.MetaDataLevel, + }, + Path: fmt.Sprintf("/%s(PartitionKey='%s', RowKey='%s')", tableName, input.PartitionKey, input.RowKey), } - resp, err := client.GetSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "entities.Client", "Get", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "Get", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + if resp.HttpResponse.Body != nil { + err = resp.HttpResponse.Unmarshal(&resp.Entity) + if err != nil { + return resp, fmt.Errorf("unmarshalling response: %+v", err) + } + } + } return } -// GetPreparer prepares the Get request. -func (client Client) GetPreparer(ctx context.Context, accountName, tableName string, input GetEntityInput) (*http.Request, error) { - - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - "partitionKey": autorest.Encode("path", input.PartitionKey), - "rowKey": autorest.Encode("path", input.RowKey), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "Accept": fmt.Sprintf("application/json;odata=%s", input.MetaDataLevel), - "DataServiceVersion": "3.0;NetFx", - "MaxDataServiceVersion": "3.0;NetFx", - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{tableName}(PartitionKey='{partitionKey}',RowKey='{rowKey}')", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type getEntitiesOptions struct { + MetaDataLevel MetaDataLevel } -// GetSender sends the Get request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g getEntitiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", fmt.Sprintf("application/json;odata=%s", g.MetaDataLevel)) + headers.Append("DataServiceVersion", "3.0;NetFx") + headers.Append("MaxDataServiceVersion", "3.0;NetFx") + return headers } -// GetResponder handles the response to the Get request. The method always -// closes the http.Response Body. -func (client Client) GetResponder(resp *http.Response) (result GetEntityResult, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result.Entity), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} +func (g getEntitiesOptions) ToOData() *odata.Query { + return nil +} - return +func (g getEntitiesOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert.go index 92b05cef5499..315b7ce5b653 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert.go @@ -5,10 +5,8 @@ import ( "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type InsertEntityInput struct { @@ -29,84 +27,74 @@ type InsertEntityInput struct { PartitionKey string } +type InsertResponse struct { + HttpResponse *client.Response +} + // Insert inserts a new entity into a table. -func (client Client) Insert(ctx context.Context, accountName, tableName string, input InsertEntityInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("entities.Client", "Insert", "`accountName` cannot be an empty string.") - } +func (c Client) Insert(ctx context.Context, tableName string, input InsertEntityInput) (resp InsertResponse, err error) { if tableName == "" { - return result, validation.NewError("entities.Client", "Insert", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } + if input.PartitionKey == "" { - return result, validation.NewError("entities.Client", "Insert", "`input.PartitionKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } + if input.RowKey == "" { - return result, validation.NewError("entities.Client", "Insert", "`input.RowKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") } - req, err := client.InsertPreparer(ctx, accountName, tableName, input) + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodPost, + OptionsObject: insertOptions{ + MetaDataLevel: input.MetaDataLevel, + }, + Path: fmt.Sprintf("/%s", tableName), + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "Insert", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.InsertSender(req) + input.Entity["PartitionKey"] = input.PartitionKey + input.Entity["RowKey"] = input.RowKey + + err = req.Marshal(&input.Entity) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "entities.Client", "Insert", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request: %v", err) } - result, err = client.InsertResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "Insert", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// InsertPreparer prepares the Insert request. -func (client Client) InsertPreparer(ctx context.Context, accountName, tableName string, input InsertEntityInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "Accept": fmt.Sprintf("application/json;odata=%s", input.MetaDataLevel), - "Prefer": "return-no-content", - } - - input.Entity["PartitionKey"] = input.PartitionKey - input.Entity["RowKey"] = input.RowKey - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json"), - autorest.AsPost(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{tableName}", pathParameters), - autorest.WithJSON(input.Entity), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type insertOptions struct { + MetaDataLevel MetaDataLevel } -// InsertSender sends the Insert request. The method will close the -// http.Response Body if it receives an error. -func (client Client) InsertSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (i insertOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", fmt.Sprintf("application/json;odata=%s", i.MetaDataLevel)) + headers.Append("Prefer", "return-no-content") + return headers } -// InsertResponder handles the response to the Insert request. The method always -// closes the http.Response Body. -func (client Client) InsertResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (i insertOptions) ToOData() *odata.Query { + return nil +} - return +func (i insertOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_merge.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_merge.go index 1fb4ed3df164..27cae93239bf 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_merge.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_merge.go @@ -2,12 +2,11 @@ package entities import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type InsertOrMergeEntityInput struct { @@ -25,84 +24,71 @@ type InsertOrMergeEntityInput struct { PartitionKey string } +type InsertOrMergeResponse struct { + HttpResponse *client.Response +} + // InsertOrMerge updates an existing entity or inserts a new entity if it does not exist in the table. // Because this operation can insert or update an entity, it is also known as an upsert operation. -func (client Client) InsertOrMerge(ctx context.Context, accountName, tableName string, input InsertOrMergeEntityInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("entities.Client", "InsertOrMerge", "`accountName` cannot be an empty string.") - } +func (c Client) InsertOrMerge(ctx context.Context, tableName string, input InsertOrMergeEntityInput) (resp InsertOrMergeResponse, err error) { if tableName == "" { - return result, validation.NewError("entities.Client", "InsertOrMerge", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } + if input.PartitionKey == "" { - return result, validation.NewError("entities.Client", "InsertOrMerge", "`input.PartitionKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } + if input.RowKey == "" { - return result, validation.NewError("entities.Client", "InsertOrMerge", "`input.RowKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: "MERGE", + OptionsObject: insertOrMergeOptions{}, + Path: fmt.Sprintf("/%s(PartitionKey='%s', RowKey='%s')", tableName, input.PartitionKey, input.RowKey), } - req, err := client.InsertOrMergePreparer(ctx, accountName, tableName, input) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "InsertOrMerge", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.InsertOrMergeSender(req) + input.Entity["PartitionKey"] = input.PartitionKey + input.Entity["RowKey"] = input.RowKey + + err = req.Marshal(&input.Entity) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "entities.Client", "InsertOrMerge", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request: %v", err) } - result, err = client.InsertOrMergeResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "InsertOrMerge", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// InsertOrMergePreparer prepares the InsertOrMerge request. -func (client Client) InsertOrMergePreparer(ctx context.Context, accountName, tableName string, input InsertOrMergeEntityInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - "partitionKey": autorest.Encode("path", input.PartitionKey), - "rowKey": autorest.Encode("path", input.RowKey), - } +type insertOrMergeOptions struct{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "Accept": "application/json", - "Prefer": "return-no-content", - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json"), - autorest.AsMerge(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{tableName}(PartitionKey='{partitionKey}', RowKey='{rowKey}')", pathParameters), - autorest.WithJSON(input.Entity), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (i insertOrMergeOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json") + headers.Append("Prefer", "return-no-content") + return headers } -// InsertOrMergeSender sends the InsertOrMerge request. The method will close the -// http.Response Body if it receives an error. -func (client Client) InsertOrMergeSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (i insertOrMergeOptions) ToOData() *odata.Query { + return nil } -// InsertOrMergeResponder handles the response to the InsertOrMerge request. The method always -// closes the http.Response Body. -func (client Client) InsertOrMergeResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (i insertOrMergeOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_replace.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_replace.go index 036ba5de5fe7..6f97eb624b7d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_replace.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_replace.go @@ -2,12 +2,11 @@ package entities import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type InsertOrReplaceEntityInput struct { @@ -25,84 +24,71 @@ type InsertOrReplaceEntityInput struct { PartitionKey string } +type InsertOrReplaceResponse struct { + HttpResponse *client.Response +} + // InsertOrReplace replaces an existing entity or inserts a new entity if it does not exist in the table. // Because this operation can insert or update an entity, it is also known as an upsert operation. -func (client Client) InsertOrReplace(ctx context.Context, accountName, tableName string, input InsertOrReplaceEntityInput) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("entities.Client", "InsertOrReplace", "`accountName` cannot be an empty string.") - } +func (c Client) InsertOrReplace(ctx context.Context, tableName string, input InsertOrReplaceEntityInput) (resp InsertOrReplaceResponse, err error) { if tableName == "" { - return result, validation.NewError("entities.Client", "InsertOrReplace", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } + if input.PartitionKey == "" { - return result, validation.NewError("entities.Client", "InsertOrReplace", "`input.PartitionKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } + if input.RowKey == "" { - return result, validation.NewError("entities.Client", "InsertOrReplace", "`input.RowKey` cannot be an empty string.") + return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: "MERGE", + OptionsObject: insertOrReplaceOptions{}, + Path: fmt.Sprintf("/%s(PartitionKey='%s', RowKey='%s')", tableName, input.PartitionKey, input.RowKey), } - req, err := client.InsertOrReplacePreparer(ctx, accountName, tableName, input) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "InsertOrReplace", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.InsertOrReplaceSender(req) + input.Entity["PartitionKey"] = input.PartitionKey + input.Entity["RowKey"] = input.RowKey + + err = req.Marshal(&input.Entity) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "entities.Client", "InsertOrReplace", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request: %v", err) } - result, err = client.InsertOrReplaceResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "InsertOrReplace", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// InsertOrReplacePreparer prepares the InsertOrReplace request. -func (client Client) InsertOrReplacePreparer(ctx context.Context, accountName, tableName string, input InsertOrReplaceEntityInput) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - "partitionKey": autorest.Encode("path", input.PartitionKey), - "rowKey": autorest.Encode("path", input.RowKey), - } +type insertOrReplaceOptions struct{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "Accept": "application/json", - "Prefer": "return-no-content", - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json"), - autorest.AsMerge(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{tableName}(PartitionKey='{partitionKey}', RowKey='{rowKey}')", pathParameters), - autorest.WithJSON(input.Entity), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (i insertOrReplaceOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json") + headers.Append("Prefer", "return-no-content") + return headers } -// InsertOrReplaceSender sends the InsertOrReplace request. The method will close the -// http.Response Body if it receives an error. -func (client Client) InsertOrReplaceSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (i insertOrReplaceOptions) ToOData() *odata.Query { + return nil } -// InsertOrReplaceResponder handles the response to the InsertOrReplace request. The method always -// closes the http.Response Body. -func (client Client) InsertOrReplaceResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (i insertOrReplaceOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/query.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/query.go index c1ba3706be7d..9137401377df 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/query.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/query.go @@ -4,12 +4,11 @@ import ( "context" "fmt" "net/http" + "strconv" "strings" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type QueryEntitiesInput struct { @@ -35,8 +34,8 @@ type QueryEntitiesInput struct { NextRowKey *string } -type QueryEntitiesResult struct { - autorest.Response +type QueryEntitiesResponse struct { + HttpResponse *client.Response NextPartitionKey string NextRowKey string @@ -46,117 +45,98 @@ type QueryEntitiesResult struct { } // Query queries entities in a table and includes the $filter and $select options. -func (client Client) Query(ctx context.Context, accountName, tableName string, input QueryEntitiesInput) (result QueryEntitiesResult, err error) { - if accountName == "" { - return result, validation.NewError("entities.Client", "Query", "`accountName` cannot be an empty string.") - } +func (c Client) Query(ctx context.Context, tableName string, input QueryEntitiesInput) (resp QueryEntitiesResponse, err error) { if tableName == "" { - return result, validation.NewError("entities.Client", "Query", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } - req, err := client.QueryPreparer(ctx, accountName, tableName, input) - if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "Query", nil, "Failure preparing request") - return + additionalParameters := make([]string, 0) + if input.PartitionKey != "" { + additionalParameters = append(additionalParameters, "PartitionKey='%s'", input.PartitionKey) + } + + if input.RowKey != "" { + additionalParameters = append(additionalParameters, "RowKey='%s'", input.RowKey) + } + + path := fmt.Sprintf("/%s", tableName) + if len(additionalParameters) > 0 { + path += fmt.Sprintf("(%s)", strings.Join(additionalParameters, ",")) } - resp, err := client.QuerySender(req) + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: queryOptions{ + input: input, + }, + Path: path, + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "entities.Client", "Query", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.QueryResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "entities.Client", "Query", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } + if resp.HttpResponse != nil { + if resp.HttpResponse.Body != nil { + err = resp.HttpResponse.Unmarshal(&resp) + if err != nil { + return resp, fmt.Errorf("unmarshalling response: %v", err) + } + } + } + return } -// QueryPreparer prepares the Query request. -func (client Client) QueryPreparer(ctx context.Context, accountName, tableName string, input QueryEntitiesInput) (*http.Request, error) { - - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - "additionalParameters": "", - } - - //PartitionKey='',RowKey='' - additionalParams := make([]string, 0) - if input.PartitionKey != "" { - additionalParams = append(additionalParams, fmt.Sprintf("PartitionKey='%s'", input.PartitionKey)) - } - if input.RowKey != "" { - additionalParams = append(additionalParams, fmt.Sprintf("RowKey='%s'", input.RowKey)) - } - if len(additionalParams) > 0 { - pathParameters["additionalParameters"] = autorest.Encode("path", strings.Join(additionalParams, ",")) - } +type queryOptions struct { + input QueryEntitiesInput +} - queryParameters := map[string]interface{}{} +func (q queryOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", fmt.Sprintf("application/json;odata=%s", q.input.MetaDataLevel)) + headers.Append("DataServiceVersion", "3.0;NetFx") + headers.Append("MaxDataServiceVersion", "3.0;NetFx") + return headers +} - if input.Filter != nil { - queryParameters["$filter"] = autorest.Encode("query", *input.Filter) - } +func (q queryOptions) ToOData() *odata.Query { + return nil +} - if input.PropertyNamesToSelect != nil { - queryParameters["$select"] = autorest.Encode("query", strings.Join(*input.PropertyNamesToSelect, ",")) - } +func (q queryOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} - if input.Top != nil { - queryParameters["$top"] = autorest.Encode("query", *input.Top) + if q.input.Filter != nil { + out.Append("$filter", *q.input.Filter) } - if input.NextPartitionKey != nil { - queryParameters["NextPartitionKey"] = *input.NextPartitionKey + if q.input.PropertyNamesToSelect != nil { + out.Append("$select", strings.Join(*q.input.PropertyNamesToSelect, ",")) } - if input.NextRowKey != nil { - queryParameters["NextRowKey"] = *input.NextRowKey + if q.input.Top != nil { + out.Append("$top", strconv.Itoa(*q.input.Top)) } - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "Accept": fmt.Sprintf("application/json;odata=%s", input.MetaDataLevel), - "DataServiceVersion": "3.0;NetFx", - "MaxDataServiceVersion": "3.0;NetFx", + if q.input.NextPartitionKey != nil { + out.Append("NextPartitionKey", *q.input.NextPartitionKey) } - // GET /myaccount/Customers()?$filter=(Rating%20ge%203)%20and%20(Rating%20le%206)&$select=PartitionKey,RowKey,Address,CustomerSince - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{tableName}({additionalParameters})", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// QuerySender sends the Query request. The method will close the -// http.Response Body if it receives an error. -func (client Client) QuerySender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) -} - -// QueryResponder handles the response to the Query request. The method always -// closes the http.Response Body. -func (client Client) QueryResponder(resp *http.Response) (result QueryEntitiesResult, err error) { - if resp != nil && resp.Header != nil { - result.NextPartitionKey = resp.Header.Get("x-ms-continuation-NextPartitionKey") - result.NextRowKey = resp.Header.Get("x-ms-continuation-NextRowKey") + if q.input.NextRowKey != nil { + out.Append("NextRowKey", *q.input.NextRowKey) } - - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/resource_id.go index 249671dc91bf..04ebe79add87 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/resource_id.go @@ -5,87 +5,123 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given Entity -// This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, tableName, partitionKey, rowKey string) string { - domain := endpoints.GetTableEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/%s(PartitionKey='%s',RowKey='%s')", domain, tableName, partitionKey, rowKey) -} +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = EntityId{} + +type EntityId struct { + // AccountId specifies the ID of the Storage Account where this Entity exists. + AccountId accounts.AccountId -type ResourceID struct { - AccountName string - TableName string + // TableName specifies the name of the Table where this Entity exists. + TableName string + + // PartitionKey specifies the Partition Key for this Entity. PartitionKey string - RowKey string + + // RowKey specifies the Row Key for this Entity. + RowKey string +} + +func NewEntityID(accountId accounts.AccountId, tableName, partitionKey, rowKey string) EntityId { + return EntityId{ + AccountId: accountId, + TableName: tableName, + PartitionKey: partitionKey, + RowKey: rowKey, + } +} + +func (b EntityId) ID() string { + return fmt.Sprintf("%s/%s(PartitionKey='%s',RowKey='%s')", b.AccountId.ID(), b.TableName, b.PartitionKey, b.RowKey) +} + +func (b EntityId) String() string { + components := []string{ + fmt.Sprintf("Partition Key %q", b.PartitionKey), + fmt.Sprintf("Row Key %q", b.RowKey), + fmt.Sprintf("Table Name %q", b.TableName), + fmt.Sprintf("Account %q", b.AccountId.String()), + } + return fmt.Sprintf("Entity (%s)", strings.Join(components, " / ")) } -// ParseResourceID parses the specified Resource ID and returns an object which -// can be used to look up the specified Entity within the specified Table -func ParseResourceID(id string) (*ResourceID, error) { - // example: https://account1.table.core.chinacloudapi.cn/table1(PartitionKey='partition1',RowKey='row1') - if id == "" { - return nil, fmt.Errorf("`id` was empty") +// ParseEntityID parses `input` into a Entity ID using a known `domainSuffix` +func ParseEntityID(input, domainSuffix string) (*EntityId, error) { + // example: https://foo.table.core.windows.net/bar(PartitionKey='partition1',RowKey='row1') + if input == "" { + return nil, fmt.Errorf("`input` was empty") } - uri, err := url.Parse(id) + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) + } + + if account.SubDomainType != accounts.TableSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.TableSubDomainType), string(account.SubDomainType)) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) } - // assume there a `Table('')` path := strings.TrimPrefix(uri.Path, "/") - if !strings.Contains(uri.Path, "(") || !strings.HasSuffix(uri.Path, ")") { - return nil, fmt.Errorf("Expected the Table Name to be in the format `tables(PartitionKey='',RowKey='')` but got %q", path) + segments := strings.Split(path, "/") + if len(segments) != 1 { + return nil, fmt.Errorf("expected the path to contain 1 segment but got %d", len(segments)) } - // NOTE: honestly this could probably be a RegEx, but this seemed like the simplest way to - // allow these two fields to be specified in either order - indexOfBracket := strings.IndexByte(path, '(') - tableName := path[0:indexOfBracket] - - // trim off the brackets - temp := strings.TrimPrefix(path, fmt.Sprintf("%s(", tableName)) - temp = strings.TrimSuffix(temp, ")") - - dictionary := strings.Split(temp, ",") - partitionKey := "" - rowKey := "" - for _, v := range dictionary { - split := strings.Split(v, "=") - if len(split) != 2 { - return nil, fmt.Errorf("Expected 2 segments but got %d for %q", len(split), v) - } - - key := split[0] - value := strings.TrimSuffix(strings.TrimPrefix(split[1], "'"), "'") - if strings.EqualFold(key, "PartitionKey") { - partitionKey = value - } else if strings.EqualFold(key, "RowKey") { - rowKey = value - } else { - return nil, fmt.Errorf("Unexpected Key %q", key) - } + // Tables and Table Entities are similar with table being `table1` and entities + // being `table1(PartitionKey='samplepartition',RowKey='samplerow')` so we need to validate this is a table + slug := strings.TrimPrefix(uri.Path, "/") + if strings.HasPrefix(slug, "Tables('") && strings.HasSuffix(slug, "')") { + // Ensure we do not parse a Table ID in the format: https://foo.table.core.windows.net/Table('foo') + return nil, fmt.Errorf("expected the path to be an entity name but got a table name: %q", slug) + } else if !strings.Contains(slug, "(") || !strings.HasSuffix(slug, ")") { + // Ensure we do not try to parse a bare table name + return nil, fmt.Errorf("expected the path to be an entity name but got an invalid format, possibly a table name: %q", slug) } - if partitionKey == "" { - return nil, fmt.Errorf("Expected a PartitionKey but didn't get one") - } - if rowKey == "" { - return nil, fmt.Errorf("Expected a RowKey but didn't get one") + indexOfFirstBracket := strings.Index(slug, "(") + tableName := slug[0:indexOfFirstBracket] + componentString := slug[indexOfFirstBracket:] + componentString = strings.TrimPrefix(componentString, "(") + componentString = strings.TrimSuffix(componentString, ")") + components := strings.Split(componentString, ",") + if len(components) != 2 { + return nil, fmt.Errorf("expected the path to be an entity name but got %q", slug) } - return &ResourceID{ - AccountName: *accountName, + partitionKey := parseValueFromKey(components[0], "PartitionKey") + rowKey := parseValueFromKey(components[1], "RowKey") + + return &EntityId{ + AccountId: *account, TableName: tableName, - PartitionKey: partitionKey, - RowKey: rowKey, + PartitionKey: *partitionKey, + RowKey: *rowKey, }, nil } + +func parseValueFromKey(input, expectedKey string) *string { + components := strings.Split(input, "=") + if len(components) != 2 { + return nil + } + key := components[0] + value := components[1] + if key != expectedKey { + return nil + } + + // the value is surrounded in single quotes, remove those + value = strings.TrimPrefix(value, "'") + value = strings.TrimSuffix(value, "'") + return &value +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/version.go index 6270953c7923..13d95b5bcd29 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/version.go @@ -1,14 +1,4 @@ package entities -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - -// APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "table/entities" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md index 40ec34959a79..a6b5ee2a239f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md @@ -14,9 +14,8 @@ package main import ( "context" "fmt" - "time" - - "github.com/Azure/go-autorest/autorest" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" ) @@ -24,13 +23,20 @@ func Example() error { accountName := "storageaccount1" storageAccountKey := "ABC123...." tableName := "mytable" - - storageAuth := autorest.NewSharedKeyLiteTableAuthorizer(accountName, storageAccountKey) - tablesClient := tables.New() - tablesClient.Client.Authorizer = storageAuth + domainSuffix := "core.windows.net" + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKeyTable) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + tablesClient, err := tables.NewWithBaseUri(fmt.Sprintf("https://%s.table.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building client for environment: %+v", err) + } + tablesClient.Client.SetAuthorizer(auth) ctx := context.TODO() - if _, err := tablesClient.Insert(ctx, accountName, tableName); err != nil { + if _, err := tablesClient.Create(ctx, tableName); err != nil { return fmt.Errorf("Error creating Table: %s", err) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go index 0ef00006530f..d927d38f9c90 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go @@ -2,92 +2,72 @@ package tables import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) -type GetACLResult struct { - autorest.Response +type GetACLResponse struct { + HttpResponse *client.Response SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` } // GetACL returns the Access Control List for the specified Table -func (client Client) GetACL(ctx context.Context, accountName, tableName string) (result GetACLResult, err error) { - if accountName == "" { - return result, validation.NewError("tables.Client", "GetACL", "`accountName` cannot be an empty string.") - } +func (c Client) GetACL(ctx context.Context, tableName string) (resp GetACLResponse, err error) { + if tableName == "" { - return result, validation.NewError("tables.Client", "GetACL", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } - req, err := client.GetACLPreparer(ctx, accountName, tableName) - if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "GetACL", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getAclTableOptions{}, + Path: fmt.Sprintf("/%s", tableName), } - resp, err := client.GetACLSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "tables.Client", "GetACL", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.GetACLResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "GetACL", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } - return -} - -// GetACLPreparer prepares the GetACL request. -func (client Client) GetACLPreparer(ctx context.Context, accountName, tableName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), + if resp.HttpResponse != nil { + if resp.HttpResponse.Body != nil { + err = resp.HttpResponse.Unmarshal(&resp) + if err != nil { + return resp, fmt.Errorf("unmarshalling response body: %v", err) + } + } } - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "acl"), - } + return +} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } +type getAclTableOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{tableName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (g getAclTableOptions) ToHeaders() *client.Headers { + return nil } -// GetACLSender sends the GetACL request. The method will close the -// http.Response Body if it receives an error. -func (client Client) GetACLSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (g getAclTableOptions) ToOData() *odata.Query { + return nil } -// GetACLResponder handles the response to the GetACL request. The method always -// closes the http.Response Body. -func (client Client) GetACLResponder(resp *http.Response) (result GetACLResult, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingXML(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (g getAclTableOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "acl") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go index c26bffc834d1..9ff4ad0e0a1e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go @@ -3,12 +3,11 @@ package tables import ( "context" "encoding/xml" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type setAcl struct { @@ -17,82 +16,58 @@ type setAcl struct { XMLName xml.Name `xml:"SignedIdentifiers"` } +type SetACLResponse struct { + HttpResponse *client.Response +} + // SetACL sets the specified Access Control List for the specified Table -func (client Client) SetACL(ctx context.Context, accountName, tableName string, acls []SignedIdentifier) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("tables.Client", "SetACL", "`accountName` cannot be an empty string.") - } +func (c Client) SetACL(ctx context.Context, tableName string, acls []SignedIdentifier) (resp SetACLResponse, err error) { if tableName == "" { - return result, validation.NewError("tables.Client", "SetACL", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodPut, + OptionsObject: setAclTableOptions{}, + Path: fmt.Sprintf("/%s", tableName), } - req, err := client.SetACLPreparer(ctx, accountName, tableName, acls) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "SetACL", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.SetACLSender(req) + err = req.Marshal(setAcl{SignedIdentifiers: acls}) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "tables.Client", "SetACL", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request: %+v", err) } - result, err = client.SetACLResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "SetACL", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// SetACLPreparer prepares the SetACL request. -func (client Client) SetACLPreparer(ctx context.Context, accountName, tableName string, acls []SignedIdentifier) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - } +type setAclTableOptions struct{} - queryParameters := map[string]interface{}{ - "comp": autorest.Encode("query", "acl"), - } - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - } - - input := setAcl{ - SignedIdentifiers: acls, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/xml; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/{tableName}", pathParameters), - autorest.WithQueryParameters(queryParameters), - autorest.WithHeaders(headers), - autorest.WithXML(&input)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (s setAclTableOptions) ToHeaders() *client.Headers { + return nil } -// SetACLSender sends the SetACL request. The method will close the -// http.Response Body if it receives an error. -func (client Client) SetACLSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (s setAclTableOptions) ToOData() *odata.Query { + return nil } -// SetACLResponder handles the response to the SetACL request. The method always -// closes the http.Response Body. -func (client Client) SetACLResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (s setAclTableOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "acl") + return out } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/api.go index d869819ff21e..75c1de621410 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/api.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/api.go @@ -2,16 +2,14 @@ package tables import ( "context" - - "github.com/Azure/go-autorest/autorest" ) type StorageTable interface { - Delete(ctx context.Context, accountName, tableName string) (result autorest.Response, err error) - Exists(ctx context.Context, accountName, tableName string) (result autorest.Response, err error) - GetACL(ctx context.Context, accountName, tableName string) (result GetACLResult, err error) - Create(ctx context.Context, accountName, tableName string) (result autorest.Response, err error) - GetResourceID(accountName, tableName string) string - Query(ctx context.Context, accountName string, metaDataLevel MetaDataLevel) (result GetResult, err error) - SetACL(ctx context.Context, accountName, tableName string, acls []SignedIdentifier) (result autorest.Response, err error) + Delete(ctx context.Context, tableName string) (resp DeleteTableResponse, err error) + Exists(ctx context.Context, tableName string) (resp TableExistsResponse, err error) + GetACL(ctx context.Context, tableName string) (resp GetACLResponse, err error) + Create(ctx context.Context, tableName string) (resp CreateTableResponse, err error) + GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, tableName string) string + Query(ctx context.Context, input QueryInput) (resp GetResponse, err error) + SetACL(ctx context.Context, tableName string, acls []SignedIdentifier) (resp SetACLResponse, err error) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/client.go index 56724b9202c9..49c714dcdd82 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/client.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/client.go @@ -1,25 +1,23 @@ package tables import ( - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" ) // Client is the base client for Table Storage Shares. type Client struct { - autorest.Client - BaseURI string -} - -// New creates an instance of the Client client. -func New() Client { - return NewWithEnvironment(azure.PublicCloud) + Client *storage.Client } -// NewWithEnvironment creates an instance of the Client client. -func NewWithEnvironment(environment azure.Environment) Client { - return Client{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: environment.StorageEndpointSuffix, +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) } + + return &Client{ + Client: baseClient, + }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go index 561f57460daf..feeebe40052f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go @@ -2,89 +2,70 @@ package tables import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) type createTableRequest struct { TableName string `json:"TableName"` } +type CreateTableResponse struct { + HttpResponse *client.Response +} + // Create creates a new table in the storage account. -func (client Client) Create(ctx context.Context, accountName, tableName string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("tables.Client", "Create", "`accountName` cannot be an empty string.") - } +func (c Client) Create(ctx context.Context, tableName string) (resp CreateTableResponse, err error) { if tableName == "" { - return result, validation.NewError("tables.Client", "Create", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } - req, err := client.CreatePreparer(ctx, accountName, tableName) + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodPost, + OptionsObject: createTableOptions{}, + Path: "/Tables", + } + + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "Create", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.CreateSender(req) + err = req.Marshal(&createTableRequest{TableName: tableName}) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "tables.Client", "Create", resp, "Failure sending request") - return + return resp, fmt.Errorf("marshalling request") } - result, err = client.CreateResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "Create", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// CreatePreparer prepares the Create request. -func (client Client) CreatePreparer(ctx context.Context, accountName, tableName string) (*http.Request, error) { - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - // NOTE: we could support returning metadata here, but it doesn't appear to be directly useful - // vs making a request using the Get methods as-necessary? - "Accept": "application/json;odata=nometadata", - "Prefer": "return-no-content", - } - - body := createTableRequest{ - TableName: tableName, - } +type createTableOptions struct{} - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json"), - autorest.AsPost(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPath("/Tables"), - autorest.WithJSON(body), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (c createTableOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json;odata=nometadata") + headers.Append("Prefer", "return-no-content") + return headers } -// CreateSender sends the Create request. The method will close the -// http.Response Body if it receives an error. -func (client Client) CreateSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (c createTableOptions) ToOData() *odata.Query { + return nil } -// CreateResponder handles the response to the Create request. The method always -// closes the http.Response Body. -func (client Client) CreateResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (c createTableOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go index 5b5ec86d9ca9..3a2817f48282 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go @@ -2,78 +2,61 @@ package tables import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type DeleteTableResponse struct { + HttpResponse *client.Response +} + // Delete deletes the specified table and any data it contains. -func (client Client) Delete(ctx context.Context, accountName, tableName string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("tables.Client", "Delete", "`accountName` cannot be an empty string.") - } +func (c Client) Delete(ctx context.Context, tableName string) (resp DeleteTableResponse, err error) { if tableName == "" { - return result, validation.NewError("tables.Client", "Delete", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } - req, err := client.DeletePreparer(ctx, accountName, tableName) - if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "Delete", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodDelete, + OptionsObject: deleteOptions{}, + Path: fmt.Sprintf("/Tables('%s')", tableName), } - resp, err := client.DeleteSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "tables.Client", "Delete", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.DeleteResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "Delete", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// DeletePreparer prepares the Delete request. -func (client Client) DeletePreparer(ctx context.Context, accountName, tableName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - } - - // NOTE: whilst the API documentation says that API Version is Optional - // apparently specifying it causes an "invalid content type" to always be returned - // as such we omit it here :shrug: - - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/Tables('{tableName}')", pathParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +type deleteOptions struct { } -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (d deleteOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json") + return headers } -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusNoContent), - autorest.ByClosing()) - result = autorest.Response{Response: resp} +func (d deleteOptions) ToOData() *odata.Query { + return nil +} - return +func (d deleteOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go index 6abe4f0bbd42..020bc6081058 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go @@ -2,85 +2,60 @@ package tables import ( "context" + "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) +type TableExistsResponse struct { + HttpResponse *client.Response +} + // Exists checks that the specified table exists -func (client Client) Exists(ctx context.Context, accountName, tableName string) (result autorest.Response, err error) { - if accountName == "" { - return result, validation.NewError("tables.Client", "Exists", "`accountName` cannot be an empty string.") - } +func (c Client) Exists(ctx context.Context, tableName string) (resp TableExistsResponse, err error) { if tableName == "" { - return result, validation.NewError("tables.Client", "Exists", "`tableName` cannot be an empty string.") + return resp, fmt.Errorf("`tableName` cannot be an empty string") } - req, err := client.ExistsPreparer(ctx, accountName, tableName) - if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "Exists", nil, "Failure preparing request") - return + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: tableExistsOptions{}, + Path: fmt.Sprintf("/Tables('%s')", tableName), } - resp, err := client.ExistsSender(req) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - result = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "tables.Client", "Exists", resp, "Failure sending request") + err = fmt.Errorf("building request: %+v", err) return } - result, err = client.ExistsResponder(resp) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "Exists", resp, "Failure responding to request") + err = fmt.Errorf("executing request: %+v", err) return } return } -// ExistsPreparer prepares the Exists request. -func (client Client) ExistsPreparer(ctx context.Context, accountName, tableName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "tableName": autorest.Encode("path", tableName), - } +type tableExistsOptions struct{} - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "Accept": "application/json;odata=nometadata", - } - - // NOTE: whilst the API documentation says that API Version is Optional - // apparently specifying it causes an "invalid content type" to always be returned - // as such we omit it here :shrug: - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.AsContentType("application/json"), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPathParameters("/Tables('{tableName}')", pathParameters), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) +func (t tableExistsOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json;odata=nometadata") + return headers } -// ExistsSender sends the Exists request. The method will close the -// http.Response Body if it receives an error. -func (client Client) ExistsSender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (t tableExistsOptions) ToOData() *odata.Query { + return nil } -// ExistsResponder handles the response to the Exists request. The method always -// closes the http.Response Body. -func (client Client) ExistsResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByClosing()) - result = autorest.Response{Response: resp} - - return +func (t tableExistsOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go index 475370f0cbd5..9a15de8d0fa7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go @@ -5,83 +5,76 @@ import ( "fmt" "net/http" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/validation" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" ) -type GetResult struct { - autorest.Response +type GetResponse struct { + HttpResponse *client.Response MetaData string `json:"odata.metadata,omitempty"` Tables []GetResultItem `json:"value"` } +type QueryInput struct { + MetaDataLevel MetaDataLevel +} + // Query returns a list of tables under the specified account. -func (client Client) Query(ctx context.Context, accountName string, metaDataLevel MetaDataLevel) (result GetResult, err error) { - if accountName == "" { - return result, validation.NewError("tables.Client", "Query", "`accountName` cannot be an empty string.") +func (c Client) Query(ctx context.Context, input QueryInput) (resp GetResponse, err error) { + + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: queryOptions{ + metaDataLevel: input.MetaDataLevel, + }, + Path: "/Tables", } - req, err := client.QueryPreparer(ctx, accountName, metaDataLevel) + req, err := c.Client.NewRequest(ctx, opts) if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "Query", nil, "Failure preparing request") + err = fmt.Errorf("building request: %+v", err) return } - resp, err := client.QuerySender(req) + resp.HttpResponse, err = req.Execute(ctx) if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "tables.Client", "Query", resp, "Failure sending request") + err = fmt.Errorf("executing request: %+v", err) return } - result, err = client.QueryResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "tables.Client", "Query", resp, "Failure responding to request") - return + if resp.HttpResponse != nil { + if resp.HttpResponse.Body != nil { + err = resp.HttpResponse.Unmarshal(&resp) + if err != nil { + return resp, fmt.Errorf("unmarshalling response: %v", err) + } + } } return } -// QueryPreparer prepares the Query request. -func (client Client) QueryPreparer(ctx context.Context, accountName string, metaDataLevel MetaDataLevel) (*http.Request, error) { +type queryOptions struct { + metaDataLevel MetaDataLevel +} + +func (q queryOptions) ToHeaders() *client.Headers { // NOTE: whilst this supports ContinuationTokens and 'Top' // it appears that 'Skip' returns a '501 Not Implemented' // as such, we intentionally don't support those right now - - headers := map[string]interface{}{ - "x-ms-version": APIVersion, - "Accept": fmt.Sprintf("application/json;odata=%s", metaDataLevel), - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(endpoints.GetTableEndpoint(client.BaseURI, accountName)), - autorest.WithPath("/Tables"), - autorest.WithHeaders(headers)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) + headers := &client.Headers{} + headers.Append("Accept", fmt.Sprintf("application/json;odata=%s", q.metaDataLevel)) + return headers } -// QuerySender sends the Query request. The method will close the -// http.Response Body if it receives an error. -func (client Client) QuerySender(req *http.Request) (*http.Response, error) { - return autorest.SendWithSender(client, req, - azure.DoRetryWithRegistration(client.Client)) +func (q queryOptions) ToOData() *odata.Query { + return nil } -// QueryResponder handles the response to the Query request. The method always -// closes the http.Response Body. -func (client Client) QueryResponder(resp *http.Response) (result GetResult, err error) { - err = autorest.Respond( - resp, - client.ByInspecting(), - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - - return +func (q queryOptions) ToQuery() *client.QueryParams { + return nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go index 4ceae10150e0..ea04fe35ae31 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go @@ -5,50 +5,97 @@ import ( "net/url" "strings" - "github.com/tombuildsstuff/giovanni/storage/internal/endpoints" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" ) -// GetResourceID returns the Resource ID for the given Table +// GetResourceManagerResourceID returns the Resource ID for the given Table // This can be useful when, for example, you're using this as a unique identifier -func (client Client) GetResourceID(accountName, tableName string) string { - domain := endpoints.GetTableEndpoint(client.BaseURI, accountName) - return fmt.Sprintf("%s/Tables('%s')", domain, tableName) +func (c Client) GetResourceManagerResourceID(subscriptionID, resourceGroup, accountName, tableName string) string { + fmtStr := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/tableServices/default/tables/%s" + return fmt.Sprintf(fmtStr, subscriptionID, resourceGroup, accountName, tableName) } -type ResourceID struct { - AccountName string - TableName string +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = TableId{} + +type TableId struct { + // AccountId specifies the ID of the Storage Account where this Table exists. + AccountId accounts.AccountId + + // TableName specifies the name of this Table. + TableName string +} + +func NewTableID(accountId accounts.AccountId, tableName string) TableId { + return TableId{ + AccountId: accountId, + TableName: tableName, + } +} + +func (b TableId) ID() string { + return fmt.Sprintf("%s/Tables('%s')", b.AccountId.ID(), b.TableName) } -// ParseResourceID parses the Resource ID and returns an object which -// can be used to interact with the Table within the specified Storage Account -func ParseResourceID(id string) (*ResourceID, error) { - // example: https://foo.table.core.windows.net/Table('foo') - if id == "" { - return nil, fmt.Errorf("`id` was empty") +func (b TableId) String() string { + components := []string{ + fmt.Sprintf("Account %q", b.AccountId.String()), } + return fmt.Sprintf("Table %q (%s)", b.TableName, strings.Join(components, " / ")) +} - uri, err := url.Parse(id) +// ParseTableID parses `input` into a Table ID using a known `domainSuffix` +func ParseTableID(input, domainSuffix string) (*TableId, error) { + // example: https://foo.table.core.windows.net/Table('bar') + if input == "" { + return nil, fmt.Errorf("`input` was empty") + } + + account, err := accounts.ParseAccountID(input, domainSuffix) if err != nil { - return nil, fmt.Errorf("Error parsing ID as a URL: %s", err) + return nil, fmt.Errorf("parsing account %q: %+v", input, err) + } + + if account.SubDomainType != accounts.TableSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.TableSubDomainType), string(account.SubDomainType)) } - accountName, err := endpoints.GetAccountNameFromEndpoint(uri.Host) + uri, err := url.Parse(input) if err != nil { - return nil, fmt.Errorf("Error parsing Account Name: %s", err) + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) } - // assume there a `Table('')` path := strings.TrimPrefix(uri.Path, "/") - if !strings.HasPrefix(path, "Tables('") || !strings.HasSuffix(path, "')") { - return nil, fmt.Errorf("Expected the Table Name to be in the format `Tables('name')` but got %q", path) + segments := strings.Split(path, "/") + if len(segments) != 1 { + return nil, fmt.Errorf("expected the path to contain 1 segment but got %d", len(segments)) + } + + // Tables and Table Entities are similar however Tables use a reserved namespace, for example: + // Table('tableName') + // whereas Entities begin with the actual table name, for example: + // tableName(PartitionKey='samplepartition',RowKey='samplerow') + // However, there was a period of time when Table IDs did not use the reserved namespace, so we attempt to parse + // both forms for maximum compatibility. + var tableName string + slug := strings.TrimPrefix(uri.Path, "/") + if strings.HasPrefix(slug, "Tables('") && strings.HasSuffix(slug, "')") { + // Ensure both prefix and suffix are present before trimming them out + tableName = strings.TrimSuffix(strings.TrimPrefix(slug, "Tables('"), "')") + } else if !strings.Contains(slug, "(") && !strings.HasSuffix(slug, ")") { + // Also accept a bare table name + tableName = slug + } else { + return nil, fmt.Errorf("expected the path to a table name and not an entity name but got %q", tableName) + } + if tableName == "" { + return nil, fmt.Errorf("expected the path to a table name but the path was empty") } - // strip off the `Table('')` - tableName := strings.TrimPrefix(uri.Path, "/Tables('") - tableName = strings.TrimSuffix(tableName, "')") - return &ResourceID{ - AccountName: *accountName, - TableName: tableName, + return &TableId{ + AccountId: *account, + TableName: tableName, }, nil } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go index 05a61a8a7c9d..3e0363fc361e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go @@ -1,14 +1,4 @@ package tables -import ( - "fmt" - - "github.com/tombuildsstuff/giovanni/version" -) - -// APIVersion is the version of the API used for all Storage API Operations -const APIVersion = "2020-08-04" - -func UserAgent() string { - return fmt.Sprintf("tombuildsstuff/giovanni/%s storage/%s", version.Number, APIVersion) -} +const apiVersion = "2020-08-04" +const componentName = "table/tables" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/internal/endpoints/endpoints.go b/vendor/github.com/tombuildsstuff/giovanni/storage/internal/endpoints/endpoints.go deleted file mode 100644 index 2c58e8f69b03..000000000000 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/internal/endpoints/endpoints.go +++ /dev/null @@ -1,39 +0,0 @@ -package endpoints - -import ( - "fmt" - "strings" -) - -func GetAccountNameFromEndpoint(endpoint string) (*string, error) { - segments := strings.Split(endpoint, ".") - if len(segments) == 0 { - return nil, fmt.Errorf("The Endpoint contained no segments") - } - return &segments[0], nil -} - -// GetBlobEndpoint returns the endpoint for Blob API Operations on this storage account -func GetBlobEndpoint(baseUri string, accountName string) string { - return fmt.Sprintf("https://%s.blob.%s", accountName, baseUri) -} - -// GetDataLakeStoreEndpoint returns the endpoint for Data Lake Store API Operations on this storage account -func GetDataLakeStoreEndpoint(baseUri string, accountName string) string { - return fmt.Sprintf("https://%s.dfs.%s", accountName, baseUri) -} - -// GetFileEndpoint returns the endpoint for File Share API Operations on this storage account -func GetFileEndpoint(baseUri string, accountName string) string { - return fmt.Sprintf("https://%s.file.%s", accountName, baseUri) -} - -// GetQueueEndpoint returns the endpoint for Queue API Operations on this storage account -func GetQueueEndpoint(baseUri string, accountName string) string { - return fmt.Sprintf("https://%s.queue.%s", accountName, baseUri) -} - -// GetTableEndpoint returns the endpoint for Table API Operations on this storage account -func GetTableEndpoint(baseUri string, accountName string) string { - return fmt.Sprintf("https://%s.table.%s", accountName, baseUri) -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/internal/metadata/parse.go b/vendor/github.com/tombuildsstuff/giovanni/storage/internal/metadata/parse.go index 1880d409a7db..5f613ab7d15b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/internal/metadata/parse.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/internal/metadata/parse.go @@ -5,16 +5,19 @@ import ( "strings" ) -// ParseFromHeaders parses the meta data from the headers +// ParseFromHeaders parses the metadata from the headers func ParseFromHeaders(headers http.Header) map[string]string { metaData := make(map[string]string, 0) + prefix := "x-ms-meta-" for k, v := range headers { key := strings.ToLower(k) - prefix := "x-ms-meta-" if !strings.HasPrefix(key, prefix) { continue } + // TODO: update this to support case-insensitive headers when the base layer is changed to `hashicorp/go-azure-sdk` + // (e.g. trim off the first 10 characters, but this can't be done until the base layer is updated, since + // `Azure/go-autorest` canonicalizes the header keys) key = strings.TrimPrefix(key, prefix) metaData[key] = v[0] } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/internal/metadata/set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/internal/metadata/set.go index d88fbd766b63..6006159f78cf 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/internal/metadata/set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/internal/metadata/set.go @@ -1,6 +1,10 @@ package metadata -import "fmt" +import ( + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client" +) // SetIntoHeaders sets the provided MetaData into the headers func SetIntoHeaders(headers map[string]interface{}, metaData map[string]string) map[string]interface{} { @@ -11,3 +15,13 @@ func SetIntoHeaders(headers map[string]interface{}, metaData map[string]string) return headers } + +// SetMetaDataHeaders sets the provided MetaData into the headers +func SetMetaDataHeaders(metaData map[string]string) client.Headers { + headers := client.Headers{} + for k, v := range metaData { + key := fmt.Sprintf("x-ms-meta-%s", k) + headers.Append(key, v) + } + return headers +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/version/version.go b/vendor/github.com/tombuildsstuff/giovanni/version/version.go deleted file mode 100644 index 45a0da69aa76..000000000000 --- a/vendor/github.com/tombuildsstuff/giovanni/version/version.go +++ /dev/null @@ -1,3 +0,0 @@ -package version - -const Number = "v0.17.0" diff --git a/vendor/modules.txt b/vendor/modules.txt index 44a266596926..3631caec2f32 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -127,7 +127,7 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/uuid v1.3.1 +# github.com/google/uuid v1.4.0 ## explicit github.com/google/uuid # github.com/hashicorp/errwrap v1.1.0 @@ -1062,6 +1062,8 @@ github.com/hashicorp/go-azure-sdk/sdk/auth github.com/hashicorp/go-azure-sdk/sdk/auth/autorest github.com/hashicorp/go-azure-sdk/sdk/claims github.com/hashicorp/go-azure-sdk/sdk/client +github.com/hashicorp/go-azure-sdk/sdk/client/dataplane +github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage github.com/hashicorp/go-azure-sdk/sdk/client/msgraph github.com/hashicorp/go-azure-sdk/sdk/client/pollers github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager @@ -1253,8 +1255,8 @@ github.com/rickb777/plural # github.com/sergi/go-diff v1.2.0 ## explicit; go 1.12 github.com/sergi/go-diff/diffmatchpatch -# github.com/tombuildsstuff/giovanni v0.20.0 -## explicit; go 1.13 +# github.com/tombuildsstuff/giovanni v0.25.1 +## explicit; go 1.21 github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers @@ -1267,9 +1269,7 @@ github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables github.com/tombuildsstuff/giovanni/storage/accesscontrol -github.com/tombuildsstuff/giovanni/storage/internal/endpoints github.com/tombuildsstuff/giovanni/storage/internal/metadata -github.com/tombuildsstuff/giovanni/version # github.com/tombuildsstuff/kermit v0.20240122.1123108 ## explicit; go 1.18 github.com/tombuildsstuff/kermit/sdk/appconfiguration/1.0/appconfiguration From e6e87a1c3842fc22da73cf4e437e104e6a1e838c Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 26 Feb 2024 21:03:47 +0000 Subject: [PATCH 02/12] provider: move helper functions into own source file --- internal/provider/helpers.go | 128 ++++++++++++++++++++++++++++++++++ internal/provider/provider.go | 119 ------------------------------- 2 files changed, 128 insertions(+), 119 deletions(-) create mode 100644 internal/provider/helpers.go diff --git a/internal/provider/helpers.go b/internal/provider/helpers.go new file mode 100644 index 000000000000..eb1ce774a23d --- /dev/null +++ b/internal/provider/helpers.go @@ -0,0 +1,128 @@ +package provider + +import ( + "encoding/base64" + "fmt" + "os" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func decodeCertificate(clientCertificate string) ([]byte, error) { + var pfx []byte + if clientCertificate != "" { + out := make([]byte, base64.StdEncoding.DecodedLen(len(clientCertificate))) + n, err := base64.StdEncoding.Decode(out, []byte(clientCertificate)) + if err != nil { + return pfx, fmt.Errorf("could not decode client certificate data: %v", err) + } + pfx = out[:n] + } + return pfx, nil +} + +func getOidcToken(d *schema.ResourceData) (*string, error) { + idToken := strings.TrimSpace(d.Get("oidc_token").(string)) + + if path := d.Get("oidc_token_file_path").(string); path != "" { + fileTokenRaw, err := os.ReadFile(path) + + if err != nil { + return nil, fmt.Errorf("reading OIDC Token from file %q: %v", path, err) + } + + fileToken := strings.TrimSpace(string(fileTokenRaw)) + + if idToken != "" && idToken != fileToken { + return nil, fmt.Errorf("mismatch between supplied OIDC token and supplied OIDC token file contents - please either remove one or ensure they match") + } + + idToken = fileToken + } + + if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_FEDERATED_TOKEN_FILE") != "" { + path := os.Getenv("AZURE_FEDERATED_TOKEN_FILE") + fileTokenRaw, err := os.ReadFile(os.Getenv("AZURE_FEDERATED_TOKEN_FILE")) + + if err != nil { + return nil, fmt.Errorf("reading OIDC Token from file %q provided by AKS Workload Identity: %v", path, err) + } + + fileToken := strings.TrimSpace(string(fileTokenRaw)) + + if idToken != "" && idToken != fileToken { + return nil, fmt.Errorf("mismatch between supplied OIDC token and OIDC token file contents provided by AKS Workload Identity - please either remove one, ensure they match, or disable use_aks_workload_identity") + } + + idToken = fileToken + } + + return &idToken, nil +} + +func getClientId(d *schema.ResourceData) (*string, error) { + clientId := strings.TrimSpace(d.Get("client_id").(string)) + + if path := d.Get("client_id_file_path").(string); path != "" { + fileClientIdRaw, err := os.ReadFile(path) + + if err != nil { + return nil, fmt.Errorf("reading Client ID from file %q: %v", path, err) + } + + fileClientId := strings.TrimSpace(string(fileClientIdRaw)) + + if clientId != "" && clientId != fileClientId { + return nil, fmt.Errorf("mismatch between supplied Client ID and supplied Client ID file contents - please either remove one or ensure they match") + } + + clientId = fileClientId + } + + if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_CLIENT_ID") != "" { + aksClientId := os.Getenv("AZURE_CLIENT_ID") + if clientId != "" && clientId != aksClientId { + return nil, fmt.Errorf("mismatch between supplied Client ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity") + } + clientId = aksClientId + } + + return &clientId, nil +} + +func getClientSecret(d *schema.ResourceData) (*string, error) { + clientSecret := strings.TrimSpace(d.Get("client_secret").(string)) + + if path := d.Get("client_secret_file_path").(string); path != "" { + fileSecretRaw, err := os.ReadFile(path) + + if err != nil { + return nil, fmt.Errorf("reading Client Secret from file %q: %v", path, err) + } + + fileSecret := strings.TrimSpace(string(fileSecretRaw)) + + if clientSecret != "" && clientSecret != fileSecret { + return nil, fmt.Errorf("mismatch between supplied Client Secret and supplied Client Secret file contents - please either remove one or ensure they match") + } + + clientSecret = fileSecret + } + + return &clientSecret, nil +} + +func getTenantId(d *schema.ResourceData) (*string, error) { + tenantId := strings.TrimSpace(d.Get("tenant_id").(string)) + + if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_TENANT_ID") != "" { + aksTenantId := os.Getenv("AZURE_TENANT_ID") + if tenantId != "" && tenantId != aksTenantId { + return nil, fmt.Errorf("mismatch between supplied Tenant ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity") + } + tenantId = aksTenantId + } + + return &tenantId, nil +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5c2d5fc23fe8..4c6fbac83948 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -5,7 +5,6 @@ package provider import ( "context" - "encoding/base64" "fmt" "log" "os" @@ -510,124 +509,6 @@ func buildClient(ctx context.Context, p *schema.Provider, d *schema.ResourceData return client, nil } -func decodeCertificate(clientCertificate string) ([]byte, error) { - var pfx []byte - if clientCertificate != "" { - out := make([]byte, base64.StdEncoding.DecodedLen(len(clientCertificate))) - n, err := base64.StdEncoding.Decode(out, []byte(clientCertificate)) - if err != nil { - return pfx, fmt.Errorf("could not decode client certificate data: %v", err) - } - pfx = out[:n] - } - return pfx, nil -} - -func getOidcToken(d *schema.ResourceData) (*string, error) { - idToken := strings.TrimSpace(d.Get("oidc_token").(string)) - - if path := d.Get("oidc_token_file_path").(string); path != "" { - fileTokenRaw, err := os.ReadFile(path) - - if err != nil { - return nil, fmt.Errorf("reading OIDC Token from file %q: %v", path, err) - } - - fileToken := strings.TrimSpace(string(fileTokenRaw)) - - if idToken != "" && idToken != fileToken { - return nil, fmt.Errorf("mismatch between supplied OIDC token and supplied OIDC token file contents - please either remove one or ensure they match") - } - - idToken = fileToken - } - - if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_FEDERATED_TOKEN_FILE") != "" { - path := os.Getenv("AZURE_FEDERATED_TOKEN_FILE") - fileTokenRaw, err := os.ReadFile(os.Getenv("AZURE_FEDERATED_TOKEN_FILE")) - - if err != nil { - return nil, fmt.Errorf("reading OIDC Token from file %q provided by AKS Workload Identity: %v", path, err) - } - - fileToken := strings.TrimSpace(string(fileTokenRaw)) - - if idToken != "" && idToken != fileToken { - return nil, fmt.Errorf("mismatch between supplied OIDC token and OIDC token file contents provided by AKS Workload Identity - please either remove one, ensure they match, or disable use_aks_workload_identity") - } - - idToken = fileToken - } - - return &idToken, nil -} - -func getClientId(d *schema.ResourceData) (*string, error) { - clientId := strings.TrimSpace(d.Get("client_id").(string)) - - if path := d.Get("client_id_file_path").(string); path != "" { - fileClientIdRaw, err := os.ReadFile(path) - - if err != nil { - return nil, fmt.Errorf("reading Client ID from file %q: %v", path, err) - } - - fileClientId := strings.TrimSpace(string(fileClientIdRaw)) - - if clientId != "" && clientId != fileClientId { - return nil, fmt.Errorf("mismatch between supplied Client ID and supplied Client ID file contents - please either remove one or ensure they match") - } - - clientId = fileClientId - } - - if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_CLIENT_ID") != "" { - aksClientId := os.Getenv("AZURE_CLIENT_ID") - if clientId != "" && clientId != aksClientId { - return nil, fmt.Errorf("mismatch between supplied Client ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity") - } - clientId = aksClientId - } - - return &clientId, nil -} - -func getClientSecret(d *schema.ResourceData) (*string, error) { - clientSecret := strings.TrimSpace(d.Get("client_secret").(string)) - - if path := d.Get("client_secret_file_path").(string); path != "" { - fileSecretRaw, err := os.ReadFile(path) - - if err != nil { - return nil, fmt.Errorf("reading Client Secret from file %q: %v", path, err) - } - - fileSecret := strings.TrimSpace(string(fileSecretRaw)) - - if clientSecret != "" && clientSecret != fileSecret { - return nil, fmt.Errorf("mismatch between supplied Client Secret and supplied Client Secret file contents - please either remove one or ensure they match") - } - - clientSecret = fileSecret - } - - return &clientSecret, nil -} - -func getTenantId(d *schema.ResourceData) (*string, error) { - tenantId := strings.TrimSpace(d.Get("tenant_id").(string)) - - if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_TENANT_ID") != "" { - aksTenantId := os.Getenv("AZURE_TENANT_ID") - if tenantId != "" && tenantId != aksTenantId { - return nil, fmt.Errorf("mismatch between supplied Tenant ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity") - } - tenantId = aksTenantId - } - - return &tenantId, nil -} - const resourceProviderRegistrationErrorFmt = `Error ensuring Resource Providers are registered. Terraform automatically attempts to register the Resource Providers it supports to From f61cfe58f190c43d5653cdfc84d2f54e06e24774 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 26 Feb 2024 21:04:57 +0000 Subject: [PATCH 03/12] common: adopt client.BaseClient interface from go-azure-sdk --- internal/common/client_options.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/internal/common/client_options.go b/internal/common/client_options.go index 6eba6eeaedcc..1b5c831b5d3b 100644 --- a/internal/common/client_options.go +++ b/internal/common/client_options.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/go-azure-helpers/sender" "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/hashicorp/go-azure-sdk/sdk/client" - "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" "github.com/hashicorp/go-azure-sdk/sdk/environments" "github.com/hashicorp/terraform-plugin-sdk/v2/meta" "github.com/hashicorp/terraform-provider-azurerm/internal/features" @@ -66,24 +65,20 @@ type ClientOptions struct { } // Configure set up a resourcemanager.Client using an auth.Authorizer from hashicorp/go-azure-sdk -func (o ClientOptions) Configure(c *resourcemanager.Client, authorizer auth.Authorizer) { - c.Authorizer = authorizer - c.UserAgent = userAgent(c.UserAgent, o.TerraformVersion, o.PartnerId, o.DisableTerraformPartnerID) +func (o ClientOptions) Configure(c client.BaseClient, authorizer auth.Authorizer) { + c.SetAuthorizer(authorizer) + c.SetUserAgent(userAgent(c.GetUserAgent(), o.TerraformVersion, o.PartnerId, o.DisableTerraformPartnerID)) - requestMiddlewares := make([]client.RequestMiddleware, 0) if !o.DisableCorrelationRequestID { id := o.CustomCorrelationRequestID if id == "" { id = correlationRequestID() } - requestMiddlewares = append(requestMiddlewares, correlationRequestIDMiddleware(id)) + c.AppendRequestMiddleware(correlationRequestIDMiddleware(id)) } - requestMiddlewares = append(requestMiddlewares, requestLoggerMiddleware("AzureRM")) - c.RequestMiddlewares = &requestMiddlewares - c.ResponseMiddlewares = &[]client.ResponseMiddleware{ - responseLoggerMiddleware("AzureRM"), - } + c.AppendRequestMiddleware(requestLoggerMiddleware("AzureRM")) + c.AppendResponseMiddleware(responseLoggerMiddleware("AzureRM")) } // ConfigureClient sets up an autorest.Client using an autorest.Authorizer From 1fb9340b772b96988469a80e4ea71015365dc1c0 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 26 Feb 2024 21:07:02 +0000 Subject: [PATCH 04/12] Storage Data Plane upgrades - Use latest tombuildsstuff/giovanni which has switched to the go-azure-sdk base layer - Support for sdk-level retries for known eventually consistent scenarios - Support for AAD authentication for all data plane APIs (where the API supports it) - Refactor data plane client helpers to be operation-aware, so that supported authentication methods can be determined not just by endpoint but also by the operation (enables more granular support for preferred authentication methods). - Adopt data plane resource IDs from tombuildsstuff/giovanni - Some tidying of `services/storage/client` package - move data plane client helpers into own source file - `azurerm_storage_share_directory`: deprecate `share_name` and `storage_account_name` in favor of `storage_share_id` - `azurerm_storage_table_entity`: deprecate `share_name` and `storage_account_name` in favor of `storage_table_id` --- ..._kubernetes_flux_configuration_resource.go | 23 +- .../kubernetes_flux_configuration_resource.go | 23 +- .../legacy/virtual_machine_resource.go | 16 +- .../legacy/virtual_machine_resource_test.go | 9 +- internal/services/storage/blobs.go | 19 +- internal/services/storage/client/client.go | 233 +------------ .../services/storage/client/data_plane.go | 308 ++++++++++++++++++ internal/services/storage/client/helpers.go | 57 +++- internal/services/storage/helpers/schema.go | 38 +++ internal/services/storage/migration/share.go | 18 +- .../services/storage/migration/share_test.go | 22 +- .../parse/storage_container_data_plane.go | 67 ---- .../storage/parse/storage_queue_data_plane.go | 67 ---- .../storage/parse/storage_share_data_plane.go | 68 ---- .../storage/parse/storage_table_data_plane.go | 68 ---- .../storage/parse/storage_table_entities.go | 5 +- internal/services/storage/shim/containers.go | 14 +- .../storage/shim/containers_data_plane.go | 91 ++---- internal/services/storage/shim/queues.go | 16 +- .../storage/shim/queues_data_plane.go | 53 +-- internal/services/storage/shim/shares.go | 18 +- .../storage/shim/shares_data_plane.go | 103 ++---- internal/services/storage/shim/tables.go | 12 +- .../storage/shim/tables_data_plane.go | 33 +- .../storage/storage_account_resource.go | 58 ++-- .../storage/storage_blob_data_source.go | 34 +- .../services/storage/storage_blob_resource.go | 146 +++++---- .../storage/storage_blob_resource_test.go | 48 ++- .../storage/storage_container_data_source.go | 39 ++- .../storage/storage_container_resource.go | 135 +++++--- .../storage_container_resource_test.go | 49 +-- .../storage/storage_containers_data_source.go | 34 +- ...rage_data_lake_gen2_filesystem_resource.go | 236 ++++++++------ ...data_lake_gen2_filesystem_resource_test.go | 47 ++- .../storage_data_lake_gen2_path_resource.go | 199 +++++++---- ...orage_data_lake_gen2_path_resource_test.go | 26 +- .../storage/storage_queue_resource.go | 99 +++--- .../storage/storage_queue_resource_test.go | 16 +- .../storage/storage_share_data_source.go | 41 ++- .../storage_share_directory_resource.go | 212 ++++++++---- .../storage_share_directory_resource_test.go | 119 +++++-- .../storage/storage_share_file_resource.go | 144 ++++---- .../storage_share_file_resource_test.go | 17 +- .../storage/storage_share_resource.go | 136 ++++---- .../storage/storage_share_resource_test.go | 37 ++- .../storage_table_entities_data_source.go | 26 +- .../storage_table_entity_data_source.go | 36 +- .../storage/storage_table_entity_resource.go | 240 ++++++++++---- .../storage_table_entity_resource_test.go | 199 +++++++---- .../storage/storage_table_resource.go | 113 ++++--- .../storage/storage_table_resource_test.go | 34 +- ...blob_properties_default_service_version.go | 2 +- .../storage/validate/storage_container.go | 16 - .../storage/validate/storage_share_name.go | 17 - .../blob/blobs/snapshot_get_properties.go | 160 --------- .../2020-08-04/blob/containers/create.go | 88 ----- .../2020-08-04/file/files/properties_get.go | 105 ------ .../blob/accounts/README.md | 4 +- .../blob/accounts/client.go | 0 .../blob/accounts/get_service_properties.go | 29 +- .../blob/accounts/models.go | 0 .../blob/accounts/resource_id.go | 0 .../accounts/service_properties_shared.go | 0 .../blob/accounts/set_service_properties.go | 15 +- .../blob/accounts/version.go | 2 +- .../blob/blobs/README.md | 6 +- .../blob/blobs/api.go | 0 .../blob/blobs/append_block.go | 63 ++-- .../blob/blobs/client.go | 0 .../blob/blobs/copy.go | 38 ++- .../blob/blobs/copy_abort.go | 23 +- .../blob/blobs/copy_and_wait.go | 0 .../blob/blobs/copy_and_wait_poller.go | 0 .../blob/blobs/delete.go | 17 +- .../blob/blobs/delete_snapshot.go | 23 +- .../blob/blobs/delete_snapshots.go | 20 +- .../blob/blobs/get.go | 37 ++- .../blob/blobs/get_block_list.go | 43 +-- .../blob/blobs/get_page_ranges.go | 46 +-- .../blob/blobs/incremental_copy_blob.go | 23 +- .../blob/blobs/lease_acquire.go | 39 ++- .../blob/blobs/lease_break.go | 23 +- .../blob/blobs/lease_change.go | 36 +- .../blob/blobs/lease_release.go | 23 +- .../blob/blobs/lease_renew.go | 23 +- .../blob/blobs/metadata_set.go | 25 +- .../blob/blobs/models.go | 0 .../blob/blobs/properties_get.go | 114 ++++--- .../blob/blobs/properties_set.go | 17 +- .../blob/blobs/put_append_blob.go | 29 +- .../blob/blobs/put_block.go | 49 +-- .../blob/blobs/put_block_blob.go | 41 ++- .../blob/blobs/put_block_blob_file.go | 6 +- .../blob/blobs/put_block_list.go | 43 ++- .../blob/blobs/put_block_url.go | 46 ++- .../blob/blobs/put_page_blob.go | 28 +- .../blob/blobs/put_page_clear.go | 33 +- .../blob/blobs/put_page_update.go | 47 ++- .../blob/blobs/resource_id.go | 2 +- .../blob/blobs/set_tier.go | 20 +- .../blob/blobs/snapshot.go | 42 ++- .../blob/blobs/snapshot_get_properties.go | 168 ++++++++++ .../blob/blobs/undelete.go | 20 +- .../blob/blobs/version.go | 2 +- .../blob/containers/README.md | 4 +- .../blob/containers/api.go | 0 .../blob/containers/client.go | 0 .../2023-11-03/blob/containers/create.go | 135 ++++++++ .../blob/containers/delete.go | 15 +- .../blob/containers/get_properties.go | 65 ++-- .../blob/containers/lease_acquire.go | 28 +- .../blob/containers/lease_break.go | 40 +-- .../blob/containers/lease_change.go | 33 +- .../blob/containers/lease_release.go | 18 +- .../blob/containers/lease_renew.go | 18 +- .../blob/containers/list_blobs.go | 34 +- .../blob/containers/models.go | 23 +- .../blob/containers/options.go | 0 .../blob/containers/resource_id.go | 2 +- .../blob/containers/set_acl.go | 15 +- .../blob/containers/set_metadata.go | 20 +- .../blob/containers/version.go | 2 +- .../datalakestore/filesystems/README.md | 5 +- .../datalakestore/filesystems/client.go | 0 .../datalakestore/filesystems/create.go | 16 +- .../datalakestore/filesystems/delete.go | 16 +- .../datalakestore/filesystems/helpers.go | 2 +- .../datalakestore/filesystems/options.go | 0 .../filesystems/properties_get.go | 39 ++- .../filesystems/properties_set.go | 16 +- .../datalakestore/filesystems/resource_id.go | 2 +- .../datalakestore/filesystems/version.go | 2 +- .../datalakestore/paths/client.go | 0 .../datalakestore/paths/create.go | 17 +- .../datalakestore/paths/delete.go | 13 +- .../datalakestore/paths/helpers.go | 2 +- .../datalakestore/paths/properties_get.go | 54 +-- .../datalakestore/paths/properties_set.go | 18 +- .../datalakestore/paths/resource_id.go | 2 +- .../datalakestore/paths/version.go | 2 +- .../file/directories/README.md | 4 +- .../file/directories/api.go | 0 .../file/directories/client.go | 0 .../file/directories/create.go | 22 +- .../file/directories/delete.go | 19 +- .../file/directories/get.go | 31 +- .../file/directories/metadata_get.go | 29 +- .../file/directories/metadata_set.go | 24 +- .../file/directories/options.go | 0 .../file/directories/resource_id.go | 2 +- .../file/directories/version.go | 2 +- .../file/files/README.md | 4 +- .../file/files/api.go | 0 .../file/files/client.go | 0 .../file/files/copy.go | 38 ++- .../file/files/copy_abort.go | 22 +- .../file/files/copy_and_wait_poller.go | 0 .../file/files/copy_wait.go | 14 +- .../file/files/create.go | 22 +- .../file/files/delete.go | 19 +- .../file/files/metadata_get.go | 29 +- .../file/files/metadata_set.go | 22 +- .../2023-11-03/file/files/properties_get.go | 112 +++++++ .../file/files/properties_set.go | 19 +- .../file/files/range_clear.go | 25 +- .../file/files/range_get.go | 50 +-- .../file/files/range_get_file.go | 20 +- .../file/files/range_put.go | 32 +- .../file/files/range_put_file.go | 7 +- .../file/files/ranges_list.go | 33 +- .../file/files/resource_id.go | 2 +- .../file/files/version.go | 2 +- .../file/shares/README.md | 4 +- .../file/shares/acl_get.go | 29 +- .../file/shares/acl_set.go | 24 +- .../file/shares/api.go | 0 .../file/shares/client.go | 0 .../file/shares/create.go | 55 +++- .../file/shares/delete.go | 16 +- .../file/shares/metadata_get.go | 24 +- .../file/shares/metadata_set.go | 21 +- .../file/shares/models.go | 8 + .../file/shares/options.go | 0 .../file/shares/properties_get.go | 43 +-- .../file/shares/properties_set.go | 16 +- .../file/shares/resource_id.go | 2 +- .../file/shares/snapshot_create.go | 28 +- .../file/shares/snapshot_delete.go | 16 +- .../file/shares/snapshot_get.go | 29 +- .../file/shares/stats.go | 28 +- .../file/shares/version.go | 2 +- .../queue/queues/README.md | 4 +- .../queue/queues/api.go | 0 .../queue/queues/client.go | 0 .../queue/queues/create.go | 16 +- .../queue/queues/delete.go | 14 +- .../queue/queues/metadata_get.go | 24 +- .../queue/queues/metadata_set.go | 16 +- .../queue/queues/models.go | 0 .../queue/queues/properties_get.go | 23 +- .../queue/queues/properties_set.go | 12 +- .../queue/queues/resource_id.go | 2 +- .../queue/queues/version.go | 2 +- .../table/entities/README.md | 4 +- .../table/entities/api.go | 0 .../table/entities/client.go | 0 .../table/entities/delete.go | 16 +- .../table/entities/get.go | 30 +- .../table/entities/insert.go | 18 +- .../table/entities/insert_or_merge.go | 18 +- .../table/entities/insert_or_replace.go | 18 +- .../table/entities/models.go | 0 .../table/entities/query.go | 27 +- .../table/entities/resource_id.go | 2 +- .../table/entities/version.go | 2 +- .../table/tables/README.md | 4 +- .../table/tables/acl_get.go | 28 +- .../table/tables/acl_set.go | 16 +- .../table/tables/api.go | 0 .../table/tables/client.go | 0 .../table/tables/create.go | 15 +- .../table/tables/delete.go | 13 +- .../table/tables/exists.go | 13 +- .../table/tables/models.go | 0 .../table/tables/query.go | 25 +- .../table/tables/resource_id.go | 2 +- .../table/tables/version.go | 2 +- vendor/modules.txt | 22 +- website/docs/d/storage_share.html.markdown | 2 + .../docs/r/storage_container.html.markdown | 2 + website/docs/r/storage_share.html.markdown | 4 +- .../r/storage_share_directory.html.markdown | 9 +- .../docs/r/storage_table_entity.html.markdown | 11 +- 233 files changed, 4370 insertions(+), 3208 deletions(-) create mode 100644 internal/services/storage/client/data_plane.go create mode 100644 internal/services/storage/helpers/schema.go delete mode 100644 internal/services/storage/parse/storage_container_data_plane.go delete mode 100644 internal/services/storage/parse/storage_queue_data_plane.go delete mode 100644 internal/services/storage/parse/storage_share_data_plane.go delete mode 100644 internal/services/storage/parse/storage_table_data_plane.go delete mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go delete mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go delete mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/accounts/README.md (90%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/accounts/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/accounts/get_service_properties.go (63%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/accounts/models.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/accounts/resource_id.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/accounts/service_properties_shared.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/accounts/set_service_properties.go (71%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/accounts/version.go (63%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/README.md (87%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/api.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/append_block.go (74%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/copy.go (90%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/copy_abort.go (77%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/copy_and_wait.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/copy_and_wait_poller.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/delete.go (79%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/delete_snapshot.go (76%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/delete_snapshots.go (77%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/get.go (67%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/get_block_list.go (70%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/get_page_ranges.go (66%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/incremental_copy_blob.go (80%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/lease_acquire.go (74%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/lease_break.go (81%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/lease_change.go (70%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/lease_release.go (73%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/lease_renew.go (72%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/metadata_set.go (75%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/models.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/properties_get.go (72%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/properties_set.go (86%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_append_blob.go (77%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_block.go (63%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_block_blob.go (73%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_block_blob_file.go (79%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_block_list.go (78%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_block_url.go (67%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_page_blob.go (83%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_page_clear.go (68%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/put_page_update.go (72%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/resource_id.go (97%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/set_tier.go (75%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/snapshot.go (79%) create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot_get_properties.go rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/undelete.go (74%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/blobs/version.go (79%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/README.md (91%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/api.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/client.go (100%) create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/create.go rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/delete.go (76%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/get_properties.go (52%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/lease_acquire.go (80%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/lease_break.go (80%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/lease_change.go (76%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/lease_release.go (79%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/lease_renew.go (79%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/list_blobs.go (90%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/models.go (74%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/options.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/resource_id.go (97%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/set_acl.go (87%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/set_metadata.go (81%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/blob/containers/version.go (65%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/README.md (90%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/create.go (85%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/delete.go (75%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/helpers.go (90%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/options.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/properties_get.go (67%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/properties_set.go (89%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/resource_id.go (97%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/filesystems/version.go (68%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/paths/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/paths/create.go (79%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/paths/delete.go (74%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/paths/helpers.go (77%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/paths/properties_get.go (64%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/paths/properties_set.go (85%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/paths/resource_id.go (97%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/datalakestore/paths/version.go (64%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/README.md (92%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/api.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/create.go (84%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/delete.go (70%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/get.go (69%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/metadata_get.go (73%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/metadata_set.go (74%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/options.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/resource_id.go (97%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/directories/version.go (81%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/README.md (91%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/api.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/copy.go (77%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/copy_abort.go (75%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/copy_and_wait_poller.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/copy_wait.go (59%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/create.go (88%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/delete.go (69%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/metadata_get.go (73%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/metadata_set.go (76%) create mode 100644 vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_get.go rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/properties_set.go (92%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/range_clear.go (73%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/range_get.go (65%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/range_get_file.go (89%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/range_put.go (71%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/range_put_file.go (93%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/ranges_list.go (70%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/resource_id.go (97%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/files/version.go (60%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/README.md (90%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/acl_get.go (75%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/acl_set.go (78%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/api.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/create.go (62%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/delete.go (80%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/metadata_get.go (76%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/metadata_set.go (75%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/models.go (78%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/options.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/properties_get.go (59%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/properties_set.go (78%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/resource_id.go (97%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/snapshot_create.go (79%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/snapshot_delete.go (75%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/snapshot_get.go (74%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/stats.go (76%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/file/shares/version.go (61%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/README.md (90%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/api.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/create.go (78%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/delete.go (72%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/metadata_get.go (69%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/metadata_set.go (78%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/models.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/properties_get.go (77%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/properties_set.go (84%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/resource_id.go (97%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/queue/queues/version.go (80%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/README.md (91%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/api.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/delete.go (81%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/get.go (74%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/insert.go (83%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/insert_or_merge.go (83%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/insert_or_replace.go (83%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/models.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/query.go (87%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/resource_id.go (98%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/entities/version.go (64%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/README.md (89%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/acl_get.go (75%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/acl_set.go (80%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/api.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/client.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/create.go (81%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/delete.go (81%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/exists.go (81%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/models.go (100%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/query.go (82%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/resource_id.go (98%) rename vendor/github.com/tombuildsstuff/giovanni/storage/{2020-08-04 => 2023-11-03}/table/tables/version.go (62%) diff --git a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go index ccdac918aa82..583300f6451e 100644 --- a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go +++ b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go @@ -16,11 +16,10 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/kubernetesconfiguration/2022-11-01/fluxconfiguration" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/services/containers/validate" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" - storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) const ( @@ -239,7 +238,7 @@ func (r ArcKubernetesFluxConfigurationResource) Arguments() map[string]*pluginsd "container_id": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: storageValidate.StorageContainerDataPlaneID, + ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL }, "account_key": { @@ -570,7 +569,7 @@ func (r ArcKubernetesFluxConfigurationResource) Create() sdk.ResourceFunc { properties.Properties.Bucket, properties.Properties.ConfigurationProtectedSettings = expandBucketDefinitionModel(model.Bucket) } else if _, exists = metadata.ResourceData.GetOk("blob_storage"); exists { properties.Properties.SourceKind = pointer.To(fluxconfiguration.SourceKindTypeAzureBlob) - azureBlob, err := expandArcAzureBlobDefinitionModel(model.BlobStorage) + azureBlob, err := expandArcAzureBlobDefinitionModel(model.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("expanding `blob_storage`: %+v", err) } @@ -624,7 +623,7 @@ func (r ArcKubernetesFluxConfigurationResource) Update() sdk.ResourceFunc { properties.Properties.ConfigurationProtectedSettings = nil if metadata.ResourceData.HasChange("blob_storage") { - azureBlob, err := expandArcAzureBlobDefinitionModel(model.BlobStorage) + azureBlob, err := expandArcAzureBlobDefinitionModel(model.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("expanding `blob_storage`: %+v", err) } @@ -717,7 +716,7 @@ func (r ArcKubernetesFluxConfigurationResource) Read() sdk.ResourceFunc { if model := resp.Model; model != nil { if properties := model.Properties; properties != nil { - blobStorage, err := flattenArcAzureBlobDefinitionModel(properties.AzureBlob, configModel.BlobStorage) + blobStorage, err := flattenArcAzureBlobDefinitionModel(properties.AzureBlob, configModel.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("flattening `blob_storage`: %+v", err) } @@ -762,7 +761,7 @@ func (r ArcKubernetesFluxConfigurationResource) Delete() sdk.ResourceFunc { } } -func expandArcAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel) (*fluxconfiguration.AzureBlobDefinition, error) { +func expandArcAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel, storageDomainSuffix string) (*fluxconfiguration.AzureBlobDefinition, error) { if len(inputList) == 0 { return nil, nil } @@ -778,13 +777,13 @@ func expandArcAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel) (*f } if input.ContainerID != "" { - id, err := parse.StorageContainerDataPlaneID(input.ContainerID) + id, err := containers.ParseContainerID(input.ContainerID, storageDomainSuffix) if err != nil { return nil, err } - output.ContainerName = &id.Name - output.Url = pointer.To(strings.TrimSuffix(input.ContainerID, "/"+id.Name)) + output.ContainerName = &id.ContainerName + output.Url = pointer.To(strings.TrimSuffix(input.ContainerID, "/"+id.ContainerName)) } if input.LocalAuthRef != "" { @@ -969,13 +968,13 @@ func expandRepositoryRefDefinitionModel(referenceType string, referenceValue str return &output, nil } -func flattenArcAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinition, azureBlob []AzureBlobDefinitionModel) ([]AzureBlobDefinitionModel, error) { +func flattenArcAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinition, azureBlob []AzureBlobDefinitionModel, storageDomainSuffix string) ([]AzureBlobDefinitionModel, error) { outputList := make([]AzureBlobDefinitionModel, 0) if input == nil { return outputList, nil } - id, err := parse.StorageContainerDataPlaneID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName))) + id, err := containers.ParseContainerID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName)), storageDomainSuffix) if err != nil { return nil, err } diff --git a/internal/services/containers/kubernetes_flux_configuration_resource.go b/internal/services/containers/kubernetes_flux_configuration_resource.go index d5b25970cdf8..0ad2d980479e 100644 --- a/internal/services/containers/kubernetes_flux_configuration_resource.go +++ b/internal/services/containers/kubernetes_flux_configuration_resource.go @@ -16,11 +16,10 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/kubernetesconfiguration/2022-11-01/fluxconfiguration" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/services/containers/validate" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" - storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) const ( @@ -244,7 +243,7 @@ func (r KubernetesFluxConfigurationResource) Arguments() map[string]*pluginsdk.S "container_id": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: storageValidate.StorageContainerDataPlaneID, + ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL }, "account_key": { @@ -589,7 +588,7 @@ func (r KubernetesFluxConfigurationResource) Create() sdk.ResourceFunc { properties.Properties.Bucket, properties.Properties.ConfigurationProtectedSettings = expandBucketDefinitionModel(model.Bucket) } else if _, exists = metadata.ResourceData.GetOk("blob_storage"); exists { properties.Properties.SourceKind = pointer.To(fluxconfiguration.SourceKindTypeAzureBlob) - azureBlob, err := expandAzureBlobDefinitionModel(model.BlobStorage) + azureBlob, err := expandAzureBlobDefinitionModel(model.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("expanding `blob_storage`: %+v", err) } @@ -643,7 +642,7 @@ func (r KubernetesFluxConfigurationResource) Update() sdk.ResourceFunc { properties.Properties.ConfigurationProtectedSettings = nil if metadata.ResourceData.HasChange("blob_storage") { - azureBlob, err := expandAzureBlobDefinitionModel(model.BlobStorage) + azureBlob, err := expandAzureBlobDefinitionModel(model.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("expanding `blob_storage`: %+v", err) } @@ -735,7 +734,7 @@ func (r KubernetesFluxConfigurationResource) Read() sdk.ResourceFunc { if model := resp.Model; model != nil { if properties := model.Properties; properties != nil { - blobStorage, err := flattenAzureBlobDefinitionModel(properties.AzureBlob, configModel.BlobStorage) + blobStorage, err := flattenAzureBlobDefinitionModel(properties.AzureBlob, configModel.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("flattening `blob_storage`: %+v", err) } @@ -780,7 +779,7 @@ func (r KubernetesFluxConfigurationResource) Delete() sdk.ResourceFunc { } } -func expandAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel) (*fluxconfiguration.AzureBlobDefinition, error) { +func expandAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel, storageDomainSuffix string) (*fluxconfiguration.AzureBlobDefinition, error) { if len(inputList) == 0 { return nil, nil } @@ -797,13 +796,13 @@ func expandAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel) (*flux } if input.ContainerID != "" { - id, err := parse.StorageContainerDataPlaneID(input.ContainerID) + id, err := containers.ParseContainerID(input.ContainerID, storageDomainSuffix) if err != nil { return nil, err } - output.ContainerName = &id.Name - output.Url = pointer.To(strings.TrimSuffix(input.ContainerID, "/"+id.Name)) + output.ContainerName = &id.ContainerName + output.Url = pointer.To(strings.TrimSuffix(input.ContainerID, "/"+id.ContainerName)) } if input.LocalAuthRef != "" { @@ -1002,13 +1001,13 @@ func expandRepositoryRefDefinitionModel(referenceType string, referenceValue str return &output, nil } -func flattenAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinition, azureBlob []AzureBlobDefinitionModel) ([]AzureBlobDefinitionModel, error) { +func flattenAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinition, azureBlob []AzureBlobDefinitionModel, storageDomainSuffix string) ([]AzureBlobDefinitionModel, error) { outputList := make([]AzureBlobDefinitionModel, 0) if input == nil { return outputList, nil } - id, err := parse.StorageContainerDataPlaneID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName))) + id, err := containers.ParseContainerID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName)), storageDomainSuffix) if err != nil { return nil, err } diff --git a/internal/services/legacy/virtual_machine_resource.go b/internal/services/legacy/virtual_machine_resource.go index e1d7d72e3e37..a1fb4be0c752 100644 --- a/internal/services/legacy/virtual_machine_resource.go +++ b/internal/services/legacy/virtual_machine_resource.go @@ -30,7 +30,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" "github.com/tombuildsstuff/kermit/sdk/compute/2023-03-01/compute" "github.com/tombuildsstuff/kermit/sdk/network/2022-07-01/network" ) @@ -1033,24 +1033,24 @@ func resourceVirtualMachineDeleteVhd(ctx context.Context, storageClient *intStor } uri := *vhd.URI - id, err := blobs.ParseResourceID(uri) + id, err := blobs.ParseBlobID(uri, storageClient.StorageDomainSuffix) if err != nil { return fmt.Errorf("parsing %q: %s", uri, err) } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountName, id.BlobName, id.ContainerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q (Disk %q)!", id.AccountName, uri) + return fmt.Errorf("Unable to locate Storage Account %q (Disk %q)!", id.AccountId.AccountName, uri) } if err != nil { return fmt.Errorf("building Blobs Client: %s", err) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Blobs Client: %s", err) } @@ -1058,8 +1058,8 @@ func resourceVirtualMachineDeleteVhd(ctx context.Context, storageClient *intStor input := blobs.DeleteInput{ DeleteSnapshots: false, } - if _, err := blobsClient.Delete(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return fmt.Errorf("deleting Blob %q (Container %q / Account %q / Resource Group %q): %s", id.BlobName, id.ContainerName, id.AccountName, account.ResourceGroup, err) + if _, err := blobsClient.Delete(ctx, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("deleting Blob %q (Container %q / Account %q / Resource Group %q): %s", id.BlobName, id.ContainerName, id.AccountId.AccountName, account.ResourceGroup, err) } return nil diff --git a/internal/services/legacy/virtual_machine_resource_test.go b/internal/services/legacy/virtual_machine_resource_test.go index 656633a55ee0..edf31b377ed5 100644 --- a/internal/services/legacy/virtual_machine_resource_test.go +++ b/internal/services/legacy/virtual_machine_resource_test.go @@ -8,13 +8,14 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) type VirtualMachineResource struct{} @@ -249,15 +250,15 @@ func (VirtualMachineResource) unmanagedDiskExistsInContainer(blobName string, sh return fmt.Errorf("Unable to locate Storage Account %q!", accountName) } - client, err := clients.Storage.BlobsClient(ctx, *account) + client, err := clients.Storage.BlobsDataPlaneClient(ctx, *account, clients.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Blobs Client: %s", err) } input := blobs.GetPropertiesInput{} - props, err := client.GetProperties(ctx, accountName, containerName, blobName, input) + props, err := client.GetProperties(ctx, containerName, blobName, input) if err != nil { - if utils.ResponseWasNotFound(props.Response) { + if response.WasNotFound(props.HttpResponse) { if !shouldExist { return nil } diff --git a/internal/services/storage/blobs.go b/internal/services/storage/blobs.go index 116c69ad9445..70e59082642b 100644 --- a/internal/services/storage/blobs.go +++ b/internal/services/storage/blobs.go @@ -14,14 +14,11 @@ import ( "runtime" "strings" "sync" - "time" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) -const pollingInterval = time.Second * 15 - type BlobUpload struct { Client *blobs.Client @@ -96,7 +93,7 @@ func (sbu BlobUpload) copy(ctx context.Context) error { CopySource: sbu.SourceUri, MetaData: sbu.MetaData, } - if err := sbu.Client.CopyAndWait(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input, pollingInterval); err != nil { + if err := sbu.Client.CopyAndWait(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("copy/waiting: %s", err) } @@ -108,7 +105,7 @@ func (sbu BlobUpload) createEmptyAppendBlob(ctx context.Context) error { ContentType: utils.String(sbu.ContentType), MetaData: sbu.MetaData, } - if _, err := sbu.Client.PutAppendBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutAppendBlob(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("PutAppendBlob: %s", err) } @@ -124,7 +121,7 @@ func (sbu BlobUpload) createEmptyBlockBlob(ctx context.Context) error { ContentType: utils.String(sbu.ContentType), MetaData: sbu.MetaData, } - if _, err := sbu.Client.PutBlockBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutBlockBlob(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("PutBlockBlob: %s", err) } @@ -161,7 +158,7 @@ func (sbu BlobUpload) uploadBlockBlob(ctx context.Context) error { if sbu.ContentMD5 != "" { input.ContentMD5 = utils.String(sbu.ContentMD5) } - if err := sbu.Client.PutBlockBlobFromFile(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, file, input); err != nil { + if err := sbu.Client.PutBlockBlobFromFile(ctx, sbu.ContainerName, sbu.BlobName, file, input); err != nil { return fmt.Errorf("PutBlockBlobFromFile: %s", err) } @@ -178,7 +175,7 @@ func (sbu BlobUpload) createEmptyPageBlob(ctx context.Context) error { ContentType: utils.String(sbu.ContentType), MetaData: sbu.MetaData, } - if _, err := sbu.Client.PutPageBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutPageBlob(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("PutPageBlob: %s", err) } @@ -228,7 +225,7 @@ func (sbu BlobUpload) uploadPageBlob(ctx context.Context) error { ContentType: utils.String(sbu.ContentType), MetaData: sbu.MetaData, } - if _, err := sbu.Client.PutPageBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutPageBlob(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("PutPageBlob: %s", err) } @@ -373,7 +370,7 @@ func (sbu BlobUpload) blobPageUploadWorker(ctx context.Context, uploadCtx blobPa Content: chunk, } - if _, err := sbu.Client.PutPageUpdate(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutPageUpdate(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { uploadCtx.errors <- fmt.Errorf("writing page at offset %d for file %q: %s", page.offset, sbu.Source, err) uploadCtx.wg.Done() continue diff --git a/internal/services/storage/client/client.go b/internal/services/storage/client/client.go index 199f0dbbfc56..dd3b3b1ea72b 100644 --- a/internal/services/storage/client/client.go +++ b/internal/services/storage/client/client.go @@ -4,62 +4,48 @@ package client import ( - "context" "fmt" "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage" // nolint: staticcheck - "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" storage_v2023_01_01 "github.com/hashicorp/go-azure-sdk/resource-manager/storage/2023-01-01" "github.com/hashicorp/go-azure-sdk/resource-manager/storagesync/2020-03-01/cloudendpointresource" "github.com/hashicorp/go-azure-sdk/resource-manager/storagesync/2020-03-01/storagesyncservicesresource" "github.com/hashicorp/go-azure-sdk/resource-manager/storagesync/2020-03-01/syncgroupresource" + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" "github.com/hashicorp/terraform-provider-azurerm/internal/common" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/shim" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" ) type Client struct { + SubscriptionId string + AccountsClient *storage.AccountsClient - FileSystemsClient *filesystems.Client - ADLSGen2PathsClient *paths.Client - BlobServicesClient *storage.BlobServicesClient BlobInventoryPoliciesClient *storage.BlobInventoryPoliciesClient + BlobServicesClient *storage.BlobServicesClient EncryptionScopesClient *storage.EncryptionScopesClient - Environment azure.Environment FileServicesClient *storage.FileServicesClient SyncCloudEndpointsClient *cloudendpointresource.CloudEndpointResourceClient - SyncServiceClient *storagesyncservicesresource.StorageSyncServicesResourceClient SyncGroupsClient *syncgroupresource.SyncGroupResourceClient - SubscriptionId string + SyncServiceClient *storagesyncservicesresource.StorageSyncServicesResourceClient ResourceManager *storage_v2023_01_01.Client - resourceManagerAuthorizer autorest.Authorizer - storageAdAuth *autorest.Authorizer + AzureEnvironment azure.Environment + StorageDomainSuffix string + + authorizerForAad auth.Authorizer } func NewClient(o *common.ClientOptions) (*Client, error) { + storageSuffix, ok := o.Environment.Storage.DomainSuffix() + if !ok { + return nil, fmt.Errorf("determining domain suffix for storage in environment: %s", o.Environment.Name) + } + accountsClient := storage.NewAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&accountsClient.Client, o.ResourceManagerAuthorizer) - fileSystemsClient := filesystems.NewWithEnvironment(o.AzureEnvironment) - o.ConfigureClient(&fileSystemsClient.Client, o.StorageAuthorizer) - - adlsGen2PathsClient := paths.NewWithEnvironment(o.AzureEnvironment) - o.ConfigureClient(&adlsGen2PathsClient.Client, o.StorageAuthorizer) - blobServicesClient := storage.NewBlobServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&blobServicesClient.Client, o.ResourceManagerAuthorizer) @@ -100,12 +86,9 @@ func NewClient(o *common.ClientOptions) (*Client, error) { // (which should fix #2977) when the storage clients have been moved in here client := Client{ AccountsClient: &accountsClient, - FileSystemsClient: &fileSystemsClient, - ADLSGen2PathsClient: &adlsGen2PathsClient, BlobServicesClient: &blobServicesClient, BlobInventoryPoliciesClient: &blobInventoryPoliciesClient, EncryptionScopesClient: &encryptionScopesClient, - Environment: o.AzureEnvironment, FileServicesClient: &fileServicesClient, ResourceManager: resourceManager, SubscriptionId: o.SubscriptionId, @@ -113,195 +96,13 @@ func NewClient(o *common.ClientOptions) (*Client, error) { SyncServiceClient: syncServiceClient, SyncGroupsClient: syncGroupsClient, - resourceManagerAuthorizer: o.ResourceManagerAuthorizer, + AzureEnvironment: o.AzureEnvironment, + StorageDomainSuffix: *storageSuffix, } if o.StorageUseAzureAD { - client.storageAdAuth = &o.StorageAuthorizer + client.authorizerForAad = o.Authorizers.Storage } return &client, nil } - -func (client Client) AccountsDataPlaneClient(ctx context.Context, account accountDetails) (*accounts.Client, error) { - if client.storageAdAuth != nil { - accountsClient := accounts.NewWithEnvironment(client.Environment) - accountsClient.Client.Authorizer = *client.storageAdAuth - return &accountsClient, nil - } - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKey) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - accountsClient := accounts.NewWithEnvironment(client.Environment) - accountsClient.Client.Authorizer = storageAuth - return &accountsClient, nil -} - -func (client Client) BlobsClient(ctx context.Context, account accountDetails) (*blobs.Client, error) { - if client.storageAdAuth != nil { - blobsClient := blobs.NewWithEnvironment(client.Environment) - blobsClient.Client.Authorizer = *client.storageAdAuth - return &blobsClient, nil - } - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKey) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - blobsClient := blobs.NewWithEnvironment(client.Environment) - blobsClient.Client.Authorizer = storageAuth - return &blobsClient, nil -} - -func (client Client) ContainersClient(ctx context.Context, account accountDetails) (shim.StorageContainerWrapper, error) { - if client.storageAdAuth != nil { - containersClient := containers.NewWithEnvironment(client.Environment) - containersClient.Client.Authorizer = *client.storageAdAuth - shim := shim.NewDataPlaneStorageContainerWrapper(&containersClient) - return shim, nil - } - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKey) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - containersClient := containers.NewWithEnvironment(client.Environment) - containersClient.Client.Authorizer = storageAuth - - shim := shim.NewDataPlaneStorageContainerWrapper(&containersClient) - return shim, nil -} - -func (client Client) FileShareDirectoriesClient(ctx context.Context, account accountDetails) (*directories.Client, error) { - // NOTE: Files do not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLite) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - directoriesClient := directories.NewWithEnvironment(client.Environment) - directoriesClient.Client.Authorizer = storageAuth - return &directoriesClient, nil -} - -func (client Client) FileShareFilesClient(ctx context.Context, account accountDetails) (*files.Client, error) { - // NOTE: Files do not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLite) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - filesClient := files.NewWithEnvironment(client.Environment) - filesClient.Client.Authorizer = storageAuth - return &filesClient, nil -} - -func (client Client) FileSharesClient(ctx context.Context, account accountDetails) (shim.StorageShareWrapper, error) { - // NOTE: Files do not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLite) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - sharesClient := shares.NewWithEnvironment(client.Environment) - sharesClient.Client.Authorizer = storageAuth - shim := shim.NewDataPlaneStorageShareWrapper(&sharesClient) - return shim, nil -} - -func (client Client) QueuesClient(ctx context.Context, account accountDetails) (shim.StorageQueuesWrapper, error) { - if client.storageAdAuth != nil { - queueClient := queues.NewWithEnvironment(client.Environment) - queueClient.Client.Authorizer = *client.storageAdAuth - return shim.NewDataPlaneStorageQueueWrapper(&queueClient), nil - } - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLite) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - queuesClient := queues.NewWithEnvironment(client.Environment) - queuesClient.Client.Authorizer = storageAuth - return shim.NewDataPlaneStorageQueueWrapper(&queuesClient), nil -} - -func (client Client) TableEntityClient(ctx context.Context, account accountDetails) (*entities.Client, error) { - // NOTE: Table Entity does not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLiteForTable) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - entitiesClient := entities.NewWithEnvironment(client.Environment) - entitiesClient.Client.Authorizer = storageAuth - return &entitiesClient, nil -} - -func (client Client) TablesClient(ctx context.Context, account accountDetails) (shim.StorageTableWrapper, error) { - // NOTE: Tables do not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLiteForTable) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - tablesClient := tables.NewWithEnvironment(client.Environment) - tablesClient.Client.Authorizer = storageAuth - shim := shim.NewDataPlaneStorageTableWrapper(&tablesClient) - return shim, nil -} diff --git a/internal/services/storage/client/data_plane.go b/internal/services/storage/client/data_plane.go new file mode 100644 index 000000000000..0ab198faa5f6 --- /dev/null +++ b/internal/services/storage/client/data_plane.go @@ -0,0 +1,308 @@ +package client + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/shim" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" +) + +type DataPlaneOperation struct { + SupportsAadAuthentication bool + SupportsSharedKeyAuthentication bool + + sharedKeyAuthenticationType auth.SharedKeyType +} + +func (Client) DataPlaneOperationSupportingAnyAuthMethod() DataPlaneOperation { + return DataPlaneOperation{ + SupportsAadAuthentication: true, + SupportsSharedKeyAuthentication: true, + } +} + +func (Client) DataPlaneOperationSupportingOnlySharedKeyAuth() DataPlaneOperation { + return DataPlaneOperation{ + SupportsAadAuthentication: false, + SupportsSharedKeyAuthentication: true, + } +} + +func (client Client) ConfigureDataPlane(ctx context.Context, baseUri, clientName string, baseClient client.BaseClient, account accountDetails, operation DataPlaneOperation) error { + if operation.SupportsAadAuthentication && client.authorizerForAad != nil { + baseClient.SetAuthorizer(client.authorizerForAad) + return nil + } + + if operation.SupportsSharedKeyAuthentication { + accountKey, err := account.AccountKey(ctx, client) + if err != nil { + return fmt.Errorf("retrieving Storage Account Key: %s", err) + } + + storageAuth, err := auth.NewSharedKeyAuthorizer(account.name, *accountKey, operation.sharedKeyAuthenticationType) + if err != nil { + return fmt.Errorf("building Shared Key Authorizer for %s client: %+v", clientName, err) + } + + baseClient.SetAuthorizer(storageAuth) + return nil + } + + return fmt.Errorf("building %s client: no configured authentication types are supported", clientName) +} + +func (client Client) AccountsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*accounts.Client, error) { + const clientName = "Blob Storage Accounts" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeBlob) + if err != nil { + return nil, err + } + + apiClient, err := accounts.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) BlobsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*blobs.Client, error) { + const clientName = "Blob Storage Blobs" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeBlob) + if err != nil { + return nil, err + } + + apiClient, err := blobs.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) ContainersDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageContainerWrapper, error) { + const clientName = "Blob Storage Containers" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeBlob) + if err != nil { + return nil, err + } + + apiClient, err := containers.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return shim.NewDataPlaneStorageContainerWrapper(apiClient), nil +} + +func (client Client) DataLakeFilesystemsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*filesystems.Client, error) { + const clientName = "Data Lake Filesystems" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeDfs) + if err != nil { + return nil, err + } + + apiClient, err := filesystems.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) DataLakePathsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*paths.Client, error) { + const clientName = "Data Lake Paths" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeDfs) + if err != nil { + return nil, err + } + + apiClient, err := paths.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) FileShareDirectoriesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*directories.Client, error) { + const clientName = "File Storage Shares" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeFile) + if err != nil { + return nil, err + } + + apiClient, err := directories.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) FileShareFilesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*files.Client, error) { + const clientName = "File Storage Share Files" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeFile) + if err != nil { + return nil, err + } + + apiClient, err := files.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) FileSharesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageShareWrapper, error) { + const clientName = "File Storage Share Shares" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeFile) + if err != nil { + return nil, err + } + + apiClient, err := shares.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return shim.NewDataPlaneStorageShareWrapper(apiClient), nil +} + +func (client Client) QueuesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageQueuesWrapper, error) { + const clientName = "File Storage Queue Queues" + operation.sharedKeyAuthenticationType = auth.SharedKey + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeQueue) + if err != nil { + return nil, err + } + + apiClient, err := queues.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return shim.NewDataPlaneStorageQueueWrapper(apiClient), nil +} + +func (client Client) TableEntityDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*entities.Client, error) { + const clientName = "Table Storage Share Entities" + operation.sharedKeyAuthenticationType = auth.SharedKeyTable + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeTable) + if err != nil { + return nil, err + } + + apiClient, err := entities.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) TablesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageTableWrapper, error) { + const clientName = "Table Storage Share Tables" + operation.sharedKeyAuthenticationType = auth.SharedKeyTable + + baseUri, err := account.DataPlaneEndpoint(EndpointTypeTable) + if err != nil { + return nil, err + } + + apiClient, err := tables.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return shim.NewDataPlaneStorageTableWrapper(apiClient), nil +} diff --git a/internal/services/storage/client/helpers.go b/internal/services/storage/client/helpers.go index 7d4a82865cb2..3396466dced6 100644 --- a/internal/services/storage/client/helpers.go +++ b/internal/services/storage/client/helpers.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "log" + "strings" "sync" "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage" // nolint: staticcheck @@ -20,6 +21,16 @@ var ( credentialsLock = sync.RWMutex{} ) +type EndpointType string + +const ( + EndpointTypeBlob = "blob" + EndpointTypeDfs = "dfs" + EndpointTypeFile = "file" + EndpointTypeQueue = "queue" + EndpointTypeTable = "table" +) + type accountDetails struct { ID string Kind storage.Kind @@ -42,11 +53,11 @@ func (ad *accountDetails) AccountKey(ctx context.Context, client Client) (*strin log.Printf("[DEBUG] Cache Miss - looking up the account key for storage account %q..", ad.name) props, err := client.AccountsClient.ListKeys(ctx, ad.ResourceGroup, ad.name, storage.ListKeyExpandKerb) if err != nil { - return nil, fmt.Errorf("Listing Keys for Storage Account %q (Resource Group %q): %+v", ad.name, ad.ResourceGroup, err) + return nil, fmt.Errorf("listing Keys for Storage Account %q (Resource Group %q): %+v", ad.name, ad.ResourceGroup, err) } if props.Keys == nil || len(*props.Keys) == 0 || (*props.Keys)[0].Value == nil { - return nil, fmt.Errorf("Keys were nil for Storage Account %q (Resource Group %q): %+v", ad.name, ad.ResourceGroup, err) + return nil, fmt.Errorf("keys were nil for Storage Account %q (Resource Group %q): %+v", ad.name, ad.ResourceGroup, err) } keys := *props.Keys @@ -58,6 +69,48 @@ func (ad *accountDetails) AccountKey(ctx context.Context, client Client) (*strin return ad.accountKey, nil } +func (ad *accountDetails) DataPlaneEndpoint(endpointType EndpointType) (*string, error) { + if ad.Properties == nil { + return nil, fmt.Errorf("storage account %q has no properties", ad.name) + } + if ad.Properties.PrimaryEndpoints == nil { + return nil, fmt.Errorf("storage account %q has missing endpoints", ad.name) + } + + var baseUri string + + switch endpointType { + case EndpointTypeBlob: + if ad.Properties.PrimaryEndpoints.Blob != nil { + baseUri = strings.TrimSuffix(*ad.Properties.PrimaryEndpoints.Blob, "/") + } + case EndpointTypeDfs: + if ad.Properties.PrimaryEndpoints.Dfs != nil { + baseUri = strings.TrimSuffix(*ad.Properties.PrimaryEndpoints.Dfs, "/") + } + case EndpointTypeFile: + if ad.Properties.PrimaryEndpoints.File != nil { + baseUri = strings.TrimSuffix(*ad.Properties.PrimaryEndpoints.File, "/") + } + case EndpointTypeQueue: + if ad.Properties.PrimaryEndpoints.Queue != nil { + baseUri = strings.TrimSuffix(*ad.Properties.PrimaryEndpoints.Queue, "/") + } + case EndpointTypeTable: + if ad.Properties.PrimaryEndpoints.Table != nil { + baseUri = strings.TrimSuffix(*ad.Properties.PrimaryEndpoints.Table, "/") + } + default: + return nil, fmt.Errorf("internal-error: unrecognised endpoint type %q when building storage client", endpointType) + } + + if baseUri == "" { + return nil, fmt.Errorf("determining storage account %s endpoint for : %q", endpointType, ad.name) + } + + return &baseUri, nil +} + func (client Client) AddToCache(accountName string, props storage.Account) error { accountsLock.Lock() defer accountsLock.Unlock() diff --git a/internal/services/storage/helpers/schema.go b/internal/services/storage/helpers/schema.go new file mode 100644 index 000000000000..5a3909f1f7c7 --- /dev/null +++ b/internal/services/storage/helpers/schema.go @@ -0,0 +1,38 @@ +package helpers + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" +) + +type StorageIDValidationFunc func(id, storageDomainSuffix string) error + +// ImporterValidatingStorageResourceId is similar to pluginsdk.ImporterValidatingResourceId whilst additionally passing in +// the storage domain suffix for the current environment/cloud, so that the domain component of the ID can be validated. +func ImporterValidatingStorageResourceId(validateFunc StorageIDValidationFunc) *schema.ResourceImporter { + return ImporterValidatingStorageResourceIdThen(validateFunc, nil) +} + +// ImporterValidatingStorageResourceIdThen is similar to pluginsdk.ImporterValidatingResourceIdThen whilst additionally passing in +// the storage domain suffix for the current environment/cloud, so that the domain component of the ID can be validated. +func ImporterValidatingStorageResourceIdThen(validateFunc StorageIDValidationFunc, thenFunc pluginsdk.ImporterFunc) *schema.ResourceImporter { + return &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) ([]*pluginsdk.ResourceData, error) { + storageDomainSuffix := meta.(*clients.Client).Storage.StorageDomainSuffix + log.Printf("[DEBUG] Importing Storage Resource - parsing %q using domain suffix %q", d.Id(), storageDomainSuffix) + if err := validateFunc(d.Id(), storageDomainSuffix); err != nil { + return []*pluginsdk.ResourceData{d}, err + } + + if thenFunc != nil { + return thenFunc(ctx, d, meta) + } + + return []*pluginsdk.ResourceData{d}, nil + }, + } +} diff --git a/internal/services/storage/migration/share.go b/internal/services/storage/migration/share.go index 6e48a71d3ae9..431069cd4f94 100644 --- a/internal/services/storage/migration/share.go +++ b/internal/services/storage/migration/share.go @@ -12,7 +12,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) var _ pluginsdk.StateUpgrade = ShareV0ToV1{} @@ -54,25 +55,28 @@ func (s ShareV1ToV2) UpgradeFunc() pluginsdk.StateUpgraderFunc { // name/resourceGroup/accountName parsedId := strings.Split(id, "/") if len(parsedId) != 3 { - return rawState, fmt.Errorf("Expected 3 segments in the ID but got %d", len(parsedId)) + return rawState, fmt.Errorf("expected 3 segments in the ID but got %d", len(parsedId)) } shareName := parsedId[0] accountName := parsedId[2] - environment := meta.(*clients.Client).Account.AzureEnvironment - client := shares.NewWithEnvironment(environment) + accountId := accounts.AccountId{ + AccountName: accountName, + SubDomainType: "file", + DomainSuffix: meta.(*clients.Client).Storage.StorageDomainSuffix, + } - newResourceId := client.GetResourceID(accountName, shareName) + newResourceId := shares.NewShareID(accountId, shareName) log.Printf("[DEBUG] Updating Resource ID from %q to %q", id, newResourceId) - rawState["id"] = newResourceId + rawState["id"] = newResourceId.ID() return rawState, nil } } -// the schema schema was used for both V0 and V1 +// this schema was used for both V0 and V1 func shareSchemaForV0AndV1() map[string]*pluginsdk.Schema { return map[string]*pluginsdk.Schema{ "name": { diff --git a/internal/services/storage/migration/share_test.go b/internal/services/storage/migration/share_test.go index 6f7496e5b9f0..8484eb67510b 100644 --- a/internal/services/storage/migration/share_test.go +++ b/internal/services/storage/migration/share_test.go @@ -10,7 +10,9 @@ import ( "testing" "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-sdk/sdk/environments" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + storageClient "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" ) func TestShareV0ToV1(t *testing.T) { @@ -59,10 +61,10 @@ func TestShareV0ToV1(t *testing.T) { } func TestShareV1ToV2(t *testing.T) { - clouds := []azure.Environment{ - azure.ChinaCloud, - azure.PublicCloud, - azure.USGovernmentCloud, + clouds := []*environments.Environment{ + environments.AzureChina(), + environments.AzurePublic(), + environments.AzureUSGovernment(), } for _, cloud := range clouds { @@ -76,14 +78,22 @@ func TestShareV1ToV2(t *testing.T) { "quota": 5120, } + storageSuffix, ok := cloud.Storage.DomainSuffix() + if !ok { + t.Fatalf("determining domain suffix for storage in environment: %s", cloud.Name) + } + meta := &clients.Client{ Account: &clients.ResourceManagerAccount{ - AzureEnvironment: cloud, + Environment: *cloud, + }, + Storage: &storageClient.Client{ + StorageDomainSuffix: *storageSuffix, }, } expected := map[string]interface{}{ - "id": fmt.Sprintf("https://account1.file.%s/share1", cloud.StorageEndpointSuffix), + "id": fmt.Sprintf("https://account1.file.%s/share1", *storageSuffix), "name": "share1", "resource_group_name": "group1", "storage_account_name": "account1", diff --git a/internal/services/storage/parse/storage_container_data_plane.go b/internal/services/storage/parse/storage_container_data_plane.go deleted file mode 100644 index 47dc25a7ec8c..000000000000 --- a/internal/services/storage/parse/storage_container_data_plane.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package parse - -import ( - "fmt" - "net/url" - "strings" - - "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" -) - -var _ resourceids.Id = StorageContainerDataPlaneId{} - -type StorageContainerDataPlaneId struct { - AccountName string - DomainSuffix string - Name string -} - -func (id StorageContainerDataPlaneId) String() string { - components := []string{ - fmt.Sprintf("Account Name %q", id.AccountName), - fmt.Sprintf("Domain Suffix %q", id.DomainSuffix), - fmt.Sprintf("Name %q", id.Name), - } - return fmt.Sprintf("Storage Container %s", strings.Join(components, " / ")) -} - -func (id StorageContainerDataPlaneId) ID() string { - return fmt.Sprintf("https://%s.blob.%s/%s", id.AccountName, id.DomainSuffix, id.Name) -} - -func NewStorageContainerDataPlaneId(accountName, domainSuffix, name string) StorageContainerDataPlaneId { - return StorageContainerDataPlaneId{ - AccountName: accountName, - DomainSuffix: domainSuffix, - Name: name, - } -} - -func StorageContainerDataPlaneID(id string) (*StorageContainerDataPlaneId, error) { - parsed, err := containers.ParseResourceID(id) - if err != nil { - return nil, err - } - - uri, err := url.Parse(id) - if err != nil { - return nil, err - } - - host := uri.Host - hostSegments := strings.Split(host, ".") - if len(hostSegments) == 0 { - return nil, fmt.Errorf("expected multiple host segments but got 0") - } - domainNameSuffix := strings.TrimPrefix(host, fmt.Sprintf("%s.blob.", hostSegments[0])) - - return &StorageContainerDataPlaneId{ - AccountName: parsed.AccountName, - DomainSuffix: domainNameSuffix, - Name: parsed.ContainerName, - }, nil -} diff --git a/internal/services/storage/parse/storage_queue_data_plane.go b/internal/services/storage/parse/storage_queue_data_plane.go deleted file mode 100644 index 3fd6770ec093..000000000000 --- a/internal/services/storage/parse/storage_queue_data_plane.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package parse - -import ( - "fmt" - "net/url" - "strings" - - "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" -) - -var _ resourceids.Id = StorageQueueDataPlaneId{} - -type StorageQueueDataPlaneId struct { - AccountName string - DomainSuffix string - Name string -} - -func (id StorageQueueDataPlaneId) String() string { - components := []string{ - fmt.Sprintf("Account Name %q", id.AccountName), - fmt.Sprintf("Domain Suffix %q", id.DomainSuffix), - fmt.Sprintf("Name %q", id.Name), - } - return fmt.Sprintf("Storage Queue %s", strings.Join(components, " / ")) -} - -func (id StorageQueueDataPlaneId) ID() string { - return fmt.Sprintf("https://%s.queue.%s/%s", id.AccountName, id.DomainSuffix, id.Name) -} - -func NewStorageQueueDataPlaneId(accountName, domainSuffix, name string) StorageQueueDataPlaneId { - return StorageQueueDataPlaneId{ - AccountName: accountName, - DomainSuffix: domainSuffix, - Name: name, - } -} - -func StorageQueueDataPlaneID(id string) (*StorageQueueDataPlaneId, error) { - parsed, err := queues.ParseResourceID(id) - if err != nil { - return nil, err - } - - uri, err := url.Parse(id) - if err != nil { - return nil, err - } - - host := uri.Host - hostSegments := strings.Split(host, ".") - if len(hostSegments) == 0 { - return nil, fmt.Errorf("expected multiple host segments but got 0") - } - domainNameSuffix := strings.TrimPrefix(host, fmt.Sprintf("%s.queue.", hostSegments[0])) - - return &StorageQueueDataPlaneId{ - AccountName: parsed.AccountName, - DomainSuffix: domainNameSuffix, - Name: parsed.QueueName, - }, nil -} diff --git a/internal/services/storage/parse/storage_share_data_plane.go b/internal/services/storage/parse/storage_share_data_plane.go deleted file mode 100644 index 321fff4a7a8f..000000000000 --- a/internal/services/storage/parse/storage_share_data_plane.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package parse - -import ( - "fmt" - "net/url" - "strings" - - "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" -) - -// TODO: tests for this -var _ resourceids.Id = StorageShareDataPlaneId{} - -type StorageShareDataPlaneId struct { - AccountName string - DomainSuffix string - Name string -} - -func (id StorageShareDataPlaneId) String() string { - components := []string{ - fmt.Sprintf("Account Name %q", id.AccountName), - fmt.Sprintf("Domain Suffix %q", id.DomainSuffix), - fmt.Sprintf("Name %q", id.Name), - } - return fmt.Sprintf("Storage Share (%s)", strings.Join(components, " / ")) -} - -func (id StorageShareDataPlaneId) ID() string { - return fmt.Sprintf("https://%s.file.%s/%s", id.AccountName, id.DomainSuffix, id.Name) -} - -func NewStorageShareDataPlaneId(accountName, domainSuffix, name string) StorageShareDataPlaneId { - return StorageShareDataPlaneId{ - AccountName: accountName, - DomainSuffix: domainSuffix, - Name: name, - } -} - -func StorageShareDataPlaneID(id string) (*StorageShareDataPlaneId, error) { - parsed, err := shares.ParseResourceID(id) - if err != nil { - return nil, err - } - - uri, err := url.Parse(id) - if err != nil { - return nil, err - } - - host := uri.Host - hostSegments := strings.Split(host, ".") - if len(hostSegments) == 0 { - return nil, fmt.Errorf("expected multiple host segments but got 0") - } - domainNameSuffix := strings.TrimPrefix(host, fmt.Sprintf("%s.file.", hostSegments[0])) - - return &StorageShareDataPlaneId{ - AccountName: parsed.AccountName, - DomainSuffix: domainNameSuffix, - Name: parsed.ShareName, - }, nil -} diff --git a/internal/services/storage/parse/storage_table_data_plane.go b/internal/services/storage/parse/storage_table_data_plane.go deleted file mode 100644 index bf668f89f317..000000000000 --- a/internal/services/storage/parse/storage_table_data_plane.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package parse - -import ( - "fmt" - "net/url" - "strings" - - "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" -) - -// TODO: tests for this -var _ resourceids.Id = StorageTableDataPlaneId{} - -type StorageTableDataPlaneId struct { - AccountName string - DomainSuffix string - Name string -} - -func (id StorageTableDataPlaneId) String() string { - components := []string{ - fmt.Sprintf("Account Name %q", id.AccountName), - fmt.Sprintf("Domain Suffix %q", id.DomainSuffix), - fmt.Sprintf("Name %q", id.Name), - } - return fmt.Sprintf("Storage Table %s", strings.Join(components, " / ")) -} - -func (id StorageTableDataPlaneId) ID() string { - return fmt.Sprintf("https://%s.table.%s/Tables('%s')", id.AccountName, id.DomainSuffix, id.Name) -} - -func NewStorageTableDataPlaneId(accountName, domainSuffix, name string) StorageTableDataPlaneId { - return StorageTableDataPlaneId{ - AccountName: accountName, - DomainSuffix: domainSuffix, - Name: name, - } -} - -func StorageTableDataPlaneID(input string) (*StorageTableDataPlaneId, error) { - parsed, err := tables.ParseResourceID(input) - if err != nil { - return nil, err - } - - uri, err := url.Parse(input) - if err != nil { - return nil, err - } - - host := uri.Host - hostSegments := strings.Split(host, ".") - if len(hostSegments) == 0 { - return nil, fmt.Errorf("expected multiple host segments but got 0") - } - domainNameSuffix := strings.TrimPrefix(host, fmt.Sprintf("%s.table.", hostSegments[0])) - - return &StorageTableDataPlaneId{ - AccountName: parsed.AccountName, - DomainSuffix: domainNameSuffix, - Name: parsed.TableName, - }, nil -} diff --git a/internal/services/storage/parse/storage_table_entities.go b/internal/services/storage/parse/storage_table_entities.go index 4c18c883d341..5d4fa0caf755 100644 --- a/internal/services/storage/parse/storage_table_entities.go +++ b/internal/services/storage/parse/storage_table_entities.go @@ -16,6 +16,7 @@ import ( // TODO: tests for this var _ resourceids.Id = StorageTableEntitiesId{} +// StorageTableEntitiesId is used by the plural data source azurerm_storage_table_entities type StorageTableEntitiesId struct { AccountName string DomainSuffix string @@ -37,14 +38,14 @@ func (id StorageTableEntitiesId) ID() string { return fmt.Sprintf("https://%s.table.%s/%s(%s)", id.AccountName, id.DomainSuffix, id.TableName, id.Filter) } -func NewStorageTableEntitiesId(accountName, domainSuffix, tablename, filter string) StorageTableEntitiesId { +func NewStorageTableEntitiesId(accountName, domainSuffix, tableName, filter string) StorageTableEntitiesId { s := utils.Base64EncodeIfNot(filter) sha := sha1.Sum([]byte(s)) filterHash := hex.EncodeToString(sha[:]) return StorageTableEntitiesId{ AccountName: accountName, DomainSuffix: domainSuffix, - TableName: tablename, + TableName: tableName, Filter: filterHash, } } diff --git a/internal/services/storage/shim/containers.go b/internal/services/storage/shim/containers.go index 55156bb5d9f3..c29325ce4aa2 100644 --- a/internal/services/storage/shim/containers.go +++ b/internal/services/storage/shim/containers.go @@ -6,16 +6,16 @@ package shim import ( "context" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) type StorageContainerWrapper interface { - Create(ctx context.Context, resourceGroup, accountName, containerName string, input containers.CreateInput) error - Delete(ctx context.Context, resourceGroup, accountName, containerName string) error - Exists(ctx context.Context, resourceGroup, accountName, containerName string) (*bool, error) - Get(ctx context.Context, resourceGroup, accountName, containerName string) (*StorageContainerProperties, error) - UpdateAccessLevel(ctx context.Context, resourceGroup, accountName, containerName string, level containers.AccessLevel) error - UpdateMetaData(ctx context.Context, resourceGroup, accountName, containerName string, metadata map[string]string) error + Create(ctx context.Context, containerName string, input containers.CreateInput) error + Delete(ctx context.Context, containerName string) error + Exists(ctx context.Context, containerName string) (*bool, error) + Get(ctx context.Context, containerName string) (*StorageContainerProperties, error) + UpdateAccessLevel(ctx context.Context, containerName string, level containers.AccessLevel) error + UpdateMetaData(ctx context.Context, containerName string, metaData map[string]string) error } type StorageContainerProperties struct { diff --git a/internal/services/storage/shim/containers_data_plane.go b/internal/services/storage/shim/containers_data_plane.go index 2310188f5230..e365ef9819fb 100644 --- a/internal/services/storage/shim/containers_data_plane.go +++ b/internal/services/storage/shim/containers_data_plane.go @@ -6,12 +6,10 @@ package shim import ( "context" "fmt" - "strings" - "time" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) type DataPlaneStorageContainerWrapper struct { @@ -24,59 +22,37 @@ func NewDataPlaneStorageContainerWrapper(client *containers.Client) StorageConta } } -func (w DataPlaneStorageContainerWrapper) Create(ctx context.Context, _, accountName, containerName string, input containers.CreateInput) error { - timeout, ok := ctx.Deadline() - if !ok { - return fmt.Errorf("context is missing a timeout") - } - - if resp, err := w.client.Create(ctx, accountName, containerName, input); err != nil { - // If we fail due to previous delete still in progress, then we can retry - if utils.ResponseWasConflict(resp.Response) && strings.Contains(err.Error(), "ContainerBeingDeleted") { - stateConf := &pluginsdk.StateChangeConf{ - Pending: []string{"waitingOnDelete"}, - Target: []string{"succeeded"}, - Refresh: w.createRefreshFunc(ctx, accountName, containerName, input), - PollInterval: 10 * time.Second, - NotFoundChecks: 180, - Timeout: time.Until(timeout), - } - - if _, err := stateConf.WaitForStateContext(ctx); err != nil { - return fmt.Errorf("failed creating container: %+v", err) - } - } else { - return fmt.Errorf("failed creating container: %+v", err) - } +func (w DataPlaneStorageContainerWrapper) Create(ctx context.Context, containerName string, input containers.CreateInput) error { + if _, err := w.client.Create(ctx, containerName, input); err != nil { + return fmt.Errorf("creating container: %+v", err) } return nil } -func (w DataPlaneStorageContainerWrapper) Delete(ctx context.Context, _, accountName, containerName string) error { - resp, err := w.client.Delete(ctx, accountName, containerName) - if utils.ResponseWasNotFound(resp) { +func (w DataPlaneStorageContainerWrapper) Delete(ctx context.Context, containerName string) error { + resp, err := w.client.Delete(ctx, containerName) + if response.WasNotFound(resp.HttpResponse) { return nil } return err } -func (w DataPlaneStorageContainerWrapper) Exists(ctx context.Context, _, accountName, containerName string) (*bool, error) { - existing, err := w.client.GetProperties(ctx, accountName, containerName) +func (w DataPlaneStorageContainerWrapper) Exists(ctx context.Context, containerName string) (*bool, error) { + existing, err := w.client.GetProperties(ctx, containerName, containers.GetPropertiesInput{}) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return nil, err + if response.WasNotFound(existing.HttpResponse) { + return pointer.To(false), nil } + return nil, err } - - exists := !utils.ResponseWasNotFound(existing.Response) - return &exists, nil + return pointer.To(true), nil } -func (w DataPlaneStorageContainerWrapper) Get(ctx context.Context, _, accountName, containerName string) (*StorageContainerProperties, error) { - props, err := w.client.GetProperties(ctx, accountName, containerName) +func (w DataPlaneStorageContainerWrapper) Get(ctx context.Context, containerName string) (*StorageContainerProperties, error) { + props, err := w.client.GetProperties(ctx, containerName, containers.GetPropertiesInput{}) if err != nil { - if utils.ResponseWasNotFound(props.Response) { + if response.WasNotFound(props.HttpResponse) { return nil, nil } @@ -91,29 +67,18 @@ func (w DataPlaneStorageContainerWrapper) Get(ctx context.Context, _, accountNam }, nil } -func (w DataPlaneStorageContainerWrapper) UpdateAccessLevel(ctx context.Context, _, accountName, containerName string, level containers.AccessLevel) error { - _, err := w.client.SetAccessControl(ctx, accountName, containerName, level) - return err -} - -func (w DataPlaneStorageContainerWrapper) UpdateMetaData(ctx context.Context, _, accountName, containerName string, metaData map[string]string) error { - _, err := w.client.SetMetaData(ctx, accountName, containerName, metaData) +func (w DataPlaneStorageContainerWrapper) UpdateAccessLevel(ctx context.Context, containerName string, level containers.AccessLevel) error { + input := containers.SetAccessControlInput{ + AccessLevel: level, + } + _, err := w.client.SetAccessControl(ctx, containerName, input) return err } -func (w DataPlaneStorageContainerWrapper) createRefreshFunc(ctx context.Context, accountName string, containerName string, input containers.CreateInput) pluginsdk.StateRefreshFunc { - return func() (interface{}, string, error) { - resp, err := w.client.Create(ctx, accountName, containerName, input) - if err != nil { - if !utils.ResponseWasConflict(resp.Response) { - return nil, "", err - } - - if utils.ResponseWasConflict(resp.Response) && strings.Contains(err.Error(), "ContainerBeingDeleted") { - return nil, "waitingOnDelete", nil - } - } - - return "succeeded", "succeeded", nil +func (w DataPlaneStorageContainerWrapper) UpdateMetaData(ctx context.Context, containerName string, metaData map[string]string) error { + input := containers.SetMetaDataInput{ + MetaData: metaData, } + _, err := w.client.SetMetaData(ctx, containerName, input) + return err } diff --git a/internal/services/storage/shim/queues.go b/internal/services/storage/shim/queues.go index d145093014b0..d6d1d4e432c9 100644 --- a/internal/services/storage/shim/queues.go +++ b/internal/services/storage/shim/queues.go @@ -6,17 +6,17 @@ package shim import ( "context" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) type StorageQueuesWrapper interface { - Create(ctx context.Context, resourceGroup, accountName, queueName string, metaData map[string]string) error - Delete(ctx context.Context, resourceGroup, accountName, queueName string) error - Exists(ctx context.Context, resourceGroup, accountName, queueName string) (*bool, error) - Get(ctx context.Context, resourceGroup, accountName, queueName string) (*StorageQueueProperties, error) - GetServiceProperties(ctx context.Context, resourceGroup, accountName string) (*queues.StorageServiceProperties, error) - UpdateMetaData(ctx context.Context, resourceGroup, accountName, queueName string, metaData map[string]string) error - UpdateServiceProperties(ctx context.Context, resourceGroup, accountName string, properties queues.StorageServiceProperties) error + Create(ctx context.Context, queueName string, metaData map[string]string) error + Delete(ctx context.Context, queueName string) error + Exists(ctx context.Context, queueName string) (*bool, error) + Get(ctx context.Context, queueName string) (*StorageQueueProperties, error) + GetServiceProperties(ctx context.Context) (*queues.StorageServiceProperties, error) + UpdateMetaData(ctx context.Context, queueName string, metaData map[string]string) error + UpdateServiceProperties(ctx context.Context, properties queues.StorageServiceProperties) error } type StorageQueueProperties struct { diff --git a/internal/services/storage/shim/queues_data_plane.go b/internal/services/storage/shim/queues_data_plane.go index 3052f205761a..8b52b1e9d068 100644 --- a/internal/services/storage/shim/queues_data_plane.go +++ b/internal/services/storage/shim/queues_data_plane.go @@ -6,8 +6,9 @@ package shim import ( "context" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) type DataPlaneStorageQueueWrapper struct { @@ -20,32 +21,34 @@ func NewDataPlaneStorageQueueWrapper(client *queues.Client) StorageQueuesWrapper } } -func (w DataPlaneStorageQueueWrapper) Create(ctx context.Context, _, accountName, queueName string, metaData map[string]string) error { - _, err := w.client.Create(ctx, accountName, queueName, metaData) +func (w DataPlaneStorageQueueWrapper) Create(ctx context.Context, queueName string, metaData map[string]string) error { + input := queues.CreateInput{ + MetaData: metaData, + } + _, err := w.client.Create(ctx, queueName, input) return err } -func (w DataPlaneStorageQueueWrapper) Delete(ctx context.Context, _, accountName, queueName string) error { - _, err := w.client.Delete(ctx, accountName, queueName) +func (w DataPlaneStorageQueueWrapper) Delete(ctx context.Context, queueName string) error { + _, err := w.client.Delete(ctx, queueName) return err } -func (w DataPlaneStorageQueueWrapper) Exists(ctx context.Context, _, accountName, queueName string) (*bool, error) { - existing, err := w.client.GetMetaData(ctx, accountName, queueName) +func (w DataPlaneStorageQueueWrapper) Exists(ctx context.Context, queueName string) (*bool, error) { + existing, err := w.client.GetMetaData(ctx, queueName) if err != nil { - if utils.ResponseWasNotFound(existing.Response) { - return utils.Bool(false), nil + if response.WasNotFound(existing.HttpResponse) { + return pointer.To(false), nil } return nil, err } - - return utils.Bool(true), nil + return pointer.To(true), nil } -func (w DataPlaneStorageQueueWrapper) Get(ctx context.Context, _, accountName, queueName string) (*StorageQueueProperties, error) { - props, err := w.client.GetMetaData(ctx, accountName, queueName) +func (w DataPlaneStorageQueueWrapper) Get(ctx context.Context, queueName string) (*StorageQueueProperties, error) { + props, err := w.client.GetMetaData(ctx, queueName) if err != nil { - if utils.ResponseWasNotFound(props.Response) { + if response.WasNotFound(props.HttpResponse) { return nil, nil } return nil, err @@ -56,10 +59,10 @@ func (w DataPlaneStorageQueueWrapper) Get(ctx context.Context, _, accountName, q }, nil } -func (w DataPlaneStorageQueueWrapper) GetServiceProperties(ctx context.Context, resourceGroup, accountName string) (*queues.StorageServiceProperties, error) { - serviceProps, err := w.client.GetServiceProperties(ctx, accountName) +func (w DataPlaneStorageQueueWrapper) GetServiceProperties(ctx context.Context) (*queues.StorageServiceProperties, error) { + serviceProps, err := w.client.GetServiceProperties(ctx) if err != nil { - if utils.ResponseWasNotFound(serviceProps.Response) { + if response.WasNotFound(serviceProps.HttpResponse) { return nil, nil } return nil, err @@ -68,12 +71,18 @@ func (w DataPlaneStorageQueueWrapper) GetServiceProperties(ctx context.Context, return &serviceProps.StorageServiceProperties, nil } -func (w DataPlaneStorageQueueWrapper) UpdateMetaData(ctx context.Context, _, accountName, queueName string, metaData map[string]string) error { - _, err := w.client.SetMetaData(ctx, accountName, queueName, metaData) +func (w DataPlaneStorageQueueWrapper) UpdateMetaData(ctx context.Context, queueName string, metaData map[string]string) error { + input := queues.SetMetaDataInput{ + MetaData: metaData, + } + _, err := w.client.SetMetaData(ctx, queueName, input) return err } -func (w DataPlaneStorageQueueWrapper) UpdateServiceProperties(ctx context.Context, _, accountName string, properties queues.StorageServiceProperties) error { - _, err := w.client.SetServiceProperties(ctx, accountName, properties) +func (w DataPlaneStorageQueueWrapper) UpdateServiceProperties(ctx context.Context, properties queues.StorageServiceProperties) error { + input := queues.SetStorageServicePropertiesInput{ + Properties: properties, + } + _, err := w.client.SetServiceProperties(ctx, input) return err } diff --git a/internal/services/storage/shim/shares.go b/internal/services/storage/shim/shares.go index 702e34b492b2..375595520e30 100644 --- a/internal/services/storage/shim/shares.go +++ b/internal/services/storage/shim/shares.go @@ -6,18 +6,18 @@ package shim import ( "context" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) type StorageShareWrapper interface { - Create(ctx context.Context, resourceGroup, accountName, shareName string, input shares.CreateInput) error - Delete(ctx context.Context, resourceGroup, accountName, shareName string) error - Exists(ctx context.Context, resourceGroup, accountName, shareName string) (*bool, error) - Get(ctx context.Context, resourceGroup, accountName, shareName string) (*StorageShareProperties, error) - UpdateACLs(ctx context.Context, resourceGroup, accountName, shareName string, acls []shares.SignedIdentifier) error - UpdateMetaData(ctx context.Context, resourceGroup, accountName, shareName string, metaData map[string]string) error - UpdateQuota(ctx context.Context, resourceGroup, accountName, shareName string, quotaGB int) error - UpdateTier(ctx context.Context, resourceGroup, accountName, shareName string, tier shares.AccessTier) error + Create(ctx context.Context, shareName string, input shares.CreateInput) error + Delete(ctx context.Context, shareName string) error + Exists(ctx context.Context, shareName string) (*bool, error) + Get(ctx context.Context, shareName string) (*StorageShareProperties, error) + UpdateACLs(ctx context.Context, shareName string, input shares.SetAclInput) error + UpdateMetaData(ctx context.Context, shareName string, metaData map[string]string) error + UpdateQuota(ctx context.Context, shareName string, quotaGB int) error + UpdateTier(ctx context.Context, shareName string, tier shares.AccessTier) error } type StorageShareProperties struct { diff --git a/internal/services/storage/shim/shares_data_plane.go b/internal/services/storage/shim/shares_data_plane.go index ae88b650cd55..a251059fd1b3 100644 --- a/internal/services/storage/shim/shares_data_plane.go +++ b/internal/services/storage/shim/shares_data_plane.go @@ -6,12 +6,10 @@ package shim import ( "context" "fmt" - "strings" - "time" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) type DataPlaneStorageShareWrapper struct { @@ -24,66 +22,43 @@ func NewDataPlaneStorageShareWrapper(client *shares.Client) StorageShareWrapper } } -func (w DataPlaneStorageShareWrapper) Create(ctx context.Context, _, accountName, shareName string, input shares.CreateInput) error { - timeout, ok := ctx.Deadline() - if !ok { - return fmt.Errorf("context is missing a timeout") +func (w DataPlaneStorageShareWrapper) Create(ctx context.Context, shareName string, input shares.CreateInput) error { + if _, err := w.client.Create(ctx, shareName, input); err != nil { + return fmt.Errorf("creating share: %+v", err) } - - resp, err := w.client.Create(ctx, accountName, shareName, input) - if err == nil { - return nil - } - - // If we fail due to previous delete still in progress, then we can retry - if utils.ResponseWasConflict(resp) && strings.Contains(err.Error(), "ShareBeingDeleted") { - stateConf := &pluginsdk.StateChangeConf{ - Pending: []string{"waitingOnDelete"}, - Target: []string{"succeeded"}, - Refresh: w.createRefreshFunc(ctx, accountName, shareName, input), - PollInterval: 10 * time.Second, - NotFoundChecks: 180, - Timeout: time.Until(timeout), - } - - _, err := stateConf.WaitForStateContext(ctx) - return err - } - - // otherwise it's a legit error, so raise it - return err + return nil } -func (w DataPlaneStorageShareWrapper) Delete(ctx context.Context, _, accountName, shareName string) error { - deleteSnapshots := true - _, err := w.client.Delete(ctx, accountName, shareName, deleteSnapshots) +func (w DataPlaneStorageShareWrapper) Delete(ctx context.Context, shareName string) error { + input := shares.DeleteInput{ + DeleteSnapshots: true, + } + _, err := w.client.Delete(ctx, shareName, input) return err } -func (w DataPlaneStorageShareWrapper) Exists(ctx context.Context, _, accountName, shareName string) (*bool, error) { - existing, err := w.client.GetProperties(ctx, accountName, shareName) +func (w DataPlaneStorageShareWrapper) Exists(ctx context.Context, shareName string) (*bool, error) { + existing, err := w.client.GetProperties(ctx, shareName) if err != nil { - if utils.ResponseWasNotFound(existing.Response) { - return nil, nil + if response.WasNotFound(existing.HttpResponse) { + return pointer.To(false), nil } - return nil, err } - - return utils.Bool(true), nil + return pointer.To(true), nil } -func (w DataPlaneStorageShareWrapper) Get(ctx context.Context, _, accountName, shareName string) (*StorageShareProperties, error) { - props, err := w.client.GetProperties(ctx, accountName, shareName) +func (w DataPlaneStorageShareWrapper) Get(ctx context.Context, shareName string) (*StorageShareProperties, error) { + props, err := w.client.GetProperties(ctx, shareName) if err != nil { - if utils.ResponseWasNotFound(props.Response) { + if response.WasNotFound(props.HttpResponse) { return nil, nil } return nil, err } - acls, err := w.client.GetACL(ctx, accountName, shareName) + acls, err := w.client.GetACL(ctx, shareName) if err != nil { return nil, err } @@ -97,44 +72,30 @@ func (w DataPlaneStorageShareWrapper) Get(ctx context.Context, _, accountName, s }, nil } -func (w DataPlaneStorageShareWrapper) UpdateACLs(ctx context.Context, _, accountName, shareName string, acls []shares.SignedIdentifier) error { - _, err := w.client.SetACL(ctx, accountName, shareName, acls) +func (w DataPlaneStorageShareWrapper) UpdateACLs(ctx context.Context, shareName string, input shares.SetAclInput) error { + _, err := w.client.SetACL(ctx, shareName, input) return err } -func (w DataPlaneStorageShareWrapper) UpdateMetaData(ctx context.Context, _, accountName, shareName string, metaData map[string]string) error { - _, err := w.client.SetMetaData(ctx, accountName, shareName, metaData) +func (w DataPlaneStorageShareWrapper) UpdateMetaData(ctx context.Context, shareName string, metaData map[string]string) error { + input := shares.SetMetaDataInput{ + MetaData: metaData, + } + _, err := w.client.SetMetaData(ctx, shareName, input) return err } -func (w DataPlaneStorageShareWrapper) UpdateQuota(ctx context.Context, _, accountName, shareName string, quotaGB int) error { - _, err := w.client.SetProperties(ctx, accountName, shareName, shares.ShareProperties{ +func (w DataPlaneStorageShareWrapper) UpdateQuota(ctx context.Context, shareName string, quotaGB int) error { + _, err := w.client.SetProperties(ctx, shareName, shares.ShareProperties{ QuotaInGb: "aGB, }) return err } -func (w DataPlaneStorageShareWrapper) UpdateTier(ctx context.Context, _, accountname, shareName string, tier shares.AccessTier) error { +func (w DataPlaneStorageShareWrapper) UpdateTier(ctx context.Context, shareName string, tier shares.AccessTier) error { props := shares.ShareProperties{ AccessTier: &tier, } - _, err := w.client.SetProperties(ctx, accountname, shareName, props) + _, err := w.client.SetProperties(ctx, shareName, props) return err } - -func (w DataPlaneStorageShareWrapper) createRefreshFunc(ctx context.Context, accountName string, shareName string, input shares.CreateInput) pluginsdk.StateRefreshFunc { - return func() (interface{}, string, error) { - resp, err := w.client.Create(ctx, accountName, shareName, input) - if err != nil { - if !utils.ResponseWasConflict(resp) { - return nil, "", err - } - - if utils.ResponseWasConflict(resp) && strings.Contains(err.Error(), "ShareBeingDeleted") { - return nil, "waitingOnDelete", nil - } - } - - return "succeeded", "succeeded", nil - } -} diff --git a/internal/services/storage/shim/tables.go b/internal/services/storage/shim/tables.go index f928d83fcea0..0734e971a046 100644 --- a/internal/services/storage/shim/tables.go +++ b/internal/services/storage/shim/tables.go @@ -6,13 +6,13 @@ package shim import ( "context" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) type StorageTableWrapper interface { - Create(ctx context.Context, resourceGroup string, accountName string, tableName string) error - Delete(ctx context.Context, resourceGroup string, accountName string, tableName string) error - Exists(ctx context.Context, resourceGroup string, accountName string, tableName string) (*bool, error) - GetACLs(ctx context.Context, resourceGroup string, accountName string, tableName string) (*[]tables.SignedIdentifier, error) - UpdateACLs(ctx context.Context, resourceGroup string, accountName string, tableName string, acls []tables.SignedIdentifier) error + Create(ctx context.Context, tableName string) error + Delete(ctx context.Context, tableName string) error + Exists(ctx context.Context, tableName string) (*bool, error) + GetACLs(ctx context.Context, tableName string) (*[]tables.SignedIdentifier, error) + UpdateACLs(ctx context.Context, tableName string, acls []tables.SignedIdentifier) error } diff --git a/internal/services/storage/shim/tables_data_plane.go b/internal/services/storage/shim/tables_data_plane.go index f8a998f06069..447fca894677 100644 --- a/internal/services/storage/shim/tables_data_plane.go +++ b/internal/services/storage/shim/tables_data_plane.go @@ -6,8 +6,9 @@ package shim import ( "context" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) type DataPlaneStorageTableWrapper struct { @@ -20,31 +21,29 @@ func NewDataPlaneStorageTableWrapper(client *tables.Client) StorageTableWrapper } } -func (w DataPlaneStorageTableWrapper) Create(ctx context.Context, _, accountName, tableName string) error { - _, err := w.client.Create(ctx, accountName, tableName) +func (w DataPlaneStorageTableWrapper) Create(ctx context.Context, tableName string) error { + _, err := w.client.Create(ctx, tableName) return err } -func (w DataPlaneStorageTableWrapper) Delete(ctx context.Context, _, accountName, tableName string) error { - _, err := w.client.Delete(ctx, accountName, tableName) +func (w DataPlaneStorageTableWrapper) Delete(ctx context.Context, tableName string) error { + _, err := w.client.Delete(ctx, tableName) return err } -func (w DataPlaneStorageTableWrapper) Exists(ctx context.Context, _, accountName, tableName string) (*bool, error) { - existing, err := w.client.Exists(ctx, accountName, tableName) +func (w DataPlaneStorageTableWrapper) Exists(ctx context.Context, tableName string) (*bool, error) { + existing, err := w.client.Exists(ctx, tableName) if err != nil { - if utils.ResponseWasNotFound(existing) { - return nil, nil + if response.WasNotFound(existing.HttpResponse) { + return pointer.To(false), nil } - return nil, err } - - return utils.Bool(true), nil + return pointer.To(true), nil } -func (w DataPlaneStorageTableWrapper) GetACLs(ctx context.Context, _, accountName, tableName string) (*[]tables.SignedIdentifier, error) { - acls, err := w.client.GetACL(ctx, accountName, tableName) +func (w DataPlaneStorageTableWrapper) GetACLs(ctx context.Context, tableName string) (*[]tables.SignedIdentifier, error) { + acls, err := w.client.GetACL(ctx, tableName) if err != nil { return nil, err } @@ -52,7 +51,7 @@ func (w DataPlaneStorageTableWrapper) GetACLs(ctx context.Context, _, accountNam return &acls.SignedIdentifiers, nil } -func (w DataPlaneStorageTableWrapper) UpdateACLs(ctx context.Context, _, accountName, tableName string, acls []tables.SignedIdentifier) error { - _, err := w.client.SetACL(ctx, accountName, tableName, acls) +func (w DataPlaneStorageTableWrapper) UpdateACLs(ctx context.Context, tableName string, acls []tables.SignedIdentifier) error { + _, err := w.client.SetACL(ctx, tableName, acls) return err } diff --git a/internal/services/storage/storage_account_resource.go b/internal/services/storage/storage_account_resource.go index b83c2a837e37..171bd1e8734f 100644 --- a/internal/services/storage/storage_account_resource.go +++ b/internal/services/storage/storage_account_resource.go @@ -40,8 +40,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) var ( @@ -1310,7 +1310,7 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e existing, err := client.GetProperties(ctx, id.ResourceGroupName, id.StorageAccountName, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing %s: %s", id, err) + return fmt.Errorf("checking for existing %s: %s", id, err) } } @@ -1585,16 +1585,15 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e if !supportLevel.supportQueue { return fmt.Errorf("`queue_properties` aren't supported for account kind %q in sku tier %q", accountKind, accountTier) } - storageClient := meta.(*clients.Client).Storage - account, err := storageClient.FindAccount(ctx, id.StorageAccountName) + accountDetails, err := storageClient.FindAccount(ctx, id.StorageAccountName) if err != nil { return fmt.Errorf("retrieving %s: %+v", id, err) } - if account == nil { + if accountDetails == nil { return fmt.Errorf("unable to locate %q", id) } - queueClient, err := storageClient.QueuesClient(ctx, *account) + queueClient, err := storageClient.QueuesDataPlaneClient(ctx, *accountDetails, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Queues Client: %s", err) } @@ -1604,7 +1603,7 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("expanding `queue_properties`: %+v", err) } - if err = queueClient.UpdateServiceProperties(ctx, id.ResourceGroupName, id.StorageAccountName, queueProperties); err != nil { + if err = queueClient.UpdateServiceProperties(ctx, queueProperties); err != nil { return fmt.Errorf("updating Queue Properties: %+v", err) } } @@ -1641,7 +1640,6 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e if !supportLevel.supportStaticWebsite { return fmt.Errorf("`static_website` aren't supported for account kind %q in sku tier %q", accountKind, accountTier) } - storageClient := meta.(*clients.Client).Storage account, err := storageClient.FindAccount(ctx, id.StorageAccountName) if err != nil { @@ -1651,7 +1649,7 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("unable to locate %s", id) } - accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account) + accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Accounts Data Plane Client: %s", err) } @@ -1689,7 +1687,7 @@ func resourceStorageAccountUpdate(d *pluginsdk.ResourceData, meta interface{}) e if accountKind == string(storage.KindBlobStorage) || accountKind == string(storage.KindStorage) { if storageType == string(storage.SkuNameStandardZRS) { - return fmt.Errorf("a `account_replication_type` of `ZRS` isn't supported for Blob Storage accounts") + return fmt.Errorf("an `account_replication_type` of `ZRS` isn't supported for Blob Storage accounts") } } @@ -1957,7 +1955,7 @@ func resourceStorageAccountUpdate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("unable to locate %s", *id) } - queueClient, err := storageClient.QueuesClient(ctx, *account) + queueClient, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Queues Client: %s", err) } @@ -1967,7 +1965,7 @@ func resourceStorageAccountUpdate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("expanding `queue_properties` for %s: %+v", *id, err) } - if err = queueClient.UpdateServiceProperties(ctx, account.ResourceGroup, id.StorageAccountName, queueProperties); err != nil { + if err = queueClient.UpdateServiceProperties(ctx, queueProperties); err != nil { return fmt.Errorf("updating Queue Properties for %s: %+v", *id, err) } } @@ -2012,7 +2010,7 @@ func resourceStorageAccountUpdate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("unable to locate %s", *id) } - accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account) + accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Data Plane client for %s: %+v", *id, err) } @@ -2298,12 +2296,12 @@ func resourceStorageAccountRead(d *pluginsdk.ResourceData, meta interface{}) err } if supportLevel.supportQueue { - queueClient, err := storageClient.QueuesClient(ctx, *account) + queueClient, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Queues Client: %s", err) } - queueProps, err := queueClient.GetServiceProperties(ctx, id.ResourceGroupName, id.StorageAccountName) + queueProps, err := queueClient.GetServiceProperties(ctx) if err != nil { return fmt.Errorf("retrieving queue properties for %s: %+v", *id, err) } @@ -2327,13 +2325,7 @@ func resourceStorageAccountRead(d *pluginsdk.ResourceData, meta interface{}) err } if supportLevel.supportStaticWebsite { - storageClient := meta.(*clients.Client).Storage - account, err := storageClient.FindAccount(ctx, id.StorageAccountName) - if err != nil { - return fmt.Errorf("retrieving %s: %+v", *id, err) - } - - accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account) + accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Accounts Data Plane Client: %s", err) } @@ -3628,18 +3620,16 @@ func flattenedSharePropertiesSMB(input *storage.SmbSetting) []interface{} { } func flattenStaticWebsiteProperties(input accounts.GetServicePropertiesResult) []interface{} { - if storageServiceProps := input.StorageServiceProperties; storageServiceProps != nil { - if staticWebsite := storageServiceProps.StaticWebsite; staticWebsite != nil { - if !staticWebsite.Enabled { - return []interface{}{} - } + if staticWebsite := input.StaticWebsite; staticWebsite != nil { + if !staticWebsite.Enabled { + return []interface{}{} + } - return []interface{}{ - map[string]interface{}{ - "index_document": staticWebsite.IndexDocument, - "error_404_document": staticWebsite.ErrorDocument404Path, - }, - } + return []interface{}{ + map[string]interface{}{ + "index_document": staticWebsite.IndexDocument, + "error_404_document": staticWebsite.ErrorDocument404Path, + }, } } return []interface{}{} diff --git a/internal/services/storage/storage_blob_data_source.go b/internal/services/storage/storage_blob_data_source.go index cbe1c2a1b655..314284c5b298 100644 --- a/internal/services/storage/storage_blob_data_source.go +++ b/internal/services/storage/storage_blob_data_source.go @@ -9,11 +9,12 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) func dataSourceStorageBlob() *pluginsdk.Resource { @@ -82,28 +83,33 @@ func dataSourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) erro account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", accountName, name, containerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %v", accountName, name, containerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } - id := blobsClient.GetResourceID(accountName, containerName, name) + accountId, err := accounts.ParseAccountID(accountName, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := blobs.NewBlobID(*accountId, containerName, name) - log.Printf("[INFO] Retrieving Storage Blob %q (Container %q / Account %q).", name, containerName, accountName) + log.Printf("[INFO] Retrieving %s", id) input := blobs.GetPropertiesInput{} - props, err := blobsClient.GetProperties(ctx, accountName, containerName, name, input) + props, err := blobsClient.GetProperties(ctx, containerName, name, input) if err != nil { - if utils.ResponseWasNotFound(props.Response) { - return fmt.Errorf("the Blob %q was not found in Container %q / Account %q", name, containerName, accountName) + if response.WasNotFound(props.HttpResponse) { + return fmt.Errorf("%s was not found", id) } - return fmt.Errorf("retrieving properties for Blob %q (Container %q / Account %q): %s", name, containerName, accountName, err) + return fmt.Errorf("retrieving properties for %s: %v", id, err) } d.Set("name", name) @@ -125,9 +131,9 @@ func dataSourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) erro d.Set("type", strings.TrimSuffix(string(props.BlobType), "Blob")) - d.SetId(id) + d.SetId(id.ID()) - d.Set("url", id) + d.Set("url", id.ID()) if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { return fmt.Errorf("setting `metadata`: %+v", err) diff --git a/internal/services/storage/storage_blob_resource.go b/internal/services/storage/storage_blob_resource.go index d7e5e837a012..bc75137f6ac0 100644 --- a/internal/services/storage/storage_blob_resource.go +++ b/internal/services/storage/storage_blob_resource.go @@ -10,15 +10,18 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) func resourceStorageBlob() *pluginsdk.Resource { @@ -33,8 +36,8 @@ func resourceStorageBlob() *pluginsdk.Resource { 0: migration.BlobV0ToV1{}, }), - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := blobs.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := blobs.ParseBlobID(id, storageDomainSuffix) return err }), @@ -47,10 +50,10 @@ func resourceStorageBlob() *pluginsdk.Resource { Schema: map[string]*pluginsdk.Schema{ "name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - // TODO: add validation + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, }, "storage_account_name": { @@ -175,28 +178,34 @@ func resourceStorageBlobCreate(d *pluginsdk.ResourceData, meta interface{}) erro account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", accountName, name, containerName, err) + return fmt.Errorf("retrieving Storage Account %q for Blob %q (Container %q): %v", accountName, name, containerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) + } + + accountId := accounts.AccountId{ + AccountName: accountName, + DomainSuffix: storageClient.StorageDomainSuffix, + SubDomainType: accounts.BlobSubDomainType, } - id := blobsClient.GetResourceID(accountName, containerName, name) + id := blobs.NewBlobID(accountId, containerName, name) if d.IsNewResource() { input := blobs.GetPropertiesInput{} - props, err := blobsClient.GetProperties(ctx, accountName, containerName, name, input) + props, err := blobsClient.GetProperties(ctx, containerName, name, input) if err != nil { - if !utils.ResponseWasNotFound(props.Response) { - return fmt.Errorf("checking if Blob %q exists (Container %q / Account %q / Resource Group %q): %s", name, containerName, accountName, account.ResourceGroup, err) + if !response.WasNotFound(props.HttpResponse) { + return fmt.Errorf("checking for existing %s: %v", id, err) } } - if !utils.ResponseWasNotFound(props.Response) { - return tf.ImportAsExistsError("azurerm_storage_blob", id) + if !response.WasNotFound(props.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_blob", id.ID()) } } @@ -210,7 +219,7 @@ func resourceStorageBlobCreate(d *pluginsdk.ResourceData, meta interface{}) erro } } - log.Printf("[DEBUG] Creating Blob %q in Container %q within Storage Account %q..", name, containerName, accountName) + log.Printf("[DEBUG] Creating %s..", id) metaDataRaw := d.Get("metadata").(map[string]interface{}) blobInput := BlobUpload{ AccountName: accountName, @@ -229,12 +238,12 @@ func resourceStorageBlobCreate(d *pluginsdk.ResourceData, meta interface{}) erro SourceContent: d.Get("source_content").(string), SourceUri: d.Get("source_uri").(string), } - if err := blobInput.Create(ctx); err != nil { - return fmt.Errorf("creating Blob %q (Container %q / Account %q): %s", name, containerName, accountName, err) + if err = blobInput.Create(ctx); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - log.Printf("[DEBUG] Created Blob %q in Container %q within Storage Account %q.", name, containerName, accountName) + log.Printf("[DEBUG] Created %s.", id) - d.SetId(id) + d.SetId(id.ID()) return resourceStorageBlobUpdate(d, meta) } @@ -244,69 +253,69 @@ func resourceStorageBlobUpdate(d *pluginsdk.ResourceData, meta interface{}) erro ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := blobs.ParseResourceID(d.Id()) + id, err := blobs.ParseBlobID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("parsing %q: %s", d.Id(), err) + return fmt.Errorf("parsing %q: %v", d.Id(), err) } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountName, id.BlobName, id.ContainerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %v", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } if d.HasChange("content_type") || d.HasChange("cache_control") { - log.Printf("[DEBUG] Updating Properties for Blob %q (Container %q / Account %q)...", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updating Properties for %s...", id) input := blobs.SetPropertiesInput{ ContentType: utils.String(d.Get("content_type").(string)), CacheControl: utils.String(d.Get("cache_control").(string)), } - // `content_md5` is `ForceNew` but must be included in the `SetPropertiesInput` update payload or it will be zeroed on the blob. + // `content_md5` is `ForceNew` but must be included in the `SetPropertiesInput` update payload, or it will be zeroed on the blob. if contentMD5 := d.Get("content_md5").(string); contentMD5 != "" { data, err := convertHexToBase64Encoding(contentMD5) if err != nil { - return fmt.Errorf("in converting hex to base64 encoding for content_md5: %s", err) + return fmt.Errorf("converting hex to base64 encoding for content_md5: %v", err) } input.ContentMD5 = utils.String(data) } - if _, err := blobsClient.SetProperties(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return fmt.Errorf("updating Properties for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err = blobsClient.SetProperties(ctx, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("updating Properties for %s: %v", id, err) } - log.Printf("[DEBUG] Updated Properties for Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updated Properties for %s", id) } if d.HasChange("metadata") { - log.Printf("[DEBUG] Updating MetaData for Blob %q (Container %q / Account %q)...", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updating MetaData for %s...", id) metaDataRaw := d.Get("metadata").(map[string]interface{}) input := blobs.SetMetaDataInput{ MetaData: ExpandMetaData(metaDataRaw), } - if _, err := blobsClient.SetMetaData(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return fmt.Errorf("updating MetaData for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err = blobsClient.SetMetaData(ctx, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("updating MetaData for %s: %v", id, err) } - log.Printf("[DEBUG] Updated MetaData for Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updated MetaData for %s", id) } if d.HasChange("access_tier") { // this is only applicable for Gen2/BlobStorage accounts - log.Printf("[DEBUG] Updating Access Tier for Blob %q (Container %q / Account %q)...", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updating Access Tier for %s...", id) accessTier := blobs.AccessTier(d.Get("access_tier").(string)) - if _, err := blobsClient.SetTier(ctx, id.AccountName, id.ContainerName, id.BlobName, accessTier); err != nil { - return fmt.Errorf("updating Access Tier for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err := blobsClient.SetTier(ctx, id.ContainerName, id.BlobName, blobs.SetTierInput{Tier: accessTier}); err != nil { + return fmt.Errorf("updating Access Tier for %s: %v", id, err) } - log.Printf("[DEBUG] Updated Access Tier for Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updated Access Tier for %s", id) } return resourceStorageBlobRead(d, meta) @@ -317,42 +326,42 @@ func resourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) error ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := blobs.ParseResourceID(d.Id()) + id, err := blobs.ParseBlobID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("parsing %q: %s", d.Id(), err) + return fmt.Errorf("parsing %q: %v", d.Id(), err) } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountName, id.BlobName, id.ContainerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %v", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } if account == nil { - log.Printf("[DEBUG] Unable to locate Account %q for Blob %q (Container %q) - assuming removed & removing from state!", id.AccountName, id.BlobName, id.ContainerName) + log.Printf("[DEBUG] Unable to locate Account %q for Blob %q (Container %q) - assuming removed & removing from state!", id.AccountId.AccountName, id.BlobName, id.ContainerName) d.SetId("") return nil } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } - log.Printf("[INFO] Retrieving Storage Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[INFO] Retrieving %s", id) input := blobs.GetPropertiesInput{} - props, err := blobsClient.GetProperties(ctx, id.AccountName, id.ContainerName, id.BlobName, input) + props, err := blobsClient.GetProperties(ctx, id.ContainerName, id.BlobName, input) if err != nil { - if utils.ResponseWasNotFound(props.Response) { - log.Printf("[INFO] Blob %q was not found in Container %q / Account %q - assuming removed & removing from state...", id.BlobName, id.ContainerName, id.AccountName) + if response.WasNotFound(props.HttpResponse) { + log.Printf("[INFO] Blob %q was not found in Container %q / Account %q - assuming removed & removing from state...", id.BlobName, id.ContainerName, id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("retrieving properties for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + return fmt.Errorf("retrieving properties for %s: %v", id, err) } d.Set("name", id.BlobName) d.Set("storage_container_name", id.ContainerName) - d.Set("storage_account_name", id.AccountName) + d.Set("storage_account_name", id.AccountId.AccountName) d.Set("access_tier", string(props.AccessTier)) d.Set("content_type", props.ContentType) @@ -363,7 +372,7 @@ func resourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) error if props.ContentMD5 != "" { contentMD5, err = convertBase64ToHexEncoding(props.ContentMD5) if err != nil { - return fmt.Errorf("in converting hex to base64 encoding for content_md5: %s", err) + return fmt.Errorf("converting hex to base64 encoding for content_md5: %v", err) } } d.Set("content_md5", contentMD5) @@ -371,8 +380,8 @@ func resourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) error d.Set("type", strings.TrimSuffix(string(props.BlobType), "Blob")) d.Set("url", d.Id()) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %+v", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } // The CopySource is only returned if the blob hasn't been modified (e.g. metadata configured etc) // as such, we need to conditionally set this to ensure it's trackable if possible @@ -388,30 +397,29 @@ func resourceStorageBlobDelete(d *pluginsdk.ResourceData, meta interface{}) erro ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := blobs.ParseResourceID(d.Id()) + id, err := blobs.ParseBlobID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("parsing %q: %s", d.Id(), err) + return fmt.Errorf("parsing %q: %v", d.Id(), err) } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountName, id.BlobName, id.ContainerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } - log.Printf("[INFO] Deleting Blob %q from Container %q / Storage Account %q", id.BlobName, id.ContainerName, id.AccountName) input := blobs.DeleteInput{ DeleteSnapshots: true, } - if _, err := blobsClient.Delete(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return fmt.Errorf("deleting Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err = blobsClient.Delete(ctx, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_blob_resource_test.go b/internal/services/storage/storage_blob_resource_test.go index 8f050af524f5..9a0c6d3b2ba3 100644 --- a/internal/services/storage/storage_blob_resource_test.go +++ b/internal/services/storage/storage_blob_resource_test.go @@ -10,13 +10,15 @@ import ( "os" "regexp" "testing" + "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) type StorageBlobResource struct{} @@ -469,56 +471,62 @@ func TestAccStorageBlob_archive(t *testing.T) { } func (r StorageBlobResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := blobs.ParseResourceID(state.ID) + id, err := blobs.ParseBlobID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { return nil, err } if account == nil { - return nil, fmt.Errorf("unable to locate Account %q for Blob %q (Container %q)", id.AccountName, id.BlobName, id.ContainerName) + return nil, fmt.Errorf("unable to locate Account %q for Blob %q (Container %q)", id.AccountId.AccountName, id.BlobName, id.ContainerName) } - blobsClient, err := client.Storage.BlobsClient(ctx, *account) + blobsClient, err := client.Storage.BlobsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Blobs Client: %+v", err) } input := blobs.GetPropertiesInput{} - resp, err := blobsClient.GetProperties(ctx, id.AccountName, id.ContainerName, id.BlobName, input) + resp, err := blobsClient.GetProperties(ctx, id.ContainerName, id.BlobName, input) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving Blob %q (Container %q / Account %q): %+v", id.BlobName, id.ContainerName, id.AccountName, err) + return nil, fmt.Errorf("retrieving Blob %q (Container %q / Account %q): %+v", id.BlobName, id.ContainerName, id.AccountId.AccountName, err) } return utils.Bool(true), nil } func (r StorageBlobResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := blobs.ParseResourceID(state.ID) + id, err := blobs.ParseBlobID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrievign Account %q for Blob %q (Container %q): %+v", id.AccountName, id.BlobName, id.ContainerName, err) + return nil, fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %+v", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } - blobsClient, err := client.Storage.BlobsClient(ctx, *account) + blobsClient, err := client.Storage.BlobsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Blobs Client: %+v", err) } input := blobs.DeleteInput{ DeleteSnapshots: false, } - if _, err := blobsClient.Delete(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return nil, fmt.Errorf("deleting Blob %q (Container %q / Account %q): %+v", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err = blobsClient.Delete(ctx, id.ContainerName, id.BlobName, input); err != nil { + return nil, fmt.Errorf("deleting Blob %q (Container %q / Account %q): %+v", id.BlobName, id.ContainerName, id.AccountId.AccountName, err) } return utils.Bool(true), nil } func (r StorageBlobResource) blobMatchesFile(kind blobs.BlobType, filePath string) func(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) error { return func(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) error { + if _, ok := ctx.Deadline(); !ok { + var cancel context.CancelFunc + ctx, cancel = context.WithDeadline(ctx, time.Now().Add(10*time.Minute)) + defer cancel() + } + name := state.Attributes["name"] containerName := state.Attributes["storage_container_name"] accountName := state.Attributes["storage_account_name"] @@ -531,14 +539,14 @@ func (r StorageBlobResource) blobMatchesFile(kind blobs.BlobType, filePath strin return fmt.Errorf("Unable to locate Storage Account %q!", accountName) } - client, err := clients.Storage.BlobsClient(ctx, *account) + client, err := clients.Storage.BlobsDataPlaneClient(ctx, *account, clients.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Blobs Client: %s", err) } // first check the type getPropsInput := blobs.GetPropertiesInput{} - props, err := client.GetProperties(ctx, accountName, containerName, name, getPropsInput) + props, err := client.GetProperties(ctx, containerName, name, getPropsInput) if err != nil { return fmt.Errorf("retrieving Properties for Blob %q (Container %q): %s", name, containerName, err) } @@ -549,20 +557,24 @@ func (r StorageBlobResource) blobMatchesFile(kind blobs.BlobType, filePath strin // then compare the content itself getInput := blobs.GetInput{} - actualProps, err := client.Get(ctx, accountName, containerName, name, getInput) + actualProps, err := client.Get(ctx, containerName, name, getInput) if err != nil { return fmt.Errorf("retrieving Blob %q (Container %q): %s", name, containerName, err) } actualContents := actualProps.Contents + if actualContents == nil { + return fmt.Errorf("Bad: Storage Blob %q (storage container: %q) returned nil contents", name, containerName) + } + // local file for comparison expectedContents, err := os.ReadFile(filePath) if err != nil { return err } - if string(actualContents) != string(expectedContents) { + if string(*actualContents) != string(expectedContents) { return fmt.Errorf("Bad: Storage Blob %q (storage container: %q) does not match contents", name, containerName) } diff --git a/internal/services/storage/storage_container_data_source.go b/internal/services/storage/storage_container_data_source.go index dc7a74da8ef0..30e99688f495 100644 --- a/internal/services/storage/storage_container_data_source.go +++ b/internal/services/storage/storage_container_data_source.go @@ -9,9 +9,11 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) func dataSourceStorageContainer() *pluginsdk.Resource { @@ -69,34 +71,47 @@ func dataSourceStorageContainerRead(d *pluginsdk.ResourceData, meta interface{}) account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", accountName, containerName, err) + return fmt.Errorf("retrieving Storage Account %q for Container %q: %v", accountName, containerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Account %q for Storage Container %q", accountName, containerName) + return fmt.Errorf("locating Storage Account %q for Container %q", accountName, containerName) } - client, err := storageClient.ContainersClient(ctx, *account) + containersDataPlaneClient, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Containers Client for Storage Account %q (Resource Group %q): %s", accountName, account.ResourceGroup, err) + return fmt.Errorf("building Containers Client: %v", err) } - id := parse.NewStorageContainerDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, containerName).ID() - d.SetId(id) + // Determine the blob endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeBlob) + if err != nil { + return fmt.Errorf("determining Blob endpoint: %v", err) + } - props, err := client.Get(ctx, account.ResourceGroup, accountName, containerName) + // Parse the blob endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("retrieving Container %q (Account %q / Resource Group %q): %s", containerName, accountName, account.ResourceGroup, err) + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := containers.NewContainerID(*accountId, containerName) + + props, err := containersDataPlaneClient.Get(ctx, containerName) + if err != nil { + return fmt.Errorf("retrieving %s: %v", id, err) } if props == nil { - return fmt.Errorf("Container %q was not found in Account %q / Resource Group %q", containerName, accountName, account.ResourceGroup) + return fmt.Errorf("retrieving %s: result was nil", id) } + d.SetId(id.ID()) + d.Set("name", containerName) d.Set("storage_account_name", accountName) d.Set("container_access_type", flattenStorageContainerAccessLevel(props.AccessLevel)) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %+v", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } d.Set("has_immutability_policy", props.HasImmutabilityPolicy) diff --git a/internal/services/storage/storage_container_resource.go b/internal/services/storage/storage_container_resource.go index c4dc99de623e..bf1db305ad27 100644 --- a/internal/services/storage/storage_container_resource.go +++ b/internal/services/storage/storage_container_resource.go @@ -11,13 +11,15 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) func resourceStorageContainer() *pluginsdk.Resource { @@ -27,8 +29,8 @@ func resourceStorageContainer() *pluginsdk.Resource { Delete: resourceStorageContainerDelete, Update: resourceStorageContainerUpdate, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.StorageContainerDataPlaneID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := containers.ParseContainerID(id, storageDomainSuffix) return err }), @@ -106,37 +108,51 @@ func resourceStorageContainerCreate(d *pluginsdk.ResourceData, meta interface{}) account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", accountName, containerName, err) + return fmt.Errorf("retrieving Account %q for Container %q: %v", accountName, containerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - client, err := storageClient.ContainersClient(ctx, *account) + containersDataPlaneClient, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building storage client: %+v", err) + return fmt.Errorf("building storage client: %v", err) } - id := parse.NewStorageContainerDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, containerName).ID() - exists, err := client.Exists(ctx, account.ResourceGroup, accountName, containerName) + // Determine the blob endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeBlob) if err != nil { - return err + return fmt.Errorf("determining Blob endpoint: %v", err) + } + + // Parse the blob endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := containers.NewContainerID(*accountId, containerName) + + exists, err := containersDataPlaneClient.Exists(ctx, containerName) + if err != nil { + return fmt.Errorf("checking for existing %s: %v", id, err) } if exists != nil && *exists { - return tf.ImportAsExistsError("azurerm_storage_container", id) + return tf.ImportAsExistsError("azurerm_storage_container", id.ID()) } - log.Printf("[INFO] Creating Container %q in Storage Account %q", containerName, accountName) + log.Printf("[INFO] Creating %s", id) input := containers.CreateInput{ AccessLevel: accessLevel, MetaData: metaData, } - if err := client.Create(ctx, account.ResourceGroup, accountName, containerName, input); err != nil { - return fmt.Errorf("failed creating container: %+v", err) + if err = containersDataPlaneClient.Create(ctx, containerName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - d.SetId(id) + d.SetId(id.ID()) + return resourceStorageContainerRead(d, meta) } @@ -145,45 +161,54 @@ func resourceStorageContainerUpdate(d *pluginsdk.ResourceData, meta interface{}) ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageContainerDataPlaneID(d.Id()) + id, err := containers.ParseContainerID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Container %q: %v", id.AccountId.AccountName, id.ContainerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) - } - client, err := storageClient.ContainersClient(ctx, *account) - if err != nil { - return fmt.Errorf("building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } if d.HasChange("container_access_type") { - log.Printf("[DEBUG] Updating the Access Control for Container %q (Storage Account %q / Resource Group %q)..", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Updating Access Level for %s...", id) + + // Updating metadata does not work with AAD authentication, returns a cryptic 404 + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) + if err != nil { + return fmt.Errorf("building Containers Client: %v", err) + } + accessLevelRaw := d.Get("container_access_type").(string) accessLevel := expandStorageContainerAccessLevel(accessLevelRaw) - if err := client.UpdateAccessLevel(ctx, account.ResourceGroup, id.AccountName, id.Name, accessLevel); err != nil { - return fmt.Errorf("updating the Access Control for Container %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + if err = client.UpdateAccessLevel(ctx, id.ContainerName, accessLevel); err != nil { + return fmt.Errorf("updating Access Level for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the Access Control for Container %q (Storage Account %q / Resource Group %q)", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Updated Access Level for %s", id) } if d.HasChange("metadata") { - log.Printf("[DEBUG] Updating the MetaData for Container %q (Storage Account %q / Resource Group %q)..", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Updating Metadata for %s...", id) + + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Containers Client: %v", err) + } + metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - if err := client.UpdateMetaData(ctx, account.ResourceGroup, id.AccountName, id.Name, metaData); err != nil { - return fmt.Errorf("updating the MetaData for Container %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + if err = client.UpdateMetaData(ctx, id.ContainerName, metaData); err != nil { + return fmt.Errorf("updating Metadata for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the MetaData for Container %q (Storage Account %q / Resource Group %q)", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Updated Metadata for %s", id) } return resourceStorageContainerRead(d, meta) @@ -195,48 +220,49 @@ func resourceStorageContainerRead(d *pluginsdk.ResourceData, meta interface{}) e ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageContainerDataPlaneID(d.Id()) + id, err := containers.ParseContainerID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Container %q: %v", id.AccountId.AccountName, id.ContainerName, err) } if account == nil { - log.Printf("[DEBUG] Unable to locate Account %q for Storage Container %q - assuming removed & removing from state", id.AccountName, id.Name) + log.Printf("[DEBUG] Unable to locate Account %q for Storage Container %q - assuming removed & removing from state", id.AccountId.AccountName, id.ContainerName) d.SetId("") return nil } - client, err := storageClient.ContainersClient(ctx, *account) + + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building Containers Client: %v", err) } - props, err := client.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + props, err := client.Get(ctx, id.ContainerName) if err != nil { - return fmt.Errorf("retrieving Container %q (Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if props == nil { - log.Printf("[DEBUG] Container %q was not found in Account %q / Resource Group %q - assuming removed & removing from state", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Container %q was not found in Account %q / Resource Group %q - assuming removed & removing from state", id.ContainerName, id.AccountId.AccountName, account.ResourceGroup) d.SetId("") return nil } - d.Set("name", id.Name) - d.Set("storage_account_name", id.AccountName) + d.Set("name", id.ContainerName) + d.Set("storage_account_name", id.AccountId.AccountName) d.Set("container_access_type", flattenStorageContainerAccessLevel(props.AccessLevel)) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %+v", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } d.Set("has_immutability_policy", props.HasImmutabilityPolicy) d.Set("has_legal_hold", props.HasLegalHold) - resourceManagerId := commonids.NewStorageContainerID(subscriptionId, account.ResourceGroup, id.AccountName, id.Name) + resourceManagerId := commonids.NewStorageContainerID(subscriptionId, account.ResourceGroup, id.AccountId.AccountName, id.ContainerName) d.Set("resource_manager_id", resourceManagerId.ID()) return nil @@ -247,25 +273,26 @@ func resourceStorageContainerDelete(d *pluginsdk.ResourceData, meta interface{}) ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageContainerDataPlaneID(d.Id()) + id, err := containers.ParseContainerID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Container %q: %v", id.AccountId.AccountName, id.ContainerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.ContainersClient(ctx, *account) + + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building Containers Client: %v", err) } - if err := client.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return fmt.Errorf("deleting Container %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + if err = client.Delete(ctx, id.ContainerName); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_container_resource_test.go b/internal/services/storage/storage_container_resource_test.go index cf0a8c0ae07b..623ac0ca36b5 100644 --- a/internal/services/storage/storage_container_resource_test.go +++ b/internal/services/storage/storage_container_resource_test.go @@ -12,10 +12,10 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) type StorageContainerResource struct{} @@ -96,14 +96,14 @@ func TestAccStorageContainer_update(t *testing.T) { data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.update(data, "private"), + Config: r.update(data, "private", "yes"), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("container_access_type").HasValue("private"), ), }, { - Config: r.update(data, "container"), + Config: r.update(data, "container", "no"), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("container_access_type").HasValue("container"), @@ -187,48 +187,55 @@ func TestAccStorageContainer_web(t *testing.T) { } func (r StorageContainerResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageContainerDataPlaneID(state.ID) + id, err := containers.ParseContainerID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Container %q: %+v", id.AccountName, id.Name, err) + return nil, fmt.Errorf("retrieving Account %q for Container %q: %+v", id.AccountId.AccountName, id.ContainerName, err) } if account == nil { - return nil, fmt.Errorf("unable to locate Storage Account %q", id.AccountName) + return nil, fmt.Errorf("unable to locate Storage Account %q", id.AccountId.AccountName) } - containersClient, err := client.Storage.ContainersClient(ctx, *account) + containersClient, err := client.Storage.ContainersDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Containers Client: %+v", err) } - prop, err := containersClient.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + + prop, err := containersClient.Get(ctx, id.ContainerName) if err != nil { - return nil, fmt.Errorf("retrieving Container %q (Account %q / Resource Group %q): %+v", id.Name, id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("retrieving Container %q (Account %q / Resource Group %q): %+v", id.ContainerName, id.AccountId.AccountName, account.ResourceGroup, err) } + return utils.Bool(prop != nil), nil } func (r StorageContainerResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageContainerDataPlaneID(state.ID) + id, err := containers.ParseContainerID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Container %q: %+v", id.AccountName, id.Name, err) + return nil, fmt.Errorf("retrieving Account %q for Container %q: %+v", id.AccountId.AccountName, id.ContainerName, err) } if account == nil { - return nil, fmt.Errorf("unable to locate Storage Account %q", id.AccountName) + return nil, fmt.Errorf("unable to locate Storage Account %q", id.AccountId.AccountName) } - containersClient, err := client.Storage.ContainersClient(ctx, *account) + + containersClient, err := client.Storage.ContainersDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Containers Client: %+v", err) } - if err := containersClient.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return nil, fmt.Errorf("deleting Container %q (Account %q / Resource Group %q): %+v", id.Name, id.AccountName, account.ResourceGroup, err) + + if err = containersClient.Delete(ctx, id.ContainerName); err != nil { + return nil, fmt.Errorf("deleting Container %q (Account %q / Resource Group %q): %+v", id.ContainerName, id.AccountId.AccountName, account.ResourceGroup, err) } + return utils.Bool(true), nil } @@ -290,7 +297,7 @@ resource "azurerm_storage_container" "import" { `, template) } -func (r StorageContainerResource) update(data acceptance.TestData, accessType string) string { +func (r StorageContainerResource) update(data acceptance.TestData, accessType, metadataVal string) string { template := r.template(data) return fmt.Sprintf(` %s @@ -299,8 +306,12 @@ resource "azurerm_storage_container" "test" { name = "vhds" storage_account_name = azurerm_storage_account.test.name container_access_type = "%s" + metadata = { + foo = "bar" + test = "%s" + } } -`, template, accessType) +`, template, accessType, metadataVal) } func (r StorageContainerResource) metaData(data acceptance.TestData) string { diff --git a/internal/services/storage/storage_containers_data_source.go b/internal/services/storage/storage_containers_data_source.go index 40c5ec7ff49a..05d62feac9b2 100644 --- a/internal/services/storage/storage_containers_data_source.go +++ b/internal/services/storage/storage_containers_data_source.go @@ -12,9 +12,11 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/go-azure-sdk/resource-manager/storage/2023-01-01/blobcontainers" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) type storageContainersDataSource struct{} @@ -86,7 +88,7 @@ func (r storageContainersDataSource) Read() sdk.ResourceFunc { Timeout: 5 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - client := metadata.Client.Storage.ResourceManager.BlobContainers + blobContainersClient := metadata.Client.Storage.ResourceManager.BlobContainers var plan storageContainersDataSourceModel if err := metadata.Decode(&plan); err != nil { @@ -98,12 +100,32 @@ func (r storageContainersDataSource) Read() sdk.ResourceFunc { return err } - resp, err := client.ListCompleteMatchingPredicate(ctx, *id, blobcontainers.DefaultListOperationOptions(), blobcontainers.ListContainerItemOperationPredicate{}) + account, err := metadata.Client.Storage.FindAccount(ctx, id.StorageAccountName) + if err != nil { + return fmt.Errorf("retrieving Storage Account %q: %v", id.StorageAccountName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", id.StorageAccountName) + } + + // Determine the blob endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeBlob) + if err != nil { + return fmt.Errorf("determining Blob endpoint: %v", err) + } + + // Parse the blob endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, metadata.Client.Storage.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + resp, err := blobContainersClient.ListCompleteMatchingPredicate(ctx, *id, blobcontainers.DefaultListOperationOptions(), blobcontainers.ListContainerItemOperationPredicate{}) if err != nil { return fmt.Errorf("retrieving %s: %+v", id, err) } - plan.Containers = flattenStorageContainersContainers(resp.Items, id.StorageAccountName, metadata.Client.Storage.Environment.StorageEndpointSuffix, plan.NamePrefix) + plan.Containers = flattenStorageContainersContainers(resp.Items, *accountId, plan.NamePrefix) if err := metadata.Encode(&plan); err != nil { return fmt.Errorf("encoding %s: %+v", id, err) @@ -116,7 +138,7 @@ func (r storageContainersDataSource) Read() sdk.ResourceFunc { } } -func flattenStorageContainersContainers(l []blobcontainers.ListContainerItem, accountName, endpointSuffix, prefix string) []containerModel { +func flattenStorageContainersContainers(l []blobcontainers.ListContainerItem, accountId accounts.AccountId, prefix string) []containerModel { var output []containerModel for _, item := range l { var name string @@ -136,7 +158,7 @@ func flattenStorageContainersContainers(l []blobcontainers.ListContainerItem, ac output = append(output, containerModel{ Name: name, ResourceManagerId: mgmtId, - DataPlaneId: parse.NewStorageContainerDataPlaneId(accountName, endpointSuffix, name).ID(), + DataPlaneId: containers.NewContainerID(accountId, name).ID(), }) } diff --git a/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go b/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go index 4998f22fc693..a6dc171ee183 100644 --- a/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go +++ b/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go @@ -10,16 +10,19 @@ import ( "regexp" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths" "github.com/tombuildsstuff/giovanni/storage/accesscontrol" ) @@ -30,23 +33,24 @@ func resourceStorageDataLakeGen2FileSystem() *pluginsdk.Resource { Update: resourceStorageDataLakeGen2FileSystemUpdate, Delete: resourceStorageDataLakeGen2FileSystemDelete, - Importer: pluginsdk.ImporterValidatingResourceIdThen(func(id string) error { - _, err := filesystems.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceIdThen(func(id, storageDomainSuffix string) error { + _, err := filesystems.ParseFileSystemID(id, storageDomainSuffix) return err }, func(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) ([]*pluginsdk.ResourceData, error) { - storageClients := meta.(*clients.Client).Storage - id, err := filesystems.ParseResourceID(d.Id()) + storageClient := meta.(*clients.Client).Storage + + id, err := filesystems.ParseFileSystemID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return []*pluginsdk.ResourceData{d}, fmt.Errorf("parsing ID %q for import of Data Lake Gen2 File System: %v", d.Id(), err) } // we then need to look up the Storage Account ID - account, err := storageClients.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving Account %q for Data Lake Gen2 File System %q: %s", id.AccountName, id.DirectoryName, err) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving Account %q for Data Lake Gen2 File System %q: %s", id.AccountId.AccountName, id.FileSystemName, err) } if account == nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("unable to locate Storage Account: %q", id.AccountId.AccountName) } d.Set("storage_account_id", account.ID) @@ -127,62 +131,84 @@ func resourceStorageDataLakeGen2FileSystem() *pluginsdk.Resource { } func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.FileSystemsClient - pathClient := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) defer cancel() - storageID, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + filesystemName := d.Get("name").(string) + + // Parse the storage_account_id which is a resource manager ID + accountResourceManagerId, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) if err != nil { return err } - aceRaw := d.Get("ace").(*pluginsdk.Set).List() - acl, err := ExpandDataLakeGen2AceList(aceRaw) + // Confirm the storage account exists and retrieve its properties + account, err := storageClient.FindAccount(ctx, accountResourceManagerId.StorageAccountName) if err != nil { - return fmt.Errorf("parsing ace list: %s", err) + return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", accountResourceManagerId.StorageAccountName, filesystemName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", accountResourceManagerId.StorageAccountName) } - // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageID.ResourceGroupName, storageID.StorageAccountName, "") + // Build the data plane clients + dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - if utils.ResponseWasNotFound(storageAccount.Response) { - return fmt.Errorf("%s was not found", storageID) - } + return fmt.Errorf("building Data Lake Filesystems Client: %v", err) + } + dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Data Lake Paths Client: %v", err) + } - return fmt.Errorf("checking for existence of %s: %+v", storageID, err) + // Determine the dfs endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeDfs) + if err != nil { + return fmt.Errorf("determining Data Lake Filesystems endpoint: %v", err) } - if acl != nil && (storageAccount.AccountProperties == nil || - storageAccount.AccountProperties.IsHnsEnabled == nil || - !*storageAccount.AccountProperties.IsHnsEnabled) { + // Parse the dfs endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + // Finally, build the data plane ID for this filesystem + id := filesystems.NewFileSystemID(*accountId, filesystemName) + + aceRaw := d.Get("ace").(*pluginsdk.Set).List() + acl, err := ExpandDataLakeGen2AceList(aceRaw) + if err != nil { + return fmt.Errorf("parsing ace list: %v", err) + } + + if acl != nil && (account.Properties == nil || + account.Properties.IsHnsEnabled == nil || + !*account.Properties.IsHnsEnabled) { return fmt.Errorf("ACL is enabled only when the Hierarchical Namespace (HNS) feature is turned ON") } - fileSystemName := d.Get("name").(string) propertiesRaw := d.Get("properties").(map[string]interface{}) properties := ExpandMetaData(propertiesRaw) - id := client.GetResourceID(storageID.StorageAccountName, fileSystemName) - - resp, err := client.GetProperties(ctx, storageID.StorageAccountName, fileSystemName) + resp, err := dataPlaneFilesystemsClient.GetProperties(ctx, id.FileSystemName) if err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("checking for existence of existing File System %q in %s: %+v", fileSystemName, storageID, err) + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("checking for existence of existing File System %q in %s: %v", id.FileSystemName, accountId, err) } } - if !utils.ResponseWasNotFound(resp.Response) { - return tf.ImportAsExistsError("azurerm_storage_data_lake_gen2_filesystem", id) + if !response.WasNotFound(resp.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_data_lake_gen2_filesystem", id.ID()) } - log.Printf("[INFO] Creating File System %q in %s.", fileSystemName, storageID) + log.Printf("[INFO] Creating %s...", id) input := filesystems.CreateInput{ Properties: properties, } - if _, err := client.Create(ctx, storageID.StorageAccountName, fileSystemName, input); err != nil { - return fmt.Errorf("creating File System %q in %s: %+v", fileSystemName, storageID, err) + if _, err = dataPlaneFilesystemsClient.Create(ctx, id.FileSystemName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } var owner *string @@ -199,7 +225,7 @@ func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta if acl != nil || owner != nil || group != nil { var aclString *string if acl != nil { - log.Printf("[INFO] Creating acl %q in File System %q in %s", acl, fileSystemName, storageID) + log.Printf("[INFO] Creating ACL %q for %s", acl, id) v := acl.String() aclString = &v } @@ -208,63 +234,66 @@ func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta Owner: owner, Group: group, } - if _, err := pathClient.SetAccessControl(ctx, storageID.StorageAccountName, fileSystemName, "/", accessControlInput); err != nil { - return fmt.Errorf("setting access control for root path in File System %q in %s: %+v", fileSystemName, storageID, err) + if _, err = dataPlanePathsClient.SetAccessControl(ctx, id.FileSystemName, "/", accessControlInput); err != nil { + return fmt.Errorf("setting access control for root path in File System %q in %s: %v", id.FileSystemName, accountId, err) } } - d.SetId(id) + d.SetId(id.ID()) + return resourceStorageDataLakeGen2FileSystemRead(d, meta) } func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.FileSystemsClient - pathClient := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := filesystems.ParseResourceID(d.Id()) + id, err := filesystems.ParseFileSystemID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - storageId, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + // Retrieve the storage account properties + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return err + return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - aceRaw := d.Get("ace").(*pluginsdk.Set).List() - acl, err := ExpandDataLakeGen2AceList(aceRaw) + // Build the data plane clients + dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("parsing ace list: %s", err) + return fmt.Errorf("building Data Lake Filesystems Client: %v", err) } - - // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageId.ResourceGroupName, storageId.StorageAccountName, "") + dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - if utils.ResponseWasNotFound(storageAccount.Response) { - return fmt.Errorf("%s was not found", storageId) - } + return fmt.Errorf("building Data Lake Paths Client: %v", err) + } - return fmt.Errorf("checking for existence of %s: %+v", storageId, err) + aceRaw := d.Get("ace").(*pluginsdk.Set).List() + acl, err := ExpandDataLakeGen2AceList(aceRaw) + if err != nil { + return fmt.Errorf("parsing ace list: %v", err) } - if acl != nil && (storageAccount.AccountProperties == nil || - storageAccount.AccountProperties.IsHnsEnabled == nil || - !*storageAccount.AccountProperties.IsHnsEnabled) { + if acl != nil && (account.Properties == nil || + account.Properties.IsHnsEnabled == nil || + !*account.Properties.IsHnsEnabled) { return fmt.Errorf("ACL is enabled only when the Hierarchical Namespace (HNS) feature is turned ON") } propertiesRaw := d.Get("properties").(map[string]interface{}) properties := ExpandMetaData(propertiesRaw) - log.Printf("[INFO] Updating Properties for File System %q in Storage Account %q.", id.DirectoryName, id.AccountName) + log.Printf("[INFO] Updating Properties for %s...", id) input := filesystems.SetPropertiesInput{ Properties: properties, } - if _, err = client.SetProperties(ctx, id.AccountName, id.DirectoryName, input); err != nil { - return fmt.Errorf("updating Properties for File System %q in Storage Account %q: %s", id.DirectoryName, id.AccountName, err) + if _, err = dataPlaneFilesystemsClient.SetProperties(ctx, id.FileSystemName, input); err != nil { + return fmt.Errorf("updating Properties for %s: %v", id, err) } var owner *string @@ -281,7 +310,7 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta if acl != nil || owner != nil || group != nil { var aclString *string if acl != nil { - log.Printf("[INFO] Creating acl %q in File System %q in Storage Account %q.", acl, id.DirectoryName, id.AccountName) + log.Printf("[INFO] Creating ACL %q for %s...", acl, id) v := acl.String() aclString = &v } @@ -290,8 +319,8 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta Owner: owner, Group: group, } - if _, err := pathClient.SetAccessControl(ctx, id.AccountName, id.DirectoryName, "/", accessControlInput); err != nil { - return fmt.Errorf("setting access control for root path in File System %q in Storage Account %q: %s", id.DirectoryName, id.AccountName, err) + if _, err = dataPlanePathsClient.SetAccessControl(ctx, id.FileSystemName, "/", accessControlInput); err != nil { + return fmt.Errorf("setting access control for root path in File System %q in Storage Account %q: %v", id.FileSystemName, id.AccountId.AccountName, err) } } @@ -299,59 +328,59 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta } func resourceStorageDataLakeGen2FileSystemRead(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.FileSystemsClient - pathClient := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := filesystems.ParseResourceID(d.Id()) + id, err := filesystems.ParseFileSystemID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - storageID, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + // Retrieve the storage account properties + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return err + return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageID.ResourceGroupName, storageID.StorageAccountName, "") + // Build the data plane clients + dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - if utils.ResponseWasNotFound(storageAccount.Response) { - log.Printf("[INFO] Storage Account %q does not exist removing from state...", id.AccountName) - d.SetId("") - return nil - } - - return fmt.Errorf("checking for existence of %s for File System %q: %+v", storageID, id.DirectoryName, err) + return fmt.Errorf("building Data Lake Filesystems Client: %v", err) + } + dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Data Lake Paths Client: %v", err) } - resp, err := client.GetProperties(ctx, id.AccountName, id.DirectoryName) + resp, err := dataPlaneFilesystemsClient.GetProperties(ctx, id.FileSystemName) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[INFO] File System %q does not exist in Storage Account %q - removing from state...", id.DirectoryName, id.AccountName) + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[INFO] File System %q does not exist in Storage Account %q - removing from state...", id.FileSystemName, id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("retrieving File System %q in Storage Account %q: %+v", id.DirectoryName, id.AccountName, err) + return fmt.Errorf("retrieving %s: %v", id, err) } - d.Set("name", id.DirectoryName) + d.Set("name", id.FileSystemName) - if err := d.Set("properties", resp.Properties); err != nil { - return fmt.Errorf("setting `properties`: %+v", err) + if err = d.Set("properties", resp.Properties); err != nil { + return fmt.Errorf("setting `properties`: %v", err) } var ace []interface{} var owner, group string // acl is only enabled when `IsHnsEnabled` is true otherwise the rest api will report error - if storageAccount.AccountProperties != nil && storageAccount.AccountProperties.IsHnsEnabled != nil && - *storageAccount.AccountProperties.IsHnsEnabled { + if account.Properties != nil && account.Properties.IsHnsEnabled != nil && + *account.Properties.IsHnsEnabled { // The above `getStatus` API request doesn't return the ACLs // Have to make a `getAccessControl` request, but that doesn't return all fields either! - pathResponse, err := pathClient.GetProperties(ctx, id.AccountName, id.DirectoryName, "/", paths.GetPropertiesActionGetAccessControl) + pathResponse, err := dataPlanePathsClient.GetProperties(ctx, id.FileSystemName, "/", paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetAccessControl}) if err == nil { acl, err := accesscontrol.ParseACL(pathResponse.ACL) if err != nil { @@ -370,19 +399,34 @@ func resourceStorageDataLakeGen2FileSystemRead(d *pluginsdk.ResourceData, meta i } func resourceStorageDataLakeGen2FileSystemDelete(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Storage.FileSystemsClient + storageClient := meta.(*clients.Client).Storage ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := filesystems.ParseResourceID(d.Id()) + id, err := filesystems.ParseFileSystemID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - resp, err := client.Delete(ctx, id.AccountName, id.DirectoryName) + // Retrieve the storage account properties + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) + if err != nil { + return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) + } + + // Build the data plane client + dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Data Lake Filesystems Client: %v", err) + } + + resp, err := dataPlaneFilesystemsClient.Delete(ctx, id.FileSystemName) if err != nil { - if !utils.ResponseWasNotFound(resp) { - return fmt.Errorf("deleting File System %q in Storage Account %q: %+v", id.DirectoryName, id.AccountName, err) + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("deleting %s: %v", id, err) } } diff --git a/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go b/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go index 8399d2b0d212..a2ff2ff9d97a 100644 --- a/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go +++ b/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go @@ -8,12 +8,13 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems" ) type StorageDataLakeGen2FileSystemResource struct{} @@ -147,28 +148,58 @@ func TestAccStorageDataLakeGen2FileSystem_withSuperUsers(t *testing.T) { } func (r StorageDataLakeGen2FileSystemResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := filesystems.ParseResourceID(state.ID) + id, err := filesystems.ParseFileSystemID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - resp, err := client.Storage.FileSystemsClient.GetProperties(ctx, id.AccountName, id.DirectoryName) + + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) + if err != nil { + return nil, fmt.Errorf("retrieving Account %q for Queue %q: %+v", id.AccountId, id.FileSystemName, err) + } + if account == nil { + return nil, fmt.Errorf("unable to determine Resource Group for Storage Queue %q (Account %q)", id.FileSystemName, id.AccountId.AccountName) + } + + filesystemsClient, err := client.Storage.DataLakeFilesystemsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + return nil, fmt.Errorf("building Data Lake Filesystems Client: %+v", err) + } + + resp, err := filesystemsClient.GetProperties(ctx, id.FileSystemName) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving File System %q (Account %q): %+v", id.DirectoryName, id.AccountName, err) + return nil, fmt.Errorf("retrieving File System %q (Account %q): %+v", id.FileSystemName, id.AccountId.AccountName, err) } + return utils.Bool(true), nil } func (r StorageDataLakeGen2FileSystemResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := filesystems.ParseResourceID(state.ID) + id, err := filesystems.ParseFileSystemID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - if _, err := client.Storage.FileSystemsClient.Delete(ctx, id.AccountName, id.DirectoryName); err != nil { - return nil, fmt.Errorf("deleting File System %q (Account %q): %+v", id.DirectoryName, id.AccountName, err) + + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) + if err != nil { + return nil, fmt.Errorf("retrieving Account %q for Queue %q: %+v", id.AccountId, id.FileSystemName, err) + } + if account == nil { + return nil, fmt.Errorf("unable to determine Resource Group for Storage Queue %q (Account %q)", id.FileSystemName, id.AccountId.AccountName) } + + filesystemsClient, err := client.Storage.DataLakeFilesystemsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return nil, fmt.Errorf("building Data Lake Filesystems Client: %+v", err) + } + + if _, err = filesystemsClient.Delete(ctx, id.FileSystemName); err != nil { + return nil, fmt.Errorf("deleting File System %q (Account %q): %+v", id.FileSystemName, id.AccountId.AccountName, err) + } + return utils.Bool(true), nil } diff --git a/internal/services/storage/storage_data_lake_gen2_path_resource.go b/internal/services/storage/storage_data_lake_gen2_path_resource.go index 8457260a94c6..b7ced88bf303 100644 --- a/internal/services/storage/storage_data_lake_gen2_path_resource.go +++ b/internal/services/storage/storage_data_lake_gen2_path_resource.go @@ -9,15 +9,18 @@ import ( "log" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths" "github.com/tombuildsstuff/giovanni/storage/accesscontrol" ) @@ -28,28 +31,34 @@ func resourceStorageDataLakeGen2Path() *pluginsdk.Resource { Update: resourceStorageDataLakeGen2PathUpdate, Delete: resourceStorageDataLakeGen2PathDelete, - Importer: pluginsdk.ImporterValidatingResourceIdThen(func(id string) error { - _, err := paths.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceIdThen(func(id, storageDomainSuffix string) error { + _, err := paths.ParsePathID(id, storageDomainSuffix) return err }, func(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) ([]*pluginsdk.ResourceData, error) { - storageClients := meta.(*clients.Client).Storage + storageClient := meta.(*clients.Client).Storage - id, err := paths.ParseResourceID(d.Id()) + id, err := paths.ParsePathID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return []*pluginsdk.ResourceData{d}, fmt.Errorf("parsing ID %q for import of Data Lake Gen2 Path: %v", d.Id(), err) } - // we then need to look up the Storage Account ID - account, err := storageClients.FindAccount(ctx, id.AccountName) + // Retrieve the storage account + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving Account %q for Data Lake Gen2 Path %q in File System %q: %s", id.AccountName, id.Path, id.FileSystemName, err) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving Account %q for Data Lake Gen2 Path %q in File System %q: %s", id.AccountId.AccountName, id.Path, id.FileSystemName, err) } if account == nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("unable to locate Storage Account: %q", id.AccountId.AccountName) } - if _, err = storageClients.FileSystemsClient.GetProperties(ctx, id.AccountName, id.FileSystemName); err != nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving File System %q for Data Lake Gen 2 Path %q in Account %q: %s", id.FileSystemName, id.Path, id.AccountName, err) + // Build the data plane client + dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return []*pluginsdk.ResourceData{d}, fmt.Errorf("building Data Lake Filesystems Client: %v", err) + } + + if _, err = dataPlaneFilesystemsClient.GetProperties(ctx, id.FileSystemName); err != nil { + return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving File System %q for Data Lake Gen 2 Path %q in Account %q: %s", id.FileSystemName, id.Path, id.AccountId.AccountName, err) } d.Set("storage_account_id", account.ID) @@ -142,38 +151,56 @@ func resourceStorageDataLakeGen2Path() *pluginsdk.Resource { } func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) defer cancel() - storageID, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + filesystemName := d.Get("filesystem_name").(string) + path := d.Get("path").(string) + + // Parse the storage_account_id which is a resource manager ID + accountResourceManagerId, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) if err != nil { return err } - // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageID.ResourceGroupName, storageID.StorageAccountName, "") + // Confirm the storage account exists and retrieve its properties + account, err := storageClient.FindAccount(ctx, accountResourceManagerId.StorageAccountName) if err != nil { - if utils.ResponseWasNotFound(storageAccount.Response) { - return fmt.Errorf("%s was not found", storageID) - } + return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", accountResourceManagerId.StorageAccountName, filesystemName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", accountResourceManagerId.StorageAccountName) + } - return fmt.Errorf("checking for existence of %s: %+v", storageID, err) + // Build the data plane client + dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Data Lake Paths Client: %v", err) } - fileSystemName := d.Get("filesystem_name").(string) - path := d.Get("path").(string) + // Determine the dfs endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeDfs) + if err != nil { + return fmt.Errorf("determining Data Lake Filesystems endpoint: %v", err) + } + + // Parse the dfs endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := paths.NewPathID(*accountId, filesystemName, path) - id := client.GetResourceID(storageID.StorageAccountName, fileSystemName, path) - resp, err := client.GetProperties(ctx, storageID.StorageAccountName, fileSystemName, path, paths.GetPropertiesActionGetStatus) + resp, err := dataPlanePathsClient.GetProperties(ctx, filesystemName, path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetStatus}) if err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("checking for existence of existing Path %q in File System %q in %s: %+v", path, fileSystemName, storageID, err) + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("checking for existence of existing Path %q in File System %q in %s: %v", path, filesystemName, accountResourceManagerId, err) } } - if !utils.ResponseWasNotFound(resp.Response) { - return tf.ImportAsExistsError("azurerm_storage_data_lake_gen2_path", id) + if !response.WasNotFound(resp.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_data_lake_gen2_path", id.ID()) } resourceString := d.Get("resource").(string) @@ -182,12 +209,12 @@ func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta inter case "directory": resource = paths.PathResourceDirectory default: - return fmt.Errorf("Unhandled resource type %q", resourceString) + return fmt.Errorf("unhandled resource type %q", resourceString) } aceRaw := d.Get("ace").(*pluginsdk.Set).List() acl, err := ExpandDataLakeGen2AceList(aceRaw) if err != nil { - return fmt.Errorf("parsing ace list: %s", err) + return fmt.Errorf("parsing ace list: %v", err) } var owner *string @@ -201,13 +228,13 @@ func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta inter group = &sv } - log.Printf("[INFO] Creating Path %q in File System %q in %s.", path, fileSystemName, storageID) + log.Printf("[INFO] Creating %s...", id) input := paths.CreateInput{ Resource: resource, } - if _, err := client.Create(ctx, storageID.StorageAccountName, fileSystemName, path, input); err != nil { - return fmt.Errorf("creating Path %q in File System %q in %s: %+v", path, fileSystemName, storageID.StorageAccountName, err) + if _, err = dataPlanePathsClient.Create(ctx, filesystemName, path, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } if acl != nil || owner != nil || group != nil { @@ -221,29 +248,39 @@ func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta inter Owner: owner, Group: group, } - if _, err := client.SetAccessControl(ctx, storageID.StorageAccountName, fileSystemName, path, accessControlInput); err != nil { - return fmt.Errorf("setting access control for Path %q in File System %q in %s: %+v", path, fileSystemName, storageID, err) + if _, err = dataPlanePathsClient.SetAccessControl(ctx, filesystemName, path, accessControlInput); err != nil { + return fmt.Errorf("setting access control for %s: %+v", id, err) } } - d.SetId(id) + d.SetId(id.ID()) + return resourceStorageDataLakeGen2PathRead(d, meta) } func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := paths.ParseResourceID(d.Id()) + id, err := paths.ParsePathID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - storageID, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + // Retrieve the storage account properties + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return err + return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) + } + + // Build the data plane client + dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Data Lake Paths Client: %v", err) } path := d.Get("path").(string) @@ -251,7 +288,7 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter aceRaw := d.Get("ace").(*pluginsdk.Set).List() acl, err := ExpandDataLakeGen2AceList(aceRaw) if err != nil { - return fmt.Errorf("parsing ace list: %s", err) + return fmt.Errorf("parsing ace list: %v", err) } var owner *string @@ -265,16 +302,6 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter group = &sv } - // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageID.ResourceGroupName, storageID.StorageAccountName, "") - if err != nil { - if utils.ResponseWasNotFound(storageAccount.Response) { - return fmt.Errorf("%s was not found", storageID) - } - - return fmt.Errorf("checking for existence of %s: %+v", storageID, err) - } - if acl != nil || owner != nil || group != nil { var aclString *string if acl != nil { @@ -286,8 +313,8 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter Owner: owner, Group: group, } - if _, err := client.SetAccessControl(ctx, id.AccountName, id.FileSystemName, path, accessControlInput); err != nil { - return fmt.Errorf("setting access control for Path %q in File System %q in Storage Account %q: %s", path, id.FileSystemName, id.AccountName, err) + if _, err = dataPlanePathsClient.SetAccessControl(ctx, id.FileSystemName, path, accessControlInput); err != nil { + return fmt.Errorf("setting access control for %s: %s", id, err) } } @@ -295,24 +322,39 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter } func resourceStorageDataLakeGen2PathRead(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := paths.ParseResourceID(d.Id()) + id, err := paths.ParsePathID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - resp, err := client.GetProperties(ctx, id.AccountName, id.FileSystemName, id.Path, paths.GetPropertiesActionGetStatus) + // Retrieve the storage account properties + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) + if err != nil { + return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) + } + + // Build the data plane client + dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[INFO] Path %q does not exist in File System %q in Storage Account %q - removing from state...", id.Path, id.FileSystemName, id.AccountName) + return fmt.Errorf("building Data Lake Paths Client: %v", err) + } + + resp, err := dataPlanePathsClient.GetProperties(ctx, id.FileSystemName, id.Path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetStatus}) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[INFO] Path %q does not exist in File System %q in Storage Account %q - removing from state...", id.Path, id.FileSystemName, id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("retrieving Path %q in File System %q in Storage Account %q: %+v", id.Path, id.FileSystemName, id.AccountName, err) + return fmt.Errorf("retrieving %s: %v", id, err) } d.Set("path", id.Path) @@ -322,20 +364,20 @@ func resourceStorageDataLakeGen2PathRead(d *pluginsdk.ResourceData, meta interfa // The above `getStatus` API request doesn't return the ACLs // Have to make a `getAccessControl` request, but that doesn't return all fields either! - resp, err = client.GetProperties(ctx, id.AccountName, id.FileSystemName, id.Path, paths.GetPropertiesActionGetAccessControl) + resp, err = dataPlanePathsClient.GetProperties(ctx, id.FileSystemName, id.Path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetAccessControl}) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[INFO] Path %q does not exist in File System %q in Storage Account %q - removing from state...", id.Path, id.FileSystemName, id.AccountName) + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[INFO] Path %q does not exist in File System %q in Storage Account %q - removing from state...", id.Path, id.FileSystemName, id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("retrieving ACLs for Path %q in File System %q in Storage Account %q: %+v", id.Path, id.FileSystemName, id.AccountName, err) + return fmt.Errorf("retrieving ACLs for %s: %v", id, err) } acl, err := accesscontrol.ParseACL(resp.ACL) if err != nil { - return fmt.Errorf("parsing response ACL %q: %s", resp.ACL, err) + return fmt.Errorf("parsing response ACL %q: %v", resp.ACL, err) } d.Set("ace", FlattenDataLakeGen2AceList(d, acl)) @@ -343,19 +385,34 @@ func resourceStorageDataLakeGen2PathRead(d *pluginsdk.ResourceData, meta interfa } func resourceStorageDataLakeGen2PathDelete(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := paths.ParseResourceID(d.Id()) + id, err := paths.ParsePathID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - resp, err := client.Delete(ctx, id.AccountName, id.FileSystemName, id.Path) + // Retrieve the storage account properties + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) + if err != nil { + return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) + } + + // Build the data plane client + dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Data Lake Paths Client: %v", err) + } + + resp, err := dataPlanePathsClient.Delete(ctx, id.FileSystemName, id.Path) if err != nil { - if !utils.ResponseWasNotFound(resp) { - return fmt.Errorf("deleting Path %q in File System %q in Storage Account %q: %+v", id.Path, id.FileSystemName, id.AccountName, err) + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("deleting %s: %v", id, err) } } diff --git a/internal/services/storage/storage_data_lake_gen2_path_resource_test.go b/internal/services/storage/storage_data_lake_gen2_path_resource_test.go index b38158910a93..2c324c4232de 100644 --- a/internal/services/storage/storage_data_lake_gen2_path_resource_test.go +++ b/internal/services/storage/storage_data_lake_gen2_path_resource_test.go @@ -8,12 +8,13 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths" ) type StorageDataLakeGen2PathResource struct{} @@ -131,17 +132,32 @@ func TestAccStorageDataLakeGen2Path_withSuperUsers(t *testing.T) { } func (r StorageDataLakeGen2PathResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := paths.ParseResourceID(state.ID) + id, err := paths.ParsePathID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - resp, err := client.Storage.ADLSGen2PathsClient.GetProperties(ctx, id.AccountName, id.FileSystemName, id.Path, paths.GetPropertiesActionGetStatus) + + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) + if err != nil { + return nil, fmt.Errorf("retrieving Account %q for Queue %q: %+v", id.AccountId, id.FileSystemName, err) + } + if account == nil { + return nil, fmt.Errorf("unable to determine Resource Group for Storage Queue %q (Account %q)", id.FileSystemName, id.AccountId.AccountName) + } + + pathsClient, err := client.Storage.DataLakePathsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + return nil, fmt.Errorf("building Data Lake Paths Client: %+v", err) + } + + resp, err := pathsClient.GetProperties(ctx, id.FileSystemName, id.Path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetStatus}) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving Path %q (File System %q / Account %q): %+v", id.Path, id.FileSystemName, id.AccountName, err) + return nil, fmt.Errorf("retrieving Path %q (File System %q / Account %q): %+v", id.Path, id.FileSystemName, id.AccountId.AccountName, err) } + return utils.Bool(true), nil } diff --git a/internal/services/storage/storage_queue_resource.go b/internal/services/storage/storage_queue_resource.go index 31b776bd0f1d..18753623b58d 100644 --- a/internal/services/storage/storage_queue_resource.go +++ b/internal/services/storage/storage_queue_resource.go @@ -10,11 +10,15 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) func resourceStorageQueue() *pluginsdk.Resource { @@ -24,8 +28,8 @@ func resourceStorageQueue() *pluginsdk.Resource { Update: resourceStorageQueueUpdate, Delete: resourceStorageQueueDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.StorageQueueDataPlaneID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := queues.ParseQueueID(id, storageDomainSuffix) return err }), @@ -79,32 +83,45 @@ func resourceStorageQueueCreate(d *pluginsdk.ResourceData, meta interface{}) err account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Queue %q: %s", accountName, queueName, err) + return fmt.Errorf("retrieving Account %q for Queue %q: %v", accountName, queueName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - client, err := storageClient.QueuesClient(ctx, *account) + queuesDataPlaneClient, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Queues Client: %s", err) + return fmt.Errorf("building Queues Client: %v", err) } - resourceId := parse.NewStorageQueueDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, queueName).ID() + // Determine the queue endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeTable) + if err != nil { + return fmt.Errorf("determining Queue endpoint: %v", err) + } - exists, err := client.Exists(ctx, account.ResourceGroup, accountName, queueName) + // Parse the queue endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("checking for presence of existing Queue %q (Storage Account %q): %s", queueName, accountName, err) + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := queues.NewQueueID(*accountId, queueName).ID() + + exists, err := queuesDataPlaneClient.Exists(ctx, queueName) + if err != nil { + return fmt.Errorf("checking for existing %s: %v", id, err) } if exists != nil && *exists { - return tf.ImportAsExistsError("azurerm_storage_queue", resourceId) + return tf.ImportAsExistsError("azurerm_storage_queue", id) } - if err := client.Create(ctx, account.ResourceGroup, accountName, queueName, metaData); err != nil { - return fmt.Errorf("creating Queue %q (Account %q): %+v", queueName, accountName, err) + if err = queuesDataPlaneClient.Create(ctx, queueName, metaData); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) } - d.SetId(resourceId) + d.SetId(id) + return resourceStorageQueueRead(d, meta) } @@ -113,7 +130,7 @@ func resourceStorageQueueUpdate(d *pluginsdk.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageQueueDataPlaneID(d.Id()) + id, err := queues.ParseQueueID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } @@ -121,21 +138,21 @@ func resourceStorageQueueUpdate(d *pluginsdk.ResourceData, meta interface{}) err metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Queue %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Queue %q: %v", id.AccountId.AccountName, id.QueueName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.QueuesClient(ctx, *account) + client, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Queues Client: %s", err) + return fmt.Errorf("building Queues Client: %v", err) } - if err := client.UpdateMetaData(ctx, account.ResourceGroup, id.AccountName, id.Name, metaData); err != nil { - return fmt.Errorf("updating MetaData for Queue %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateMetaData(ctx, id.QueueName, metaData); err != nil { + return fmt.Errorf("updating MetaData for %s: %v", id, err) } return resourceStorageQueueRead(d, meta) @@ -147,44 +164,44 @@ func resourceStorageQueueRead(d *pluginsdk.ResourceData, meta interface{}) error ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageQueueDataPlaneID(d.Id()) + id, err := queues.ParseQueueID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Queue %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Queue %q: %v", id.AccountId.AccountName, id.QueueName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Resource Group for Storage Queue %q (Account %s) - assuming removed & removing from state", id.Name, id.AccountName) + log.Printf("[WARN] Unable to determine Resource Group for Storage Queue %q (Account %s) - assuming removed & removing from state", id.QueueName, id.AccountId.AccountName) d.SetId("") return nil } - client, err := storageClient.QueuesClient(ctx, *account) + client, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Queues Client: %s", err) + return fmt.Errorf("building Queues Client: %v", err) } - queue, err := client.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + queue, err := client.Get(ctx, id.QueueName) if err != nil { - return fmt.Errorf("retrieving Queue %q (Account %q): %+v", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if queue == nil { - log.Printf("[INFO] Storage Queue %q no longer exists, removing from state...", id.Name) + log.Printf("[INFO] Storage Queue %q no longer exists, removing from state...", id.QueueName) d.SetId("") return nil } - d.Set("name", id.Name) - d.Set("storage_account_name", id.AccountName) + d.Set("name", id.QueueName) + d.Set("storage_account_name", id.AccountId.AccountName) if err := d.Set("metadata", FlattenMetaData(queue.MetaData)); err != nil { return fmt.Errorf("setting `metadata`: %s", err) } - resourceManagerId := parse.NewStorageQueueResourceManagerID(subscriptionId, account.ResourceGroup, id.AccountName, "default", id.Name) + resourceManagerId := parse.NewStorageQueueResourceManagerID(subscriptionId, account.ResourceGroup, id.AccountId.AccountName, "default", id.QueueName) d.Set("resource_manager_id", resourceManagerId.ID()) return nil @@ -195,28 +212,28 @@ func resourceStorageQueueDelete(d *pluginsdk.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageQueueDataPlaneID(d.Id()) + id, err := queues.ParseQueueID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Queue %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Queue %q: %s", id.AccountId.AccountName, id.QueueName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Resource Group for Storage Queue %q (Account %s) - assuming removed & removing from state", id.Name, id.AccountName) + log.Printf("[WARN] Unable to determine Resource Group for Storage Queue %q (Account %s) - assuming removed & removing from state", id.QueueName, id.AccountId.AccountName) d.SetId("") return nil } - client, err := storageClient.QueuesClient(ctx, *account) + client, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Queues Client: %s", err) + return fmt.Errorf("building Queues Client: %v", err) } - if err := client.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return fmt.Errorf("deleting Storage Queue %q (Account %q): %s", id.Name, id.AccountName, err) + if err = client.Delete(ctx, id.QueueName); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_queue_resource_test.go b/internal/services/storage/storage_queue_resource_test.go index 178637af8368..70979503d6b0 100644 --- a/internal/services/storage/storage_queue_resource_test.go +++ b/internal/services/storage/storage_queue_resource_test.go @@ -11,9 +11,9 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) type StorageQueueResource struct{} @@ -86,24 +86,24 @@ func TestAccStorageQueue_metaData(t *testing.T) { } func (r StorageQueueResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageQueueDataPlaneID(state.ID) + id, err := queues.ParseQueueID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Queue %q: %+v", id.AccountName, id.Name, err) + return nil, fmt.Errorf("retrieving Account %q for Queue %q: %+v", id.AccountId.AccountName, id.QueueName, err) } if account == nil { - return nil, fmt.Errorf("unable to determine Resource Group for Storage Queue %q (Account %q)", id.Name, id.AccountName) + return nil, fmt.Errorf("unable to determine Resource Group for Storage Queue %q (Account %q)", id.QueueName, id.AccountId.AccountName) } - queuesClient, err := client.Storage.QueuesClient(ctx, *account) + queuesClient, err := client.Storage.QueuesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Queues Client: %+v", err) } - queue, err := queuesClient.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + queue, err := queuesClient.Get(ctx, id.QueueName) if err != nil { - return nil, fmt.Errorf("retrieving Queue %q (Account %q): %+v", id.Name, id.AccountName, err) + return nil, fmt.Errorf("retrieving Queue %q (Account %q): %+v", id.QueueName, id.AccountId.AccountName, err) } return utils.Bool(queue != nil), nil } diff --git a/internal/services/storage/storage_share_data_source.go b/internal/services/storage/storage_share_data_source.go index 76f0fc0d026b..9faace9ed9ae 100644 --- a/internal/services/storage/storage_share_data_source.go +++ b/internal/services/storage/storage_share_data_source.go @@ -8,9 +8,12 @@ import ( "time" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) func dataSourceStorageShare() *pluginsdk.Resource { @@ -90,36 +93,50 @@ func dataSourceStorageShareRead(d *pluginsdk.ResourceData, meta interface{}) err account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", accountName, shareName, err) + return fmt.Errorf("retrieving Storage Account %q for Share %q: %s", accountName, shareName, err) } if account == nil { - return fmt.Errorf("unable to locate Account %q for Share %q", accountName, shareName) + return fmt.Errorf("locating Storage Account %q for Share %q", accountName, shareName) } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + sharesDataPlaneClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building FileShares Client for Storage Account %q (Resource Group %q): %s", accountName, account.ResourceGroup, err) + return fmt.Errorf("building FileShares Client: %v", err) } - id := parse.NewStorageShareDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, shareName).ID() - props, err := client.Get(ctx, account.ResourceGroup, accountName, shareName) + // Determine the file endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeFile) if err != nil { - return fmt.Errorf("retrieving Share %q (Account %q / Resource Group %q): %s", shareName, accountName, account.ResourceGroup, err) + return fmt.Errorf("determining File endpoint: %v", err) + } + + // Parse the file endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := shares.NewShareID(*accountId, shareName).ID() + + props, err := sharesDataPlaneClient.Get(ctx, shareName) + if err != nil { + return fmt.Errorf("retrieving %s: %v", id, err) } if props == nil { - return fmt.Errorf("share %q was not found in Account %q / Resource Group %q", shareName, accountName, account.ResourceGroup) + return fmt.Errorf("%s was not found", id) } d.SetId(id) d.Set("name", shareName) d.Set("storage_account_name", accountName) d.Set("quota", props.QuotaGB) - if err := d.Set("acl", flattenStorageShareACLs(props.ACLs)); err != nil { - return fmt.Errorf("setting `acl`: %+v", err) + if err = d.Set("acl", flattenStorageShareACLs(props.ACLs)); err != nil { + return fmt.Errorf("setting `acl`: %v", err) } - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %+v", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } resourceManagerId := parse.NewStorageShareResourceManagerID(storageClient.SubscriptionId, account.ResourceGroup, accountName, "default", shareName) diff --git a/internal/services/storage/storage_share_directory_resource.go b/internal/services/storage/storage_share_directory_resource.go index 67f91fe22134..7629a44c0966 100644 --- a/internal/services/storage/storage_share_directory_resource.go +++ b/internal/services/storage/storage_share_directory_resource.go @@ -10,14 +10,19 @@ import ( "strconv" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) func resourceStorageShareDirectory() *pluginsdk.Resource { @@ -27,8 +32,8 @@ func resourceStorageShareDirectory() *pluginsdk.Resource { Update: resourceStorageShareDirectoryUpdate, Delete: resourceStorageShareDirectoryDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := directories.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := directories.ParseDirectoryID(id, storageDomainSuffix) return err }), @@ -46,17 +51,36 @@ func resourceStorageShareDirectory() *pluginsdk.Resource { ForceNew: true, ValidateFunc: validate.StorageShareDirectoryName, }, + + "storage_share_id": { + Type: pluginsdk.TypeString, + Optional: true, // TODO: make required and forcenew in v4.0 + Computed: true, // TODO: remove computed in v4.0 + ForceNew: true, + ConflictsWith: []string{"share_name", "storage_account_name"}, + ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL + }, + "share_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Deprecated: "the `share_name` and `storage_account_name` properties have been superseded by the `storage_share_id` property and will be removed in version 4.0 of the AzureRM provider", + ConflictsWith: []string{"storage_share_id"}, + RequiredWith: []string{"storage_account_name"}, + ValidateFunc: validation.StringIsNotEmpty, }, + "storage_account_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Deprecated: "the `share_name` and `storage_account_name` properties have been superseded by the `storage_share_id` property and will be removed in version 4.0 of the AzureRM provider", + ConflictsWith: []string{"storage_share_id"}, + RequiredWith: []string{"share_name"}, + ValidateFunc: validation.StringIsNotEmpty, }, "metadata": MetaDataSchema(), @@ -69,62 +93,103 @@ func resourceStorageShareDirectoryCreate(d *pluginsdk.ResourceData, meta interfa defer cancel() storageClient := meta.(*clients.Client).Storage - accountName := d.Get("storage_account_name").(string) - shareName := d.Get("share_name").(string) directoryName := d.Get("name").(string) - metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - account, err := storageClient.FindAccount(ctx, accountName) + var storageShareId *shares.ShareId + var err error + if v, ok := d.GetOk("storage_share_id"); ok && v.(string) != "" { + storageShareId, err = shares.ParseShareID(v.(string), storageClient.StorageDomainSuffix) + if err != nil { + return err + } + } else { + // TODO: this is needed until `share_name` / `storage_account_name` are removed in favor of `storage_share_id` in v4.0 + // we will retrieve the storage account twice but this will make it easier to refactor later + storageAccountName := d.Get("storage_account_name").(string) + + account, err := storageClient.FindAccount(ctx, storageAccountName) + if err != nil { + return fmt.Errorf("retrieving Account %q: %v", storageAccountName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", storageAccountName) + } + + // Determine the file endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeFile) + if err != nil { + return fmt.Errorf("determining File endpoint: %v", err) + } + + // Parse the file endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + storageShareId = pointer.To(shares.NewShareID(*accountId, d.Get("share_name").(string))) + } + + if storageShareId == nil { + return fmt.Errorf("determining storage share ID") + } + + account, err := storageClient.FindAccount(ctx, storageShareId.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", accountName, directoryName, shareName, err) + return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %v", storageShareId.AccountId.AccountName, directoryName, storageShareId.ShareName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", storageShareId.AccountId.AccountName) + } + + accountId, err := accounts.ParseAccountID(storageShareId.ID(), storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) } - client, err := storageClient.FileShareDirectoriesClient(ctx, *account) + id := directories.NewDirectoryID(*accountId, storageShareId.ShareName, directoryName) + + client, err := storageClient.FileShareDirectoriesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Directories Client: %s", err) + return fmt.Errorf("building File Share Directories Client: %v", err) } - existing, err := client.Get(ctx, accountName, shareName, directoryName) + existing, err := client.Get(ctx, storageShareId.ShareName, directoryName) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing Directory %q (File Share %q / Storage Account %q / Resource Group %q): %s", directoryName, shareName, accountName, account.ResourceGroup, err) + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for existing %s: %s", id, err) } } - if !utils.ResponseWasNotFound(existing.Response) { - id := client.GetResourceID(accountName, shareName, directoryName) - return tf.ImportAsExistsError("azurerm_storage_share_directory", id) + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_share_directory", id.ID()) } input := directories.CreateDirectoryInput{ MetaData: metaData, } - if _, err := client.Create(ctx, accountName, shareName, directoryName, input); err != nil { - return fmt.Errorf("creating Directory %q (File Share %q / Account %q): %+v", directoryName, shareName, accountName, err) + if _, err = client.Create(ctx, storageShareId.ShareName, directoryName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } // Storage Share Directories are eventually consistent - log.Printf("[DEBUG] Waiting for Directory %q (File Share %q / Account %q) to become available", directoryName, shareName, accountName) + log.Printf("[DEBUG] Waiting for %s to become available", id) stateConf := &pluginsdk.StateChangeConf{ Pending: []string{"404"}, Target: []string{"200"}, - Refresh: storageShareDirectoryRefreshFunc(ctx, client, accountName, shareName, directoryName), + Refresh: storageShareDirectoryRefreshFunc(ctx, client, id), MinTimeout: 10 * time.Second, ContinuousTargetOccurence: 5, Timeout: d.Timeout(pluginsdk.TimeoutCreate), } - if _, err := stateConf.WaitForStateContext(ctx); err != nil { - return fmt.Errorf("waiting for Directory %q (File Share %q / Account %q) to become available: %s", directoryName, shareName, accountName, err) + if _, err = stateConf.WaitForStateContext(ctx); err != nil { + return fmt.Errorf("waiting for %s to become available: %v", id, err) } - resourceID := client.GetResourceID(accountName, shareName, directoryName) - d.SetId(resourceID) + d.SetId(id.ID()) return resourceStorageShareDirectoryRead(d, meta) } @@ -134,7 +199,7 @@ func resourceStorageShareDirectoryUpdate(d *pluginsdk.ResourceData, meta interfa defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := directories.ParseResourceID(d.Id()) + id, err := directories.ParseDirectoryID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } @@ -142,21 +207,21 @@ func resourceStorageShareDirectoryUpdate(d *pluginsdk.ResourceData, meta interfa metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountName, id.DirectoryName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %v", id.AccountId.AccountName, id.DirectoryPath, id.ShareName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account: %q", id.AccountId.AccountName) } - client, err := storageClient.FileShareDirectoriesClient(ctx, *account) + client, err := storageClient.FileShareDirectoriesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Client: %s", err) + return fmt.Errorf("building File Share Client: %v", err) } - if _, err := client.SetMetaData(ctx, id.AccountName, id.ShareName, id.DirectoryName, metaData); err != nil { - return fmt.Errorf("updating MetaData for Directory %q (File Share %q / Account %q): %+v", id.DirectoryName, id.ShareName, id.AccountName, err) + if _, err = client.SetMetaData(ctx, id.ShareName, id.DirectoryPath, directories.SetMetaDataInput{MetaData: metaData}); err != nil { + return fmt.Errorf("updating Metadata for %s: %v", id, err) } return resourceStorageShareDirectoryRead(d, meta) @@ -167,37 +232,52 @@ func resourceStorageShareDirectoryRead(d *pluginsdk.ResourceData, meta interface defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := directories.ParseResourceID(d.Id()) + id, err := directories.ParseDirectoryID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountName, id.DirectoryName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %v", id.AccountId.AccountName, id.DirectoryPath, id.ShareName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Resource Group for Storage Share Directory %q (Share %s, Account %s) - assuming removed & removing from state", id.DirectoryName, id.ShareName, id.AccountName) + log.Printf("[WARN] Unable to determine Resource Group for Storage Share Directory %q (Share %s, Account %s) - assuming removed & removing from state", id.DirectoryPath, id.ShareName, id.AccountId.AccountName) d.SetId("") return nil } - client, err := storageClient.FileShareDirectoriesClient(ctx, *account) + // Determine the file endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeFile) + if err != nil { + return fmt.Errorf("determining File endpoint: %v", err) + } + + // Parse the file endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + storageShareId := shares.NewShareID(*accountId, id.ShareName) + + client, err := storageClient.FileShareDirectoriesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client: %v", err) } - props, err := client.Get(ctx, id.AccountName, id.ShareName, id.DirectoryName) + props, err := client.Get(ctx, id.ShareName, id.DirectoryPath) if err != nil { - return fmt.Errorf("retrieving Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryName, id.ShareName, id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } - d.Set("name", id.DirectoryName) + d.Set("name", id.DirectoryPath) + d.Set("storage_share_id", storageShareId.ID()) d.Set("share_name", id.ShareName) - d.Set("storage_account_name", id.AccountName) + d.Set("storage_account_name", id.AccountId.AccountName) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %s", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } return nil @@ -208,38 +288,38 @@ func resourceStorageShareDirectoryDelete(d *pluginsdk.ResourceData, meta interfa defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := directories.ParseResourceID(d.Id()) + id, err := directories.ParseDirectoryID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountName, id.DirectoryName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %v", id.AccountId.AccountName, id.DirectoryPath, id.ShareName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.FileShareDirectoriesClient(ctx, *account) + client, err := storageClient.FileShareDirectoriesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client: %v", err) } - if _, err := client.Delete(ctx, id.AccountName, id.ShareName, id.DirectoryName); err != nil { - return fmt.Errorf("deleting Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryName, id.ShareName, id.AccountName, account.ResourceGroup, err) + if _, err = client.Delete(ctx, id.ShareName, id.DirectoryPath); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil } -func storageShareDirectoryRefreshFunc(ctx context.Context, client *directories.Client, accountName, shareName, directoryName string) pluginsdk.StateRefreshFunc { +func storageShareDirectoryRefreshFunc(ctx context.Context, client *directories.Client, id directories.DirectoryId) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { - res, err := client.Get(ctx, accountName, shareName, directoryName) + res, err := client.Get(ctx, id.ShareName, id.DirectoryPath) if err != nil { - return nil, strconv.Itoa(res.StatusCode), fmt.Errorf("retrieving Directory %q (File Share %q / Account %q): %s", directoryName, shareName, accountName, err) + return nil, strconv.Itoa(res.HttpResponse.StatusCode), fmt.Errorf("retrieving %s: %v", id, err) } - return res, strconv.Itoa(res.StatusCode), nil + return res, strconv.Itoa(res.HttpResponse.StatusCode), nil } } diff --git a/internal/services/storage/storage_share_directory_resource_test.go b/internal/services/storage/storage_share_directory_resource_test.go index f68cfde672fc..9617eabbbdef 100644 --- a/internal/services/storage/storage_share_directory_resource_test.go +++ b/internal/services/storage/storage_share_directory_resource_test.go @@ -8,12 +8,13 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories" ) type StorageShareDirectoryResource struct{} @@ -33,6 +34,52 @@ func TestAccStorageShareDirectory_basic(t *testing.T) { }) } +func TestAccStorageShareDirectory_basicDeprecated(t *testing.T) { + // TODO: remove test in v4.0 + data := acceptance.BuildTestData(t, "azurerm_storage_share_directory", "test") + r := StorageShareDirectoryResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccStorageShareDirectory_migrateStorageShareId(t *testing.T) { + // TODO: remove test in v4.0 + data := acceptance.BuildTestData(t, "azurerm_storage_share_directory", "test") + r := StorageShareDirectoryResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccStorageShareDirectory_uppercase(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_storage_share_directory", "test") r := StorageShareDirectoryResource{} @@ -119,27 +166,27 @@ func TestAccStorageShareDirectory_nested(t *testing.T) { } func (r StorageShareDirectoryResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := directories.ParseResourceID(state.ID) + id, err := directories.ParseDirectoryID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountName, id.DirectoryName, id.ShareName, err) + return nil, fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountId.AccountName, id.DirectoryPath, id.ShareName, err) } if account == nil { - return nil, fmt.Errorf("unable to determine Resource Group for Storage Share Directory %q (Share %q / Account %q)", id.DirectoryName, id.ShareName, id.AccountName) + return nil, fmt.Errorf("unable to determine Resource Group for Storage Share Directory %q (Share %q / Account %q)", id.DirectoryPath, id.ShareName, id.AccountId.AccountName) } - dirClient, err := client.Storage.FileShareDirectoriesClient(ctx, *account) + dirClient, err := client.Storage.FileShareDirectoriesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return nil, fmt.Errorf("building File Share client for Storage Account %q (Resource Group %q): %+v", id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("building File Share client for Storage Account %q (Resource Group %q): %+v", id.AccountId.AccountName, account.ResourceGroup, err) } - resp, err := dirClient.Get(ctx, id.AccountName, id.ShareName, id.DirectoryName) + resp, err := dirClient.Get(ctx, id.ShareName, id.DirectoryPath) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryName, id.ShareName, id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("retrieving Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryPath, id.ShareName, id.AccountId.AccountName, account.ResourceGroup, err) } return utils.Bool(true), nil } @@ -149,6 +196,18 @@ func (r StorageShareDirectoryResource) basic(data acceptance.TestData) string { return fmt.Sprintf(` %s +resource "azurerm_storage_share_directory" "test" { + name = "dir" + storage_share_id = azurerm_storage_share.test.id +} +`, template) +} + +func (r StorageShareDirectoryResource) basicDeprecated(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + resource "azurerm_storage_share_directory" "test" { name = "dir" share_name = azurerm_storage_share.test.name @@ -163,9 +222,8 @@ func (r StorageShareDirectoryResource) uppercase(data acceptance.TestData) strin %s resource "azurerm_storage_share_directory" "test" { - name = "UpperCaseCharacterS" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "UpperCaseCharacterS" + storage_share_id = azurerm_storage_share.test.id } `, template) } @@ -176,9 +234,8 @@ func (r StorageShareDirectoryResource) requiresImport(data acceptance.TestData) %s resource "azurerm_storage_share_directory" "import" { - name = azurerm_storage_share_directory.test.name - share_name = azurerm_storage_share_directory.test.share_name - storage_account_name = azurerm_storage_share_directory.test.storage_account_name + name = azurerm_storage_share_directory.test.name + storage_share_id = azurerm_storage_share.test.id } `, template) } @@ -189,9 +246,8 @@ func (r StorageShareDirectoryResource) complete(data acceptance.TestData) string %s resource "azurerm_storage_share_directory" "test" { - name = "dir" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "dir" + storage_share_id = azurerm_storage_share.test.id metadata = { hello = "world" @@ -206,9 +262,8 @@ func (r StorageShareDirectoryResource) updated(data acceptance.TestData) string %s resource "azurerm_storage_share_directory" "test" { - name = "dir" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "dir" + storage_share_id = azurerm_storage_share.test.id metadata = { hello = "world" @@ -224,27 +279,23 @@ func (r StorageShareDirectoryResource) nested(data acceptance.TestData) string { %s resource "azurerm_storage_share_directory" "parent" { - name = "123--parent-dir" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "123--parent-dir" + storage_share_id = azurerm_storage_share.test.id } resource "azurerm_storage_share_directory" "child_one" { - name = "${azurerm_storage_share_directory.parent.name}/child1" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "${azurerm_storage_share_directory.parent.name}/child1" + storage_share_id = azurerm_storage_share.test.id } resource "azurerm_storage_share_directory" "child_two" { - name = "${azurerm_storage_share_directory.child_one.name}/childtwo--123" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "${azurerm_storage_share_directory.child_one.name}/childtwo--123" + storage_share_id = azurerm_storage_share.test.id } resource "azurerm_storage_share_directory" "multiple_child_one" { - name = "${azurerm_storage_share_directory.parent.name}/c" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "${azurerm_storage_share_directory.parent.name}/c" + storage_share_id = azurerm_storage_share.test.id } `, template) } diff --git a/internal/services/storage/storage_share_file_resource.go b/internal/services/storage/storage_share_file_resource.go index 48b4cf882332..fd88486c068f 100644 --- a/internal/services/storage/storage_share_file_resource.go +++ b/internal/services/storage/storage_share_file_resource.go @@ -9,15 +9,18 @@ import ( "os" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) func resourceStorageShareFile() *pluginsdk.Resource { @@ -27,8 +30,8 @@ func resourceStorageShareFile() *pluginsdk.Resource { Update: resourceStorageShareFileUpdate, Delete: resourceStorageShareFileDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := files.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := files.ParseFileID(id, storageDomainSuffix) return err }), @@ -45,12 +48,14 @@ func resourceStorageShareFile() *pluginsdk.Resource { Required: true, ForceNew: true, }, + "storage_share_id": { Type: pluginsdk.TypeString, Required: true, ForceNew: true, - ValidateFunc: storageValidate.StorageShareID, + ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL }, + "path": { Type: pluginsdk.TypeString, ForceNew: true, @@ -106,7 +111,7 @@ func resourceStorageShareFileCreate(d *pluginsdk.ResourceData, meta interface{}) defer cancel() storageClient := meta.(*clients.Client).Storage - storageShareID, err := parse.StorageShareDataPlaneID(d.Get("storage_share_id").(string)) + storageShareId, err := shares.ParseShareID(d.Get("storage_share_id").(string), storageClient.StorageDomainSuffix) if err != nil { return err } @@ -114,42 +119,48 @@ func resourceStorageShareFileCreate(d *pluginsdk.ResourceData, meta interface{}) fileName := d.Get("name").(string) path := d.Get("path").(string) - account, err := storageClient.FindAccount(ctx, storageShareID.AccountName) + account, err := storageClient.FindAccount(ctx, storageShareId.AccountId.AccountName) if err != nil { - return fmt.Errorf("eretrieving Account %q for File %q (Share %q): %s", storageShareID.AccountName, fileName, storageShareID.Name, err) + return fmt.Errorf("retrieving Account %q for File %q (Share %q): %v", storageShareId.AccountId.AccountName, fileName, storageShareId.ShareName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", storageShareID.AccountName) + return fmt.Errorf("locating Storage Account %q", storageShareId.AccountId.AccountName) } - fileSharesClient, err := storageClient.FileSharesClient(ctx, *account) + accountId, err := accounts.ParseAccountID(storageShareId.ID(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("building File Share Directories Client: %s", err) + return fmt.Errorf("parsing Account ID: %v", err) } - share, err := fileSharesClient.Get(ctx, account.ResourceGroup, storageShareID.AccountName, storageShareID.Name) + id := files.NewFileID(*accountId, storageShareId.ShareName, path, fileName) + + fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("retrieving Share %q for File %q: %s", storageShareID.Name, fileName, err) + return fmt.Errorf("building File Share Directories Client: %v", err) + } + + share, err := fileSharesClient.Get(ctx, storageShareId.ShareName) + if err != nil { + return fmt.Errorf("retrieving Share %q for File %q: %v", storageShareId.ShareName, fileName, err) } if share == nil { - return fmt.Errorf("unable to locate Storage Share %q", storageShareID.Name) + return fmt.Errorf("unable to locate Storage Share %q", storageShareId.ShareName) } - client, err := storageClient.FileShareFilesClient(ctx, *account) + client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building File Share Directories Client: %s", err) } - existing, err := client.GetProperties(ctx, storageShareID.AccountName, storageShareID.Name, path, fileName) + existing, err := client.GetProperties(ctx, storageShareId.ShareName, path, fileName) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing File %q (File Share %q / Storage Account %q / Resource Group %q): %s", fileName, storageShareID.Name, storageShareID.AccountName, account.ResourceGroup, err) + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for existing %s: %v", id, err) } } - if !utils.ResponseWasNotFound(existing.Response) { - id := client.GetResourceID(storageShareID.AccountName, storageShareID.Name, path, fileName) - return tf.ImportAsExistsError("azurerm_storage_share_file", id) + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_share_file", id.ID()) } input := files.CreateInput{ @@ -167,33 +178,32 @@ func resourceStorageShareFileCreate(d *pluginsdk.ResourceData, meta interface{}) if v, ok := d.GetOk("source"); ok { file, err = os.Open(v.(string)) if err != nil { - return fmt.Errorf("opening file : %s", err) + return fmt.Errorf("opening file: %s", err) } info, err := file.Stat() if err != nil { - return fmt.Errorf("'stat'-ing File %q (File Share %q / Account %q): %+v", fileName, storageShareID.Name, storageShareID.AccountName, err) + return fmt.Errorf("'stat'-ing File %q (File Share %q / Account %q): %v", fileName, storageShareId.ShareName, storageShareId.AccountId.AccountName, err) } if info.Size() == 0 { - return fmt.Errorf("file %q (File Share %q / Account %q) is empty", fileName, storageShareID.Name, storageShareID.AccountName) + return fmt.Errorf("file %q (File Share %q / Account %q) is empty", fileName, storageShareId.ShareName, storageShareId.AccountId.AccountName) } input.ContentLength = info.Size() } - if _, err := client.Create(ctx, storageShareID.AccountName, storageShareID.Name, path, fileName, input); err != nil { - return fmt.Errorf("creating File %q (File Share %q / Account %q): %+v", fileName, storageShareID.Name, storageShareID.AccountName, err) + if _, err = client.Create(ctx, storageShareId.ShareName, path, fileName, input); err != nil { + return fmt.Errorf("creating File %q (File Share %q / Account %q): %v", fileName, storageShareId.ShareName, storageShareId.AccountId.AccountName, err) } if file != nil { - if err := client.PutFile(ctx, storageShareID.AccountName, storageShareID.Name, path, fileName, file, 4); err != nil { - return fmt.Errorf("uploading File: %q (File Share %q / Account %q): %+v", fileName, storageShareID.Name, storageShareID.AccountName, err) + if err = client.PutFile(ctx, storageShareId.ShareName, path, fileName, file, 4); err != nil { + return fmt.Errorf("uploading File: %q (File Share %q / Account %q): %v", fileName, storageShareId.ShareName, storageShareId.AccountId.AccountName, err) } } - resourceID := client.GetResourceID(storageShareID.AccountName, storageShareID.Name, path, fileName) - d.SetId(resourceID) + d.SetId(id.ID()) return resourceStorageShareFileRead(d, meta) } @@ -203,41 +213,41 @@ func resourceStorageShareFileUpdate(d *pluginsdk.ResourceData, meta interface{}) defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := files.ParseResourceID(d.Id()) + id, err := files.ParseFileID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountName, id.FileName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for %s: %v", id.AccountId.AccountName, id, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - fileSharesClient, err := storageClient.FileSharesClient(ctx, *account) + fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Directories Client: %s", err) + return fmt.Errorf("building File Share Directories Client: %v", err) } - share, err := fileSharesClient.Get(ctx, account.ResourceGroup, id.AccountName, id.ShareName) + share, err := fileSharesClient.Get(ctx, id.ShareName) if err != nil { - return fmt.Errorf("retrieving Share %q for File %q: %s", id.ShareName, id.FileName, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if share == nil { return fmt.Errorf("unable to locate Storage Share %q", id.ShareName) } - client, err := storageClient.FileShareFilesClient(ctx, *account) + client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Files Client: %s", err) + return fmt.Errorf("building File Share Files Client: %v", err) } - existing, err := client.GetProperties(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName) + existing, err := client.GetProperties(ctx, id.ShareName, id.DirectoryPath, id.FileName) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing File %q (File Share %q / Storage Account %q / Resource Group %q): %s", id.FileName, id.ShareName, id.AccountName, account.ResourceGroup, err) + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for presence of existing %s: %v", id, err) } } @@ -254,8 +264,8 @@ func resourceStorageShareFileUpdate(d *pluginsdk.ResourceData, meta interface{}) input.ContentMD5 = utils.String(v.(string)) } - if _, err := client.SetProperties(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName, input); err != nil { - return fmt.Errorf("creating File %q (File Share %q / Account %q): %+v", id.FileName, id.ShareName, id.AccountName, err) + if _, err = client.SetProperties(ctx, id.ShareName, id.DirectoryPath, id.FileName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } } @@ -267,53 +277,53 @@ func resourceStorageShareFileRead(d *pluginsdk.ResourceData, meta interface{}) e defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := files.ParseResourceID(d.Id()) + id, err := files.ParseFileID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountName, id.FileName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountId.AccountName, id.FileName, id.ShareName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Storage Account for Storage Share File %q (Share %s, Account %s) - assuming removed & removing from state", id.FileName, id.ShareName, id.AccountName) + log.Printf("[WARN] Unable to determine Storage Account for %s - assuming removed & removing from state", id) d.SetId("") return nil } - fileSharesClient, err := storageClient.FileSharesClient(ctx, *account) + fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building File Share Directories Client: %s", err) } - share, err := fileSharesClient.Get(ctx, account.ResourceGroup, id.AccountName, id.ShareName) + share, err := fileSharesClient.Get(ctx, id.ShareName) if err != nil { return fmt.Errorf("retrieving Share %q for File %q: %s", id.ShareName, id.FileName, err) } if share == nil { - log.Printf("[WARN] Unable to determine Storage Share for Storage Share File %q (Share %s, Account %s) - assuming removed & removing from state", id.FileName, id.ShareName, id.AccountName) + log.Printf("[WARN] Unable to determine Storage Share for %s - assuming removed & removing from state", id) d.SetId("") return nil } - client, err := storageClient.FileShareFilesClient(ctx, *account) + client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client for Storage Account %s: %s", id.AccountId, err) } - props, err := client.GetProperties(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName) + props, err := client.GetProperties(ctx, id.ShareName, id.DirectoryPath, id.FileName) if err != nil { - log.Printf("Retrieving Storage File Share file %q (Directory %q / File Share %q / Account %q / Resource Group %q): %s", id.FileName, id.DirectoryName, id.ShareName, id.AccountName, account.ResourceGroup, err) + log.Printf("retrieving %s: %s", id, err) d.SetId("") return nil } d.Set("name", id.FileName) - d.Set("path", id.DirectoryName) - d.Set("storage_share_id", parse.NewStorageShareDataPlaneId(id.AccountName, storageClient.Environment.StorageEndpointSuffix, id.ShareName).ID()) + d.Set("path", id.DirectoryPath) + d.Set("storage_share_id", shares.NewShareID(id.AccountId, id.ShareName).ID()) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { return fmt.Errorf("setting `metadata`: %s", err) } d.Set("content_type", props.ContentType) @@ -335,26 +345,26 @@ func resourceStorageShareFileDelete(d *pluginsdk.ResourceData, meta interface{}) defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := files.ParseResourceID(d.Id()) + id, err := files.ParseFileID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountName, id.FileName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for File %q (Share %q): %v", id.AccountId.AccountName, id.FileName, id.ShareName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.FileShareFilesClient(ctx, *account) + client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share File Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share File Client for Storage Account %q (Resource Group %q): %v", id.AccountId.AccountName, account.ResourceGroup, err) } - if _, err := client.Delete(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName); err != nil { - return fmt.Errorf("deleting Storage Share File %q (File Share %q / Account %q / Resource Group %q): %s", id.FileName, id.ShareName, id.AccountName, account.ResourceGroup, err) + if _, err = client.Delete(ctx, id.ShareName, id.DirectoryPath, id.FileName); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_share_file_resource_test.go b/internal/services/storage/storage_share_file_resource_test.go index 2a2b5b0b3d64..e488f909e9be 100644 --- a/internal/services/storage/storage_share_file_resource_test.go +++ b/internal/services/storage/storage_share_file_resource_test.go @@ -10,12 +10,13 @@ import ( "regexp" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files" ) type StorageShareFileResource struct{} @@ -137,28 +138,28 @@ func TestAccAzureRMStorageShareFile_withEmptyFile(t *testing.T) { } func (StorageShareFileResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := files.ParseResourceID(state.ID) + id, err := files.ParseFileID(state.ID, clients.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := clients.Storage.FindAccount(ctx, id.AccountName) + account, err := clients.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountName, id.FileName, id.ShareName, err) + return nil, fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountId.AccountName, id.FileName, id.ShareName, err) } if account == nil { return utils.Bool(false), nil } - client, err := clients.Storage.FileShareFilesClient(ctx, *account) + client, err := clients.Storage.FileShareFilesDataPlaneClient(ctx, *account, clients.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building File Share Files Client: %s", err) } - resp, err := client.GetProperties(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName) + resp, err := client.GetProperties(ctx, id.ShareName, id.DirectoryPath, id.FileName) if err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return nil, fmt.Errorf("checking for presence of existing File %q (File Share %q / Storage Account %q / Resource Group %q): %s", id.FileName, id.ShareName, id.AccountName, account.ResourceGroup, err) + if !response.WasNotFound(resp.HttpResponse) { + return nil, fmt.Errorf("checking for presence of existing File %q (File Share %q / Storage Account %q / Resource Group %q): %s", id.FileName, id.ShareName, id.AccountId.AccountName, account.ResourceGroup, err) } } diff --git a/internal/services/storage/storage_share_resource.go b/internal/services/storage/storage_share_resource.go index 42c4f458f341..58b923dec4da 100644 --- a/internal/services/storage/storage_share_resource.go +++ b/internal/services/storage/storage_share_resource.go @@ -11,13 +11,16 @@ import ( "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage" // nolint: staticcheck "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) func resourceStorageShare() *pluginsdk.Resource { @@ -27,8 +30,8 @@ func resourceStorageShare() *pluginsdk.Resource { Update: resourceStorageShareUpdate, Delete: resourceStorageShareDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.StorageShareDataPlaneID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := shares.ParseShareID(id, storageDomainSuffix) return err }), @@ -158,12 +161,26 @@ func resourceStorageShareCreate(d *pluginsdk.ResourceData, meta interface{}) err account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", accountName, shareName, err) + return fmt.Errorf("retrieving Account %q for Share %q: %v", accountName, shareName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } + // Determine the file endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeFile) + if err != nil { + return fmt.Errorf("determining File endpoint: %v", err) + } + + // Parse the file endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := shares.NewShareID(*accountId, shareName) + protocol := shares.ShareProtocol(d.Get("enabled_protocol").(string)) if protocol == shares.NFS { // Only FileStorage (whose sku tier is Premium only) storage account is able to have NFS file shares. @@ -173,19 +190,18 @@ func resourceStorageShareCreate(d *pluginsdk.ResourceData, meta interface{}) err } } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building File Share Client: %s", err) + return fmt.Errorf("building File Share Client: %v", err) } - id := parse.NewStorageShareDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, shareName).ID() - - exists, err := client.Exists(ctx, account.ResourceGroup, accountName, shareName) + exists, err := client.Exists(ctx, shareName) if err != nil { - return fmt.Errorf("checking for existence of existing Storage Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, account.ResourceGroup, err) + return fmt.Errorf("checking for existing %s: %v", id, err) } if exists != nil && *exists { - return tf.ImportAsExistsError("azurerm_storage_share", id) + return tf.ImportAsExistsError("azurerm_storage_share", id.ID()) } log.Printf("[INFO] Creating Share %q in Storage Account %q", shareName, accountName) @@ -200,13 +216,14 @@ func resourceStorageShareCreate(d *pluginsdk.ResourceData, meta interface{}) err input.AccessTier = &tier } - if err := client.Create(ctx, account.ResourceGroup, accountName, shareName, input); err != nil { - return fmt.Errorf("creating Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, account.ResourceGroup, err) + if err = client.Create(ctx, shareName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - d.SetId(id) - if err := client.UpdateACLs(ctx, account.ResourceGroup, accountName, shareName, acls); err != nil { - return fmt.Errorf("setting ACL's for Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, account.ResourceGroup, err) + d.SetId(id.ID()) + + if err = client.UpdateACLs(ctx, shareName, shares.SetAclInput{SignedIdentifiers: acls}); err != nil { + return fmt.Errorf("setting ACLs for %s: %v", id, err) } return resourceStorageShareRead(d, meta) @@ -217,38 +234,39 @@ func resourceStorageShareRead(d *pluginsdk.ResourceData, meta interface{}) error defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := parse.StorageShareDataPlaneID(d.Id()) + id, err := shares.ParseShareID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Share %q: %v", id.AccountId.AccountName, id.ShareName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Account %q for Storage Share %q - assuming removed & removing from state", id.AccountName, id.Name) + log.Printf("[WARN] Unable to determine Account %q for Storage Share %q - assuming removed & removing from state", id.AccountId.AccountName, id.ShareName) d.SetId("") return nil } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %v", id.AccountId.AccountName, account.ResourceGroup, err) } - props, err := client.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + props, err := client.Get(ctx, id.ShareName) if err != nil { return err } if props == nil { - log.Printf("[DEBUG] File Share %q was not found in Account %q / Resource Group %q - assuming removed & removing from state", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] File Share %q was not found in Account %q / Resource Group %q - assuming removed & removing from state", id.ShareName, id.AccountId.AccountName, account.ResourceGroup) d.SetId("") return nil } - d.Set("name", id.Name) - d.Set("storage_account_name", id.AccountName) + d.Set("name", id.ShareName) + d.Set("storage_account_name", id.AccountId.AccountName) d.Set("quota", props.QuotaGB) d.Set("url", id.ID()) d.Set("enabled_protocol", string(props.EnabledProtocol)) @@ -267,7 +285,7 @@ func resourceStorageShareRead(d *pluginsdk.ResourceData, meta interface{}) error return fmt.Errorf("flattening `metadata`: %+v", err) } - resourceManagerId := parse.NewStorageShareResourceManagerID(storageClient.SubscriptionId, account.ResourceGroup, id.AccountName, "default", id.Name) + resourceManagerId := parse.NewStorageShareResourceManagerID(storageClient.SubscriptionId, account.ResourceGroup, id.AccountId.AccountName, "default", id.ShareName) d.Set("resource_manager_id", resourceManagerId.ID()) return nil @@ -278,70 +296,71 @@ func resourceStorageShareUpdate(d *pluginsdk.ResourceData, meta interface{}) err defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := parse.StorageShareDataPlaneID(d.Id()) + id, err := shares.ParseShareID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Share %q: %v", id.AccountId.AccountName, id.ShareName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %v", id.AccountId.AccountName, account.ResourceGroup, err) } if d.HasChange("quota") { - log.Printf("[DEBUG] Updating the Quota for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating the Quota for %s", id) quota := d.Get("quota").(int) - if err := client.UpdateQuota(ctx, account.ResourceGroup, id.AccountName, id.Name, quota); err != nil { - return fmt.Errorf("updating Quota for File Share %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateQuota(ctx, id.ShareName, quota); err != nil { + return fmt.Errorf("updating Quota for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the Quota for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated the Quota for %s", id) } if d.HasChange("metadata") { - log.Printf("[DEBUG] Updating the MetaData for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating the MetaData for %s", id) metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - if err := client.UpdateMetaData(ctx, account.ResourceGroup, id.AccountName, id.Name, metaData); err != nil { - return fmt.Errorf("updating MetaData for File Share %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateMetaData(ctx, id.ShareName, metaData); err != nil { + return fmt.Errorf("updating MetaData for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the MetaData for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated the MetaData for %s", id) } if d.HasChange("acl") { - log.Printf("[DEBUG] Updating the ACL's for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating the ACLs for %s", id) aclsRaw := d.Get("acl").(*pluginsdk.Set).List() acls := expandStorageShareACLs(aclsRaw) - if err := client.UpdateACLs(ctx, account.ResourceGroup, id.AccountName, id.Name, acls); err != nil { - return fmt.Errorf("updating ACL's for File Share %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateACLs(ctx, id.ShareName, shares.SetAclInput{SignedIdentifiers: acls}); err != nil { + return fmt.Errorf("updating ACLs for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the ACL's for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated ACLs for %s", id) } if d.HasChange("access_tier") { - log.Printf("[DEBUG] Updating the Access Tier for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating Access Tier for %s", id) tier := shares.AccessTier(d.Get("access_tier").(string)) - if err := client.UpdateTier(ctx, account.ResourceGroup, id.AccountName, id.Name, tier); err != nil { - return fmt.Errorf("updating Access Tier for File Share %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateTier(ctx, id.ShareName, tier); err != nil { + return fmt.Errorf("updating Access Tier for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the Access Tier for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated Access Tier for %s", id) } return resourceStorageShareRead(d, meta) @@ -352,26 +371,27 @@ func resourceStorageShareDelete(d *pluginsdk.ResourceData, meta interface{}) err defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := parse.StorageShareDataPlaneID(d.Id()) + id, err := shares.ParseShareID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Share %q: %v", id.AccountId.AccountName, id.ShareName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %v", id.AccountId.AccountName, account.ResourceGroup, err) } - if err := client.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return fmt.Errorf("deleting File Share %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + if err = client.Delete(ctx, id.ShareName); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_share_resource_test.go b/internal/services/storage/storage_share_resource_test.go index aec5733e28d2..0ebb64d4c9f0 100644 --- a/internal/services/storage/storage_share_resource_test.go +++ b/internal/services/storage/storage_share_resource_test.go @@ -11,9 +11,9 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) type StorageShareResource struct{} @@ -271,52 +271,54 @@ func TestAccStorageShare_protocolUpdate(t *testing.T) { } func (r StorageShareResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageShareDataPlaneID(state.ID) + id, err := shares.ParseShareID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Share %q: %+v", id.AccountName, id.Name, err) + return nil, fmt.Errorf("retrieving Account %q for Share %q: %+v", id.AccountId.AccountName, id.ShareName, err) } if account == nil { - return nil, fmt.Errorf("unable to determine Account %q for Storage Share %q", id.AccountName, id.Name) + return nil, fmt.Errorf("unable to determine Account %q for Storage Share %q", id.AccountId.AccountName, id.ShareName) } - sharesClient, err := client.Storage.FileSharesClient(ctx, *account) + sharesClient, err := client.Storage.FileSharesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return nil, fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %+v", id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %+v", id.AccountId.AccountName, account.ResourceGroup, err) } - props, err := sharesClient.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + props, err := sharesClient.Get(ctx, id.ShareName) if err != nil { - return nil, fmt.Errorf("retrieving File Share %q (Account %q / Resource Group %q): %+v", id.Name, id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("retrieving File Share %q (Account %q / Resource Group %q): %+v", id.ShareName, id.AccountId.AccountName, account.ResourceGroup, err) } + return utils.Bool(props != nil), nil } func (r StorageShareResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageShareDataPlaneID(state.ID) + id, err := shares.ParseShareID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Share %q: %+v", id.AccountName, id.Name, err) + return nil, fmt.Errorf("retrieving Account %q for Share %q: %+v", id.AccountId.AccountName, id.ShareName, err) } if account == nil { - return nil, fmt.Errorf("unable to determine Account %q for Storage Share %q", id.AccountName, id.Name) + return nil, fmt.Errorf("unable to determine Account %q for Storage Share %q", id.AccountId.AccountName, id.ShareName) } - sharesClient, err := client.Storage.FileSharesClient(ctx, *account) + sharesClient, err := client.Storage.FileSharesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return nil, fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %+v", id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %+v", id.AccountId.AccountName, account.ResourceGroup, err) } - if err := sharesClient.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return nil, fmt.Errorf("deleting File Share %q (Account %q / Resource Group %q): %+v", id.Name, id.AccountName, account.ResourceGroup, err) + if err := sharesClient.Delete(ctx, id.ShareName); err != nil { + return nil, fmt.Errorf("deleting File Share %q (Account %q / Resource Group %q): %+v", id.ShareName, id.AccountId.AccountName, account.ResourceGroup, err) } + return utils.Bool(true), nil } @@ -537,6 +539,7 @@ func (r StorageShareResource) accessTierStandard(data acceptance.TestData, tier return fmt.Sprintf(` provider "azurerm" { features {} + storage_use_azuread = true } resource "azurerm_resource_group" "test" { diff --git a/internal/services/storage/storage_table_entities_data_source.go b/internal/services/storage/storage_table_entities_data_source.go index 8d5364765a65..106e43a54cc1 100644 --- a/internal/services/storage/storage_table_entities_data_source.go +++ b/internal/services/storage/storage_table_entities_data_source.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" ) type storageTableEntitiesDataSource struct{} @@ -23,14 +23,14 @@ type storageTableEntitiesDataSource struct{} var _ sdk.DataSource = storageTableEntitiesDataSource{} type TableEntitiesDataSourceModel struct { - TableName string `tfschema:"table_name"` - StorageAccountName string `tfschema:"storage_account_name"` - Filter string `tfschema:"filter"` - Select []string `tfschema:"select"` - Items []TableEntitiyDataSourceModel `tfschema:"items"` + TableName string `tfschema:"table_name"` + StorageAccountName string `tfschema:"storage_account_name"` + Filter string `tfschema:"filter"` + Select []string `tfschema:"select"` + Items []TableEntityDataSourceModel `tfschema:"items"` } -type TableEntitiyDataSourceModel struct { +type TableEntityDataSourceModel struct { PartitionKey string `tfschema:"partition_key"` RowKey string `tfschema:"row_key"` Properties map[string]interface{} `tfschema:"properties"` @@ -123,7 +123,7 @@ func (k storageTableEntitiesDataSource) Read() sdk.ResourceFunc { return fmt.Errorf("the parent Storage Account %s was not found", model.StorageAccountName) } - client, err := storageClient.TableEntityClient(ctx, *account) + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %s", model.StorageAccountName, account.ResourceGroup, err) } @@ -138,14 +138,14 @@ func (k storageTableEntitiesDataSource) Read() sdk.ResourceFunc { input.PropertyNamesToSelect = &model.Select } - id := parse.NewStorageTableEntitiesId(model.StorageAccountName, storageClient.Environment.StorageEndpointSuffix, model.TableName, model.Filter) + id := parse.NewStorageTableEntitiesId(model.StorageAccountName, storageClient.StorageDomainSuffix, model.TableName, model.Filter) - result, err := client.Query(ctx, model.StorageAccountName, model.TableName, input) + result, err := client.Query(ctx, model.TableName, input) if err != nil { return fmt.Errorf("retrieving Entities (Filter %q) (Table %q / Storage Account %q / Resource Group %q): %s", model.Filter, model.TableName, model.StorageAccountName, account.ResourceGroup, err) } - var flattenedEntities []TableEntitiyDataSourceModel + var flattenedEntities []TableEntityDataSourceModel for _, entity := range result.Entities { flattenedEntity := flattenEntityWithMetadata(entity) if len(flattenedEntity.Properties) == 0 { @@ -163,10 +163,10 @@ func (k storageTableEntitiesDataSource) Read() sdk.ResourceFunc { } // The api returns extra information that we already have. We'll remove it here before setting it in state. -func flattenEntityWithMetadata(entity map[string]interface{}) TableEntitiyDataSourceModel { +func flattenEntityWithMetadata(entity map[string]interface{}) TableEntityDataSourceModel { delete(entity, "Timestamp") - result := TableEntitiyDataSourceModel{} + result := TableEntityDataSourceModel{} for k, v := range entity { properties := map[string]interface{}{} diff --git a/internal/services/storage/storage_table_entity_data_source.go b/internal/services/storage/storage_table_entity_data_source.go index 8cda4c4950f0..75ca7869a123 100644 --- a/internal/services/storage/storage_table_entity_data_source.go +++ b/internal/services/storage/storage_table_entity_data_source.go @@ -12,7 +12,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" ) func dataSourceStorageTableEntity() *pluginsdk.Resource { @@ -64,25 +65,30 @@ func dataSourceStorageTableEntityRead(d *pluginsdk.ResourceData, meta interface{ defer cancel() storageClient := meta.(*clients.Client).Storage - storageAccountName := d.Get("storage_account_name").(string) + accountName := d.Get("storage_account_name").(string) tableName := d.Get("table_name").(string) partitionKey := d.Get("partition_key").(string) rowKey := d.Get("row_key").(string) - account, err := storageClient.FindAccount(ctx, storageAccountName) + account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", storageAccountName, tableName, err) + return fmt.Errorf("retrieving Account %q for Table %q: %v", accountName, tableName, err) } if account == nil { - return fmt.Errorf("the parent Storage Account %s was not found", storageAccountName) + return fmt.Errorf("the parent Storage Account %s was not found", accountName) } - client, err := storageClient.TableEntityClient(ctx, *account) + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %s", storageAccountName, account.ResourceGroup, err) + return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %v", accountName, account.ResourceGroup, err) } - id := client.GetResourceID(storageAccountName, tableName, partitionKey, rowKey) + accountId, err := accounts.ParseAccountID(accountName, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := entities.NewEntityID(*accountId, tableName, partitionKey, rowKey) input := entities.GetEntityInput{ PartitionKey: partitionKey, @@ -90,19 +96,21 @@ func dataSourceStorageTableEntityRead(d *pluginsdk.ResourceData, meta interface{ MetaDataLevel: entities.NoMetaData, } - result, err := client.Get(ctx, storageAccountName, tableName, input) + result, err := client.Get(ctx, tableName, input) if err != nil { - return fmt.Errorf("retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", partitionKey, rowKey, tableName, storageAccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } - d.Set("storage_account_name", storageAccountName) + d.Set("storage_account_name", accountName) d.Set("table_name", tableName) d.Set("partition_key", partitionKey) d.Set("row_key", rowKey) - if err := d.Set("entity", flattenEntity(result.Entity)); err != nil { - return fmt.Errorf("setting `entity` for Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", partitionKey, rowKey, tableName, storageAccountName, account.ResourceGroup, err) + + if err = d.Set("entity", flattenEntity(result.Entity)); err != nil { + return fmt.Errorf("setting `entity` for %s: %v", id, err) } - d.SetId(id) + + d.SetId(id.ID()) return nil } diff --git a/internal/services/storage/storage_table_entity_resource.go b/internal/services/storage/storage_table_entity_resource.go index ae5d8e334577..3ede566cb41d 100644 --- a/internal/services/storage/storage_table_entity_resource.go +++ b/internal/services/storage/storage_table_entity_resource.go @@ -9,25 +9,30 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) func resourceStorageTableEntity() *pluginsdk.Resource { return &pluginsdk.Resource{ - Create: resourceStorageTableEntityCreateUpdate, + Create: resourceStorageTableEntityCreate, Read: resourceStorageTableEntityRead, - Update: resourceStorageTableEntityCreateUpdate, + Update: resourceStorageTableEntityUpdate, Delete: resourceStorageTableEntityDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := entities.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := entities.ParseEntityID(id, storageDomainSuffix) return err }), @@ -39,30 +44,48 @@ func resourceStorageTableEntity() *pluginsdk.Resource { }, Schema: map[string]*pluginsdk.Schema{ + "storage_table_id": { + Type: pluginsdk.TypeString, + Optional: true, // TODO: make required and forcenew in v4.0 + Computed: true, // TODO: remove computed in v4.0 + ConflictsWith: []string{"table_name", "storage_account_name"}, + ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL + }, + "table_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validate.StorageTableName, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + Deprecated: "the `table_name` and `storage_account_name` properties have been superseded by the `storage_table_id` property and will be removed in version 4.0 of the AzureRM provider", + ConflictsWith: []string{"storage_table_id"}, + RequiredWith: []string{"storage_account_name"}, + ValidateFunc: validate.StorageTableName, }, + "storage_account_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validate.StorageAccountName, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + Deprecated: "the `table_name` and `storage_account_name` properties have been superseded by the `storage_table_id` property and will be removed in version 4.0 of the AzureRM provider", + ConflictsWith: []string{"storage_table_id"}, + RequiredWith: []string{"table_name"}, + ValidateFunc: validate.StorageAccountName, }, + "partition_key": { Type: pluginsdk.TypeString, Required: true, ForceNew: true, ValidateFunc: validation.StringIsNotEmpty, }, + "row_key": { Type: pluginsdk.TypeString, Required: true, ForceNew: true, ValidateFunc: validation.StringIsNotEmpty, }, + "entity": { Type: pluginsdk.TypeMap, Required: true, @@ -74,67 +97,142 @@ func resourceStorageTableEntity() *pluginsdk.Resource { } } -func resourceStorageTableEntityCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { - ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) +func resourceStorageTableEntityCreate(d *pluginsdk.ResourceData, meta interface{}) error { + ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) defer cancel() storageClient := meta.(*clients.Client).Storage - accountName := d.Get("storage_account_name").(string) - tableName := d.Get("table_name").(string) partitionKey := d.Get("partition_key").(string) rowKey := d.Get("row_key").(string) - entity := d.Get("entity").(map[string]interface{}) - account, err := storageClient.FindAccount(ctx, accountName) + var storageTableId *tables.TableId + var err error + if v, ok := d.GetOk("storage_table_id"); ok && v.(string) != "" { + storageTableId, err = tables.ParseTableID(v.(string), storageClient.StorageDomainSuffix) + if err != nil { + return err + } + } else { + // TODO: this is needed until `table_name` / `storage_account_name` are removed in favor of `storage_table_id` in v4.0 + // we will retrieve the storage account twice but this will make it easier to refactor later + storageAccountName := d.Get("storage_account_name").(string) + + account, err := storageClient.FindAccount(ctx, storageAccountName) + if err != nil { + return fmt.Errorf("retrieving Account %q: %v", storageAccountName, err) + } + if account == nil { + return fmt.Errorf("locating Storage Account %q", storageAccountName) + } + + // Determine the table endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeTable) + if err != nil { + return fmt.Errorf("determining Table endpoint: %v", err) + } + + // Parse the table endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + storageTableId = pointer.To(tables.NewTableID(*accountId, d.Get("table_name").(string))) + } + + if storageTableId == nil { + return fmt.Errorf("determining storage table ID") + } + + account, err := storageClient.FindAccount(ctx, storageTableId.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", accountName, tableName, err) + return fmt.Errorf("retrieving Account %q for Table %q: %v", storageTableId.AccountId.AccountName, storageTableId.TableName, err) } if account == nil { - if d.IsNewResource() { - return fmt.Errorf("Unable to locate Account %q for Storage Table %q", accountName, tableName) - } else { - log.Printf("[DEBUG] Unable to locate Account %q for Storage Table %q - assuming removed & removing from state", accountName, tableName) - d.SetId("") - return nil - } + return fmt.Errorf("locating Storage Account %q for Table %q", storageTableId.AccountId.AccountName, storageTableId.TableName) } - client, err := storageClient.TableEntityClient(ctx, *account) + accountId, err := accounts.ParseAccountID(storageTableId.ID(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("building Entity Client: %s", err) + return fmt.Errorf("parsing Account ID: %s", err) } - if d.IsNewResource() { - input := entities.GetEntityInput{ - PartitionKey: partitionKey, - RowKey: rowKey, - MetaDataLevel: entities.NoMetaData, - } - existing, err := client.Get(ctx, accountName, tableName, input) - if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", partitionKey, rowKey, tableName, accountName, account.ResourceGroup, err) - } - } + id := entities.NewEntityID(*accountId, storageTableId.TableName, partitionKey, rowKey) - if !utils.ResponseWasNotFound(existing.Response) { - id := client.GetResourceID(accountName, tableName, partitionKey, rowKey) - return tf.ImportAsExistsError("azurerm_storage_table_entity", id) + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Entity Client: %v", err) + } + + getEntityInput := entities.GetEntityInput{ + PartitionKey: partitionKey, + RowKey: rowKey, + MetaDataLevel: entities.NoMetaData, + } + existing, err := client.Get(ctx, storageTableId.TableName, getEntityInput) + if err != nil { + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for existing %s: %v", id, err) } } + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_table_entity", id.ID()) + } + input := entities.InsertOrMergeEntityInput{ PartitionKey: partitionKey, RowKey: rowKey, - Entity: entity, + Entity: d.Get("entity").(map[string]interface{}), + } + + if _, err = client.InsertOrMerge(ctx, storageTableId.TableName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) + } + + d.SetId(id.ID()) + + return resourceStorageTableEntityRead(d, meta) +} + +func resourceStorageTableEntityUpdate(d *pluginsdk.ResourceData, meta interface{}) error { + ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + storageClient := meta.(*clients.Client).Storage + + id, err := entities.ParseEntityID(d.Id(), storageClient.StorageDomainSuffix) + if err != nil { + return err + } + + storageTableId := tables.NewTableID(id.AccountId, id.TableName) + + account, err := storageClient.FindAccount(ctx, storageTableId.AccountId.AccountName) + if err != nil { + return fmt.Errorf("retrieving Account %q for Table %q: %v", storageTableId.AccountId.AccountName, storageTableId.TableName, err) + } + if account == nil { + log.Printf("[DEBUG] Unable to locate Storage Account %q for Table %q - assuming removed & removing from state", storageTableId.AccountId.AccountName, storageTableId.TableName) + d.SetId("") + return nil } - if _, err := client.InsertOrMerge(ctx, accountName, tableName, input); err != nil { - return fmt.Errorf("creating Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %+v", partitionKey, rowKey, tableName, accountName, account.ResourceGroup, err) + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Entity Client: %v", err) } - resourceID := client.GetResourceID(accountName, tableName, partitionKey, rowKey) - d.SetId(resourceID) + input := entities.InsertOrMergeEntityInput{ + PartitionKey: d.Get("partition_key").(string), + RowKey: d.Get("row_key").(string), + Entity: d.Get("entity").(map[string]interface{}), + } + + if _, err = client.InsertOrMerge(ctx, storageTableId.TableName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) + } + + d.SetId(id.ID()) return resourceStorageTableEntityRead(d, meta) } @@ -144,24 +242,26 @@ func resourceStorageTableEntityRead(d *pluginsdk.ResourceData, meta interface{}) defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := entities.ParseResourceID(d.Id()) + id, err := entities.ParseEntityID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.TableName, err) + return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountId.AccountName, id.TableName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Resource Group for Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountName) + log.Printf("[WARN] Unable to determine Resource Group for Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountId.AccountName) d.SetId("") return nil } - client, err := storageClient.TableEntityClient(ctx, *account) + storageTableId := tables.NewTableID(id.AccountId, id.TableName) + + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountId.AccountName, account.ResourceGroup, err) } input := entities.GetEntityInput{ @@ -170,17 +270,19 @@ func resourceStorageTableEntityRead(d *pluginsdk.ResourceData, meta interface{}) MetaDataLevel: entities.FullMetaData, } - result, err := client.Get(ctx, id.AccountName, id.TableName, input) + result, err := client.Get(ctx, id.TableName, input) if err != nil { - return fmt.Errorf("retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } - d.Set("storage_account_name", id.AccountName) + d.Set("storage_table_id", storageTableId.ID()) + d.Set("storage_account_name", id.AccountId.AccountName) d.Set("table_name", id.TableName) d.Set("partition_key", id.PartitionKey) d.Set("row_key", id.RowKey) - if err := d.Set("entity", flattenEntity(result.Entity)); err != nil { - return fmt.Errorf("setting `entity` for Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, account.ResourceGroup, err) + + if err = d.Set("entity", flattenEntity(result.Entity)); err != nil { + return fmt.Errorf("setting `entity` for %s: %v", id, err) } return nil @@ -191,22 +293,22 @@ func resourceStorageTableEntityDelete(d *pluginsdk.ResourceData, meta interface{ defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := entities.ParseResourceID(d.Id()) + id, err := entities.ParseEntityID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.TableName, err) + return fmt.Errorf("retrieving Storage Account %q for Table %q: %s", id.AccountId.AccountName, id.TableName, err) } if account == nil { - return fmt.Errorf("Storage Account %q was not found!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.TableEntityClient(ctx, *account) + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountId.AccountName, account.ResourceGroup, err) } input := entities.DeleteEntityInput{ @@ -214,8 +316,8 @@ func resourceStorageTableEntityDelete(d *pluginsdk.ResourceData, meta interface{ RowKey: id.RowKey, } - if _, err := client.Delete(ctx, id.AccountName, id.TableName, input); err != nil { - return fmt.Errorf("deleting Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, account.ResourceGroup, err) + if _, err = client.Delete(ctx, id.TableName, input); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_table_entity_resource_test.go b/internal/services/storage/storage_table_entity_resource_test.go index c2edacd39f65..aca908ee7ed2 100644 --- a/internal/services/storage/storage_table_entity_resource_test.go +++ b/internal/services/storage/storage_table_entity_resource_test.go @@ -8,12 +8,13 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" ) type StorageTableEntityResource struct{} @@ -33,6 +34,52 @@ func TestAccTableEntity_basic(t *testing.T) { }) } +func TestAccTableEntity_basicDeprecated(t *testing.T) { + // TODO: remove test in v4.0 + data := acceptance.BuildTestData(t, "azurerm_storage_table_entity", "test") + r := StorageTableEntityResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccTableEntity_migrateStorageTableId(t *testing.T) { + // TODO: remove test in v4.0 + data := acceptance.BuildTestData(t, "azurerm_storage_table_entity", "test") + r := StorageTableEntityResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccTableEntity_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_storage_table_entity", "test") r := StorageTableEntityResource{} @@ -70,7 +117,7 @@ func TestAccTableEntity_update(t *testing.T) { }) } -func TestAccTableEntity_update_typed(t *testing.T) { +func TestAccTableEntity_updateTyped(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_storage_table_entity", "test") r := StorageTableEntityResource{} data.ResourceTest(t, r, []acceptance.TestStep{ @@ -82,32 +129,32 @@ func TestAccTableEntity_update_typed(t *testing.T) { }, data.ImportStep(), { - Config: r.updated_typed(data), + Config: r.updateType(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), }, data.ImportStep(), { - Config: r.updated_typedInt64(data), + Config: r.updatedTypeInt64(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), }, { - Config: r.updated_typedDouble(data), + Config: r.updatedTypeDouble(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), }, { - Config: r.updated_typedString(data), + Config: r.updateTypeString(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), }, { - Config: r.updated_typedBoolean(data), + Config: r.updateTypeBoolean(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -116,19 +163,19 @@ func TestAccTableEntity_update_typed(t *testing.T) { } func (r StorageTableEntityResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := entities.ParseResourceID(state.ID) + id, err := entities.ParseEntityID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Table %q: %+v", id.AccountName, id.TableName, err) + return nil, fmt.Errorf("retrieving Account %q for Table %q: %+v", id.AccountId.AccountName, id.TableName, err) } if account == nil { - return nil, fmt.Errorf("storage Account %q was not found", id.AccountName) + return nil, fmt.Errorf("storage Account %q was not found", id.AccountId.AccountName) } - entitiesClient, err := client.Storage.TableEntityClient(ctx, *account) + entitiesClient, err := client.Storage.TableEntityDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Table Entity Client: %+v", err) } @@ -138,12 +185,12 @@ func (r StorageTableEntityResource) Exists(ctx context.Context, client *clients. RowKey: id.RowKey, MetaDataLevel: entities.NoMetaData, } - resp, err := entitiesClient.Get(ctx, id.AccountName, id.TableName, input) + resp, err := entitiesClient.Get(ctx, id.TableName, input) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %+v", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %+v", id.PartitionKey, id.RowKey, id.TableName, id.AccountId.AccountName, account.ResourceGroup, err) } return utils.Bool(true), nil } @@ -151,129 +198,140 @@ func (r StorageTableEntityResource) Exists(ctx context.Context, client *clients. func (r StorageTableEntityResource) basic(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` -%s +%[1]s + +resource "azurerm_storage_table_entity" "test" { + storage_table_id = azurerm_storage_table.test.id + + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" + entity = { + Foo = "Bar" + } +} +`, template, data.RandomInteger) +} + +func (r StorageTableEntityResource) basicDeprecated(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%[1]s resource "azurerm_storage_table_entity" "test" { storage_account_name = azurerm_storage_account.test.name table_name = azurerm_storage_table.test.name - partition_key = "test_partition%d" - row_key = "test_row%d" + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" entity = { Foo = "Bar" } } -`, template, data.RandomInteger, data.RandomInteger) +`, template, data.RandomInteger) } func (r StorageTableEntityResource) requiresImport(data acceptance.TestData) string { template := r.basic(data) return fmt.Sprintf(` -%s +%[1]s resource "azurerm_storage_table_entity" "import" { - storage_account_name = azurerm_storage_account.test.name - table_name = azurerm_storage_table.test.name + storage_table_id = azurerm_storage_table.test.id - partition_key = "test_partition%d" - row_key = "test_row%d" + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" entity = { Foo = "Bar" } } -`, template, data.RandomInteger, data.RandomInteger) +`, template, data.RandomInteger) } func (r StorageTableEntityResource) updated(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` -%s +%[1]s resource "azurerm_storage_table_entity" "test" { - storage_account_name = azurerm_storage_account.test.name - table_name = azurerm_storage_table.test.name + storage_table_id = azurerm_storage_table.test.id - partition_key = "test_partition%d" - row_key = "test_row%d" + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" entity = { Foo = "Bar" Test = "Updated" } } -`, template, data.RandomInteger, data.RandomInteger) +`, template, data.RandomInteger) } -func (r StorageTableEntityResource) updated_typed(data acceptance.TestData) string { +func (r StorageTableEntityResource) updateType(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` -%s +%[1]s resource "azurerm_storage_table_entity" "test" { - storage_account_name = azurerm_storage_account.test.name - table_name = azurerm_storage_table.test.name + storage_table_id = azurerm_storage_table.test.id - partition_key = "test_partition%d" - row_key = "test_row%d" + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" entity = { Foo = 123 "Foo@odata.type" = "Edm.Int32" Test = "Updated" } } -`, template, data.RandomInteger, data.RandomInteger) +`, template, data.RandomInteger) } -func (r StorageTableEntityResource) updated_typedInt64(data acceptance.TestData) string { +func (r StorageTableEntityResource) updatedTypeInt64(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` -%s +%[1]s resource "azurerm_storage_table_entity" "test" { - storage_account_name = azurerm_storage_account.test.name - table_name = azurerm_storage_table.test.name + storage_table_id = azurerm_storage_table.test.id - partition_key = "test_partition%d" - row_key = "test_row%d" + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" entity = { Foo = 123 "Foo@odata.type" = "Edm.Int64" Test = "Updated" } } -`, template, data.RandomInteger, data.RandomInteger) +`, template, data.RandomInteger) } -func (r StorageTableEntityResource) updated_typedDouble(data acceptance.TestData) string { +func (r StorageTableEntityResource) updatedTypeDouble(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` -%s +%[1]s resource "azurerm_storage_table_entity" "test" { - storage_account_name = azurerm_storage_account.test.name - table_name = azurerm_storage_table.test.name + storage_table_id = azurerm_storage_table.test.id - partition_key = "test_partition%d" - row_key = "test_row%d" + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" entity = { Foo = 123.123 "Foo@odata.type" = "Edm.Double" Test = "Updated" } } -`, template, data.RandomInteger, data.RandomInteger) +`, template, data.RandomInteger) } -func (r StorageTableEntityResource) updated_typedString(data acceptance.TestData) string { +func (r StorageTableEntityResource) updateTypeString(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` -%s +%[1]s resource "azurerm_storage_table_entity" "test" { - storage_account_name = azurerm_storage_account.test.name - table_name = azurerm_storage_table.test.name + storage_table_id = azurerm_storage_table.test.id - partition_key = "test_partition%d" - row_key = "test_row%d" + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" entity = { Foo = "123.123" "Foo@odata.type" = "Edm.String" @@ -283,27 +341,26 @@ resource "azurerm_storage_table_entity" "test" { ignore_changes = [entity] } } -`, template, data.RandomInteger, data.RandomInteger) +`, template, data.RandomInteger) } -func (r StorageTableEntityResource) updated_typedBoolean(data acceptance.TestData) string { +func (r StorageTableEntityResource) updateTypeBoolean(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` -%s +%[1]s resource "azurerm_storage_table_entity" "test" { - storage_account_name = azurerm_storage_account.test.name - table_name = azurerm_storage_table.test.name + storage_table_id = azurerm_storage_table.test.id - partition_key = "test_partition%d" - row_key = "test_row%d" + partition_key = "test_partition%[2]d" + row_key = "test_row%[2]d" entity = { Foo = "true" "Foo@odata.type" = "Edm.Boolean" Test = "Updated" } } -`, template, data.RandomInteger, data.RandomInteger) +`, template, data.RandomInteger) } func (r StorageTableEntityResource) template(data acceptance.TestData) string { @@ -313,12 +370,12 @@ provider "azurerm" { } resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" + name = "acctestRG-%[1]d" + location = "%[2]s" } resource "azurerm_storage_account" "test" { - name = "acctestsa%s" + name = "acctestsa%[3]s" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location account_tier = "Standard" @@ -326,8 +383,8 @@ resource "azurerm_storage_account" "test" { } resource "azurerm_storage_table" "test" { - name = "acctestst%d" + name = "acctestst%[1]d" storage_account_name = azurerm_storage_account.test.name } -`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomInteger) +`, data.RandomInteger, data.Locations.Primary, data.RandomString) } diff --git a/internal/services/storage/storage_table_resource.go b/internal/services/storage/storage_table_resource.go index 21581f05798c..598ee58ae5b0 100644 --- a/internal/services/storage/storage_table_resource.go +++ b/internal/services/storage/storage_table_resource.go @@ -10,13 +10,15 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) func resourceStorageTable() *pluginsdk.Resource { @@ -26,8 +28,8 @@ func resourceStorageTable() *pluginsdk.Resource { Delete: resourceStorageTableDelete, Update: resourceStorageTableUpdate, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.StorageTableDataPlaneID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := tables.ParseTableID(id, storageDomainSuffix) return err }), @@ -114,32 +116,44 @@ func resourceStorageTableCreate(d *pluginsdk.ResourceData, meta interface{}) err return fmt.Errorf("retrieving Account %q for Table %q: %s", accountName, tableName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - client, err := storageClient.TablesClient(ctx, *account) + tablesDataPlaneClient, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Table Client: %s", err) } - id := parse.NewStorageTableDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, tableName).ID() + // Determine the table endpoint, so we can build a data plane ID + endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeTable) + if err != nil { + return fmt.Errorf("determining Table endpoint: %v", err) + } + + // Parse the table endpoint as a data plane account ID + accountId, err := accounts.ParseAccountID(*endpoint, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } - exists, err := client.Exists(ctx, account.ResourceGroup, accountName, tableName) + id := tables.NewTableID(*accountId, tableName) + + exists, err := tablesDataPlaneClient.Exists(ctx, tableName) if err != nil { - return fmt.Errorf("checking for existence of existing Storage Table %q (Account %q / Resource Group %q): %+v", tableName, accountName, account.ResourceGroup, err) + return fmt.Errorf("checking for existing %s: %v", id, err) } if exists != nil && *exists { - return tf.ImportAsExistsError("azurerm_storage_table", id) + return tf.ImportAsExistsError("azurerm_storage_table", id.ID()) } - log.Printf("[DEBUG] Creating Table %q in Storage Account %q.", tableName, accountName) - if err := client.Create(ctx, account.ResourceGroup, accountName, tableName); err != nil { - return fmt.Errorf("creating Table %q within Storage Account %q: %s", tableName, accountName, err) + if err = tablesDataPlaneClient.Create(ctx, tableName); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - d.SetId(id) - if err := client.UpdateACLs(ctx, account.ResourceGroup, accountName, tableName, acls); err != nil { - return fmt.Errorf("setting ACL's for Storage Table %q (Account %q / Resource Group %q): %+v", tableName, accountName, account.ResourceGroup, err) + d.SetId(id.ID()) + + if err = tablesDataPlaneClient.UpdateACLs(ctx, tableName, acls); err != nil { + return fmt.Errorf("setting ACLs for %s: %v", id, err) } return resourceStorageTableRead(d, meta) @@ -150,46 +164,46 @@ func resourceStorageTableRead(d *pluginsdk.ResourceData, meta interface{}) error ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageTableDataPlaneID(d.Id()) + id, err := tables.ParseTableID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Storage Account %q for Table %q: %v", id.AccountId.AccountName, id.TableName, err) } if account == nil { - log.Printf("Unable to determine Resource Group for Storage Storage Table %q (Account %s) - assuming removed & removing from state", id.Name, id.AccountName) + log.Printf("Unable to determine Resource Group for Storage Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountId.AccountName) d.SetId("") return nil } - client, err := storageClient.TablesClient(ctx, *account) + client, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Client: %s", err) + return fmt.Errorf("building Tables Client: %v", err) } - exists, err := client.Exists(ctx, account.ResourceGroup, id.AccountName, id.Name) + exists, err := client.Exists(ctx, id.TableName) if err != nil { - return fmt.Errorf("retrieving Table %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if exists == nil || !*exists { - log.Printf("[DEBUG] Storage Account %q not found, removing table %q from state", id.AccountName, id.Name) + log.Printf("[DEBUG] %s not found, removing from state", id) d.SetId("") return nil } - acls, err := client.GetACLs(ctx, account.ResourceGroup, id.AccountName, id.Name) + acls, err := client.GetACLs(ctx, id.TableName) if err != nil { - return fmt.Errorf("retrieving ACL's %q in Storage Account %q: %s", id.Name, id.AccountName, err) + return fmt.Errorf("retrieving ACLs for %s: %v", id, err) } - d.Set("name", id.Name) - d.Set("storage_account_name", id.AccountName) + d.Set("name", id.TableName) + d.Set("storage_account_name", id.AccountId.AccountName) - if err := d.Set("acl", flattenStorageTableACLs(acls)); err != nil { - return fmt.Errorf("flattening `acl`: %+v", err) + if err = d.Set("acl", flattenStorageTableACLs(acls)); err != nil { + return fmt.Errorf("setting `acl`: %v", err) } return nil @@ -200,27 +214,26 @@ func resourceStorageTableDelete(d *pluginsdk.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageTableDataPlaneID(d.Id()) + id, err := tables.ParseTableID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Storage Account %q for Table %q: %v", id.AccountId.AccountName, id.TableName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.TablesClient(ctx, *account) + client, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Client: %s", err) + return fmt.Errorf("building Tables Client: %v", err) } - log.Printf("[INFO] Deleting Table %q in Storage Account %q", id.Name, id.AccountName) - if err := client.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return fmt.Errorf("deleting Table %q from Storage Account %q: %s", id.Name, id.AccountName, err) + if err = client.Delete(ctx, id.TableName); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil @@ -231,35 +244,35 @@ func resourceStorageTableUpdate(d *pluginsdk.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageTableDataPlaneID(d.Id()) + id, err := tables.ParseTableID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Storage Account %q for Table %q: %v", id.AccountId.AccountName, id.TableName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.TablesClient(ctx, *account) + client, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Client: %s", err) + return fmt.Errorf("building Table Client: %v", err) } if d.HasChange("acl") { - log.Printf("[DEBUG] Updating the ACL's for Storage Table %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating ACLs for %s", id) aclsRaw := d.Get("acl").(*pluginsdk.Set).List() acls := expandStorageTableACLs(aclsRaw) - if err := client.UpdateACLs(ctx, account.ResourceGroup, id.AccountName, id.Name, acls); err != nil { - return fmt.Errorf("updating ACL's for Table %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateACLs(ctx, id.TableName, acls); err != nil { + return fmt.Errorf("updating ACLs for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the ACL's for Storage Table %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated ACLs for %s", id) } return resourceStorageTableRead(d, meta) diff --git a/internal/services/storage/storage_table_resource_test.go b/internal/services/storage/storage_table_resource_test.go index 683ac23e0287..053d23d768d8 100644 --- a/internal/services/storage/storage_table_resource_test.go +++ b/internal/services/storage/storage_table_resource_test.go @@ -11,9 +11,9 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) type StorageTableResource struct{} @@ -83,51 +83,51 @@ func TestAccStorageTable_acl(t *testing.T) { } func (r StorageTableResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageTableDataPlaneID(state.ID) + id, err := tables.ParseTableID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Table %q: %+v", id.AccountName, id.Name, err) + return nil, fmt.Errorf("retrieving Account %q for Table %q: %+v", id.AccountId.AccountName, id.TableName, err) } if account == nil { - return nil, fmt.Errorf("unable to determine Resource Group for Storage Storage Table %q (Account %q)", id.Name, id.AccountName) + return nil, fmt.Errorf("unable to determine Resource Group for Storage Storage Table %q (Account %q)", id.TableName, id.AccountId.AccountName) } - tablesClient, err := client.Storage.TablesClient(ctx, *account) + tablesClient, err := client.Storage.TablesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Table Client: %+v", err) } - return tablesClient.Exists(ctx, account.ResourceGroup, id.AccountName, id.Name) + return tablesClient.Exists(ctx, id.TableName) } func (r StorageTableResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageTableDataPlaneID(state.ID) + id, err := tables.ParseTableID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Table %q: %+v", id.AccountName, id.Name, err) + return nil, fmt.Errorf("retrieving Account %q for Table %q: %+v", id.AccountId.AccountName, id.TableName, err) } if account == nil { - return nil, fmt.Errorf("unable to determine Resource Group for Storage Storage Table %q (Account %q)", id.Name, id.AccountName) + return nil, fmt.Errorf("unable to determine Resource Group for Storage Storage Table %q (Account %q)", id.TableName, id.AccountId.AccountName) } - tablesClient, err := client.Storage.TablesClient(ctx, *account) + tablesClient, err := client.Storage.TablesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Table Client: %+v", err) } - exists, err := tablesClient.Exists(ctx, account.ResourceGroup, id.AccountName, id.Name) + exists, err := tablesClient.Exists(ctx, id.TableName) if err != nil { - return nil, fmt.Errorf("retrieving Table %q (Account %q): %+v", id.Name, id.AccountName, err) + return nil, fmt.Errorf("retrieving Table %q (Account %q): %+v", id.TableName, id.AccountId.AccountName, err) } if exists == nil || !*exists { - return nil, fmt.Errorf("table %q doesn't exist in Account %q so it can't be deleted", id.Name, id.AccountName) + return nil, fmt.Errorf("table %q doesn't exist in Account %q so it can't be deleted", id.TableName, id.AccountId.AccountName) } - if err := tablesClient.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return nil, fmt.Errorf("deleting Table %q (Account %q): %+v", id.Name, id.AccountName, err) + if err := tablesClient.Delete(ctx, id.TableName); err != nil { + return nil, fmt.Errorf("deleting Table %q (Account %q): %+v", id.TableName, id.AccountId.AccountName, err) } return utils.Bool(true), nil } diff --git a/internal/services/storage/validate/storage_blob_properties_default_service_version.go b/internal/services/storage/validate/storage_blob_properties_default_service_version.go index f6f3e8611411..6852d4bf1177 100644 --- a/internal/services/storage/validate/storage_blob_properties_default_service_version.go +++ b/internal/services/storage/validate/storage_blob_properties_default_service_version.go @@ -39,7 +39,7 @@ func BlobPropertiesDefaultServiceVersion(i interface{}, k string) (warnings []st "2020-02-10", "2020-04-08", "2020-06-12", - "2020-08-04", + "2023-11-03", "2020-10-02", "2020-12-06", "2021-02-12", diff --git a/internal/services/storage/validate/storage_container.go b/internal/services/storage/validate/storage_container.go index 365e785a3495..bb378de43f13 100644 --- a/internal/services/storage/validate/storage_container.go +++ b/internal/services/storage/validate/storage_container.go @@ -6,8 +6,6 @@ package validate import ( "fmt" "regexp" - - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" ) func StorageContainerName(v interface{}, k string) (warnings []string, errors []error) { @@ -28,17 +26,3 @@ func StorageContainerName(v interface{}, k string) (warnings []string, errors [] } return warnings, errors } - -func StorageContainerDataPlaneID(input interface{}, key string) (warnings []string, errors []error) { - v, ok := input.(string) - if !ok { - errors = append(errors, fmt.Errorf("expected %q to be a string", key)) - return - } - - if _, err := parse.StorageContainerDataPlaneID(v); err != nil { - errors = append(errors, err) - } - - return -} diff --git a/internal/services/storage/validate/storage_share_name.go b/internal/services/storage/validate/storage_share_name.go index b79e4ee93606..d9a2a03dcf44 100644 --- a/internal/services/storage/validate/storage_share_name.go +++ b/internal/services/storage/validate/storage_share_name.go @@ -6,8 +6,6 @@ package validate import ( "fmt" "regexp" - - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" ) func StorageShareName(v interface{}, k string) (warnings []string, errors []error) { @@ -33,18 +31,3 @@ func StorageShareName(v interface{}, k string) (warnings []string, errors []erro } return warnings, errors } - -func StorageShareID(i interface{}, k string) (warnings []string, errors []error) { - v, ok := i.(string) - if !ok { - errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) - return - } - - if _, err := parse.StorageShareDataPlaneID(v); err != nil { - errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err)) - return - } - - return warnings, errors -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go deleted file mode 100644 index 57a02f34e819..000000000000 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go +++ /dev/null @@ -1,160 +0,0 @@ -package blobs - -import ( - "context" - "fmt" - "net/http" - "strconv" - "strings" - - "github.com/hashicorp/go-azure-sdk/sdk/client" - "github.com/hashicorp/go-azure-sdk/sdk/odata" - "github.com/tombuildsstuff/giovanni/storage/internal/metadata" -) - -type GetSnapshotPropertiesInput struct { - // The ID of the Lease - // This must be specified if a Lease is present on the Blob, else a 403 is returned - LeaseID *string - - // The ID of the Snapshot which should be retrieved - SnapshotID string -} - -// GetSnapshotProperties returns all user-defined metadata, standard HTTP properties, and system properties for -// the specified snapshot of a blob -func (c Client) GetSnapshotProperties(ctx context.Context, containerName, blobName string, input GetSnapshotPropertiesInput) (resp GetPropertiesResponse, err error) { - - if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") - } - - if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") - } - - if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") - } - - if input.SnapshotID == "" { - return resp, fmt.Errorf("`input.SnapshotID` cannot be an empty string") - } - - opts := client.RequestOptions{ - ExpectedStatusCodes: []int{ - http.StatusOK, - }, - HttpMethod: http.MethodHead, - OptionsObject: snapshotGetPropertiesOptions{ - input: input, - }, - Path: fmt.Sprintf("/%s/%s", containerName, blobName), - } - - req, err := c.Client.NewRequest(ctx, opts) - if err != nil { - err = fmt.Errorf("building request: %+v", err) - return - } - - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.AccessTier = AccessTier(resp.HttpResponse.Header.Get("x-ms-access-tier")) - resp.AccessTierChangeTime = resp.HttpResponse.Header.Get("x-ms-access-tier-change-time") - resp.ArchiveStatus = ArchiveStatus(resp.HttpResponse.Header.Get("x-ms-archive-status")) - resp.BlobCommittedBlockCount = resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count") - resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") - resp.BlobType = BlobType(resp.HttpResponse.Header.Get("x-ms-blob-type")) - resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") - resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") - resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") - resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") - resp.CopyDestinationSnapshot = resp.HttpResponse.Header.Get("x-ms-copy-destination-snapshot") - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") - resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") - resp.CopyStatus = CopyStatus(resp.HttpResponse.Header.Get("x-ms-copy-status")) - resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") - resp.CreationTime = resp.HttpResponse.Header.Get("x-ms-creation-time") - resp.ETag = resp.HttpResponse.Header.Get("Etag") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") - resp.LeaseDuration = LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) - resp.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) - resp.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - - if v := resp.HttpResponse.Header.Get("x-ms-access-tier-inferred"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) - return - } - - resp.AccessTierInferred = b - } - - if v := resp.HttpResponse.Header.Get("Content-Length"); v != "" { - i, innerErr := strconv.Atoi(v) - if innerErr != nil { - err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) - } - - resp.ContentLength = int64(i) - } - - if v := resp.HttpResponse.Header.Get("x-ms-incremental-copy"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) - return - } - - resp.IncrementalCopy = b - } - - if v := resp.HttpResponse.Header.Get("x-ms-server-encrypted"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) - return - } - - resp.ServerEncrypted = b - } - } - } - - return -} - -type snapshotGetPropertiesOptions struct { - input GetSnapshotPropertiesInput -} - -func (s snapshotGetPropertiesOptions) ToHeaders() *client.Headers { - headers := &client.Headers{} - if s.input.LeaseID != nil { - headers.Append("x-ms-lease-id", *s.input.LeaseID) - } - return headers -} - -func (s snapshotGetPropertiesOptions) ToOData() *odata.Query { - return nil -} - -func (s snapshotGetPropertiesOptions) ToQuery() *client.QueryParams { - out := &client.QueryParams{} - out.Append("snapshot", s.input.SnapshotID) - return out -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go deleted file mode 100644 index 1acbae869d91..000000000000 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go +++ /dev/null @@ -1,88 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "net/http" - - "github.com/hashicorp/go-azure-sdk/sdk/client" - "github.com/hashicorp/go-azure-sdk/sdk/odata" - "github.com/tombuildsstuff/giovanni/storage/internal/metadata" -) - -type CreateInput struct { - // Specifies whether data in the container may be accessed publicly and the level of access - AccessLevel AccessLevel - - // A name-value pair to associate with the container as metadata. - MetaData map[string]string -} - -type CreateResponse struct { - HttpResponse *client.Response - Error *ErrorResponse `xml:"Error"` -} - -// Create creates a new container under the specified account. -// If the container with the same name already exists, the operation fails. -func (c Client) Create(ctx context.Context, containerName string, input CreateInput) (resp CreateResponse, err error) { - if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") - } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %+v", err) - } - - opts := client.RequestOptions{ - ContentType: "application/xml; charset=utf-8", - ExpectedStatusCodes: []int{ - http.StatusCreated, - }, - HttpMethod: http.MethodPut, - OptionsObject: createOptions{ - accessLevel: input.AccessLevel, - metaData: input.MetaData, - }, - Path: fmt.Sprintf("/%s", containerName), - } - req, err := c.Client.NewRequest(ctx, opts) - if err != nil { - err = fmt.Errorf("building request: %+v", err) - return - } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - - return -} - -var _ client.Options = createOptions{} - -type createOptions struct { - accessLevel AccessLevel - metaData map[string]string -} - -func (o createOptions) ToHeaders() *client.Headers { - headers := containerOptions{ - metaData: o.metaData, - }.ToHeaders() - - // If this header is not included in the request, container data is private to the account owner. - if o.accessLevel != Private { - headers.Append("x-ms-blob-public-access", string(o.accessLevel)) - } - - return headers -} - -func (createOptions) ToOData() *odata.Query { - return nil -} - -func (createOptions) ToQuery() *client.QueryParams { - return containerOptions{}.ToQuery() -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go deleted file mode 100644 index 6a21f7784940..000000000000 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go +++ /dev/null @@ -1,105 +0,0 @@ -package files - -import ( - "context" - "fmt" - "net/http" - "strconv" - "strings" - - "github.com/hashicorp/go-azure-sdk/sdk/client" - "github.com/tombuildsstuff/giovanni/storage/internal/metadata" -) - -type GetResponse struct { - HttpResponse *client.Response - - CacheControl string - ContentDisposition string - ContentEncoding string - ContentLanguage string - ContentLength *int64 - ContentMD5 string - ContentType string - CopyID string - CopyStatus string - CopySource string - CopyProgress string - CopyStatusDescription string - CopyCompletionTime string - Encrypted bool - - MetaData map[string]string -} - -// GetProperties returns the Properties for the specified file -func (c Client) GetProperties(ctx context.Context, shareName, path, fileName string) (resp GetResponse, err error) { - if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") - } - - if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") - } - - if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") - } - - if path != "" { - path = fmt.Sprintf("/%s/", path) - } - - opts := client.RequestOptions{ - ContentType: "application/xml; charset=utf-8", - ExpectedStatusCodes: []int{ - http.StatusOK, - }, - HttpMethod: http.MethodHead, - OptionsObject: nil, - Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), - } - - req, err := c.Client.NewRequest(ctx, opts) - if err != nil { - err = fmt.Errorf("building request: %+v", err) - return - } - - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") - resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") - resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") - resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") - resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") - resp.CopyStatus = resp.HttpResponse.Header.Get("x-ms-copy-status") - resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") - resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") - resp.Encrypted = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-server-encrypted"), "true") - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - - contentLengthRaw := resp.HttpResponse.Header.Get("Content-Length") - if contentLengthRaw != "" { - contentLength, err := strconv.Atoi(contentLengthRaw) - if err != nil { - return resp, fmt.Errorf("error parsing %q for Content-Length as an integer: %s", contentLengthRaw, err) - } - contentLengthI64 := int64(contentLength) - resp.ContentLength = &contentLengthI64 - } - } - } - - return -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/README.md similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/README.md index fd69cf79e810..01fdc3f22ded 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/README.md @@ -1,4 +1,4 @@ -## Blob Storage Account SDK for API version 2020-08-04 +## Blob Storage Account SDK for API version 2023-11-03 This package allows you to interact with the Accounts Blob Storage API @@ -16,7 +16,7 @@ import ( "fmt" "time" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/get_service_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/get_service_properties.go similarity index 63% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/get_service_properties.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/get_service_properties.go index 0c9a51a41117..f230f16a83d7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/get_service_properties.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/get_service_properties.go @@ -9,13 +9,13 @@ import ( ) type GetServicePropertiesResult struct { - HttpResponse *client.Response - Model *StorageServiceProperties + StorageServiceProperties + HttpResponse *http.Response } -func (c Client) GetServiceProperties(ctx context.Context, accountName string) (resp GetServicePropertiesResult, err error) { +func (c Client) GetServiceProperties(ctx context.Context, accountName string) (result GetServicePropertiesResult, err error) { if accountName == "" { - return resp, fmt.Errorf("`accountName` cannot be an empty string") + return result, fmt.Errorf("`accountName` cannot be an empty string") } opts := client.RequestOptions{ @@ -27,23 +27,28 @@ func (c Client) GetServiceProperties(ctx context.Context, accountName string) (r OptionsObject: servicePropertiesOptions{}, Path: "/", } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - if resp.HttpResponse != nil { - if err = resp.HttpResponse.Unmarshal(&resp.Model); err != nil { - err = fmt.Errorf("unmarshaling response: %+v", err) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/models.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/models.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/resource_id.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/resource_id.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/service_properties_shared.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/service_properties_shared.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/service_properties_shared.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/service_properties_shared.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/set_service_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/set_service_properties.go similarity index 71% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/set_service_properties.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/set_service_properties.go index 0be703217d99..d881b049fa5c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/set_service_properties.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/set_service_properties.go @@ -9,12 +9,12 @@ import ( ) type SetServicePropertiesResult struct { - HttpResponse *client.Response + HttpResponse *http.Response } -func (c Client) SetServiceProperties(ctx context.Context, accountName string, input StorageServiceProperties) (resp SetServicePropertiesResult, err error) { +func (c Client) SetServiceProperties(ctx context.Context, accountName string, input StorageServiceProperties) (result SetServicePropertiesResult, err error) { if accountName == "" { - return resp, fmt.Errorf("`accountName` cannot be an empty string") + return result, fmt.Errorf("`accountName` cannot be an empty string") } opts := client.RequestOptions{ @@ -26,16 +26,23 @@ func (c Client) SetServiceProperties(ctx context.Context, accountName string, in OptionsObject: servicePropertiesOptions{}, Path: "/", } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } + if err = req.Marshal(&input); err != nil { err = fmt.Errorf("marshaling request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/version.go similarity index 63% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/version.go index d575c4f40957..427d66da7364 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/version.go @@ -1,4 +1,4 @@ package accounts -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "blob/accounts" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/README.md similarity index 87% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/README.md index aa5ebd16da14..0b26e1cd140f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/README.md @@ -1,4 +1,4 @@ -## Blob Storage Blobs SDK for API version 2020-08-04 +## Blob Storage Blobs SDK for API version 2023-11-03 This package allows you to interact with the Blobs Blob Storage API @@ -18,7 +18,7 @@ import ( "time" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) func Example() error { @@ -30,7 +30,7 @@ func Example() error { blobClient, err := blobs.NewWithBaseUri(fmt.Sprintf("https://%s.blob.%s", accountName, domainSuffix)) if err != nil { - return fmt.Errorf("building client for environment: %+v", err) + return fmt.Errorf("building client for environment: %v", err) } auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/append_block.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/append_block.go index a1068d459c5c..b82558f937d3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/append_block.go @@ -1,10 +1,8 @@ package blobs import ( - "bytes" "context" "fmt" - "io" "net/http" "strconv" "strings" @@ -14,7 +12,6 @@ import ( ) type AppendBlockInput struct { - // A number indicating the byte offset to compare. // Append Block will succeed only if the append position is equal to this number. // If it is not, the request will fail with an AppendPositionConditionNotMet @@ -43,10 +40,13 @@ type AppendBlockInput struct { // Required if the blob has an active lease. // To perform this operation on a blob with an active lease, specify the valid lease ID for this header. LeaseID *string + + // The encryption scope to set for the request content. + EncryptionScope *string } type AppendBlockResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response BlobAppendOffset string BlobCommittedBlockCount int64 @@ -56,22 +56,25 @@ type AppendBlockResponse struct { } // AppendBlock commits a new block of data to the end of an existing append blob. -func (c Client) AppendBlock(ctx context.Context, containerName, blobName string, input AppendBlockInput) (resp AppendBlockResponse, err error) { - +func (c Client) AppendBlock(ctx context.Context, containerName, blobName string, input AppendBlockInput) (result AppendBlockResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.Content != nil && len(*input.Content) > (4*1024*1024) { - return resp, fmt.Errorf("`input.Content` must be at most 4MB") + err = fmt.Errorf("`input.Content` must be at most 4MB") + return } opts := client.RequestOptions{ @@ -91,36 +94,37 @@ func (c Client) AppendBlock(ctx context.Context, containerName, blobName string, return } - if input.Content != nil { - req.Body = io.NopCloser(bytes.NewReader(*input.Content)) - } - - req.ContentLength = int64(len(*input.Content)) - - resp.HttpResponse, err = req.Execute(ctx) + err = req.Marshal(input.Content) if err != nil { - err = fmt.Errorf("executing request: %+v", err) + err = fmt.Errorf("marshalling request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.BlobAppendOffset = resp.HttpResponse.Header.Get("x-ms-blob-append-offset") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ETag = resp.HttpResponse.Header.Get("ETag") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.BlobAppendOffset = resp.Header.Get("x-ms-blob-append-offset") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ETag = resp.Header.Get("ETag") + result.LastModified = resp.Header.Get("Last-Modified") - if v := resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count"); v != "" { + if v := resp.Header.Get("x-ms-blob-committed-block-count"); v != "" { i, innerErr := strconv.Atoi(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-blob-committed-block-count` header value %q: %+v", v, innerErr) return } - resp.BlobCommittedBlockCount = int64(i) + result.BlobCommittedBlockCount = int64(i) } - } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } @@ -143,6 +147,9 @@ func (a appendBlockOptions) ToHeaders() *client.Headers { if a.input.LeaseID != nil { headers.Append("x-ms-lease-id", *a.input.LeaseID) } + if a.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *a.input.EncryptionScope) + } if a.input.Content != nil { headers.Append("Content-Length", strconv.Itoa(len(*a.input.Content))) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy.go similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy.go index 2ff309cc75da..68bf1d816a99 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy.go @@ -103,32 +103,34 @@ type CopyInput struct { // If the source blob has been modified, the Blob service returns status code 412 (Precondition Failed). // This header cannot be specified if the source is an Azure File. SourceIfUnmodifiedSince *string + + // The encryption scope to set for the request content. + EncryptionScope *string } type CopyResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response CopyID string CopyStatus string } // Copy copies a blob to a destination within the storage account asynchronously. -func (c Client) Copy(ctx context.Context, containerName, blobName string, input CopyInput) (resp CopyResponse, err error) { - +func (c Client) Copy(ctx context.Context, containerName, blobName string, input CopyInput) (result CopyResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } if input.CopySource == "" { - return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") + return result, fmt.Errorf("`input.CopySource` cannot be an empty string") } opts := client.RequestOptions{ @@ -148,19 +150,21 @@ func (c Client) Copy(ctx context.Context, containerName, blobName string, input return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopyStatus = resp.Header.Get("x-ms-copy-status") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopyStatus = resp.HttpResponse.Header.Get("x-ms-copy-status") - } - } - return } @@ -216,6 +220,10 @@ func (c copyOptions) ToHeaders() *client.Headers { headers.Append("x-ms-source-if-unmodified-since", *c.input.SourceIfUnmodifiedSince) } + if c.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *c.input.EncryptionScope) + } + headers.Merge(metadata.SetMetaDataHeaders(c.input.MetaData)) return headers diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_abort.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_abort.go index 064c56f09ab8..5d9469a5097c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_abort.go @@ -20,26 +20,29 @@ type AbortCopyInput struct { } type CopyAbortResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // AbortCopy aborts a pending Copy Blob operation, and leaves a destination blob with zero length and full metadata. -func (c Client) AbortCopy(ctx context.Context, containerName, blobName string, input AbortCopyInput) (resp CopyAbortResponse, err error) { - +func (c Client) AbortCopy(ctx context.Context, containerName, blobName string, input AbortCopyInput) (result CopyAbortResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.CopyID == "" { - return resp, fmt.Errorf("`input.CopyID` cannot be an empty string") + err = fmt.Errorf("`input.CopyID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -59,7 +62,11 @@ func (c Client) AbortCopy(ctx context.Context, containerName, blobName string, i return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_and_wait.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_and_wait.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait_poller.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_and_wait_poller.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait_poller.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_and_wait_poller.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete.go index e13aaa599fe6..80c1e4332389 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete.go @@ -21,22 +21,21 @@ type DeleteInput struct { } type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. -func (c Client) Delete(ctx context.Context, containerName, blobName string, input DeleteInput) (resp DeleteResponse, err error) { - +func (c Client) Delete(ctx context.Context, containerName, blobName string, input DeleteInput) (result DeleteResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } opts := client.RequestOptions{ @@ -56,7 +55,11 @@ func (c Client) Delete(ctx context.Context, containerName, blobName string, inpu return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshot.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshot.go index 0407eb1f7829..e5cfa3c8f0b6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshot.go @@ -20,26 +20,29 @@ type DeleteSnapshotInput struct { } type DeleteSnapshotResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // DeleteSnapshot marks a single Snapshot of a Blob for Deletion based on it's DateTime, which will be deleted during the next Garbage Collection cycle. -func (c Client) DeleteSnapshot(ctx context.Context, containerName, blobName string, input DeleteSnapshotInput) (resp DeleteSnapshotResponse, err error) { - +func (c Client) DeleteSnapshot(ctx context.Context, containerName, blobName string, input DeleteSnapshotInput) (result DeleteSnapshotResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.SnapshotDateTime == "" { - return resp, fmt.Errorf("`input.SnapshotDateTime` cannot be an empty string") + err = fmt.Errorf("`input.SnapshotDateTime` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -59,7 +62,11 @@ func (c Client) DeleteSnapshot(ctx context.Context, containerName, blobName stri return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshots.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshots.go index 34b3beb623a8..dd0ce7be20fc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshots.go @@ -17,22 +17,24 @@ type DeleteSnapshotsInput struct { } type DeleteSnapshotsResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // DeleteSnapshots marks all Snapshots of a Blob for Deletion, which will be deleted during the next Garbage Collection Cycle. -func (c Client) DeleteSnapshots(ctx context.Context, containerName, blobName string, input DeleteSnapshotsInput) (resp DeleteSnapshotsResponse, err error) { - +func (c Client) DeleteSnapshots(ctx context.Context, containerName, blobName string, input DeleteSnapshotsInput) (result DeleteSnapshotsResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -52,7 +54,11 @@ func (c Client) DeleteSnapshots(ctx context.Context, containerName, blobName str return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get.go similarity index 67% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get.go index 0f5572a8b9c2..5829324459f5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get.go @@ -17,32 +17,31 @@ type GetInput struct { } type GetResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response - Contents []byte + Contents *[]byte } // Get reads or downloads a blob from the system, including its metadata and properties. -func (c Client) Get(ctx context.Context, containerName, blobName string, input GetInput) (resp GetResponse, err error) { - +func (c Client) Get(ctx context.Context, containerName, blobName string, input GetInput) (result GetResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } if input.LeaseID != nil && *input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` should either be specified or nil, not an empty string") + return result, fmt.Errorf("`input.LeaseID` should either be specified or nil, not an empty string") } if (input.StartByte != nil && input.EndByte == nil) || input.StartByte == nil && input.EndByte != nil { - return resp, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") + return result, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") } opts := client.RequestOptions{ @@ -63,18 +62,22 @@ func (c Client) Get(ctx context.Context, containerName, blobName string, input G return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.Contents = &[]byte{} + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - err = resp.HttpResponse.Unmarshal(&resp.Contents) + err = resp.Unmarshal(result.Contents) if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_block_list.go similarity index 70% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_block_list.go index 9a783cb6ebac..b7c4037d88f0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_block_list.go @@ -17,7 +17,7 @@ type GetBlockListInput struct { } type GetBlockListResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The size of the blob in bytes BlobContentLength *int64 @@ -36,18 +36,17 @@ type GetBlockListResponse struct { } // GetBlockList retrieves the list of blocks that have been uploaded as part of a block blob. -func (c Client) GetBlockList(ctx context.Context, containerName, blobName string, input GetBlockListInput) (resp GetBlockListResponse, err error) { - +func (c Client) GetBlockList(ctx context.Context, containerName, blobName string, input GetBlockListInput) (result GetBlockListResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } opts := client.RequestOptions{ @@ -67,33 +66,37 @@ func (c Client) GetBlockList(ctx context.Context, containerName, blobName string return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.ETag = resp.HttpResponse.Header.Get("ETag") + if resp.Header != nil { + result.ContentType = resp.Header.Get("Content-Type") + result.ETag = resp.Header.Get("ETag") - if v := resp.HttpResponse.Header.Get("x-ms-blob-content-length"); v != "" { + if v := resp.Header.Get("x-ms-blob-content-length"); v != "" { i, innerErr := strconv.Atoi(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-blob-content-length` header value %q: %s", v, innerErr) return } i64 := int64(i) - resp.BlobContentLength = &i64 + result.BlobContentLength = &i64 } } - err = resp.HttpResponse.Unmarshal(&resp) + + err = resp.Unmarshal(&result) if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_page_ranges.go similarity index 66% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_page_ranges.go index 6d0f54163eaa..fe83294cc0b3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_page_ranges.go @@ -19,7 +19,7 @@ type GetPageRangesInput struct { } type GetPageRangesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The size of the blob in bytes ContentLength *int64 @@ -42,22 +42,21 @@ type PageRange struct { } // GetPageRanges returns the list of valid page ranges for a page blob or snapshot of a page blob. -func (c Client) GetPageRanges(ctx context.Context, containerName, blobName string, input GetPageRangesInput) (resp GetPageRangesResponse, err error) { - +func (c Client) GetPageRanges(ctx context.Context, containerName, blobName string, input GetPageRangesInput) (result GetPageRangesResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } - if (input.StartByte != nil && input.EndByte == nil) || input.StartByte == nil && input.EndByte != nil { - return resp, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") + if (input.StartByte != nil && input.EndByte == nil) || (input.StartByte == nil && input.EndByte != nil) { + return result, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") } opts := client.RequestOptions{ @@ -77,34 +76,37 @@ func (c Client) GetPageRanges(ctx context.Context, containerName, blobName strin return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.ETag = resp.HttpResponse.Header.Get("ETag") + if resp.Header != nil { + result.ContentType = resp.Header.Get("Content-Type") + result.ETag = resp.Header.Get("ETag") - if v := resp.HttpResponse.Header.Get("x-ms-blob-content-length"); v != "" { + if v := resp.Header.Get("x-ms-blob-content-length"); v != "" { i, innerErr := strconv.Atoi(v) if innerErr != nil { - err = fmt.Errorf("Error parsing %q as an integer: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-blob-content-length` header value %q: %+v", v, innerErr) return } i64 := int64(i) - resp.ContentLength = &i64 + result.ContentLength = &i64 } } - err = resp.HttpResponse.Unmarshal(&resp) + err = resp.Unmarshal(&result) if err != nil { - return resp, fmt.Errorf("unmarshalling response: %s", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/incremental_copy_blob.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/incremental_copy_blob.go index d059f11e2bc7..0423c0f99e22 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/incremental_copy_blob.go @@ -19,29 +19,32 @@ type IncrementalCopyBlobInput struct { } type IncrementalCopyBlob struct { - HttpResponse *client.Response + HttpResponse *http.Response } // IncrementalCopyBlob copies a snapshot of the source page blob to a destination page blob. // The snapshot is copied such that only the differential changes between the previously copied // snapshot are transferred to the destination. // The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual. -func (c Client) IncrementalCopyBlob(ctx context.Context, containerName, blobName string, input IncrementalCopyBlobInput) (resp IncrementalCopyBlob, err error) { - +func (c Client) IncrementalCopyBlob(ctx context.Context, containerName, blobName string, input IncrementalCopyBlobInput) (result IncrementalCopyBlob, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.CopySource == "" { - return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") + err = fmt.Errorf("`input.CopySource` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -61,7 +64,11 @@ func (c Client) IncrementalCopyBlob(ctx context.Context, containerName, blobName return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_acquire.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_acquire.go index 214808ca0713..d4477564eacc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_acquire.go @@ -24,36 +24,41 @@ type AcquireLeaseInput struct { } type AcquireLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response LeaseID string } // AcquireLease establishes and manages a lock on a blob for write and delete operations. -func (c Client) AcquireLease(ctx context.Context, containerName, blobName string, input AcquireLeaseInput) (resp AcquireLeaseResponse, err error) { - +func (c Client) AcquireLease(ctx context.Context, containerName, blobName string, input AcquireLeaseInput) (result AcquireLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.LeaseID != nil && *input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string, if specified") + err = fmt.Errorf("`input.LeaseID` cannot be an empty string, if specified") + return } if input.ProposedLeaseID != nil && *input.ProposedLeaseID == "" { - return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string, if specified") + err = fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string, if specified") + return } // An infinite lease duration is -1 seconds. A non-infinite lease can be between 15 and 60 seconds if input.LeaseDuration != -1 && (input.LeaseDuration <= 15 || input.LeaseDuration >= 60) { - return resp, fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") + err = fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") + return } opts := client.RequestOptions{ @@ -73,18 +78,20 @@ func (c Client) AcquireLease(ctx context.Context, containerName, blobName string return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.LeaseID = resp.Header.Get("x-ms-lease-id") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.LeaseID = resp.HttpResponse.Header.Get("x-ms-lease-id") - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_break.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_break.go index 858c3061793f..74e689106694 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_break.go @@ -26,7 +26,7 @@ type BreakLeaseInput struct { } type BreakLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // Approximate time remaining in the lease period, in seconds. // If the break is immediate, 0 is returned. @@ -34,22 +34,25 @@ type BreakLeaseResponse struct { } // BreakLease breaks an existing lock on a blob using the LeaseID. -func (c Client) BreakLease(ctx context.Context, containerName, blobName string, input BreakLeaseInput) (resp BreakLeaseResponse, err error) { - +func (c Client) BreakLease(ctx context.Context, containerName, blobName string, input BreakLeaseInput) (result BreakLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") + err = fmt.Errorf("`input.LeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -69,7 +72,11 @@ func (c Client) BreakLease(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_change.go similarity index 70% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_change.go index c69d05483b89..f983d1dd9c6c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_change.go @@ -16,32 +16,36 @@ type ChangeLeaseInput struct { } type ChangeLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response LeaseID string } // ChangeLease changes an existing lock on a blob for another lock. -func (c Client) ChangeLease(ctx context.Context, containerName, blobName string, input ChangeLeaseInput) (resp ChangeLeaseResponse, err error) { - +func (c Client) ChangeLease(ctx context.Context, containerName, blobName string, input ChangeLeaseInput) (result ChangeLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.ExistingLeaseID == "" { - return resp, fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") + err = fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") + return } if input.ProposedLeaseID == "" { - return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") + err = fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -61,18 +65,20 @@ func (c Client) ChangeLease(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.LeaseID = resp.Header.Get("x-ms-lease-id") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.LeaseID = resp.HttpResponse.Header.Get("x-ms-lease-id") - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_release.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_release.go index 350493da229b..2101828b24e1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_release.go @@ -11,7 +11,7 @@ import ( ) type ReleaseLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type ReleaseLeaseInput struct { @@ -19,22 +19,25 @@ type ReleaseLeaseInput struct { } // ReleaseLease releases a lock based on the Lease ID. -func (c Client) ReleaseLease(ctx context.Context, containerName, blobName string, input ReleaseLeaseInput) (resp ReleaseLeaseResponse, err error) { - +func (c Client) ReleaseLease(ctx context.Context, containerName, blobName string, input ReleaseLeaseInput) (result ReleaseLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") + err = fmt.Errorf("`input.LeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -54,7 +57,11 @@ func (c Client) ReleaseLease(ctx context.Context, containerName, blobName string return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_renew.go similarity index 72% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_renew.go index 2a82a0af2a9e..e43a12d96ea9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_renew.go @@ -11,29 +11,32 @@ import ( ) type RenewLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type RenewLeaseInput struct { LeaseID string } -func (c Client) RenewLease(ctx context.Context, containerName, blobName string, input RenewLeaseInput) (resp RenewLeaseResponse, err error) { - +func (c Client) RenewLease(ctx context.Context, containerName, blobName string, input RenewLeaseInput) (result RenewLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") + err = fmt.Errorf("`input.LeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -53,7 +56,11 @@ func (c Client) RenewLease(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/metadata_set.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/metadata_set.go index 604e7a7bd31d..ce6c047d0256 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/metadata_set.go @@ -21,26 +21,29 @@ type SetMetaDataInput struct { } type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetMetaData marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. -func (c Client) SetMetaData(ctx context.Context, containerName, blobName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { - +func (c Client) SetMetaData(ctx context.Context, containerName, blobName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return } opts := client.RequestOptions{ @@ -60,7 +63,11 @@ func (c Client) SetMetaData(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/models.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/models.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_get.go similarity index 72% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_get.go index 86b7c1100bd5..3edfa8900845 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_get.go @@ -19,7 +19,7 @@ type GetPropertiesInput struct { } type GetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The tier of page blob on a premium storage account or tier of block blob on blob storage or general purpose v2 account. AccessTier AccessTier @@ -158,19 +158,24 @@ type GetPropertiesResponse struct { // Is the Storage Account encrypted using server-side encryption? This should always return true ServerEncrypted bool + + // The encryption scope for the request content. + EncryptionScope string } // GetProperties returns all user-defined metadata, standard HTTP properties, and system properties for the blob -func (c Client) GetProperties(ctx context.Context, containerName, blobName string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { - +func (c Client) GetProperties(ctx context.Context, containerName, blobName string, input GetPropertiesInput) (result GetPropertiesResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -190,77 +195,80 @@ func (c Client) GetProperties(ctx context.Context, containerName, blobName strin return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.AccessTier = AccessTier(resp.HttpResponse.Header.Get("x-ms-access-tier")) - resp.AccessTierChangeTime = resp.HttpResponse.Header.Get("x-ms-access-tier-change-time") - resp.ArchiveStatus = ArchiveStatus(resp.HttpResponse.Header.Get("x-ms-archive-status")) - resp.BlobCommittedBlockCount = resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count") - resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") - resp.BlobType = BlobType(resp.HttpResponse.Header.Get("x-ms-blob-type")) - resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") - resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") - resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") - resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") - resp.CopyDestinationSnapshot = resp.HttpResponse.Header.Get("x-ms-copy-destination-snapshot") - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") - resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") - resp.CopyStatus = CopyStatus(resp.HttpResponse.Header.Get("x-ms-copy-status")) - resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") - resp.CreationTime = resp.HttpResponse.Header.Get("x-ms-creation-time") - resp.ETag = resp.HttpResponse.Header.Get("Etag") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") - resp.LeaseDuration = LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) - resp.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) - resp.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - - if v := resp.HttpResponse.Header.Get("x-ms-access-tier-inferred"); v != "" { + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.AccessTier = AccessTier(resp.Header.Get("x-ms-access-tier")) + result.AccessTierChangeTime = resp.Header.Get("x-ms-access-tier-change-time") + result.ArchiveStatus = ArchiveStatus(resp.Header.Get("x-ms-archive-status")) + result.BlobCommittedBlockCount = resp.Header.Get("x-ms-blob-committed-block-count") + result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") + result.BlobType = BlobType(resp.Header.Get("x-ms-blob-type")) + result.CacheControl = resp.Header.Get("Cache-Control") + result.ContentDisposition = resp.Header.Get("Content-Disposition") + result.ContentEncoding = resp.Header.Get("Content-Encoding") + result.ContentLanguage = resp.Header.Get("Content-Language") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ContentType = resp.Header.Get("Content-Type") + result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time") + result.CopyDestinationSnapshot = resp.Header.Get("x-ms-copy-destination-snapshot") + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopyProgress = resp.Header.Get("x-ms-copy-progress") + result.CopySource = resp.Header.Get("x-ms-copy-source") + result.CopyStatus = CopyStatus(resp.Header.Get("x-ms-copy-status")) + result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description") + result.CreationTime = resp.Header.Get("x-ms-creation-time") + result.ETag = resp.Header.Get("Etag") + result.LastModified = resp.Header.Get("Last-Modified") + result.LeaseDuration = LeaseDuration(resp.Header.Get("x-ms-lease-duration")) + result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state")) + result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status")) + result.EncryptionScope = resp.Header.Get("x-ms-encryption-scope") + result.MetaData = metadata.ParseFromHeaders(resp.Header) + + if v := resp.Header.Get("x-ms-access-tier-inferred"); v != "" { b, innerErr := strconv.ParseBool(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-access-tier-inferred` header value %q: %s", v, innerErr) return } - resp.AccessTierInferred = b + result.AccessTierInferred = b } - if v := resp.HttpResponse.Header.Get("Content-Length"); v != "" { + if v := resp.Header.Get("Content-Length"); v != "" { i, innerErr := strconv.Atoi(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + err = fmt.Errorf("parsing `Content-Length` header value %q: %s", v, innerErr) } - resp.ContentLength = int64(i) + result.ContentLength = int64(i) } - if v := resp.HttpResponse.Header.Get("x-ms-incremental-copy"); v != "" { + if v := resp.Header.Get("x-ms-incremental-copy"); v != "" { b, innerErr := strconv.ParseBool(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-incremental-copy` header value %q: %s", v, innerErr) return } - resp.IncrementalCopy = b + result.IncrementalCopy = b } - if v := resp.HttpResponse.Header.Get("x-ms-server-encrypted"); v != "" { + if v := resp.Header.Get("x-ms-server-encrypted"); v != "" { b, innerErr := strconv.ParseBool(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-server-encrypted` header value %q: %s", v, innerErr) return } - resp.ServerEncrypted = b + result.ServerEncrypted = b } } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_set.go similarity index 86% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_set.go index ebe098556ded..73b417f04540 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_set.go @@ -25,25 +25,24 @@ type SetPropertiesInput struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response BlobSequenceNumber string Etag string } // SetProperties sets system properties on the blob. -func (c Client) SetProperties(ctx context.Context, containerName, blobName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { - +func (c Client) SetProperties(ctx context.Context, containerName, blobName string, input SetPropertiesInput) (result SetPropertiesResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } opts := client.RequestOptions{ @@ -63,7 +62,11 @@ func (c Client) SetProperties(ctx context.Context, containerName, blobName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_append_blob.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_append_blob.go index 0f3aa30733a5..8cc53001882f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_append_blob.go @@ -19,31 +19,35 @@ type PutAppendBlobInput struct { ContentMD5 *string ContentType *string LeaseID *string + EncryptionScope *string MetaData map[string]string } type PutAppendBlobResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutAppendBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new append blob, or updates the content of an existing blob. -func (c Client) PutAppendBlob(ctx context.Context, containerName, blobName string, input PutAppendBlobInput) (resp PutAppendBlobResponse, err error) { - +func (c Client) PutAppendBlob(ctx context.Context, containerName, blobName string, input PutAppendBlobInput) (result PutAppendBlobResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return } opts := client.RequestOptions{ @@ -63,7 +67,11 @@ func (c Client) PutAppendBlob(ctx context.Context, containerName, blobName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -103,6 +111,9 @@ func (p putAppendBlobOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) return headers diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block.go similarity index 63% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block.go index a6059c4aed27..f261ddec3140 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block.go @@ -1,8 +1,10 @@ package blobs import ( + "bytes" "context" "fmt" + "io" "net/http" "strconv" "strings" @@ -12,39 +14,43 @@ import ( ) type PutBlockInput struct { - BlockID string - Content []byte - ContentMD5 *string - LeaseID *string + BlockID string + Content []byte + ContentMD5 *string + LeaseID *string + EncryptionScope *string } type PutBlockResponse struct { - HttpResponse *client.Response - - ContentMD5 string + HttpResponse *http.Response + ContentMD5 string } // PutBlock creates a new block to be committed as part of a blob. -func (c Client) PutBlock(ctx context.Context, containerName, blobName string, input PutBlockInput) (resp PutBlockResponse, err error) { - +func (c Client) PutBlock(ctx context.Context, containerName, blobName string, input PutBlockInput) (result PutBlockResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.BlockID == "" { - return resp, fmt.Errorf("`input.BlockID` cannot be an empty string") + err = fmt.Errorf("`input.BlockID` cannot be an empty string") + return } if len(input.Content) == 0 { - return resp, fmt.Errorf("`input.Content` cannot be empty") + err = fmt.Errorf("`input.Content` cannot be empty") + return } opts := client.RequestOptions{ @@ -64,12 +70,14 @@ func (c Client) PutBlock(ctx context.Context, containerName, blobName string, in return } - err = req.Marshal(&input.Content) - if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) - } + req.ContentLength = int64(len(input.Content)) + req.Body = io.NopCloser(bytes.NewReader(input.Content)) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -92,6 +100,9 @@ func (p putBlockOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } return headers } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob.go index 462ea17272a0..d5d677393c9e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob.go @@ -21,35 +21,40 @@ type PutBlockBlobInput struct { ContentMD5 *string ContentType *string LeaseID *string + EncryptionScope *string MetaData map[string]string } type PutBlockBlobResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutBlockBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new block append blob, or updates the content of an existing block blob. -func (c Client) PutBlockBlob(ctx context.Context, containerName, blobName string, input PutBlockBlobInput) (resp PutBlockBlobResponse, err error) { - +func (c Client) PutBlockBlob(ctx context.Context, containerName, blobName string, input PutBlockBlobInput) (result PutBlockBlobResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.Content != nil && len(*input.Content) == 0 { - return resp, fmt.Errorf("`input.Content` must either be nil or not empty") + err = fmt.Errorf("`input.Content` must either be nil or not empty") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return } opts := client.RequestOptions{ @@ -63,18 +68,27 @@ func (c Client) PutBlockBlob(ctx context.Context, containerName, blobName string Path: fmt.Sprintf("/%s/%s", containerName, blobName), } + if input.ContentType != nil { + opts.ContentType = *input.ContentType + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - err = req.Marshal(&input.Content) + err = req.Marshal(input.Content) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + err = fmt.Errorf("marshalling request: %+v", err) + return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -112,6 +126,9 @@ func (p putBlockBlobOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } if p.input.Content != nil { headers.Append("Content-Length", strconv.Itoa(len(*p.input.Content))) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob_file.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob_file.go index 932fb320607d..f5f21b0736ed 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob_file.go @@ -11,7 +11,7 @@ import ( func (c Client) PutBlockBlobFromFile(ctx context.Context, containerName, blobName string, file *os.File, input PutBlockBlobInput) error { fileInfo, err := file.Stat() if err != nil { - return fmt.Errorf("error loading file info: %s", err) + return fmt.Errorf("loading file info: %s", err) } fileSize := fileInfo.Size() @@ -20,14 +20,14 @@ func (c Client) PutBlockBlobFromFile(ctx context.Context, containerName, blobNam _, err = file.ReadAt(bytes, 0) if err != nil { if err != io.EOF { - return fmt.Errorf("Error reading bytes: %s", err) + return fmt.Errorf("reading bytes: %s", err) } } input.Content = &bytes if _, err = c.PutBlockBlob(ctx, containerName, blobName, input); err != nil { - return fmt.Errorf("error putting bytes: %s", err) + return fmt.Errorf("putting bytes: %s", err) } return nil diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_list.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_list.go index bfe451b941c9..a600fdbe369a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_list.go @@ -29,12 +29,13 @@ type PutBlockListInput struct { ContentLanguage *string ContentMD5 *string ContentType *string - MetaData map[string]string LeaseID *string + EncryptionScope *string + MetaData map[string]string } type PutBlockListResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response ContentMD5 string ETag string @@ -44,18 +45,20 @@ type PutBlockListResponse struct { // PutBlockList writes a blob by specifying the list of block IDs that make up the blob. // In order to be written as part of a blob, a block must have been successfully written // to the server in a prior Put Block operation. -func (c Client) PutBlockList(ctx context.Context, containerName, blobName string, input PutBlockListInput) (resp PutBlockListResponse, err error) { - +func (c Client) PutBlockList(ctx context.Context, containerName, blobName string, input PutBlockListInput) (result PutBlockListResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -77,23 +80,26 @@ func (c Client) PutBlockList(ctx context.Context, containerName, blobName string err = req.Marshal(&input.BlockList) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + err = fmt.Errorf("marshalling request: %+v", err) + return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ETag = resp.Header.Get("ETag") + result.LastModified = resp.Header.Get("Last-Modified") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ETag = resp.HttpResponse.Header.Get("ETag") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") - } - } - return } @@ -125,6 +131,9 @@ func (p putBlockListOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_url.go similarity index 67% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_url.go index cd8487c5c265..088742367bea 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_url.go @@ -14,37 +14,42 @@ type PutBlockFromURLInput struct { BlockID string CopySource string - ContentMD5 *string - LeaseID *string - Range *string + ContentMD5 *string + LeaseID *string + Range *string + EncryptionScope *string } type PutBlockFromURLResponse struct { - HttpResponse *client.Response ContentMD5 string + HttpResponse *http.Response } // PutBlockFromURL creates a new block to be committed as part of a blob where the contents are read from a URL -func (c Client) PutBlockFromURL(ctx context.Context, containerName, blobName string, input PutBlockFromURLInput) (resp PutBlockFromURLResponse, err error) { - +func (c Client) PutBlockFromURL(ctx context.Context, containerName, blobName string, input PutBlockFromURLInput) (result PutBlockFromURLResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.BlockID == "" { - return resp, fmt.Errorf("`input.BlockID` cannot be an empty string") + err = fmt.Errorf("`input.BlockID` cannot be an empty string") + return } if input.CopySource == "" { - return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") + err = fmt.Errorf("`input.CopySource` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -64,18 +69,20 @@ func (c Client) PutBlockFromURL(ctx context.Context, containerName, blobName str return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.ContentMD5 = resp.Header.Get("Content-MD5") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - } - } - return } @@ -97,6 +104,9 @@ func (p putBlockUrlOptions) ToHeaders() *client.Headers { if p.input.Range != nil { headers.Append("x-ms-source-range", *p.input.Range) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } return headers } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_blob.go similarity index 83% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_blob.go index 2b733c4c1311..74bfc6b2b260 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_blob.go @@ -20,6 +20,7 @@ type PutPageBlobInput struct { ContentMD5 *string ContentType *string LeaseID *string + EncryptionScope *string MetaData map[string]string BlobContentLengthBytes int64 @@ -28,27 +29,30 @@ type PutPageBlobInput struct { } type PutPageBlobResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutPageBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new block blob, or updates the content of an existing page blob. -func (c Client) PutPageBlob(ctx context.Context, containerName, blobName string, input PutPageBlobInput) (resp PutPageBlobResponse, err error) { - +func (c Client) PutPageBlob(ctx context.Context, containerName, blobName string, input PutPageBlobInput) (result PutPageBlobResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.BlobContentLengthBytes == 0 || input.BlobContentLengthBytes%512 != 0 { - return resp, fmt.Errorf("`input.BlobContentLengthBytes` must be aligned to a 512-byte boundary") + err = fmt.Errorf("`input.BlobContentLengthBytes` must be aligned to a 512-byte boundary") + return } opts := client.RequestOptions{ @@ -68,7 +72,11 @@ func (c Client) PutPageBlob(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -130,6 +138,10 @@ func (p putPageBlobOptions) ToHeaders() *client.Headers { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } + headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) return headers } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_clear.go similarity index 68% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_clear.go index 1a995138d166..45e0499e431d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_clear.go @@ -14,34 +14,39 @@ type PutPageClearInput struct { StartByte int64 EndByte int64 - LeaseID *string + LeaseID *string + EncryptionScope *string } type PutPageClearResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutPageClear clears a range of pages within a page blob. -func (c Client) PutPageClear(ctx context.Context, containerName, blobName string, input PutPageClearInput) (resp PutPageClearResponse, err error) { - +func (c Client) PutPageClear(ctx context.Context, containerName, blobName string, input PutPageClearInput) (result PutPageClearResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.StartByte < 0 { - return resp, fmt.Errorf("`input.StartByte` must be greater than or equal to 0") + err = fmt.Errorf("`input.StartByte` must be greater than or equal to 0") + return } if input.EndByte <= 0 { - return resp, fmt.Errorf("`input.EndByte` must be greater than 0") + err = fmt.Errorf("`input.EndByte` must be greater than 0") + return } opts := client.RequestOptions{ @@ -61,7 +66,11 @@ func (c Client) PutPageClear(ctx context.Context, containerName, blobName string return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -83,6 +92,10 @@ func (p putPageClearOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } + return headers } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_update.go similarity index 72% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_update.go index 448fe343d903..ab5f258373e3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_update.go @@ -26,10 +26,11 @@ type PutPageUpdateInput struct { IfMatch *string IfNoneMatch *string LeaseID *string + EncryptionScope *string } type PutPageUpdateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response BlobSequenceNumber string ContentMD5 string @@ -37,32 +38,37 @@ type PutPageUpdateResponse struct { } // PutPageUpdate writes a range of pages to a page blob. -func (c Client) PutPageUpdate(ctx context.Context, containerName, blobName string, input PutPageUpdateInput) (resp PutPageUpdateResponse, err error) { - +func (c Client) PutPageUpdate(ctx context.Context, containerName, blobName string, input PutPageUpdateInput) (result PutPageUpdateResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.StartByte < 0 { - return resp, fmt.Errorf("`input.StartByte` must be greater than or equal to 0") + err = fmt.Errorf("`input.StartByte` must be greater than or equal to 0") + return } if input.EndByte <= 0 { - return resp, fmt.Errorf("`input.EndByte` must be greater than 0") + err = fmt.Errorf("`input.EndByte` must be greater than 0") + return } expectedSize := (input.EndByte - input.StartByte) + 1 actualSize := int64(len(input.Content)) if expectedSize != actualSize { - return resp, fmt.Errorf(fmt.Sprintf("Content Size was defined as %d but got %d.", expectedSize, actualSize)) + err = fmt.Errorf(fmt.Sprintf("Content Size was defined as %d but got %d.", expectedSize, actualSize)) + return } opts := client.RequestOptions{ @@ -82,21 +88,26 @@ func (c Client) PutPageUpdate(ctx context.Context, containerName, blobName strin return } + // this is needed to avoid `Content-Length: 0` in the request req.Body = io.NopCloser(bytes.NewReader(input.Content)) req.ContentLength = int64(len(input.Content)) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.LastModified = resp.Header.Get("Last-Modified") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil && resp.HttpResponse.Header != nil { - resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") - } - return } @@ -114,6 +125,10 @@ func (p putPageUpdateOptions) ToHeaders() *client.Headers { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } + if p.input.IfSequenceNumberEQ != nil { headers.Append("x-ms-if-sequence-number-eq", *p.input.IfSequenceNumberEQ) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/resource_id.go index a31673f4e25a..95b78f5ca780 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/set_tier.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/set_tier.go index 35cca5b8d7f9..66b9d64884ae 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/set_tier.go @@ -15,22 +15,24 @@ type SetTierInput struct { } type SetTierResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetTier sets the tier on a blob. -func (c Client) SetTier(ctx context.Context, containerName, blobName string, input SetTierInput) (resp SetTierResponse, err error) { - +func (c Client) SetTier(ctx context.Context, containerName, blobName string, input SetTierInput) (result SetTierResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -51,7 +53,11 @@ func (c Client) SetTier(ctx context.Context, containerName, blobName string, inp return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot.go index 8a90dcdaf204..ebbcb2011220 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot.go @@ -16,6 +16,9 @@ type SnapshotInput struct { // This must be specified if a Lease is present on the Blob, else a 403 is returned LeaseID *string + // The encryption scope to set for the request content. + EncryptionScope *string + // MetaData is a user-defined name-value pair associated with the blob. // If no name-value pairs are specified, the operation will copy the base blob metadata to the snapshot. // If one or more name-value pairs are specified, the snapshot is created with the specified metadata, @@ -41,7 +44,7 @@ type SnapshotInput struct { } type SnapshotResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The ETag of the snapshot ETag string @@ -53,22 +56,25 @@ type SnapshotResponse struct { } // Snapshot captures a Snapshot of a given Blob -func (c Client) Snapshot(ctx context.Context, containerName, blobName string, input SnapshotInput) (resp SnapshotResponse, err error) { - +func (c Client) Snapshot(ctx context.Context, containerName, blobName string, input SnapshotInput) (result SnapshotResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return } opts := client.RequestOptions{ @@ -88,17 +94,21 @@ func (c Client) Snapshot(ctx context.Context, containerName, blobName string, in return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.ETag = resp.Header.Get("ETag") + result.SnapshotDateTime = resp.Header.Get("x-ms-snapshot") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil && resp.HttpResponse.Header != nil { - resp.ETag = resp.HttpResponse.Header.Get("ETag") - resp.SnapshotDateTime = resp.HttpResponse.Header.Get("x-ms-snapshot") - } - return } @@ -113,6 +123,10 @@ func (s snapshotOptions) ToHeaders() *client.Headers { headers.Append("x-ms-lease-id", *s.input.LeaseID) } + if s.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *s.input.EncryptionScope) + } + if s.input.IfModifiedSince != nil { headers.Append("If-Modified-Since", *s.input.IfModifiedSince) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot_get_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot_get_properties.go new file mode 100644 index 000000000000..09e53cf43f19 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot_get_properties.go @@ -0,0 +1,168 @@ +package blobs + +import ( + "context" + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/tombuildsstuff/giovanni/storage/internal/metadata" +) + +type GetSnapshotPropertiesInput struct { + // The ID of the Lease + // This must be specified if a Lease is present on the Blob, else a 403 is returned + LeaseID *string + + // The ID of the Snapshot which should be retrieved + SnapshotID string +} + +// GetSnapshotProperties returns all user-defined metadata, standard HTTP properties, and system properties for +// the specified snapshot of a blob +func (c Client) GetSnapshotProperties(ctx context.Context, containerName, blobName string, input GetSnapshotPropertiesInput) (result GetPropertiesResponse, err error) { + if containerName == "" { + err = fmt.Errorf("`containerName` cannot be an empty string") + return + } + + if strings.ToLower(containerName) != containerName { + err = fmt.Errorf("`containerName` must be a lower-cased string") + return + } + + if blobName == "" { + err = fmt.Errorf("`blobName` cannot be an empty string") + return + } + + if input.SnapshotID == "" { + err = fmt.Errorf("`input.SnapshotID` cannot be an empty string") + return + } + + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: snapshotGetPropertiesOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.AccessTier = AccessTier(resp.Header.Get("x-ms-access-tier")) + result.AccessTierChangeTime = resp.Header.Get("x-ms-access-tier-change-time") + result.ArchiveStatus = ArchiveStatus(resp.Header.Get("x-ms-archive-status")) + result.BlobCommittedBlockCount = resp.Header.Get("x-ms-blob-committed-block-count") + result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") + result.BlobType = BlobType(resp.Header.Get("x-ms-blob-type")) + result.CacheControl = resp.Header.Get("Cache-Control") + result.ContentDisposition = resp.Header.Get("Content-Disposition") + result.ContentEncoding = resp.Header.Get("Content-Encoding") + result.ContentLanguage = resp.Header.Get("Content-Language") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ContentType = resp.Header.Get("Content-Type") + result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time") + result.CopyDestinationSnapshot = resp.Header.Get("x-ms-copy-destination-snapshot") + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopyProgress = resp.Header.Get("x-ms-copy-progress") + result.CopySource = resp.Header.Get("x-ms-copy-source") + result.CopyStatus = CopyStatus(resp.Header.Get("x-ms-copy-status")) + result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description") + result.CreationTime = resp.Header.Get("x-ms-creation-time") + result.ETag = resp.Header.Get("Etag") + result.LastModified = resp.Header.Get("Last-Modified") + result.LeaseDuration = LeaseDuration(resp.Header.Get("x-ms-lease-duration")) + result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state")) + result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status")) + result.MetaData = metadata.ParseFromHeaders(resp.Header) + + if v := resp.Header.Get("Content-Length"); v != "" { + i, innerErr := strconv.Atoi(v) + if innerErr != nil { + err = fmt.Errorf("parsing `Content-Length` header value %q: %+v", v, innerErr) + } + + result.ContentLength = int64(i) + } + + if v := resp.Header.Get("x-ms-access-tier-inferred"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("parsing `x-ms-access-tier-inferred` header value %q: %+v", v, innerErr) + return + } + + result.AccessTierInferred = b + } + + if v := resp.Header.Get("x-ms-incremental-copy"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("parsing `x-ms-incremental-copy` header value %q: %+v", v, innerErr) + return + } + + result.IncrementalCopy = b + } + + if v := resp.Header.Get("x-ms-server-encrypted"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("parsing `\"x-ms-server-encrypted` header value %q: %+v", v, innerErr) + return + } + + result.ServerEncrypted = b + } + } + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + if result.HttpResponse != nil { + } + + return +} + +type snapshotGetPropertiesOptions struct { + input GetSnapshotPropertiesInput +} + +func (s snapshotGetPropertiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if s.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *s.input.LeaseID) + } + return headers +} + +func (s snapshotGetPropertiesOptions) ToOData() *odata.Query { + return nil +} + +func (s snapshotGetPropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("snapshot", s.input.SnapshotID) + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/undelete.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/undelete.go index e46277c77af1..149971fc1035 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/undelete.go @@ -11,22 +11,24 @@ import ( ) type UndeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Undelete restores the contents and metadata of soft deleted blob and any associated soft deleted snapshots. -func (c Client) Undelete(ctx context.Context, containerName, blobName string) (resp UndeleteResponse, err error) { - +func (c Client) Undelete(ctx context.Context, containerName, blobName string) (result UndeleteResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -44,7 +46,11 @@ func (c Client) Undelete(ctx context.Context, containerName, blobName string) (r return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/version.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/version.go index 414d3405774a..da934d3c1001 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/version.go @@ -1,5 +1,5 @@ package blobs // APIVersion is the version of the API used for all Storage API Operations -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "blob/blobs" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/README.md similarity index 91% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/README.md index c93528771d6e..6283cd7f7113 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/README.md @@ -1,4 +1,4 @@ -## Blob Storage Container SDK for API version 2020-08-04 +## Blob Storage Container SDK for API version 2023-11-03 This package allows you to interact with the Containers Blob Storage API @@ -19,7 +19,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/create.go new file mode 100644 index 000000000000..f47c4cf1f422 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/create.go @@ -0,0 +1,135 @@ +package containers + +import ( + "bytes" + "context" + "encoding/xml" + "fmt" + "io" + "net/http" + "strings" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/tombuildsstuff/giovanni/storage/internal/metadata" +) + +type CreateInput struct { + // Specifies whether data in the container may be accessed publicly and the level of access + AccessLevel AccessLevel + + // The encryption scope to set as the default on the container. + DefaultEncryptionScope string + + // Setting this to ture indicates that every blob that's uploaded to this container uses the default encryption scope. + EncryptionScopeOverrideDisabled bool + + // A name-value pair to associate with the container as metadata. + MetaData map[string]string +} + +type CreateResponse struct { + HttpResponse *http.Response +} + +// Create creates a new container under the specified account. +// If the container with the same name already exists, the operation fails. +func (c Client) Create(ctx context.Context, containerName string, input CreateInput) (result CreateResponse, err error) { + if containerName == "" { + err = fmt.Errorf("`containerName` cannot be an empty string") + return + } + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf("`input.MetaData` is not valid: %+v", err) + return + } + + // Retry the container creation if a conflicting container is still in the process of being deleted + retryFunc := func(resp *http.Response, _ *odata.OData) (bool, error) { + if resp != nil { + if response.WasStatusCode(resp, http.StatusConflict) { + // TODO: move this error response parsing to a common helper function + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return false, fmt.Errorf("could not parse response body") + } + resp.Body.Close() + respBody = bytes.TrimPrefix(respBody, []byte("\xef\xbb\xbf")) + res := ErrorResponse{} + if err = xml.Unmarshal(respBody, &res); err != nil { + return false, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(respBody)) + if res.Code != nil { + return strings.Contains(*res.Code, "ContainerBeingDeleted"), nil + } + } + } + return false, nil + } + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: createOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s", containerName), + RetryFunc: retryFunc, + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} + +var _ client.Options = createOptions{} + +type createOptions struct { + input CreateInput +} + +func (o createOptions) ToHeaders() *client.Headers { + headers := containerOptions{ + metaData: o.input.MetaData, + }.ToHeaders() + + // If this header is not included in the request, container data is private to the account owner. + if o.input.AccessLevel != Private { + headers.Append("x-ms-blob-public-access", string(o.input.AccessLevel)) + } + + if o.input.DefaultEncryptionScope != "" { + // These two headers must be used together. + headers.Append("x-ms-default-encryption-scope", o.input.DefaultEncryptionScope) + headers.Append("x-ms-deny-encryption-scope-override", fmt.Sprintf("%t", o.input.EncryptionScopeOverrideDisabled)) + } + + return headers +} + +func (createOptions) ToOData() *odata.Query { + return nil +} + +func (createOptions) ToQuery() *client.QueryParams { + return containerOptions{}.ToQuery() +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/delete.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/delete.go index 0aea0ed7f1df..d654e4aba8a7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/delete.go @@ -9,14 +9,15 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete marks the specified container for deletion. // The container and any blobs contained within it are later deleted during garbage collection. -func (c Client) Delete(ctx context.Context, containerName string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, containerName string) (result DeleteResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -28,12 +29,18 @@ func (c Client) Delete(ctx context.Context, containerName string) (resp DeleteRe OptionsObject: containerOptions{}, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/get_properties.go similarity index 52% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/get_properties.go index 2655b0ba89e1..ca97cf83a7f9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/get_properties.go @@ -16,14 +16,15 @@ type GetPropertiesInput struct { } type GetPropertiesResponse struct { - HttpResponse *client.Response - Model *ContainerProperties + ContainerProperties + HttpResponse *http.Response } // GetProperties returns the properties for this Container without a Lease -func (c Client) GetProperties(ctx context.Context, containerName string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { +func (c Client) GetProperties(ctx context.Context, containerName string, input GetPropertiesInput) (result GetPropertiesResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,40 +38,48 @@ func (c Client) GetProperties(ctx context.Context, containerName string, input G }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.DefaultEncryptionScope = resp.Header.Get("x-ms-default-encryption-scope") + result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status")) + result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state")) + if result.LeaseStatus == Locked { + duration := LeaseDuration(resp.Header.Get("x-ms-lease-duration")) + result.LeaseDuration = &duration + } + + // If this header is not returned in the response, the container is private to the account owner. + accessLevel := resp.Header.Get("x-ms-blob-public-access") + if accessLevel != "" { + result.AccessLevel = AccessLevel(accessLevel) + } else { + result.AccessLevel = Private + } + + // we can't necessarily use strconv.ParseBool here since this could be nil (only in some API versions) + result.EncryptionScopeOverrideDisabled = strings.EqualFold(resp.Header.Get("x-ms-deny-encryption-scope-override"), "true") + result.HasImmutabilityPolicy = strings.EqualFold(resp.Header.Get("x-ms-has-immutability-policy"), "true") + result.HasLegalHold = strings.EqualFold(resp.Header.Get("x-ms-has-legal-hold"), "true") + + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - resp.Model = &ContainerProperties{} - resp.Model.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) - resp.Model.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) - if resp.Model.LeaseStatus == Locked { - duration := LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) - resp.Model.LeaseDuration = &duration - } - - // If this header is not returned in the response, the container is private to the account owner. - accessLevel := resp.HttpResponse.Header.Get("x-ms-blob-public-access") - if accessLevel != "" { - resp.Model.AccessLevel = AccessLevel(accessLevel) - } else { - resp.Model.AccessLevel = Private - } - - // we can't necessarily use strconv.ParseBool here since this could be nil (only in some API versions) - resp.Model.HasImmutabilityPolicy = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-has-immutability-policy"), "true") - resp.Model.HasLegalHold = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-has-legal-hold"), "true") - resp.Model.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_acquire.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_acquire.go index 409f15a47172..a863c1498247 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_acquire.go @@ -18,8 +18,8 @@ type AcquireLeaseInput struct { } type AcquireLeaseResponse struct { - HttpResponse *client.Response - Model *AcquireLeaseModel + AcquireLeaseModel + HttpResponse *http.Response } type AcquireLeaseModel struct { @@ -27,13 +27,13 @@ type AcquireLeaseModel struct { } // AcquireLease establishes and manages a lock on a container for delete operations. -func (c Client) AcquireLease(ctx context.Context, containerName string, input AcquireLeaseInput) (resp AcquireLeaseResponse, err error) { +func (c Client) AcquireLease(ctx context.Context, containerName string, input AcquireLeaseInput) (result AcquireLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } // An infinite lease duration is -1 seconds. A non-infinite lease can be between 15 and 60 seconds if input.LeaseDuration != -1 && (input.LeaseDuration <= 15 || input.LeaseDuration >= 60) { - return resp, fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") + return result, fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") } opts := client.RequestOptions{ @@ -48,23 +48,27 @@ func (c Client) AcquireLease(ctx context.Context, containerName string, input Ac }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.LeaseID = resp.Header.Get("x-ms-lease-id") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - resp.Model = &AcquireLeaseModel{ - LeaseID: resp.HttpResponse.Header.Get("x-ms-lease-id"), - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_break.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_break.go index 0ede9a818a0f..b141e2582f00 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_break.go @@ -3,11 +3,10 @@ package containers import ( "context" "fmt" - "net/http" - "strconv" - "github.com/hashicorp/go-azure-sdk/sdk/client" "github.com/hashicorp/go-azure-sdk/sdk/odata" + "net/http" + "strconv" ) type BreakLeaseInput struct { @@ -25,8 +24,8 @@ type BreakLeaseInput struct { } type BreakLeaseResponse struct { - HttpResponse *client.Response - Model *BreakLeaseModel + BreakLeaseModel + HttpResponse *http.Response } type BreakLeaseModel struct { @@ -36,12 +35,12 @@ type BreakLeaseModel struct { } // BreakLease breaks a lock based on it's Lease ID -func (c Client) BreakLease(ctx context.Context, containerName string, input BreakLeaseInput) (resp BreakLeaseResponse, err error) { +func (c Client) BreakLease(ctx context.Context, containerName string, input BreakLeaseInput) (result BreakLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") + return result, fmt.Errorf("`input.LeaseID` cannot be an empty string") } opts := client.RequestOptions{ @@ -56,27 +55,30 @@ func (c Client) BreakLease(ctx context.Context, containerName string, input Brea }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - if resp.HttpResponse != nil { - leaseRaw := resp.HttpResponse.Header.Get("x-ms-lease-time") - if leaseRaw != "" { - if i, err := strconv.Atoi(leaseRaw); err == nil { - resp.Model = &BreakLeaseModel{ - LeaseTime: i, + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + if leaseTimeRaw := resp.Header.Get("x-ms-lease-time"); leaseTimeRaw != "" { + if leaseTime, err := strconv.Atoi(leaseTimeRaw); err == nil { + result.LeaseTime = leaseTime } } } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_change.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_change.go index 6326507707ee..1c1d7321066d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_change.go @@ -15,8 +15,8 @@ type ChangeLeaseInput struct { } type ChangeLeaseResponse struct { - HttpResponse *client.Response - Model *ChangeLeaseModel + ChangeLeaseModel + HttpResponse *http.Response } type ChangeLeaseModel struct { @@ -24,15 +24,18 @@ type ChangeLeaseModel struct { } // ChangeLease changes the lock from one Lease ID to another Lease ID -func (c Client) ChangeLease(ctx context.Context, containerName string, input ChangeLeaseInput) (resp ChangeLeaseResponse, err error) { +func (c Client) ChangeLease(ctx context.Context, containerName string, input ChangeLeaseInput) (result ChangeLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if input.ExistingLeaseID == "" { - return resp, fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") + err = fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") + return } if input.ProposedLeaseID == "" { - return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") + err = fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -47,23 +50,27 @@ func (c Client) ChangeLease(ctx context.Context, containerName string, input Cha }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.LeaseID = resp.Header.Get("x-ms-lease-id") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - resp.Model = &ChangeLeaseModel{ - LeaseID: resp.HttpResponse.Header.Get("x-ms-lease-id"), - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_release.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_release.go index 8a2cf4114e00..cdff4e2cf9ce 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_release.go @@ -14,16 +14,18 @@ type ReleaseLeaseInput struct { } type ReleaseLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // ReleaseLease releases the lock based on the Lease ID -func (c Client) ReleaseLease(ctx context.Context, containerName string, input ReleaseLeaseInput) (resp ReleaseLeaseResponse, err error) { +func (c Client) ReleaseLease(ctx context.Context, containerName string, input ReleaseLeaseInput) (result ReleaseLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if input.LeaseId == "" { - return resp, fmt.Errorf("`input.LeaseId` cannot be an empty string") + err = fmt.Errorf("`input.LeaseId` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,12 +39,18 @@ func (c Client) ReleaseLease(ctx context.Context, containerName string, input Re }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_renew.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_renew.go index eda202989f23..38c948689996 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_renew.go @@ -14,16 +14,18 @@ type RenewLeaseInput struct { } type RenewLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // RenewLease renews the lock based on the Lease ID -func (c Client) RenewLease(ctx context.Context, containerName string, input RenewLeaseInput) (resp RenewLeaseResponse, err error) { +func (c Client) RenewLease(ctx context.Context, containerName string, input RenewLeaseInput) (result RenewLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if input.LeaseId == "" { - return resp, fmt.Errorf("`input.LeaseId` cannot be an empty string") + err = fmt.Errorf("`input.LeaseId` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,12 +39,18 @@ func (c Client) RenewLease(ctx context.Context, containerName string, input Rene }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/list_blobs.go similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/list_blobs.go index f3bd4674d30d..86ddc7c0a9df 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/list_blobs.go @@ -19,8 +19,9 @@ type ListBlobsInput struct { } type ListBlobsResponse struct { - HttpResponse *client.Response - Model *ListBlobsResult + ListBlobsResult + + HttpResponse *http.Response } type ListBlobsResult struct { @@ -80,12 +81,14 @@ type BlobPrefix struct { } // ListBlobs lists the blobs matching the specified query within the specified Container -func (c Client) ListBlobs(ctx context.Context, containerName string, input ListBlobsInput) (resp ListBlobsResponse, err error) { +func (c Client) ListBlobs(ctx context.Context, containerName string, input ListBlobsInput) (result ListBlobsResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if input.MaxResults != nil && (*input.MaxResults <= 0 || *input.MaxResults > 5000) { - return resp, fmt.Errorf("`input.MaxResults` can either be nil or between 0 and 5000") + err = fmt.Errorf("`input.MaxResults` can either be nil or between 0 and 5000") + return } opts := client.RequestOptions{ ContentType: "application/xml; charset=utf-8", @@ -102,23 +105,28 @@ func (c Client) ListBlobs(ctx context.Context, containerName string, input ListB }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - if resp.HttpResponse != nil { - if err = resp.HttpResponse.Unmarshal(&resp.Model); err != nil { - err = fmt.Errorf("unmarshaling response: %+v", err) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/models.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/models.go index ddfe1953aae6..94c3b86b2916 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/models.go @@ -1,5 +1,7 @@ package containers +import "encoding/xml" + type AccessLevel string var ( @@ -19,13 +21,15 @@ var ( ) type ContainerProperties struct { - AccessLevel AccessLevel - LeaseStatus LeaseStatus - LeaseState LeaseState - LeaseDuration *LeaseDuration - MetaData map[string]string - HasImmutabilityPolicy bool - HasLegalHold bool + AccessLevel AccessLevel + DefaultEncryptionScope string + EncryptionScopeOverrideDisabled bool + LeaseStatus LeaseStatus + LeaseState LeaseState + LeaseDuration *LeaseDuration + MetaData map[string]string + HasImmutabilityPolicy bool + HasLegalHold bool } type Dataset string @@ -39,8 +43,9 @@ var ( ) type ErrorResponse struct { - Code *string `xml:"Code"` - Message *string `xml:"Message"` + XMLName xml.Name `xml:"Error"` + Code *string `xml:"Code"` + Message *string `xml:"Message"` } type LeaseDuration string diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/options.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/options.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/options.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/resource_id.go index 321ea60e4a29..691360246ed8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource Manager specific diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_acl.go similarity index 87% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_acl.go index 642053735ff4..280ad4e391ff 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_acl.go @@ -15,14 +15,15 @@ type SetAccessControlInput struct { } type SetAccessControlResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetAccessControl sets the Access Control for a Container without a Lease ID // NOTE: The SetAccessControl operation only supports Shared Key authorization. -func (c Client) SetAccessControl(ctx context.Context, containerName string, input SetAccessControlInput) (resp SetAccessControlResponse, err error) { +func (c Client) SetAccessControl(ctx context.Context, containerName string, input SetAccessControlInput) (result SetAccessControlResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,12 +38,18 @@ func (c Client) SetAccessControl(ctx context.Context, containerName string, inpu }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_metadata.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_metadata.go index 578c9a169558..3f8bb07e2819 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_metadata.go @@ -16,16 +16,18 @@ type SetMetaDataInput struct { } type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetMetaData sets the specified MetaData on the Container without a Lease ID -func (c Client) SetMetaData(ctx context.Context, containerName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, containerName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } opts := client.RequestOptions{ @@ -40,12 +42,18 @@ func (c Client) SetMetaData(ctx context.Context, containerName string, input Set }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/version.go similarity index 65% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/version.go index d55e9ee67f88..1806c68f4143 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/version.go @@ -1,4 +1,4 @@ package containers -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "blob/containers" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/README.md similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/README.md index df369cc10c47..ac35149dab39 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/README.md @@ -1,4 +1,4 @@ -## Data Lake Storage Gen2 File Systems SDK for API version 2020-08-04 +## Data Lake Storage Gen2 File Systems SDK for API version 2023-11-03 This package allows you to interact with the Data Lake Storage Gen2 File Systems API @@ -14,12 +14,11 @@ package main import ( "context" "fmt" - "os" "github.com/hashicorp/go-azure-helpers/authentication" "github.com/hashicorp/go-azure-helpers/sender" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/create.go similarity index 85% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/create.go index d0d4bab6321e..5bf1b66b5251 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/create.go @@ -18,14 +18,14 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) Create(ctx context.Context, fileSystemName string, input CreateInput) (resp CreateResponse, err error) { - +func (c Client) Create(ctx context.Context, fileSystemName string, input CreateInput) (result CreateResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -42,12 +42,16 @@ func (c Client) Create(ctx context.Context, fileSystemName string, input CreateI } req, err := c.Client.NewRequest(ctx, opts) - if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/delete.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/delete.go index a6d33b332801..6900f2899d35 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/delete.go @@ -9,14 +9,14 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) Delete(ctx context.Context, fileSystemName string) (resp DeleteResponse, err error) { - +func (c Client) Delete(ctx context.Context, fileSystemName string) (result DeleteResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -28,12 +28,18 @@ func (c Client) Delete(ctx context.Context, fileSystemName string) (resp DeleteR OptionsObject: fileSystemOptions{}, Path: fmt.Sprintf("/%s", fileSystemName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/helpers.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/helpers.go similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/helpers.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/helpers.go index 605ed425929d..7822a128154e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/helpers.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/helpers.go @@ -29,7 +29,7 @@ func parseProperties(input string) (*map[string]string, error) { // as such we can't string split on that -_- position := strings.Index(propertyRaw, "=") if position < 0 { - return nil, fmt.Errorf("Expected there to be an equals in the key value pair: %q", propertyRaw) + return nil, fmt.Errorf("expected an equal sign in the key value pair: %q", propertyRaw) } key := propertyRaw[0:position] diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/options.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/options.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/options.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_get.go similarity index 67% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_get.go index e8e4a67d0a05..47f394ab6dd2 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_get.go @@ -10,7 +10,7 @@ import ( ) type GetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // A map of base64-encoded strings to store as user-defined properties with the File System // Note that items may only contain ASCII characters in the ISO-8859-1 character set. @@ -23,10 +23,10 @@ type GetPropertiesResponse struct { } // GetProperties gets the properties for a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) GetProperties(ctx context.Context, fileSystemName string) (resp GetPropertiesResponse, err error) { - +func (c Client) GetProperties(ctx context.Context, fileSystemName string) (result GetPropertiesResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -45,24 +45,27 @@ func (c Client) GetProperties(ctx context.Context, fileSystemName string) (resp return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + propertiesRaw := resp.Header.Get("x-ms-properties") + var properties *map[string]string + properties, err = parseProperties(propertiesRaw) + if err != nil { + return + } + + result.Properties = *properties + result.NamespaceEnabled = strings.EqualFold(resp.Header.Get("x-ms-namespace-enabled"), "true") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - - propertiesRaw := resp.HttpResponse.Header.Get("x-ms-properties") - var properties *map[string]string - properties, err = parseProperties(propertiesRaw) - if err != nil { - return - } - - resp.Properties = *properties - resp.NamespaceEnabled = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-namespace-enabled"), "true") - - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_set.go similarity index 89% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_set.go index 82c259a236e8..775807aeb338 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_set.go @@ -26,14 +26,14 @@ type SetPropertiesInput struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetProperties sets the Properties for a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) SetProperties(ctx context.Context, fileSystemName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { - +func (c Client) SetProperties(ctx context.Context, fileSystemName string, input SetPropertiesInput) (result SetPropertiesResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -52,12 +52,16 @@ func (c Client) SetProperties(ctx context.Context, fileSystemName string, input } req, err := c.Client.NewRequest(ctx, opts) - if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/resource_id.go index a2664ac47590..60670df684a1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource Manager specific diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/version.go similarity index 68% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/version.go index ff22a87f4eca..954c9cac5a64 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/version.go @@ -1,4 +1,4 @@ package filesystems -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "datalakestore/filesystems" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/create.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/create.go index c95ea17ba1a5..8db9b66413eb 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/create.go @@ -19,14 +19,14 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a Data Lake Store Gen2 Path within a Storage Account -func (c Client) Create(ctx context.Context, fileSystemName string, path string, input CreateInput) (resp CreateResponse, err error) { +func (c Client) Create(ctx context.Context, fileSystemName string, path string, input CreateInput) (result CreateResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + return result, fmt.Errorf("`fileSystemName` cannot be an empty string") } opts := client.RequestOptions{ @@ -46,12 +46,17 @@ func (c Client) Create(ctx context.Context, fileSystemName string, path string, if err != nil { err = fmt.Errorf("building request: %+v", err) - return resp, err + return result, err + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response } - resp.HttpResponse, err = req.Execute(ctx) if err != nil { err = fmt.Errorf("executing request: %+v", err) - return resp, err + return result, err } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/delete.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/delete.go index 4ea6e9312cdb..990be5157dc9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/delete.go @@ -9,14 +9,14 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) Delete(ctx context.Context, fileSystemName string, path string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, fileSystemName string, path string) (result DeleteResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + return result, fmt.Errorf("`fileSystemName` cannot be an empty string") } opts := client.RequestOptions{ @@ -33,7 +33,12 @@ func (c Client) Delete(ctx context.Context, fileSystemName string, path string) err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/helpers.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/helpers.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/helpers.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/helpers.go index e6ef6f4bfb9f..08d893c2b81d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/helpers.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/helpers.go @@ -11,5 +11,5 @@ func parsePathResource(input string) (PathResource, error) { case "directory": return PathResourceDirectory, nil } - return "", fmt.Errorf("Unhandled path resource type %q", input) + return "", fmt.Errorf("unhandled path resource type %q", input) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_get.go similarity index 64% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_get.go index 2bb81afc574f..f5dcb782a5a4 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_get.go @@ -11,7 +11,7 @@ import ( ) type GetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response ETag string LastModified time.Time @@ -24,7 +24,7 @@ type GetPropertiesResponse struct { } type GetPropertiesInput struct { - action GetPropertiesAction + Action GetPropertiesAction } type GetPropertiesAction string @@ -35,9 +35,10 @@ const ( ) // GetProperties gets the properties for a Data Lake Store Gen2 Path in a FileSystem within a Storage Account -func (c Client) GetProperties(ctx context.Context, fileSystemName string, path string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { +func (c Client) GetProperties(ctx context.Context, fileSystemName string, path string, input GetPropertiesInput) (result GetPropertiesResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -47,7 +48,7 @@ func (c Client) GetProperties(ctx context.Context, fileSystemName string, path s }, HttpMethod: http.MethodHead, OptionsObject: getPropertyOptions{ - action: input.action, + action: input.Action, }, Path: fmt.Sprintf("/%s/%s", fileSystemName, path), } @@ -56,31 +57,36 @@ func (c Client) GetProperties(ctx context.Context, fileSystemName string, path s if err != nil { err = fmt.Errorf("building request: %+v", err) - return resp, err + return result, err } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.ResourceType = PathResource(resp.Header.Get("x-ms-resource-type")) + result.ETag = resp.Header.Get("ETag") + + if lastModifiedRaw := resp.Header.Get("Last-Modified"); lastModifiedRaw != "" { + lastModified, err := time.Parse(time.RFC1123, lastModifiedRaw) + if err != nil { + return GetPropertiesResponse{}, err + } + result.LastModified = lastModified + } + + result.Owner = resp.Header.Get("x-ms-owner") + result.Group = resp.Header.Get("x-ms-group") + result.ACL = resp.Header.Get("x-ms-acl") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) - return resp, err + return result, err } - if resp.HttpResponse != nil { - resp.ResourceType = PathResource(resp.HttpResponse.Header.Get("x-ms-resource-type")) - resp.ETag = resp.HttpResponse.Header.Get("ETag") - - if lastModifiedRaw := resp.HttpResponse.Header.Get("Last-Modified"); lastModifiedRaw != "" { - lastModified, err := time.Parse(time.RFC1123, lastModifiedRaw) - if err != nil { - return GetPropertiesResponse{}, err - } - resp.LastModified = lastModified - } - - resp.Owner = resp.HttpResponse.Header.Get("x-ms-owner") - resp.Group = resp.HttpResponse.Header.Get("x-ms-group") - resp.ACL = resp.HttpResponse.Header.Get("x-ms-acl") - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_set.go similarity index 85% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_set.go index 055f199cbc87..826e0ef46ce9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_set.go @@ -24,14 +24,14 @@ type SetAccessControlInput struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetProperties sets the access control properties for a Data Lake Store Gen2 Path within a Storage Account File System -func (c Client) SetAccessControl(ctx context.Context, fileSystemName string, path string, input SetAccessControlInput) (resp SetPropertiesResponse, err error) { - +func (c Client) SetAccessControl(ctx context.Context, fileSystemName string, path string, input SetAccessControlInput) (result SetPropertiesResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -50,13 +50,17 @@ func (c Client) SetAccessControl(ctx context.Context, fileSystemName string, pat if err != nil { err = fmt.Errorf("building request: %+v", err) - return resp, err + return result, err } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) - return resp, err + return result, err } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/resource_id.go index 61022090e774..58570e6abd35 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/version.go similarity index 64% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/version.go index bd06c2d4d15c..70c22f9a4ac0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/version.go @@ -1,4 +1,4 @@ package paths -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "datalakestore/paths" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/README.md similarity index 92% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/README.md index 602f0a6d9910..d81f7b0c581a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/README.md @@ -1,4 +1,4 @@ -## File Storage Directories SDK for API version 2020-08-04 +## File Storage Directories SDK for API version 2023-11-03 This package allows you to interact with the Directories File Storage API @@ -21,7 +21,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/create.go similarity index 84% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/create.go index 7f63f9f87737..fdca3cf3f9a9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/create.go @@ -28,26 +28,30 @@ type CreateDirectoryInput struct { } type CreateDirectoryResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a new directory under the specified share or parent directory. -func (c Client) Create(ctx context.Context, shareName, path string, input CreateDirectoryInput) (resp CreateDirectoryResponse, err error) { +func (c Client) Create(ctx context.Context, shareName, path string, input CreateDirectoryInput) (result CreateDirectoryResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -68,7 +72,11 @@ func (c Client) Create(ctx context.Context, shareName, path string, input Create return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/delete.go similarity index 70% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/delete.go index fb96108862e4..35b7298307ae 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/delete.go @@ -10,23 +10,26 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete removes the specified empty directory // Note that the directory must be empty before it can be deleted. -func (c Client) Delete(ctx context.Context, shareName, path string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, shareName, path string) (result DeleteResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -45,7 +48,11 @@ func (c Client) Delete(ctx context.Context, shareName, path string) (resp Delete return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/get.go similarity index 69% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/get.go index 5c900c4d10ff..2aeb03186f08 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/get.go @@ -11,7 +11,7 @@ import ( ) type GetResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // A set of name-value pairs that contain metadata for the directory. MetaData map[string]string @@ -23,17 +23,20 @@ type GetResponse struct { // Get returns all system properties for the specified directory, // and can also be used to check the existence of a directory. -func (c Client) Get(ctx context.Context, shareName, path string) (resp GetResponse, err error) { +func (c Client) Get(ctx context.Context, shareName, path string) (result GetResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -52,18 +55,20 @@ func (c Client) Get(ctx context.Context, shareName, path string) (resp GetRespon return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.DirectoryMetaDataEncrypted = strings.EqualFold(resp.Header.Get("x-ms-server-encrypted"), "true") + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - resp.DirectoryMetaDataEncrypted = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-server-encrypted"), "true") - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_get.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_get.go index 1911d39616f4..cfefeb5d5726 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_get.go @@ -12,23 +12,26 @@ import ( ) type GetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } // GetMetaData returns all user-defined metadata for the specified directory -func (c Client) GetMetaData(ctx context.Context, shareName, path string) (resp GetMetaDataResponse, err error) { +func (c Client) GetMetaData(ctx context.Context, shareName, path string) (result GetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -47,18 +50,20 @@ func (c Client) GetMetaData(ctx context.Context, shareName, path string) (resp G return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_set.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_set.go index 965f5ffef12a..8aa9097d3ef9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_set.go @@ -12,7 +12,7 @@ import ( ) type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetMetaDataInput struct { @@ -20,22 +20,26 @@ type SetMetaDataInput struct { } // SetMetaData updates user defined metadata for the specified directory -func (c Client) SetMetaData(ctx context.Context, shareName, path string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, shareName, path string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`metadata` is not valid: %s", err) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf("`metadata` is not valid: %s", err) + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -56,7 +60,11 @@ func (c Client) SetMetaData(ctx context.Context, shareName, path string, input S return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/options.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/options.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/options.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/resource_id.go index 26b0d4ca3f43..b49c41ade78b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/version.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/version.go index 508cbe75c3fe..785860cbd092 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/version.go @@ -1,5 +1,5 @@ package directories // APIVersion is the version of the API used for all Storage API Operations -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "file/directories" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/README.md similarity index 91% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/README.md index dc8df5ff3af1..0ac6146b88cc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/README.md @@ -1,4 +1,4 @@ -## File Storage Files SDK for API version 2020-08-04 +## File Storage Files SDK for API version 2023-11-03 This package allows you to interact with the Files File Storage API @@ -21,7 +21,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy.go index 577f95d60e30..d8351395df86 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy.go @@ -25,7 +25,7 @@ type CopyInput struct { } type CopyResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The CopyID, which can be passed to AbortCopy to abort the copy. CopyID string @@ -35,26 +35,31 @@ type CopyResponse struct { } // Copy copies a blob or file to a destination file within the storage account asynchronously. -func (c Client) Copy(ctx context.Context, shareName, path, fileName string, input CopyInput) (resp CopyResponse, err error) { +func (c Client) Copy(ctx context.Context, shareName, path, fileName string, input CopyInput) (result CopyResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.CopySource == "" { - return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") + err = fmt.Errorf("`input.CopySource` cannot be an empty string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } if path != "" { @@ -78,19 +83,22 @@ func (c Client) Copy(ctx context.Context, shareName, path, fileName string, inpu err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopySuccess = resp.Header.Get("x-ms-copy-status") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopySuccess = resp.HttpResponse.Header.Get("x-ms-copy-status") - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_abort.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_abort.go index 55611602d37e..191929b8dab5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_abort.go @@ -15,26 +15,30 @@ type CopyAbortInput struct { } type CopyAbortResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // AbortCopy aborts a pending Copy File operation, and leaves a destination file with zero length and full metadata -func (c Client) AbortCopy(ctx context.Context, shareName, path, fileName string, input CopyAbortInput) (resp CopyAbortResponse, err error) { +func (c Client) AbortCopy(ctx context.Context, shareName, path, fileName string, input CopyAbortInput) (result CopyAbortResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.copyID == "" { - return resp, fmt.Errorf("`copyID` cannot be an empty string") + err = fmt.Errorf("`copyID` cannot be an empty string") + return } if path != "" { @@ -59,7 +63,11 @@ func (c Client) AbortCopy(ctx context.Context, shareName, path, fileName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_and_wait_poller.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_and_wait_poller.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_and_wait_poller.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_and_wait_poller.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_wait.go similarity index 59% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_wait.go index 1ccb5f31e635..9223f54331ae 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_wait.go @@ -9,20 +9,20 @@ import ( ) // CopyAndWait is a convenience method which doesn't exist in the API, which copies the file and then waits for the copy to complete -func (c Client) CopyAndWait(ctx context.Context, shareName, path, fileName string, input CopyInput) (resp CopyResponse, err error) { - copy, e := c.Copy(ctx, shareName, path, fileName, input) +func (c Client) CopyAndWait(ctx context.Context, shareName, path, fileName string, input CopyInput) (result CopyResponse, err error) { + fileCopy, e := c.Copy(ctx, shareName, path, fileName, input) if err != nil { - resp.HttpResponse = copy.HttpResponse - err = fmt.Errorf("error copying: %s", e) + result.HttpResponse = fileCopy.HttpResponse + err = fmt.Errorf("copying: %s", e) return } - resp.CopyID = copy.CopyID + result.CopyID = fileCopy.CopyID pollerType := NewCopyAndWaitPoller(&c, shareName, path, fileName) poller := pollers.NewPoller(pollerType, 10*time.Second, pollers.DefaultNumberOfDroppedConnectionsToAllow) - if err := poller.PollUntilDone(ctx); err != nil { - return resp, fmt.Errorf("waiting for file to copy: %+v", err) + if err = poller.PollUntilDone(ctx); err != nil { + return result, fmt.Errorf("waiting for file to copy: %+v", err) } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/create.go similarity index 88% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/create.go index 7c08a85bc1f1..5fb8e97d2e8b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/create.go @@ -51,25 +51,29 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a new file or replaces a file. -func (c Client) Create(ctx context.Context, shareName, path, fileName string, input CreateInput) (resp CreateResponse, err error) { +func (c Client) Create(ctx context.Context, shareName, path, fileName string, input CreateInput) (result CreateResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } if path != "" { @@ -94,7 +98,11 @@ func (c Client) Create(ctx context.Context, shareName, path, fileName string, in return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/delete.go similarity index 69% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/delete.go index d5e32405038f..f3841fa0427d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/delete.go @@ -10,22 +10,25 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete immediately deletes the file from the File Share. -func (c Client) Delete(ctx context.Context, shareName, path, fileName string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, shareName, path, fileName string) (result DeleteResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if path != "" { @@ -48,7 +51,11 @@ func (c Client) Delete(ctx context.Context, shareName, path, fileName string) (r return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_get.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_get.go index 3e0fbad008ad..a4d1cc9ef532 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_get.go @@ -12,23 +12,26 @@ import ( ) type GetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } // GetMetaData returns the MetaData for the specified File. -func (c Client) GetMetaData(ctx context.Context, shareName, path, fileName string) (resp GetMetaDataResponse, err error) { +func (c Client) GetMetaData(ctx context.Context, shareName, path, fileName string) (result GetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if path != "" { @@ -51,18 +54,20 @@ func (c Client) GetMetaData(ctx context.Context, shareName, path, fileName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_set.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_set.go index 4087ef58fdc7..3a51a1086bfd 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_set.go @@ -12,7 +12,7 @@ import ( ) type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetMetaDataInput struct { @@ -20,21 +20,25 @@ type SetMetaDataInput struct { } // SetMetaData updates the specified File to have the specified MetaData. -func (c Client) SetMetaData(ctx context.Context, shareName, path, fileName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, shareName, path, fileName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } if path != "" { @@ -59,7 +63,11 @@ func (c Client) SetMetaData(ctx context.Context, shareName, path, fileName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_get.go new file mode 100644 index 000000000000..2ea1f633efe8 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_get.go @@ -0,0 +1,112 @@ +package files + +import ( + "context" + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/tombuildsstuff/giovanni/storage/internal/metadata" +) + +type GetResponse struct { + HttpResponse *http.Response + + CacheControl string + ContentDisposition string + ContentEncoding string + ContentLanguage string + ContentLength *int64 + ContentMD5 string + ContentType string + CopyID string + CopyStatus string + CopySource string + CopyProgress string + CopyStatusDescription string + CopyCompletionTime string + Encrypted bool + + MetaData map[string]string +} + +// GetProperties returns the Properties for the specified file +func (c Client) GetProperties(ctx context.Context, shareName, path, fileName string) (result GetResponse, err error) { + if shareName == "" { + err = fmt.Errorf("`shareName` cannot be an empty string") + return + } + + if strings.ToLower(shareName) != shareName { + err = fmt.Errorf("`shareName` must be a lower-cased string") + return + } + + if fileName == "" { + err = fmt.Errorf("`fileName` cannot be an empty string") + return + } + + if path != "" { + path = fmt.Sprintf("/%s/", path) + } + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: nil, + Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.CacheControl = resp.Header.Get("Cache-Control") + result.ContentDisposition = resp.Header.Get("Content-Disposition") + result.ContentEncoding = resp.Header.Get("Content-Encoding") + result.ContentLanguage = resp.Header.Get("Content-Language") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ContentType = resp.Header.Get("Content-Type") + result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time") + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopyProgress = resp.Header.Get("x-ms-copy-progress") + result.CopySource = resp.Header.Get("x-ms-copy-source") + result.CopyStatus = resp.Header.Get("x-ms-copy-status") + result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description") + result.Encrypted = strings.EqualFold(resp.Header.Get("x-ms-server-encrypted"), "true") + result.MetaData = metadata.ParseFromHeaders(resp.Header) + + contentLengthRaw := resp.Header.Get("Content-Length") + if contentLengthRaw != "" { + var contentLength int + contentLength, err = strconv.Atoi(contentLengthRaw) + if err != nil { + err = fmt.Errorf("parsing `Content-Length` header value %q: %s", contentLengthRaw, err) + return + } + contentLengthI64 := int64(contentLength) + result.ContentLength = &contentLengthI64 + } + } + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_set.go similarity index 92% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_set.go index 0e2c547a8d96..83bd84118eb5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_set.go @@ -68,21 +68,24 @@ type SetPropertiesInput struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetProperties sets the specified properties on the specified File -func (c Client) SetProperties(ctx context.Context, shareName, path, fileName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { +func (c Client) SetProperties(ctx context.Context, shareName, path, fileName string, input SetPropertiesInput) (result SetPropertiesResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if path != "" { @@ -107,7 +110,11 @@ func (c Client) SetProperties(ctx context.Context, shareName, path, fileName str return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_clear.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_clear.go index c2391a1c9c04..0a1e8149ed73 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_clear.go @@ -16,30 +16,35 @@ type ClearByteRangeInput struct { } type ClearByteRangeResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // ClearByteRange clears the specified Byte Range from within the specified File -func (c Client) ClearByteRange(ctx context.Context, shareName, path, fileName string, input ClearByteRangeInput) (resp ClearByteRangeResponse, err error) { +func (c Client) ClearByteRange(ctx context.Context, shareName, path, fileName string, input ClearByteRangeInput) (result ClearByteRangeResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.StartBytes < 0 { - return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + err = fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + return } if input.EndBytes <= 0 { - return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") + err = fmt.Errorf("`input.EndBytes` must be greater than 0") + return } if path != "" { @@ -64,7 +69,11 @@ func (c Client) ClearByteRange(ctx context.Context, shareName, path, fileName st return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get.go similarity index 65% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get.go index 90a1089b3798..f8b40b87d1a7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get.go @@ -3,7 +3,6 @@ package files import ( "context" "fmt" - "io" "net/http" "strings" @@ -17,40 +16,46 @@ type GetByteRangeInput struct { } type GetByteRangeResponse struct { - HttpResponse *client.Response - - Contents []byte + HttpResponse *http.Response + Contents *[]byte } // GetByteRange returns the specified Byte Range from the specified File. -func (c Client) GetByteRange(ctx context.Context, shareName, path, fileName string, input GetByteRangeInput) (resp GetByteRangeResponse, err error) { +func (c Client) GetByteRange(ctx context.Context, shareName, path, fileName string, input GetByteRangeInput) (result GetByteRangeResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.StartBytes < 0 { - return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + err = fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + return } if input.EndBytes <= 0 { - return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") + err = fmt.Errorf("`input.EndBytes` must be greater than 0") + return } expectedBytes := input.EndBytes - input.StartBytes if expectedBytes < (4 * 1024) { - return resp, fmt.Errorf("requested Byte Range must be at least 4KB") + err = fmt.Errorf("requested Byte Range must be at least 4KB") + return } if expectedBytes > (4 * 1024 * 1024) { - return resp, fmt.Errorf("requested Byte Range must be at most 4MB") + err = fmt.Errorf("requested Byte Range must be at most 4MB") + return } if path != "" { @@ -75,18 +80,21 @@ func (c Client) GetByteRange(ctx context.Context, shareName, path, fileName stri return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.Contents = &[]byte{} + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - bytes, err := io.ReadAll(resp.HttpResponse.Body) + err = resp.Unmarshal(result.Contents) if err != nil { - return resp, fmt.Errorf("reading response body: %v", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } - resp.Contents = bytes + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get_file.go similarity index 89% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get_file.go index f81852604283..e923eb31f3b0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get_file.go @@ -5,10 +5,9 @@ import ( "fmt" "log" "math" + "net/http" "runtime" "sync" - - "github.com/hashicorp/go-azure-sdk/sdk/client" ) type GetFileInput struct { @@ -16,18 +15,17 @@ type GetFileInput struct { } type GetFileResponse struct { - HttpResponse *client.Response - - OutputBytes []byte + HttpResponse *http.Response + OutputBytes *[]byte } // GetFile is a helper method to download a file by chunking it automatically -func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, input GetFileInput) (resp GetFileResponse, err error) { +func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, input GetFileInput) (result GetFileResponse, err error) { // first look up the file and check out how many bytes it is file, e := c.GetProperties(ctx, shareName, path, fileName) if err != nil { - resp.HttpResponse = file.HttpResponse + result.HttpResponse = file.HttpResponse err = e return } @@ -37,7 +35,7 @@ func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, i return } - resp.HttpResponse = file.HttpResponse + result.HttpResponse = file.HttpResponse length := *file.ContentLength chunkSize := int64(4 * 1024 * 1024) // 4MB @@ -92,10 +90,10 @@ func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, i // then finally put it all together, in order and return it output := make([]byte, length) for _, v := range results { - copy(output[v.startBytes:v.endBytes], v.bytes) + copy(output[v.startBytes:v.endBytes], *v.bytes) } - resp.OutputBytes = output + *result.OutputBytes = output return } @@ -108,7 +106,7 @@ type downloadFileChunkInput struct { type downloadFileChunkResult struct { startBytes int64 endBytes int64 - bytes []byte + bytes *[]byte } func (c Client) downloadFileChunk(ctx context.Context, shareName, path, fileName string, input downloadFileChunkInput) (*downloadFileChunkResult, error) { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put.go similarity index 71% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put.go index 7588f8b4131e..58e6f9bb0cff 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put.go @@ -23,39 +23,45 @@ type PutByteRangeInput struct { } type PutRangeResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutByteRange puts the specified Byte Range in the specified File. -func (c Client) PutByteRange(ctx context.Context, shareName, path, fileName string, input PutByteRangeInput) (resp PutRangeResponse, err error) { - +func (c Client) PutByteRange(ctx context.Context, shareName, path, fileName string, input PutByteRangeInput) (result PutRangeResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.StartBytes < 0 { - return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + err = fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + return } if input.EndBytes <= 0 { - return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") + err = fmt.Errorf("`input.EndBytes` must be greater than 0") + return } expectedBytes := input.EndBytes - input.StartBytes actualBytes := len(input.Content) if expectedBytes != int64(actualBytes) { - return resp, fmt.Errorf(fmt.Sprintf("The specified byte-range (%d) didn't match the content size (%d).", expectedBytes, actualBytes)) + err = fmt.Errorf(fmt.Sprintf("The specified byte-range (%d) didn't match the content size (%d).", expectedBytes, actualBytes)) + return } if expectedBytes > (4 * 1024 * 1024) { - return resp, fmt.Errorf("specified Byte Range must be at most 4MB") + err = fmt.Errorf("specified Byte Range must be at most 4MB") + return } if path != "" { @@ -82,7 +88,11 @@ func (c Client) PutByteRange(ctx context.Context, shareName, path, fileName stri req.Body = io.NopCloser(bytes.NewReader(input.Content)) req.ContentLength = int64(len(input.Content)) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put_file.go similarity index 93% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put_file.go index 16cb68719311..660122c1aa8f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put_file.go @@ -16,7 +16,6 @@ func (c Client) PutFile(ctx context.Context, shareName, path, fileName string, f if err != nil { return fmt.Errorf("error loading file info: %s", err) } - if fileInfo.Size() == 0 { return fmt.Errorf("file is empty which is not supported") } @@ -67,7 +66,7 @@ func (c Client) PutFile(ctx context.Context, shareName, path, fileName string, f // TODO: we should switch to hashicorp/multi-error here if len(errors) > 0 { - return fmt.Errorf("Error uploading file: %s", <-errors) + return fmt.Errorf("uploading file: %s", <-errors) } return nil @@ -95,7 +94,7 @@ func (c Client) uploadChunk(ctx context.Context, shareName, path, fileName strin _, err = file.ReadAt(bytes, startBytes) if err != nil { if err != io.EOF { - return result, fmt.Errorf("Error reading bytes: %s", err) + return result, fmt.Errorf("reading bytes: %s", err) } } @@ -106,7 +105,7 @@ func (c Client) uploadChunk(ctx context.Context, shareName, path, fileName strin } result, err = c.PutByteRange(ctx, shareName, path, fileName, putBytesInput) if err != nil { - return result, fmt.Errorf("error putting bytes: %s", err) + return result, fmt.Errorf("putting bytes: %s", err) } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/ranges_list.go similarity index 70% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/ranges_list.go index 9a67cab82857..0b89e6c1a110 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/ranges_list.go @@ -11,7 +11,7 @@ import ( ) type ListRangesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response Ranges []Range `xml:"Range"` } @@ -22,22 +22,25 @@ type Range struct { } // ListRanges returns the list of valid ranges for the specified File. -func (c Client) ListRanges(ctx context.Context, shareName, path, fileName string) (resp ListRangesResponse, err error) { - +func (c Client) ListRanges(ctx context.Context, shareName, path, fileName string) (result ListRangesResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if path != "" { @@ -60,16 +63,22 @@ func (c Client) ListRanges(ctx context.Context, shareName, path, fileName string return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - resp.HttpResponse.Unmarshal(&resp) - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/resource_id.go index b29471c87e32..492889780e31 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/version.go similarity index 60% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/version.go index 5b70f293ad01..1d4bc38bea91 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/version.go @@ -1,4 +1,4 @@ package files -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "file/files" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/README.md similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/README.md index 68b41e2d5e49..5ec0fb4f8fc0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/README.md @@ -1,4 +1,4 @@ -## File Storage Shares SDK for API version 2020-08-04 +## File Storage Shares SDK for API version 2023-11-03 This package allows you to interact with the Shares File Storage API @@ -17,7 +17,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_get.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_get.go index 56aa6413d4b8..8add483a5e3e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_get.go @@ -11,19 +11,20 @@ import ( ) type GetACLResult struct { - HttpResponse *client.Response + HttpResponse *http.Response SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` } // GetACL get the Access Control List for the specified Storage Share -func (c Client) GetACL(ctx context.Context, shareName string) (resp GetACLResult, err error) { - +func (c Client) GetACL(ctx context.Context, shareName string) (result GetACLResult, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -42,18 +43,22 @@ func (c Client) GetACL(ctx context.Context, shareName string) (resp GetACLResult return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) - } - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_set.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_set.go index 33b7c84a47d0..216d714eb2ac 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_set.go @@ -15,24 +15,24 @@ import ( ) type SetAclResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetAclInput struct { SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` - - XMLName xml.Name `xml:"SignedIdentifiers"` + XMLName xml.Name `xml:"SignedIdentifiers"` } // SetACL sets the specified Access Control List on the specified Storage Share -func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) (resp SetAclResponse, err error) { - +func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) (result SetAclResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -53,7 +53,8 @@ func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) b, err := xml.Marshal(&input) if err != nil { - return resp, fmt.Errorf("marshalling input: %v", err) + err = fmt.Errorf("marshalling input: %+v", err) + return } withHeader := xml.Header + string(b) bytesWithHeader := []byte(withHeader) @@ -61,11 +62,16 @@ func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) req.Header.Set("Content-Length", strconv.Itoa(len(bytesWithHeader))) req.Body = io.NopCloser(bytes.NewReader(bytesWithHeader)) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } + return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/create.go similarity index 62% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/create.go index b0184600af0e..46e8757466fc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/create.go @@ -1,12 +1,16 @@ package shares import ( + "bytes" "context" + "encoding/xml" "fmt" + "io" "net/http" "strconv" "strings" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/sdk/client" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" @@ -36,26 +40,54 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates the specified Storage Share within the specified Storage Account -func (c Client) Create(ctx context.Context, shareName string, input CreateInput) (resp CreateResponse, err error) { +func (c Client) Create(ctx context.Context, shareName string, input CreateInput) (result CreateResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if input.QuotaInGB <= 0 || input.QuotaInGB > 102400 { - return resp, fmt.Errorf("`input.QuotaInGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") + err = fmt.Errorf("`input.QuotaInGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return + } + + // Retry the share creation if a conflicting share is still in the process of being deleted + retryFunc := func(resp *http.Response, _ *odata.OData) (bool, error) { + if resp != nil { + if response.WasStatusCode(resp, http.StatusConflict) { + // TODO: move this error response parsing to a common helper function + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return false, fmt.Errorf("could not parse response body") + } + resp.Body.Close() + respBody = bytes.TrimPrefix(respBody, []byte("\xef\xbb\xbf")) + res := ErrorResponse{} + if err = xml.Unmarshal(respBody, &res); err != nil { + return false, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(respBody)) + if res.Code != nil { + return strings.Contains(*res.Code, "ShareBeingDeleted"), nil + } + } + } + return false, nil } opts := client.RequestOptions{ @@ -67,18 +99,25 @@ func (c Client) Create(ctx context.Context, shareName string, input CreateInput) OptionsObject: CreateOptions{ input: input, }, - Path: fmt.Sprintf("/%s", shareName), + Path: fmt.Sprintf("/%s", shareName), + RetryFunc: retryFunc, } req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } + return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/delete.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/delete.go index 7ae11b3dbef3..84667f68a3ef 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/delete.go @@ -11,7 +11,7 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type DeleteInput struct { @@ -19,13 +19,15 @@ type DeleteInput struct { } // Delete deletes the specified Storage Share from within a Storage Account -func (c Client) Delete(ctx context.Context, shareName string, input DeleteInput) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, shareName string, input DeleteInput) (result DeleteResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -45,7 +47,11 @@ func (c Client) Delete(ctx context.Context, shareName string, input DeleteInput) return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_get.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_get.go index e31762bd2d8a..eeb8b4d1e7dc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_get.go @@ -12,18 +12,18 @@ import ( ) type GetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } // GetMetaData returns the MetaData associated with the specified Storage Share -func (c Client) GetMetaData(ctx context.Context, shareName string) (resp GetMetaDataResponse, err error) { +func (c Client) GetMetaData(ctx context.Context, shareName string) (result GetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + return result, fmt.Errorf("`shareName` cannot be an empty string") } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + return result, fmt.Errorf("`shareName` must be a lower-cased string") } opts := client.RequestOptions{ @@ -42,18 +42,20 @@ func (c Client) GetMetaData(ctx context.Context, shareName string) (resp GetMeta return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_set.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_set.go index 3a23d90e780f..55bf1d4bedfc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_set.go @@ -12,7 +12,7 @@ import ( ) type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetMetaDataInput struct { @@ -20,18 +20,21 @@ type SetMetaDataInput struct { } // SetMetaData sets the MetaData on the specified Storage Share -func (c Client) SetMetaData(ctx context.Context, shareName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, shareName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`metadata` is not valid: %v", err) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf("`metadata` is not valid: %+v", err) + return } opts := client.RequestOptions{ @@ -52,7 +55,11 @@ func (c Client) SetMetaData(ctx context.Context, shareName string, input SetMeta return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/models.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/models.go index 32727164cc83..61c3be66ae47 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/models.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/models.go @@ -1,5 +1,7 @@ package shares +import "encoding/xml" + type SignedIdentifier struct { Id string `xml:"Id"` AccessPolicy AccessPolicy `xml:"AccessPolicy"` @@ -20,3 +22,9 @@ const ( // NFS indicates the share can be accessed by NFSv4.1. A premium account is required for this option. NFS ShareProtocol = "NFS" ) + +type ErrorResponse struct { + XMLName xml.Name `xml:"Error"` + Code *string `xml:"Code"` + Message *string `xml:"Message"` +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/options.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/options.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/options.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_get.go similarity index 59% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_get.go index 763584ef648b..fb153628fd09 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_get.go @@ -12,7 +12,7 @@ import ( ) type GetPropertiesResult struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string QuotaInGB int @@ -21,13 +21,15 @@ type GetPropertiesResult struct { } // GetProperties returns the properties about the specified Storage Share -func (c Client) GetProperties(ctx context.Context, shareName string) (resp GetPropertiesResult, err error) { +func (c Client) GetProperties(ctx context.Context, shareName string) (result GetPropertiesResult, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -46,37 +48,40 @@ func (c Client) GetProperties(ctx context.Context, shareName string) (resp GetPr return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) - quotaRaw := resp.HttpResponse.Header.Get("x-ms-share-quota") + quotaRaw := resp.Header.Get("x-ms-share-quota") if quotaRaw != "" { quota, e := strconv.Atoi(quotaRaw) if e != nil { - return resp, fmt.Errorf("error converting %q to an integer: %s", quotaRaw, err) + err = fmt.Errorf("error converting %q to an integer: %s", quotaRaw, err) + return } - resp.QuotaInGB = quota + result.QuotaInGB = quota } protocol := SMB - if protocolRaw := resp.HttpResponse.Header.Get("x-ms-enabled-protocols"); protocolRaw != "" { + if protocolRaw := resp.Header.Get("x-ms-enabled-protocols"); protocolRaw != "" { protocol = ShareProtocol(protocolRaw) } - if accessTierRaw := resp.HttpResponse.Header.Get("x-ms-access-tier"); accessTierRaw != "" { + if accessTierRaw := resp.Header.Get("x-ms-access-tier"); accessTierRaw != "" { tier := AccessTier(accessTierRaw) - resp.AccessTier = &tier + result.AccessTier = &tier } - resp.EnabledProtocol = protocol + result.EnabledProtocol = protocol } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_set.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_set.go index ef3854af6de9..f80df4fdce1c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_set.go @@ -17,22 +17,22 @@ type ShareProperties struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetProperties lets you update the Quota for the specified Storage Share -func (c Client) SetProperties(ctx context.Context, shareName string, properties ShareProperties) (resp SetPropertiesResponse, err error) { +func (c Client) SetProperties(ctx context.Context, shareName string, properties ShareProperties) (result SetPropertiesResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + return result, fmt.Errorf("`shareName` cannot be an empty string") } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + return result, fmt.Errorf("`shareName` must be a lower-cased string") } if newQuotaGB := properties.QuotaInGb; newQuotaGB != nil && (*newQuotaGB <= 0 || *newQuotaGB > 102400) { - return resp, fmt.Errorf("`newQuotaGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") + return result, fmt.Errorf("`newQuotaGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") } opts := client.RequestOptions{ @@ -53,7 +53,11 @@ func (c Client) SetProperties(ctx context.Context, shareName string, properties return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/resource_id.go index 73b93bd70768..c46092b4400f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource Manager specific diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_create.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_create.go index 8ba7a07c7b4a..d4dff0328043 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_create.go @@ -16,7 +16,7 @@ type CreateSnapshotInput struct { } type CreateSnapshotResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // This header is a DateTime value that uniquely identifies the share snapshot. // The value of this header may be used in subsequent requests to access the share snapshot. @@ -27,18 +27,21 @@ type CreateSnapshotResponse struct { // CreateSnapshot creates a read-only snapshot of the share // A share can support creation of 200 share snapshots. Attempting to create more than 200 share snapshots fails with 409 (Conflict). // Attempting to create a share snapshot while a previous Snapshot Share operation is in progress fails with 409 (Conflict). -func (c Client) CreateSnapshot(ctx context.Context, shareName string, input CreateSnapshotInput) (resp CreateSnapshotResponse, err error) { +func (c Client) CreateSnapshot(ctx context.Context, shareName string, input CreateSnapshotInput) (result CreateSnapshotResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %v", err) + err = fmt.Errorf("`input.MetaData` is not valid: %+v", err) + return } opts := client.RequestOptions{ @@ -59,17 +62,20 @@ func (c Client) CreateSnapshot(ctx context.Context, shareName string, input Crea return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.SnapshotDateTime = resp.Header.Get("x-ms-snapshot") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.SnapshotDateTime = resp.HttpResponse.Header.Get("x-ms-snapshot") - } - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_delete.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_delete.go index bf3ccd6719a6..64dd532068a0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_delete.go @@ -11,22 +11,22 @@ import ( ) type DeleteSnapshotResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // DeleteSnapshot deletes the specified Snapshot of a Storage Share -func (c Client) DeleteSnapshot(ctx context.Context, accountName, shareName string, shareSnapshot string) (resp DeleteSnapshotResponse, err error) { +func (c Client) DeleteSnapshot(ctx context.Context, accountName, shareName string, shareSnapshot string) (result DeleteSnapshotResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + return result, fmt.Errorf("`shareName` cannot be an empty string") } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + return result, fmt.Errorf("`shareName` must be a lower-cased string") } if shareSnapshot == "" { - return resp, fmt.Errorf("`shareSnapshot` cannot be an empty string") + return result, fmt.Errorf("`shareSnapshot` cannot be an empty string") } opts := client.RequestOptions{ @@ -47,7 +47,11 @@ func (c Client) DeleteSnapshot(ctx context.Context, accountName, shareName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_get.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_get.go index f4a12e9f0cdc..e4aee485b016 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_get.go @@ -12,7 +12,7 @@ import ( ) type GetSnapshotPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } @@ -22,17 +22,20 @@ type GetSnapshotPropertiesInput struct { } // GetSnapshot gets information about the specified Snapshot of the specified Storage Share -func (c Client) GetSnapshot(ctx context.Context, shareName string, input GetSnapshotPropertiesInput) (resp GetSnapshotPropertiesResponse, err error) { +func (c Client) GetSnapshot(ctx context.Context, shareName string, input GetSnapshotPropertiesInput) (result GetSnapshotPropertiesResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if input.snapshotShare == "" { - return resp, fmt.Errorf("`snapshotShare` cannot be an empty string") + err = fmt.Errorf("`snapshotShare` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -53,18 +56,20 @@ func (c Client) GetSnapshot(ctx context.Context, shareName string, input GetSnap return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/stats.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/stats.go index 23e48afe4043..d375d837ed7e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/stats.go @@ -11,7 +11,7 @@ import ( ) type GetStatsResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The approximate size of the data stored on the share. // Note that this value may not include all recently created or recently resized files. @@ -19,13 +19,15 @@ type GetStatsResponse struct { } // GetStats returns information about the specified Storage Share -func (c Client) GetStats(ctx context.Context, shareName string) (resp GetStatsResponse, err error) { +func (c Client) GetStats(ctx context.Context, shareName string) (result GetStatsResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -44,18 +46,22 @@ func (c Client) GetStats(ctx context.Context, shareName string) (resp GetStatsRe return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) - } - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/version.go similarity index 61% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/version.go index a3c5b6d50170..6f62a9bdaf85 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/version.go @@ -1,4 +1,4 @@ package shares -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "file/shares" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/README.md similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/README.md index 7c9fd1a3c6ec..745cc6d70ca5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/README.md @@ -1,4 +1,4 @@ -## Queue Storage Queues SDK for API version 2020-08-04 +## Queue Storage Queues SDK for API version 2023-11-03 This package allows you to interact with the Queues Queue Storage API @@ -17,7 +17,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/create.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/create.go index d156052ca70d..f548088ce288 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/create.go @@ -16,22 +16,22 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates the specified Queue within the specified Storage Account -func (c Client) Create(ctx context.Context, queueName string, input CreateInput) (resp CreateResponse, err error) { +func (c Client) Create(ctx context.Context, queueName string, input CreateInput) (result CreateResponse, err error) { if queueName == "" { - return resp, fmt.Errorf("`queueName` cannot be an empty string") + return result, fmt.Errorf("`queueName` cannot be an empty string") } if strings.ToLower(queueName) != queueName { - return resp, fmt.Errorf("`queueName` must be a lower-cased string") + return result, fmt.Errorf("`queueName` must be a lower-cased string") } if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`metadata` is not valid: %s", err) + return result, fmt.Errorf("`metadata` is not valid: %s", err) } opts := client.RequestOptions{ @@ -52,7 +52,11 @@ func (c Client) Create(ctx context.Context, queueName string, input CreateInput) return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/delete.go similarity index 72% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/delete.go index 39d5d64fa059..e8d7babb12fe 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/delete.go @@ -10,18 +10,18 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes the specified Queue within the specified Storage Account -func (c Client) Delete(ctx context.Context, queueName string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, queueName string) (result DeleteResponse, err error) { if queueName == "" { - return resp, fmt.Errorf("`queueName` cannot be an empty string") + return result, fmt.Errorf("`queueName` cannot be an empty string") } if strings.ToLower(queueName) != queueName { - return resp, fmt.Errorf("`queueName` must be a lower-cased string") + return result, fmt.Errorf("`queueName` must be a lower-cased string") } opts := client.RequestOptions{ @@ -40,7 +40,11 @@ func (c Client) Delete(ctx context.Context, queueName string) (resp DeleteRespon return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_get.go similarity index 69% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_get.go index 14c32d64d0f5..c8a259f451ba 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_get.go @@ -12,20 +12,20 @@ import ( ) type GetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } // GetMetaData returns the metadata for this Queue -func (c Client) GetMetaData(ctx context.Context, queueName string) (resp GetMetaDataResponse, err error) { +func (c Client) GetMetaData(ctx context.Context, queueName string) (result GetMetaDataResponse, err error) { if queueName == "" { - return resp, fmt.Errorf("`queueName` cannot be an empty string") + return result, fmt.Errorf("`queueName` cannot be an empty string") } if strings.ToLower(queueName) != queueName { - return resp, fmt.Errorf("`queueName` must be a lower-cased string") + return result, fmt.Errorf("`queueName` must be a lower-cased string") } opts := client.RequestOptions{ @@ -44,15 +44,23 @@ func (c Client) GetMetaData(ctx context.Context, queueName string) (resp GetMeta return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + if result.HttpResponse != nil { + if result.HttpResponse.Header != nil { + result.MetaData = metadata.ParseFromHeaders(result.HttpResponse.Header) } } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_set.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_set.go index ea8eac3192da..6ab770de1f52 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_set.go @@ -12,7 +12,7 @@ import ( ) type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetMetaDataInput struct { @@ -20,18 +20,18 @@ type SetMetaDataInput struct { } // SetMetaData returns the metadata for this Queue -func (c Client) SetMetaData(ctx context.Context, queueName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, queueName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if queueName == "" { - return resp, fmt.Errorf("`queueName` cannot be an empty string") + return result, fmt.Errorf("`queueName` cannot be an empty string") } if strings.ToLower(queueName) != queueName { - return resp, fmt.Errorf("`queueName` must be a lower-cased string") + return result, fmt.Errorf("`queueName` must be a lower-cased string") } if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`metadata` is not valid: %v", err) + return result, fmt.Errorf("`metadata` is not valid: %+v", err) } opts := client.RequestOptions{ @@ -52,7 +52,11 @@ func (c Client) SetMetaData(ctx context.Context, queueName string, input SetMeta return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/models.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/models.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_get.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_get.go index b2ea774e5534..0647f26d1b8f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_get.go @@ -11,11 +11,11 @@ import ( type GetStorageServicePropertiesResponse struct { StorageServiceProperties - HttpResponse *client.Response + HttpResponse *http.Response } // GetServiceProperties gets the properties for this queue -func (c Client) GetServiceProperties(ctx context.Context) (resp GetStorageServicePropertiesResponse, err error) { +func (c Client) GetServiceProperties(ctx context.Context) (result GetStorageServicePropertiesResponse, err error) { opts := client.RequestOptions{ ContentType: "application/xml; charset=utf-8", @@ -33,18 +33,21 @@ func (c Client) GetServiceProperties(ctx context.Context) (resp GetStorageServic return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - err = resp.HttpResponse.Unmarshal(&resp) + err = resp.Unmarshal(&result) if err != nil { - return resp, fmt.Errorf("unmarshalling respnse: %v", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_set.go similarity index 84% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_set.go index 744bd9767ed1..d80b6728b398 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_set.go @@ -14,7 +14,7 @@ import ( ) type SetStorageServicePropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetStorageServicePropertiesInput struct { @@ -22,7 +22,7 @@ type SetStorageServicePropertiesInput struct { } // SetServiceProperties sets the properties for this queue -func (c Client) SetServiceProperties(ctx context.Context, input SetStorageServicePropertiesInput) (resp SetStorageServicePropertiesResponse, err error) { +func (c Client) SetServiceProperties(ctx context.Context, input SetStorageServicePropertiesInput) (result SetStorageServicePropertiesResponse, err error) { opts := client.RequestOptions{ ContentType: "application/xml; charset=utf-8", @@ -42,14 +42,18 @@ func (c Client) SetServiceProperties(ctx context.Context, input SetStorageServic marshalledProps, err := xml.Marshal(&input.Properties) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + return result, fmt.Errorf("marshalling request: %+v", err) } body := xml.Header + string(marshalledProps) req.Body = io.NopCloser(bytes.NewReader([]byte(body))) req.ContentLength = int64(len(body)) req.Header.Set("Content-Length", strconv.Itoa(len(body))) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/resource_id.go index 455319a23308..8acd0bb0ae74 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource Manager ID for the given Queue diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/version.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/version.go index 10937c5727d3..c22267eb6e7d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/version.go @@ -1,5 +1,5 @@ package queues // APIVersion is the version of the API used for all Storage API Operations -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "queue/queues" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/README.md similarity index 91% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/README.md index e98e21e68eeb..06b519b89423 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/README.md @@ -1,4 +1,4 @@ -## Table Storage Entities SDK for API version 2020-08-04 +## Table Storage Entities SDK for API version 2023-11-03 This package allows you to interact with the Entities Table Storage API @@ -16,7 +16,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/delete.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/delete.go index 05d09b3ce32e..61e7c712ac5e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/delete.go @@ -20,22 +20,22 @@ type DeleteEntityInput struct { } type DeleteEntityResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes an existing entity in a table. -func (c Client) Delete(ctx context.Context, tableName string, input DeleteEntityInput) (resp DeleteEntityResponse, err error) { +func (c Client) Delete(ctx context.Context, tableName string, input DeleteEntityInput) (result DeleteEntityResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + return result, fmt.Errorf("`tableName` cannot be an empty string") } if input.PartitionKey == "" { - return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } if input.RowKey == "" { - return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") } opts := client.RequestOptions{ @@ -54,7 +54,11 @@ func (c Client) Delete(ctx context.Context, tableName string, input DeleteEntity return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/get.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/get.go index 14cd5ad38d04..daf428acdffa 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/get.go @@ -18,23 +18,23 @@ type GetEntityInput struct { } type GetEntityResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response Entity map[string]interface{} } // Get queries entities in a table and includes the $filter and $select options. -func (c Client) Get(ctx context.Context, tableName string, input GetEntityInput) (resp GetEntityResponse, err error) { +func (c Client) Get(ctx context.Context, tableName string, input GetEntityInput) (result GetEntityResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + return result, fmt.Errorf("`tableName` cannot be an empty string") } if input.PartitionKey == "" { - return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } if input.RowKey == "" { - return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") } opts := client.RequestOptions{ @@ -54,20 +54,22 @@ func (c Client) Get(ctx context.Context, tableName string, input GetEntityInput) return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result.Entity) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Body != nil { - err = resp.HttpResponse.Unmarshal(&resp.Entity) - if err != nil { - return resp, fmt.Errorf("unmarshalling response: %+v", err) - } - } - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert.go similarity index 83% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert.go index 315b7ce5b653..1996ba8b9cef 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert.go @@ -28,21 +28,21 @@ type InsertEntityInput struct { } type InsertResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Insert inserts a new entity into a table. -func (c Client) Insert(ctx context.Context, tableName string, input InsertEntityInput) (resp InsertResponse, err error) { +func (c Client) Insert(ctx context.Context, tableName string, input InsertEntityInput) (result InsertResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + return result, fmt.Errorf("`tableName` cannot be an empty string") } if input.PartitionKey == "" { - return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } if input.RowKey == "" { - return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") } opts := client.RequestOptions{ @@ -68,10 +68,14 @@ func (c Client) Insert(ctx context.Context, tableName string, input InsertEntity err = req.Marshal(&input.Entity) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + return result, fmt.Errorf("marshalling request: %+v", err) } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_merge.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_merge.go similarity index 83% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_merge.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_merge.go index 27cae93239bf..8ec8191f6ea5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_merge.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_merge.go @@ -25,22 +25,22 @@ type InsertOrMergeEntityInput struct { } type InsertOrMergeResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // InsertOrMerge updates an existing entity or inserts a new entity if it does not exist in the table. // Because this operation can insert or update an entity, it is also known as an upsert operation. -func (c Client) InsertOrMerge(ctx context.Context, tableName string, input InsertOrMergeEntityInput) (resp InsertOrMergeResponse, err error) { +func (c Client) InsertOrMerge(ctx context.Context, tableName string, input InsertOrMergeEntityInput) (result InsertOrMergeResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + return result, fmt.Errorf("`tableName` cannot be an empty string") } if input.PartitionKey == "" { - return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } if input.RowKey == "" { - return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") } opts := client.RequestOptions{ @@ -64,10 +64,14 @@ func (c Client) InsertOrMerge(ctx context.Context, tableName string, input Inser err = req.Marshal(&input.Entity) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + return result, fmt.Errorf("marshalling request: %+v", err) } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_replace.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_replace.go similarity index 83% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_replace.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_replace.go index 6f97eb624b7d..269437c06cae 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/insert_or_replace.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_replace.go @@ -25,22 +25,22 @@ type InsertOrReplaceEntityInput struct { } type InsertOrReplaceResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // InsertOrReplace replaces an existing entity or inserts a new entity if it does not exist in the table. // Because this operation can insert or update an entity, it is also known as an upsert operation. -func (c Client) InsertOrReplace(ctx context.Context, tableName string, input InsertOrReplaceEntityInput) (resp InsertOrReplaceResponse, err error) { +func (c Client) InsertOrReplace(ctx context.Context, tableName string, input InsertOrReplaceEntityInput) (result InsertOrReplaceResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + return result, fmt.Errorf("`tableName` cannot be an empty string") } if input.PartitionKey == "" { - return resp, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") } if input.RowKey == "" { - return resp, fmt.Errorf("`input.RowKey` cannot be an empty string") + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") } opts := client.RequestOptions{ @@ -64,10 +64,14 @@ func (c Client) InsertOrReplace(ctx context.Context, tableName string, input Ins err = req.Marshal(&input.Entity) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + return result, fmt.Errorf("marshalling request: %+v", err) } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/models.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/models.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/query.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/query.go similarity index 87% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/query.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/query.go index 9137401377df..57b411a55bf6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/query.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/query.go @@ -35,7 +35,7 @@ type QueryEntitiesInput struct { } type QueryEntitiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response NextPartitionKey string NextRowKey string @@ -45,9 +45,9 @@ type QueryEntitiesResponse struct { } // Query queries entities in a table and includes the $filter and $select options. -func (c Client) Query(ctx context.Context, tableName string, input QueryEntitiesInput) (resp QueryEntitiesResponse, err error) { +func (c Client) Query(ctx context.Context, tableName string, input QueryEntitiesInput) (result QueryEntitiesResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + return result, fmt.Errorf("`tableName` cannot be an empty string") } additionalParameters := make([]string, 0) @@ -82,21 +82,22 @@ func (c Client) Query(ctx context.Context, tableName string, input QueryEntities return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Body != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) - } - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/resource_id.go similarity index 98% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/resource_id.go index 04ebe79add87..741c24bfc5ca 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/version.go similarity index 64% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/version.go index 13d95b5bcd29..5eae649209e3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/version.go @@ -1,4 +1,4 @@ package entities -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "table/entities" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/README.md similarity index 89% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/README.md index a6b5ee2a239f..65a459f79dcd 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/README.md @@ -1,4 +1,4 @@ -## Table Storage Tables SDK for API version 2020-08-04 +## Table Storage Tables SDK for API version 2023-11-03 This package allows you to interact with the Tables Table Storage API @@ -16,7 +16,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_get.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_get.go index d927d38f9c90..3f2f2a18692f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_get.go @@ -10,16 +10,17 @@ import ( ) type GetACLResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` } // GetACL returns the Access Control List for the specified Table -func (c Client) GetACL(ctx context.Context, tableName string) (resp GetACLResponse, err error) { +func (c Client) GetACL(ctx context.Context, tableName string) (result GetACLResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -38,21 +39,22 @@ func (c Client) GetACL(ctx context.Context, tableName string) (resp GetACLRespon return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Body != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response body: %v", err) - } - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_set.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_set.go index 9ff4ad0e0a1e..9749bd062c5f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_set.go @@ -17,13 +17,14 @@ type setAcl struct { } type SetACLResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetACL sets the specified Access Control List for the specified Table -func (c Client) SetACL(ctx context.Context, tableName string, acls []SignedIdentifier) (resp SetACLResponse, err error) { +func (c Client) SetACL(ctx context.Context, tableName string, acls []SignedIdentifier) (result SetACLResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -44,10 +45,15 @@ func (c Client) SetACL(ctx context.Context, tableName string, acls []SignedIdent err = req.Marshal(setAcl{SignedIdentifiers: acls}) if err != nil { - return resp, fmt.Errorf("marshalling request: %+v", err) + err = fmt.Errorf("marshalling request: %+v", err) + return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/create.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/create.go index feeebe40052f..6adfd5ab5e36 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/create.go @@ -14,13 +14,14 @@ type createTableRequest struct { } type CreateTableResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a new table in the storage account. -func (c Client) Create(ctx context.Context, tableName string) (resp CreateTableResponse, err error) { +func (c Client) Create(ctx context.Context, tableName string) (result CreateTableResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -41,10 +42,14 @@ func (c Client) Create(ctx context.Context, tableName string) (resp CreateTableR err = req.Marshal(&createTableRequest{TableName: tableName}) if err != nil { - return resp, fmt.Errorf("marshalling request") + return result, fmt.Errorf("marshalling request") } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/delete.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/delete.go index 3a2817f48282..b1fab65b30c0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/delete.go @@ -10,13 +10,14 @@ import ( ) type DeleteTableResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes the specified table and any data it contains. -func (c Client) Delete(ctx context.Context, tableName string) (resp DeleteTableResponse, err error) { +func (c Client) Delete(ctx context.Context, tableName string) (result DeleteTableResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -35,7 +36,11 @@ func (c Client) Delete(ctx context.Context, tableName string) (resp DeleteTableR return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/exists.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/exists.go index 020bc6081058..dc8a43ae3716 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/exists.go @@ -10,13 +10,14 @@ import ( ) type TableExistsResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Exists checks that the specified table exists -func (c Client) Exists(ctx context.Context, tableName string) (resp TableExistsResponse, err error) { +func (c Client) Exists(ctx context.Context, tableName string) (result TableExistsResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -35,7 +36,11 @@ func (c Client) Exists(ctx context.Context, tableName string) (resp TableExistsR return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/models.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/models.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/query.go similarity index 82% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/query.go index 9a15de8d0fa7..4cc07ead352e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/query.go @@ -10,7 +10,7 @@ import ( ) type GetResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData string `json:"odata.metadata,omitempty"` Tables []GetResultItem `json:"value"` @@ -21,7 +21,7 @@ type QueryInput struct { } // Query returns a list of tables under the specified account. -func (c Client) Query(ctx context.Context, input QueryInput) (resp GetResponse, err error) { +func (c Client) Query(ctx context.Context, input QueryInput) (result GetResponse, err error) { opts := client.RequestOptions{ ExpectedStatusCodes: []int{ @@ -40,21 +40,22 @@ func (c Client) Query(ctx context.Context, input QueryInput) (resp GetResponse, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Body != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) - } - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/resource_id.go similarity index 98% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/resource_id.go index ea04fe35ae31..2dcf79f670ac 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource ID for the given Table diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/version.go similarity index 62% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/version.go index 3e0363fc361e..63c317fdfa2c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/version.go @@ -1,4 +1,4 @@ package tables -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "table/tables" diff --git a/vendor/modules.txt b/vendor/modules.txt index 3631caec2f32..00c498ed0185 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1257,17 +1257,17 @@ github.com/rickb777/plural github.com/sergi/go-diff/diffmatchpatch # github.com/tombuildsstuff/giovanni v0.25.1 ## explicit; go 1.21 -github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts -github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs -github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers -github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems -github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths -github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories -github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files -github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares -github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues -github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities -github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables +github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts +github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs +github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers +github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems +github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths +github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories +github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files +github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares +github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues +github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities +github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables github.com/tombuildsstuff/giovanni/storage/accesscontrol github.com/tombuildsstuff/giovanni/storage/internal/metadata # github.com/tombuildsstuff/kermit v0.20240122.1123108 diff --git a/website/docs/d/storage_share.html.markdown b/website/docs/d/storage_share.html.markdown index 20763c76e730..d4e0bbbdda16 100644 --- a/website/docs/d/storage_share.html.markdown +++ b/website/docs/d/storage_share.html.markdown @@ -10,6 +10,8 @@ description: |- Use this data source to access information about an existing File Share. +~> **Note on Authentication** Shared Key authentication will always be used for this data source, as AzureAD authentication is not supported by the Storage API for files. + ## Example Usage ```hcl diff --git a/website/docs/r/storage_container.html.markdown b/website/docs/r/storage_container.html.markdown index 33465c9183f4..2136d1f4fdca 100644 --- a/website/docs/r/storage_container.html.markdown +++ b/website/docs/r/storage_container.html.markdown @@ -47,6 +47,8 @@ The following arguments are supported: * `container_access_type` - (Optional) The Access Level configured for this Container. Possible values are `blob`, `container` or `private`. Defaults to `private`. +~> **Note** When updating `container_access_type` for an existing storage container resource, Shared Key authentication will always be used, as AzureAD authentication is not supported. + * `metadata` - (Optional) A mapping of MetaData for this Container. All metadata keys should be lowercase. ## Attributes Reference diff --git a/website/docs/r/storage_share.html.markdown b/website/docs/r/storage_share.html.markdown index e79dc16d0f6d..7fd0544df73d 100644 --- a/website/docs/r/storage_share.html.markdown +++ b/website/docs/r/storage_share.html.markdown @@ -10,7 +10,9 @@ description: |- Manages a File Share within Azure Storage. -~> **Note:** The storage share supports two storage tiers: premium and standard. Standard file shares are created in general purpose (GPv1 or GPv2) storage accounts and premium file shares are created in FileStorage storage accounts. For further information, refer to the section "What storage tiers are supported in Azure Files?" of [documentation](https://docs.microsoft.com/azure/storage/files/storage-files-faq#general). +~> **Note** The storage share supports two storage tiers: premium and standard. Standard file shares are created in general purpose (GPv1 or GPv2) storage accounts and premium file shares are created in FileStorage storage accounts. For further information, refer to the section "What storage tiers are supported in Azure Files?" of [documentation](https://docs.microsoft.com/azure/storage/files/storage-files-faq#general). + +~> **Note on Authentication** Shared Key authentication will always be used for this resource, as AzureAD authentication is not supported by the Storage API for files. ## Example Usage diff --git a/website/docs/r/storage_share_directory.html.markdown b/website/docs/r/storage_share_directory.html.markdown index e758c74abe46..8cba5456992a 100644 --- a/website/docs/r/storage_share_directory.html.markdown +++ b/website/docs/r/storage_share_directory.html.markdown @@ -33,9 +33,8 @@ resource "azurerm_storage_share" "example" { } resource "azurerm_storage_share_directory" "example" { - name = "example" - share_name = azurerm_storage_share.example.name - storage_account_name = azurerm_storage_account.example.name + name = "example" + storage_share_id = azurerm_storage_share.example.id } ``` @@ -45,9 +44,7 @@ The following arguments are supported: * `name` - (Required) The name (or path) of the Directory that should be created within this File Share. Changing this forces a new resource to be created. -* `share_name` - (Required) The name of the File Share where this Directory should be created. Changing this forces a new resource to be created. - -* `storage_account_name` - (Required) The name of the Storage Account within which the File Share is located. Changing this forces a new resource to be created. +* `storage_share_id` - (Required) The Storage Share ID in which this file will be placed into. Changing this forces a new resource to be created. * `metadata` - (Optional) A mapping of metadata to assign to this Directory. diff --git a/website/docs/r/storage_table_entity.html.markdown b/website/docs/r/storage_table_entity.html.markdown index ba0b2e63cee5..c8614b2f8fed 100644 --- a/website/docs/r/storage_table_entity.html.markdown +++ b/website/docs/r/storage_table_entity.html.markdown @@ -32,8 +32,7 @@ resource "azurerm_storage_table" "example" { } resource "azurerm_storage_table_entity" "example" { - storage_account_name = azurerm_storage_account.example.name - table_name = azurerm_storage_table.example.name + storage_table_id = azurerm_storage_table.example.id partition_key = "examplepartition" row_key = "examplerow" @@ -48,13 +47,11 @@ resource "azurerm_storage_table_entity" "example" { The following arguments are supported: -* `storage_account_name` - (Required) Specifies the storage account in which to create the storage table entity. Changing this forces a new resource to be created. - -* `table_name` - (Required) The name of the storage table in which to create the storage table entity. Changing this forces a new resource to be created. +* `storage_table_id` - (Required) The Storage Share ID in which this file will be placed into. Changing this forces a new resource to be created. -* `partition_key` - (Required) The key for the partition where the entity will be inserted/merged. Changing this forces a new resource. +* `partition_key` - (Required) The key for the partition where the entity will be inserted/merged. Changing this forces a new resource to be created. -* `row_key` - (Required) The key for the row where the entity will be inserted/merged. Changing this forces a new resource. +* `row_key` - (Required) The key for the row where the entity will be inserted/merged. Changing this forces a new resource to be created. * `entity` - (Required) A map of key/value pairs that describe the entity to be inserted/merged in to the storage table. From b2c069fd850638f0d9ac389fa7f40747daded9e7 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 1 Mar 2024 00:43:50 +0000 Subject: [PATCH 05/12] machinelearning: support national and private clouds for `azurerm_machine_learning_datastore_blobstorage`, `azurerm_machine_learning_datastore_datalake_gen2` and `azurerm_machine_learning_datastore_fileshare` resources. closes: #22467 --- .../machine_learning_datastore_blobstorage_resource.go | 7 +------ .../machine_learning_datastore_datalake_gen2_resource.go | 1 + .../machine_learning_datastore_fileshare_resource.go | 1 + 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/internal/services/machinelearning/machine_learning_datastore_blobstorage_resource.go b/internal/services/machinelearning/machine_learning_datastore_blobstorage_resource.go index 81dbe550c3ff..a18f56dac9c3 100644 --- a/internal/services/machinelearning/machine_learning_datastore_blobstorage_resource.go +++ b/internal/services/machinelearning/machine_learning_datastore_blobstorage_resource.go @@ -160,14 +160,9 @@ func (r MachineLearningDataStoreBlobStorage) Create() sdk.ResourceFunc { Type: pointer.To(string(datastore.DatastoreTypeAzureBlob)), } - storageDomainSuffix, ok := metadata.Client.Account.Environment.Storage.DomainSuffix() - if !ok { - return fmt.Errorf("could not determine Storage domain suffix for environment %q", metadata.Client.Account.Environment.Name) - } - props := &datastore.AzureBlobDatastore{ AccountName: pointer.To(containerId.StorageAccountName), - Endpoint: storageDomainSuffix, + Endpoint: pointer.To(metadata.Client.Storage.StorageDomainSuffix), ContainerName: pointer.To(containerId.ContainerName), Description: pointer.To(model.Description), ServiceDataAccessAuthIdentity: pointer.To(datastore.ServiceDataAccessAuthIdentity(model.ServiceDataAuthIdentity)), diff --git a/internal/services/machinelearning/machine_learning_datastore_datalake_gen2_resource.go b/internal/services/machinelearning/machine_learning_datastore_datalake_gen2_resource.go index 819e8bd67594..ee95fb156a10 100644 --- a/internal/services/machinelearning/machine_learning_datastore_datalake_gen2_resource.go +++ b/internal/services/machinelearning/machine_learning_datastore_datalake_gen2_resource.go @@ -178,6 +178,7 @@ func (r MachineLearningDataStoreDataLakeGen2) Create() sdk.ResourceFunc { props := &datastore.AzureDataLakeGen2Datastore{ AccountName: containerId.StorageAccountName, + Endpoint: pointer.To(metadata.Client.Storage.StorageDomainSuffix), Filesystem: containerId.ContainerName, Description: utils.String(model.Description), ServiceDataAccessAuthIdentity: pointer.To(datastore.ServiceDataAccessAuthIdentity(model.ServiceDataIdentity)), diff --git a/internal/services/machinelearning/machine_learning_datastore_fileshare_resource.go b/internal/services/machinelearning/machine_learning_datastore_fileshare_resource.go index 4e452949b913..a1b50df2fbcd 100644 --- a/internal/services/machinelearning/machine_learning_datastore_fileshare_resource.go +++ b/internal/services/machinelearning/machine_learning_datastore_fileshare_resource.go @@ -161,6 +161,7 @@ func (r MachineLearningDataStoreFileShare) Create() sdk.ResourceFunc { props := &datastore.AzureFileDatastore{ AccountName: fileShareId.StorageAccountName, + Endpoint: pointer.To(metadata.Client.Storage.StorageDomainSuffix), FileShareName: fileShareId.FileshareName, Description: pointer.To(model.Description), ServiceDataAccessAuthIdentity: pointer.To(datastore.ServiceDataAccessAuthIdentity(model.ServiceDataIdentity)), From cd850520df4d135587134f593d61641192683d8c Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 1 Mar 2024 01:02:38 +0000 Subject: [PATCH 06/12] update docs for `storage_use_azuread` provider property --- website/docs/index.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 9555c1bf6ad6..8a9f14886329 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -201,7 +201,7 @@ For some advanced scenarios, such as where more granular permissions are necessa ~> **Note:** This requires that the User/Service Principal being used has the associated `Storage` roles - which are added to new Contributor/Owner role-assignments, but **have not** been backported by Azure to existing role-assignments. -~> **Note:** The Files & Table Storage API's do not support authenticating via AzureAD and will continue to use a SharedKey to access the API's. +~> **Note:** The Files Storage API does not support authenticating via AzureAD and will continue to use a SharedKey when AAD authentication is enabled. * `use_msal` - (Optional) When `true`, and when using service principal authentication, the provider will obtain [v2 authentication tokens](https://docs.microsoft.com/azure/active-directory/develop/access-tokens#token-formats-and-ownership) from the Microsoft Identity Platform. Has no effect when authenticating via Managed Identity or the Azure CLI. Can also be set via the `ARM_USE_MSAL` or `ARM_USE_MSGRAPH` environment variables. From 4d4e810a43b5b0ab7cfb72338a82295f9c7fbeb4 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 1 Mar 2024 01:47:37 +0000 Subject: [PATCH 07/12] azurerm_storaage_table: always use shared key auth as ACLs are not supported with AAD authentication --- .../storage/storage_table_resource.go | 33 +++++++++++++------ website/docs/r/storage_table.html.markdown | 2 ++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/internal/services/storage/storage_table_resource.go b/internal/services/storage/storage_table_resource.go index 598ee58ae5b0..ef34a4cef454 100644 --- a/internal/services/storage/storage_table_resource.go +++ b/internal/services/storage/storage_table_resource.go @@ -121,13 +121,13 @@ func resourceStorageTableCreate(d *pluginsdk.ResourceData, meta interface{}) err tablesDataPlaneClient, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Client: %s", err) + return fmt.Errorf("building Tables Client: %s", err) } // Determine the table endpoint, so we can build a data plane ID endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeTable) if err != nil { - return fmt.Errorf("determining Table endpoint: %v", err) + return fmt.Errorf("determining Tables endpoint: %v", err) } // Parse the table endpoint as a data plane account ID @@ -152,7 +152,13 @@ func resourceStorageTableCreate(d *pluginsdk.ResourceData, meta interface{}) err d.SetId(id.ID()) - if err = tablesDataPlaneClient.UpdateACLs(ctx, tableName, acls); err != nil { + // Setting ACLs only supports shared key authentication (@manicminer, 2024-02-29) + aclClient, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) + if err != nil { + return fmt.Errorf("building Tables Client: %v", err) + } + + if err = aclClient.UpdateACLs(ctx, tableName, acls); err != nil { return fmt.Errorf("setting ACLs for %s: %v", id, err) } @@ -194,7 +200,13 @@ func resourceStorageTableRead(d *pluginsdk.ResourceData, meta interface{}) error return nil } - acls, err := client.GetACLs(ctx, id.TableName) + // Retrieving ACLs only supports shared key authentication (@manicminer, 2024-02-29) + aclClient, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) + if err != nil { + return fmt.Errorf("building Tables Client: %v", err) + } + + acls, err := aclClient.GetACLs(ctx, id.TableName) if err != nil { return fmt.Errorf("retrieving ACLs for %s: %v", id, err) } @@ -257,18 +269,19 @@ func resourceStorageTableUpdate(d *pluginsdk.ResourceData, meta interface{}) err return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) - if err != nil { - return fmt.Errorf("building Table Client: %v", err) - } - if d.HasChange("acl") { log.Printf("[DEBUG] Updating ACLs for %s", id) aclsRaw := d.Get("acl").(*pluginsdk.Set).List() acls := expandStorageTableACLs(aclsRaw) - if err = client.UpdateACLs(ctx, id.TableName, acls); err != nil { + // Setting ACLs only supports shared key authentication (@manicminer, 2024-02-29) + aclClient, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) + if err != nil { + return fmt.Errorf("building Tables Client: %v", err) + } + + if err = aclClient.UpdateACLs(ctx, id.TableName, acls); err != nil { return fmt.Errorf("updating ACLs for %s: %v", id, err) } diff --git a/website/docs/r/storage_table.html.markdown b/website/docs/r/storage_table.html.markdown index 22b7ffefa569..3235526402cb 100644 --- a/website/docs/r/storage_table.html.markdown +++ b/website/docs/r/storage_table.html.markdown @@ -10,6 +10,8 @@ description: |- Manages a Table within an Azure Storage Account. +~> **Note on Authentication** Shared Key authentication will always be used for this resource, as AzureAD authentication is not supported when setting or retrieving ACLs for Tables. + ## Example Usage ```hcl From 2022cfab9efb9abab0d24decf9898b1ab201afa3 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 1 Mar 2024 11:38:08 +0000 Subject: [PATCH 08/12] storage: add more tests for AzureAD authentication, remove superfluous checks where AzureAD auth not supported --- .../services/storage/client/data_plane.go | 4 +- .../storage_share_directory_resource_test.go | 48 +++++++++++++++++ .../storage/storage_share_file_resource.go | 41 --------------- .../storage_share_file_resource_test.go | 52 +++++++++++++++++++ .../storage/storage_table_entity_resource.go | 2 +- .../storage_table_entity_resource_test.go | 52 +++++++++++++++++++ 6 files changed, 155 insertions(+), 44 deletions(-) diff --git a/internal/services/storage/client/data_plane.go b/internal/services/storage/client/data_plane.go index 0ab198faa5f6..3e99076610d7 100644 --- a/internal/services/storage/client/data_plane.go +++ b/internal/services/storage/client/data_plane.go @@ -176,7 +176,7 @@ func (client Client) DataLakePathsDataPlaneClient(ctx context.Context, account a } func (client Client) FileShareDirectoriesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*directories.Client, error) { - const clientName = "File Storage Shares" + const clientName = "File Storage Share Directories" operation.sharedKeyAuthenticationType = auth.SharedKey baseUri, err := account.DataPlaneEndpoint(EndpointTypeFile) @@ -220,7 +220,7 @@ func (client Client) FileShareFilesDataPlaneClient(ctx context.Context, account } func (client Client) FileSharesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageShareWrapper, error) { - const clientName = "File Storage Share Shares" + const clientName = "File Storage Shares" operation.sharedKeyAuthenticationType = auth.SharedKey baseUri, err := account.DataPlaneEndpoint(EndpointTypeFile) diff --git a/internal/services/storage/storage_share_directory_resource_test.go b/internal/services/storage/storage_share_directory_resource_test.go index 9617eabbbdef..573a34b25a6c 100644 --- a/internal/services/storage/storage_share_directory_resource_test.go +++ b/internal/services/storage/storage_share_directory_resource_test.go @@ -34,6 +34,21 @@ func TestAccStorageShareDirectory_basic(t *testing.T) { }) } +func TestAccStorageShareDirectory_basicAzureADAuth(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_storage_share_directory", "test") + r := StorageShareDirectoryResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicAzureADAuth(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccStorageShareDirectory_basicDeprecated(t *testing.T) { // TODO: remove test in v4.0 data := acceptance.BuildTestData(t, "azurerm_storage_share_directory", "test") @@ -203,6 +218,39 @@ resource "azurerm_storage_share_directory" "test" { `, template) } +func (r StorageShareDirectoryResource) basicAzureADAuth(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + storage_use_azuread = true + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%[3]s" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_share" "test" { + name = "fileshare" + storage_account_name = azurerm_storage_account.test.name + quota = 50 +} + +resource "azurerm_storage_share_directory" "test" { + name = "dir" + storage_share_id = azurerm_storage_share.test.id +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString) +} + func (r StorageShareDirectoryResource) basicDeprecated(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` diff --git a/internal/services/storage/storage_share_file_resource.go b/internal/services/storage/storage_share_file_resource.go index fd88486c068f..7fc78dcccfa4 100644 --- a/internal/services/storage/storage_share_file_resource.go +++ b/internal/services/storage/storage_share_file_resource.go @@ -134,19 +134,6 @@ func resourceStorageShareFileCreate(d *pluginsdk.ResourceData, meta interface{}) id := files.NewFileID(*accountId, storageShareId.ShareName, path, fileName) - fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) - if err != nil { - return fmt.Errorf("building File Share Directories Client: %v", err) - } - - share, err := fileSharesClient.Get(ctx, storageShareId.ShareName) - if err != nil { - return fmt.Errorf("retrieving Share %q for File %q: %v", storageShareId.ShareName, fileName, err) - } - if share == nil { - return fmt.Errorf("unable to locate Storage Share %q", storageShareId.ShareName) - } - client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building File Share Directories Client: %s", err) @@ -226,19 +213,6 @@ func resourceStorageShareFileUpdate(d *pluginsdk.ResourceData, meta interface{}) return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) - if err != nil { - return fmt.Errorf("building File Share Directories Client: %v", err) - } - - share, err := fileSharesClient.Get(ctx, id.ShareName) - if err != nil { - return fmt.Errorf("retrieving %s: %v", id, err) - } - if share == nil { - return fmt.Errorf("unable to locate Storage Share %q", id.ShareName) - } - client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building File Share Files Client: %v", err) @@ -292,21 +266,6 @@ func resourceStorageShareFileRead(d *pluginsdk.ResourceData, meta interface{}) e return nil } - fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) - if err != nil { - return fmt.Errorf("building File Share Directories Client: %s", err) - } - - share, err := fileSharesClient.Get(ctx, id.ShareName) - if err != nil { - return fmt.Errorf("retrieving Share %q for File %q: %s", id.ShareName, id.FileName, err) - } - if share == nil { - log.Printf("[WARN] Unable to determine Storage Share for %s - assuming removed & removing from state", id) - d.SetId("") - return nil - } - client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building File Share Client for Storage Account %s: %s", id.AccountId, err) diff --git a/internal/services/storage/storage_share_file_resource_test.go b/internal/services/storage/storage_share_file_resource_test.go index e488f909e9be..139af76c9d67 100644 --- a/internal/services/storage/storage_share_file_resource_test.go +++ b/internal/services/storage/storage_share_file_resource_test.go @@ -36,6 +36,21 @@ func TestAccAzureRMStorageShareFile_basic(t *testing.T) { }) } +func TestAccAzureRMStorageShareFile_basicAzureADAuth(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_storage_share_file", "test") + r := StorageShareFileResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicAzureADAuth(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccAzureRMStorageShareFile_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_storage_share_file", "test") r := StorageShareFileResource{} @@ -208,6 +223,43 @@ resource "azurerm_storage_share_file" "test" { `, r.template(data)) } +func (r StorageShareFileResource) basicAzureADAuth(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + storage_use_azuread = true + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-storage-%[1]d" + location = "%[2]s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%[3]s" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_share" "test" { + name = "fileshare" + storage_account_name = azurerm_storage_account.test.name + quota = 50 +} + +resource "azurerm_storage_share_file" "test" { + name = "dir" + storage_share_id = azurerm_storage_share.test.id + + metadata = { + hello = "world" + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString) +} + func (r StorageShareFileResource) requiresImport(data acceptance.TestData) string { return fmt.Sprintf(` %s diff --git a/internal/services/storage/storage_table_entity_resource.go b/internal/services/storage/storage_table_entity_resource.go index 3ede566cb41d..8d61e74fa4f0 100644 --- a/internal/services/storage/storage_table_entity_resource.go +++ b/internal/services/storage/storage_table_entity_resource.go @@ -176,7 +176,7 @@ func resourceStorageTableEntityCreate(d *pluginsdk.ResourceData, meta interface{ } } - if !response.WasNotFound(existing.HttpResponse) { + if !response.WasNotFound(existing.HttpResponse) && !response.WasForbidden(existing.HttpResponse) { return tf.ImportAsExistsError("azurerm_storage_table_entity", id.ID()) } diff --git a/internal/services/storage/storage_table_entity_resource_test.go b/internal/services/storage/storage_table_entity_resource_test.go index aca908ee7ed2..def0633d6565 100644 --- a/internal/services/storage/storage_table_entity_resource_test.go +++ b/internal/services/storage/storage_table_entity_resource_test.go @@ -34,6 +34,21 @@ func TestAccTableEntity_basic(t *testing.T) { }) } +func TestAccTableEntity_basicAzureADAuth(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_storage_table_entity", "test") + r := StorageTableEntityResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicAzureADAuth(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccTableEntity_basicDeprecated(t *testing.T) { // TODO: remove test in v4.0 data := acceptance.BuildTestData(t, "azurerm_storage_table_entity", "test") @@ -212,6 +227,43 @@ resource "azurerm_storage_table_entity" "test" { `, template, data.RandomInteger) } +func (r StorageTableEntityResource) basicAzureADAuth(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + storage_use_azuread = true + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%[3]s" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_table" "test" { + name = "acctestst%[1]d" + storage_account_name = azurerm_storage_account.test.name +} + +resource "azurerm_storage_table_entity" "test" { + storage_table_id = azurerm_storage_table.test.id + + partition_key = "test_partition%[1]d" + row_key = "test_row%[1]d" + entity = { + Foo = "Bar" + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString) +} + func (r StorageTableEntityResource) basicDeprecated(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` From 049c93d88872a69fc0d77cfa3de107dd67489936 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 1 Mar 2024 12:59:12 +0000 Subject: [PATCH 09/12] azurerm_virtual_machine: ensure testcheck func context has a deadline --- internal/services/legacy/virtual_machine_resource_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/services/legacy/virtual_machine_resource_test.go b/internal/services/legacy/virtual_machine_resource_test.go index edf31b377ed5..1e5eb5e0d43a 100644 --- a/internal/services/legacy/virtual_machine_resource_test.go +++ b/internal/services/legacy/virtual_machine_resource_test.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "testing" + "time" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" @@ -239,6 +240,9 @@ func (VirtualMachineResource) deallocate(ctx context.Context, client *clients.Cl func (VirtualMachineResource) unmanagedDiskExistsInContainer(blobName string, shouldExist bool) acceptance.ClientCheckFunc { return func(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) error { + ctx, cancel := context.WithTimeout(ctx, 5*time.Minute) + defer cancel() + accountName := state.Attributes["storage_account_name"] containerName := state.Attributes["name"] From e3f0cae1c45f8e10a29f5296ee48f67ca1254139 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 13 Mar 2024 12:01:57 +0000 Subject: [PATCH 10/12] address review, improve storage account URL handling in kubernetes flux configuration resources --- ..._kubernetes_flux_configuration_resource.go | 10 ++++--- .../kubernetes_flux_configuration_resource.go | 10 ++++--- .../services/storage/client/data_plane.go | 28 +++++++++---------- ...rage_data_lake_gen2_filesystem_resource.go | 24 ++++++++-------- ...data_lake_gen2_filesystem_resource_test.go | 4 +-- .../storage_data_lake_gen2_path_resource.go | 22 +++++++-------- ...orage_data_lake_gen2_path_resource_test.go | 2 +- 7 files changed, 52 insertions(+), 48 deletions(-) diff --git a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go index 583300f6451e..3775f9fc12df 100644 --- a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go +++ b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go @@ -7,7 +7,6 @@ import ( "context" "fmt" "regexp" - "strings" "time" "github.com/hashicorp/go-azure-helpers/lang/pointer" @@ -19,6 +18,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) @@ -783,7 +783,7 @@ func expandArcAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel, sto } output.ContainerName = &id.ContainerName - output.Url = pointer.To(strings.TrimSuffix(input.ContainerID, "/"+id.ContainerName)) + output.Url = pointer.To(id.AccountId.ID()) } if input.LocalAuthRef != "" { @@ -974,11 +974,13 @@ func flattenArcAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefini return outputList, nil } - id, err := containers.ParseContainerID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName)), storageDomainSuffix) + accountId, err := accounts.ParseAccountID(pointer.From(input.Url), storageDomainSuffix) if err != nil { - return nil, err + return nil, fmt.Errorf("parsing account %q: %+v", input, err) } + id := containers.NewContainerID(*accountId, pointer.From(input.ContainerName)) + output := AzureBlobDefinitionModel{ ContainerID: id.ID(), LocalAuthRef: pointer.From(input.LocalAuthRef), diff --git a/internal/services/containers/kubernetes_flux_configuration_resource.go b/internal/services/containers/kubernetes_flux_configuration_resource.go index 0ad2d980479e..0c9250d3bd6d 100644 --- a/internal/services/containers/kubernetes_flux_configuration_resource.go +++ b/internal/services/containers/kubernetes_flux_configuration_resource.go @@ -7,7 +7,6 @@ import ( "context" "fmt" "regexp" - "strings" "time" "github.com/hashicorp/go-azure-helpers/lang/pointer" @@ -19,6 +18,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) @@ -802,7 +802,7 @@ func expandAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel, storag } output.ContainerName = &id.ContainerName - output.Url = pointer.To(strings.TrimSuffix(input.ContainerID, "/"+id.ContainerName)) + output.Url = pointer.To(id.AccountId.ID()) } if input.LocalAuthRef != "" { @@ -1007,11 +1007,13 @@ func flattenAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinitio return outputList, nil } - id, err := containers.ParseContainerID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName)), storageDomainSuffix) + accountId, err := accounts.ParseAccountID(pointer.From(input.Url), storageDomainSuffix) if err != nil { - return nil, err + return nil, fmt.Errorf("parsing account %q: %+v", input, err) } + id := containers.NewContainerID(*accountId, pointer.From(input.ContainerName)) + output := AzureBlobDefinitionModel{ ContainerID: id.ID(), LocalAuthRef: pointer.From(input.LocalAuthRef), diff --git a/internal/services/storage/client/data_plane.go b/internal/services/storage/client/data_plane.go index 3e99076610d7..d8b284608f6d 100644 --- a/internal/services/storage/client/data_plane.go +++ b/internal/services/storage/client/data_plane.go @@ -41,7 +41,7 @@ func (Client) DataPlaneOperationSupportingOnlySharedKeyAuth() DataPlaneOperation } } -func (client Client) ConfigureDataPlane(ctx context.Context, baseUri, clientName string, baseClient client.BaseClient, account accountDetails, operation DataPlaneOperation) error { +func (client Client) configureDataPlane(ctx context.Context, baseUri, clientName string, baseClient client.BaseClient, account accountDetails, operation DataPlaneOperation) error { if operation.SupportsAadAuthentication && client.authorizerForAad != nil { baseClient.SetAuthorizer(client.authorizerForAad) return nil @@ -79,7 +79,7 @@ func (client Client) AccountsDataPlaneClient(ctx context.Context, account accoun return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -101,7 +101,7 @@ func (client Client) BlobsDataPlaneClient(ctx context.Context, account accountDe return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -123,7 +123,7 @@ func (client Client) ContainersDataPlaneClient(ctx context.Context, account acco return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -132,7 +132,7 @@ func (client Client) ContainersDataPlaneClient(ctx context.Context, account acco } func (client Client) DataLakeFilesystemsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*filesystems.Client, error) { - const clientName = "Data Lake Filesystems" + const clientName = "Data Lake Gen2 Filesystems" operation.sharedKeyAuthenticationType = auth.SharedKey baseUri, err := account.DataPlaneEndpoint(EndpointTypeDfs) @@ -145,7 +145,7 @@ func (client Client) DataLakeFilesystemsDataPlaneClient(ctx context.Context, acc return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -154,7 +154,7 @@ func (client Client) DataLakeFilesystemsDataPlaneClient(ctx context.Context, acc } func (client Client) DataLakePathsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*paths.Client, error) { - const clientName = "Data Lake Paths" + const clientName = "Data Lake Gen2 Paths" operation.sharedKeyAuthenticationType = auth.SharedKey baseUri, err := account.DataPlaneEndpoint(EndpointTypeDfs) @@ -167,7 +167,7 @@ func (client Client) DataLakePathsDataPlaneClient(ctx context.Context, account a return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -189,7 +189,7 @@ func (client Client) FileShareDirectoriesDataPlaneClient(ctx context.Context, ac return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -211,7 +211,7 @@ func (client Client) FileShareFilesDataPlaneClient(ctx context.Context, account return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -233,7 +233,7 @@ func (client Client) FileSharesDataPlaneClient(ctx context.Context, account acco return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -255,7 +255,7 @@ func (client Client) QueuesDataPlaneClient(ctx context.Context, account accountD return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -277,7 +277,7 @@ func (client Client) TableEntityDataPlaneClient(ctx context.Context, account acc return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -299,7 +299,7 @@ func (client Client) TablesDataPlaneClient(ctx context.Context, account accountD return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } diff --git a/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go b/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go index a6dc171ee183..f75fd303e9e6 100644 --- a/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go +++ b/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go @@ -146,7 +146,7 @@ func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta // Confirm the storage account exists and retrieve its properties account, err := storageClient.FindAccount(ctx, accountResourceManagerId.StorageAccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", accountResourceManagerId.StorageAccountName, filesystemName, err) + return fmt.Errorf("retrieving Account %q for Data Lake Gen2 Filesystem %q: %v", accountResourceManagerId.StorageAccountName, filesystemName, err) } if account == nil { return fmt.Errorf("locating Storage Account %q", accountResourceManagerId.StorageAccountName) @@ -155,17 +155,17 @@ func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta // Build the data plane clients dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Filesystems Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Filesystems Client: %v", err) } dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Paths Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Paths Client: %v", err) } // Determine the dfs endpoint, so we can build a data plane ID endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeDfs) if err != nil { - return fmt.Errorf("determining Data Lake Filesystems endpoint: %v", err) + return fmt.Errorf("determining Data Lake Gen2 Filesystems endpoint: %v", err) } // Parse the dfs endpoint as a data plane account ID @@ -257,7 +257,7 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta // Retrieve the storage account properties account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + return fmt.Errorf("retrieving Account %q for Data Lake Gen2 Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) } if account == nil { return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) @@ -266,11 +266,11 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta // Build the data plane clients dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Filesystems Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Filesystems Client: %v", err) } dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Paths Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Paths Client: %v", err) } aceRaw := d.Get("ace").(*pluginsdk.Set).List() @@ -340,7 +340,7 @@ func resourceStorageDataLakeGen2FileSystemRead(d *pluginsdk.ResourceData, meta i // Retrieve the storage account properties account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + return fmt.Errorf("retrieving Account %q for Data Lake Gen2 Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) } if account == nil { return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) @@ -349,11 +349,11 @@ func resourceStorageDataLakeGen2FileSystemRead(d *pluginsdk.ResourceData, meta i // Build the data plane clients dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Filesystems Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Filesystems Client: %v", err) } dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Paths Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Paths Client: %v", err) } resp, err := dataPlaneFilesystemsClient.GetProperties(ctx, id.FileSystemName) @@ -411,7 +411,7 @@ func resourceStorageDataLakeGen2FileSystemDelete(d *pluginsdk.ResourceData, meta // Retrieve the storage account properties account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + return fmt.Errorf("retrieving Account %q for Data Lake Gen2 Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) } if account == nil { return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) @@ -420,7 +420,7 @@ func resourceStorageDataLakeGen2FileSystemDelete(d *pluginsdk.ResourceData, meta // Build the data plane client dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Filesystems Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Filesystems Client: %v", err) } resp, err := dataPlaneFilesystemsClient.Delete(ctx, id.FileSystemName) diff --git a/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go b/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go index a2ff2ff9d97a..90d1a441ede3 100644 --- a/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go +++ b/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go @@ -163,7 +163,7 @@ func (r StorageDataLakeGen2FileSystemResource) Exists(ctx context.Context, clien filesystemsClient, err := client.Storage.DataLakeFilesystemsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return nil, fmt.Errorf("building Data Lake Filesystems Client: %+v", err) + return nil, fmt.Errorf("building Data Lake Gen2 Filesystems Client: %+v", err) } resp, err := filesystemsClient.GetProperties(ctx, id.FileSystemName) @@ -193,7 +193,7 @@ func (r StorageDataLakeGen2FileSystemResource) Destroy(ctx context.Context, clie filesystemsClient, err := client.Storage.DataLakeFilesystemsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return nil, fmt.Errorf("building Data Lake Filesystems Client: %+v", err) + return nil, fmt.Errorf("building Data Lake Gen2 Filesystems Client: %+v", err) } if _, err = filesystemsClient.Delete(ctx, id.FileSystemName); err != nil { diff --git a/internal/services/storage/storage_data_lake_gen2_path_resource.go b/internal/services/storage/storage_data_lake_gen2_path_resource.go index b7ced88bf303..e398e9d696ad 100644 --- a/internal/services/storage/storage_data_lake_gen2_path_resource.go +++ b/internal/services/storage/storage_data_lake_gen2_path_resource.go @@ -54,11 +54,11 @@ func resourceStorageDataLakeGen2Path() *pluginsdk.Resource { // Build the data plane client dataPlaneFilesystemsClient, err := storageClient.DataLakeFilesystemsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("building Data Lake Filesystems Client: %v", err) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("building Data Lake Gen2 Filesystems Client: %v", err) } if _, err = dataPlaneFilesystemsClient.GetProperties(ctx, id.FileSystemName); err != nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving File System %q for Data Lake Gen 2 Path %q in Account %q: %s", id.FileSystemName, id.Path, id.AccountId.AccountName, err) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving File System %q for Data Lake Gen2 Path %q in Account %q: %s", id.FileSystemName, id.Path, id.AccountId.AccountName, err) } d.Set("storage_account_id", account.ID) @@ -167,7 +167,7 @@ func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta inter // Confirm the storage account exists and retrieve its properties account, err := storageClient.FindAccount(ctx, accountResourceManagerId.StorageAccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", accountResourceManagerId.StorageAccountName, filesystemName, err) + return fmt.Errorf("retrieving Account %q for Data Lake Gen2 Filesystem %q: %v", accountResourceManagerId.StorageAccountName, filesystemName, err) } if account == nil { return fmt.Errorf("locating Storage Account %q", accountResourceManagerId.StorageAccountName) @@ -176,13 +176,13 @@ func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta inter // Build the data plane client dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Paths Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Paths Client: %v", err) } // Determine the dfs endpoint, so we can build a data plane ID endpoint, err := account.DataPlaneEndpoint(client.EndpointTypeDfs) if err != nil { - return fmt.Errorf("determining Data Lake Filesystems endpoint: %v", err) + return fmt.Errorf("determining Data Lake Gen2 Filesystems endpoint: %v", err) } // Parse the dfs endpoint as a data plane account ID @@ -271,7 +271,7 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter // Retrieve the storage account properties account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + return fmt.Errorf("retrieving Account %q for Data Lake Gen2 Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) } if account == nil { return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) @@ -280,7 +280,7 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter // Build the data plane client dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Paths Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Paths Client: %v", err) } path := d.Get("path").(string) @@ -334,7 +334,7 @@ func resourceStorageDataLakeGen2PathRead(d *pluginsdk.ResourceData, meta interfa // Retrieve the storage account properties account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + return fmt.Errorf("retrieving Account %q for Data Lake Gen2 Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) } if account == nil { return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) @@ -343,7 +343,7 @@ func resourceStorageDataLakeGen2PathRead(d *pluginsdk.ResourceData, meta interfa // Build the data plane client dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Paths Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Paths Client: %v", err) } resp, err := dataPlanePathsClient.GetProperties(ctx, id.FileSystemName, id.Path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetStatus}) @@ -397,7 +397,7 @@ func resourceStorageDataLakeGen2PathDelete(d *pluginsdk.ResourceData, meta inter // Retrieve the storage account properties account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Data Lake Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) + return fmt.Errorf("retrieving Account %q for Data Lake Gen2 Filesystem %q: %v", id.AccountId.AccountName, id.FileSystemName, err) } if account == nil { return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) @@ -406,7 +406,7 @@ func resourceStorageDataLakeGen2PathDelete(d *pluginsdk.ResourceData, meta inter // Build the data plane client dataPlanePathsClient, err := storageClient.DataLakePathsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Data Lake Paths Client: %v", err) + return fmt.Errorf("building Data Lake Gen2 Paths Client: %v", err) } resp, err := dataPlanePathsClient.Delete(ctx, id.FileSystemName, id.Path) diff --git a/internal/services/storage/storage_data_lake_gen2_path_resource_test.go b/internal/services/storage/storage_data_lake_gen2_path_resource_test.go index 2c324c4232de..81d8130c5934 100644 --- a/internal/services/storage/storage_data_lake_gen2_path_resource_test.go +++ b/internal/services/storage/storage_data_lake_gen2_path_resource_test.go @@ -147,7 +147,7 @@ func (r StorageDataLakeGen2PathResource) Exists(ctx context.Context, client *cli pathsClient, err := client.Storage.DataLakePathsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return nil, fmt.Errorf("building Data Lake Paths Client: %+v", err) + return nil, fmt.Errorf("building Data Lake Gen2 Paths Client: %+v", err) } resp, err := pathsClient.GetProperties(ctx, id.FileSystemName, id.Path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetStatus}) From a7b8108779cd1b9f0cc59fd3fe8584b325ebb072 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 13 Mar 2024 15:07:52 +0000 Subject: [PATCH 11/12] linting --- ..._kubernetes_flux_configuration_resource.go | 2 +- .../kubernetes_flux_configuration_resource.go | 2 +- .../services/storage/client/data_plane.go | 52 +++++++++---------- internal/services/storage/client/helpers.go | 8 +-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go index 3775f9fc12df..1388abf15f79 100644 --- a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go +++ b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go @@ -976,7 +976,7 @@ func flattenArcAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefini accountId, err := accounts.ParseAccountID(pointer.From(input.Url), storageDomainSuffix) if err != nil { - return nil, fmt.Errorf("parsing account %q: %+v", input, err) + return nil, fmt.Errorf("parsing account %q: %+v", pointer.From(input.Url), err) } id := containers.NewContainerID(*accountId, pointer.From(input.ContainerName)) diff --git a/internal/services/containers/kubernetes_flux_configuration_resource.go b/internal/services/containers/kubernetes_flux_configuration_resource.go index 0c9250d3bd6d..6c4fb9004e33 100644 --- a/internal/services/containers/kubernetes_flux_configuration_resource.go +++ b/internal/services/containers/kubernetes_flux_configuration_resource.go @@ -1009,7 +1009,7 @@ func flattenAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinitio accountId, err := accounts.ParseAccountID(pointer.From(input.Url), storageDomainSuffix) if err != nil { - return nil, fmt.Errorf("parsing account %q: %+v", input, err) + return nil, fmt.Errorf("parsing account %q: %+v", pointer.From(input.Url), err) } id := containers.NewContainerID(*accountId, pointer.From(input.ContainerName)) diff --git a/internal/services/storage/client/data_plane.go b/internal/services/storage/client/data_plane.go index d8b284608f6d..7e8a070209fd 100644 --- a/internal/services/storage/client/data_plane.go +++ b/internal/services/storage/client/data_plane.go @@ -41,14 +41,14 @@ func (Client) DataPlaneOperationSupportingOnlySharedKeyAuth() DataPlaneOperation } } -func (client Client) configureDataPlane(ctx context.Context, baseUri, clientName string, baseClient client.BaseClient, account accountDetails, operation DataPlaneOperation) error { - if operation.SupportsAadAuthentication && client.authorizerForAad != nil { - baseClient.SetAuthorizer(client.authorizerForAad) +func (c Client) configureDataPlane(ctx context.Context, clientName string, baseClient client.BaseClient, account accountDetails, operation DataPlaneOperation) error { + if operation.SupportsAadAuthentication && c.authorizerForAad != nil { + baseClient.SetAuthorizer(c.authorizerForAad) return nil } if operation.SupportsSharedKeyAuthentication { - accountKey, err := account.AccountKey(ctx, client) + accountKey, err := account.AccountKey(ctx, c) if err != nil { return fmt.Errorf("retrieving Storage Account Key: %s", err) } @@ -65,7 +65,7 @@ func (client Client) configureDataPlane(ctx context.Context, baseUri, clientName return fmt.Errorf("building %s client: no configured authentication types are supported", clientName) } -func (client Client) AccountsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*accounts.Client, error) { +func (c Client) AccountsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*accounts.Client, error) { const clientName = "Blob Storage Accounts" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -79,7 +79,7 @@ func (client Client) AccountsDataPlaneClient(ctx context.Context, account accoun return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -87,7 +87,7 @@ func (client Client) AccountsDataPlaneClient(ctx context.Context, account accoun return apiClient, nil } -func (client Client) BlobsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*blobs.Client, error) { +func (c Client) BlobsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*blobs.Client, error) { const clientName = "Blob Storage Blobs" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -101,7 +101,7 @@ func (client Client) BlobsDataPlaneClient(ctx context.Context, account accountDe return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -109,7 +109,7 @@ func (client Client) BlobsDataPlaneClient(ctx context.Context, account accountDe return apiClient, nil } -func (client Client) ContainersDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageContainerWrapper, error) { +func (c Client) ContainersDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageContainerWrapper, error) { const clientName = "Blob Storage Containers" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -123,7 +123,7 @@ func (client Client) ContainersDataPlaneClient(ctx context.Context, account acco return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -131,7 +131,7 @@ func (client Client) ContainersDataPlaneClient(ctx context.Context, account acco return shim.NewDataPlaneStorageContainerWrapper(apiClient), nil } -func (client Client) DataLakeFilesystemsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*filesystems.Client, error) { +func (c Client) DataLakeFilesystemsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*filesystems.Client, error) { const clientName = "Data Lake Gen2 Filesystems" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -145,7 +145,7 @@ func (client Client) DataLakeFilesystemsDataPlaneClient(ctx context.Context, acc return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -153,7 +153,7 @@ func (client Client) DataLakeFilesystemsDataPlaneClient(ctx context.Context, acc return apiClient, nil } -func (client Client) DataLakePathsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*paths.Client, error) { +func (c Client) DataLakePathsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*paths.Client, error) { const clientName = "Data Lake Gen2 Paths" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -167,7 +167,7 @@ func (client Client) DataLakePathsDataPlaneClient(ctx context.Context, account a return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -175,7 +175,7 @@ func (client Client) DataLakePathsDataPlaneClient(ctx context.Context, account a return apiClient, nil } -func (client Client) FileShareDirectoriesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*directories.Client, error) { +func (c Client) FileShareDirectoriesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*directories.Client, error) { const clientName = "File Storage Share Directories" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -189,7 +189,7 @@ func (client Client) FileShareDirectoriesDataPlaneClient(ctx context.Context, ac return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -197,7 +197,7 @@ func (client Client) FileShareDirectoriesDataPlaneClient(ctx context.Context, ac return apiClient, nil } -func (client Client) FileShareFilesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*files.Client, error) { +func (c Client) FileShareFilesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*files.Client, error) { const clientName = "File Storage Share Files" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -211,7 +211,7 @@ func (client Client) FileShareFilesDataPlaneClient(ctx context.Context, account return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -219,7 +219,7 @@ func (client Client) FileShareFilesDataPlaneClient(ctx context.Context, account return apiClient, nil } -func (client Client) FileSharesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageShareWrapper, error) { +func (c Client) FileSharesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageShareWrapper, error) { const clientName = "File Storage Shares" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -233,7 +233,7 @@ func (client Client) FileSharesDataPlaneClient(ctx context.Context, account acco return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -241,7 +241,7 @@ func (client Client) FileSharesDataPlaneClient(ctx context.Context, account acco return shim.NewDataPlaneStorageShareWrapper(apiClient), nil } -func (client Client) QueuesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageQueuesWrapper, error) { +func (c Client) QueuesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageQueuesWrapper, error) { const clientName = "File Storage Queue Queues" operation.sharedKeyAuthenticationType = auth.SharedKey @@ -255,7 +255,7 @@ func (client Client) QueuesDataPlaneClient(ctx context.Context, account accountD return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -263,7 +263,7 @@ func (client Client) QueuesDataPlaneClient(ctx context.Context, account accountD return shim.NewDataPlaneStorageQueueWrapper(apiClient), nil } -func (client Client) TableEntityDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*entities.Client, error) { +func (c Client) TableEntityDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*entities.Client, error) { const clientName = "Table Storage Share Entities" operation.sharedKeyAuthenticationType = auth.SharedKeyTable @@ -277,7 +277,7 @@ func (client Client) TableEntityDataPlaneClient(ctx context.Context, account acc return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } @@ -285,7 +285,7 @@ func (client Client) TableEntityDataPlaneClient(ctx context.Context, account acc return apiClient, nil } -func (client Client) TablesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageTableWrapper, error) { +func (c Client) TablesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageTableWrapper, error) { const clientName = "Table Storage Share Tables" operation.sharedKeyAuthenticationType = auth.SharedKeyTable @@ -299,7 +299,7 @@ func (client Client) TablesDataPlaneClient(ctx context.Context, account accountD return nil, fmt.Errorf("building %s client: %+v", clientName, err) } - err = client.configureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + err = c.configureDataPlane(ctx, clientName, apiClient.Client, account, operation) if err != nil { return nil, err } diff --git a/internal/services/storage/client/helpers.go b/internal/services/storage/client/helpers.go index 3396466dced6..47e2fe3162f5 100644 --- a/internal/services/storage/client/helpers.go +++ b/internal/services/storage/client/helpers.go @@ -111,7 +111,7 @@ func (ad *accountDetails) DataPlaneEndpoint(endpointType EndpointType) (*string, return &baseUri, nil } -func (client Client) AddToCache(accountName string, props storage.Account) error { +func (c Client) AddToCache(accountName string, props storage.Account) error { accountsLock.Lock() defer accountsLock.Unlock() @@ -125,13 +125,13 @@ func (client Client) AddToCache(accountName string, props storage.Account) error return nil } -func (client Client) RemoveAccountFromCache(accountName string) { +func (c Client) RemoveAccountFromCache(accountName string) { accountsLock.Lock() delete(storageAccountsCache, accountName) accountsLock.Unlock() } -func (client Client) FindAccount(ctx context.Context, accountName string) (*accountDetails, error) { +func (c Client) FindAccount(ctx context.Context, accountName string) (*accountDetails, error) { accountsLock.Lock() defer accountsLock.Unlock() @@ -139,7 +139,7 @@ func (client Client) FindAccount(ctx context.Context, accountName string) (*acco return &existing, nil } - accountsPage, err := client.AccountsClient.List(ctx) + accountsPage, err := c.AccountsClient.List(ctx) if err != nil { return nil, fmt.Errorf("retrieving storage accounts: %+v", err) } From 3d4058d408aa1c1817f109bd23febec0ef22e749 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 13 Mar 2024 16:48:26 +0000 Subject: [PATCH 12/12] populate global variable for storage domain, to use in validation functions --- ..._kubernetes_flux_configuration_resource.go | 3 ++- .../kubernetes_flux_configuration_resource.go | 3 ++- internal/services/storage/client/client.go | 6 +++++ .../storage/validate/storage_container.go | 22 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go index 1388abf15f79..68810ecab054 100644 --- a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go +++ b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/kubernetesconfiguration/2022-11-01/fluxconfiguration" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/services/containers/validate" + storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/utils" @@ -238,7 +239,7 @@ func (r ArcKubernetesFluxConfigurationResource) Arguments() map[string]*pluginsd "container_id": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL + ValidateFunc: storageValidate.StorageContainerDataPlaneID, }, "account_key": { diff --git a/internal/services/containers/kubernetes_flux_configuration_resource.go b/internal/services/containers/kubernetes_flux_configuration_resource.go index 6c4fb9004e33..3814185e3ee6 100644 --- a/internal/services/containers/kubernetes_flux_configuration_resource.go +++ b/internal/services/containers/kubernetes_flux_configuration_resource.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/kubernetesconfiguration/2022-11-01/fluxconfiguration" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/services/containers/validate" + storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/utils" @@ -243,7 +244,7 @@ func (r KubernetesFluxConfigurationResource) Arguments() map[string]*pluginsdk.S "container_id": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL + ValidateFunc: storageValidate.StorageContainerDataPlaneID, }, "account_key": { diff --git a/internal/services/storage/client/client.go b/internal/services/storage/client/client.go index dd3b3b1ea72b..c5d47935bc7f 100644 --- a/internal/services/storage/client/client.go +++ b/internal/services/storage/client/client.go @@ -17,6 +17,9 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/common" ) +// StorageDomainSuffix is used by validation functions +var StorageDomainSuffix *string + type Client struct { SubscriptionId string @@ -43,6 +46,9 @@ func NewClient(o *common.ClientOptions) (*Client, error) { return nil, fmt.Errorf("determining domain suffix for storage in environment: %s", o.Environment.Name) } + // Set global variable for post-configure validation + StorageDomainSuffix = storageSuffix + accountsClient := storage.NewAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&accountsClient.Client, o.ResourceManagerAuthorizer) diff --git a/internal/services/storage/validate/storage_container.go b/internal/services/storage/validate/storage_container.go index bb378de43f13..e2be952b4b8a 100644 --- a/internal/services/storage/validate/storage_container.go +++ b/internal/services/storage/validate/storage_container.go @@ -6,6 +6,10 @@ package validate import ( "fmt" "regexp" + + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) func StorageContainerName(v interface{}, k string) (warnings []string, errors []error) { @@ -26,3 +30,21 @@ func StorageContainerName(v interface{}, k string) (warnings []string, errors [] } return warnings, errors } + +func StorageContainerDataPlaneID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if client.StorageDomainSuffix == nil { + return validation.IsURLWithPath(input, key) + } + + if _, err := containers.ParseContainerID(v, *client.StorageDomainSuffix); err != nil { + errors = append(errors, err) + } + + return +}