forked from TrueCloudLab/distribution
[#1] Remove vendor directory
Signed-off-by: Roman Loginov <r.loginov@yadro.com>
This commit is contained in:
parent
576d93fee3
commit
39e42437aa
2759 changed files with 0 additions and 970910 deletions
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
202
vendor/cloud.google.com/go/compute/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/compute/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
18
vendor/cloud.google.com/go/compute/internal/version.go
generated
vendored
18
vendor/cloud.google.com/go/compute/internal/version.go
generated
vendored
|
@ -1,18 +0,0 @@
|
||||||
// Copyright 2022 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package internal
|
|
||||||
|
|
||||||
// Version is the current tagged release of the library.
|
|
||||||
const Version = "1.23.0"
|
|
19
vendor/cloud.google.com/go/compute/metadata/CHANGES.md
generated
vendored
19
vendor/cloud.google.com/go/compute/metadata/CHANGES.md
generated
vendored
|
@ -1,19 +0,0 @@
|
||||||
# Changes
|
|
||||||
|
|
||||||
## [0.2.3](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.2...compute/metadata/v0.2.3) (2022-12-15)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compute/metadata:** Switch DNS lookup to an absolute lookup ([119b410](https://github.com/googleapis/google-cloud-go/commit/119b41060c7895e45e48aee5621ad35607c4d021)), refs [#7165](https://github.com/googleapis/google-cloud-go/issues/7165)
|
|
||||||
|
|
||||||
## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.1...compute/metadata/v0.2.2) (2022-12-01)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compute/metadata:** Set IdleConnTimeout for http.Client ([#7084](https://github.com/googleapis/google-cloud-go/issues/7084)) ([766516a](https://github.com/googleapis/google-cloud-go/commit/766516aaf3816bfb3159efeea65aa3d1d205a3e2)), refs [#5430](https://github.com/googleapis/google-cloud-go/issues/5430)
|
|
||||||
|
|
||||||
## [0.1.0] (2022-10-26)
|
|
||||||
|
|
||||||
Initial release of metadata being it's own module.
|
|
202
vendor/cloud.google.com/go/compute/metadata/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/compute/metadata/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
27
vendor/cloud.google.com/go/compute/metadata/README.md
generated
vendored
27
vendor/cloud.google.com/go/compute/metadata/README.md
generated
vendored
|
@ -1,27 +0,0 @@
|
||||||
# Compute API
|
|
||||||
|
|
||||||
[![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/compute.svg)](https://pkg.go.dev/cloud.google.com/go/compute/metadata)
|
|
||||||
|
|
||||||
This is a utility library for communicating with Google Cloud metadata service
|
|
||||||
on Google Cloud.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get cloud.google.com/go/compute/metadata
|
|
||||||
```
|
|
||||||
|
|
||||||
## Go Version Support
|
|
||||||
|
|
||||||
See the [Go Versions Supported](https://github.com/googleapis/google-cloud-go#go-versions-supported)
|
|
||||||
section in the root directory's README.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md)
|
|
||||||
document for details.
|
|
||||||
|
|
||||||
Please note that this project is released with a Contributor Code of Conduct.
|
|
||||||
By participating in this project you agree to abide by its terms. See
|
|
||||||
[Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct)
|
|
||||||
for more information.
|
|
543
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
543
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
|
@ -1,543 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package metadata provides access to Google Compute Engine (GCE)
|
|
||||||
// metadata and API service accounts.
|
|
||||||
//
|
|
||||||
// This package is a wrapper around the GCE metadata service,
|
|
||||||
// as documented at https://cloud.google.com/compute/docs/metadata/overview.
|
|
||||||
package metadata // import "cloud.google.com/go/compute/metadata"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// metadataIP is the documented metadata server IP address.
|
|
||||||
metadataIP = "169.254.169.254"
|
|
||||||
|
|
||||||
// metadataHostEnv is the environment variable specifying the
|
|
||||||
// GCE metadata hostname. If empty, the default value of
|
|
||||||
// metadataIP ("169.254.169.254") is used instead.
|
|
||||||
// This is variable name is not defined by any spec, as far as
|
|
||||||
// I know; it was made up for the Go package.
|
|
||||||
metadataHostEnv = "GCE_METADATA_HOST"
|
|
||||||
|
|
||||||
userAgent = "gcloud-golang/0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
type cachedValue struct {
|
|
||||||
k string
|
|
||||||
trim bool
|
|
||||||
mu sync.Mutex
|
|
||||||
v string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
projID = &cachedValue{k: "project/project-id", trim: true}
|
|
||||||
projNum = &cachedValue{k: "project/numeric-project-id", trim: true}
|
|
||||||
instID = &cachedValue{k: "instance/id", trim: true}
|
|
||||||
)
|
|
||||||
|
|
||||||
var defaultClient = &Client{hc: newDefaultHTTPClient()}
|
|
||||||
|
|
||||||
func newDefaultHTTPClient() *http.Client {
|
|
||||||
return &http.Client{
|
|
||||||
Transport: &http.Transport{
|
|
||||||
Dial: (&net.Dialer{
|
|
||||||
Timeout: 2 * time.Second,
|
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
}).Dial,
|
|
||||||
IdleConnTimeout: 60 * time.Second,
|
|
||||||
},
|
|
||||||
Timeout: 5 * time.Second,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotDefinedError is returned when requested metadata is not defined.
|
|
||||||
//
|
|
||||||
// The underlying string is the suffix after "/computeMetadata/v1/".
|
|
||||||
//
|
|
||||||
// This error is not returned if the value is defined to be the empty
|
|
||||||
// string.
|
|
||||||
type NotDefinedError string
|
|
||||||
|
|
||||||
func (suffix NotDefinedError) Error() string {
|
|
||||||
return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cachedValue) get(cl *Client) (v string, err error) {
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
c.mu.Lock()
|
|
||||||
if c.v != "" {
|
|
||||||
return c.v, nil
|
|
||||||
}
|
|
||||||
if c.trim {
|
|
||||||
v, err = cl.getTrimmed(c.k)
|
|
||||||
} else {
|
|
||||||
v, err = cl.Get(c.k)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
c.v = v
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
onGCEOnce sync.Once
|
|
||||||
onGCE bool
|
|
||||||
)
|
|
||||||
|
|
||||||
// OnGCE reports whether this process is running on Google Compute Engine.
|
|
||||||
func OnGCE() bool {
|
|
||||||
onGCEOnce.Do(initOnGCE)
|
|
||||||
return onGCE
|
|
||||||
}
|
|
||||||
|
|
||||||
func initOnGCE() {
|
|
||||||
onGCE = testOnGCE()
|
|
||||||
}
|
|
||||||
|
|
||||||
func testOnGCE() bool {
|
|
||||||
// The user explicitly said they're on GCE, so trust them.
|
|
||||||
if os.Getenv(metadataHostEnv) != "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
resc := make(chan bool, 2)
|
|
||||||
|
|
||||||
// Try two strategies in parallel.
|
|
||||||
// See https://github.com/googleapis/google-cloud-go/issues/194
|
|
||||||
go func() {
|
|
||||||
req, _ := http.NewRequest("GET", "http://"+metadataIP, nil)
|
|
||||||
req.Header.Set("User-Agent", userAgent)
|
|
||||||
res, err := newDefaultHTTPClient().Do(req.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
resc <- false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
resc <- res.Header.Get("Metadata-Flavor") == "Google"
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
resolver := &net.Resolver{}
|
|
||||||
addrs, err := resolver.LookupHost(ctx, "metadata.google.internal.")
|
|
||||||
if err != nil || len(addrs) == 0 {
|
|
||||||
resc <- false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resc <- strsContains(addrs, metadataIP)
|
|
||||||
}()
|
|
||||||
|
|
||||||
tryHarder := systemInfoSuggestsGCE()
|
|
||||||
if tryHarder {
|
|
||||||
res := <-resc
|
|
||||||
if res {
|
|
||||||
// The first strategy succeeded, so let's use it.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// Wait for either the DNS or metadata server probe to
|
|
||||||
// contradict the other one and say we are running on
|
|
||||||
// GCE. Give it a lot of time to do so, since the system
|
|
||||||
// info already suggests we're running on a GCE BIOS.
|
|
||||||
timer := time.NewTimer(5 * time.Second)
|
|
||||||
defer timer.Stop()
|
|
||||||
select {
|
|
||||||
case res = <-resc:
|
|
||||||
return res
|
|
||||||
case <-timer.C:
|
|
||||||
// Too slow. Who knows what this system is.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There's no hint from the system info that we're running on
|
|
||||||
// GCE, so use the first probe's result as truth, whether it's
|
|
||||||
// true or false. The goal here is to optimize for speed for
|
|
||||||
// users who are NOT running on GCE. We can't assume that
|
|
||||||
// either a DNS lookup or an HTTP request to a blackholed IP
|
|
||||||
// address is fast. Worst case this should return when the
|
|
||||||
// metaClient's Transport.ResponseHeaderTimeout or
|
|
||||||
// Transport.Dial.Timeout fires (in two seconds).
|
|
||||||
return <-resc
|
|
||||||
}
|
|
||||||
|
|
||||||
// systemInfoSuggestsGCE reports whether the local system (without
|
|
||||||
// doing network requests) suggests that we're running on GCE. If this
|
|
||||||
// returns true, testOnGCE tries a bit harder to reach its metadata
|
|
||||||
// server.
|
|
||||||
func systemInfoSuggestsGCE() bool {
|
|
||||||
if runtime.GOOS != "linux" {
|
|
||||||
// We don't have any non-Linux clues available, at least yet.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name")
|
|
||||||
name := strings.TrimSpace(string(slurp))
|
|
||||||
return name == "Google" || name == "Google Compute Engine"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe calls Client.Subscribe on the default client.
|
|
||||||
func Subscribe(suffix string, fn func(v string, ok bool) error) error {
|
|
||||||
return defaultClient.Subscribe(suffix, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get calls Client.Get on the default client.
|
|
||||||
func Get(suffix string) (string, error) { return defaultClient.Get(suffix) }
|
|
||||||
|
|
||||||
// ProjectID returns the current instance's project ID string.
|
|
||||||
func ProjectID() (string, error) { return defaultClient.ProjectID() }
|
|
||||||
|
|
||||||
// NumericProjectID returns the current instance's numeric project ID.
|
|
||||||
func NumericProjectID() (string, error) { return defaultClient.NumericProjectID() }
|
|
||||||
|
|
||||||
// InternalIP returns the instance's primary internal IP address.
|
|
||||||
func InternalIP() (string, error) { return defaultClient.InternalIP() }
|
|
||||||
|
|
||||||
// ExternalIP returns the instance's primary external (public) IP address.
|
|
||||||
func ExternalIP() (string, error) { return defaultClient.ExternalIP() }
|
|
||||||
|
|
||||||
// Email calls Client.Email on the default client.
|
|
||||||
func Email(serviceAccount string) (string, error) { return defaultClient.Email(serviceAccount) }
|
|
||||||
|
|
||||||
// Hostname returns the instance's hostname. This will be of the form
|
|
||||||
// "<instanceID>.c.<projID>.internal".
|
|
||||||
func Hostname() (string, error) { return defaultClient.Hostname() }
|
|
||||||
|
|
||||||
// InstanceTags returns the list of user-defined instance tags,
|
|
||||||
// assigned when initially creating a GCE instance.
|
|
||||||
func InstanceTags() ([]string, error) { return defaultClient.InstanceTags() }
|
|
||||||
|
|
||||||
// InstanceID returns the current VM's numeric instance ID.
|
|
||||||
func InstanceID() (string, error) { return defaultClient.InstanceID() }
|
|
||||||
|
|
||||||
// InstanceName returns the current VM's instance ID string.
|
|
||||||
func InstanceName() (string, error) { return defaultClient.InstanceName() }
|
|
||||||
|
|
||||||
// Zone returns the current VM's zone, such as "us-central1-b".
|
|
||||||
func Zone() (string, error) { return defaultClient.Zone() }
|
|
||||||
|
|
||||||
// InstanceAttributes calls Client.InstanceAttributes on the default client.
|
|
||||||
func InstanceAttributes() ([]string, error) { return defaultClient.InstanceAttributes() }
|
|
||||||
|
|
||||||
// ProjectAttributes calls Client.ProjectAttributes on the default client.
|
|
||||||
func ProjectAttributes() ([]string, error) { return defaultClient.ProjectAttributes() }
|
|
||||||
|
|
||||||
// InstanceAttributeValue calls Client.InstanceAttributeValue on the default client.
|
|
||||||
func InstanceAttributeValue(attr string) (string, error) {
|
|
||||||
return defaultClient.InstanceAttributeValue(attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectAttributeValue calls Client.ProjectAttributeValue on the default client.
|
|
||||||
func ProjectAttributeValue(attr string) (string, error) {
|
|
||||||
return defaultClient.ProjectAttributeValue(attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scopes calls Client.Scopes on the default client.
|
|
||||||
func Scopes(serviceAccount string) ([]string, error) { return defaultClient.Scopes(serviceAccount) }
|
|
||||||
|
|
||||||
func strsContains(ss []string, s string) bool {
|
|
||||||
for _, v := range ss {
|
|
||||||
if v == s {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Client provides metadata.
|
|
||||||
type Client struct {
|
|
||||||
hc *http.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient returns a Client that can be used to fetch metadata.
|
|
||||||
// Returns the client that uses the specified http.Client for HTTP requests.
|
|
||||||
// If nil is specified, returns the default client.
|
|
||||||
func NewClient(c *http.Client) *Client {
|
|
||||||
if c == nil {
|
|
||||||
return defaultClient
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Client{hc: c}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getETag returns a value from the metadata service as well as the associated ETag.
|
|
||||||
// This func is otherwise equivalent to Get.
|
|
||||||
func (c *Client) getETag(suffix string) (value, etag string, err error) {
|
|
||||||
ctx := context.TODO()
|
|
||||||
// Using a fixed IP makes it very difficult to spoof the metadata service in
|
|
||||||
// a container, which is an important use-case for local testing of cloud
|
|
||||||
// deployments. To enable spoofing of the metadata service, the environment
|
|
||||||
// variable GCE_METADATA_HOST is first inspected to decide where metadata
|
|
||||||
// requests shall go.
|
|
||||||
host := os.Getenv(metadataHostEnv)
|
|
||||||
if host == "" {
|
|
||||||
// Using 169.254.169.254 instead of "metadata" here because Go
|
|
||||||
// binaries built with the "netgo" tag and without cgo won't
|
|
||||||
// know the search suffix for "metadata" is
|
|
||||||
// ".google.internal", and this IP address is documented as
|
|
||||||
// being stable anyway.
|
|
||||||
host = metadataIP
|
|
||||||
}
|
|
||||||
suffix = strings.TrimLeft(suffix, "/")
|
|
||||||
u := "http://" + host + "/computeMetadata/v1/" + suffix
|
|
||||||
req, err := http.NewRequest("GET", u, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
req.Header.Set("Metadata-Flavor", "Google")
|
|
||||||
req.Header.Set("User-Agent", userAgent)
|
|
||||||
var res *http.Response
|
|
||||||
var reqErr error
|
|
||||||
retryer := newRetryer()
|
|
||||||
for {
|
|
||||||
res, reqErr = c.hc.Do(req)
|
|
||||||
var code int
|
|
||||||
if res != nil {
|
|
||||||
code = res.StatusCode
|
|
||||||
}
|
|
||||||
if delay, shouldRetry := retryer.Retry(code, reqErr); shouldRetry {
|
|
||||||
if err := sleep(ctx, delay); err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if reqErr != nil {
|
|
||||||
return "", "", reqErr
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
if res.StatusCode == http.StatusNotFound {
|
|
||||||
return "", "", NotDefinedError(suffix)
|
|
||||||
}
|
|
||||||
all, err := ioutil.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
if res.StatusCode != 200 {
|
|
||||||
return "", "", &Error{Code: res.StatusCode, Message: string(all)}
|
|
||||||
}
|
|
||||||
return string(all), res.Header.Get("Etag"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns a value from the metadata service.
|
|
||||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
|
|
||||||
//
|
|
||||||
// If the GCE_METADATA_HOST environment variable is not defined, a default of
|
|
||||||
// 169.254.169.254 will be used instead.
|
|
||||||
//
|
|
||||||
// If the requested metadata is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
func (c *Client) Get(suffix string) (string, error) {
|
|
||||||
val, _, err := c.getETag(suffix)
|
|
||||||
return val, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) getTrimmed(suffix string) (s string, err error) {
|
|
||||||
s, err = c.Get(suffix)
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) lines(suffix string) ([]string, error) {
|
|
||||||
j, err := c.Get(suffix)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s := strings.Split(strings.TrimSpace(j), "\n")
|
|
||||||
for i := range s {
|
|
||||||
s[i] = strings.TrimSpace(s[i])
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectID returns the current instance's project ID string.
|
|
||||||
func (c *Client) ProjectID() (string, error) { return projID.get(c) }
|
|
||||||
|
|
||||||
// NumericProjectID returns the current instance's numeric project ID.
|
|
||||||
func (c *Client) NumericProjectID() (string, error) { return projNum.get(c) }
|
|
||||||
|
|
||||||
// InstanceID returns the current VM's numeric instance ID.
|
|
||||||
func (c *Client) InstanceID() (string, error) { return instID.get(c) }
|
|
||||||
|
|
||||||
// InternalIP returns the instance's primary internal IP address.
|
|
||||||
func (c *Client) InternalIP() (string, error) {
|
|
||||||
return c.getTrimmed("instance/network-interfaces/0/ip")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Email returns the email address associated with the service account.
|
|
||||||
// The account may be empty or the string "default" to use the instance's
|
|
||||||
// main account.
|
|
||||||
func (c *Client) Email(serviceAccount string) (string, error) {
|
|
||||||
if serviceAccount == "" {
|
|
||||||
serviceAccount = "default"
|
|
||||||
}
|
|
||||||
return c.getTrimmed("instance/service-accounts/" + serviceAccount + "/email")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExternalIP returns the instance's primary external (public) IP address.
|
|
||||||
func (c *Client) ExternalIP() (string, error) {
|
|
||||||
return c.getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hostname returns the instance's hostname. This will be of the form
|
|
||||||
// "<instanceID>.c.<projID>.internal".
|
|
||||||
func (c *Client) Hostname() (string, error) {
|
|
||||||
return c.getTrimmed("instance/hostname")
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceTags returns the list of user-defined instance tags,
|
|
||||||
// assigned when initially creating a GCE instance.
|
|
||||||
func (c *Client) InstanceTags() ([]string, error) {
|
|
||||||
var s []string
|
|
||||||
j, err := c.Get("instance/tags")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceName returns the current VM's instance ID string.
|
|
||||||
func (c *Client) InstanceName() (string, error) {
|
|
||||||
return c.getTrimmed("instance/name")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zone returns the current VM's zone, such as "us-central1-b".
|
|
||||||
func (c *Client) Zone() (string, error) {
|
|
||||||
zone, err := c.getTrimmed("instance/zone")
|
|
||||||
// zone is of the form "projects/<projNum>/zones/<zoneName>".
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return zone[strings.LastIndex(zone, "/")+1:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceAttributes returns the list of user-defined attributes,
|
|
||||||
// assigned when initially creating a GCE VM instance. The value of an
|
|
||||||
// attribute can be obtained with InstanceAttributeValue.
|
|
||||||
func (c *Client) InstanceAttributes() ([]string, error) { return c.lines("instance/attributes/") }
|
|
||||||
|
|
||||||
// ProjectAttributes returns the list of user-defined attributes
|
|
||||||
// applying to the project as a whole, not just this VM. The value of
|
|
||||||
// an attribute can be obtained with ProjectAttributeValue.
|
|
||||||
func (c *Client) ProjectAttributes() ([]string, error) { return c.lines("project/attributes/") }
|
|
||||||
|
|
||||||
// InstanceAttributeValue returns the value of the provided VM
|
|
||||||
// instance attribute.
|
|
||||||
//
|
|
||||||
// If the requested attribute is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
//
|
|
||||||
// InstanceAttributeValue may return ("", nil) if the attribute was
|
|
||||||
// defined to be the empty string.
|
|
||||||
func (c *Client) InstanceAttributeValue(attr string) (string, error) {
|
|
||||||
return c.Get("instance/attributes/" + attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectAttributeValue returns the value of the provided
|
|
||||||
// project attribute.
|
|
||||||
//
|
|
||||||
// If the requested attribute is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
//
|
|
||||||
// ProjectAttributeValue may return ("", nil) if the attribute was
|
|
||||||
// defined to be the empty string.
|
|
||||||
func (c *Client) ProjectAttributeValue(attr string) (string, error) {
|
|
||||||
return c.Get("project/attributes/" + attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scopes returns the service account scopes for the given account.
|
|
||||||
// The account may be empty or the string "default" to use the instance's
|
|
||||||
// main account.
|
|
||||||
func (c *Client) Scopes(serviceAccount string) ([]string, error) {
|
|
||||||
if serviceAccount == "" {
|
|
||||||
serviceAccount = "default"
|
|
||||||
}
|
|
||||||
return c.lines("instance/service-accounts/" + serviceAccount + "/scopes")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe subscribes to a value from the metadata service.
|
|
||||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
|
|
||||||
// The suffix may contain query parameters.
|
|
||||||
//
|
|
||||||
// Subscribe calls fn with the latest metadata value indicated by the provided
|
|
||||||
// suffix. If the metadata value is deleted, fn is called with the empty string
|
|
||||||
// and ok false. Subscribe blocks until fn returns a non-nil error or the value
|
|
||||||
// is deleted. Subscribe returns the error value returned from the last call to
|
|
||||||
// fn, which may be nil when ok == false.
|
|
||||||
func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error {
|
|
||||||
const failedSubscribeSleep = time.Second * 5
|
|
||||||
|
|
||||||
// First check to see if the metadata value exists at all.
|
|
||||||
val, lastETag, err := c.getETag(suffix)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := fn(val, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ok := true
|
|
||||||
if strings.ContainsRune(suffix, '?') {
|
|
||||||
suffix += "&wait_for_change=true&last_etag="
|
|
||||||
} else {
|
|
||||||
suffix += "?wait_for_change=true&last_etag="
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
val, etag, err := c.getETag(suffix + url.QueryEscape(lastETag))
|
|
||||||
if err != nil {
|
|
||||||
if _, deleted := err.(NotDefinedError); !deleted {
|
|
||||||
time.Sleep(failedSubscribeSleep)
|
|
||||||
continue // Retry on other errors.
|
|
||||||
}
|
|
||||||
ok = false
|
|
||||||
}
|
|
||||||
lastETag = etag
|
|
||||||
|
|
||||||
if err := fn(val, ok); err != nil || !ok {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error contains an error response from the server.
|
|
||||||
type Error struct {
|
|
||||||
// Code is the HTTP response status code.
|
|
||||||
Code int
|
|
||||||
// Message is the server response message.
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message)
|
|
||||||
}
|
|
114
vendor/cloud.google.com/go/compute/metadata/retry.go
generated
vendored
114
vendor/cloud.google.com/go/compute/metadata/retry.go
generated
vendored
|
@ -1,114 +0,0 @@
|
||||||
// Copyright 2021 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package metadata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
maxRetryAttempts = 5
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
syscallRetryable = func(err error) bool { return false }
|
|
||||||
)
|
|
||||||
|
|
||||||
// defaultBackoff is basically equivalent to gax.Backoff without the need for
|
|
||||||
// the dependency.
|
|
||||||
type defaultBackoff struct {
|
|
||||||
max time.Duration
|
|
||||||
mul float64
|
|
||||||
cur time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *defaultBackoff) Pause() time.Duration {
|
|
||||||
d := time.Duration(1 + rand.Int63n(int64(b.cur)))
|
|
||||||
b.cur = time.Duration(float64(b.cur) * b.mul)
|
|
||||||
if b.cur > b.max {
|
|
||||||
b.cur = b.max
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
// sleep is the equivalent of gax.Sleep without the need for the dependency.
|
|
||||||
func sleep(ctx context.Context, d time.Duration) error {
|
|
||||||
t := time.NewTimer(d)
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
t.Stop()
|
|
||||||
return ctx.Err()
|
|
||||||
case <-t.C:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRetryer() *metadataRetryer {
|
|
||||||
return &metadataRetryer{bo: &defaultBackoff{
|
|
||||||
cur: 100 * time.Millisecond,
|
|
||||||
max: 30 * time.Second,
|
|
||||||
mul: 2,
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
type backoff interface {
|
|
||||||
Pause() time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
type metadataRetryer struct {
|
|
||||||
bo backoff
|
|
||||||
attempts int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *metadataRetryer) Retry(status int, err error) (time.Duration, bool) {
|
|
||||||
if status == http.StatusOK {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
retryOk := shouldRetry(status, err)
|
|
||||||
if !retryOk {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
if r.attempts == maxRetryAttempts {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
r.attempts++
|
|
||||||
return r.bo.Pause(), true
|
|
||||||
}
|
|
||||||
|
|
||||||
func shouldRetry(status int, err error) bool {
|
|
||||||
if 500 <= status && status <= 599 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if err == io.ErrUnexpectedEOF {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// Transient network errors should be retried.
|
|
||||||
if syscallRetryable(err) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if err, ok := err.(interface{ Temporary() bool }); ok {
|
|
||||||
if err.Temporary() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err, ok := err.(interface{ Unwrap() error }); ok {
|
|
||||||
return shouldRetry(status, err.Unwrap())
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
26
vendor/cloud.google.com/go/compute/metadata/retry_linux.go
generated
vendored
26
vendor/cloud.google.com/go/compute/metadata/retry_linux.go
generated
vendored
|
@ -1,26 +0,0 @@
|
||||||
// Copyright 2021 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
//go:build linux
|
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package metadata
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Initialize syscallRetryable to return true on transient socket-level
|
|
||||||
// errors. These errors are specific to Linux.
|
|
||||||
syscallRetryable = func(err error) bool { return err == syscall.ECONNRESET || err == syscall.ECONNREFUSED }
|
|
||||||
}
|
|
23
vendor/cloud.google.com/go/compute/metadata/tidyfix.go
generated
vendored
23
vendor/cloud.google.com/go/compute/metadata/tidyfix.go
generated
vendored
|
@ -1,23 +0,0 @@
|
||||||
// Copyright 2022 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// This file, and the {{.RootMod}} import, won't actually become part of
|
|
||||||
// the resultant binary.
|
|
||||||
//go:build modhack
|
|
||||||
// +build modhack
|
|
||||||
|
|
||||||
package metadata
|
|
||||||
|
|
||||||
// Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
|
|
||||||
import _ "cloud.google.com/go/compute/internal"
|
|
126
vendor/cloud.google.com/go/iam/CHANGES.md
generated
vendored
126
vendor/cloud.google.com/go/iam/CHANGES.md
generated
vendored
|
@ -1,126 +0,0 @@
|
||||||
# Changes
|
|
||||||
|
|
||||||
|
|
||||||
## [1.1.1](https://github.com/googleapis/google-cloud-go/compare/iam/v1.1.0...iam/v1.1.1) (2023-06-20)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **iam:** REST query UpdateMask bug ([df52820](https://github.com/googleapis/google-cloud-go/commit/df52820b0e7721954809a8aa8700b93c5662dc9b))
|
|
||||||
|
|
||||||
## [1.1.0](https://github.com/googleapis/google-cloud-go/compare/iam/v1.0.1...iam/v1.1.0) (2023-05-30)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** Update all direct dependencies ([b340d03](https://github.com/googleapis/google-cloud-go/commit/b340d030f2b52a4ce48846ce63984b28583abde6))
|
|
||||||
|
|
||||||
## [1.0.1](https://github.com/googleapis/google-cloud-go/compare/iam/v1.0.0...iam/v1.0.1) (2023-05-08)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **iam:** Update grpc to v1.55.0 ([1147ce0](https://github.com/googleapis/google-cloud-go/commit/1147ce02a990276ca4f8ab7a1ab65c14da4450ef))
|
|
||||||
|
|
||||||
## [1.0.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.13.0...iam/v1.0.0) (2023-04-04)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** Promote to GA ([#7627](https://github.com/googleapis/google-cloud-go/issues/7627)) ([b351906](https://github.com/googleapis/google-cloud-go/commit/b351906a10e17a02d7f7e2551bc1585fd9dc3742))
|
|
||||||
|
|
||||||
## [0.13.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.12.0...iam/v0.13.0) (2023-03-15)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** Update iam and longrunning deps ([91a1f78](https://github.com/googleapis/google-cloud-go/commit/91a1f784a109da70f63b96414bba8a9b4254cddd))
|
|
||||||
|
|
||||||
## [0.12.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.11.0...iam/v0.12.0) (2023-02-17)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** Migrate to new stubs ([a61ddcd](https://github.com/googleapis/google-cloud-go/commit/a61ddcd3041c7af4a15109dc4431f9b327c497fb))
|
|
||||||
|
|
||||||
## [0.11.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.10.0...iam/v0.11.0) (2023-02-16)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** Start generating proto stubs ([970d763](https://github.com/googleapis/google-cloud-go/commit/970d763531b54b2bc75d7ff26a20b6e05150cab8))
|
|
||||||
|
|
||||||
## [0.10.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.9.0...iam/v0.10.0) (2023-01-04)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** Add REST client ([06a54a1](https://github.com/googleapis/google-cloud-go/commit/06a54a16a5866cce966547c51e203b9e09a25bc0))
|
|
||||||
|
|
||||||
## [0.9.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.8.0...iam/v0.9.0) (2022-12-15)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** Rewrite iam sigs and update proto import ([#7137](https://github.com/googleapis/google-cloud-go/issues/7137)) ([ad67fa3](https://github.com/googleapis/google-cloud-go/commit/ad67fa36c263c161226f7fecbab5221592374dca))
|
|
||||||
|
|
||||||
## [0.8.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.7.0...iam/v0.8.0) (2022-12-05)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** Start generating and refresh some libraries ([#7089](https://github.com/googleapis/google-cloud-go/issues/7089)) ([a9045ff](https://github.com/googleapis/google-cloud-go/commit/a9045ff191a711089c37f1d94a63522d9939ce38))
|
|
||||||
|
|
||||||
## [0.7.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.6.0...iam/v0.7.0) (2022-11-03)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** rewrite signatures in terms of new location ([3c4b2b3](https://github.com/googleapis/google-cloud-go/commit/3c4b2b34565795537aac1661e6af2442437e34ad))
|
|
||||||
|
|
||||||
## [0.6.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.5.0...iam/v0.6.0) (2022-10-25)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** start generating stubs dir ([de2d180](https://github.com/googleapis/google-cloud-go/commit/de2d18066dc613b72f6f8db93ca60146dabcfdcc))
|
|
||||||
|
|
||||||
## [0.5.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.4.0...iam/v0.5.0) (2022-09-28)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** remove ListApplicablePolicies ([52dddd1](https://github.com/googleapis/google-cloud-go/commit/52dddd1ed89fbe77e1859311c3b993a77a82bfc7))
|
|
||||||
|
|
||||||
## [0.4.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.3.0...iam/v0.4.0) (2022-09-06)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** start generating apiv2 ([#6605](https://github.com/googleapis/google-cloud-go/issues/6605)) ([a6004e7](https://github.com/googleapis/google-cloud-go/commit/a6004e762f782869cd85688937475744f7b17e50))
|
|
||||||
|
|
||||||
## [0.3.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.2.0...iam/v0.3.0) (2022-02-23)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** set versionClient to module version ([55f0d92](https://github.com/googleapis/google-cloud-go/commit/55f0d92bf112f14b024b4ab0076c9875a17423c9))
|
|
||||||
|
|
||||||
## [0.2.0](https://github.com/googleapis/google-cloud-go/compare/iam/v0.1.1...iam/v0.2.0) (2022-02-14)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **iam:** add file for tracking version ([17b36ea](https://github.com/googleapis/google-cloud-go/commit/17b36ead42a96b1a01105122074e65164357519e))
|
|
||||||
|
|
||||||
### [0.1.1](https://www.github.com/googleapis/google-cloud-go/compare/iam/v0.1.0...iam/v0.1.1) (2022-01-14)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **iam:** run formatter ([#5277](https://www.github.com/googleapis/google-cloud-go/issues/5277)) ([8682e4e](https://www.github.com/googleapis/google-cloud-go/commit/8682e4ed57a4428a659fbc225f56c91767e2a4a9))
|
|
||||||
|
|
||||||
## v0.1.0
|
|
||||||
|
|
||||||
This is the first tag to carve out iam as its own module. See
|
|
||||||
[Add a module to a multi-module repository](https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository).
|
|
202
vendor/cloud.google.com/go/iam/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/iam/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
40
vendor/cloud.google.com/go/iam/README.md
generated
vendored
40
vendor/cloud.google.com/go/iam/README.md
generated
vendored
|
@ -1,40 +0,0 @@
|
||||||
# IAM API
|
|
||||||
|
|
||||||
[![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/iam.svg)](https://pkg.go.dev/cloud.google.com/go/iam)
|
|
||||||
|
|
||||||
Go Client Library for IAM API.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get cloud.google.com/go/iam
|
|
||||||
```
|
|
||||||
|
|
||||||
## Stability
|
|
||||||
|
|
||||||
The stability of this module is indicated by SemVer.
|
|
||||||
|
|
||||||
However, a `v1+` module may have breaking changes in two scenarios:
|
|
||||||
|
|
||||||
* Packages with `alpha` or `beta` in the import path
|
|
||||||
* The GoDoc has an explicit stability disclaimer (for example, for an experimental feature).
|
|
||||||
|
|
||||||
## Go Version Support
|
|
||||||
|
|
||||||
See the [Go Versions Supported](https://github.com/googleapis/google-cloud-go#go-versions-supported)
|
|
||||||
section in the root directory's README.
|
|
||||||
|
|
||||||
## Authorization
|
|
||||||
|
|
||||||
See the [Authorization](https://github.com/googleapis/google-cloud-go#authorization)
|
|
||||||
section in the root directory's README.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md)
|
|
||||||
document for details.
|
|
||||||
|
|
||||||
Please note that this project is released with a Contributor Code of Conduct.
|
|
||||||
By participating in this project you agree to abide by its terms. See
|
|
||||||
[Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct)
|
|
||||||
for more information.
|
|
672
vendor/cloud.google.com/go/iam/apiv1/iampb/iam_policy.pb.go
generated
vendored
672
vendor/cloud.google.com/go/iam/apiv1/iampb/iam_policy.pb.go
generated
vendored
|
@ -1,672 +0,0 @@
|
||||||
// Copyright 2022 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// protoc-gen-go v1.30.0
|
|
||||||
// protoc v4.23.2
|
|
||||||
// source: google/iam/v1/iam_policy.proto
|
|
||||||
|
|
||||||
package iampb
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
|
|
||||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Verify that this generated code is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
||||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Request message for `SetIamPolicy` method.
|
|
||||||
type SetIamPolicyRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
// REQUIRED: The resource for which the policy is being specified.
|
|
||||||
// See the operation documentation for the appropriate value for this field.
|
|
||||||
Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
|
|
||||||
// REQUIRED: The complete policy to be applied to the `resource`. The size of
|
|
||||||
// the policy is limited to a few 10s of KB. An empty policy is a
|
|
||||||
// valid policy but certain Cloud Platform services (such as Projects)
|
|
||||||
// might reject them.
|
|
||||||
Policy *Policy `protobuf:"bytes,2,opt,name=policy,proto3" json:"policy,omitempty"`
|
|
||||||
// OPTIONAL: A FieldMask specifying which fields of the policy to modify. Only
|
|
||||||
// the fields in the mask will be modified. If no mask is provided, the
|
|
||||||
// following default mask is used:
|
|
||||||
//
|
|
||||||
// `paths: "bindings, etag"`
|
|
||||||
UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,3,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetIamPolicyRequest) Reset() {
|
|
||||||
*x = SetIamPolicyRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[0]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetIamPolicyRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*SetIamPolicyRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *SetIamPolicyRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[0]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use SetIamPolicyRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*SetIamPolicyRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_google_iam_v1_iam_policy_proto_rawDescGZIP(), []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetIamPolicyRequest) GetResource() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Resource
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetIamPolicyRequest) GetPolicy() *Policy {
|
|
||||||
if x != nil {
|
|
||||||
return x.Policy
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetIamPolicyRequest) GetUpdateMask() *fieldmaskpb.FieldMask {
|
|
||||||
if x != nil {
|
|
||||||
return x.UpdateMask
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request message for `GetIamPolicy` method.
|
|
||||||
type GetIamPolicyRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
// REQUIRED: The resource for which the policy is being requested.
|
|
||||||
// See the operation documentation for the appropriate value for this field.
|
|
||||||
Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
|
|
||||||
// OPTIONAL: A `GetPolicyOptions` object for specifying options to
|
|
||||||
// `GetIamPolicy`.
|
|
||||||
Options *GetPolicyOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetIamPolicyRequest) Reset() {
|
|
||||||
*x = GetIamPolicyRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[1]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetIamPolicyRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*GetIamPolicyRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *GetIamPolicyRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[1]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use GetIamPolicyRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*GetIamPolicyRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_google_iam_v1_iam_policy_proto_rawDescGZIP(), []int{1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetIamPolicyRequest) GetResource() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Resource
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetIamPolicyRequest) GetOptions() *GetPolicyOptions {
|
|
||||||
if x != nil {
|
|
||||||
return x.Options
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request message for `TestIamPermissions` method.
|
|
||||||
type TestIamPermissionsRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
// REQUIRED: The resource for which the policy detail is being requested.
|
|
||||||
// See the operation documentation for the appropriate value for this field.
|
|
||||||
Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
|
|
||||||
// The set of permissions to check for the `resource`. Permissions with
|
|
||||||
// wildcards (such as '*' or 'storage.*') are not allowed. For more
|
|
||||||
// information see
|
|
||||||
// [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions).
|
|
||||||
Permissions []string `protobuf:"bytes,2,rep,name=permissions,proto3" json:"permissions,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsRequest) Reset() {
|
|
||||||
*x = TestIamPermissionsRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[2]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*TestIamPermissionsRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[2]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use TestIamPermissionsRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*TestIamPermissionsRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_google_iam_v1_iam_policy_proto_rawDescGZIP(), []int{2}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsRequest) GetResource() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Resource
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsRequest) GetPermissions() []string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Permissions
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response message for `TestIamPermissions` method.
|
|
||||||
type TestIamPermissionsResponse struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
// A subset of `TestPermissionsRequest.permissions` that the caller is
|
|
||||||
// allowed.
|
|
||||||
Permissions []string `protobuf:"bytes,1,rep,name=permissions,proto3" json:"permissions,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsResponse) Reset() {
|
|
||||||
*x = TestIamPermissionsResponse{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[3]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsResponse) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*TestIamPermissionsResponse) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsResponse) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[3]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use TestIamPermissionsResponse.ProtoReflect.Descriptor instead.
|
|
||||||
func (*TestIamPermissionsResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return file_google_iam_v1_iam_policy_proto_rawDescGZIP(), []int{3}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *TestIamPermissionsResponse) GetPermissions() []string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Permissions
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_google_iam_v1_iam_policy_proto protoreflect.FileDescriptor
|
|
||||||
|
|
||||||
var file_google_iam_v1_iam_policy_proto_rawDesc = []byte{
|
|
||||||
0x0a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f,
|
|
||||||
0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
|
||||||
0x12, 0x0d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x1a,
|
|
||||||
0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f,
|
|
||||||
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
|
|
||||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61,
|
|
||||||
0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f,
|
|
||||||
0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
|
|
||||||
0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
|
||||||
0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76,
|
|
||||||
0x31, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
|
|
||||||
0x1a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x70,
|
|
||||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f,
|
|
||||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65,
|
|
||||||
0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xad, 0x01,
|
|
||||||
0x0a, 0x13, 0x53, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65,
|
|
||||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
|
||||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x03, 0x0a,
|
|
||||||
0x01, 0x2a, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x06,
|
|
||||||
0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c,
|
|
||||||
0x69, 0x63, 0x79, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
|
|
||||||
0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18,
|
|
||||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73,
|
|
||||||
0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x77, 0x0a,
|
|
||||||
0x13, 0x47, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71,
|
|
||||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x03, 0x0a, 0x01,
|
|
||||||
0x2a, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x6f,
|
|
||||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
|
|
||||||
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f,
|
|
||||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x69, 0x0a, 0x19, 0x54, 0x65, 0x73, 0x74, 0x49, 0x61,
|
|
||||||
0x6d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75,
|
|
||||||
0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18,
|
|
||||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x03, 0x0a, 0x01, 0x2a,
|
|
||||||
0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x70, 0x65,
|
|
||||||
0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42,
|
|
||||||
0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
|
||||||
0x73, 0x22, 0x3e, 0x0a, 0x1a, 0x54, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72, 0x6d,
|
|
||||||
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
|
||||||
0x20, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01,
|
|
||||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
|
||||||
0x73, 0x32, 0xb4, 0x03, 0x0a, 0x09, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12,
|
|
||||||
0x74, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12,
|
|
||||||
0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e,
|
|
||||||
0x53, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75,
|
|
||||||
0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d,
|
|
||||||
0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93,
|
|
||||||
0x02, 0x23, 0x3a, 0x01, 0x2a, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f,
|
|
||||||
0x75, 0x72, 0x63, 0x65, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50,
|
|
||||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x74, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50,
|
|
||||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69,
|
|
||||||
0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69,
|
|
||||||
0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
|
||||||
0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79,
|
|
||||||
0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x3a, 0x01, 0x2a, 0x22, 0x1e, 0x2f, 0x76, 0x31,
|
|
||||||
0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x67,
|
|
||||||
0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x9a, 0x01, 0x0a, 0x12,
|
|
||||||
0x54, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
|
|
||||||
0x6e, 0x73, 0x12, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e,
|
|
||||||
0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73,
|
|
||||||
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73,
|
|
||||||
0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52,
|
|
||||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a,
|
|
||||||
0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
|
||||||
0x65, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72,
|
|
||||||
0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1e, 0xca, 0x41, 0x1b, 0x69, 0x61, 0x6d,
|
|
||||||
0x2d, 0x6d, 0x65, 0x74, 0x61, 0x2d, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
|
||||||
0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x42, 0x7f, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e,
|
|
||||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x0e, 0x49,
|
|
||||||
0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
|
||||||
0x29, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
|
|
||||||
0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x69,
|
|
||||||
0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xaa, 0x02, 0x13,
|
|
||||||
0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x49, 0x61, 0x6d,
|
|
||||||
0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f,
|
|
||||||
0x75, 0x64, 0x5c, 0x49, 0x61, 0x6d, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
|
||||||
0x33,
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
file_google_iam_v1_iam_policy_proto_rawDescOnce sync.Once
|
|
||||||
file_google_iam_v1_iam_policy_proto_rawDescData = file_google_iam_v1_iam_policy_proto_rawDesc
|
|
||||||
)
|
|
||||||
|
|
||||||
func file_google_iam_v1_iam_policy_proto_rawDescGZIP() []byte {
|
|
||||||
file_google_iam_v1_iam_policy_proto_rawDescOnce.Do(func() {
|
|
||||||
file_google_iam_v1_iam_policy_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_iam_v1_iam_policy_proto_rawDescData)
|
|
||||||
})
|
|
||||||
return file_google_iam_v1_iam_policy_proto_rawDescData
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_google_iam_v1_iam_policy_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
|
||||||
var file_google_iam_v1_iam_policy_proto_goTypes = []interface{}{
|
|
||||||
(*SetIamPolicyRequest)(nil), // 0: google.iam.v1.SetIamPolicyRequest
|
|
||||||
(*GetIamPolicyRequest)(nil), // 1: google.iam.v1.GetIamPolicyRequest
|
|
||||||
(*TestIamPermissionsRequest)(nil), // 2: google.iam.v1.TestIamPermissionsRequest
|
|
||||||
(*TestIamPermissionsResponse)(nil), // 3: google.iam.v1.TestIamPermissionsResponse
|
|
||||||
(*Policy)(nil), // 4: google.iam.v1.Policy
|
|
||||||
(*fieldmaskpb.FieldMask)(nil), // 5: google.protobuf.FieldMask
|
|
||||||
(*GetPolicyOptions)(nil), // 6: google.iam.v1.GetPolicyOptions
|
|
||||||
}
|
|
||||||
var file_google_iam_v1_iam_policy_proto_depIdxs = []int32{
|
|
||||||
4, // 0: google.iam.v1.SetIamPolicyRequest.policy:type_name -> google.iam.v1.Policy
|
|
||||||
5, // 1: google.iam.v1.SetIamPolicyRequest.update_mask:type_name -> google.protobuf.FieldMask
|
|
||||||
6, // 2: google.iam.v1.GetIamPolicyRequest.options:type_name -> google.iam.v1.GetPolicyOptions
|
|
||||||
0, // 3: google.iam.v1.IAMPolicy.SetIamPolicy:input_type -> google.iam.v1.SetIamPolicyRequest
|
|
||||||
1, // 4: google.iam.v1.IAMPolicy.GetIamPolicy:input_type -> google.iam.v1.GetIamPolicyRequest
|
|
||||||
2, // 5: google.iam.v1.IAMPolicy.TestIamPermissions:input_type -> google.iam.v1.TestIamPermissionsRequest
|
|
||||||
4, // 6: google.iam.v1.IAMPolicy.SetIamPolicy:output_type -> google.iam.v1.Policy
|
|
||||||
4, // 7: google.iam.v1.IAMPolicy.GetIamPolicy:output_type -> google.iam.v1.Policy
|
|
||||||
3, // 8: google.iam.v1.IAMPolicy.TestIamPermissions:output_type -> google.iam.v1.TestIamPermissionsResponse
|
|
||||||
6, // [6:9] is the sub-list for method output_type
|
|
||||||
3, // [3:6] is the sub-list for method input_type
|
|
||||||
3, // [3:3] is the sub-list for extension type_name
|
|
||||||
3, // [3:3] is the sub-list for extension extendee
|
|
||||||
0, // [0:3] is the sub-list for field type_name
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { file_google_iam_v1_iam_policy_proto_init() }
|
|
||||||
func file_google_iam_v1_iam_policy_proto_init() {
|
|
||||||
if File_google_iam_v1_iam_policy_proto != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
file_google_iam_v1_options_proto_init()
|
|
||||||
file_google_iam_v1_policy_proto_init()
|
|
||||||
if !protoimpl.UnsafeEnabled {
|
|
||||||
file_google_iam_v1_iam_policy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*SetIamPolicyRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_google_iam_v1_iam_policy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*GetIamPolicyRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_google_iam_v1_iam_policy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*TestIamPermissionsRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_google_iam_v1_iam_policy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*TestIamPermissionsResponse); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type x struct{}
|
|
||||||
out := protoimpl.TypeBuilder{
|
|
||||||
File: protoimpl.DescBuilder{
|
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
||||||
RawDescriptor: file_google_iam_v1_iam_policy_proto_rawDesc,
|
|
||||||
NumEnums: 0,
|
|
||||||
NumMessages: 4,
|
|
||||||
NumExtensions: 0,
|
|
||||||
NumServices: 1,
|
|
||||||
},
|
|
||||||
GoTypes: file_google_iam_v1_iam_policy_proto_goTypes,
|
|
||||||
DependencyIndexes: file_google_iam_v1_iam_policy_proto_depIdxs,
|
|
||||||
MessageInfos: file_google_iam_v1_iam_policy_proto_msgTypes,
|
|
||||||
}.Build()
|
|
||||||
File_google_iam_v1_iam_policy_proto = out.File
|
|
||||||
file_google_iam_v1_iam_policy_proto_rawDesc = nil
|
|
||||||
file_google_iam_v1_iam_policy_proto_goTypes = nil
|
|
||||||
file_google_iam_v1_iam_policy_proto_depIdxs = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
|
||||||
var _ context.Context
|
|
||||||
var _ grpc.ClientConnInterface
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
const _ = grpc.SupportPackageIsVersion6
|
|
||||||
|
|
||||||
// IAMPolicyClient is the client API for IAMPolicy service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
|
||||||
type IAMPolicyClient interface {
|
|
||||||
// Sets the access control policy on the specified resource. Replaces any
|
|
||||||
// existing policy.
|
|
||||||
//
|
|
||||||
// Can return `NOT_FOUND`, `INVALID_ARGUMENT`, and `PERMISSION_DENIED` errors.
|
|
||||||
SetIamPolicy(ctx context.Context, in *SetIamPolicyRequest, opts ...grpc.CallOption) (*Policy, error)
|
|
||||||
// Gets the access control policy for a resource.
|
|
||||||
// Returns an empty policy if the resource exists and does not have a policy
|
|
||||||
// set.
|
|
||||||
GetIamPolicy(ctx context.Context, in *GetIamPolicyRequest, opts ...grpc.CallOption) (*Policy, error)
|
|
||||||
// Returns permissions that a caller has on the specified resource.
|
|
||||||
// If the resource does not exist, this will return an empty set of
|
|
||||||
// permissions, not a `NOT_FOUND` error.
|
|
||||||
//
|
|
||||||
// Note: This operation is designed to be used for building permission-aware
|
|
||||||
// UIs and command-line tools, not for authorization checking. This operation
|
|
||||||
// may "fail open" without warning.
|
|
||||||
TestIamPermissions(ctx context.Context, in *TestIamPermissionsRequest, opts ...grpc.CallOption) (*TestIamPermissionsResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type iAMPolicyClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIAMPolicyClient(cc grpc.ClientConnInterface) IAMPolicyClient {
|
|
||||||
return &iAMPolicyClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iAMPolicyClient) SetIamPolicy(ctx context.Context, in *SetIamPolicyRequest, opts ...grpc.CallOption) (*Policy, error) {
|
|
||||||
out := new(Policy)
|
|
||||||
err := c.cc.Invoke(ctx, "/google.iam.v1.IAMPolicy/SetIamPolicy", in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iAMPolicyClient) GetIamPolicy(ctx context.Context, in *GetIamPolicyRequest, opts ...grpc.CallOption) (*Policy, error) {
|
|
||||||
out := new(Policy)
|
|
||||||
err := c.cc.Invoke(ctx, "/google.iam.v1.IAMPolicy/GetIamPolicy", in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iAMPolicyClient) TestIamPermissions(ctx context.Context, in *TestIamPermissionsRequest, opts ...grpc.CallOption) (*TestIamPermissionsResponse, error) {
|
|
||||||
out := new(TestIamPermissionsResponse)
|
|
||||||
err := c.cc.Invoke(ctx, "/google.iam.v1.IAMPolicy/TestIamPermissions", in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IAMPolicyServer is the server API for IAMPolicy service.
|
|
||||||
type IAMPolicyServer interface {
|
|
||||||
// Sets the access control policy on the specified resource. Replaces any
|
|
||||||
// existing policy.
|
|
||||||
//
|
|
||||||
// Can return `NOT_FOUND`, `INVALID_ARGUMENT`, and `PERMISSION_DENIED` errors.
|
|
||||||
SetIamPolicy(context.Context, *SetIamPolicyRequest) (*Policy, error)
|
|
||||||
// Gets the access control policy for a resource.
|
|
||||||
// Returns an empty policy if the resource exists and does not have a policy
|
|
||||||
// set.
|
|
||||||
GetIamPolicy(context.Context, *GetIamPolicyRequest) (*Policy, error)
|
|
||||||
// Returns permissions that a caller has on the specified resource.
|
|
||||||
// If the resource does not exist, this will return an empty set of
|
|
||||||
// permissions, not a `NOT_FOUND` error.
|
|
||||||
//
|
|
||||||
// Note: This operation is designed to be used for building permission-aware
|
|
||||||
// UIs and command-line tools, not for authorization checking. This operation
|
|
||||||
// may "fail open" without warning.
|
|
||||||
TestIamPermissions(context.Context, *TestIamPermissionsRequest) (*TestIamPermissionsResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedIAMPolicyServer can be embedded to have forward compatible implementations.
|
|
||||||
type UnimplementedIAMPolicyServer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*UnimplementedIAMPolicyServer) SetIamPolicy(context.Context, *SetIamPolicyRequest) (*Policy, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method SetIamPolicy not implemented")
|
|
||||||
}
|
|
||||||
func (*UnimplementedIAMPolicyServer) GetIamPolicy(context.Context, *GetIamPolicyRequest) (*Policy, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetIamPolicy not implemented")
|
|
||||||
}
|
|
||||||
func (*UnimplementedIAMPolicyServer) TestIamPermissions(context.Context, *TestIamPermissionsRequest) (*TestIamPermissionsResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method TestIamPermissions not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterIAMPolicyServer(s *grpc.Server, srv IAMPolicyServer) {
|
|
||||||
s.RegisterService(&_IAMPolicy_serviceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IAMPolicy_SetIamPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(SetIamPolicyRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(IAMPolicyServer).SetIamPolicy(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/google.iam.v1.IAMPolicy/SetIamPolicy",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(IAMPolicyServer).SetIamPolicy(ctx, req.(*SetIamPolicyRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IAMPolicy_GetIamPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetIamPolicyRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(IAMPolicyServer).GetIamPolicy(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/google.iam.v1.IAMPolicy/GetIamPolicy",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(IAMPolicyServer).GetIamPolicy(ctx, req.(*GetIamPolicyRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IAMPolicy_TestIamPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(TestIamPermissionsRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(IAMPolicyServer).TestIamPermissions(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/google.iam.v1.IAMPolicy/TestIamPermissions",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(IAMPolicyServer).TestIamPermissions(ctx, req.(*TestIamPermissionsRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _IAMPolicy_serviceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "google.iam.v1.IAMPolicy",
|
|
||||||
HandlerType: (*IAMPolicyServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "SetIamPolicy",
|
|
||||||
Handler: _IAMPolicy_SetIamPolicy_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetIamPolicy",
|
|
||||||
Handler: _IAMPolicy_GetIamPolicy_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "TestIamPermissions",
|
|
||||||
Handler: _IAMPolicy_TestIamPermissions_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "google/iam/v1/iam_policy.proto",
|
|
||||||
}
|
|
187
vendor/cloud.google.com/go/iam/apiv1/iampb/options.pb.go
generated
vendored
187
vendor/cloud.google.com/go/iam/apiv1/iampb/options.pb.go
generated
vendored
|
@ -1,187 +0,0 @@
|
||||||
// Copyright 2022 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// protoc-gen-go v1.30.0
|
|
||||||
// protoc v4.23.2
|
|
||||||
// source: google/iam/v1/options.proto
|
|
||||||
|
|
||||||
package iampb
|
|
||||||
|
|
||||||
import (
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Verify that this generated code is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
||||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Encapsulates settings provided to GetIamPolicy.
|
|
||||||
type GetPolicyOptions struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
// Optional. The maximum policy version that will be used to format the
|
|
||||||
// policy.
|
|
||||||
//
|
|
||||||
// Valid values are 0, 1, and 3. Requests specifying an invalid value will be
|
|
||||||
// rejected.
|
|
||||||
//
|
|
||||||
// Requests for policies with any conditional role bindings must specify
|
|
||||||
// version 3. Policies with no conditional role bindings may specify any valid
|
|
||||||
// value or leave the field unset.
|
|
||||||
//
|
|
||||||
// The policy in the response might use the policy version that you specified,
|
|
||||||
// or it might use a lower policy version. For example, if you specify version
|
|
||||||
// 3, but the policy has no conditional role bindings, the response uses
|
|
||||||
// version 1.
|
|
||||||
//
|
|
||||||
// To learn which resources support conditions in their IAM policies, see the
|
|
||||||
// [IAM
|
|
||||||
// documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
|
|
||||||
RequestedPolicyVersion int32 `protobuf:"varint,1,opt,name=requested_policy_version,json=requestedPolicyVersion,proto3" json:"requested_policy_version,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetPolicyOptions) Reset() {
|
|
||||||
*x = GetPolicyOptions{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_google_iam_v1_options_proto_msgTypes[0]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetPolicyOptions) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*GetPolicyOptions) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *GetPolicyOptions) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_google_iam_v1_options_proto_msgTypes[0]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use GetPolicyOptions.ProtoReflect.Descriptor instead.
|
|
||||||
func (*GetPolicyOptions) Descriptor() ([]byte, []int) {
|
|
||||||
return file_google_iam_v1_options_proto_rawDescGZIP(), []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetPolicyOptions) GetRequestedPolicyVersion() int32 {
|
|
||||||
if x != nil {
|
|
||||||
return x.RequestedPolicyVersion
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_google_iam_v1_options_proto protoreflect.FileDescriptor
|
|
||||||
|
|
||||||
var file_google_iam_v1_options_proto_rawDesc = []byte{
|
|
||||||
0x0a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f,
|
|
||||||
0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x22, 0x4c, 0x0a, 0x10,
|
|
||||||
0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
|
||||||
0x12, 0x38, 0x0a, 0x18, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x6f,
|
|
||||||
0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
|
|
||||||
0x28, 0x05, 0x52, 0x16, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c,
|
|
||||||
0x69, 0x63, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x7d, 0x0a, 0x11, 0x63, 0x6f,
|
|
||||||
0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x42,
|
|
||||||
0x0c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
|
||||||
0x29, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
|
|
||||||
0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x69,
|
|
||||||
0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xaa, 0x02, 0x13,
|
|
||||||
0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x49, 0x61, 0x6d,
|
|
||||||
0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f,
|
|
||||||
0x75, 0x64, 0x5c, 0x49, 0x61, 0x6d, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
|
||||||
0x33,
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
file_google_iam_v1_options_proto_rawDescOnce sync.Once
|
|
||||||
file_google_iam_v1_options_proto_rawDescData = file_google_iam_v1_options_proto_rawDesc
|
|
||||||
)
|
|
||||||
|
|
||||||
func file_google_iam_v1_options_proto_rawDescGZIP() []byte {
|
|
||||||
file_google_iam_v1_options_proto_rawDescOnce.Do(func() {
|
|
||||||
file_google_iam_v1_options_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_iam_v1_options_proto_rawDescData)
|
|
||||||
})
|
|
||||||
return file_google_iam_v1_options_proto_rawDescData
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_google_iam_v1_options_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
|
||||||
var file_google_iam_v1_options_proto_goTypes = []interface{}{
|
|
||||||
(*GetPolicyOptions)(nil), // 0: google.iam.v1.GetPolicyOptions
|
|
||||||
}
|
|
||||||
var file_google_iam_v1_options_proto_depIdxs = []int32{
|
|
||||||
0, // [0:0] is the sub-list for method output_type
|
|
||||||
0, // [0:0] is the sub-list for method input_type
|
|
||||||
0, // [0:0] is the sub-list for extension type_name
|
|
||||||
0, // [0:0] is the sub-list for extension extendee
|
|
||||||
0, // [0:0] is the sub-list for field type_name
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { file_google_iam_v1_options_proto_init() }
|
|
||||||
func file_google_iam_v1_options_proto_init() {
|
|
||||||
if File_google_iam_v1_options_proto != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !protoimpl.UnsafeEnabled {
|
|
||||||
file_google_iam_v1_options_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*GetPolicyOptions); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type x struct{}
|
|
||||||
out := protoimpl.TypeBuilder{
|
|
||||||
File: protoimpl.DescBuilder{
|
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
||||||
RawDescriptor: file_google_iam_v1_options_proto_rawDesc,
|
|
||||||
NumEnums: 0,
|
|
||||||
NumMessages: 1,
|
|
||||||
NumExtensions: 0,
|
|
||||||
NumServices: 0,
|
|
||||||
},
|
|
||||||
GoTypes: file_google_iam_v1_options_proto_goTypes,
|
|
||||||
DependencyIndexes: file_google_iam_v1_options_proto_depIdxs,
|
|
||||||
MessageInfos: file_google_iam_v1_options_proto_msgTypes,
|
|
||||||
}.Build()
|
|
||||||
File_google_iam_v1_options_proto = out.File
|
|
||||||
file_google_iam_v1_options_proto_rawDesc = nil
|
|
||||||
file_google_iam_v1_options_proto_goTypes = nil
|
|
||||||
file_google_iam_v1_options_proto_depIdxs = nil
|
|
||||||
}
|
|
1176
vendor/cloud.google.com/go/iam/apiv1/iampb/policy.pb.go
generated
vendored
1176
vendor/cloud.google.com/go/iam/apiv1/iampb/policy.pb.go
generated
vendored
File diff suppressed because it is too large
Load diff
387
vendor/cloud.google.com/go/iam/iam.go
generated
vendored
387
vendor/cloud.google.com/go/iam/iam.go
generated
vendored
|
@ -1,387 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package iam supports the resource-specific operations of Google Cloud
|
|
||||||
// IAM (Identity and Access Management) for the Google Cloud Libraries.
|
|
||||||
// See https://cloud.google.com/iam for more about IAM.
|
|
||||||
//
|
|
||||||
// Users of the Google Cloud Libraries will typically not use this package
|
|
||||||
// directly. Instead they will begin with some resource that supports IAM, like
|
|
||||||
// a pubsub topic, and call its IAM method to get a Handle for that resource.
|
|
||||||
package iam
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
pb "cloud.google.com/go/iam/apiv1/iampb"
|
|
||||||
gax "github.com/googleapis/gax-go/v2"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
)
|
|
||||||
|
|
||||||
// client abstracts the IAMPolicy API to allow multiple implementations.
|
|
||||||
type client interface {
|
|
||||||
Get(ctx context.Context, resource string) (*pb.Policy, error)
|
|
||||||
Set(ctx context.Context, resource string, p *pb.Policy) error
|
|
||||||
Test(ctx context.Context, resource string, perms []string) ([]string, error)
|
|
||||||
GetWithVersion(ctx context.Context, resource string, requestedPolicyVersion int32) (*pb.Policy, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// grpcClient implements client for the standard gRPC-based IAMPolicy service.
|
|
||||||
type grpcClient struct {
|
|
||||||
c pb.IAMPolicyClient
|
|
||||||
}
|
|
||||||
|
|
||||||
var withRetry = gax.WithRetry(func() gax.Retryer {
|
|
||||||
return gax.OnCodes([]codes.Code{
|
|
||||||
codes.DeadlineExceeded,
|
|
||||||
codes.Unavailable,
|
|
||||||
}, gax.Backoff{
|
|
||||||
Initial: 100 * time.Millisecond,
|
|
||||||
Max: 60 * time.Second,
|
|
||||||
Multiplier: 1.3,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
func (g *grpcClient) Get(ctx context.Context, resource string) (*pb.Policy, error) {
|
|
||||||
return g.GetWithVersion(ctx, resource, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *grpcClient) GetWithVersion(ctx context.Context, resource string, requestedPolicyVersion int32) (*pb.Policy, error) {
|
|
||||||
var proto *pb.Policy
|
|
||||||
md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource))
|
|
||||||
ctx = insertMetadata(ctx, md)
|
|
||||||
|
|
||||||
err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error {
|
|
||||||
var err error
|
|
||||||
proto, err = g.c.GetIamPolicy(ctx, &pb.GetIamPolicyRequest{
|
|
||||||
Resource: resource,
|
|
||||||
Options: &pb.GetPolicyOptions{
|
|
||||||
RequestedPolicyVersion: requestedPolicyVersion,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}, withRetry)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return proto, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *grpcClient) Set(ctx context.Context, resource string, p *pb.Policy) error {
|
|
||||||
md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource))
|
|
||||||
ctx = insertMetadata(ctx, md)
|
|
||||||
|
|
||||||
return gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error {
|
|
||||||
_, err := g.c.SetIamPolicy(ctx, &pb.SetIamPolicyRequest{
|
|
||||||
Resource: resource,
|
|
||||||
Policy: p,
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}, withRetry)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *grpcClient) Test(ctx context.Context, resource string, perms []string) ([]string, error) {
|
|
||||||
var res *pb.TestIamPermissionsResponse
|
|
||||||
md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource))
|
|
||||||
ctx = insertMetadata(ctx, md)
|
|
||||||
|
|
||||||
err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error {
|
|
||||||
var err error
|
|
||||||
res, err = g.c.TestIamPermissions(ctx, &pb.TestIamPermissionsRequest{
|
|
||||||
Resource: resource,
|
|
||||||
Permissions: perms,
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}, withRetry)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return res.Permissions, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Handle provides IAM operations for a resource.
|
|
||||||
type Handle struct {
|
|
||||||
c client
|
|
||||||
resource string
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Handle3 provides IAM operations for a resource. It is similar to a Handle, but provides access to newer IAM features (e.g., conditions).
|
|
||||||
type Handle3 struct {
|
|
||||||
c client
|
|
||||||
resource string
|
|
||||||
version int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// InternalNewHandle is for use by the Google Cloud Libraries only.
|
|
||||||
//
|
|
||||||
// InternalNewHandle returns a Handle for resource.
|
|
||||||
// The conn parameter refers to a server that must support the IAMPolicy service.
|
|
||||||
func InternalNewHandle(conn grpc.ClientConnInterface, resource string) *Handle {
|
|
||||||
return InternalNewHandleGRPCClient(pb.NewIAMPolicyClient(conn), resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InternalNewHandleGRPCClient is for use by the Google Cloud Libraries only.
|
|
||||||
//
|
|
||||||
// InternalNewHandleClient returns a Handle for resource using the given
|
|
||||||
// grpc service that implements IAM as a mixin
|
|
||||||
func InternalNewHandleGRPCClient(c pb.IAMPolicyClient, resource string) *Handle {
|
|
||||||
return InternalNewHandleClient(&grpcClient{c: c}, resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InternalNewHandleClient is for use by the Google Cloud Libraries only.
|
|
||||||
//
|
|
||||||
// InternalNewHandleClient returns a Handle for resource using the given
|
|
||||||
// client implementation.
|
|
||||||
func InternalNewHandleClient(c client, resource string) *Handle {
|
|
||||||
return &Handle{
|
|
||||||
c: c,
|
|
||||||
resource: resource,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// V3 returns a Handle3, which is like Handle except it sets
|
|
||||||
// requestedPolicyVersion to 3 when retrieving a policy and policy.version to 3
|
|
||||||
// when storing a policy.
|
|
||||||
func (h *Handle) V3() *Handle3 {
|
|
||||||
return &Handle3{
|
|
||||||
c: h.c,
|
|
||||||
resource: h.resource,
|
|
||||||
version: 3,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Policy retrieves the IAM policy for the resource.
|
|
||||||
func (h *Handle) Policy(ctx context.Context) (*Policy, error) {
|
|
||||||
proto, err := h.c.Get(ctx, h.resource)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Policy{InternalProto: proto}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPolicy replaces the resource's current policy with the supplied Policy.
|
|
||||||
//
|
|
||||||
// If policy was created from a prior call to Get, then the modification will
|
|
||||||
// only succeed if the policy has not changed since the Get.
|
|
||||||
func (h *Handle) SetPolicy(ctx context.Context, policy *Policy) error {
|
|
||||||
return h.c.Set(ctx, h.resource, policy.InternalProto)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPermissions returns the subset of permissions that the caller has on the resource.
|
|
||||||
func (h *Handle) TestPermissions(ctx context.Context, permissions []string) ([]string, error) {
|
|
||||||
return h.c.Test(ctx, h.resource, permissions)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A RoleName is a name representing a collection of permissions.
|
|
||||||
type RoleName string
|
|
||||||
|
|
||||||
// Common role names.
|
|
||||||
const (
|
|
||||||
Owner RoleName = "roles/owner"
|
|
||||||
Editor RoleName = "roles/editor"
|
|
||||||
Viewer RoleName = "roles/viewer"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// AllUsers is a special member that denotes all users, even unauthenticated ones.
|
|
||||||
AllUsers = "allUsers"
|
|
||||||
|
|
||||||
// AllAuthenticatedUsers is a special member that denotes all authenticated users.
|
|
||||||
AllAuthenticatedUsers = "allAuthenticatedUsers"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Policy is a list of Bindings representing roles
|
|
||||||
// granted to members.
|
|
||||||
//
|
|
||||||
// The zero Policy is a valid policy with no bindings.
|
|
||||||
type Policy struct {
|
|
||||||
// TODO(jba): when type aliases are available, put Policy into an internal package
|
|
||||||
// and provide an exported alias here.
|
|
||||||
|
|
||||||
// This field is exported for use by the Google Cloud Libraries only.
|
|
||||||
// It may become unexported in a future release.
|
|
||||||
InternalProto *pb.Policy
|
|
||||||
}
|
|
||||||
|
|
||||||
// Members returns the list of members with the supplied role.
|
|
||||||
// The return value should not be modified. Use Add and Remove
|
|
||||||
// to modify the members of a role.
|
|
||||||
func (p *Policy) Members(r RoleName) []string {
|
|
||||||
b := p.binding(r)
|
|
||||||
if b == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return b.Members
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasRole reports whether member has role r.
|
|
||||||
func (p *Policy) HasRole(member string, r RoleName) bool {
|
|
||||||
return memberIndex(member, p.binding(r)) >= 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds member member to role r if it is not already present.
|
|
||||||
// A new binding is created if there is no binding for the role.
|
|
||||||
func (p *Policy) Add(member string, r RoleName) {
|
|
||||||
b := p.binding(r)
|
|
||||||
if b == nil {
|
|
||||||
if p.InternalProto == nil {
|
|
||||||
p.InternalProto = &pb.Policy{}
|
|
||||||
}
|
|
||||||
p.InternalProto.Bindings = append(p.InternalProto.Bindings, &pb.Binding{
|
|
||||||
Role: string(r),
|
|
||||||
Members: []string{member},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if memberIndex(member, b) < 0 {
|
|
||||||
b.Members = append(b.Members, member)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove removes member from role r if it is present.
|
|
||||||
func (p *Policy) Remove(member string, r RoleName) {
|
|
||||||
bi := p.bindingIndex(r)
|
|
||||||
if bi < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bindings := p.InternalProto.Bindings
|
|
||||||
b := bindings[bi]
|
|
||||||
mi := memberIndex(member, b)
|
|
||||||
if mi < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Order doesn't matter for bindings or members, so to remove, move the last item
|
|
||||||
// into the removed spot and shrink the slice.
|
|
||||||
if len(b.Members) == 1 {
|
|
||||||
// Remove binding.
|
|
||||||
last := len(bindings) - 1
|
|
||||||
bindings[bi] = bindings[last]
|
|
||||||
bindings[last] = nil
|
|
||||||
p.InternalProto.Bindings = bindings[:last]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Remove member.
|
|
||||||
// TODO(jba): worry about multiple copies of m?
|
|
||||||
last := len(b.Members) - 1
|
|
||||||
b.Members[mi] = b.Members[last]
|
|
||||||
b.Members[last] = ""
|
|
||||||
b.Members = b.Members[:last]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Roles returns the names of all the roles that appear in the Policy.
|
|
||||||
func (p *Policy) Roles() []RoleName {
|
|
||||||
if p.InternalProto == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var rns []RoleName
|
|
||||||
for _, b := range p.InternalProto.Bindings {
|
|
||||||
rns = append(rns, RoleName(b.Role))
|
|
||||||
}
|
|
||||||
return rns
|
|
||||||
}
|
|
||||||
|
|
||||||
// binding returns the Binding for the suppied role, or nil if there isn't one.
|
|
||||||
func (p *Policy) binding(r RoleName) *pb.Binding {
|
|
||||||
i := p.bindingIndex(r)
|
|
||||||
if i < 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return p.InternalProto.Bindings[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Policy) bindingIndex(r RoleName) int {
|
|
||||||
if p.InternalProto == nil {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
for i, b := range p.InternalProto.Bindings {
|
|
||||||
if b.Role == string(r) {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// memberIndex returns the index of m in b's Members, or -1 if not found.
|
|
||||||
func memberIndex(m string, b *pb.Binding) int {
|
|
||||||
if b == nil {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
for i, mm := range b.Members {
|
|
||||||
if mm == m {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// insertMetadata inserts metadata into the given context
|
|
||||||
func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
|
|
||||||
out, _ := metadata.FromOutgoingContext(ctx)
|
|
||||||
out = out.Copy()
|
|
||||||
for _, md := range mds {
|
|
||||||
for k, v := range md {
|
|
||||||
out[k] = append(out[k], v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return metadata.NewOutgoingContext(ctx, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Policy3 is a list of Bindings representing roles granted to members.
|
|
||||||
//
|
|
||||||
// The zero Policy3 is a valid policy with no bindings.
|
|
||||||
//
|
|
||||||
// It is similar to a Policy, except a Policy3 provides direct access to the
|
|
||||||
// list of Bindings.
|
|
||||||
//
|
|
||||||
// The policy version is always set to 3.
|
|
||||||
type Policy3 struct {
|
|
||||||
etag []byte
|
|
||||||
Bindings []*pb.Binding
|
|
||||||
}
|
|
||||||
|
|
||||||
// Policy retrieves the IAM policy for the resource.
|
|
||||||
//
|
|
||||||
// requestedPolicyVersion is always set to 3.
|
|
||||||
func (h *Handle3) Policy(ctx context.Context) (*Policy3, error) {
|
|
||||||
proto, err := h.c.GetWithVersion(ctx, h.resource, h.version)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Policy3{
|
|
||||||
Bindings: proto.Bindings,
|
|
||||||
etag: proto.Etag,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPolicy replaces the resource's current policy with the supplied Policy.
|
|
||||||
//
|
|
||||||
// If policy was created from a prior call to Get, then the modification will
|
|
||||||
// only succeed if the policy has not changed since the Get.
|
|
||||||
func (h *Handle3) SetPolicy(ctx context.Context, policy *Policy3) error {
|
|
||||||
return h.c.Set(ctx, h.resource, &pb.Policy{
|
|
||||||
Bindings: policy.Bindings,
|
|
||||||
Etag: policy.etag,
|
|
||||||
Version: h.version,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPermissions returns the subset of permissions that the caller has on the resource.
|
|
||||||
func (h *Handle3) TestPermissions(ctx context.Context, permissions []string) ([]string, error) {
|
|
||||||
return h.c.Test(ctx, h.resource, permissions)
|
|
||||||
}
|
|
2402
vendor/cloud.google.com/go/internal/.repo-metadata-full.json
generated
vendored
2402
vendor/cloud.google.com/go/internal/.repo-metadata-full.json
generated
vendored
File diff suppressed because it is too large
Load diff
29
vendor/cloud.google.com/go/internal/README.md
generated
vendored
29
vendor/cloud.google.com/go/internal/README.md
generated
vendored
|
@ -1,29 +0,0 @@
|
||||||
# Internal
|
|
||||||
|
|
||||||
This directory contains internal code for cloud.google.com/go packages.
|
|
||||||
|
|
||||||
## .repo-metadata-full.json
|
|
||||||
|
|
||||||
`.repo-metadata-full.json` contains metadata about the packages in this repo. It
|
|
||||||
is generated by `internal/gapicgen/generator`. It's processed by external tools
|
|
||||||
to build lists of all of the packages.
|
|
||||||
|
|
||||||
Don't make breaking changes to the format without consulting with the external
|
|
||||||
tools.
|
|
||||||
|
|
||||||
One day, we may want to create individual `.repo-metadata.json` files next to
|
|
||||||
each package, which is the pattern followed by some other languages. External
|
|
||||||
tools would then talk to pkg.go.dev or some other service to get the overall
|
|
||||||
list of packages and use the `.repo-metadata.json` files to get the additional
|
|
||||||
metadata required. For now, `.repo-metadata-full.json` includes everything.
|
|
||||||
|
|
||||||
### Updating OwlBot SHA
|
|
||||||
|
|
||||||
You may want to manually update the which version of the post-processor will be
|
|
||||||
used -- to do this you need to update the SHA in the OwlBot lock file.
|
|
||||||
|
|
||||||
See the [postprocessor/README](postprocessor/README.md) for detailed
|
|
||||||
instructions.
|
|
||||||
|
|
||||||
*Note*: OwlBot will eventually open a pull request to update this value if it
|
|
||||||
discovers a new version of the container.
|
|
55
vendor/cloud.google.com/go/internal/annotate.go
generated
vendored
55
vendor/cloud.google.com/go/internal/annotate.go
generated
vendored
|
@ -1,55 +0,0 @@
|
||||||
// Copyright 2017 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Annotate prepends msg to the error message in err, attempting
|
|
||||||
// to preserve other information in err, like an error code.
|
|
||||||
//
|
|
||||||
// Annotate panics if err is nil.
|
|
||||||
//
|
|
||||||
// Annotate knows about these error types:
|
|
||||||
// - "google.golang.org/grpc/status".Status
|
|
||||||
// - "google.golang.org/api/googleapi".Error
|
|
||||||
// If the error is not one of these types, Annotate behaves
|
|
||||||
// like
|
|
||||||
//
|
|
||||||
// fmt.Errorf("%s: %v", msg, err)
|
|
||||||
func Annotate(err error, msg string) error {
|
|
||||||
if err == nil {
|
|
||||||
panic("Annotate called with nil")
|
|
||||||
}
|
|
||||||
if s, ok := status.FromError(err); ok {
|
|
||||||
p := s.Proto()
|
|
||||||
p.Message = msg + ": " + p.Message
|
|
||||||
return status.ErrorProto(p)
|
|
||||||
}
|
|
||||||
if g, ok := err.(*googleapi.Error); ok {
|
|
||||||
g.Message = msg + ": " + g.Message
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
return fmt.Errorf("%s: %v", msg, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Annotatef uses format and args to format a string, then calls Annotate.
|
|
||||||
func Annotatef(err error, format string, args ...interface{}) error {
|
|
||||||
return Annotate(err, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
108
vendor/cloud.google.com/go/internal/optional/optional.go
generated
vendored
108
vendor/cloud.google.com/go/internal/optional/optional.go
generated
vendored
|
@ -1,108 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package optional provides versions of primitive types that can
|
|
||||||
// be nil. These are useful in methods that update some of an API object's
|
|
||||||
// fields.
|
|
||||||
package optional
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
// Bool is either a bool or nil.
|
|
||||||
Bool interface{}
|
|
||||||
|
|
||||||
// String is either a string or nil.
|
|
||||||
String interface{}
|
|
||||||
|
|
||||||
// Int is either an int or nil.
|
|
||||||
Int interface{}
|
|
||||||
|
|
||||||
// Uint is either a uint or nil.
|
|
||||||
Uint interface{}
|
|
||||||
|
|
||||||
// Float64 is either a float64 or nil.
|
|
||||||
Float64 interface{}
|
|
||||||
|
|
||||||
// Duration is either a time.Duration or nil.
|
|
||||||
Duration interface{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// ToBool returns its argument as a bool.
|
|
||||||
// It panics if its argument is nil or not a bool.
|
|
||||||
func ToBool(v Bool) bool {
|
|
||||||
x, ok := v.(bool)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Bool", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToString returns its argument as a string.
|
|
||||||
// It panics if its argument is nil or not a string.
|
|
||||||
func ToString(v String) string {
|
|
||||||
x, ok := v.(string)
|
|
||||||
if !ok {
|
|
||||||
doPanic("String", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToInt returns its argument as an int.
|
|
||||||
// It panics if its argument is nil or not an int.
|
|
||||||
func ToInt(v Int) int {
|
|
||||||
x, ok := v.(int)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Int", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToUint returns its argument as a uint.
|
|
||||||
// It panics if its argument is nil or not a uint.
|
|
||||||
func ToUint(v Uint) uint {
|
|
||||||
x, ok := v.(uint)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Uint", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToFloat64 returns its argument as a float64.
|
|
||||||
// It panics if its argument is nil or not a float64.
|
|
||||||
func ToFloat64(v Float64) float64 {
|
|
||||||
x, ok := v.(float64)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Float64", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToDuration returns its argument as a time.Duration.
|
|
||||||
// It panics if its argument is nil or not a time.Duration.
|
|
||||||
func ToDuration(v Duration) time.Duration {
|
|
||||||
x, ok := v.(time.Duration)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Duration", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
func doPanic(capType string, v interface{}) {
|
|
||||||
panic(fmt.Sprintf("optional.%s value should be %s, got %T", capType, strings.ToLower(capType), v))
|
|
||||||
}
|
|
76
vendor/cloud.google.com/go/internal/retry.go
generated
vendored
76
vendor/cloud.google.com/go/internal/retry.go
generated
vendored
|
@ -1,76 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
gax "github.com/googleapis/gax-go/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Retry calls the supplied function f repeatedly according to the provided
|
|
||||||
// backoff parameters. It returns when one of the following occurs:
|
|
||||||
// When f's first return value is true, Retry immediately returns with f's second
|
|
||||||
// return value.
|
|
||||||
// When the provided context is done, Retry returns with an error that
|
|
||||||
// includes both ctx.Error() and the last error returned by f.
|
|
||||||
func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error)) error {
|
|
||||||
return retry(ctx, bo, f, gax.Sleep)
|
|
||||||
}
|
|
||||||
|
|
||||||
func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error),
|
|
||||||
sleep func(context.Context, time.Duration) error) error {
|
|
||||||
var lastErr error
|
|
||||||
for {
|
|
||||||
stop, err := f()
|
|
||||||
if stop {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Remember the last "real" error from f.
|
|
||||||
if err != nil && err != context.Canceled && err != context.DeadlineExceeded {
|
|
||||||
lastErr = err
|
|
||||||
}
|
|
||||||
p := bo.Pause()
|
|
||||||
if ctxErr := sleep(ctx, p); ctxErr != nil {
|
|
||||||
if lastErr != nil {
|
|
||||||
return wrappedCallErr{ctxErr: ctxErr, wrappedErr: lastErr}
|
|
||||||
}
|
|
||||||
return ctxErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use this error type to return an error which allows introspection of both
|
|
||||||
// the context error and the error from the service.
|
|
||||||
type wrappedCallErr struct {
|
|
||||||
ctxErr error
|
|
||||||
wrappedErr error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e wrappedCallErr) Error() string {
|
|
||||||
return fmt.Sprintf("retry failed with %v; last error: %v", e.ctxErr, e.wrappedErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e wrappedCallErr) Unwrap() error {
|
|
||||||
return e.wrappedErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is allows errors.Is to match the error from the call as well as context
|
|
||||||
// sentinel errors.
|
|
||||||
func (e wrappedCallErr) Is(err error) bool {
|
|
||||||
return e.ctxErr == err || e.wrappedErr == err
|
|
||||||
}
|
|
111
vendor/cloud.google.com/go/internal/trace/trace.go
generated
vendored
111
vendor/cloud.google.com/go/internal/trace/trace.go
generated
vendored
|
@ -1,111 +0,0 @@
|
||||||
// Copyright 2018 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package trace
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"go.opencensus.io/trace"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
"google.golang.org/genproto/googleapis/rpc/code"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StartSpan adds a span to the trace with the given name.
|
|
||||||
func StartSpan(ctx context.Context, name string) context.Context {
|
|
||||||
ctx, _ = trace.StartSpan(ctx, name)
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
// EndSpan ends a span with the given error.
|
|
||||||
func EndSpan(ctx context.Context, err error) {
|
|
||||||
span := trace.FromContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
span.SetStatus(toStatus(err))
|
|
||||||
}
|
|
||||||
span.End()
|
|
||||||
}
|
|
||||||
|
|
||||||
// toStatus interrogates an error and converts it to an appropriate
|
|
||||||
// OpenCensus status.
|
|
||||||
func toStatus(err error) trace.Status {
|
|
||||||
var err2 *googleapi.Error
|
|
||||||
if ok := xerrors.As(err, &err2); ok {
|
|
||||||
return trace.Status{Code: httpStatusCodeToOCCode(err2.Code), Message: err2.Message}
|
|
||||||
} else if s, ok := status.FromError(err); ok {
|
|
||||||
return trace.Status{Code: int32(s.Code()), Message: s.Message()}
|
|
||||||
} else {
|
|
||||||
return trace.Status{Code: int32(code.Code_UNKNOWN), Message: err.Error()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(deklerk): switch to using OpenCensus function when it becomes available.
|
|
||||||
// Reference: https://github.com/googleapis/googleapis/blob/26b634d2724ac5dd30ae0b0cbfb01f07f2e4050e/google/rpc/code.proto
|
|
||||||
func httpStatusCodeToOCCode(httpStatusCode int) int32 {
|
|
||||||
switch httpStatusCode {
|
|
||||||
case 200:
|
|
||||||
return int32(code.Code_OK)
|
|
||||||
case 499:
|
|
||||||
return int32(code.Code_CANCELLED)
|
|
||||||
case 500:
|
|
||||||
return int32(code.Code_UNKNOWN) // Could also be Code_INTERNAL, Code_DATA_LOSS
|
|
||||||
case 400:
|
|
||||||
return int32(code.Code_INVALID_ARGUMENT) // Could also be Code_OUT_OF_RANGE
|
|
||||||
case 504:
|
|
||||||
return int32(code.Code_DEADLINE_EXCEEDED)
|
|
||||||
case 404:
|
|
||||||
return int32(code.Code_NOT_FOUND)
|
|
||||||
case 409:
|
|
||||||
return int32(code.Code_ALREADY_EXISTS) // Could also be Code_ABORTED
|
|
||||||
case 403:
|
|
||||||
return int32(code.Code_PERMISSION_DENIED)
|
|
||||||
case 401:
|
|
||||||
return int32(code.Code_UNAUTHENTICATED)
|
|
||||||
case 429:
|
|
||||||
return int32(code.Code_RESOURCE_EXHAUSTED)
|
|
||||||
case 501:
|
|
||||||
return int32(code.Code_UNIMPLEMENTED)
|
|
||||||
case 503:
|
|
||||||
return int32(code.Code_UNAVAILABLE)
|
|
||||||
default:
|
|
||||||
return int32(code.Code_UNKNOWN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: (odeke-em): perhaps just pass around spans due to the cost
|
|
||||||
// incurred from using trace.FromContext(ctx) yet we could avoid
|
|
||||||
// throwing away the work done by ctx, span := trace.StartSpan.
|
|
||||||
func TracePrintf(ctx context.Context, attrMap map[string]interface{}, format string, args ...interface{}) {
|
|
||||||
var attrs []trace.Attribute
|
|
||||||
for k, v := range attrMap {
|
|
||||||
var a trace.Attribute
|
|
||||||
switch v := v.(type) {
|
|
||||||
case string:
|
|
||||||
a = trace.StringAttribute(k, v)
|
|
||||||
case bool:
|
|
||||||
a = trace.BoolAttribute(k, v)
|
|
||||||
case int:
|
|
||||||
a = trace.Int64Attribute(k, int64(v))
|
|
||||||
case int64:
|
|
||||||
a = trace.Int64Attribute(k, v)
|
|
||||||
default:
|
|
||||||
a = trace.StringAttribute(k, fmt.Sprintf("%#v", v))
|
|
||||||
}
|
|
||||||
attrs = append(attrs, a)
|
|
||||||
}
|
|
||||||
trace.FromContext(ctx).Annotatef(attrs, format, args...)
|
|
||||||
}
|
|
19
vendor/cloud.google.com/go/internal/version/update_version.sh
generated
vendored
19
vendor/cloud.google.com/go/internal/version/update_version.sh
generated
vendored
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Copyright 2019 Google LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
today=$(date +%Y%m%d)
|
|
||||||
|
|
||||||
sed -i -r -e 's/const Repo = "([0-9]{8})"/const Repo = "'$today'"/' $GOFILE
|
|
||||||
|
|
71
vendor/cloud.google.com/go/internal/version/version.go
generated
vendored
71
vendor/cloud.google.com/go/internal/version/version.go
generated
vendored
|
@ -1,71 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
//go:generate ./update_version.sh
|
|
||||||
|
|
||||||
// Package version contains version information for Google Cloud Client
|
|
||||||
// Libraries for Go, as reported in request headers.
|
|
||||||
package version
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Repo is the current version of the client libraries in this
|
|
||||||
// repo. It should be a date in YYYYMMDD format.
|
|
||||||
const Repo = "20201104"
|
|
||||||
|
|
||||||
// Go returns the Go runtime version. The returned string
|
|
||||||
// has no whitespace.
|
|
||||||
func Go() string {
|
|
||||||
return goVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
var goVersion = goVer(runtime.Version())
|
|
||||||
|
|
||||||
const develPrefix = "devel +"
|
|
||||||
|
|
||||||
func goVer(s string) string {
|
|
||||||
if strings.HasPrefix(s, develPrefix) {
|
|
||||||
s = s[len(develPrefix):]
|
|
||||||
if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
|
|
||||||
s = s[:p]
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(s, "go1") {
|
|
||||||
s = s[2:]
|
|
||||||
var prerelease string
|
|
||||||
if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
|
|
||||||
s, prerelease = s[:p], s[p:]
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(s, ".") {
|
|
||||||
s += "0"
|
|
||||||
} else if strings.Count(s, ".") < 2 {
|
|
||||||
s += ".0"
|
|
||||||
}
|
|
||||||
if prerelease != "" {
|
|
||||||
s += "-" + prerelease
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func notSemverRune(r rune) bool {
|
|
||||||
return !strings.ContainsRune("0123456789.", r)
|
|
||||||
}
|
|
366
vendor/cloud.google.com/go/storage/CHANGES.md
generated
vendored
366
vendor/cloud.google.com/go/storage/CHANGES.md
generated
vendored
|
@ -1,366 +0,0 @@
|
||||||
# Changes
|
|
||||||
|
|
||||||
|
|
||||||
## [1.30.1](https://github.com/googleapis/google-cloud-go/compare/storage/v1.30.0...storage/v1.30.1) (2023-03-21)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** Retract versions with Copier bug ([#7583](https://github.com/googleapis/google-cloud-go/issues/7583)) ([9c10b6f](https://github.com/googleapis/google-cloud-go/commit/9c10b6f8a54cb8447260148b5e4a9b5160281020))
|
|
||||||
* Versions v1.25.0-v1.27.0 are retracted due to [#6857](https://github.com/googleapis/google-cloud-go/issues/6857).
|
|
||||||
* **storage:** SignedURL v4 allows headers with colons in value ([#7603](https://github.com/googleapis/google-cloud-go/issues/7603)) ([6b50f9b](https://github.com/googleapis/google-cloud-go/commit/6b50f9b368f5b271ade1706c342865cef46712e6))
|
|
||||||
|
|
||||||
## [1.30.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.29.0...storage/v1.30.0) (2023-03-15)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage/internal:** Update routing annotation for CreateBucketRequest docs: Add support for end-to-end checksumming in the gRPC WriteObject flow feat!: BREAKING CHANGE - renaming Notification to NotificationConfig ([2fef56f](https://github.com/googleapis/google-cloud-go/commit/2fef56f75a63dc4ff6e0eea56c7b26d4831c8e27))
|
|
||||||
* **storage:** Json downloads ([#7158](https://github.com/googleapis/google-cloud-go/issues/7158)) ([574a86c](https://github.com/googleapis/google-cloud-go/commit/574a86c614445f8c3f5a54446820df774c31cd47))
|
|
||||||
* **storage:** Update iam and longrunning deps ([91a1f78](https://github.com/googleapis/google-cloud-go/commit/91a1f784a109da70f63b96414bba8a9b4254cddd))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** Specify credentials with STORAGE_EMULATOR_HOST ([#7271](https://github.com/googleapis/google-cloud-go/issues/7271)) ([940ae15](https://github.com/googleapis/google-cloud-go/commit/940ae15f725ff384e345e627feb03d22e1fd8db5))
|
|
||||||
|
|
||||||
## [1.29.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.28.1...storage/v1.29.0) (2023-01-19)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** Add ComponentCount as part of ObjectAttrs ([#7230](https://github.com/googleapis/google-cloud-go/issues/7230)) ([a19bca6](https://github.com/googleapis/google-cloud-go/commit/a19bca60704b4fbb674cf51d828580aa653c8210))
|
|
||||||
* **storage:** Add REST client ([06a54a1](https://github.com/googleapis/google-cloud-go/commit/06a54a16a5866cce966547c51e203b9e09a25bc0))
|
|
||||||
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
|
|
||||||
* **storage/internal:** Corrected typos and spellings ([7357077](https://github.com/googleapis/google-cloud-go/commit/735707796d81d7f6f32fc3415800c512fe62297e))
|
|
||||||
|
|
||||||
## [1.28.1](https://github.com/googleapis/google-cloud-go/compare/storage/v1.28.0...storage/v1.28.1) (2022-12-02)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** downgrade some dependencies ([7540152](https://github.com/googleapis/google-cloud-go/commit/754015236d5af7c82a75da218b71a87b9ead6eb5))
|
|
||||||
|
|
||||||
## [1.28.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.27.0...storage/v1.28.0) (2022-11-03)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage/internal:** Add routing annotations ([ce3f945](https://github.com/googleapis/google-cloud-go/commit/ce3f9458e511eca0910992763232abbcd64698f1))
|
|
||||||
* **storage:** Add Autoclass support ([#6828](https://github.com/googleapis/google-cloud-go/issues/6828)) ([f7c7f41](https://github.com/googleapis/google-cloud-go/commit/f7c7f41e4d7fcffe05860e1114cb20f40c869da8))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** Fix read-write race in Writer.Write ([#6817](https://github.com/googleapis/google-cloud-go/issues/6817)) ([4766d3e](https://github.com/googleapis/google-cloud-go/commit/4766d3e1004119b93c6bd352024b5bf3404252eb))
|
|
||||||
* **storage:** Fix request token passing for Copier.Run ([#6863](https://github.com/googleapis/google-cloud-go/issues/6863)) ([faaab06](https://github.com/googleapis/google-cloud-go/commit/faaab066d8e509dc440bcbc87391557ecee7dbf2)), refs [#6857](https://github.com/googleapis/google-cloud-go/issues/6857)
|
|
||||||
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
|
|
||||||
* **storage:** Update broken links for SignURL and PostPolicy ([#6779](https://github.com/googleapis/google-cloud-go/issues/6779)) ([776138b](https://github.com/googleapis/google-cloud-go/commit/776138bc06a1e5fd45acbf8f9d36e9dc6ce31dd3))
|
|
||||||
|
|
||||||
## [1.27.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.26.0...storage/v1.27.0) (2022-09-22)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** Find GoogleAccessID when using impersonated creds ([#6591](https://github.com/googleapis/google-cloud-go/issues/6591)) ([a2d16a7](https://github.com/googleapis/google-cloud-go/commit/a2d16a7a778c85d13217fc67955ec5dac1da34e8))
|
|
||||||
|
|
||||||
## [1.26.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.25.0...storage/v1.26.0) (2022-08-29)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** export ShouldRetry ([#6370](https://github.com/googleapis/google-cloud-go/issues/6370)) ([0da9ab0](https://github.com/googleapis/google-cloud-go/commit/0da9ab0831540569dc04c0a23437b084b1564e15)), refs [#6362](https://github.com/googleapis/google-cloud-go/issues/6362)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** allow to use age=0 in OLM conditions ([#6204](https://github.com/googleapis/google-cloud-go/issues/6204)) ([c85704f](https://github.com/googleapis/google-cloud-go/commit/c85704f4284626ce728cb48f3b130f2ce2a0165e))
|
|
||||||
|
|
||||||
## [1.25.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.24.0...storage/v1.25.0) (2022-08-11)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage/internal:** Add routing annotations ([8a8ba85](https://github.com/googleapis/google-cloud-go/commit/8a8ba85311f85701c97fd7c10f1d88b738ce423f))
|
|
||||||
* **storage:** refactor to use transport-agnostic interface ([#6465](https://github.com/googleapis/google-cloud-go/issues/6465)) ([d03c3e1](https://github.com/googleapis/google-cloud-go/commit/d03c3e15a79fe9afa1232d9c8bd4c484a9bb927e))
|
|
||||||
|
|
||||||
## [1.24.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.23.0...storage/v1.24.0) (2022-07-20)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** add Custom Placement Config Dual Region Support ([#6294](https://github.com/googleapis/google-cloud-go/issues/6294)) ([5a8c607](https://github.com/googleapis/google-cloud-go/commit/5a8c607e3a9a3265887e27cb13f8943f3e3fa23d))
|
|
||||||
|
|
||||||
## [1.23.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.22.1...storage/v1.23.0) (2022-06-23)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** add support for OLM Prefix/Suffix ([#5929](https://github.com/googleapis/google-cloud-go/issues/5929)) ([ec21d10](https://github.com/googleapis/google-cloud-go/commit/ec21d10d6d1b01aa97a52560319775041707690d))
|
|
||||||
* **storage:** support AbortIncompleteMultipartUpload LifecycleAction ([#5812](https://github.com/googleapis/google-cloud-go/issues/5812)) ([fdec929](https://github.com/googleapis/google-cloud-go/commit/fdec929b9da6e01dda0ab3c72544d44d6bd82bd4)), refs [#5795](https://github.com/googleapis/google-cloud-go/issues/5795)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** allow for Age *int64 type and int64 type ([#6230](https://github.com/googleapis/google-cloud-go/issues/6230)) ([cc7acb8](https://github.com/googleapis/google-cloud-go/commit/cc7acb8bffb31828e9e96d4834a65f9728494473))
|
|
||||||
|
|
||||||
### [1.22.1](https://github.com/googleapis/google-cloud-go/compare/storage/v1.22.0...storage/v1.22.1) (2022-05-19)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** bump genproto, remove deadcode ([#6059](https://github.com/googleapis/google-cloud-go/issues/6059)) ([bb10f9f](https://github.com/googleapis/google-cloud-go/commit/bb10f9faca57dc3b987e0fb601090887b3507f07))
|
|
||||||
* **storage:** remove field that no longer exists ([#6061](https://github.com/googleapis/google-cloud-go/issues/6061)) ([ee150cf](https://github.com/googleapis/google-cloud-go/commit/ee150cfd194463ddfcb59898cfb0237e47777973))
|
|
||||||
|
|
||||||
## [1.22.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.21.0...storage/v1.22.0) (2022-03-31)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** allow specifying includeTrailingDelimiter ([#5617](https://github.com/googleapis/google-cloud-go/issues/5617)) ([a34503b](https://github.com/googleapis/google-cloud-go/commit/a34503bc0f0b95399285e8db66976b227e3b0072))
|
|
||||||
* **storage:** set versionClient to module version ([55f0d92](https://github.com/googleapis/google-cloud-go/commit/55f0d92bf112f14b024b4ab0076c9875a17423c9))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** respect STORAGE_EMULATOR_HOST in signedURL ([#5673](https://github.com/googleapis/google-cloud-go/issues/5673)) ([1c249ae](https://github.com/googleapis/google-cloud-go/commit/1c249ae5b4980cf53fa74635943ca8bf6a96a341))
|
|
||||||
|
|
||||||
## [1.21.0](https://github.com/googleapis/google-cloud-go/compare/storage/v1.20.0...storage/v1.21.0) (2022-02-17)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** add better version metadata to calls ([#5507](https://github.com/googleapis/google-cloud-go/issues/5507)) ([13fe0bc](https://github.com/googleapis/google-cloud-go/commit/13fe0bc0d8acbffd46b59ab69b25449f1cbd6a88)), refs [#2749](https://github.com/googleapis/google-cloud-go/issues/2749)
|
|
||||||
* **storage:** add Writer.ChunkRetryDeadline ([#5482](https://github.com/googleapis/google-cloud-go/issues/5482)) ([498a746](https://github.com/googleapis/google-cloud-go/commit/498a746769fa43958b92af8875b927879947128e))
|
|
||||||
|
|
||||||
## [1.20.0](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.19.0...storage/v1.20.0) (2022-02-04)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage/internal:** Update definition of RewriteObjectRequest to bring to parity with JSON API support ([#5447](https://www.github.com/googleapis/google-cloud-go/issues/5447)) ([7d175ef](https://www.github.com/googleapis/google-cloud-go/commit/7d175ef12b7b3e75585427f5dd2aab4a175e92d6))
|
|
||||||
|
|
||||||
## [1.19.0](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.18.2...storage/v1.19.0) (2022-01-25)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** add fully configurable and idempotency-aware retry strategy ([#5384](https://www.github.com/googleapis/google-cloud-go/issues/5384), [#5185](https://www.github.com/googleapis/google-cloud-go/issues/5185), [#5170](https://www.github.com/googleapis/google-cloud-go/issues/5170), [#5223](https://www.github.com/googleapis/google-cloud-go/issues/5223), [#5221](https://www.github.com/googleapis/google-cloud-go/issues/5221), [#5193](https://www.github.com/googleapis/google-cloud-go/issues/5193), [#5159](https://www.github.com/googleapis/google-cloud-go/issues/5159), [#5165](https://www.github.com/googleapis/google-cloud-go/issues/5165), [#5166](https://www.github.com/googleapis/google-cloud-go/issues/5166), [#5210](https://www.github.com/googleapis/google-cloud-go/issues/5210), [#5172](https://www.github.com/googleapis/google-cloud-go/issues/5172), [#5314](https://www.github.com/googleapis/google-cloud-go/issues/5314))
|
|
||||||
* This release contains changes to fully align this library's retry strategy
|
|
||||||
with best practices as described in the
|
|
||||||
Cloud Storage [docs](https://cloud.google.com/storage/docs/retry-strategy).
|
|
||||||
* The library will now retry only idempotent operations by default. This means
|
|
||||||
that for certain operations, including object upload, compose, rewrite,
|
|
||||||
update, and delete, requests will not be retried by default unless
|
|
||||||
[idempotency conditions](https://cloud.google.com/storage/docs/retry-strategy#idempotency)
|
|
||||||
for the request have been met.
|
|
||||||
* The library now has methods to configure aspects of retry policy for
|
|
||||||
API calls, including which errors are retried, the timing of the
|
|
||||||
exponential backoff, and how idempotency is taken into account.
|
|
||||||
* If you wish to re-enable retries for a non-idempotent request, use the
|
|
||||||
[RetryAlways](https://pkg.go.dev/cloud.google.com/go/storage@main#RetryAlways)
|
|
||||||
policy.
|
|
||||||
* For full details on how to configure retries, see the
|
|
||||||
[package docs](https://pkg.go.dev/cloud.google.com/go/storage@main#hdr-Retrying_failed_requests)
|
|
||||||
and the
|
|
||||||
[Cloud Storage docs](https://cloud.google.com/storage/docs/retry-strategy)
|
|
||||||
* **storage:** GenerateSignedPostPolicyV4 can use existing creds to authenticate ([#5105](https://www.github.com/googleapis/google-cloud-go/issues/5105)) ([46489f4](https://www.github.com/googleapis/google-cloud-go/commit/46489f4c8a634068a3e7cf2fd5e5ca11b555c0a8))
|
|
||||||
* **storage:** post policy can be signed with a fn that takes raw bytes ([#5079](https://www.github.com/googleapis/google-cloud-go/issues/5079)) ([25d1278](https://www.github.com/googleapis/google-cloud-go/commit/25d1278cab539fbfdd8563ed6b297e30d3fe555c))
|
|
||||||
* **storage:** add rpo (turbo replication) support ([#5003](https://www.github.com/googleapis/google-cloud-go/issues/5003)) ([3bd5995](https://www.github.com/googleapis/google-cloud-go/commit/3bd59958e0c06d2655b67fcb5410668db3c52af0))
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** fix nil check in gRPC Reader ([#5376](https://www.github.com/googleapis/google-cloud-go/issues/5376)) ([5e7d722](https://www.github.com/googleapis/google-cloud-go/commit/5e7d722d18a62b28ba98169b3bdbb49401377264))
|
|
||||||
|
|
||||||
### [1.18.2](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.18.1...storage/v1.18.2) (2021-10-18)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** upgrade genproto ([#4993](https://www.github.com/googleapis/google-cloud-go/issues/4993)) ([5ca462d](https://www.github.com/googleapis/google-cloud-go/commit/5ca462d99fe851b7cddfd70108798e2fa959bdfd)), refs [#4991](https://www.github.com/googleapis/google-cloud-go/issues/4991)
|
|
||||||
|
|
||||||
### [1.18.1](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.18.0...storage/v1.18.1) (2021-10-14)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** don't assume auth from a client option ([#4982](https://www.github.com/googleapis/google-cloud-go/issues/4982)) ([e17334d](https://www.github.com/googleapis/google-cloud-go/commit/e17334d1fe7645d89d14ae7148313498b984dfbb))
|
|
||||||
|
|
||||||
## [1.18.0](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.17.0...storage/v1.18.0) (2021-10-11)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** returned wrapped error for timeouts ([#4802](https://www.github.com/googleapis/google-cloud-go/issues/4802)) ([0e102a3](https://www.github.com/googleapis/google-cloud-go/commit/0e102a385dc67a06f6b444b3a93e6998428529be)), refs [#4197](https://www.github.com/googleapis/google-cloud-go/issues/4197)
|
|
||||||
* **storage:** SignedUrl can use existing creds to authenticate ([#4604](https://www.github.com/googleapis/google-cloud-go/issues/4604)) ([b824c89](https://www.github.com/googleapis/google-cloud-go/commit/b824c897e6941270747b612f6d36a8d6ae081315))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** update PAP to use inherited instead of unspecified ([#4909](https://www.github.com/googleapis/google-cloud-go/issues/4909)) ([dac26b1](https://www.github.com/googleapis/google-cloud-go/commit/dac26b1af2f2972f12775341173bcc5f982438b8))
|
|
||||||
|
|
||||||
## [1.17.0](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.16.1...storage/v1.17.0) (2021-09-28)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** add projectNumber field to bucketAttrs. ([#4805](https://www.github.com/googleapis/google-cloud-go/issues/4805)) ([07343af](https://www.github.com/googleapis/google-cloud-go/commit/07343afc15085b164cc41d202d13f9d46f5c0d02))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** align retry idempotency (part 1) ([#4715](https://www.github.com/googleapis/google-cloud-go/issues/4715)) ([ffa903e](https://www.github.com/googleapis/google-cloud-go/commit/ffa903eeec61aa3869e5220e2f09371127b5c393))
|
|
||||||
|
|
||||||
### [1.16.1](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.16.0...storage/v1.16.1) (2021-08-30)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage/internal:** Update encryption_key fields to "bytes" type. fix: Improve date/times and field name clarity in lifecycle conditions. ([a52baa4](https://www.github.com/googleapis/google-cloud-go/commit/a52baa456ed8513ec492c4b573c191eb61468758))
|
|
||||||
* **storage:** accept emulator env var without scheme ([#4616](https://www.github.com/googleapis/google-cloud-go/issues/4616)) ([5f8cbb9](https://www.github.com/googleapis/google-cloud-go/commit/5f8cbb98070109e2a34409ac775ed63b94d37efd))
|
|
||||||
* **storage:** preserve supplied endpoint's scheme ([#4609](https://www.github.com/googleapis/google-cloud-go/issues/4609)) ([ee2756f](https://www.github.com/googleapis/google-cloud-go/commit/ee2756fb0a335d591464a770c9fa4f8fe0ba2e01))
|
|
||||||
* **storage:** remove unnecessary variable ([#4608](https://www.github.com/googleapis/google-cloud-go/issues/4608)) ([27fc784](https://www.github.com/googleapis/google-cloud-go/commit/27fc78456fb251652bdf5cdb493734a7e1e643e1))
|
|
||||||
* **storage:** retry LockRetentionPolicy ([#4439](https://www.github.com/googleapis/google-cloud-go/issues/4439)) ([09879ea](https://www.github.com/googleapis/google-cloud-go/commit/09879ea80cb67f9bfd8fc9384b0fda335567cba9)), refs [#4437](https://www.github.com/googleapis/google-cloud-go/issues/4437)
|
|
||||||
* **storage:** revise Reader to send XML preconditions ([#4479](https://www.github.com/googleapis/google-cloud-go/issues/4479)) ([e36b29a](https://www.github.com/googleapis/google-cloud-go/commit/e36b29a3d43bce5c1c044f7daf6e1db00b0a49e0)), refs [#4470](https://www.github.com/googleapis/google-cloud-go/issues/4470)
|
|
||||||
|
|
||||||
## [1.16.0](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.15.0...storage/v1.16.0) (2021-06-28)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** support PublicAccessPrevention ([#3608](https://www.github.com/googleapis/google-cloud-go/issues/3608)) ([99bc782](https://www.github.com/googleapis/google-cloud-go/commit/99bc782fb50a47602b45278384ef5d5b5da9263b)), refs [#3203](https://www.github.com/googleapis/google-cloud-go/issues/3203)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** fix Writer.ChunkSize validation ([#4255](https://www.github.com/googleapis/google-cloud-go/issues/4255)) ([69c2e9d](https://www.github.com/googleapis/google-cloud-go/commit/69c2e9dc6303e1a004d3104a8178532fa738e742)), refs [#4167](https://www.github.com/googleapis/google-cloud-go/issues/4167)
|
|
||||||
* **storage:** try to reopen for failed Reads ([#4226](https://www.github.com/googleapis/google-cloud-go/issues/4226)) ([564102b](https://www.github.com/googleapis/google-cloud-go/commit/564102b335dbfb558bec8af883e5f898efb5dd10)), refs [#3040](https://www.github.com/googleapis/google-cloud-go/issues/3040)
|
|
||||||
|
|
||||||
## [1.15.0](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.13.0...storage/v1.15.0) (2021-04-21)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **transport** Bump dependency on google.golang.org/api to pick up HTTP/2
|
|
||||||
config updates (see [googleapis/google-api-go-client#882](https://github.com/googleapis/google-api-go-client/pull/882)).
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** retry io.ErrUnexpectedEOF ([#3957](https://www.github.com/googleapis/google-cloud-go/issues/3957)) ([f6590cd](https://www.github.com/googleapis/google-cloud-go/commit/f6590cdc26c8479be5df48949fa59f879e0c24fc))
|
|
||||||
|
|
||||||
|
|
||||||
## v1.14.0
|
|
||||||
|
|
||||||
- Updates to various dependencies.
|
|
||||||
|
|
||||||
## [1.13.0](https://www.github.com/googleapis/google-cloud-go/compare/storage/v1.12.0...v1.13.0) (2021-02-03)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **storage:** add missing StorageClass in BucketAttrsToUpdate ([#3038](https://www.github.com/googleapis/google-cloud-go/issues/3038)) ([2fa1b72](https://www.github.com/googleapis/google-cloud-go/commit/2fa1b727f8a7b20aa62fe0990530744f6c109be0))
|
|
||||||
* **storage:** add projection parameter for BucketHandle.Objects() ([#3549](https://www.github.com/googleapis/google-cloud-go/issues/3549)) ([9b9c3dc](https://www.github.com/googleapis/google-cloud-go/commit/9b9c3dce3ee10af5b6c4d070821bf47a861efd5b))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **storage:** fix endpoint selection logic ([#3172](https://www.github.com/googleapis/google-cloud-go/issues/3172)) ([99edf0d](https://www.github.com/googleapis/google-cloud-go/commit/99edf0d211a9e617f2586fbc83b6f9630da3c537))
|
|
||||||
|
|
||||||
## v1.12.0
|
|
||||||
- V4 signed URL fixes:
|
|
||||||
- Fix encoding of spaces in query parameters.
|
|
||||||
- Add fields that were missing from PostPolicyV4 policy conditions.
|
|
||||||
- Fix Query to correctly list prefixes as well as objects when SetAttrSelection
|
|
||||||
is used.
|
|
||||||
|
|
||||||
## v1.11.0
|
|
||||||
- Add support for CustomTime and NoncurrentTime object lifecycle management
|
|
||||||
features.
|
|
||||||
|
|
||||||
## v1.10.0
|
|
||||||
- Bump dependency on google.golang.org/api to capture changes to retry logic
|
|
||||||
which will make retries on writes more resilient.
|
|
||||||
- Improve documentation for Writer.ChunkSize.
|
|
||||||
- Fix a bug in lifecycle to allow callers to clear lifecycle rules on a bucket.
|
|
||||||
|
|
||||||
## v1.9.0
|
|
||||||
- Add retry for transient network errors on most operations (with the exception
|
|
||||||
of writes).
|
|
||||||
- Bump dependency for google.golang.org/api to capture a change in the default
|
|
||||||
HTTP transport which will improve performance for reads under heavy load.
|
|
||||||
- Add CRC32C checksum validation option to Composer.
|
|
||||||
|
|
||||||
## v1.8.0
|
|
||||||
- Add support for V4 signed post policies.
|
|
||||||
|
|
||||||
## v1.7.0
|
|
||||||
- V4 signed URL support:
|
|
||||||
- Add support for bucket-bound domains and virtual hosted style URLs.
|
|
||||||
- Add support for query parameters in the signature.
|
|
||||||
- Fix text encoding to align with standards.
|
|
||||||
- Add the object name to query parameters for write calls.
|
|
||||||
- Fix retry behavior when reading files with Content-Encoding gzip.
|
|
||||||
- Fix response header in reader.
|
|
||||||
- New code examples:
|
|
||||||
- Error handling for `ObjectHandle` preconditions.
|
|
||||||
- Existence checks for buckets and objects.
|
|
||||||
|
|
||||||
## v1.6.0
|
|
||||||
|
|
||||||
- Updated option handling:
|
|
||||||
- Don't drop custom scopes (#1756)
|
|
||||||
- Don't drop port in provided endpoint (#1737)
|
|
||||||
|
|
||||||
## v1.5.0
|
|
||||||
|
|
||||||
- Honor WithEndpoint client option for reads as well as writes.
|
|
||||||
- Add archive storage class to docs.
|
|
||||||
- Make fixes to storage benchwrapper.
|
|
||||||
|
|
||||||
## v1.4.0
|
|
||||||
|
|
||||||
- When listing objects in a bucket, allow callers to specify which attributes
|
|
||||||
are queried. This allows for performance optimization.
|
|
||||||
|
|
||||||
## v1.3.0
|
|
||||||
|
|
||||||
- Use `storage.googleapis.com/storage/v1` by default for GCS requests
|
|
||||||
instead of `www.googleapis.com/storage/v1`.
|
|
||||||
|
|
||||||
## v1.2.1
|
|
||||||
|
|
||||||
- Fixed a bug where UniformBucketLevelAccess and BucketPolicyOnly were not
|
|
||||||
being sent in all cases.
|
|
||||||
|
|
||||||
## v1.2.0
|
|
||||||
|
|
||||||
- Add support for UniformBucketLevelAccess. This configures access checks
|
|
||||||
to use only bucket-level IAM policies.
|
|
||||||
See: https://godoc.org/cloud.google.com/go/storage#UniformBucketLevelAccess.
|
|
||||||
- Fix userAgent to use correct version.
|
|
||||||
|
|
||||||
## v1.1.2
|
|
||||||
|
|
||||||
- Fix memory leak in BucketIterator and ObjectIterator.
|
|
||||||
|
|
||||||
## v1.1.1
|
|
||||||
|
|
||||||
- Send BucketPolicyOnly even when it's disabled.
|
|
||||||
|
|
||||||
## v1.1.0
|
|
||||||
|
|
||||||
- Performance improvements for ObjectIterator and BucketIterator.
|
|
||||||
- Fix Bucket.ObjectIterator size calculation checks.
|
|
||||||
- Added HMACKeyOptions to all the methods which allows for options such as
|
|
||||||
UserProject to be set per invocation and optionally be used.
|
|
||||||
|
|
||||||
## v1.0.0
|
|
||||||
|
|
||||||
This is the first tag to carve out storage as its own module. See:
|
|
||||||
https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository.
|
|
202
vendor/cloud.google.com/go/storage/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/storage/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
32
vendor/cloud.google.com/go/storage/README.md
generated
vendored
32
vendor/cloud.google.com/go/storage/README.md
generated
vendored
|
@ -1,32 +0,0 @@
|
||||||
## Cloud Storage [![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/storage.svg)](https://pkg.go.dev/cloud.google.com/go/storage)
|
|
||||||
|
|
||||||
- [About Cloud Storage](https://cloud.google.com/storage/)
|
|
||||||
- [API documentation](https://cloud.google.com/storage/docs)
|
|
||||||
- [Go client documentation](https://cloud.google.com/go/docs/reference/cloud.google.com/go/storage/latest)
|
|
||||||
- [Complete sample programs](https://github.com/GoogleCloudPlatform/golang-samples/tree/main/storage)
|
|
||||||
|
|
||||||
### Example Usage
|
|
||||||
|
|
||||||
First create a `storage.Client` to use throughout your application:
|
|
||||||
|
|
||||||
[snip]:# (storage-1)
|
|
||||||
```go
|
|
||||||
client, err := storage.NewClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[snip]:# (storage-2)
|
|
||||||
```go
|
|
||||||
// Read the object1 from bucket.
|
|
||||||
rc, err := client.Bucket("bucket").Object("object1").NewReader(ctx)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer rc.Close()
|
|
||||||
body, err := io.ReadAll(rc)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
```
|
|
356
vendor/cloud.google.com/go/storage/acl.go
generated
vendored
356
vendor/cloud.google.com/go/storage/acl.go
generated
vendored
|
@ -1,356 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
storagepb "cloud.google.com/go/storage/internal/apiv2/stubs"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ACLRole is the level of access to grant.
|
|
||||||
type ACLRole string
|
|
||||||
|
|
||||||
const (
|
|
||||||
RoleOwner ACLRole = "OWNER"
|
|
||||||
RoleReader ACLRole = "READER"
|
|
||||||
RoleWriter ACLRole = "WRITER"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ACLEntity refers to a user or group.
|
|
||||||
// They are sometimes referred to as grantees.
|
|
||||||
//
|
|
||||||
// It could be in the form of:
|
|
||||||
// "user-<userId>", "user-<email>", "group-<groupId>", "group-<email>",
|
|
||||||
// "domain-<domain>" and "project-team-<projectId>".
|
|
||||||
//
|
|
||||||
// Or one of the predefined constants: AllUsers, AllAuthenticatedUsers.
|
|
||||||
type ACLEntity string
|
|
||||||
|
|
||||||
const (
|
|
||||||
AllUsers ACLEntity = "allUsers"
|
|
||||||
AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ACLRule represents a grant for a role to an entity (user, group or team) for a
|
|
||||||
// Google Cloud Storage object or bucket.
|
|
||||||
type ACLRule struct {
|
|
||||||
Entity ACLEntity
|
|
||||||
EntityID string
|
|
||||||
Role ACLRole
|
|
||||||
Domain string
|
|
||||||
Email string
|
|
||||||
ProjectTeam *ProjectTeam
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectTeam is the project team associated with the entity, if any.
|
|
||||||
type ProjectTeam struct {
|
|
||||||
ProjectNumber string
|
|
||||||
Team string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object.
|
|
||||||
// ACLHandle on an object operates on the latest generation of that object by default.
|
|
||||||
// Selecting a specific generation of an object is not currently supported by the client.
|
|
||||||
type ACLHandle struct {
|
|
||||||
c *Client
|
|
||||||
bucket string
|
|
||||||
object string
|
|
||||||
isDefault bool
|
|
||||||
userProject string // for requester-pays buckets
|
|
||||||
retry *retryConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete permanently deletes the ACL entry for the given entity.
|
|
||||||
func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) (err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Delete")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if a.object != "" {
|
|
||||||
return a.objectDelete(ctx, entity)
|
|
||||||
}
|
|
||||||
if a.isDefault {
|
|
||||||
return a.bucketDefaultDelete(ctx, entity)
|
|
||||||
}
|
|
||||||
return a.bucketDelete(ctx, entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets the role for the given entity.
|
|
||||||
func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) (err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Set")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if a.object != "" {
|
|
||||||
return a.objectSet(ctx, entity, role, false)
|
|
||||||
}
|
|
||||||
if a.isDefault {
|
|
||||||
return a.objectSet(ctx, entity, role, true)
|
|
||||||
}
|
|
||||||
return a.bucketSet(ctx, entity, role)
|
|
||||||
}
|
|
||||||
|
|
||||||
// List retrieves ACL entries.
|
|
||||||
func (a *ACLHandle) List(ctx context.Context) (rules []ACLRule, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.List")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if a.object != "" {
|
|
||||||
return a.objectList(ctx)
|
|
||||||
}
|
|
||||||
if a.isDefault {
|
|
||||||
return a.bucketDefaultList(ctx)
|
|
||||||
}
|
|
||||||
return a.bucketList(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) {
|
|
||||||
opts := makeStorageOpts(true, a.retry, a.userProject)
|
|
||||||
return a.c.tc.ListDefaultObjectACLs(ctx, a.bucket, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error {
|
|
||||||
opts := makeStorageOpts(false, a.retry, a.userProject)
|
|
||||||
return a.c.tc.DeleteDefaultObjectACL(ctx, a.bucket, entity, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) {
|
|
||||||
opts := makeStorageOpts(true, a.retry, a.userProject)
|
|
||||||
return a.c.tc.ListBucketACLs(ctx, a.bucket, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRole) error {
|
|
||||||
opts := makeStorageOpts(false, a.retry, a.userProject)
|
|
||||||
return a.c.tc.UpdateBucketACL(ctx, a.bucket, entity, role, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error {
|
|
||||||
opts := makeStorageOpts(false, a.retry, a.userProject)
|
|
||||||
return a.c.tc.DeleteBucketACL(ctx, a.bucket, entity, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) {
|
|
||||||
opts := makeStorageOpts(true, a.retry, a.userProject)
|
|
||||||
return a.c.tc.ListObjectACLs(ctx, a.bucket, a.object, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole, isBucketDefault bool) error {
|
|
||||||
opts := makeStorageOpts(false, a.retry, a.userProject)
|
|
||||||
if isBucketDefault {
|
|
||||||
return a.c.tc.UpdateDefaultObjectACL(ctx, a.bucket, entity, role, opts...)
|
|
||||||
}
|
|
||||||
return a.c.tc.UpdateObjectACL(ctx, a.bucket, a.object, entity, role, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error {
|
|
||||||
opts := makeStorageOpts(false, a.retry, a.userProject)
|
|
||||||
return a.c.tc.DeleteObjectACL(ctx, a.bucket, a.object, entity, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) configureCall(ctx context.Context, call interface{ Header() http.Header }) {
|
|
||||||
vc := reflect.ValueOf(call)
|
|
||||||
vc.MethodByName("Context").Call([]reflect.Value{reflect.ValueOf(ctx)})
|
|
||||||
if a.userProject != "" {
|
|
||||||
vc.MethodByName("UserProject").Call([]reflect.Value{reflect.ValueOf(a.userProject)})
|
|
||||||
}
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
}
|
|
||||||
|
|
||||||
func toObjectACLRules(items []*raw.ObjectAccessControl) []ACLRule {
|
|
||||||
var rs []ACLRule
|
|
||||||
for _, item := range items {
|
|
||||||
rs = append(rs, toObjectACLRule(item))
|
|
||||||
}
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
func toObjectACLRulesFromProto(items []*storagepb.ObjectAccessControl) []ACLRule {
|
|
||||||
var rs []ACLRule
|
|
||||||
for _, item := range items {
|
|
||||||
rs = append(rs, toObjectACLRuleFromProto(item))
|
|
||||||
}
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBucketACLRules(items []*raw.BucketAccessControl) []ACLRule {
|
|
||||||
var rs []ACLRule
|
|
||||||
for _, item := range items {
|
|
||||||
rs = append(rs, toBucketACLRule(item))
|
|
||||||
}
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBucketACLRulesFromProto(items []*storagepb.BucketAccessControl) []ACLRule {
|
|
||||||
var rs []ACLRule
|
|
||||||
for _, item := range items {
|
|
||||||
rs = append(rs, toBucketACLRuleFromProto(item))
|
|
||||||
}
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
func toObjectACLRule(a *raw.ObjectAccessControl) ACLRule {
|
|
||||||
return ACLRule{
|
|
||||||
Entity: ACLEntity(a.Entity),
|
|
||||||
EntityID: a.EntityId,
|
|
||||||
Role: ACLRole(a.Role),
|
|
||||||
Domain: a.Domain,
|
|
||||||
Email: a.Email,
|
|
||||||
ProjectTeam: toObjectProjectTeam(a.ProjectTeam),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toObjectACLRuleFromProto(a *storagepb.ObjectAccessControl) ACLRule {
|
|
||||||
return ACLRule{
|
|
||||||
Entity: ACLEntity(a.GetEntity()),
|
|
||||||
EntityID: a.GetEntityId(),
|
|
||||||
Role: ACLRole(a.GetRole()),
|
|
||||||
Domain: a.GetDomain(),
|
|
||||||
Email: a.GetEmail(),
|
|
||||||
ProjectTeam: toProjectTeamFromProto(a.GetProjectTeam()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBucketACLRule(a *raw.BucketAccessControl) ACLRule {
|
|
||||||
return ACLRule{
|
|
||||||
Entity: ACLEntity(a.Entity),
|
|
||||||
EntityID: a.EntityId,
|
|
||||||
Role: ACLRole(a.Role),
|
|
||||||
Domain: a.Domain,
|
|
||||||
Email: a.Email,
|
|
||||||
ProjectTeam: toBucketProjectTeam(a.ProjectTeam),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBucketACLRuleFromProto(a *storagepb.BucketAccessControl) ACLRule {
|
|
||||||
return ACLRule{
|
|
||||||
Entity: ACLEntity(a.GetEntity()),
|
|
||||||
EntityID: a.GetEntityId(),
|
|
||||||
Role: ACLRole(a.GetRole()),
|
|
||||||
Domain: a.GetDomain(),
|
|
||||||
Email: a.GetEmail(),
|
|
||||||
ProjectTeam: toProjectTeamFromProto(a.GetProjectTeam()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toRawObjectACL(rules []ACLRule) []*raw.ObjectAccessControl {
|
|
||||||
if len(rules) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
r := make([]*raw.ObjectAccessControl, 0, len(rules))
|
|
||||||
for _, rule := range rules {
|
|
||||||
r = append(r, rule.toRawObjectAccessControl("")) // bucket name unnecessary
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func toProtoObjectACL(rules []ACLRule) []*storagepb.ObjectAccessControl {
|
|
||||||
if len(rules) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
r := make([]*storagepb.ObjectAccessControl, 0, len(rules))
|
|
||||||
for _, rule := range rules {
|
|
||||||
r = append(r, rule.toProtoObjectAccessControl("")) // bucket name unnecessary
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func toRawBucketACL(rules []ACLRule) []*raw.BucketAccessControl {
|
|
||||||
if len(rules) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
r := make([]*raw.BucketAccessControl, 0, len(rules))
|
|
||||||
for _, rule := range rules {
|
|
||||||
r = append(r, rule.toRawBucketAccessControl("")) // bucket name unnecessary
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func toProtoBucketACL(rules []ACLRule) []*storagepb.BucketAccessControl {
|
|
||||||
if len(rules) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
r := make([]*storagepb.BucketAccessControl, 0, len(rules))
|
|
||||||
for _, rule := range rules {
|
|
||||||
r = append(r, rule.toProtoBucketAccessControl())
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ACLRule) toRawBucketAccessControl(bucket string) *raw.BucketAccessControl {
|
|
||||||
return &raw.BucketAccessControl{
|
|
||||||
Bucket: bucket,
|
|
||||||
Entity: string(r.Entity),
|
|
||||||
Role: string(r.Role),
|
|
||||||
// The other fields are not settable.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ACLRule) toRawObjectAccessControl(bucket string) *raw.ObjectAccessControl {
|
|
||||||
return &raw.ObjectAccessControl{
|
|
||||||
Bucket: bucket,
|
|
||||||
Entity: string(r.Entity),
|
|
||||||
Role: string(r.Role),
|
|
||||||
// The other fields are not settable.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ACLRule) toProtoObjectAccessControl(bucket string) *storagepb.ObjectAccessControl {
|
|
||||||
return &storagepb.ObjectAccessControl{
|
|
||||||
Entity: string(r.Entity),
|
|
||||||
Role: string(r.Role),
|
|
||||||
// The other fields are not settable.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ACLRule) toProtoBucketAccessControl() *storagepb.BucketAccessControl {
|
|
||||||
return &storagepb.BucketAccessControl{
|
|
||||||
Entity: string(r.Entity),
|
|
||||||
Role: string(r.Role),
|
|
||||||
// The other fields are not settable.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBucketProjectTeam(p *raw.BucketAccessControlProjectTeam) *ProjectTeam {
|
|
||||||
if p == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &ProjectTeam{
|
|
||||||
ProjectNumber: p.ProjectNumber,
|
|
||||||
Team: p.Team,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toProjectTeamFromProto(p *storagepb.ProjectTeam) *ProjectTeam {
|
|
||||||
if p == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &ProjectTeam{
|
|
||||||
ProjectNumber: p.GetProjectNumber(),
|
|
||||||
Team: p.GetTeam(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toObjectProjectTeam(p *raw.ObjectAccessControlProjectTeam) *ProjectTeam {
|
|
||||||
if p == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &ProjectTeam{
|
|
||||||
ProjectNumber: p.ProjectNumber,
|
|
||||||
Team: p.Team,
|
|
||||||
}
|
|
||||||
}
|
|
2165
vendor/cloud.google.com/go/storage/bucket.go
generated
vendored
2165
vendor/cloud.google.com/go/storage/bucket.go
generated
vendored
File diff suppressed because it is too large
Load diff
333
vendor/cloud.google.com/go/storage/client.go
generated
vendored
333
vendor/cloud.google.com/go/storage/client.go
generated
vendored
|
@ -1,333 +0,0 @@
|
||||||
// Copyright 2022 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"cloud.google.com/go/iam/apiv1/iampb"
|
|
||||||
gax "github.com/googleapis/gax-go/v2"
|
|
||||||
"google.golang.org/api/option"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(noahdietz): Move existing factory methods to this file.
|
|
||||||
|
|
||||||
// storageClient is an internal-only interface designed to separate the
|
|
||||||
// transport-specific logic of making Storage API calls from the logic of the
|
|
||||||
// client library.
|
|
||||||
//
|
|
||||||
// Implementation requirements beyond implementing the interface include:
|
|
||||||
// * factory method(s) must accept a `userProject string` param
|
|
||||||
// * `settings` must be retained per instance
|
|
||||||
// * `storageOption`s must be resolved in the order they are received
|
|
||||||
// * all API errors must be wrapped in the gax-go APIError type
|
|
||||||
// * any unimplemented interface methods must return a StorageUnimplementedErr
|
|
||||||
//
|
|
||||||
// TODO(noahdietz): This interface is currently not used in the production code
|
|
||||||
// paths
|
|
||||||
type storageClient interface {
|
|
||||||
|
|
||||||
// Top-level methods.
|
|
||||||
|
|
||||||
GetServiceAccount(ctx context.Context, project string, opts ...storageOption) (string, error)
|
|
||||||
CreateBucket(ctx context.Context, project, bucket string, attrs *BucketAttrs, opts ...storageOption) (*BucketAttrs, error)
|
|
||||||
ListBuckets(ctx context.Context, project string, opts ...storageOption) *BucketIterator
|
|
||||||
Close() error
|
|
||||||
|
|
||||||
// Bucket methods.
|
|
||||||
|
|
||||||
DeleteBucket(ctx context.Context, bucket string, conds *BucketConditions, opts ...storageOption) error
|
|
||||||
GetBucket(ctx context.Context, bucket string, conds *BucketConditions, opts ...storageOption) (*BucketAttrs, error)
|
|
||||||
UpdateBucket(ctx context.Context, bucket string, uattrs *BucketAttrsToUpdate, conds *BucketConditions, opts ...storageOption) (*BucketAttrs, error)
|
|
||||||
LockBucketRetentionPolicy(ctx context.Context, bucket string, conds *BucketConditions, opts ...storageOption) error
|
|
||||||
ListObjects(ctx context.Context, bucket string, q *Query, opts ...storageOption) *ObjectIterator
|
|
||||||
|
|
||||||
// Object metadata methods.
|
|
||||||
|
|
||||||
DeleteObject(ctx context.Context, bucket, object string, gen int64, conds *Conditions, opts ...storageOption) error
|
|
||||||
GetObject(ctx context.Context, bucket, object string, gen int64, encryptionKey []byte, conds *Conditions, opts ...storageOption) (*ObjectAttrs, error)
|
|
||||||
UpdateObject(ctx context.Context, bucket, object string, uattrs *ObjectAttrsToUpdate, gen int64, encryptionKey []byte, conds *Conditions, opts ...storageOption) (*ObjectAttrs, error)
|
|
||||||
|
|
||||||
// Default Object ACL methods.
|
|
||||||
|
|
||||||
DeleteDefaultObjectACL(ctx context.Context, bucket string, entity ACLEntity, opts ...storageOption) error
|
|
||||||
ListDefaultObjectACLs(ctx context.Context, bucket string, opts ...storageOption) ([]ACLRule, error)
|
|
||||||
UpdateDefaultObjectACL(ctx context.Context, bucket string, entity ACLEntity, role ACLRole, opts ...storageOption) error
|
|
||||||
|
|
||||||
// Bucket ACL methods.
|
|
||||||
|
|
||||||
DeleteBucketACL(ctx context.Context, bucket string, entity ACLEntity, opts ...storageOption) error
|
|
||||||
ListBucketACLs(ctx context.Context, bucket string, opts ...storageOption) ([]ACLRule, error)
|
|
||||||
UpdateBucketACL(ctx context.Context, bucket string, entity ACLEntity, role ACLRole, opts ...storageOption) error
|
|
||||||
|
|
||||||
// Object ACL methods.
|
|
||||||
|
|
||||||
DeleteObjectACL(ctx context.Context, bucket, object string, entity ACLEntity, opts ...storageOption) error
|
|
||||||
ListObjectACLs(ctx context.Context, bucket, object string, opts ...storageOption) ([]ACLRule, error)
|
|
||||||
UpdateObjectACL(ctx context.Context, bucket, object string, entity ACLEntity, role ACLRole, opts ...storageOption) error
|
|
||||||
|
|
||||||
// Media operations.
|
|
||||||
|
|
||||||
ComposeObject(ctx context.Context, req *composeObjectRequest, opts ...storageOption) (*ObjectAttrs, error)
|
|
||||||
RewriteObject(ctx context.Context, req *rewriteObjectRequest, opts ...storageOption) (*rewriteObjectResponse, error)
|
|
||||||
|
|
||||||
NewRangeReader(ctx context.Context, params *newRangeReaderParams, opts ...storageOption) (*Reader, error)
|
|
||||||
OpenWriter(params *openWriterParams, opts ...storageOption) (*io.PipeWriter, error)
|
|
||||||
|
|
||||||
// IAM methods.
|
|
||||||
|
|
||||||
GetIamPolicy(ctx context.Context, resource string, version int32, opts ...storageOption) (*iampb.Policy, error)
|
|
||||||
SetIamPolicy(ctx context.Context, resource string, policy *iampb.Policy, opts ...storageOption) error
|
|
||||||
TestIamPermissions(ctx context.Context, resource string, permissions []string, opts ...storageOption) ([]string, error)
|
|
||||||
|
|
||||||
// HMAC Key methods.
|
|
||||||
|
|
||||||
GetHMACKey(ctx context.Context, project, accessID string, opts ...storageOption) (*HMACKey, error)
|
|
||||||
ListHMACKeys(ctx context.Context, project, serviceAccountEmail string, showDeletedKeys bool, opts ...storageOption) *HMACKeysIterator
|
|
||||||
UpdateHMACKey(ctx context.Context, project, serviceAccountEmail, accessID string, attrs *HMACKeyAttrsToUpdate, opts ...storageOption) (*HMACKey, error)
|
|
||||||
CreateHMACKey(ctx context.Context, project, serviceAccountEmail string, opts ...storageOption) (*HMACKey, error)
|
|
||||||
DeleteHMACKey(ctx context.Context, project, accessID string, opts ...storageOption) error
|
|
||||||
|
|
||||||
// Notification methods.
|
|
||||||
ListNotifications(ctx context.Context, bucket string, opts ...storageOption) (map[string]*Notification, error)
|
|
||||||
CreateNotification(ctx context.Context, bucket string, n *Notification, opts ...storageOption) (*Notification, error)
|
|
||||||
DeleteNotification(ctx context.Context, bucket string, id string, opts ...storageOption) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// settings contains transport-agnostic configuration for API calls made via
|
|
||||||
// the storageClient inteface. All implementations must utilize settings
|
|
||||||
// and respect those that are applicable.
|
|
||||||
type settings struct {
|
|
||||||
// retry is the complete retry configuration to use when evaluating if an
|
|
||||||
// API call should be retried.
|
|
||||||
retry *retryConfig
|
|
||||||
|
|
||||||
// gax is a set of gax.CallOption to be conveyed to gax.Invoke.
|
|
||||||
// Note: Not all storageClient interfaces will must use gax.Invoke.
|
|
||||||
gax []gax.CallOption
|
|
||||||
|
|
||||||
// idempotent indicates if the call is idempotent or not when considering
|
|
||||||
// if the call should be retired or not.
|
|
||||||
idempotent bool
|
|
||||||
|
|
||||||
// clientOption is a set of option.ClientOption to be used during client
|
|
||||||
// transport initialization. See https://pkg.go.dev/google.golang.org/api/option
|
|
||||||
// for a list of supported options.
|
|
||||||
clientOption []option.ClientOption
|
|
||||||
|
|
||||||
// userProject is the user project that should be billed for the request.
|
|
||||||
userProject string
|
|
||||||
}
|
|
||||||
|
|
||||||
func initSettings(opts ...storageOption) *settings {
|
|
||||||
s := &settings{}
|
|
||||||
resolveOptions(s, opts...)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolveOptions(s *settings, opts ...storageOption) {
|
|
||||||
for _, o := range opts {
|
|
||||||
o.Apply(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// callSettings is a helper for resolving storage options against the settings
|
|
||||||
// in the context of an individual call. This is to ensure that client-level
|
|
||||||
// default settings are not mutated by two different calls getting options.
|
|
||||||
//
|
|
||||||
// Example: s := callSettings(c.settings, opts...)
|
|
||||||
func callSettings(defaults *settings, opts ...storageOption) *settings {
|
|
||||||
if defaults == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// This does not make a deep copy of the pointer/slice fields, but all
|
|
||||||
// options replace the settings fields rather than modify their values in
|
|
||||||
// place.
|
|
||||||
cs := *defaults
|
|
||||||
resolveOptions(&cs, opts...)
|
|
||||||
return &cs
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeStorageOpts is a helper for generating a set of storageOption based on
|
|
||||||
// idempotency, retryConfig, and userProject. All top-level client operations
|
|
||||||
// will generally have to pass these options through the interface.
|
|
||||||
func makeStorageOpts(isIdempotent bool, retry *retryConfig, userProject string) []storageOption {
|
|
||||||
opts := []storageOption{idempotent(isIdempotent)}
|
|
||||||
if retry != nil {
|
|
||||||
opts = append(opts, withRetryConfig(retry))
|
|
||||||
}
|
|
||||||
if userProject != "" {
|
|
||||||
opts = append(opts, withUserProject(userProject))
|
|
||||||
}
|
|
||||||
return opts
|
|
||||||
}
|
|
||||||
|
|
||||||
// storageOption is the transport-agnostic call option for the storageClient
|
|
||||||
// interface.
|
|
||||||
type storageOption interface {
|
|
||||||
Apply(s *settings)
|
|
||||||
}
|
|
||||||
|
|
||||||
func withGAXOptions(opts ...gax.CallOption) storageOption {
|
|
||||||
return &gaxOption{opts}
|
|
||||||
}
|
|
||||||
|
|
||||||
type gaxOption struct {
|
|
||||||
opts []gax.CallOption
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *gaxOption) Apply(s *settings) { s.gax = o.opts }
|
|
||||||
|
|
||||||
func withRetryConfig(rc *retryConfig) storageOption {
|
|
||||||
return &retryOption{rc}
|
|
||||||
}
|
|
||||||
|
|
||||||
type retryOption struct {
|
|
||||||
rc *retryConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *retryOption) Apply(s *settings) { s.retry = o.rc }
|
|
||||||
|
|
||||||
func idempotent(i bool) storageOption {
|
|
||||||
return &idempotentOption{i}
|
|
||||||
}
|
|
||||||
|
|
||||||
type idempotentOption struct {
|
|
||||||
idempotency bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *idempotentOption) Apply(s *settings) { s.idempotent = o.idempotency }
|
|
||||||
|
|
||||||
func withClientOptions(opts ...option.ClientOption) storageOption {
|
|
||||||
return &clientOption{opts: opts}
|
|
||||||
}
|
|
||||||
|
|
||||||
type clientOption struct {
|
|
||||||
opts []option.ClientOption
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *clientOption) Apply(s *settings) { s.clientOption = o.opts }
|
|
||||||
|
|
||||||
func withUserProject(project string) storageOption {
|
|
||||||
return &userProjectOption{project}
|
|
||||||
}
|
|
||||||
|
|
||||||
type userProjectOption struct {
|
|
||||||
project string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *userProjectOption) Apply(s *settings) { s.userProject = o.project }
|
|
||||||
|
|
||||||
type openWriterParams struct {
|
|
||||||
// Writer configuration
|
|
||||||
|
|
||||||
// ctx is the context used by the writer routine to make all network calls
|
|
||||||
// and to manage the writer routine - see `Writer.ctx`.
|
|
||||||
// Required.
|
|
||||||
ctx context.Context
|
|
||||||
// chunkSize - see `Writer.ChunkSize`.
|
|
||||||
// Optional.
|
|
||||||
chunkSize int
|
|
||||||
// chunkRetryDeadline - see `Writer.ChunkRetryDeadline`.
|
|
||||||
// Optional.
|
|
||||||
chunkRetryDeadline time.Duration
|
|
||||||
|
|
||||||
// Object/request properties
|
|
||||||
|
|
||||||
// bucket - see `Writer.o.bucket`.
|
|
||||||
// Required.
|
|
||||||
bucket string
|
|
||||||
// attrs - see `Writer.ObjectAttrs`.
|
|
||||||
// Required.
|
|
||||||
attrs *ObjectAttrs
|
|
||||||
// conds - see `Writer.o.conds`.
|
|
||||||
// Optional.
|
|
||||||
conds *Conditions
|
|
||||||
// encryptionKey - see `Writer.o.encryptionKey`
|
|
||||||
// Optional.
|
|
||||||
encryptionKey []byte
|
|
||||||
// sendCRC32C - see `Writer.SendCRC32C`.
|
|
||||||
// Optional.
|
|
||||||
sendCRC32C bool
|
|
||||||
|
|
||||||
// Writer callbacks
|
|
||||||
|
|
||||||
// donec - see `Writer.donec`.
|
|
||||||
// Required.
|
|
||||||
donec chan struct{}
|
|
||||||
// setError callback for reporting errors - see `Writer.error`.
|
|
||||||
// Required.
|
|
||||||
setError func(error)
|
|
||||||
// progress callback for reporting upload progress - see `Writer.progress`.
|
|
||||||
// Required.
|
|
||||||
progress func(int64)
|
|
||||||
// setObj callback for reporting the resulting object - see `Writer.obj`.
|
|
||||||
// Required.
|
|
||||||
setObj func(*ObjectAttrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
type newRangeReaderParams struct {
|
|
||||||
bucket string
|
|
||||||
conds *Conditions
|
|
||||||
encryptionKey []byte
|
|
||||||
gen int64
|
|
||||||
length int64
|
|
||||||
object string
|
|
||||||
offset int64
|
|
||||||
readCompressed bool // Use accept-encoding: gzip. Only works for HTTP currently.
|
|
||||||
}
|
|
||||||
|
|
||||||
type composeObjectRequest struct {
|
|
||||||
dstBucket string
|
|
||||||
dstObject destinationObject
|
|
||||||
srcs []sourceObject
|
|
||||||
predefinedACL string
|
|
||||||
sendCRC32C bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type sourceObject struct {
|
|
||||||
name string
|
|
||||||
bucket string
|
|
||||||
gen int64
|
|
||||||
conds *Conditions
|
|
||||||
encryptionKey []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type destinationObject struct {
|
|
||||||
name string
|
|
||||||
bucket string
|
|
||||||
conds *Conditions
|
|
||||||
attrs *ObjectAttrs // attrs to set on the destination object.
|
|
||||||
encryptionKey []byte
|
|
||||||
keyName string
|
|
||||||
}
|
|
||||||
|
|
||||||
type rewriteObjectRequest struct {
|
|
||||||
srcObject sourceObject
|
|
||||||
dstObject destinationObject
|
|
||||||
predefinedACL string
|
|
||||||
token string
|
|
||||||
maxBytesRewrittenPerCall int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type rewriteObjectResponse struct {
|
|
||||||
resource *ObjectAttrs
|
|
||||||
done bool
|
|
||||||
written int64
|
|
||||||
size int64
|
|
||||||
token string
|
|
||||||
}
|
|
233
vendor/cloud.google.com/go/storage/copy.go
generated
vendored
233
vendor/cloud.google.com/go/storage/copy.go
generated
vendored
|
@ -1,233 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CopierFrom creates a Copier that can copy src to dst.
|
|
||||||
// You can immediately call Run on the returned Copier, or
|
|
||||||
// you can configure it first.
|
|
||||||
//
|
|
||||||
// For Requester Pays buckets, the user project of dst is billed, unless it is empty,
|
|
||||||
// in which case the user project of src is billed.
|
|
||||||
func (dst *ObjectHandle) CopierFrom(src *ObjectHandle) *Copier {
|
|
||||||
return &Copier{dst: dst, src: src}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Copier copies a source object to a destination.
|
|
||||||
type Copier struct {
|
|
||||||
// ObjectAttrs are optional attributes to set on the destination object.
|
|
||||||
// Any attributes must be initialized before any calls on the Copier. Nil
|
|
||||||
// or zero-valued attributes are ignored.
|
|
||||||
ObjectAttrs
|
|
||||||
|
|
||||||
// RewriteToken can be set before calling Run to resume a copy
|
|
||||||
// operation. After Run returns a non-nil error, RewriteToken will
|
|
||||||
// have been updated to contain the value needed to resume the copy.
|
|
||||||
RewriteToken string
|
|
||||||
|
|
||||||
// ProgressFunc can be used to monitor the progress of a multi-RPC copy
|
|
||||||
// operation. If ProgressFunc is not nil and copying requires multiple
|
|
||||||
// calls to the underlying service (see
|
|
||||||
// https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite), then
|
|
||||||
// ProgressFunc will be invoked after each call with the number of bytes of
|
|
||||||
// content copied so far and the total size in bytes of the source object.
|
|
||||||
//
|
|
||||||
// ProgressFunc is intended to make upload progress available to the
|
|
||||||
// application. For example, the implementation of ProgressFunc may update
|
|
||||||
// a progress bar in the application's UI, or log the result of
|
|
||||||
// float64(copiedBytes)/float64(totalBytes).
|
|
||||||
//
|
|
||||||
// ProgressFunc should return quickly without blocking.
|
|
||||||
ProgressFunc func(copiedBytes, totalBytes uint64)
|
|
||||||
|
|
||||||
// The Cloud KMS key, in the form projects/P/locations/L/keyRings/R/cryptoKeys/K,
|
|
||||||
// that will be used to encrypt the object. Overrides the object's KMSKeyName, if
|
|
||||||
// any.
|
|
||||||
//
|
|
||||||
// Providing both a DestinationKMSKeyName and a customer-supplied encryption key
|
|
||||||
// (via ObjectHandle.Key) on the destination object will result in an error when
|
|
||||||
// Run is called.
|
|
||||||
DestinationKMSKeyName string
|
|
||||||
|
|
||||||
dst, src *ObjectHandle
|
|
||||||
|
|
||||||
// The maximum number of bytes that will be rewritten per rewrite request.
|
|
||||||
// Most callers shouldn't need to specify this parameter - it is primarily
|
|
||||||
// in place to support testing. If specified the value must be an integral
|
|
||||||
// multiple of 1 MiB (1048576). Also, this only applies to requests where
|
|
||||||
// the source and destination span locations and/or storage classes. Finally,
|
|
||||||
// this value must not change across rewrite calls else you'll get an error
|
|
||||||
// that the `rewriteToken` is invalid.
|
|
||||||
maxBytesRewrittenPerCall int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run performs the copy.
|
|
||||||
func (c *Copier) Run(ctx context.Context) (attrs *ObjectAttrs, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Copier.Run")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if err := c.src.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := c.dst.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if c.DestinationKMSKeyName != "" && c.dst.encryptionKey != nil {
|
|
||||||
return nil, errors.New("storage: cannot use DestinationKMSKeyName with a customer-supplied encryption key")
|
|
||||||
}
|
|
||||||
if c.dst.gen != defaultGen {
|
|
||||||
return nil, fmt.Errorf("storage: generation cannot be specified on copy destination, got %v", c.dst.gen)
|
|
||||||
}
|
|
||||||
// Convert destination attributes to raw form, omitting the bucket.
|
|
||||||
// If the bucket is included but name or content-type aren't, the service
|
|
||||||
// returns a 400 with "Required" as the only message. Omitting the bucket
|
|
||||||
// does not cause any problems.
|
|
||||||
req := &rewriteObjectRequest{
|
|
||||||
srcObject: sourceObject{
|
|
||||||
name: c.src.object,
|
|
||||||
bucket: c.src.bucket,
|
|
||||||
gen: c.src.gen,
|
|
||||||
conds: c.src.conds,
|
|
||||||
encryptionKey: c.src.encryptionKey,
|
|
||||||
},
|
|
||||||
dstObject: destinationObject{
|
|
||||||
name: c.dst.object,
|
|
||||||
bucket: c.dst.bucket,
|
|
||||||
conds: c.dst.conds,
|
|
||||||
attrs: &c.ObjectAttrs,
|
|
||||||
encryptionKey: c.dst.encryptionKey,
|
|
||||||
keyName: c.DestinationKMSKeyName,
|
|
||||||
},
|
|
||||||
predefinedACL: c.PredefinedACL,
|
|
||||||
token: c.RewriteToken,
|
|
||||||
maxBytesRewrittenPerCall: c.maxBytesRewrittenPerCall,
|
|
||||||
}
|
|
||||||
|
|
||||||
isIdempotent := c.dst.conds != nil && (c.dst.conds.GenerationMatch != 0 || c.dst.conds.DoesNotExist)
|
|
||||||
var userProject string
|
|
||||||
if c.dst.userProject != "" {
|
|
||||||
userProject = c.dst.userProject
|
|
||||||
} else if c.src.userProject != "" {
|
|
||||||
userProject = c.src.userProject
|
|
||||||
}
|
|
||||||
opts := makeStorageOpts(isIdempotent, c.dst.retry, userProject)
|
|
||||||
|
|
||||||
for {
|
|
||||||
res, err := c.dst.c.tc.RewriteObject(ctx, req, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.RewriteToken = res.token
|
|
||||||
req.token = res.token
|
|
||||||
if c.ProgressFunc != nil {
|
|
||||||
c.ProgressFunc(uint64(res.written), uint64(res.size))
|
|
||||||
}
|
|
||||||
if res.done { // Finished successfully.
|
|
||||||
return res.resource, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ComposerFrom creates a Composer that can compose srcs into dst.
|
|
||||||
// You can immediately call Run on the returned Composer, or you can
|
|
||||||
// configure it first.
|
|
||||||
//
|
|
||||||
// The encryption key for the destination object will be used to decrypt all
|
|
||||||
// source objects and encrypt the destination object. It is an error
|
|
||||||
// to specify an encryption key for any of the source objects.
|
|
||||||
func (dst *ObjectHandle) ComposerFrom(srcs ...*ObjectHandle) *Composer {
|
|
||||||
return &Composer{dst: dst, srcs: srcs}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Composer composes source objects into a destination object.
|
|
||||||
//
|
|
||||||
// For Requester Pays buckets, the user project of dst is billed.
|
|
||||||
type Composer struct {
|
|
||||||
// ObjectAttrs are optional attributes to set on the destination object.
|
|
||||||
// Any attributes must be initialized before any calls on the Composer. Nil
|
|
||||||
// or zero-valued attributes are ignored.
|
|
||||||
ObjectAttrs
|
|
||||||
|
|
||||||
// SendCRC specifies whether to transmit a CRC32C field. It should be set
|
|
||||||
// to true in addition to setting the Composer's CRC32C field, because zero
|
|
||||||
// is a valid CRC and normally a zero would not be transmitted.
|
|
||||||
// If a CRC32C is sent, and the data in the destination object does not match
|
|
||||||
// the checksum, the compose will be rejected.
|
|
||||||
SendCRC32C bool
|
|
||||||
|
|
||||||
dst *ObjectHandle
|
|
||||||
srcs []*ObjectHandle
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run performs the compose operation.
|
|
||||||
func (c *Composer) Run(ctx context.Context) (attrs *ObjectAttrs, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Composer.Run")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if err := c.dst.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if c.dst.gen != defaultGen {
|
|
||||||
return nil, fmt.Errorf("storage: generation cannot be specified on compose destination, got %v", c.dst.gen)
|
|
||||||
}
|
|
||||||
if len(c.srcs) == 0 {
|
|
||||||
return nil, errors.New("storage: at least one source object must be specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, src := range c.srcs {
|
|
||||||
if err := src.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if src.bucket != c.dst.bucket {
|
|
||||||
return nil, fmt.Errorf("storage: all source objects must be in bucket %q, found %q", c.dst.bucket, src.bucket)
|
|
||||||
}
|
|
||||||
if src.encryptionKey != nil {
|
|
||||||
return nil, fmt.Errorf("storage: compose source %s.%s must not have encryption key", src.bucket, src.object)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
req := &composeObjectRequest{
|
|
||||||
dstBucket: c.dst.bucket,
|
|
||||||
predefinedACL: c.PredefinedACL,
|
|
||||||
sendCRC32C: c.SendCRC32C,
|
|
||||||
}
|
|
||||||
req.dstObject = destinationObject{
|
|
||||||
name: c.dst.object,
|
|
||||||
bucket: c.dst.bucket,
|
|
||||||
conds: c.dst.conds,
|
|
||||||
attrs: &c.ObjectAttrs,
|
|
||||||
encryptionKey: c.dst.encryptionKey,
|
|
||||||
}
|
|
||||||
for _, src := range c.srcs {
|
|
||||||
s := sourceObject{
|
|
||||||
name: src.object,
|
|
||||||
bucket: src.bucket,
|
|
||||||
gen: src.gen,
|
|
||||||
conds: src.conds,
|
|
||||||
}
|
|
||||||
req.srcs = append(req.srcs, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
isIdempotent := c.dst.conds != nil && (c.dst.conds.GenerationMatch != 0 || c.dst.conds.DoesNotExist)
|
|
||||||
opts := makeStorageOpts(isIdempotent, c.dst.retry, c.dst.userProject)
|
|
||||||
return c.dst.c.tc.ComposeObject(ctx, req, opts...)
|
|
||||||
}
|
|
331
vendor/cloud.google.com/go/storage/doc.go
generated
vendored
331
vendor/cloud.google.com/go/storage/doc.go
generated
vendored
|
@ -1,331 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package storage provides an easy way to work with Google Cloud Storage.
|
|
||||||
Google Cloud Storage stores data in named objects, which are grouped into buckets.
|
|
||||||
|
|
||||||
More information about Google Cloud Storage is available at
|
|
||||||
https://cloud.google.com/storage/docs.
|
|
||||||
|
|
||||||
See https://pkg.go.dev/cloud.google.com/go for authentication, timeouts,
|
|
||||||
connection pooling and similar aspects of this package.
|
|
||||||
|
|
||||||
# Creating a Client
|
|
||||||
|
|
||||||
To start working with this package, create a [Client]:
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
client, err := storage.NewClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
The client will use your default application credentials. Clients should be
|
|
||||||
reused instead of created as needed. The methods of [Client] are safe for
|
|
||||||
concurrent use by multiple goroutines.
|
|
||||||
|
|
||||||
You may configure the client by passing in options from the [google.golang.org/api/option]
|
|
||||||
package. You may also use options defined in this package, such as [WithJSONReads].
|
|
||||||
|
|
||||||
If you only wish to access public data, you can create
|
|
||||||
an unauthenticated client with
|
|
||||||
|
|
||||||
client, err := storage.NewClient(ctx, option.WithoutAuthentication())
|
|
||||||
|
|
||||||
To use an emulator with this library, you can set the STORAGE_EMULATOR_HOST
|
|
||||||
environment variable to the address at which your emulator is running. This will
|
|
||||||
send requests to that address instead of to Cloud Storage. You can then create
|
|
||||||
and use a client as usual:
|
|
||||||
|
|
||||||
// Set STORAGE_EMULATOR_HOST environment variable.
|
|
||||||
err := os.Setenv("STORAGE_EMULATOR_HOST", "localhost:9000")
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create client as usual.
|
|
||||||
client, err := storage.NewClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
// This request is now directed to http://localhost:9000/storage/v1/b
|
|
||||||
// instead of https://storage.googleapis.com/storage/v1/b
|
|
||||||
if err := client.Bucket("my-bucket").Create(ctx, projectID, nil); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
Please note that there is no official emulator for Cloud Storage.
|
|
||||||
|
|
||||||
# Buckets
|
|
||||||
|
|
||||||
A Google Cloud Storage bucket is a collection of objects. To work with a
|
|
||||||
bucket, make a bucket handle:
|
|
||||||
|
|
||||||
bkt := client.Bucket(bucketName)
|
|
||||||
|
|
||||||
A handle is a reference to a bucket. You can have a handle even if the
|
|
||||||
bucket doesn't exist yet. To create a bucket in Google Cloud Storage,
|
|
||||||
call [BucketHandle.Create]:
|
|
||||||
|
|
||||||
if err := bkt.Create(ctx, projectID, nil); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
Note that although buckets are associated with projects, bucket names are
|
|
||||||
global across all projects.
|
|
||||||
|
|
||||||
Each bucket has associated metadata, represented in this package by
|
|
||||||
[BucketAttrs]. The third argument to [BucketHandle.Create] allows you to set
|
|
||||||
the initial [BucketAttrs] of a bucket. To retrieve a bucket's attributes, use
|
|
||||||
[BucketHandle.Attrs]:
|
|
||||||
|
|
||||||
attrs, err := bkt.Attrs(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Printf("bucket %s, created at %s, is located in %s with storage class %s\n",
|
|
||||||
attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass)
|
|
||||||
|
|
||||||
# Objects
|
|
||||||
|
|
||||||
An object holds arbitrary data as a sequence of bytes, like a file. You
|
|
||||||
refer to objects using a handle, just as with buckets, but unlike buckets
|
|
||||||
you don't explicitly create an object. Instead, the first time you write
|
|
||||||
to an object it will be created. You can use the standard Go [io.Reader]
|
|
||||||
and [io.Writer] interfaces to read and write object data:
|
|
||||||
|
|
||||||
obj := bkt.Object("data")
|
|
||||||
// Write something to obj.
|
|
||||||
// w implements io.Writer.
|
|
||||||
w := obj.NewWriter(ctx)
|
|
||||||
// Write some text to obj. This will either create the object or overwrite whatever is there already.
|
|
||||||
if _, err := fmt.Fprintf(w, "This object contains text.\n"); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
// Close, just like writing a file.
|
|
||||||
if err := w.Close(); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read it back.
|
|
||||||
r, err := obj.NewReader(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
defer r.Close()
|
|
||||||
if _, err := io.Copy(os.Stdout, r); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
// Prints "This object contains text."
|
|
||||||
|
|
||||||
Objects also have attributes, which you can fetch with [ObjectHandle.Attrs]:
|
|
||||||
|
|
||||||
objAttrs, err := obj.Attrs(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Printf("object %s has size %d and can be read using %s\n",
|
|
||||||
objAttrs.Name, objAttrs.Size, objAttrs.MediaLink)
|
|
||||||
|
|
||||||
# Listing objects
|
|
||||||
|
|
||||||
Listing objects in a bucket is done with the [BucketHandle.Objects] method:
|
|
||||||
|
|
||||||
query := &storage.Query{Prefix: ""}
|
|
||||||
|
|
||||||
var names []string
|
|
||||||
it := bkt.Objects(ctx, query)
|
|
||||||
for {
|
|
||||||
attrs, err := it.Next()
|
|
||||||
if err == iterator.Done {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
names = append(names, attrs.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
Objects are listed lexicographically by name. To filter objects
|
|
||||||
lexicographically, [Query.StartOffset] and/or [Query.EndOffset] can be used:
|
|
||||||
|
|
||||||
query := &storage.Query{
|
|
||||||
Prefix: "",
|
|
||||||
StartOffset: "bar/", // Only list objects lexicographically >= "bar/"
|
|
||||||
EndOffset: "foo/", // Only list objects lexicographically < "foo/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... as before
|
|
||||||
|
|
||||||
If only a subset of object attributes is needed when listing, specifying this
|
|
||||||
subset using [Query.SetAttrSelection] may speed up the listing process:
|
|
||||||
|
|
||||||
query := &storage.Query{Prefix: ""}
|
|
||||||
query.SetAttrSelection([]string{"Name"})
|
|
||||||
|
|
||||||
// ... as before
|
|
||||||
|
|
||||||
# ACLs
|
|
||||||
|
|
||||||
Both objects and buckets have ACLs (Access Control Lists). An ACL is a list of
|
|
||||||
ACLRules, each of which specifies the role of a user, group or project. ACLs
|
|
||||||
are suitable for fine-grained control, but you may prefer using IAM to control
|
|
||||||
access at the project level (see [Cloud Storage IAM docs].
|
|
||||||
|
|
||||||
To list the ACLs of a bucket or object, obtain an [ACLHandle] and call [ACLHandle.List]:
|
|
||||||
|
|
||||||
acls, err := obj.ACL().List(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
for _, rule := range acls {
|
|
||||||
fmt.Printf("%s has role %s\n", rule.Entity, rule.Role)
|
|
||||||
}
|
|
||||||
|
|
||||||
You can also set and delete ACLs.
|
|
||||||
|
|
||||||
# Conditions
|
|
||||||
|
|
||||||
Every object has a generation and a metageneration. The generation changes
|
|
||||||
whenever the content changes, and the metageneration changes whenever the
|
|
||||||
metadata changes. [Conditions] let you check these values before an operation;
|
|
||||||
the operation only executes if the conditions match. You can use conditions to
|
|
||||||
prevent race conditions in read-modify-write operations.
|
|
||||||
|
|
||||||
For example, say you've read an object's metadata into objAttrs. Now
|
|
||||||
you want to write to that object, but only if its contents haven't changed
|
|
||||||
since you read it. Here is how to express that:
|
|
||||||
|
|
||||||
w = obj.If(storage.Conditions{GenerationMatch: objAttrs.Generation}).NewWriter(ctx)
|
|
||||||
// Proceed with writing as above.
|
|
||||||
|
|
||||||
# Signed URLs
|
|
||||||
|
|
||||||
You can obtain a URL that lets anyone read or write an object for a limited time.
|
|
||||||
Signing a URL requires credentials authorized to sign a URL. To use the same
|
|
||||||
authentication that was used when instantiating the Storage client, use
|
|
||||||
[BucketHandle.SignedURL].
|
|
||||||
|
|
||||||
url, err := client.Bucket(bucketName).SignedURL(objectName, opts)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Println(url)
|
|
||||||
|
|
||||||
You can also sign a URL without creating a client. See the documentation of
|
|
||||||
[SignedURL] for details.
|
|
||||||
|
|
||||||
url, err := storage.SignedURL(bucketName, "shared-object", opts)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Println(url)
|
|
||||||
|
|
||||||
# Post Policy V4 Signed Request
|
|
||||||
|
|
||||||
A type of signed request that allows uploads through HTML forms directly to Cloud Storage with
|
|
||||||
temporary permission. Conditions can be applied to restrict how the HTML form is used and exercised
|
|
||||||
by a user.
|
|
||||||
|
|
||||||
For more information, please see the [XML POST Object docs] as well
|
|
||||||
as the documentation of [BucketHandle.GenerateSignedPostPolicyV4].
|
|
||||||
|
|
||||||
pv4, err := client.Bucket(bucketName).GenerateSignedPostPolicyV4(objectName, opts)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Printf("URL: %s\nFields; %v\n", pv4.URL, pv4.Fields)
|
|
||||||
|
|
||||||
# Credential requirements for signing
|
|
||||||
|
|
||||||
If the GoogleAccessID and PrivateKey option fields are not provided, they will
|
|
||||||
be automatically detected by [BucketHandle.SignedURL] and
|
|
||||||
[BucketHandle.GenerateSignedPostPolicyV4] if any of the following are true:
|
|
||||||
- you are authenticated to the Storage Client with a service account's
|
|
||||||
downloaded private key, either directly in code or by setting the
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS environment variable (see [Other Environments]),
|
|
||||||
- your application is running on Google Compute Engine (GCE), or
|
|
||||||
- you are logged into [gcloud using application default credentials]
|
|
||||||
with [impersonation enabled].
|
|
||||||
|
|
||||||
Detecting GoogleAccessID may not be possible if you are authenticated using a
|
|
||||||
token source or using [option.WithHTTPClient]. In this case, you can provide a
|
|
||||||
service account email for GoogleAccessID and the client will attempt to sign
|
|
||||||
the URL or Post Policy using that service account.
|
|
||||||
|
|
||||||
To generate the signature, you must have:
|
|
||||||
- iam.serviceAccounts.signBlob permissions on the GoogleAccessID service
|
|
||||||
account, and
|
|
||||||
- the [IAM Service Account Credentials API] enabled (unless authenticating
|
|
||||||
with a downloaded private key).
|
|
||||||
|
|
||||||
# Errors
|
|
||||||
|
|
||||||
Errors returned by this client are often of the type [googleapi.Error].
|
|
||||||
These errors can be introspected for more information by using [errors.As]
|
|
||||||
with the richer [googleapi.Error] type. For example:
|
|
||||||
|
|
||||||
var e *googleapi.Error
|
|
||||||
if ok := errors.As(err, &e); ok {
|
|
||||||
if e.Code == 409 { ... }
|
|
||||||
}
|
|
||||||
|
|
||||||
# Retrying failed requests
|
|
||||||
|
|
||||||
Methods in this package may retry calls that fail with transient errors.
|
|
||||||
Retrying continues indefinitely unless the controlling context is canceled, the
|
|
||||||
client is closed, or a non-transient error is received. To stop retries from
|
|
||||||
continuing, use context timeouts or cancellation.
|
|
||||||
|
|
||||||
The retry strategy in this library follows best practices for Cloud Storage. By
|
|
||||||
default, operations are retried only if they are idempotent, and exponential
|
|
||||||
backoff with jitter is employed. In addition, errors are only retried if they
|
|
||||||
are defined as transient by the service. See the [Cloud Storage retry docs]
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
Users can configure non-default retry behavior for a single library call (using
|
|
||||||
[BucketHandle.Retryer] and [ObjectHandle.Retryer]) or for all calls made by a
|
|
||||||
client (using [Client.SetRetry]). For example:
|
|
||||||
|
|
||||||
o := client.Bucket(bucket).Object(object).Retryer(
|
|
||||||
// Use WithBackoff to change the timing of the exponential backoff.
|
|
||||||
storage.WithBackoff(gax.Backoff{
|
|
||||||
Initial: 2 * time.Second,
|
|
||||||
}),
|
|
||||||
// Use WithPolicy to configure the idempotency policy. RetryAlways will
|
|
||||||
// retry the operation even if it is non-idempotent.
|
|
||||||
storage.WithPolicy(storage.RetryAlways),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Use a context timeout to set an overall deadline on the call, including all
|
|
||||||
// potential retries.
|
|
||||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// Delete an object using the specified strategy and timeout.
|
|
||||||
if err := o.Delete(ctx); err != nil {
|
|
||||||
// Handle err.
|
|
||||||
}
|
|
||||||
|
|
||||||
[Cloud Storage IAM docs]: https://cloud.google.com/storage/docs/access-control/iam
|
|
||||||
[XML POST Object docs]: https://cloud.google.com/storage/docs/xml-api/post-object
|
|
||||||
[Cloud Storage retry docs]: https://cloud.google.com/storage/docs/retry-strategy
|
|
||||||
[Other Environments]: https://cloud.google.com/storage/docs/authentication#libauth
|
|
||||||
[gcloud using application default credentials]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login
|
|
||||||
[impersonation enabled]: https://cloud.google.com/sdk/gcloud/reference#--impersonate-service-account
|
|
||||||
[IAM Service Account Credentials API]: https://console.developers.google.com/apis/api/iamcredentials.googleapis.com/overview
|
|
||||||
*/
|
|
||||||
package storage // import "cloud.google.com/go/storage"
|
|
92
vendor/cloud.google.com/go/storage/emulator_test.sh
generated
vendored
92
vendor/cloud.google.com/go/storage/emulator_test.sh
generated
vendored
|
@ -1,92 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Copyright 2021 Google LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License..
|
|
||||||
|
|
||||||
# Fail on any error
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
# Display commands being run
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# Only run on Go 1.17+
|
|
||||||
min_minor_ver=17
|
|
||||||
|
|
||||||
v=`go version | { read _ _ v _; echo ${v#go}; }`
|
|
||||||
comps=(${v//./ })
|
|
||||||
minor_ver=${comps[1]}
|
|
||||||
|
|
||||||
if [ "$minor_ver" -lt "$min_minor_ver" ]; then
|
|
||||||
echo minor version $minor_ver, skipping
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
export STORAGE_EMULATOR_HOST="http://localhost:9000"
|
|
||||||
export STORAGE_EMULATOR_HOST_GRPC="localhost:8888"
|
|
||||||
|
|
||||||
DEFAULT_IMAGE_NAME='gcr.io/cloud-devrel-public-resources/storage-testbench'
|
|
||||||
DEFAULT_IMAGE_TAG='latest'
|
|
||||||
DOCKER_IMAGE=${DEFAULT_IMAGE_NAME}:${DEFAULT_IMAGE_TAG}
|
|
||||||
CONTAINER_NAME=storage_testbench
|
|
||||||
|
|
||||||
# Note: --net=host makes the container bind directly to the Docker host’s network,
|
|
||||||
# with no network isolation. If we were to use port-mapping instead, reset connection errors
|
|
||||||
# would be captured differently and cause unexpected test behaviour.
|
|
||||||
# The host networking driver works only on Linux hosts.
|
|
||||||
# See more about using host networking: https://docs.docker.com/network/host/
|
|
||||||
DOCKER_NETWORK="--net=host"
|
|
||||||
# Note: We do not expect the RetryConformanceTest suite to pass on darwin due to
|
|
||||||
# differences in the network errors emitted by the system.
|
|
||||||
if [ `go env GOOS` == 'darwin' ]; then
|
|
||||||
DOCKER_NETWORK="-p 9000:9000 -p 8888:8888"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the docker image for the testbench
|
|
||||||
docker pull $DOCKER_IMAGE
|
|
||||||
|
|
||||||
# Start the testbench
|
|
||||||
|
|
||||||
docker run --name $CONTAINER_NAME --rm -d $DOCKER_NETWORK $DOCKER_IMAGE
|
|
||||||
echo "Running the Cloud Storage testbench: $STORAGE_EMULATOR_HOST"
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# Stop the testbench & cleanup environment variables
|
|
||||||
function cleanup() {
|
|
||||||
echo "Cleanup testbench"
|
|
||||||
docker stop $CONTAINER_NAME
|
|
||||||
unset STORAGE_EMULATOR_HOST;
|
|
||||||
unset STORAGE_EMULATOR_HOST_GRPC;
|
|
||||||
}
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Check that the server is running - retry several times to allow for start-up time
|
|
||||||
response=$(curl -w "%{http_code}\n" $STORAGE_EMULATOR_HOST --retry-connrefused --retry 5 -o /dev/null)
|
|
||||||
|
|
||||||
if [[ $response != 200 ]]
|
|
||||||
then
|
|
||||||
echo "Testbench server did not start correctly"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Start the gRPC server on port 8888.
|
|
||||||
echo "Starting the gRPC server on port 8888"
|
|
||||||
response=$(curl -w "%{http_code}\n" --retry 5 --retry-max-time 40 -o /dev/null "$STORAGE_EMULATOR_HOST/start_grpc?port=8888")
|
|
||||||
|
|
||||||
if [[ $response != 200 ]]
|
|
||||||
then
|
|
||||||
echo "Testbench gRPC server did not start correctly"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Run tests
|
|
||||||
go test -v -timeout 10m ./ -run="^Test(RetryConformance|.*Emulated)$" -short 2>&1 | tee -a sponge_log.log
|
|
1749
vendor/cloud.google.com/go/storage/grpc_client.go
generated
vendored
1749
vendor/cloud.google.com/go/storage/grpc_client.go
generated
vendored
File diff suppressed because it is too large
Load diff
392
vendor/cloud.google.com/go/storage/hmac.go
generated
vendored
392
vendor/cloud.google.com/go/storage/hmac.go
generated
vendored
|
@ -1,392 +0,0 @@
|
||||||
// Copyright 2019 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
storagepb "cloud.google.com/go/storage/internal/apiv2/stubs"
|
|
||||||
"google.golang.org/api/iterator"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HMACState is the state of the HMAC key.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACState string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Active is the status for an active key that can be used to sign
|
|
||||||
// requests.
|
|
||||||
Active HMACState = "ACTIVE"
|
|
||||||
|
|
||||||
// Inactive is the status for an inactive key thus requests signed by
|
|
||||||
// this key will be denied.
|
|
||||||
Inactive HMACState = "INACTIVE"
|
|
||||||
|
|
||||||
// Deleted is the status for a key that is deleted.
|
|
||||||
// Once in this state the key cannot key cannot be recovered
|
|
||||||
// and does not count towards key limits. Deleted keys will be cleaned
|
|
||||||
// up later.
|
|
||||||
Deleted HMACState = "DELETED"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HMACKey is the representation of a Google Cloud Storage HMAC key.
|
|
||||||
//
|
|
||||||
// HMAC keys are used to authenticate signed access to objects. To enable HMAC key
|
|
||||||
// authentication, please visit https://cloud.google.com/storage/docs/migrating.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKey struct {
|
|
||||||
// The HMAC's secret key.
|
|
||||||
Secret string
|
|
||||||
|
|
||||||
// AccessID is the ID of the HMAC key.
|
|
||||||
AccessID string
|
|
||||||
|
|
||||||
// Etag is the HTTP/1.1 Entity tag.
|
|
||||||
Etag string
|
|
||||||
|
|
||||||
// ID is the ID of the HMAC key, including the ProjectID and AccessID.
|
|
||||||
ID string
|
|
||||||
|
|
||||||
// ProjectID is the ID of the project that owns the
|
|
||||||
// service account to which the key authenticates.
|
|
||||||
ProjectID string
|
|
||||||
|
|
||||||
// ServiceAccountEmail is the email address
|
|
||||||
// of the key's associated service account.
|
|
||||||
ServiceAccountEmail string
|
|
||||||
|
|
||||||
// CreatedTime is the creation time of the HMAC key.
|
|
||||||
CreatedTime time.Time
|
|
||||||
|
|
||||||
// UpdatedTime is the last modification time of the HMAC key metadata.
|
|
||||||
UpdatedTime time.Time
|
|
||||||
|
|
||||||
// State is the state of the HMAC key.
|
|
||||||
// It can be one of StateActive, StateInactive or StateDeleted.
|
|
||||||
State HMACState
|
|
||||||
}
|
|
||||||
|
|
||||||
// HMACKeyHandle helps provide access and management for HMAC keys.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKeyHandle struct {
|
|
||||||
projectID string
|
|
||||||
accessID string
|
|
||||||
retry *retryConfig
|
|
||||||
tc storageClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// HMACKeyHandle creates a handle that will be used for HMACKey operations.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (c *Client) HMACKeyHandle(projectID, accessID string) *HMACKeyHandle {
|
|
||||||
return &HMACKeyHandle{
|
|
||||||
projectID: projectID,
|
|
||||||
accessID: accessID,
|
|
||||||
retry: c.retry,
|
|
||||||
tc: c.tc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get invokes an RPC to retrieve the HMAC key referenced by the
|
|
||||||
// HMACKeyHandle's accessID.
|
|
||||||
//
|
|
||||||
// Options such as UserProjectForHMACKeys can be used to set the
|
|
||||||
// userProject to be billed against for operations.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (hkh *HMACKeyHandle) Get(ctx context.Context, opts ...HMACKeyOption) (*HMACKey, error) {
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
o := makeStorageOpts(true, hkh.retry, desc.userProjectID)
|
|
||||||
hk, err := hkh.tc.GetHMACKey(ctx, hkh.projectID, hkh.accessID, o...)
|
|
||||||
|
|
||||||
return hk, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete invokes an RPC to delete the key referenced by accessID, on Google Cloud Storage.
|
|
||||||
// Only inactive HMAC keys can be deleted.
|
|
||||||
// After deletion, a key cannot be used to authenticate requests.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (hkh *HMACKeyHandle) Delete(ctx context.Context, opts ...HMACKeyOption) error {
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
o := makeStorageOpts(true, hkh.retry, desc.userProjectID)
|
|
||||||
return hkh.tc.DeleteHMACKey(ctx, hkh.projectID, hkh.accessID, o...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func toHMACKeyFromRaw(hk *raw.HmacKey, updatedTimeCanBeNil bool) (*HMACKey, error) {
|
|
||||||
hkmd := hk.Metadata
|
|
||||||
if hkmd == nil {
|
|
||||||
return nil, errors.New("field Metadata cannot be nil")
|
|
||||||
}
|
|
||||||
createdTime, err := time.Parse(time.RFC3339, hkmd.TimeCreated)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("field CreatedTime: %w", err)
|
|
||||||
}
|
|
||||||
updatedTime, err := time.Parse(time.RFC3339, hkmd.Updated)
|
|
||||||
if err != nil && !updatedTimeCanBeNil {
|
|
||||||
return nil, fmt.Errorf("field UpdatedTime: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
hmKey := &HMACKey{
|
|
||||||
AccessID: hkmd.AccessId,
|
|
||||||
Secret: hk.Secret,
|
|
||||||
Etag: hkmd.Etag,
|
|
||||||
ID: hkmd.Id,
|
|
||||||
State: HMACState(hkmd.State),
|
|
||||||
ProjectID: hkmd.ProjectId,
|
|
||||||
CreatedTime: createdTime,
|
|
||||||
UpdatedTime: updatedTime,
|
|
||||||
|
|
||||||
ServiceAccountEmail: hkmd.ServiceAccountEmail,
|
|
||||||
}
|
|
||||||
|
|
||||||
return hmKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func toHMACKeyFromProto(pbmd *storagepb.HmacKeyMetadata) *HMACKey {
|
|
||||||
if pbmd == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &HMACKey{
|
|
||||||
AccessID: pbmd.GetAccessId(),
|
|
||||||
ID: pbmd.GetId(),
|
|
||||||
State: HMACState(pbmd.GetState()),
|
|
||||||
ProjectID: pbmd.GetProject(),
|
|
||||||
CreatedTime: convertProtoTime(pbmd.GetCreateTime()),
|
|
||||||
UpdatedTime: convertProtoTime(pbmd.GetUpdateTime()),
|
|
||||||
ServiceAccountEmail: pbmd.GetServiceAccountEmail(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateHMACKey invokes an RPC for Google Cloud Storage to create a new HMACKey.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (c *Client) CreateHMACKey(ctx context.Context, projectID, serviceAccountEmail string, opts ...HMACKeyOption) (*HMACKey, error) {
|
|
||||||
if projectID == "" {
|
|
||||||
return nil, errors.New("storage: expecting a non-blank projectID")
|
|
||||||
}
|
|
||||||
if serviceAccountEmail == "" {
|
|
||||||
return nil, errors.New("storage: expecting a non-blank service account email")
|
|
||||||
}
|
|
||||||
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
o := makeStorageOpts(false, c.retry, desc.userProjectID)
|
|
||||||
hk, err := c.tc.CreateHMACKey(ctx, projectID, serviceAccountEmail, o...)
|
|
||||||
return hk, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// HMACKeyAttrsToUpdate defines the attributes of an HMACKey that will be updated.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKeyAttrsToUpdate struct {
|
|
||||||
// State is required and must be either StateActive or StateInactive.
|
|
||||||
State HMACState
|
|
||||||
|
|
||||||
// Etag is an optional field and it is the HTTP/1.1 Entity tag.
|
|
||||||
Etag string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update mutates the HMACKey referred to by accessID.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (h *HMACKeyHandle) Update(ctx context.Context, au HMACKeyAttrsToUpdate, opts ...HMACKeyOption) (*HMACKey, error) {
|
|
||||||
if au.State != Active && au.State != Inactive {
|
|
||||||
return nil, fmt.Errorf("storage: invalid state %q for update, must be either %q or %q", au.State, Active, Inactive)
|
|
||||||
}
|
|
||||||
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
isIdempotent := len(au.Etag) > 0
|
|
||||||
o := makeStorageOpts(isIdempotent, h.retry, desc.userProjectID)
|
|
||||||
hk, err := h.tc.UpdateHMACKey(ctx, h.projectID, desc.forServiceAccountEmail, h.accessID, &au, o...)
|
|
||||||
return hk, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// An HMACKeysIterator is an iterator over HMACKeys.
|
|
||||||
//
|
|
||||||
// Note: This iterator is not safe for concurrent operations without explicit synchronization.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKeysIterator struct {
|
|
||||||
ctx context.Context
|
|
||||||
raw *raw.ProjectsHmacKeysService
|
|
||||||
projectID string
|
|
||||||
hmacKeys []*HMACKey
|
|
||||||
pageInfo *iterator.PageInfo
|
|
||||||
nextFunc func() error
|
|
||||||
index int
|
|
||||||
desc hmacKeyDesc
|
|
||||||
retry *retryConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListHMACKeys returns an iterator for listing HMACKeys.
|
|
||||||
//
|
|
||||||
// Note: This iterator is not safe for concurrent operations without explicit synchronization.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (c *Client) ListHMACKeys(ctx context.Context, projectID string, opts ...HMACKeyOption) *HMACKeysIterator {
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
o := makeStorageOpts(true, c.retry, desc.userProjectID)
|
|
||||||
return c.tc.ListHMACKeys(ctx, projectID, desc.forServiceAccountEmail, desc.showDeletedKeys, o...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next returns the next result. Its second return value is iterator.Done if
|
|
||||||
// there are no more results. Once Next returns iterator.Done, all subsequent
|
|
||||||
// calls will return iterator.Done.
|
|
||||||
//
|
|
||||||
// Note: This iterator is not safe for concurrent operations without explicit synchronization.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (it *HMACKeysIterator) Next() (*HMACKey, error) {
|
|
||||||
if err := it.nextFunc(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
key := it.hmacKeys[it.index]
|
|
||||||
it.index++
|
|
||||||
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
|
|
||||||
//
|
|
||||||
// Note: This iterator is not safe for concurrent operations without explicit synchronization.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (it *HMACKeysIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }
|
|
||||||
|
|
||||||
func (it *HMACKeysIterator) fetch(pageSize int, pageToken string) (token string, err error) {
|
|
||||||
// TODO: Remove fetch method upon integration. This method is internalized into
|
|
||||||
// httpStorageClient.ListHMACKeys() as it is the only caller.
|
|
||||||
call := it.raw.List(it.projectID)
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
if pageToken != "" {
|
|
||||||
call = call.PageToken(pageToken)
|
|
||||||
}
|
|
||||||
if it.desc.showDeletedKeys {
|
|
||||||
call = call.ShowDeletedKeys(true)
|
|
||||||
}
|
|
||||||
if it.desc.userProjectID != "" {
|
|
||||||
call = call.UserProject(it.desc.userProjectID)
|
|
||||||
}
|
|
||||||
if it.desc.forServiceAccountEmail != "" {
|
|
||||||
call = call.ServiceAccountEmail(it.desc.forServiceAccountEmail)
|
|
||||||
}
|
|
||||||
if pageSize > 0 {
|
|
||||||
call = call.MaxResults(int64(pageSize))
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := it.ctx
|
|
||||||
var resp *raw.HmacKeysMetadata
|
|
||||||
err = run(it.ctx, func() error {
|
|
||||||
resp, err = call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
}, it.retry, true, setRetryHeaderHTTP(call))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, metadata := range resp.Items {
|
|
||||||
hk := &raw.HmacKey{
|
|
||||||
Metadata: metadata,
|
|
||||||
}
|
|
||||||
hkey, err := toHMACKeyFromRaw(hk, true)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
it.hmacKeys = append(it.hmacKeys, hkey)
|
|
||||||
}
|
|
||||||
return resp.NextPageToken, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type hmacKeyDesc struct {
|
|
||||||
forServiceAccountEmail string
|
|
||||||
showDeletedKeys bool
|
|
||||||
userProjectID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// HMACKeyOption configures the behavior of HMACKey related methods and actions.
|
|
||||||
//
|
|
||||||
// This interface is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKeyOption interface {
|
|
||||||
withHMACKeyDesc(*hmacKeyDesc)
|
|
||||||
}
|
|
||||||
|
|
||||||
type hmacKeyDescFunc func(*hmacKeyDesc)
|
|
||||||
|
|
||||||
func (hkdf hmacKeyDescFunc) withHMACKeyDesc(hkd *hmacKeyDesc) {
|
|
||||||
hkdf(hkd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ForHMACKeyServiceAccountEmail returns HMAC Keys that are
|
|
||||||
// associated with the email address of a service account in the project.
|
|
||||||
//
|
|
||||||
// Only one service account email can be used as a filter, so if multiple
|
|
||||||
// of these options are applied, the last email to be set will be used.
|
|
||||||
//
|
|
||||||
// This option is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func ForHMACKeyServiceAccountEmail(serviceAccountEmail string) HMACKeyOption {
|
|
||||||
return hmacKeyDescFunc(func(hkd *hmacKeyDesc) {
|
|
||||||
hkd.forServiceAccountEmail = serviceAccountEmail
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShowDeletedHMACKeys will also list keys whose state is "DELETED".
|
|
||||||
//
|
|
||||||
// This option is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func ShowDeletedHMACKeys() HMACKeyOption {
|
|
||||||
return hmacKeyDescFunc(func(hkd *hmacKeyDesc) {
|
|
||||||
hkd.showDeletedKeys = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserProjectForHMACKeys will bill the request against userProjectID
|
|
||||||
// if userProjectID is non-empty.
|
|
||||||
//
|
|
||||||
// Note: This is a noop right now and only provided for API compatibility.
|
|
||||||
//
|
|
||||||
// This option is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func UserProjectForHMACKeys(userProjectID string) HMACKeyOption {
|
|
||||||
return hmacKeyDescFunc(func(hkd *hmacKeyDesc) {
|
|
||||||
hkd.userProjectID = userProjectID
|
|
||||||
})
|
|
||||||
}
|
|
1418
vendor/cloud.google.com/go/storage/http_client.go
generated
vendored
1418
vendor/cloud.google.com/go/storage/http_client.go
generated
vendored
File diff suppressed because it is too large
Load diff
133
vendor/cloud.google.com/go/storage/iam.go
generated
vendored
133
vendor/cloud.google.com/go/storage/iam.go
generated
vendored
|
@ -1,133 +0,0 @@
|
||||||
// Copyright 2017 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"cloud.google.com/go/iam"
|
|
||||||
"cloud.google.com/go/iam/apiv1/iampb"
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
"google.golang.org/genproto/googleapis/type/expr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IAM provides access to IAM access control for the bucket.
|
|
||||||
func (b *BucketHandle) IAM() *iam.Handle {
|
|
||||||
return iam.InternalNewHandleClient(&iamClient{
|
|
||||||
userProject: b.userProject,
|
|
||||||
retry: b.retry,
|
|
||||||
client: b.c,
|
|
||||||
}, b.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// iamClient implements the iam.client interface.
|
|
||||||
type iamClient struct {
|
|
||||||
userProject string
|
|
||||||
retry *retryConfig
|
|
||||||
client *Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iamClient) Get(ctx context.Context, resource string) (p *iampb.Policy, err error) {
|
|
||||||
return c.GetWithVersion(ctx, resource, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iamClient) GetWithVersion(ctx context.Context, resource string, requestedPolicyVersion int32) (p *iampb.Policy, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Get")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
o := makeStorageOpts(true, c.retry, c.userProject)
|
|
||||||
return c.client.tc.GetIamPolicy(ctx, resource, requestedPolicyVersion, o...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iamClient) Set(ctx context.Context, resource string, p *iampb.Policy) (err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Set")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
isIdempotent := len(p.Etag) > 0
|
|
||||||
o := makeStorageOpts(isIdempotent, c.retry, c.userProject)
|
|
||||||
return c.client.tc.SetIamPolicy(ctx, resource, p, o...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iamClient) Test(ctx context.Context, resource string, perms []string) (permissions []string, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Test")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
o := makeStorageOpts(true, c.retry, c.userProject)
|
|
||||||
return c.client.tc.TestIamPermissions(ctx, resource, perms, o...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamToStoragePolicy(ip *iampb.Policy) *raw.Policy {
|
|
||||||
return &raw.Policy{
|
|
||||||
Bindings: iamToStorageBindings(ip.Bindings),
|
|
||||||
Etag: string(ip.Etag),
|
|
||||||
Version: int64(ip.Version),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamToStorageBindings(ibs []*iampb.Binding) []*raw.PolicyBindings {
|
|
||||||
var rbs []*raw.PolicyBindings
|
|
||||||
for _, ib := range ibs {
|
|
||||||
rbs = append(rbs, &raw.PolicyBindings{
|
|
||||||
Role: ib.Role,
|
|
||||||
Members: ib.Members,
|
|
||||||
Condition: iamToStorageCondition(ib.Condition),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return rbs
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamToStorageCondition(exprpb *expr.Expr) *raw.Expr {
|
|
||||||
if exprpb == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &raw.Expr{
|
|
||||||
Expression: exprpb.Expression,
|
|
||||||
Description: exprpb.Description,
|
|
||||||
Location: exprpb.Location,
|
|
||||||
Title: exprpb.Title,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamFromStoragePolicy(rp *raw.Policy) *iampb.Policy {
|
|
||||||
return &iampb.Policy{
|
|
||||||
Bindings: iamFromStorageBindings(rp.Bindings),
|
|
||||||
Etag: []byte(rp.Etag),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamFromStorageBindings(rbs []*raw.PolicyBindings) []*iampb.Binding {
|
|
||||||
var ibs []*iampb.Binding
|
|
||||||
for _, rb := range rbs {
|
|
||||||
ibs = append(ibs, &iampb.Binding{
|
|
||||||
Role: rb.Role,
|
|
||||||
Members: rb.Members,
|
|
||||||
Condition: iamFromStorageCondition(rb.Condition),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return ibs
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamFromStorageCondition(rawexpr *raw.Expr) *expr.Expr {
|
|
||||||
if rawexpr == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &expr.Expr{
|
|
||||||
Expression: rawexpr.Expression,
|
|
||||||
Description: rawexpr.Description,
|
|
||||||
Location: rawexpr.Location,
|
|
||||||
Title: rawexpr.Title,
|
|
||||||
}
|
|
||||||
}
|
|
176
vendor/cloud.google.com/go/storage/internal/apiv2/doc.go
generated
vendored
176
vendor/cloud.google.com/go/storage/internal/apiv2/doc.go
generated
vendored
|
@ -1,176 +0,0 @@
|
||||||
// Copyright 2023 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
|
|
||||||
|
|
||||||
// Package storage is an auto-generated package for the
|
|
||||||
// Cloud Storage API.
|
|
||||||
//
|
|
||||||
// Lets you store and retrieve potentially-large, immutable data objects.
|
|
||||||
//
|
|
||||||
// NOTE: This package is in alpha. It is not stable, and is likely to change.
|
|
||||||
//
|
|
||||||
// # General documentation
|
|
||||||
//
|
|
||||||
// For information about setting deadlines, reusing contexts, and more
|
|
||||||
// please visit https://pkg.go.dev/cloud.google.com/go.
|
|
||||||
//
|
|
||||||
// # Example usage
|
|
||||||
//
|
|
||||||
// To get started with this package, create a client.
|
|
||||||
//
|
|
||||||
// ctx := context.Background()
|
|
||||||
// // This snippet has been automatically generated and should be regarded as a code template only.
|
|
||||||
// // It will require modifications to work:
|
|
||||||
// // - It may require correct/in-range values for request initialization.
|
|
||||||
// // - It may require specifying regional endpoints when creating the service client as shown in:
|
|
||||||
// // https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
|
|
||||||
// c, err := storage.NewClient(ctx)
|
|
||||||
// if err != nil {
|
|
||||||
// // TODO: Handle error.
|
|
||||||
// }
|
|
||||||
// defer c.Close()
|
|
||||||
//
|
|
||||||
// The client will use your default application credentials. Clients should be reused instead of created as needed.
|
|
||||||
// The methods of Client are safe for concurrent use by multiple goroutines.
|
|
||||||
// The returned client must be Closed when it is done being used.
|
|
||||||
//
|
|
||||||
// # Using the Client
|
|
||||||
//
|
|
||||||
// The following is an example of making an API call with the newly created client.
|
|
||||||
//
|
|
||||||
// ctx := context.Background()
|
|
||||||
// // This snippet has been automatically generated and should be regarded as a code template only.
|
|
||||||
// // It will require modifications to work:
|
|
||||||
// // - It may require correct/in-range values for request initialization.
|
|
||||||
// // - It may require specifying regional endpoints when creating the service client as shown in:
|
|
||||||
// // https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
|
|
||||||
// c, err := storage.NewClient(ctx)
|
|
||||||
// if err != nil {
|
|
||||||
// // TODO: Handle error.
|
|
||||||
// }
|
|
||||||
// defer c.Close()
|
|
||||||
//
|
|
||||||
// req := &storagepb.DeleteBucketRequest{
|
|
||||||
// // TODO: Fill request struct fields.
|
|
||||||
// // See https://pkg.go.dev/cloud.google.com/go/storage/internal/apiv2/stubs#DeleteBucketRequest.
|
|
||||||
// }
|
|
||||||
// err = c.DeleteBucket(ctx, req)
|
|
||||||
// if err != nil {
|
|
||||||
// // TODO: Handle error.
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// # Use of Context
|
|
||||||
//
|
|
||||||
// The ctx passed to NewClient is used for authentication requests and
|
|
||||||
// for creating the underlying connection, but is not used for subsequent calls.
|
|
||||||
// Individual methods on the client use the ctx given to them.
|
|
||||||
//
|
|
||||||
// To close the open connection, use the Close() method.
|
|
||||||
package storage // import "cloud.google.com/go/storage/internal/apiv2"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
|
|
||||||
"google.golang.org/api/option"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
)
|
|
||||||
|
|
||||||
// For more information on implementing a client constructor hook, see
|
|
||||||
// https://github.com/googleapis/google-cloud-go/wiki/Customizing-constructors.
|
|
||||||
type clientHookParams struct{}
|
|
||||||
type clientHook func(context.Context, clientHookParams) ([]option.ClientOption, error)
|
|
||||||
|
|
||||||
var versionClient string
|
|
||||||
|
|
||||||
func getVersionClient() string {
|
|
||||||
if versionClient == "" {
|
|
||||||
return "UNKNOWN"
|
|
||||||
}
|
|
||||||
return versionClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
|
|
||||||
out, _ := metadata.FromOutgoingContext(ctx)
|
|
||||||
out = out.Copy()
|
|
||||||
for _, md := range mds {
|
|
||||||
for k, v := range md {
|
|
||||||
out[k] = append(out[k], v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return metadata.NewOutgoingContext(ctx, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkDisableDeadlines() (bool, error) {
|
|
||||||
raw, ok := os.LookupEnv("GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE")
|
|
||||||
if !ok {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := strconv.ParseBool(raw)
|
|
||||||
return b, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultAuthScopes reports the default set of authentication scopes to use with this package.
|
|
||||||
func DefaultAuthScopes() []string {
|
|
||||||
return []string{
|
|
||||||
"https://www.googleapis.com/auth/cloud-platform",
|
|
||||||
"https://www.googleapis.com/auth/cloud-platform.read-only",
|
|
||||||
"https://www.googleapis.com/auth/devstorage.full_control",
|
|
||||||
"https://www.googleapis.com/auth/devstorage.read_only",
|
|
||||||
"https://www.googleapis.com/auth/devstorage.read_write",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// versionGo returns the Go runtime version. The returned string
|
|
||||||
// has no whitespace, suitable for reporting in header.
|
|
||||||
func versionGo() string {
|
|
||||||
const develPrefix = "devel +"
|
|
||||||
|
|
||||||
s := runtime.Version()
|
|
||||||
if strings.HasPrefix(s, develPrefix) {
|
|
||||||
s = s[len(develPrefix):]
|
|
||||||
if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
|
|
||||||
s = s[:p]
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
notSemverRune := func(r rune) bool {
|
|
||||||
return !strings.ContainsRune("0123456789.", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(s, "go1") {
|
|
||||||
s = s[2:]
|
|
||||||
var prerelease string
|
|
||||||
if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
|
|
||||||
s, prerelease = s[:p], s[p:]
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(s, ".") {
|
|
||||||
s += "0"
|
|
||||||
} else if strings.Count(s, ".") < 2 {
|
|
||||||
s += ".0"
|
|
||||||
}
|
|
||||||
if prerelease != "" {
|
|
||||||
s += "-" + prerelease
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return "UNKNOWN"
|
|
||||||
}
|
|
168
vendor/cloud.google.com/go/storage/internal/apiv2/gapic_metadata.json
generated
vendored
168
vendor/cloud.google.com/go/storage/internal/apiv2/gapic_metadata.json
generated
vendored
|
@ -1,168 +0,0 @@
|
||||||
{
|
|
||||||
"schema": "1.0",
|
|
||||||
"comment": "This file maps proto services/RPCs to the corresponding library clients/methods.",
|
|
||||||
"language": "go",
|
|
||||||
"protoPackage": "google.storage.v2",
|
|
||||||
"libraryPackage": "cloud.google.com/go/storage/internal/apiv2",
|
|
||||||
"services": {
|
|
||||||
"Storage": {
|
|
||||||
"clients": {
|
|
||||||
"grpc": {
|
|
||||||
"libraryClient": "Client",
|
|
||||||
"rpcs": {
|
|
||||||
"CancelResumableWrite": {
|
|
||||||
"methods": [
|
|
||||||
"CancelResumableWrite"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ComposeObject": {
|
|
||||||
"methods": [
|
|
||||||
"ComposeObject"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"CreateBucket": {
|
|
||||||
"methods": [
|
|
||||||
"CreateBucket"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"CreateHmacKey": {
|
|
||||||
"methods": [
|
|
||||||
"CreateHmacKey"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"CreateNotificationConfig": {
|
|
||||||
"methods": [
|
|
||||||
"CreateNotificationConfig"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"DeleteBucket": {
|
|
||||||
"methods": [
|
|
||||||
"DeleteBucket"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"DeleteHmacKey": {
|
|
||||||
"methods": [
|
|
||||||
"DeleteHmacKey"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"DeleteNotificationConfig": {
|
|
||||||
"methods": [
|
|
||||||
"DeleteNotificationConfig"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"DeleteObject": {
|
|
||||||
"methods": [
|
|
||||||
"DeleteObject"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"GetBucket": {
|
|
||||||
"methods": [
|
|
||||||
"GetBucket"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"GetHmacKey": {
|
|
||||||
"methods": [
|
|
||||||
"GetHmacKey"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"GetIamPolicy": {
|
|
||||||
"methods": [
|
|
||||||
"GetIamPolicy"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"GetNotificationConfig": {
|
|
||||||
"methods": [
|
|
||||||
"GetNotificationConfig"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"GetObject": {
|
|
||||||
"methods": [
|
|
||||||
"GetObject"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"GetServiceAccount": {
|
|
||||||
"methods": [
|
|
||||||
"GetServiceAccount"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ListBuckets": {
|
|
||||||
"methods": [
|
|
||||||
"ListBuckets"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ListHmacKeys": {
|
|
||||||
"methods": [
|
|
||||||
"ListHmacKeys"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ListNotificationConfigs": {
|
|
||||||
"methods": [
|
|
||||||
"ListNotificationConfigs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ListObjects": {
|
|
||||||
"methods": [
|
|
||||||
"ListObjects"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"LockBucketRetentionPolicy": {
|
|
||||||
"methods": [
|
|
||||||
"LockBucketRetentionPolicy"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"QueryWriteStatus": {
|
|
||||||
"methods": [
|
|
||||||
"QueryWriteStatus"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ReadObject": {
|
|
||||||
"methods": [
|
|
||||||
"ReadObject"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"RewriteObject": {
|
|
||||||
"methods": [
|
|
||||||
"RewriteObject"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"SetIamPolicy": {
|
|
||||||
"methods": [
|
|
||||||
"SetIamPolicy"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"StartResumableWrite": {
|
|
||||||
"methods": [
|
|
||||||
"StartResumableWrite"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"TestIamPermissions": {
|
|
||||||
"methods": [
|
|
||||||
"TestIamPermissions"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"UpdateBucket": {
|
|
||||||
"methods": [
|
|
||||||
"UpdateBucket"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"UpdateHmacKey": {
|
|
||||||
"methods": [
|
|
||||||
"UpdateHmacKey"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"UpdateObject": {
|
|
||||||
"methods": [
|
|
||||||
"UpdateObject"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"WriteObject": {
|
|
||||||
"methods": [
|
|
||||||
"WriteObject"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
26
vendor/cloud.google.com/go/storage/internal/apiv2/metadata.go
generated
vendored
26
vendor/cloud.google.com/go/storage/internal/apiv2/metadata.go
generated
vendored
|
@ -1,26 +0,0 @@
|
||||||
// Copyright 2022 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InsertMetadata inserts the given gRPC metadata into the outgoing context.
|
|
||||||
func InsertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
|
|
||||||
return insertMetadata(ctx, mds...)
|
|
||||||
}
|
|
1619
vendor/cloud.google.com/go/storage/internal/apiv2/storage_client.go
generated
vendored
1619
vendor/cloud.google.com/go/storage/internal/apiv2/storage_client.go
generated
vendored
File diff suppressed because it is too large
Load diff
10759
vendor/cloud.google.com/go/storage/internal/apiv2/stubs/storage.pb.go
generated
vendored
10759
vendor/cloud.google.com/go/storage/internal/apiv2/stubs/storage.pb.go
generated
vendored
File diff suppressed because it is too large
Load diff
23
vendor/cloud.google.com/go/storage/internal/apiv2/version.go
generated
vendored
23
vendor/cloud.google.com/go/storage/internal/apiv2/version.go
generated
vendored
|
@ -1,23 +0,0 @@
|
||||||
// Copyright 2023 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Code generated by gapicgen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import "cloud.google.com/go/storage/internal"
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
versionClient = internal.Version
|
|
||||||
}
|
|
18
vendor/cloud.google.com/go/storage/internal/version.go
generated
vendored
18
vendor/cloud.google.com/go/storage/internal/version.go
generated
vendored
|
@ -1,18 +0,0 @@
|
||||||
// Copyright 2022 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package internal
|
|
||||||
|
|
||||||
// Version is the current tagged release of the library.
|
|
||||||
const Version = "1.30.1"
|
|
146
vendor/cloud.google.com/go/storage/invoke.go
generated
vendored
146
vendor/cloud.google.com/go/storage/invoke.go
generated
vendored
|
@ -1,146 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal"
|
|
||||||
"cloud.google.com/go/internal/version"
|
|
||||||
sinternal "cloud.google.com/go/storage/internal"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
gax "github.com/googleapis/gax-go/v2"
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
var defaultRetry *retryConfig = &retryConfig{}
|
|
||||||
var xGoogDefaultHeader = fmt.Sprintf("gl-go/%s gccl/%s", version.Go(), sinternal.Version)
|
|
||||||
|
|
||||||
// run determines whether a retry is necessary based on the config and
|
|
||||||
// idempotency information. It then calls the function with or without retries
|
|
||||||
// as appropriate, using the configured settings.
|
|
||||||
func run(ctx context.Context, call func() error, retry *retryConfig, isIdempotent bool, setHeader func(string, int)) error {
|
|
||||||
attempts := 1
|
|
||||||
invocationID := uuid.New().String()
|
|
||||||
|
|
||||||
if retry == nil {
|
|
||||||
retry = defaultRetry
|
|
||||||
}
|
|
||||||
if (retry.policy == RetryIdempotent && !isIdempotent) || retry.policy == RetryNever {
|
|
||||||
setHeader(invocationID, attempts)
|
|
||||||
return call()
|
|
||||||
}
|
|
||||||
bo := gax.Backoff{}
|
|
||||||
if retry.backoff != nil {
|
|
||||||
bo.Multiplier = retry.backoff.Multiplier
|
|
||||||
bo.Initial = retry.backoff.Initial
|
|
||||||
bo.Max = retry.backoff.Max
|
|
||||||
}
|
|
||||||
var errorFunc func(err error) bool = ShouldRetry
|
|
||||||
if retry.shouldRetry != nil {
|
|
||||||
errorFunc = retry.shouldRetry
|
|
||||||
}
|
|
||||||
|
|
||||||
return internal.Retry(ctx, bo, func() (stop bool, err error) {
|
|
||||||
setHeader(invocationID, attempts)
|
|
||||||
err = call()
|
|
||||||
attempts++
|
|
||||||
return !errorFunc(err), err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func setRetryHeaderHTTP(req interface{ Header() http.Header }) func(string, int) {
|
|
||||||
return func(invocationID string, attempts int) {
|
|
||||||
if req == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
header := req.Header()
|
|
||||||
invocationHeader := fmt.Sprintf("gccl-invocation-id/%v gccl-attempt-count/%v", invocationID, attempts)
|
|
||||||
xGoogHeader := strings.Join([]string{invocationHeader, xGoogDefaultHeader}, " ")
|
|
||||||
header.Set("x-goog-api-client", xGoogHeader)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Implement method setting header via context for gRPC
|
|
||||||
func setRetryHeaderGRPC(_ context.Context) func(string, int) {
|
|
||||||
return func(_ string, _ int) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldRetry returns true if an error is retryable, based on best practice
|
|
||||||
// guidance from GCS. See
|
|
||||||
// https://cloud.google.com/storage/docs/retry-strategy#go for more information
|
|
||||||
// on what errors are considered retryable.
|
|
||||||
//
|
|
||||||
// If you would like to customize retryable errors, use the WithErrorFunc to
|
|
||||||
// supply a RetryOption to your library calls. For example, to retry additional
|
|
||||||
// errors, you can write a custom func that wraps ShouldRetry and also specifies
|
|
||||||
// additional errors that should return true.
|
|
||||||
func ShouldRetry(err error) bool {
|
|
||||||
if err == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if errors.Is(err, io.ErrUnexpectedEOF) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
switch e := err.(type) {
|
|
||||||
case *net.OpError:
|
|
||||||
if strings.Contains(e.Error(), "use of closed network connection") {
|
|
||||||
// TODO: check against net.ErrClosed (go 1.16+) instead of string
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case *googleapi.Error:
|
|
||||||
// Retry on 408, 429, and 5xx, according to
|
|
||||||
// https://cloud.google.com/storage/docs/exponential-backoff.
|
|
||||||
return e.Code == 408 || e.Code == 429 || (e.Code >= 500 && e.Code < 600)
|
|
||||||
case *url.Error:
|
|
||||||
// Retry socket-level errors ECONNREFUSED and ECONNRESET (from syscall).
|
|
||||||
// Unfortunately the error type is unexported, so we resort to string
|
|
||||||
// matching.
|
|
||||||
retriable := []string{"connection refused", "connection reset"}
|
|
||||||
for _, s := range retriable {
|
|
||||||
if strings.Contains(e.Error(), s) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case interface{ Temporary() bool }:
|
|
||||||
if e.Temporary() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// HTTP 429, 502, 503, and 504 all map to gRPC UNAVAILABLE per
|
|
||||||
// https://grpc.github.io/grpc/core/md_doc_http-grpc-status-mapping.html.
|
|
||||||
//
|
|
||||||
// This is only necessary for the experimental gRPC-based media operations.
|
|
||||||
if st, ok := status.FromError(err); ok && st.Code() == codes.Unavailable {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// Unwrap is only supported in go1.13.x+
|
|
||||||
if e, ok := err.(interface{ Unwrap() error }); ok {
|
|
||||||
return ShouldRetry(e.Unwrap())
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
200
vendor/cloud.google.com/go/storage/notifications.go
generated
vendored
200
vendor/cloud.google.com/go/storage/notifications.go
generated
vendored
|
@ -1,200 +0,0 @@
|
||||||
// Copyright 2017 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
storagepb "cloud.google.com/go/storage/internal/apiv2/stubs"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Notification describes how to send Cloud PubSub messages when certain
|
|
||||||
// events occur in a bucket.
|
|
||||||
type Notification struct {
|
|
||||||
//The ID of the notification.
|
|
||||||
ID string
|
|
||||||
|
|
||||||
// The ID of the topic to which this subscription publishes.
|
|
||||||
TopicID string
|
|
||||||
|
|
||||||
// The ID of the project to which the topic belongs.
|
|
||||||
TopicProjectID string
|
|
||||||
|
|
||||||
// Only send notifications about listed event types. If empty, send notifications
|
|
||||||
// for all event types.
|
|
||||||
// See https://cloud.google.com/storage/docs/pubsub-notifications#events.
|
|
||||||
EventTypes []string
|
|
||||||
|
|
||||||
// If present, only apply this notification configuration to object names that
|
|
||||||
// begin with this prefix.
|
|
||||||
ObjectNamePrefix string
|
|
||||||
|
|
||||||
// An optional list of additional attributes to attach to each Cloud PubSub
|
|
||||||
// message published for this notification subscription.
|
|
||||||
CustomAttributes map[string]string
|
|
||||||
|
|
||||||
// The contents of the message payload.
|
|
||||||
// See https://cloud.google.com/storage/docs/pubsub-notifications#payload.
|
|
||||||
PayloadFormat string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Values for Notification.PayloadFormat.
|
|
||||||
const (
|
|
||||||
// Send no payload with notification messages.
|
|
||||||
NoPayload = "NONE"
|
|
||||||
|
|
||||||
// Send object metadata as JSON with notification messages.
|
|
||||||
JSONPayload = "JSON_API_V1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Values for Notification.EventTypes.
|
|
||||||
const (
|
|
||||||
// Event that occurs when an object is successfully created.
|
|
||||||
ObjectFinalizeEvent = "OBJECT_FINALIZE"
|
|
||||||
|
|
||||||
// Event that occurs when the metadata of an existing object changes.
|
|
||||||
ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE"
|
|
||||||
|
|
||||||
// Event that occurs when an object is permanently deleted.
|
|
||||||
ObjectDeleteEvent = "OBJECT_DELETE"
|
|
||||||
|
|
||||||
// Event that occurs when the live version of an object becomes an
|
|
||||||
// archived version.
|
|
||||||
ObjectArchiveEvent = "OBJECT_ARCHIVE"
|
|
||||||
)
|
|
||||||
|
|
||||||
func toNotification(rn *raw.Notification) *Notification {
|
|
||||||
n := &Notification{
|
|
||||||
ID: rn.Id,
|
|
||||||
EventTypes: rn.EventTypes,
|
|
||||||
ObjectNamePrefix: rn.ObjectNamePrefix,
|
|
||||||
CustomAttributes: rn.CustomAttributes,
|
|
||||||
PayloadFormat: rn.PayloadFormat,
|
|
||||||
}
|
|
||||||
n.TopicProjectID, n.TopicID = parseNotificationTopic(rn.Topic)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func toNotificationFromProto(pbn *storagepb.NotificationConfig) *Notification {
|
|
||||||
n := &Notification{
|
|
||||||
ID: pbn.GetName(),
|
|
||||||
EventTypes: pbn.GetEventTypes(),
|
|
||||||
ObjectNamePrefix: pbn.GetObjectNamePrefix(),
|
|
||||||
CustomAttributes: pbn.GetCustomAttributes(),
|
|
||||||
PayloadFormat: pbn.GetPayloadFormat(),
|
|
||||||
}
|
|
||||||
n.TopicProjectID, n.TopicID = parseNotificationTopic(pbn.Topic)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func toProtoNotification(n *Notification) *storagepb.NotificationConfig {
|
|
||||||
return &storagepb.NotificationConfig{
|
|
||||||
Name: n.ID,
|
|
||||||
Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s",
|
|
||||||
n.TopicProjectID, n.TopicID),
|
|
||||||
EventTypes: n.EventTypes,
|
|
||||||
ObjectNamePrefix: n.ObjectNamePrefix,
|
|
||||||
CustomAttributes: n.CustomAttributes,
|
|
||||||
PayloadFormat: n.PayloadFormat,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var topicRE = regexp.MustCompile("^//pubsub.googleapis.com/projects/([^/]+)/topics/([^/]+)")
|
|
||||||
|
|
||||||
// parseNotificationTopic extracts the project and topic IDs from from the full
|
|
||||||
// resource name returned by the service. If the name is malformed, it returns
|
|
||||||
// "?" for both IDs.
|
|
||||||
func parseNotificationTopic(nt string) (projectID, topicID string) {
|
|
||||||
matches := topicRE.FindStringSubmatch(nt)
|
|
||||||
if matches == nil {
|
|
||||||
return "?", "?"
|
|
||||||
}
|
|
||||||
return matches[1], matches[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
func toRawNotification(n *Notification) *raw.Notification {
|
|
||||||
return &raw.Notification{
|
|
||||||
Id: n.ID,
|
|
||||||
Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s",
|
|
||||||
n.TopicProjectID, n.TopicID),
|
|
||||||
EventTypes: n.EventTypes,
|
|
||||||
ObjectNamePrefix: n.ObjectNamePrefix,
|
|
||||||
CustomAttributes: n.CustomAttributes,
|
|
||||||
PayloadFormat: string(n.PayloadFormat),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddNotification adds a notification to b. You must set n's TopicProjectID, TopicID
|
|
||||||
// and PayloadFormat, and must not set its ID. The other fields are all optional. The
|
|
||||||
// returned Notification's ID can be used to refer to it.
|
|
||||||
func (b *BucketHandle) AddNotification(ctx context.Context, n *Notification) (ret *Notification, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.AddNotification")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if n.ID != "" {
|
|
||||||
return nil, errors.New("storage: AddNotification: ID must not be set")
|
|
||||||
}
|
|
||||||
if n.TopicProjectID == "" {
|
|
||||||
return nil, errors.New("storage: AddNotification: missing TopicProjectID")
|
|
||||||
}
|
|
||||||
if n.TopicID == "" {
|
|
||||||
return nil, errors.New("storage: AddNotification: missing TopicID")
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := makeStorageOpts(false, b.retry, b.userProject)
|
|
||||||
ret, err = b.c.tc.CreateNotification(ctx, b.name, n, opts...)
|
|
||||||
return ret, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notifications returns all the Notifications configured for this bucket, as a map
|
|
||||||
// indexed by notification ID.
|
|
||||||
func (b *BucketHandle) Notifications(ctx context.Context) (n map[string]*Notification, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Notifications")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
opts := makeStorageOpts(true, b.retry, b.userProject)
|
|
||||||
n, err = b.c.tc.ListNotifications(ctx, b.name, opts...)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func notificationsToMap(rns []*raw.Notification) map[string]*Notification {
|
|
||||||
m := map[string]*Notification{}
|
|
||||||
for _, rn := range rns {
|
|
||||||
m[rn.Id] = toNotification(rn)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func notificationsToMapFromProto(ns []*storagepb.NotificationConfig) map[string]*Notification {
|
|
||||||
m := map[string]*Notification{}
|
|
||||||
for _, n := range ns {
|
|
||||||
m[n.Name] = toNotificationFromProto(n)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteNotification deletes the notification with the given ID.
|
|
||||||
func (b *BucketHandle) DeleteNotification(ctx context.Context, id string) (err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.DeleteNotification")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
opts := makeStorageOpts(true, b.retry, b.userProject)
|
|
||||||
return b.c.tc.DeleteNotification(ctx, b.name, id, opts...)
|
|
||||||
}
|
|
75
vendor/cloud.google.com/go/storage/option.go
generated
vendored
75
vendor/cloud.google.com/go/storage/option.go
generated
vendored
|
@ -1,75 +0,0 @@
|
||||||
// Copyright 2023 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"google.golang.org/api/option"
|
|
||||||
"google.golang.org/api/option/internaloption"
|
|
||||||
)
|
|
||||||
|
|
||||||
// storageConfig contains the Storage client option configuration that can be
|
|
||||||
// set through storageClientOptions.
|
|
||||||
type storageConfig struct {
|
|
||||||
useJSONforReads bool
|
|
||||||
readAPIWasSet bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// newStorageConfig generates a new storageConfig with all the given
|
|
||||||
// storageClientOptions applied.
|
|
||||||
func newStorageConfig(opts ...option.ClientOption) storageConfig {
|
|
||||||
var conf storageConfig
|
|
||||||
for _, opt := range opts {
|
|
||||||
if storageOpt, ok := opt.(storageClientOption); ok {
|
|
||||||
storageOpt.ApplyStorageOpt(&conf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return conf
|
|
||||||
}
|
|
||||||
|
|
||||||
// A storageClientOption is an option for a Google Storage client.
|
|
||||||
type storageClientOption interface {
|
|
||||||
option.ClientOption
|
|
||||||
ApplyStorageOpt(*storageConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithJSONReads is an option that may be passed to a Storage Client on creation.
|
|
||||||
// It sets the client to use the JSON API for object reads. Currently, the
|
|
||||||
// default API used for reads is XML.
|
|
||||||
// Setting this option is required to use the GenerationNotMatch condition.
|
|
||||||
//
|
|
||||||
// Note that when this option is set, reads will return a zero date for
|
|
||||||
// [ReaderObjectAttrs].LastModified and may return a different value for
|
|
||||||
// [ReaderObjectAttrs].CacheControl.
|
|
||||||
func WithJSONReads() option.ClientOption {
|
|
||||||
return &withReadAPI{useJSON: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithXMLReads is an option that may be passed to a Storage Client on creation.
|
|
||||||
// It sets the client to use the JSON API for object reads.
|
|
||||||
//
|
|
||||||
// This is the current default.
|
|
||||||
func WithXMLReads() option.ClientOption {
|
|
||||||
return &withReadAPI{useJSON: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
type withReadAPI struct {
|
|
||||||
internaloption.EmbeddableAdapter
|
|
||||||
useJSON bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *withReadAPI) ApplyStorageOpt(c *storageConfig) {
|
|
||||||
c.useJSONforReads = w.useJSON
|
|
||||||
c.readAPIWasSet = true
|
|
||||||
}
|
|
436
vendor/cloud.google.com/go/storage/post_policy_v4.go
generated
vendored
436
vendor/cloud.google.com/go/storage/post_policy_v4.go
generated
vendored
|
@ -1,436 +0,0 @@
|
||||||
// Copyright 2020 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostPolicyV4Options are used to construct a signed post policy.
|
|
||||||
// Please see https://cloud.google.com/storage/docs/xml-api/post-object
|
|
||||||
// for reference about the fields.
|
|
||||||
type PostPolicyV4Options struct {
|
|
||||||
// GoogleAccessID represents the authorizer of the signed URL generation.
|
|
||||||
// It is typically the Google service account client email address from
|
|
||||||
// the Google Developers Console in the form of "xxx@developer.gserviceaccount.com".
|
|
||||||
// Required.
|
|
||||||
GoogleAccessID string
|
|
||||||
|
|
||||||
// PrivateKey is the Google service account private key. It is obtainable
|
|
||||||
// from the Google Developers Console.
|
|
||||||
// At https://console.developers.google.com/project/<your-project-id>/apiui/credential,
|
|
||||||
// create a service account client ID or reuse one of your existing service account
|
|
||||||
// credentials. Click on the "Generate new P12 key" to generate and download
|
|
||||||
// a new private key. Once you download the P12 file, use the following command
|
|
||||||
// to convert it into a PEM file.
|
|
||||||
//
|
|
||||||
// $ openssl pkcs12 -in key.p12 -passin pass:notasecret -out key.pem -nodes
|
|
||||||
//
|
|
||||||
// Provide the contents of the PEM file as a byte slice.
|
|
||||||
// Exactly one of PrivateKey or SignBytes must be non-nil.
|
|
||||||
PrivateKey []byte
|
|
||||||
|
|
||||||
// SignBytes is a function for implementing custom signing.
|
|
||||||
//
|
|
||||||
// Deprecated: Use SignRawBytes. If both SignBytes and SignRawBytes are defined,
|
|
||||||
// SignBytes will be ignored.
|
|
||||||
// This SignBytes function expects the bytes it receives to be hashed, while
|
|
||||||
// SignRawBytes accepts the raw bytes without hashing, allowing more flexibility.
|
|
||||||
// Add the following to the top of your signing function to hash the bytes
|
|
||||||
// to use SignRawBytes instead:
|
|
||||||
// shaSum := sha256.Sum256(bytes)
|
|
||||||
// bytes = shaSum[:]
|
|
||||||
//
|
|
||||||
SignBytes func(hashBytes []byte) (signature []byte, err error)
|
|
||||||
|
|
||||||
// SignRawBytes is a function for implementing custom signing. For example, if
|
|
||||||
// your application is running on Google App Engine, you can use
|
|
||||||
// appengine's internal signing function:
|
|
||||||
// ctx := appengine.NewContext(request)
|
|
||||||
// acc, _ := appengine.ServiceAccount(ctx)
|
|
||||||
// &PostPolicyV4Options{
|
|
||||||
// GoogleAccessID: acc,
|
|
||||||
// SignRawBytes: func(b []byte) ([]byte, error) {
|
|
||||||
// _, signedBytes, err := appengine.SignBytes(ctx, b)
|
|
||||||
// return signedBytes, err
|
|
||||||
// },
|
|
||||||
// // etc.
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// SignRawBytes is equivalent to the SignBytes field on SignedURLOptions;
|
|
||||||
// that is, you may use the same signing function for the two.
|
|
||||||
//
|
|
||||||
// Exactly one of PrivateKey or SignRawBytes must be non-nil.
|
|
||||||
SignRawBytes func(bytes []byte) (signature []byte, err error)
|
|
||||||
|
|
||||||
// Expires is the expiration time on the signed URL.
|
|
||||||
// It must be a time in the future.
|
|
||||||
// Required.
|
|
||||||
Expires time.Time
|
|
||||||
|
|
||||||
// Style provides options for the type of URL to use. Options are
|
|
||||||
// PathStyle (default), BucketBoundHostname, and VirtualHostedStyle. See
|
|
||||||
// https://cloud.google.com/storage/docs/request-endpoints for details.
|
|
||||||
// Optional.
|
|
||||||
Style URLStyle
|
|
||||||
|
|
||||||
// Insecure when set indicates that the generated URL's scheme
|
|
||||||
// will use "http" instead of "https" (default).
|
|
||||||
// Optional.
|
|
||||||
Insecure bool
|
|
||||||
|
|
||||||
// Fields specifies the attributes of a PostPolicyV4 request.
|
|
||||||
// When Fields is non-nil, its attributes must match those that will
|
|
||||||
// passed into field Conditions.
|
|
||||||
// Optional.
|
|
||||||
Fields *PolicyV4Fields
|
|
||||||
|
|
||||||
// The conditions that the uploaded file will be expected to conform to.
|
|
||||||
// When used, the failure of an upload to satisfy a condition will result in
|
|
||||||
// a 4XX status code, back with the message describing the problem.
|
|
||||||
// Optional.
|
|
||||||
Conditions []PostPolicyV4Condition
|
|
||||||
|
|
||||||
shouldHashSignBytes bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (opts *PostPolicyV4Options) clone() *PostPolicyV4Options {
|
|
||||||
return &PostPolicyV4Options{
|
|
||||||
GoogleAccessID: opts.GoogleAccessID,
|
|
||||||
PrivateKey: opts.PrivateKey,
|
|
||||||
SignBytes: opts.SignBytes,
|
|
||||||
SignRawBytes: opts.SignRawBytes,
|
|
||||||
Expires: opts.Expires,
|
|
||||||
Style: opts.Style,
|
|
||||||
Insecure: opts.Insecure,
|
|
||||||
Fields: opts.Fields,
|
|
||||||
Conditions: opts.Conditions,
|
|
||||||
shouldHashSignBytes: opts.shouldHashSignBytes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PolicyV4Fields describes the attributes for a PostPolicyV4 request.
|
|
||||||
type PolicyV4Fields struct {
|
|
||||||
// ACL specifies the access control permissions for the object.
|
|
||||||
// Optional.
|
|
||||||
ACL string
|
|
||||||
// CacheControl specifies the caching directives for the object.
|
|
||||||
// Optional.
|
|
||||||
CacheControl string
|
|
||||||
// ContentType specifies the media type of the object.
|
|
||||||
// Optional.
|
|
||||||
ContentType string
|
|
||||||
// ContentDisposition specifies how the file will be served back to requesters.
|
|
||||||
// Optional.
|
|
||||||
ContentDisposition string
|
|
||||||
// ContentEncoding specifies the decompressive transcoding that the object.
|
|
||||||
// This field is complementary to ContentType in that the file could be
|
|
||||||
// compressed but ContentType specifies the file's original media type.
|
|
||||||
// Optional.
|
|
||||||
ContentEncoding string
|
|
||||||
// Metadata specifies custom metadata for the object.
|
|
||||||
// If any key doesn't begin with "x-goog-meta-", an error will be returned.
|
|
||||||
// Optional.
|
|
||||||
Metadata map[string]string
|
|
||||||
// StatusCodeOnSuccess when set, specifies the status code that Cloud Storage
|
|
||||||
// will serve back on successful upload of the object.
|
|
||||||
// Optional.
|
|
||||||
StatusCodeOnSuccess int
|
|
||||||
// RedirectToURLOnSuccess when set, specifies the URL that Cloud Storage
|
|
||||||
// will serve back on successful upload of the object.
|
|
||||||
// Optional.
|
|
||||||
RedirectToURLOnSuccess string
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostPolicyV4 describes the URL and respective form fields for a generated PostPolicyV4 request.
|
|
||||||
type PostPolicyV4 struct {
|
|
||||||
// URL is the generated URL that the file upload will be made to.
|
|
||||||
URL string
|
|
||||||
// Fields specifies the generated key-values that the file uploader
|
|
||||||
// must include in their multipart upload form.
|
|
||||||
Fields map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostPolicyV4Condition describes the constraints that the subsequent
|
|
||||||
// object upload's multipart form fields will be expected to conform to.
|
|
||||||
type PostPolicyV4Condition interface {
|
|
||||||
isEmpty() bool
|
|
||||||
json.Marshaler
|
|
||||||
}
|
|
||||||
|
|
||||||
type startsWith struct {
|
|
||||||
key, value string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sw *startsWith) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal([]string{"starts-with", sw.key, sw.value})
|
|
||||||
}
|
|
||||||
func (sw *startsWith) isEmpty() bool {
|
|
||||||
return sw.value == ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConditionStartsWith checks that an attributes starts with value.
|
|
||||||
// An empty value will cause this condition to be ignored.
|
|
||||||
func ConditionStartsWith(key, value string) PostPolicyV4Condition {
|
|
||||||
return &startsWith{key, value}
|
|
||||||
}
|
|
||||||
|
|
||||||
type contentLengthRangeCondition struct {
|
|
||||||
start, end uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (clr *contentLengthRangeCondition) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal([]interface{}{"content-length-range", clr.start, clr.end})
|
|
||||||
}
|
|
||||||
func (clr *contentLengthRangeCondition) isEmpty() bool {
|
|
||||||
return clr.start == 0 && clr.end == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type singleValueCondition struct {
|
|
||||||
name, value string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *singleValueCondition) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(map[string]string{svc.name: svc.value})
|
|
||||||
}
|
|
||||||
func (svc *singleValueCondition) isEmpty() bool {
|
|
||||||
return svc.value == ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConditionContentLengthRange constraints the limits that the
|
|
||||||
// multipart upload's range header will be expected to be within.
|
|
||||||
func ConditionContentLengthRange(start, end uint64) PostPolicyV4Condition {
|
|
||||||
return &contentLengthRangeCondition{start, end}
|
|
||||||
}
|
|
||||||
|
|
||||||
func conditionRedirectToURLOnSuccess(redirectURL string) PostPolicyV4Condition {
|
|
||||||
return &singleValueCondition{"success_action_redirect", redirectURL}
|
|
||||||
}
|
|
||||||
|
|
||||||
func conditionStatusCodeOnSuccess(statusCode int) PostPolicyV4Condition {
|
|
||||||
svc := &singleValueCondition{name: "success_action_status"}
|
|
||||||
if statusCode > 0 {
|
|
||||||
svc.value = fmt.Sprintf("%d", statusCode)
|
|
||||||
}
|
|
||||||
return svc
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateSignedPostPolicyV4 generates a PostPolicyV4 value from bucket, object and opts.
|
|
||||||
// The generated URL and fields will then allow an unauthenticated client to perform multipart uploads.
|
|
||||||
// If initializing a Storage Client, instead use the Bucket.GenerateSignedPostPolicyV4
|
|
||||||
// method which uses the Client's credentials to handle authentication.
|
|
||||||
func GenerateSignedPostPolicyV4(bucket, object string, opts *PostPolicyV4Options) (*PostPolicyV4, error) {
|
|
||||||
if bucket == "" {
|
|
||||||
return nil, errors.New("storage: bucket must be non-empty")
|
|
||||||
}
|
|
||||||
if object == "" {
|
|
||||||
return nil, errors.New("storage: object must be non-empty")
|
|
||||||
}
|
|
||||||
now := utcNow()
|
|
||||||
if err := validatePostPolicyV4Options(opts, now); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var signingFn func(hashedBytes []byte) ([]byte, error)
|
|
||||||
switch {
|
|
||||||
case opts.SignRawBytes != nil:
|
|
||||||
signingFn = opts.SignRawBytes
|
|
||||||
case opts.shouldHashSignBytes:
|
|
||||||
signingFn = opts.SignBytes
|
|
||||||
case len(opts.PrivateKey) != 0:
|
|
||||||
parsedRSAPrivKey, err := parseKey(opts.PrivateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
signingFn = func(b []byte) ([]byte, error) {
|
|
||||||
sum := sha256.Sum256(b)
|
|
||||||
return rsa.SignPKCS1v15(rand.Reader, parsedRSAPrivKey, crypto.SHA256, sum[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, errors.New("storage: exactly one of PrivateKey or SignRawBytes must be set")
|
|
||||||
}
|
|
||||||
|
|
||||||
var descFields PolicyV4Fields
|
|
||||||
if opts.Fields != nil {
|
|
||||||
descFields = *opts.Fields
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := validateMetadata(descFields.Metadata); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the policy.
|
|
||||||
conds := make([]PostPolicyV4Condition, len(opts.Conditions))
|
|
||||||
copy(conds, opts.Conditions)
|
|
||||||
conds = append(conds,
|
|
||||||
// These are ordered lexicographically. Technically the order doesn't matter
|
|
||||||
// for creating the policy, but we use this order to match the
|
|
||||||
// cross-language conformance tests for this feature.
|
|
||||||
&singleValueCondition{"acl", descFields.ACL},
|
|
||||||
&singleValueCondition{"cache-control", descFields.CacheControl},
|
|
||||||
&singleValueCondition{"content-disposition", descFields.ContentDisposition},
|
|
||||||
&singleValueCondition{"content-encoding", descFields.ContentEncoding},
|
|
||||||
&singleValueCondition{"content-type", descFields.ContentType},
|
|
||||||
conditionRedirectToURLOnSuccess(descFields.RedirectToURLOnSuccess),
|
|
||||||
conditionStatusCodeOnSuccess(descFields.StatusCodeOnSuccess),
|
|
||||||
)
|
|
||||||
|
|
||||||
YYYYMMDD := now.Format(yearMonthDay)
|
|
||||||
policyFields := map[string]string{
|
|
||||||
"key": object,
|
|
||||||
"x-goog-date": now.Format(iso8601),
|
|
||||||
"x-goog-credential": opts.GoogleAccessID + "/" + YYYYMMDD + "/auto/storage/goog4_request",
|
|
||||||
"x-goog-algorithm": "GOOG4-RSA-SHA256",
|
|
||||||
"acl": descFields.ACL,
|
|
||||||
"cache-control": descFields.CacheControl,
|
|
||||||
"content-disposition": descFields.ContentDisposition,
|
|
||||||
"content-encoding": descFields.ContentEncoding,
|
|
||||||
"content-type": descFields.ContentType,
|
|
||||||
"success_action_redirect": descFields.RedirectToURLOnSuccess,
|
|
||||||
}
|
|
||||||
for key, value := range descFields.Metadata {
|
|
||||||
conds = append(conds, &singleValueCondition{key, value})
|
|
||||||
policyFields[key] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Following from the order expected by the conformance test cases,
|
|
||||||
// hence manually inserting these fields in a specific order.
|
|
||||||
conds = append(conds,
|
|
||||||
&singleValueCondition{"bucket", bucket},
|
|
||||||
&singleValueCondition{"key", object},
|
|
||||||
&singleValueCondition{"x-goog-date", now.Format(iso8601)},
|
|
||||||
&singleValueCondition{
|
|
||||||
name: "x-goog-credential",
|
|
||||||
value: opts.GoogleAccessID + "/" + YYYYMMDD + "/auto/storage/goog4_request",
|
|
||||||
},
|
|
||||||
&singleValueCondition{"x-goog-algorithm", "GOOG4-RSA-SHA256"},
|
|
||||||
)
|
|
||||||
|
|
||||||
nonEmptyConds := make([]PostPolicyV4Condition, 0, len(opts.Conditions))
|
|
||||||
for _, cond := range conds {
|
|
||||||
if cond == nil || !cond.isEmpty() {
|
|
||||||
nonEmptyConds = append(nonEmptyConds, cond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
condsAsJSON, err := json.Marshal(map[string]interface{}{
|
|
||||||
"conditions": nonEmptyConds,
|
|
||||||
"expiration": opts.Expires.Format(time.RFC3339),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("storage: PostPolicyV4 JSON serialization failed: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
b64Policy := base64.StdEncoding.EncodeToString(condsAsJSON)
|
|
||||||
var signature []byte
|
|
||||||
var signErr error
|
|
||||||
|
|
||||||
if opts.shouldHashSignBytes {
|
|
||||||
// SignBytes expects hashed bytes as input instead of raw bytes, so we hash them
|
|
||||||
shaSum := sha256.Sum256([]byte(b64Policy))
|
|
||||||
signature, signErr = signingFn(shaSum[:])
|
|
||||||
} else {
|
|
||||||
signature, signErr = signingFn([]byte(b64Policy))
|
|
||||||
}
|
|
||||||
if signErr != nil {
|
|
||||||
return nil, signErr
|
|
||||||
}
|
|
||||||
|
|
||||||
policyFields["policy"] = b64Policy
|
|
||||||
policyFields["x-goog-signature"] = fmt.Sprintf("%x", signature)
|
|
||||||
|
|
||||||
// Construct the URL.
|
|
||||||
scheme := "https"
|
|
||||||
if opts.Insecure {
|
|
||||||
scheme = "http"
|
|
||||||
}
|
|
||||||
path := opts.Style.path(bucket, "") + "/"
|
|
||||||
u := &url.URL{
|
|
||||||
Path: path,
|
|
||||||
RawPath: pathEncodeV4(path),
|
|
||||||
Host: opts.Style.host(bucket),
|
|
||||||
Scheme: scheme,
|
|
||||||
}
|
|
||||||
|
|
||||||
if descFields.StatusCodeOnSuccess > 0 {
|
|
||||||
policyFields["success_action_status"] = fmt.Sprintf("%d", descFields.StatusCodeOnSuccess)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear out fields with blanks values.
|
|
||||||
for key, value := range policyFields {
|
|
||||||
if value == "" {
|
|
||||||
delete(policyFields, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pp4 := &PostPolicyV4{
|
|
||||||
Fields: policyFields,
|
|
||||||
URL: u.String(),
|
|
||||||
}
|
|
||||||
return pp4, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// validatePostPolicyV4Options checks that:
|
|
||||||
// * GoogleAccessID is set
|
|
||||||
// * either PrivateKey or SignRawBytes/SignBytes is set, but not both
|
|
||||||
// * the deadline set in Expires is not in the past
|
|
||||||
// * if Style is not set, it'll use PathStyle
|
|
||||||
// * sets shouldHashSignBytes to true if opts.SignBytes should be used
|
|
||||||
func validatePostPolicyV4Options(opts *PostPolicyV4Options, now time.Time) error {
|
|
||||||
if opts == nil || opts.GoogleAccessID == "" {
|
|
||||||
return errors.New("storage: missing required GoogleAccessID")
|
|
||||||
}
|
|
||||||
if privBlank, signBlank := len(opts.PrivateKey) == 0, opts.SignBytes == nil && opts.SignRawBytes == nil; privBlank == signBlank {
|
|
||||||
return errors.New("storage: exactly one of PrivateKey or SignRawBytes must be set")
|
|
||||||
}
|
|
||||||
if opts.Expires.Before(now) {
|
|
||||||
return errors.New("storage: expecting Expires to be in the future")
|
|
||||||
}
|
|
||||||
if opts.Style == nil {
|
|
||||||
opts.Style = PathStyle()
|
|
||||||
}
|
|
||||||
if opts.SignRawBytes == nil && opts.SignBytes != nil {
|
|
||||||
opts.shouldHashSignBytes = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// validateMetadata ensures that all keys passed in have a prefix of "x-goog-meta-",
|
|
||||||
// otherwise it will return an error.
|
|
||||||
func validateMetadata(hdrs map[string]string) (err error) {
|
|
||||||
if len(hdrs) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
badKeys := make([]string, 0, len(hdrs))
|
|
||||||
for key := range hdrs {
|
|
||||||
if !strings.HasPrefix(key, "x-goog-meta-") {
|
|
||||||
badKeys = append(badKeys, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(badKeys) != 0 {
|
|
||||||
err = errors.New("storage: expected metadata to begin with x-goog-meta-, got " + strings.Join(badKeys, ", "))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
274
vendor/cloud.google.com/go/storage/reader.go
generated
vendored
274
vendor/cloud.google.com/go/storage/reader.go
generated
vendored
|
@ -1,274 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"hash/crc32"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
)
|
|
||||||
|
|
||||||
var crc32cTable = crc32.MakeTable(crc32.Castagnoli)
|
|
||||||
|
|
||||||
// ReaderObjectAttrs are attributes about the object being read. These are populated
|
|
||||||
// during the New call. This struct only holds a subset of object attributes: to
|
|
||||||
// get the full set of attributes, use ObjectHandle.Attrs.
|
|
||||||
//
|
|
||||||
// Each field is read-only.
|
|
||||||
type ReaderObjectAttrs struct {
|
|
||||||
// Size is the length of the object's content.
|
|
||||||
Size int64
|
|
||||||
|
|
||||||
// StartOffset is the byte offset within the object
|
|
||||||
// from which reading begins.
|
|
||||||
// This value is only non-zero for range requests.
|
|
||||||
StartOffset int64
|
|
||||||
|
|
||||||
// ContentType is the MIME type of the object's content.
|
|
||||||
ContentType string
|
|
||||||
|
|
||||||
// ContentEncoding is the encoding of the object's content.
|
|
||||||
ContentEncoding string
|
|
||||||
|
|
||||||
// CacheControl specifies whether and for how long browser and Internet
|
|
||||||
// caches are allowed to cache your objects.
|
|
||||||
CacheControl string
|
|
||||||
|
|
||||||
// LastModified is the time that the object was last modified.
|
|
||||||
LastModified time.Time
|
|
||||||
|
|
||||||
// Generation is the generation number of the object's content.
|
|
||||||
Generation int64
|
|
||||||
|
|
||||||
// Metageneration is the version of the metadata for this object at
|
|
||||||
// this generation. This field is used for preconditions and for
|
|
||||||
// detecting changes in metadata. A metageneration number is only
|
|
||||||
// meaningful in the context of a particular generation of a
|
|
||||||
// particular object.
|
|
||||||
Metageneration int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewReader creates a new Reader to read the contents of the
|
|
||||||
// object.
|
|
||||||
// ErrObjectNotExist will be returned if the object is not found.
|
|
||||||
//
|
|
||||||
// The caller must call Close on the returned Reader when done reading.
|
|
||||||
func (o *ObjectHandle) NewReader(ctx context.Context) (*Reader, error) {
|
|
||||||
return o.NewRangeReader(ctx, 0, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRangeReader reads part of an object, reading at most length bytes
|
|
||||||
// starting at the given offset. If length is negative, the object is read
|
|
||||||
// until the end. If offset is negative, the object is read abs(offset) bytes
|
|
||||||
// from the end, and length must also be negative to indicate all remaining
|
|
||||||
// bytes will be read.
|
|
||||||
//
|
|
||||||
// If the object's metadata property "Content-Encoding" is set to "gzip" or satisfies
|
|
||||||
// decompressive transcoding per https://cloud.google.com/storage/docs/transcoding
|
|
||||||
// that file will be served back whole, regardless of the requested range as
|
|
||||||
// Google Cloud Storage dictates.
|
|
||||||
func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64) (r *Reader, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Object.NewRangeReader")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if err := o.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if offset < 0 && length >= 0 {
|
|
||||||
return nil, fmt.Errorf("storage: invalid offset %d < 0 requires negative length", offset)
|
|
||||||
}
|
|
||||||
if o.conds != nil {
|
|
||||||
if err := o.conds.validate("NewRangeReader"); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := makeStorageOpts(true, o.retry, o.userProject)
|
|
||||||
|
|
||||||
params := &newRangeReaderParams{
|
|
||||||
bucket: o.bucket,
|
|
||||||
object: o.object,
|
|
||||||
gen: o.gen,
|
|
||||||
offset: offset,
|
|
||||||
length: length,
|
|
||||||
encryptionKey: o.encryptionKey,
|
|
||||||
conds: o.conds,
|
|
||||||
readCompressed: o.readCompressed,
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err = o.c.tc.NewRangeReader(ctx, params, opts...)
|
|
||||||
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// decompressiveTranscoding returns true if the request was served decompressed
|
|
||||||
// and different than its original storage form. This happens when the "Content-Encoding"
|
|
||||||
// header is "gzip".
|
|
||||||
// See:
|
|
||||||
// - https://cloud.google.com/storage/docs/transcoding#transcoding_and_gzip
|
|
||||||
// - https://github.com/googleapis/google-cloud-go/issues/1800
|
|
||||||
func decompressiveTranscoding(res *http.Response) bool {
|
|
||||||
// Decompressive Transcoding.
|
|
||||||
return res.Header.Get("Content-Encoding") == "gzip" ||
|
|
||||||
res.Header.Get("X-Goog-Stored-Content-Encoding") == "gzip"
|
|
||||||
}
|
|
||||||
|
|
||||||
func uncompressedByServer(res *http.Response) bool {
|
|
||||||
// If the data is stored as gzip but is not encoded as gzip, then it
|
|
||||||
// was uncompressed by the server.
|
|
||||||
return res.Header.Get("X-Goog-Stored-Content-Encoding") == "gzip" &&
|
|
||||||
res.Header.Get("Content-Encoding") != "gzip"
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseCRC32c parses the crc32c hash from the X-Goog-Hash header.
|
|
||||||
// It can parse headers in the form [crc32c=xxx md5=xxx] (XML responses) or the
|
|
||||||
// form [crc32c=xxx,md5=xxx] (JSON responses). The md5 hash is ignored.
|
|
||||||
func parseCRC32c(res *http.Response) (uint32, bool) {
|
|
||||||
const prefix = "crc32c="
|
|
||||||
for _, spec := range res.Header["X-Goog-Hash"] {
|
|
||||||
values := strings.Split(spec, ",")
|
|
||||||
|
|
||||||
for _, v := range values {
|
|
||||||
if strings.HasPrefix(v, prefix) {
|
|
||||||
c, err := decodeUint32(v[len(prefix):])
|
|
||||||
if err == nil {
|
|
||||||
return c, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// setConditionsHeaders sets precondition request headers for downloads
|
|
||||||
// using the XML API. It assumes that the conditions have been validated.
|
|
||||||
func setConditionsHeaders(headers http.Header, conds *Conditions) error {
|
|
||||||
if conds == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if conds.MetagenerationMatch != 0 {
|
|
||||||
headers.Set("x-goog-if-metageneration-match", fmt.Sprint(conds.MetagenerationMatch))
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case conds.GenerationMatch != 0:
|
|
||||||
headers.Set("x-goog-if-generation-match", fmt.Sprint(conds.GenerationMatch))
|
|
||||||
case conds.DoesNotExist:
|
|
||||||
headers.Set("x-goog-if-generation-match", "0")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap a request to look similar to an apiary library request, in order to
|
|
||||||
// be used by run().
|
|
||||||
type readerRequestWrapper struct {
|
|
||||||
req *http.Request
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *readerRequestWrapper) Header() http.Header {
|
|
||||||
return w.req.Header
|
|
||||||
}
|
|
||||||
|
|
||||||
var emptyBody = ioutil.NopCloser(strings.NewReader(""))
|
|
||||||
|
|
||||||
// Reader reads a Cloud Storage object.
|
|
||||||
// It implements io.Reader.
|
|
||||||
//
|
|
||||||
// Typically, a Reader computes the CRC of the downloaded content and compares it to
|
|
||||||
// the stored CRC, returning an error from Read if there is a mismatch. This integrity check
|
|
||||||
// is skipped if transcoding occurs. See https://cloud.google.com/storage/docs/transcoding.
|
|
||||||
type Reader struct {
|
|
||||||
Attrs ReaderObjectAttrs
|
|
||||||
seen, remain, size int64
|
|
||||||
checkCRC bool // should we check the CRC?
|
|
||||||
wantCRC uint32 // the CRC32c value the server sent in the header
|
|
||||||
gotCRC uint32 // running crc
|
|
||||||
|
|
||||||
reader io.ReadCloser
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the Reader. It must be called when done reading.
|
|
||||||
func (r *Reader) Close() error {
|
|
||||||
return r.reader.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Reader) Read(p []byte) (int, error) {
|
|
||||||
n, err := r.reader.Read(p)
|
|
||||||
if r.remain != -1 {
|
|
||||||
r.remain -= int64(n)
|
|
||||||
}
|
|
||||||
if r.checkCRC {
|
|
||||||
r.gotCRC = crc32.Update(r.gotCRC, crc32cTable, p[:n])
|
|
||||||
// Check CRC here. It would be natural to check it in Close, but
|
|
||||||
// everybody defers Close on the assumption that it doesn't return
|
|
||||||
// anything worth looking at.
|
|
||||||
if err == io.EOF {
|
|
||||||
if r.gotCRC != r.wantCRC {
|
|
||||||
return n, fmt.Errorf("storage: bad CRC on read: got %d, want %d",
|
|
||||||
r.gotCRC, r.wantCRC)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size returns the size of the object in bytes.
|
|
||||||
// The returned value is always the same and is not affected by
|
|
||||||
// calls to Read or Close.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.Size.
|
|
||||||
func (r *Reader) Size() int64 {
|
|
||||||
return r.Attrs.Size
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remain returns the number of bytes left to read, or -1 if unknown.
|
|
||||||
func (r *Reader) Remain() int64 {
|
|
||||||
return r.remain
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContentType returns the content type of the object.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.ContentType.
|
|
||||||
func (r *Reader) ContentType() string {
|
|
||||||
return r.Attrs.ContentType
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContentEncoding returns the content encoding of the object.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.ContentEncoding.
|
|
||||||
func (r *Reader) ContentEncoding() string {
|
|
||||||
return r.Attrs.ContentEncoding
|
|
||||||
}
|
|
||||||
|
|
||||||
// CacheControl returns the cache control of the object.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.CacheControl.
|
|
||||||
func (r *Reader) CacheControl() string {
|
|
||||||
return r.Attrs.CacheControl
|
|
||||||
}
|
|
||||||
|
|
||||||
// LastModified returns the value of the Last-Modified header.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.LastModified.
|
|
||||||
func (r *Reader) LastModified() (time.Time, error) {
|
|
||||||
return r.Attrs.LastModified, nil
|
|
||||||
}
|
|
2221
vendor/cloud.google.com/go/storage/storage.go
generated
vendored
2221
vendor/cloud.google.com/go/storage/storage.go
generated
vendored
File diff suppressed because it is too large
Load diff
30067
vendor/cloud.google.com/go/storage/storage.replay
generated
vendored
30067
vendor/cloud.google.com/go/storage/storage.replay
generated
vendored
File diff suppressed because one or more lines are too long
273
vendor/cloud.google.com/go/storage/writer.go
generated
vendored
273
vendor/cloud.google.com/go/storage/writer.go
generated
vendored
|
@ -1,273 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Writer writes a Cloud Storage object.
|
|
||||||
type Writer struct {
|
|
||||||
// ObjectAttrs are optional attributes to set on the object. Any attributes
|
|
||||||
// must be initialized before the first Write call. Nil or zero-valued
|
|
||||||
// attributes are ignored.
|
|
||||||
ObjectAttrs
|
|
||||||
|
|
||||||
// SendCRC32C specifies whether to transmit a CRC32C field. It should be set
|
|
||||||
// to true in addition to setting the Writer's CRC32C field, because zero
|
|
||||||
// is a valid CRC and normally a zero would not be transmitted.
|
|
||||||
// If a CRC32C is sent, and the data written does not match the checksum,
|
|
||||||
// the write will be rejected.
|
|
||||||
//
|
|
||||||
// Note: SendCRC32C must be set to true BEFORE the first call to
|
|
||||||
// Writer.Write() in order to send the checksum. If it is set after that
|
|
||||||
// point, the checksum will be ignored.
|
|
||||||
SendCRC32C bool
|
|
||||||
|
|
||||||
// ChunkSize controls the maximum number of bytes of the object that the
|
|
||||||
// Writer will attempt to send to the server in a single request. Objects
|
|
||||||
// smaller than the size will be sent in a single request, while larger
|
|
||||||
// objects will be split over multiple requests. The value will be rounded up
|
|
||||||
// to the nearest multiple of 256K. The default ChunkSize is 16MiB.
|
|
||||||
//
|
|
||||||
// Each Writer will internally allocate a buffer of size ChunkSize. This is
|
|
||||||
// used to buffer input data and allow for the input to be sent again if a
|
|
||||||
// request must be retried.
|
|
||||||
//
|
|
||||||
// If you upload small objects (< 16MiB), you should set ChunkSize
|
|
||||||
// to a value slightly larger than the objects' sizes to avoid memory bloat.
|
|
||||||
// This is especially important if you are uploading many small objects
|
|
||||||
// concurrently. See
|
|
||||||
// https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload#size
|
|
||||||
// for more information about performance trade-offs related to ChunkSize.
|
|
||||||
//
|
|
||||||
// If ChunkSize is set to zero, chunking will be disabled and the object will
|
|
||||||
// be uploaded in a single request without the use of a buffer. This will
|
|
||||||
// further reduce memory used during uploads, but will also prevent the writer
|
|
||||||
// from retrying in case of a transient error from the server or resuming an
|
|
||||||
// upload that fails midway through, since the buffer is required in order to
|
|
||||||
// retry the failed request.
|
|
||||||
//
|
|
||||||
// ChunkSize must be set before the first Write call.
|
|
||||||
ChunkSize int
|
|
||||||
|
|
||||||
// ChunkRetryDeadline sets a per-chunk retry deadline for multi-chunk
|
|
||||||
// resumable uploads.
|
|
||||||
//
|
|
||||||
// For uploads of larger files, the Writer will attempt to retry if the
|
|
||||||
// request to upload a particular chunk fails with a transient error.
|
|
||||||
// If a single chunk has been attempting to upload for longer than this
|
|
||||||
// deadline and the request fails, it will no longer be retried, and the error
|
|
||||||
// will be returned to the caller. This is only applicable for files which are
|
|
||||||
// large enough to require a multi-chunk resumable upload. The default value
|
|
||||||
// is 32s. Users may want to pick a longer deadline if they are using larger
|
|
||||||
// values for ChunkSize or if they expect to have a slow or unreliable
|
|
||||||
// internet connection.
|
|
||||||
//
|
|
||||||
// To set a deadline on the entire upload, use context timeout or
|
|
||||||
// cancellation.
|
|
||||||
ChunkRetryDeadline time.Duration
|
|
||||||
|
|
||||||
// ProgressFunc can be used to monitor the progress of a large write.
|
|
||||||
// operation. If ProgressFunc is not nil and writing requires multiple
|
|
||||||
// calls to the underlying service (see
|
|
||||||
// https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload),
|
|
||||||
// then ProgressFunc will be invoked after each call with the number of bytes of
|
|
||||||
// content copied so far.
|
|
||||||
//
|
|
||||||
// ProgressFunc should return quickly without blocking.
|
|
||||||
ProgressFunc func(int64)
|
|
||||||
|
|
||||||
ctx context.Context
|
|
||||||
o *ObjectHandle
|
|
||||||
|
|
||||||
opened bool
|
|
||||||
pw *io.PipeWriter
|
|
||||||
|
|
||||||
donec chan struct{} // closed after err and obj are set.
|
|
||||||
obj *ObjectAttrs
|
|
||||||
|
|
||||||
mu sync.Mutex
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write appends to w. It implements the io.Writer interface.
|
|
||||||
//
|
|
||||||
// Since writes happen asynchronously, Write may return a nil
|
|
||||||
// error even though the write failed (or will fail). Always
|
|
||||||
// use the error returned from Writer.Close to determine if
|
|
||||||
// the upload was successful.
|
|
||||||
//
|
|
||||||
// Writes will be retried on transient errors from the server, unless
|
|
||||||
// Writer.ChunkSize has been set to zero.
|
|
||||||
func (w *Writer) Write(p []byte) (n int, err error) {
|
|
||||||
w.mu.Lock()
|
|
||||||
werr := w.err
|
|
||||||
w.mu.Unlock()
|
|
||||||
if werr != nil {
|
|
||||||
return 0, werr
|
|
||||||
}
|
|
||||||
if !w.opened {
|
|
||||||
if err := w.openWriter(); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n, err = w.pw.Write(p)
|
|
||||||
if err != nil {
|
|
||||||
w.mu.Lock()
|
|
||||||
werr := w.err
|
|
||||||
w.mu.Unlock()
|
|
||||||
// Preserve existing functionality that when context is canceled, Write will return
|
|
||||||
// context.Canceled instead of "io: read/write on closed pipe". This hides the
|
|
||||||
// pipe implementation detail from users and makes Write seem as though it's an RPC.
|
|
||||||
if errors.Is(werr, context.Canceled) || errors.Is(werr, context.DeadlineExceeded) {
|
|
||||||
return n, werr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close completes the write operation and flushes any buffered data.
|
|
||||||
// If Close doesn't return an error, metadata about the written object
|
|
||||||
// can be retrieved by calling Attrs.
|
|
||||||
func (w *Writer) Close() error {
|
|
||||||
if !w.opened {
|
|
||||||
if err := w.openWriter(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closing either the read or write causes the entire pipe to close.
|
|
||||||
if err := w.pw.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
<-w.donec
|
|
||||||
w.mu.Lock()
|
|
||||||
defer w.mu.Unlock()
|
|
||||||
return w.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Writer) openWriter() (err error) {
|
|
||||||
if err := w.validateWriteAttrs(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if w.o.gen != defaultGen {
|
|
||||||
return fmt.Errorf("storage: generation not supported on Writer, got %v", w.o.gen)
|
|
||||||
}
|
|
||||||
|
|
||||||
isIdempotent := w.o.conds != nil && (w.o.conds.GenerationMatch >= 0 || w.o.conds.DoesNotExist == true)
|
|
||||||
opts := makeStorageOpts(isIdempotent, w.o.retry, w.o.userProject)
|
|
||||||
params := &openWriterParams{
|
|
||||||
ctx: w.ctx,
|
|
||||||
chunkSize: w.ChunkSize,
|
|
||||||
chunkRetryDeadline: w.ChunkRetryDeadline,
|
|
||||||
bucket: w.o.bucket,
|
|
||||||
attrs: &w.ObjectAttrs,
|
|
||||||
conds: w.o.conds,
|
|
||||||
encryptionKey: w.o.encryptionKey,
|
|
||||||
sendCRC32C: w.SendCRC32C,
|
|
||||||
donec: w.donec,
|
|
||||||
setError: w.error,
|
|
||||||
progress: w.progress,
|
|
||||||
setObj: func(o *ObjectAttrs) { w.obj = o },
|
|
||||||
}
|
|
||||||
if err := w.ctx.Err(); err != nil {
|
|
||||||
return err // short-circuit
|
|
||||||
}
|
|
||||||
w.pw, err = w.o.c.tc.OpenWriter(params, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.opened = true
|
|
||||||
go w.monitorCancel()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// monitorCancel is intended to be used as a background goroutine. It monitors the
|
|
||||||
// context, and when it observes that the context has been canceled, it manually
|
|
||||||
// closes things that do not take a context.
|
|
||||||
func (w *Writer) monitorCancel() {
|
|
||||||
select {
|
|
||||||
case <-w.ctx.Done():
|
|
||||||
w.mu.Lock()
|
|
||||||
werr := w.ctx.Err()
|
|
||||||
w.err = werr
|
|
||||||
w.mu.Unlock()
|
|
||||||
|
|
||||||
// Closing either the read or write causes the entire pipe to close.
|
|
||||||
w.CloseWithError(werr)
|
|
||||||
case <-w.donec:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseWithError aborts the write operation with the provided error.
|
|
||||||
// CloseWithError always returns nil.
|
|
||||||
//
|
|
||||||
// Deprecated: cancel the context passed to NewWriter instead.
|
|
||||||
func (w *Writer) CloseWithError(err error) error {
|
|
||||||
if !w.opened {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return w.pw.CloseWithError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attrs returns metadata about a successfully-written object.
|
|
||||||
// It's only valid to call it after Close returns nil.
|
|
||||||
func (w *Writer) Attrs() *ObjectAttrs {
|
|
||||||
return w.obj
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Writer) validateWriteAttrs() error {
|
|
||||||
attrs := w.ObjectAttrs
|
|
||||||
// Check the developer didn't change the object Name (this is unfortunate, but
|
|
||||||
// we don't want to store an object under the wrong name).
|
|
||||||
if attrs.Name != w.o.object {
|
|
||||||
return fmt.Errorf("storage: Writer.Name %q does not match object name %q", attrs.Name, w.o.object)
|
|
||||||
}
|
|
||||||
if !utf8.ValidString(attrs.Name) {
|
|
||||||
return fmt.Errorf("storage: object name %q is not valid UTF-8", attrs.Name)
|
|
||||||
}
|
|
||||||
if attrs.KMSKeyName != "" && w.o.encryptionKey != nil {
|
|
||||||
return errors.New("storage: cannot use KMSKeyName with a customer-supplied encryption key")
|
|
||||||
}
|
|
||||||
if w.ChunkSize < 0 {
|
|
||||||
return errors.New("storage: Writer.ChunkSize must be non-negative")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// progress is a convenience wrapper that reports write progress to the Writer
|
|
||||||
// ProgressFunc if it is set and progress is non-zero.
|
|
||||||
func (w *Writer) progress(p int64) {
|
|
||||||
if w.ProgressFunc != nil && p != 0 {
|
|
||||||
w.ProgressFunc(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// error acquires the Writer's lock, sets the Writer's err to the given error,
|
|
||||||
// then relinquishes the lock.
|
|
||||||
func (w *Writer) error(err error) {
|
|
||||||
w.mu.Lock()
|
|
||||||
w.err = err
|
|
||||||
w.mu.Unlock()
|
|
||||||
}
|
|
201
vendor/github.com/AdaLogics/go-fuzz-headers/LICENSE
generated
vendored
201
vendor/github.com/AdaLogics/go-fuzz-headers/LICENSE
generated
vendored
|
@ -1,201 +0,0 @@
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
93
vendor/github.com/AdaLogics/go-fuzz-headers/README.md
generated
vendored
93
vendor/github.com/AdaLogics/go-fuzz-headers/README.md
generated
vendored
|
@ -1,93 +0,0 @@
|
||||||
# go-fuzz-headers
|
|
||||||
This repository contains various helper functions for go fuzzing. It is mostly used in combination with [go-fuzz](https://github.com/dvyukov/go-fuzz), but compatibility with fuzzing in the standard library will also be supported. Any coverage guided fuzzing engine that provides an array or slice of bytes can be used with go-fuzz-headers.
|
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
Using go-fuzz-headers is easy. First create a new consumer with the bytes provided by the fuzzing engine:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
|
||||||
)
|
|
||||||
data := []byte{'R', 'a', 'n', 'd', 'o', 'm'}
|
|
||||||
f := fuzz.NewConsumer(data)
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
This creates a `Consumer` that consumes the bytes of the input as it uses them to fuzz different types.
|
|
||||||
|
|
||||||
After that, `f` can be used to easily create fuzzed instances of different types. Below are some examples:
|
|
||||||
|
|
||||||
### Structs
|
|
||||||
One of the most useful features of go-fuzz-headers is its ability to fill structs with the data provided by the fuzzing engine. This is done with a single line:
|
|
||||||
```go
|
|
||||||
type Person struct {
|
|
||||||
Name string
|
|
||||||
Age int
|
|
||||||
}
|
|
||||||
p := Person{}
|
|
||||||
// Fill p with values based on the data provided by the fuzzing engine:
|
|
||||||
err := f.GenerateStruct(&p)
|
|
||||||
```
|
|
||||||
|
|
||||||
This includes nested structs too. In this example, the fuzz Consumer will also insert values in `p.BestFriend`:
|
|
||||||
```go
|
|
||||||
type PersonI struct {
|
|
||||||
Name string
|
|
||||||
Age int
|
|
||||||
BestFriend PersonII
|
|
||||||
}
|
|
||||||
type PersonII struct {
|
|
||||||
Name string
|
|
||||||
Age int
|
|
||||||
}
|
|
||||||
p := PersonI{}
|
|
||||||
err := f.GenerateStruct(&p)
|
|
||||||
```
|
|
||||||
|
|
||||||
If the consumer should insert values for unexported fields as well as exported, this can be enabled with:
|
|
||||||
|
|
||||||
```go
|
|
||||||
f.AllowUnexportedFields()
|
|
||||||
```
|
|
||||||
|
|
||||||
...and disabled with:
|
|
||||||
|
|
||||||
```go
|
|
||||||
f.DisallowUnexportedFields()
|
|
||||||
```
|
|
||||||
|
|
||||||
### Other types:
|
|
||||||
|
|
||||||
Other useful APIs:
|
|
||||||
|
|
||||||
```go
|
|
||||||
createdString, err := f.GetString() // Gets a string
|
|
||||||
createdInt, err := f.GetInt() // Gets an integer
|
|
||||||
createdByte, err := f.GetByte() // Gets a byte
|
|
||||||
createdBytes, err := f.GetBytes() // Gets a byte slice
|
|
||||||
createdBool, err := f.GetBool() // Gets a boolean
|
|
||||||
err := f.FuzzMap(target_map) // Fills a map
|
|
||||||
createdTarBytes, err := f.TarBytes() // Gets bytes of a valid tar archive
|
|
||||||
err := f.CreateFiles(inThisDir) // Fills inThisDir with files
|
|
||||||
createdString, err := f.GetStringFrom("anyCharInThisString", ofThisLength) // Gets a string that consists of chars from "anyCharInThisString" and has the exact length "ofThisLength"
|
|
||||||
```
|
|
||||||
|
|
||||||
Most APIs are added as they are needed.
|
|
||||||
|
|
||||||
## Projects that use go-fuzz-headers
|
|
||||||
- [runC](https://github.com/opencontainers/runc)
|
|
||||||
- [Istio](https://github.com/istio/istio)
|
|
||||||
- [Vitess](https://github.com/vitessio/vitess)
|
|
||||||
- [Containerd](https://github.com/containerd/containerd)
|
|
||||||
|
|
||||||
Feel free to add your own project to the list, if you use go-fuzz-headers to fuzz it.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Status
|
|
||||||
The project is under development and will be updated regularly.
|
|
||||||
|
|
||||||
## References
|
|
||||||
go-fuzz-headers' approach to fuzzing structs is strongly inspired by [gofuzz](https://github.com/google/gofuzz).
|
|
932
vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go
generated
vendored
932
vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go
generated
vendored
|
@ -1,932 +0,0 @@
|
||||||
package gofuzzheaders
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/tar"
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"math"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
securejoin "github.com/cyphar/filepath-securejoin"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
MaxTotalLen = uint32(2000000)
|
|
||||||
)
|
|
||||||
|
|
||||||
func SetMaxTotalLen(newLen uint32) {
|
|
||||||
MaxTotalLen = newLen
|
|
||||||
}
|
|
||||||
|
|
||||||
type ConsumeFuzzer struct {
|
|
||||||
data []byte
|
|
||||||
CommandPart []byte
|
|
||||||
RestOfArray []byte
|
|
||||||
NumberOfCalls int
|
|
||||||
position uint32
|
|
||||||
fuzzUnexportedFields bool
|
|
||||||
Funcs map[reflect.Type]reflect.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsDivisibleBy(n int, divisibleby int) bool {
|
|
||||||
return (n % divisibleby) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewConsumer(fuzzData []byte) *ConsumeFuzzer {
|
|
||||||
fuzzMap := make(map[reflect.Type]reflect.Value)
|
|
||||||
f := &ConsumeFuzzer{data: fuzzData, position: 0, Funcs: fuzzMap}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) Split(minCalls, maxCalls int) error {
|
|
||||||
if len(f.data) == 0 {
|
|
||||||
return errors.New("Could not split")
|
|
||||||
}
|
|
||||||
numberOfCalls := int(f.data[0])
|
|
||||||
if numberOfCalls < minCalls || numberOfCalls > maxCalls {
|
|
||||||
return errors.New("Bad number of calls")
|
|
||||||
|
|
||||||
}
|
|
||||||
if len(f.data) < numberOfCalls+numberOfCalls+1 {
|
|
||||||
return errors.New("Length of data does not match required parameters")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define part 2 and 3 of the data array
|
|
||||||
commandPart := f.data[1 : numberOfCalls+1]
|
|
||||||
restOfArray := f.data[numberOfCalls+1:]
|
|
||||||
|
|
||||||
// Just a small check. It is necessary
|
|
||||||
if len(commandPart) != numberOfCalls {
|
|
||||||
return errors.New("Length of commandPart does not match number of calls")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if restOfArray is divisible by numberOfCalls
|
|
||||||
if !IsDivisibleBy(len(restOfArray), numberOfCalls) {
|
|
||||||
return errors.New("Length of commandPart does not match number of calls")
|
|
||||||
}
|
|
||||||
f.CommandPart = commandPart
|
|
||||||
f.RestOfArray = restOfArray
|
|
||||||
f.NumberOfCalls = numberOfCalls
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) AllowUnexportedFields() {
|
|
||||||
f.fuzzUnexportedFields = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) DisallowUnexportedFields() {
|
|
||||||
f.fuzzUnexportedFields = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GenerateStruct(targetStruct interface{}) error {
|
|
||||||
v := reflect.ValueOf(targetStruct)
|
|
||||||
/*if !v.CanSet() {
|
|
||||||
return errors.New("This interface cannot be set")
|
|
||||||
}*/
|
|
||||||
e := v.Elem()
|
|
||||||
err := f.fuzzStruct(e, false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) setCustom(v reflect.Value) error {
|
|
||||||
// First: see if we have a fuzz function for it.
|
|
||||||
doCustom, ok := f.Funcs[v.Type()]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Could not find a custom function")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Ptr:
|
|
||||||
if v.IsNil() {
|
|
||||||
if !v.CanSet() {
|
|
||||||
return fmt.Errorf("Could not use a custom function")
|
|
||||||
}
|
|
||||||
v.Set(reflect.New(v.Type().Elem()))
|
|
||||||
}
|
|
||||||
case reflect.Map:
|
|
||||||
if v.IsNil() {
|
|
||||||
if !v.CanSet() {
|
|
||||||
return fmt.Errorf("Could not use a custom function")
|
|
||||||
}
|
|
||||||
v.Set(reflect.MakeMap(v.Type()))
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Could not use a custom function")
|
|
||||||
}
|
|
||||||
|
|
||||||
verr := doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{
|
|
||||||
F: f,
|
|
||||||
})})
|
|
||||||
// check if we return an error
|
|
||||||
if verr[0].IsNil() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Could not use a custom function")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error {
|
|
||||||
|
|
||||||
// We check if we should check for custom functions
|
|
||||||
if customFunctions {
|
|
||||||
if e.IsValid() {
|
|
||||||
if e.CanAddr() {
|
|
||||||
err := f.setCustom(e.Addr())
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* return f.setCustom(e)
|
|
||||||
_, ok := f.Funcs[e.Type()]
|
|
||||||
if ok {
|
|
||||||
if e.CanAddr() {
|
|
||||||
err := f.setCustom(e.Addr())
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
//return f.setCustom(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch e.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
for i := 0; i < e.NumField(); i++ {
|
|
||||||
var v reflect.Value
|
|
||||||
if !e.Field(i).CanSet() {
|
|
||||||
if f.fuzzUnexportedFields {
|
|
||||||
v = reflect.NewAt(e.Field(i).Type(), unsafe.Pointer(e.Field(i).UnsafeAddr())).Elem()
|
|
||||||
}
|
|
||||||
err := f.fuzzStruct(v, customFunctions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*if e.Field(i).Kind() == reflect.Struct {
|
|
||||||
//e = reflect.NewAt(e.Type(), unsafe.Pointer(e.UnsafeAddr())).Elem()
|
|
||||||
//e.Field(i).Set(reflect.New(e.Field(i).Type()))
|
|
||||||
}*/
|
|
||||||
v = e.Field(i)
|
|
||||||
//v = reflect.New(e.Field(i).Type())
|
|
||||||
err := f.fuzzStruct(v, customFunctions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
/*if e.Field(i).CanSet() {
|
|
||||||
e.Field(i).Set(v.Elem())
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.String:
|
|
||||||
str, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.SetString(str)
|
|
||||||
}
|
|
||||||
case reflect.Slice:
|
|
||||||
var maxElements uint32
|
|
||||||
// Byte slices should not be restricted
|
|
||||||
if e.Type().String() == "[]uint8" {
|
|
||||||
maxElements = 10000000
|
|
||||||
} else {
|
|
||||||
maxElements = 50
|
|
||||||
}
|
|
||||||
|
|
||||||
randQty, err := f.GetUint32()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var numOfElements uint32
|
|
||||||
numOfElements = randQty % maxElements
|
|
||||||
if (uint32(len(f.data)) - f.position) < numOfElements {
|
|
||||||
numOfElements = uint32(len(f.data)) - f.position
|
|
||||||
}
|
|
||||||
|
|
||||||
uu := reflect.MakeSlice(e.Type(), int(numOfElements), int(numOfElements))
|
|
||||||
|
|
||||||
for i := 0; i < int(numOfElements); i++ {
|
|
||||||
err := f.fuzzStruct(uu.Index(i), customFunctions)
|
|
||||||
// If we have more than 10, then we can proceed with that.
|
|
||||||
if err != nil {
|
|
||||||
if i >= 10 {
|
|
||||||
if e.CanSet() {
|
|
||||||
e.Set(uu)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.Set(uu)
|
|
||||||
}
|
|
||||||
case reflect.Uint16:
|
|
||||||
newInt, err := f.GetUint16()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.SetUint(uint64(newInt))
|
|
||||||
}
|
|
||||||
case reflect.Uint32:
|
|
||||||
newInt, err := f.GetUint32()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.SetUint(uint64(newInt))
|
|
||||||
}
|
|
||||||
case reflect.Uint64:
|
|
||||||
newInt, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.SetUint(uint64(newInt))
|
|
||||||
}
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
newInt, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.SetInt(int64(newInt))
|
|
||||||
}
|
|
||||||
case reflect.Float32:
|
|
||||||
newFloat, err := f.GetFloat32()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.SetFloat(float64(newFloat))
|
|
||||||
}
|
|
||||||
case reflect.Float64:
|
|
||||||
newFloat, err := f.GetFloat64()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.SetFloat(float64(newFloat))
|
|
||||||
}
|
|
||||||
case reflect.Map:
|
|
||||||
if e.CanSet() {
|
|
||||||
e.Set(reflect.MakeMap(e.Type()))
|
|
||||||
maxElements := 50
|
|
||||||
randQty, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
numOfElements := randQty % maxElements
|
|
||||||
for i := 0; i < numOfElements; i++ {
|
|
||||||
key := reflect.New(e.Type().Key()).Elem()
|
|
||||||
err := f.fuzzStruct(key, customFunctions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
val := reflect.New(e.Type().Elem()).Elem()
|
|
||||||
err = f.fuzzStruct(val, customFunctions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
e.SetMapIndex(key, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Ptr:
|
|
||||||
if e.CanSet() {
|
|
||||||
e.Set(reflect.New(e.Type().Elem()))
|
|
||||||
err := f.fuzzStruct(e.Elem(), customFunctions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
case reflect.Uint8:
|
|
||||||
b, err := f.GetByte()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.CanSet() {
|
|
||||||
e.SetUint(uint64(b))
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetStringArray() (reflect.Value, error) {
|
|
||||||
// The max size of the array:
|
|
||||||
max := uint32(20)
|
|
||||||
|
|
||||||
arraySize := f.position
|
|
||||||
if arraySize > max {
|
|
||||||
arraySize = max
|
|
||||||
}
|
|
||||||
elemType := reflect.TypeOf("string")
|
|
||||||
stringArray := reflect.MakeSlice(reflect.SliceOf(elemType), int(arraySize), int(arraySize))
|
|
||||||
if f.position+arraySize >= uint32(len(f.data)) {
|
|
||||||
return stringArray, errors.New("Could not make string array")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < int(arraySize); i++ {
|
|
||||||
stringSize := uint32(f.data[f.position])
|
|
||||||
|
|
||||||
if f.position+stringSize >= uint32(len(f.data)) {
|
|
||||||
return stringArray, nil
|
|
||||||
}
|
|
||||||
stringToAppend := string(f.data[f.position : f.position+stringSize])
|
|
||||||
strVal := reflect.ValueOf(stringToAppend)
|
|
||||||
stringArray = reflect.Append(stringArray, strVal)
|
|
||||||
f.position = f.position + stringSize
|
|
||||||
}
|
|
||||||
return stringArray, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetInt() (int, error) {
|
|
||||||
if f.position >= uint32(len(f.data)) {
|
|
||||||
return 0, errors.New("Not enough bytes to create int")
|
|
||||||
}
|
|
||||||
returnInt := int(f.data[f.position])
|
|
||||||
f.position++
|
|
||||||
return returnInt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetByte() (byte, error) {
|
|
||||||
if len(f.data) == 0 {
|
|
||||||
return 0x00, errors.New("Not enough bytes to get byte")
|
|
||||||
}
|
|
||||||
if f.position >= uint32(len(f.data)) {
|
|
||||||
return 0x00, errors.New("Not enough bytes to get byte")
|
|
||||||
}
|
|
||||||
returnByte := f.data[f.position]
|
|
||||||
f.position += 1
|
|
||||||
return returnByte, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetNBytes(numberOfBytes int) ([]byte, error) {
|
|
||||||
returnBytes := make([]byte, 0)
|
|
||||||
if len(f.data) == 0 {
|
|
||||||
return returnBytes, errors.New("Not enough bytes to get byte")
|
|
||||||
}
|
|
||||||
if f.position >= uint32(len(f.data)) {
|
|
||||||
return returnBytes, errors.New("Not enough bytes to get byte")
|
|
||||||
}
|
|
||||||
for i := 0; i < numberOfBytes; i++ {
|
|
||||||
newByte, err := f.GetByte()
|
|
||||||
if err != nil {
|
|
||||||
return returnBytes, err
|
|
||||||
}
|
|
||||||
returnBytes = append(returnBytes, newByte)
|
|
||||||
}
|
|
||||||
return returnBytes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetUint16() (uint16, error) {
|
|
||||||
u16, err := f.GetNBytes(2)
|
|
||||||
if err != nil {
|
|
||||||
return uint16(0), err
|
|
||||||
}
|
|
||||||
littleEndian, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
return uint16(0), err
|
|
||||||
}
|
|
||||||
if littleEndian {
|
|
||||||
u16LE := binary.LittleEndian.Uint16(u16)
|
|
||||||
return u16LE, nil
|
|
||||||
}
|
|
||||||
u16BE := binary.BigEndian.Uint16(u16)
|
|
||||||
return u16BE, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetUint32() (uint32, error) {
|
|
||||||
u32, err := f.GetNBytes(4)
|
|
||||||
if err != nil {
|
|
||||||
return uint32(0), err
|
|
||||||
}
|
|
||||||
littleEndian, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
return uint32(0), err
|
|
||||||
}
|
|
||||||
if littleEndian {
|
|
||||||
u32LE := binary.LittleEndian.Uint32(u32)
|
|
||||||
return u32LE, nil
|
|
||||||
}
|
|
||||||
u32BE := binary.BigEndian.Uint32(u32)
|
|
||||||
return u32BE, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetUint64() (uint64, error) {
|
|
||||||
u64, err := f.GetNBytes(8)
|
|
||||||
if err != nil {
|
|
||||||
return uint64(0), err
|
|
||||||
}
|
|
||||||
littleEndian, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
return uint64(0), err
|
|
||||||
}
|
|
||||||
if littleEndian {
|
|
||||||
u64LE := binary.LittleEndian.Uint64(u64)
|
|
||||||
return u64LE, nil
|
|
||||||
}
|
|
||||||
u64BE := binary.BigEndian.Uint64(u64)
|
|
||||||
return u64BE, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetBytes() ([]byte, error) {
|
|
||||||
if len(f.data) == 0 || f.position >= uint32(len(f.data)) {
|
|
||||||
return nil, errors.New("Not enough bytes to create byte array")
|
|
||||||
}
|
|
||||||
length, err := f.GetUint32()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("Not enough bytes to create byte array")
|
|
||||||
}
|
|
||||||
if f.position+length > MaxTotalLen {
|
|
||||||
return nil, errors.New("Created too large a string")
|
|
||||||
}
|
|
||||||
byteBegin := f.position - 1
|
|
||||||
if byteBegin >= uint32(len(f.data)) {
|
|
||||||
return nil, errors.New("Not enough bytes to create byte array")
|
|
||||||
}
|
|
||||||
if length == 0 {
|
|
||||||
return nil, errors.New("Zero-length is not supported")
|
|
||||||
}
|
|
||||||
if byteBegin+length >= uint32(len(f.data)) {
|
|
||||||
return nil, errors.New("Not enough bytes to create byte array")
|
|
||||||
}
|
|
||||||
if byteBegin+length < byteBegin {
|
|
||||||
return nil, errors.New("Nunmbers overflow. Returning")
|
|
||||||
}
|
|
||||||
b := f.data[byteBegin : byteBegin+length]
|
|
||||||
f.position = byteBegin + length
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetString() (string, error) {
|
|
||||||
if f.position >= uint32(len(f.data)) {
|
|
||||||
return "nil", errors.New("Not enough bytes to create string")
|
|
||||||
}
|
|
||||||
length, err := f.GetUint32()
|
|
||||||
if err != nil {
|
|
||||||
return "nil", errors.New("Not enough bytes to create string")
|
|
||||||
}
|
|
||||||
if f.position > MaxTotalLen {
|
|
||||||
return "nil", errors.New("Created too large a string")
|
|
||||||
}
|
|
||||||
byteBegin := f.position - 1
|
|
||||||
if byteBegin >= uint32(len(f.data)) {
|
|
||||||
return "nil", errors.New("Not enough bytes to create string")
|
|
||||||
}
|
|
||||||
if byteBegin+length > uint32(len(f.data)) {
|
|
||||||
return "nil", errors.New("Not enough bytes to create string")
|
|
||||||
}
|
|
||||||
if byteBegin > byteBegin+length {
|
|
||||||
return "nil", errors.New("Numbers overflow. Returning")
|
|
||||||
}
|
|
||||||
str := string(f.data[byteBegin : byteBegin+length])
|
|
||||||
f.position = byteBegin + length
|
|
||||||
return str, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetBool() (bool, error) {
|
|
||||||
if f.position >= uint32(len(f.data)) {
|
|
||||||
return false, errors.New("Not enough bytes to create bool")
|
|
||||||
}
|
|
||||||
if IsDivisibleBy(int(f.data[f.position]), 2) {
|
|
||||||
f.position++
|
|
||||||
return true, nil
|
|
||||||
} else {
|
|
||||||
f.position++
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) FuzzMap(m interface{}) error {
|
|
||||||
err := f.GenerateStruct(m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func returnTarBytes(buf []byte) ([]byte, error) {
|
|
||||||
reader := bytes.NewReader(buf)
|
|
||||||
tr := tar.NewReader(reader)
|
|
||||||
|
|
||||||
// Count files
|
|
||||||
var fileCounter int
|
|
||||||
fileCounter = 0
|
|
||||||
for {
|
|
||||||
_, err := tr.Next()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fileCounter++
|
|
||||||
}
|
|
||||||
if fileCounter > 4 {
|
|
||||||
return buf, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("Not enough files were created\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func setTarHeaderFormat(hdr *tar.Header, f *ConsumeFuzzer) error {
|
|
||||||
ind, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch ind % 4 {
|
|
||||||
case 0:
|
|
||||||
hdr.Format = tar.FormatUnknown
|
|
||||||
case 1:
|
|
||||||
hdr.Format = tar.FormatUSTAR
|
|
||||||
case 2:
|
|
||||||
hdr.Format = tar.FormatPAX
|
|
||||||
case 3:
|
|
||||||
hdr.Format = tar.FormatGNU
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setTarHeaderTypeflag(hdr *tar.Header, f *ConsumeFuzzer) error {
|
|
||||||
ind, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch ind % 13 {
|
|
||||||
case 0:
|
|
||||||
hdr.Typeflag = tar.TypeReg
|
|
||||||
case 1:
|
|
||||||
hdr.Typeflag = tar.TypeLink
|
|
||||||
linkname, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hdr.Linkname = linkname
|
|
||||||
case 2:
|
|
||||||
hdr.Typeflag = tar.TypeSymlink
|
|
||||||
linkname, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hdr.Linkname = linkname
|
|
||||||
case 3:
|
|
||||||
hdr.Typeflag = tar.TypeChar
|
|
||||||
case 4:
|
|
||||||
hdr.Typeflag = tar.TypeBlock
|
|
||||||
case 5:
|
|
||||||
hdr.Typeflag = tar.TypeDir
|
|
||||||
case 6:
|
|
||||||
hdr.Typeflag = tar.TypeFifo
|
|
||||||
case 7:
|
|
||||||
hdr.Typeflag = tar.TypeCont
|
|
||||||
case 8:
|
|
||||||
hdr.Typeflag = tar.TypeXHeader
|
|
||||||
case 9:
|
|
||||||
hdr.Typeflag = tar.TypeXGlobalHeader
|
|
||||||
case 10:
|
|
||||||
hdr.Typeflag = tar.TypeGNUSparse
|
|
||||||
case 11:
|
|
||||||
hdr.Typeflag = tar.TypeGNULongName
|
|
||||||
case 12:
|
|
||||||
hdr.Typeflag = tar.TypeGNULongLink
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) createTarFileBody() ([]byte, error) {
|
|
||||||
if len(f.data) == 0 || f.position >= uint32(len(f.data)) {
|
|
||||||
return nil, errors.New("Not enough bytes to create byte array")
|
|
||||||
}
|
|
||||||
length, err := f.GetUint32()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("Not enough bytes to create byte array")
|
|
||||||
}
|
|
||||||
|
|
||||||
// A bit of optimization to attempt to create a file body
|
|
||||||
// when we don't have as many bytes left as "length"
|
|
||||||
remainingBytes := (uint32(len(f.data)) - f.position)
|
|
||||||
totalDataLen := uint32(len(f.data))
|
|
||||||
if uint32(len(f.data))-f.position < 50 {
|
|
||||||
if remainingBytes == 0 {
|
|
||||||
return nil, errors.New("Created too large a string")
|
|
||||||
}
|
|
||||||
length = length % remainingBytes
|
|
||||||
} else if len(f.data) < 500 {
|
|
||||||
if totalDataLen == 0 {
|
|
||||||
return nil, errors.New("Created too large a string")
|
|
||||||
}
|
|
||||||
length = length % totalDataLen
|
|
||||||
}
|
|
||||||
if f.position+length > MaxTotalLen {
|
|
||||||
return nil, errors.New("Created too large a string")
|
|
||||||
}
|
|
||||||
byteBegin := f.position - 1
|
|
||||||
if byteBegin >= uint32(len(f.data)) {
|
|
||||||
return nil, errors.New("Not enough bytes to create byte array")
|
|
||||||
}
|
|
||||||
if length == 0 {
|
|
||||||
return nil, errors.New("Zero-length is not supported")
|
|
||||||
}
|
|
||||||
if byteBegin+length >= uint32(len(f.data)) {
|
|
||||||
return nil, errors.New("Not enough bytes to create byte array")
|
|
||||||
}
|
|
||||||
if byteBegin+length < byteBegin {
|
|
||||||
return nil, errors.New("Nunmbers overflow. Returning")
|
|
||||||
}
|
|
||||||
filebody := f.data[byteBegin : byteBegin+length]
|
|
||||||
f.position = byteBegin + length
|
|
||||||
return filebody, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is similar to GetString(), but creates string based on the length
|
|
||||||
// of the length of f.data to increase the likelihood of not overflowing
|
|
||||||
// f.data
|
|
||||||
func (f *ConsumeFuzzer) getTarFilename() (string, error) {
|
|
||||||
if f.position >= uint32(len(f.data)) {
|
|
||||||
return "nil", errors.New("Not enough bytes to create string")
|
|
||||||
}
|
|
||||||
length, err := f.GetUint32()
|
|
||||||
if err != nil {
|
|
||||||
return "nil", errors.New("Not enough bytes to create string")
|
|
||||||
}
|
|
||||||
|
|
||||||
// A bit of optimization to attempt to create a file name
|
|
||||||
// when we don't have as many bytes left as "length"
|
|
||||||
remainingBytes := (uint32(len(f.data)) - f.position)
|
|
||||||
totalDataLen := uint32(len(f.data))
|
|
||||||
if uint32(len(f.data))-f.position < 50 {
|
|
||||||
if remainingBytes == 0 {
|
|
||||||
return "nil", errors.New("Created too large a string")
|
|
||||||
}
|
|
||||||
length = length % remainingBytes
|
|
||||||
} else if len(f.data) < 500 {
|
|
||||||
if totalDataLen == 0 {
|
|
||||||
return "nil", errors.New("Created too large a string")
|
|
||||||
}
|
|
||||||
length = length % totalDataLen
|
|
||||||
}
|
|
||||||
if f.position > MaxTotalLen {
|
|
||||||
return "nil", errors.New("Created too large a string")
|
|
||||||
}
|
|
||||||
byteBegin := f.position - 1
|
|
||||||
if byteBegin >= uint32(len(f.data)) {
|
|
||||||
return "nil", errors.New("Not enough bytes to create string")
|
|
||||||
}
|
|
||||||
if byteBegin+length > uint32(len(f.data)) {
|
|
||||||
return "nil", errors.New("Not enough bytes to create string")
|
|
||||||
}
|
|
||||||
if byteBegin > byteBegin+length {
|
|
||||||
return "nil", errors.New("Numbers overflow. Returning")
|
|
||||||
}
|
|
||||||
str := string(f.data[byteBegin : byteBegin+length])
|
|
||||||
f.position = byteBegin + length
|
|
||||||
return str, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TarBytes returns valid bytes for a tar archive
|
|
||||||
func (f *ConsumeFuzzer) TarBytes() ([]byte, error) {
|
|
||||||
numberOfFiles, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
tw := tar.NewWriter(&buf)
|
|
||||||
defer tw.Close()
|
|
||||||
|
|
||||||
maxNoOfFiles := 1000
|
|
||||||
for i := 0; i < numberOfFiles%maxNoOfFiles; i++ {
|
|
||||||
filename, err := f.getTarFilename()
|
|
||||||
if err != nil {
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
filebody, err := f.createTarFileBody()
|
|
||||||
if err != nil {
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
hdr := &tar.Header{}
|
|
||||||
|
|
||||||
err = setTarHeaderTypeflag(hdr, f)
|
|
||||||
if err != nil {
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
sec, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
nsec, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
hdr.ModTime = time.Unix(int64(sec), int64(nsec))
|
|
||||||
|
|
||||||
hdr.Name = filename
|
|
||||||
hdr.Size = int64(len(filebody))
|
|
||||||
hdr.Mode = 0600
|
|
||||||
|
|
||||||
err = setTarHeaderFormat(hdr, f)
|
|
||||||
if err != nil {
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tw.WriteHeader(hdr); err != nil {
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
if _, err := tw.Write(filebody); err != nil {
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnTarBytes(buf.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates pseudo-random files in rootDir.
|
|
||||||
// Will create subdirs and place the files there.
|
|
||||||
// It is the callers responsibility to ensure that
|
|
||||||
// rootDir exists.
|
|
||||||
func (f *ConsumeFuzzer) CreateFiles(rootDir string) error {
|
|
||||||
var noOfCreatedFiles int
|
|
||||||
noOfCreatedFiles = 0
|
|
||||||
numberOfFiles, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
maxNumberOfFiles := numberOfFiles % 4000 // This is completely arbitrary
|
|
||||||
if maxNumberOfFiles == 0 {
|
|
||||||
return errors.New("maxNumberOfFiles is nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < maxNumberOfFiles; i++ {
|
|
||||||
// The file to create:
|
|
||||||
fileName, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
if noOfCreatedFiles > 0 {
|
|
||||||
// If files have been created, we don't return
|
|
||||||
// an error
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
return errors.New("Could not get fileName")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var fullFilePath string
|
|
||||||
fullFilePath, err = securejoin.SecureJoin(rootDir, fileName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the subdirectory of the file
|
|
||||||
subDir := filepath.Dir(fileName)
|
|
||||||
if subDir != "" && subDir != "." {
|
|
||||||
// create the dir first
|
|
||||||
|
|
||||||
// Avoid going outside the root dir
|
|
||||||
if strings.Contains(subDir, "../") || (len(subDir) > 0 && subDir[0] == 47) || strings.Contains(subDir, "\\") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
dirPath := filepath.Join(rootDir, subDir)
|
|
||||||
dirPath, err := securejoin.SecureJoin(rootDir, subDir)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
|
|
||||||
err2 := os.MkdirAll(dirPath, 0777)
|
|
||||||
if err2 != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fullFilePath, err = securejoin.SecureJoin(dirPath, fileName)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Create symlink
|
|
||||||
createSymlink, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
if noOfCreatedFiles > 0 {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
return errors.New("Could not create the symlink")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if createSymlink {
|
|
||||||
symlinkTarget, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
os.Symlink(symlinkTarget, fullFilePath)
|
|
||||||
// stop loop here, since a symlink needs no further action
|
|
||||||
noOfCreatedFiles++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// We create a normal file
|
|
||||||
fileContents, err := f.GetBytes()
|
|
||||||
if err != nil {
|
|
||||||
if noOfCreatedFiles > 0 {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
return errors.New("Could not create the file")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
createdFile, err := os.Create(fullFilePath)
|
|
||||||
if err != nil {
|
|
||||||
createdFile.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
_, err = createdFile.Write(fileContents)
|
|
||||||
if err != nil {
|
|
||||||
createdFile.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
createdFile.Close()
|
|
||||||
noOfCreatedFiles++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a string that can only consists of characters that are
|
|
||||||
// included in possibleChars. Will return an error if the created
|
|
||||||
// string does not have the specified length
|
|
||||||
func (f *ConsumeFuzzer) GetStringFrom(possibleChars string, length int) (string, error) {
|
|
||||||
returnString := ""
|
|
||||||
if (uint32(len(f.data)) - f.position) < uint32(length) {
|
|
||||||
return returnString, errors.New("Not enough bytes to create a string")
|
|
||||||
}
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
charIndex, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return returnString, err
|
|
||||||
}
|
|
||||||
charToAdd := string(possibleChars[charIndex%len(possibleChars)])
|
|
||||||
returnString = fmt.Sprintf(returnString + charToAdd)
|
|
||||||
}
|
|
||||||
return returnString, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetRune() ([]rune, error) {
|
|
||||||
stringToConvert, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return []rune("nil"), err
|
|
||||||
}
|
|
||||||
return []rune(stringToConvert), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetFloat32() (float32, error) {
|
|
||||||
u32, err := f.GetNBytes(4)
|
|
||||||
if err != nil {
|
|
||||||
return float32(0.0), err
|
|
||||||
}
|
|
||||||
littleEndian, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
return float32(0.0), err
|
|
||||||
}
|
|
||||||
if littleEndian {
|
|
||||||
u32LE := binary.LittleEndian.Uint32(u32)
|
|
||||||
return math.Float32frombits(u32LE), nil
|
|
||||||
}
|
|
||||||
u32BE := binary.BigEndian.Uint32(u32)
|
|
||||||
return math.Float32frombits(u32BE), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GetFloat64() (float64, error) {
|
|
||||||
u64, err := f.GetNBytes(8)
|
|
||||||
if err != nil {
|
|
||||||
return float64(0.0), err
|
|
||||||
}
|
|
||||||
littleEndian, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
return float64(0.0), err
|
|
||||||
}
|
|
||||||
if littleEndian {
|
|
||||||
u64LE := binary.LittleEndian.Uint64(u64)
|
|
||||||
return math.Float64frombits(u64LE), nil
|
|
||||||
}
|
|
||||||
u64BE := binary.BigEndian.Uint64(u64)
|
|
||||||
return math.Float64frombits(u64BE), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) CreateSlice(targetSlice interface{}) error {
|
|
||||||
err := f.GenerateStruct(targetSlice)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
57
vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go
generated
vendored
57
vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go
generated
vendored
|
@ -1,57 +0,0 @@
|
||||||
package gofuzzheaders
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Continue struct {
|
|
||||||
F *ConsumeFuzzer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) AddFuncs(fuzzFuncs []interface{}) {
|
|
||||||
for i := range fuzzFuncs {
|
|
||||||
v := reflect.ValueOf(fuzzFuncs[i])
|
|
||||||
if v.Kind() != reflect.Func {
|
|
||||||
panic("Need only funcs!")
|
|
||||||
}
|
|
||||||
t := v.Type()
|
|
||||||
if t.NumIn() != 2 || t.NumOut() != 1 {
|
|
||||||
fmt.Println(t.NumIn(), t.NumOut())
|
|
||||||
|
|
||||||
panic("Need 2 in and 1 out params. In must be the type. Out must be an error")
|
|
||||||
}
|
|
||||||
argT := t.In(0)
|
|
||||||
switch argT.Kind() {
|
|
||||||
case reflect.Ptr, reflect.Map:
|
|
||||||
default:
|
|
||||||
panic("fuzzFunc must take pointer or map type")
|
|
||||||
}
|
|
||||||
if t.In(1) != reflect.TypeOf(Continue{}) {
|
|
||||||
panic("fuzzFunc's second parameter must be type Continue")
|
|
||||||
}
|
|
||||||
f.Funcs[argT] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *ConsumeFuzzer) GenerateWithCustom(targetStruct interface{}) error {
|
|
||||||
v := reflect.ValueOf(targetStruct)
|
|
||||||
e := v.Elem()
|
|
||||||
return f.fuzzStruct(e, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Continue) GenerateStruct(targetStruct interface{}) error {
|
|
||||||
err := c.F.GenerateStruct(targetStruct)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Continue) GenerateStructWithCustom(targetStruct interface{}) error {
|
|
||||||
err := c.F.GenerateWithCustom(targetStruct)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
524
vendor/github.com/AdaLogics/go-fuzz-headers/sql.go
generated
vendored
524
vendor/github.com/AdaLogics/go-fuzz-headers/sql.go
generated
vendored
|
@ -1,524 +0,0 @@
|
||||||
package gofuzzheaders
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// returns a keyword by index
|
|
||||||
func getKeyword(f *ConsumeFuzzer) (string, error) {
|
|
||||||
index, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return keywords[0], err
|
|
||||||
}
|
|
||||||
for i, k := range keywords {
|
|
||||||
if i == index {
|
|
||||||
return k, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keywords[0], fmt.Errorf("Could not get a kw")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simple utility function to check if a string
|
|
||||||
// slice contains a string.
|
|
||||||
func containsString(s []string, e string) bool {
|
|
||||||
for _, a := range s {
|
|
||||||
if a == e {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// These keywords are used specifically for fuzzing Vitess
|
|
||||||
var keywords = []string{
|
|
||||||
"accessible", "action", "add", "after", "against", "algorithm",
|
|
||||||
"all", "alter", "always", "analyze", "and", "as", "asc", "asensitive",
|
|
||||||
"auto_increment", "avg_row_length", "before", "begin", "between",
|
|
||||||
"bigint", "binary", "_binary", "_utf8mb4", "_utf8", "_latin1", "bit",
|
|
||||||
"blob", "bool", "boolean", "both", "by", "call", "cancel", "cascade",
|
|
||||||
"cascaded", "case", "cast", "channel", "change", "char", "character",
|
|
||||||
"charset", "check", "checksum", "coalesce", "code", "collate", "collation",
|
|
||||||
"column", "columns", "comment", "committed", "commit", "compact", "complete",
|
|
||||||
"compressed", "compression", "condition", "connection", "constraint", "continue",
|
|
||||||
"convert", "copy", "cume_dist", "substr", "substring", "create", "cross",
|
|
||||||
"csv", "current_date", "current_time", "current_timestamp", "current_user",
|
|
||||||
"cursor", "data", "database", "databases", "day", "day_hour", "day_microsecond",
|
|
||||||
"day_minute", "day_second", "date", "datetime", "dec", "decimal", "declare",
|
|
||||||
"default", "definer", "delay_key_write", "delayed", "delete", "dense_rank",
|
|
||||||
"desc", "describe", "deterministic", "directory", "disable", "discard",
|
|
||||||
"disk", "distinct", "distinctrow", "div", "double", "do", "drop", "dumpfile",
|
|
||||||
"duplicate", "dynamic", "each", "else", "elseif", "empty", "enable",
|
|
||||||
"enclosed", "encryption", "end", "enforced", "engine", "engines", "enum",
|
|
||||||
"error", "escape", "escaped", "event", "exchange", "exclusive", "exists",
|
|
||||||
"exit", "explain", "expansion", "export", "extended", "extract", "false",
|
|
||||||
"fetch", "fields", "first", "first_value", "fixed", "float", "float4",
|
|
||||||
"float8", "flush", "for", "force", "foreign", "format", "from", "full",
|
|
||||||
"fulltext", "function", "general", "generated", "geometry", "geometrycollection",
|
|
||||||
"get", "global", "gtid_executed", "grant", "group", "grouping", "groups",
|
|
||||||
"group_concat", "having", "header", "high_priority", "hosts", "hour", "hour_microsecond",
|
|
||||||
"hour_minute", "hour_second", "if", "ignore", "import", "in", "index", "indexes",
|
|
||||||
"infile", "inout", "inner", "inplace", "insensitive", "insert", "insert_method",
|
|
||||||
"int", "int1", "int2", "int3", "int4", "int8", "integer", "interval",
|
|
||||||
"into", "io_after_gtids", "is", "isolation", "iterate", "invoker", "join",
|
|
||||||
"json", "json_table", "key", "keys", "keyspaces", "key_block_size", "kill", "lag",
|
|
||||||
"language", "last", "last_value", "last_insert_id", "lateral", "lead", "leading",
|
|
||||||
"leave", "left", "less", "level", "like", "limit", "linear", "lines",
|
|
||||||
"linestring", "load", "local", "localtime", "localtimestamp", "lock", "logs",
|
|
||||||
"long", "longblob", "longtext", "loop", "low_priority", "manifest",
|
|
||||||
"master_bind", "match", "max_rows", "maxvalue", "mediumblob", "mediumint",
|
|
||||||
"mediumtext", "memory", "merge", "microsecond", "middleint", "min_rows", "minute",
|
|
||||||
"minute_microsecond", "minute_second", "mod", "mode", "modify", "modifies",
|
|
||||||
"multilinestring", "multipoint", "multipolygon", "month", "name",
|
|
||||||
"names", "natural", "nchar", "next", "no", "none", "not", "no_write_to_binlog",
|
|
||||||
"nth_value", "ntile", "null", "numeric", "of", "off", "offset", "on",
|
|
||||||
"only", "open", "optimize", "optimizer_costs", "option", "optionally",
|
|
||||||
"or", "order", "out", "outer", "outfile", "over", "overwrite", "pack_keys",
|
|
||||||
"parser", "partition", "partitioning", "password", "percent_rank", "plugins",
|
|
||||||
"point", "polygon", "precision", "primary", "privileges", "processlist",
|
|
||||||
"procedure", "query", "quarter", "range", "rank", "read", "reads", "read_write",
|
|
||||||
"real", "rebuild", "recursive", "redundant", "references", "regexp", "relay",
|
|
||||||
"release", "remove", "rename", "reorganize", "repair", "repeat", "repeatable",
|
|
||||||
"replace", "require", "resignal", "restrict", "return", "retry", "revert",
|
|
||||||
"revoke", "right", "rlike", "rollback", "row", "row_format", "row_number",
|
|
||||||
"rows", "s3", "savepoint", "schema", "schemas", "second", "second_microsecond",
|
|
||||||
"security", "select", "sensitive", "separator", "sequence", "serializable",
|
|
||||||
"session", "set", "share", "shared", "show", "signal", "signed", "slow",
|
|
||||||
"smallint", "spatial", "specific", "sql", "sqlexception", "sqlstate",
|
|
||||||
"sqlwarning", "sql_big_result", "sql_cache", "sql_calc_found_rows",
|
|
||||||
"sql_no_cache", "sql_small_result", "ssl", "start", "starting",
|
|
||||||
"stats_auto_recalc", "stats_persistent", "stats_sample_pages", "status",
|
|
||||||
"storage", "stored", "straight_join", "stream", "system", "vstream",
|
|
||||||
"table", "tables", "tablespace", "temporary", "temptable", "terminated",
|
|
||||||
"text", "than", "then", "time", "timestamp", "timestampadd", "timestampdiff",
|
|
||||||
"tinyblob", "tinyint", "tinytext", "to", "trailing", "transaction", "tree",
|
|
||||||
"traditional", "trigger", "triggers", "true", "truncate", "uncommitted",
|
|
||||||
"undefined", "undo", "union", "unique", "unlock", "unsigned", "update",
|
|
||||||
"upgrade", "usage", "use", "user", "user_resources", "using", "utc_date",
|
|
||||||
"utc_time", "utc_timestamp", "validation", "values", "variables", "varbinary",
|
|
||||||
"varchar", "varcharacter", "varying", "vgtid_executed", "virtual", "vindex",
|
|
||||||
"vindexes", "view", "vitess", "vitess_keyspaces", "vitess_metadata",
|
|
||||||
"vitess_migration", "vitess_migrations", "vitess_replication_status",
|
|
||||||
"vitess_shards", "vitess_tablets", "vschema", "warnings", "when",
|
|
||||||
"where", "while", "window", "with", "without", "work", "write", "xor",
|
|
||||||
"year", "year_month", "zerofill"}
|
|
||||||
|
|
||||||
// Keywords that could get an additional keyword
|
|
||||||
var needCustomString = []string{
|
|
||||||
"DISTINCTROW", "FROM", // Select keywords:
|
|
||||||
"GROUP BY", "HAVING", "WINDOW",
|
|
||||||
"FOR",
|
|
||||||
"ORDER BY", "LIMIT",
|
|
||||||
"INTO", "PARTITION", "AS", // Insert Keywords:
|
|
||||||
"ON DUPLICATE KEY UPDATE",
|
|
||||||
"WHERE", "LIMIT", // Delete keywords
|
|
||||||
"INFILE", "INTO TABLE", "CHARACTER SET", // Load keywords
|
|
||||||
"TERMINATED BY", "ENCLOSED BY",
|
|
||||||
"ESCAPED BY", "STARTING BY",
|
|
||||||
"TERMINATED BY", "STARTING BY",
|
|
||||||
"IGNORE",
|
|
||||||
"VALUE", "VALUES", // Replace tokens
|
|
||||||
"SET", // Update tokens
|
|
||||||
"ENGINE =", // Drop tokens
|
|
||||||
"DEFINER =", "ON SCHEDULE", "RENAME TO", // Alter tokens
|
|
||||||
"COMMENT", "DO", "INITIAL_SIZE = ", "OPTIONS",
|
|
||||||
}
|
|
||||||
|
|
||||||
var alterTableTokens = [][]string{
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
{"CUSTOM_ALTTER_TABLE_OPTIONS"},
|
|
||||||
{"PARTITION_OPTIONS_FOR_ALTER_TABLE"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var alterTokens = [][]string{
|
|
||||||
{"DATABASE", "SCHEMA", "DEFINER = ", "EVENT", "FUNCTION", "INSTANCE",
|
|
||||||
"LOGFILE GROUP", "PROCEDURE", "SERVER"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
{"ON SCHEDULE", "ON COMPLETION PRESERVE", "ON COMPLETION NOT PRESERVE",
|
|
||||||
"ADD UNDOFILE", "OPTIONS"},
|
|
||||||
{"RENAME TO", "INITIAL_SIZE = "},
|
|
||||||
{"ENABLE", "DISABLE", "DISABLE ON SLAVE", "ENGINE"},
|
|
||||||
{"COMMENT"},
|
|
||||||
{"DO"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var setTokens = [][]string{
|
|
||||||
{"CHARACTER SET", "CHARSET", "CUSTOM_FUZZ_STRING", "NAMES"},
|
|
||||||
{"CUSTOM_FUZZ_STRING", "DEFAULT", "="},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var dropTokens = [][]string{
|
|
||||||
{"TEMPORARY", "UNDO"},
|
|
||||||
{"DATABASE", "SCHEMA", "EVENT", "INDEX", "LOGFILE GROUP",
|
|
||||||
"PROCEDURE", "FUNCTION", "SERVER", "SPATIAL REFERENCE SYSTEM",
|
|
||||||
"TABLE", "TABLESPACE", "TRIGGER", "VIEW"},
|
|
||||||
{"IF EXISTS"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
{"ON", "ENGINE = ", "RESTRICT", "CASCADE"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var renameTokens = [][]string{
|
|
||||||
{"TABLE"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
{"TO"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var truncateTokens = [][]string{
|
|
||||||
{"TABLE"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var createTokens = [][]string{
|
|
||||||
{"OR REPLACE", "TEMPORARY", "UNDO"}, // For create spatial reference system
|
|
||||||
{"UNIQUE", "FULLTEXT", "SPATIAL", "ALGORITHM = UNDEFINED", "ALGORITHM = MERGE",
|
|
||||||
"ALGORITHM = TEMPTABLE"},
|
|
||||||
{"DATABASE", "SCHEMA", "EVENT", "FUNCTION", "INDEX", "LOGFILE GROUP",
|
|
||||||
"PROCEDURE", "SERVER", "SPATIAL REFERENCE SYSTEM", "TABLE", "TABLESPACE",
|
|
||||||
"TRIGGER", "VIEW"},
|
|
||||||
{"IF NOT EXISTS"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var updateTokens = [][]string{
|
|
||||||
{"LOW_PRIORITY"},
|
|
||||||
{"IGNORE"},
|
|
||||||
{"SET"},
|
|
||||||
{"WHERE"},
|
|
||||||
{"ORDER BY"},
|
|
||||||
{"LIMIT"},
|
|
||||||
}
|
|
||||||
var replaceTokens = [][]string{
|
|
||||||
{"LOW_PRIORITY", "DELAYED"},
|
|
||||||
{"INTO"},
|
|
||||||
{"PARTITION"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
{"VALUES", "VALUE"},
|
|
||||||
}
|
|
||||||
var loadTokens = [][]string{
|
|
||||||
{"DATA"},
|
|
||||||
{"LOW_PRIORITY", "CONCURRENT", "LOCAL"},
|
|
||||||
{"INFILE"},
|
|
||||||
{"REPLACE", "IGNORE"},
|
|
||||||
{"INTO TABLE"},
|
|
||||||
{"PARTITION"},
|
|
||||||
{"CHARACTER SET"},
|
|
||||||
{"FIELDS", "COLUMNS"},
|
|
||||||
{"TERMINATED BY"},
|
|
||||||
{"OPTIONALLY"},
|
|
||||||
{"ENCLOSED BY"},
|
|
||||||
{"ESCAPED BY"},
|
|
||||||
{"LINES"},
|
|
||||||
{"STARTING BY"},
|
|
||||||
{"TERMINATED BY"},
|
|
||||||
{"IGNORE"},
|
|
||||||
{"LINES", "ROWS"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// These Are everything that comes after "INSERT"
|
|
||||||
var insertTokens = [][]string{
|
|
||||||
{"LOW_PRIORITY", "DELAYED", "HIGH_PRIORITY", "IGNORE"},
|
|
||||||
{"INTO"},
|
|
||||||
{"PARTITION"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
{"AS"},
|
|
||||||
{"ON DUPLICATE KEY UPDATE"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are everything that comes after "SELECT"
|
|
||||||
var selectTokens = [][]string{
|
|
||||||
{"*", "CUSTOM_FUZZ_STRING", "DISTINCTROW"},
|
|
||||||
{"HIGH_PRIORITY"},
|
|
||||||
{"STRAIGHT_JOIN"},
|
|
||||||
{"SQL_SMALL_RESULT", "SQL_BIG_RESULT", "SQL_BUFFER_RESULT"},
|
|
||||||
{"SQL_NO_CACHE", "SQL_CALC_FOUND_ROWS"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
{"FROM"},
|
|
||||||
{"WHERE"},
|
|
||||||
{"GROUP BY"},
|
|
||||||
{"HAVING"},
|
|
||||||
{"WINDOW"},
|
|
||||||
{"ORDER BY"},
|
|
||||||
{"LIMIT"},
|
|
||||||
{"CUSTOM_FUZZ_STRING"},
|
|
||||||
{"FOR"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are everything that comes after "DELETE"
|
|
||||||
var deleteTokens = [][]string{
|
|
||||||
{"LOW_PRIORITY", "QUICK", "IGNORE", "FROM", "AS"},
|
|
||||||
{"PARTITION"},
|
|
||||||
{"WHERE"},
|
|
||||||
{"ORDER BY"},
|
|
||||||
{"LIMIT"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var alter_table_options = []string{
|
|
||||||
"ADD", "COLUMN", "FIRST", "AFTER", "INDEX", "KEY", "FULLTEXT", "SPATIAL",
|
|
||||||
"CONSTRAINT", "UNIQUE", "FOREIGN KEY", "CHECK", "ENFORCED", "DROP", "ALTER",
|
|
||||||
"NOT", "INPLACE", "COPY", "SET", "VISIBLE", "INVISIBLE", "DEFAULT", "CHANGE",
|
|
||||||
"CHARACTER SET", "COLLATE", "DISABLE", "ENABLE", "KEYS", "TABLESPACE", "LOCK",
|
|
||||||
"FORCE", "MODIFY", "SHARED", "EXCLUSIVE", "NONE", "ORDER BY", "RENAME COLUMN",
|
|
||||||
"AS", "=", "ASC", "DESC", "WITH", "WITHOUT", "VALIDATION", "ADD PARTITION",
|
|
||||||
"DROP PARTITION", "DISCARD PARTITION", "IMPORT PARTITION", "TRUNCATE PARTITION",
|
|
||||||
"COALESCE PARTITION", "REORGANIZE PARTITION", "EXCHANGE PARTITION",
|
|
||||||
"ANALYZE PARTITION", "CHECK PARTITION", "OPTIMIZE PARTITION", "REBUILD PARTITION",
|
|
||||||
"REPAIR PARTITION", "REMOVE PARTITIONING", "USING", "BTREE", "HASH", "COMMENT",
|
|
||||||
"KEY_BLOCK_SIZE", "WITH PARSER", "AUTOEXTEND_SIZE", "AUTO_INCREMENT", "AVG_ROW_LENGTH",
|
|
||||||
"CHECKSUM", "INSERT_METHOD", "ROW_FORMAT", "DYNAMIC", "FIXED", "COMPRESSED", "REDUNDANT",
|
|
||||||
"COMPACT", "SECONDARY_ENGINE_ATTRIBUTE", "STATS_AUTO_RECALC", "STATS_PERSISTENT",
|
|
||||||
"STATS_SAMPLE_PAGES", "ZLIB", "LZ4", "ENGINE_ATTRIBUTE", "KEY_BLOCK_SIZE", "MAX_ROWS",
|
|
||||||
"MIN_ROWS", "PACK_KEYS", "PASSWORD", "COMPRESSION", "CONNECTION", "DIRECTORY",
|
|
||||||
"DELAY_KEY_WRITE", "ENCRYPTION", "STORAGE", "DISK", "MEMORY", "UNION"}
|
|
||||||
|
|
||||||
// Creates an 'alter table' statement. 'alter table' is an exception
|
|
||||||
// in that it has its own function. The majority of statements
|
|
||||||
// are created by 'createStmt()'.
|
|
||||||
func createAlterTableStmt(f *ConsumeFuzzer) (string, error) {
|
|
||||||
var stmt strings.Builder
|
|
||||||
stmt.WriteString("ALTER TABLE ")
|
|
||||||
maxArgs, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
maxArgs = maxArgs % 30
|
|
||||||
if maxArgs == 0 {
|
|
||||||
return "", fmt.Errorf("Could not create alter table stmt")
|
|
||||||
}
|
|
||||||
for i := 0; i < maxArgs; i++ {
|
|
||||||
// Calculate if we get existing token or custom string
|
|
||||||
tokenType, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if tokenType%4 == 1 {
|
|
||||||
customString, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
stmt.WriteString(fmt.Sprintf(" %s", customString))
|
|
||||||
} else {
|
|
||||||
tokenIndex, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
stmt.WriteString(fmt.Sprintf(" %s", alter_table_options[tokenIndex%len(alter_table_options)]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stmt.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func chooseToken(tokens []string, f *ConsumeFuzzer) (string, error) {
|
|
||||||
index, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
var token strings.Builder
|
|
||||||
token.WriteString(fmt.Sprintf(" %s", tokens[index%len(tokens)]))
|
|
||||||
if token.String() == "CUSTOM_FUZZ_STRING" {
|
|
||||||
customFuzzString, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return customFuzzString, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if token requires an argument
|
|
||||||
if containsString(needCustomString, token.String()) {
|
|
||||||
customFuzzString, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
token.WriteString(fmt.Sprintf(" %s", customFuzzString))
|
|
||||||
}
|
|
||||||
return token.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var stmtTypes = map[string][][]string{
|
|
||||||
"DELETE": deleteTokens,
|
|
||||||
"INSERT": insertTokens,
|
|
||||||
"SELECT": selectTokens,
|
|
||||||
"LOAD": loadTokens,
|
|
||||||
"REPLACE": replaceTokens,
|
|
||||||
"CREATE": createTokens,
|
|
||||||
"DROP": dropTokens,
|
|
||||||
"RENAME": renameTokens,
|
|
||||||
"TRUNCATE": truncateTokens,
|
|
||||||
"SET": setTokens,
|
|
||||||
"ALTER": alterTokens,
|
|
||||||
"ALTER TABLE": alterTableTokens, // ALTER TABLE has its own set of tokens
|
|
||||||
}
|
|
||||||
|
|
||||||
var stmtTypeEnum = map[int]string{
|
|
||||||
0: "DELETE",
|
|
||||||
1: "INSERT",
|
|
||||||
2: "SELECT",
|
|
||||||
3: "LOAD",
|
|
||||||
4: "REPLACE",
|
|
||||||
5: "CREATE",
|
|
||||||
6: "DROP",
|
|
||||||
7: "RENAME",
|
|
||||||
8: "TRUNCATE",
|
|
||||||
9: "SET",
|
|
||||||
10: "ALTER",
|
|
||||||
11: "ALTER TABLE",
|
|
||||||
}
|
|
||||||
|
|
||||||
func createStmt(f *ConsumeFuzzer) (string, error) {
|
|
||||||
stmtIndex, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
stmtIndex = stmtIndex % len(stmtTypes)
|
|
||||||
|
|
||||||
queryType := stmtTypeEnum[stmtIndex]
|
|
||||||
tokens := stmtTypes[queryType]
|
|
||||||
|
|
||||||
// We have custom creator for ALTER TABLE
|
|
||||||
if queryType == "ALTER TABLE" {
|
|
||||||
query, err := createAlterTableStmt(f)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return query, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Here we are creating a query that is not
|
|
||||||
// an 'alter table' query. For available
|
|
||||||
// queries, see "stmtTypes"
|
|
||||||
|
|
||||||
// First specify the first query keyword:
|
|
||||||
var query strings.Builder
|
|
||||||
query.WriteString(queryType)
|
|
||||||
|
|
||||||
// Next create the args for the
|
|
||||||
queryArgs, err := createStmtArgs(tokens, f)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
query.WriteString(fmt.Sprintf(" %s", queryArgs))
|
|
||||||
return query.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the arguments of a statements. In a select statement
|
|
||||||
// that would be everything after "select".
|
|
||||||
func createStmtArgs(tokenslice [][]string, f *ConsumeFuzzer) (string, error) {
|
|
||||||
var query strings.Builder
|
|
||||||
var token strings.Builder
|
|
||||||
|
|
||||||
// We go through the tokens in the tokenslice,
|
|
||||||
// create the respective token and add it to
|
|
||||||
// "query"
|
|
||||||
for _, tokens := range tokenslice {
|
|
||||||
|
|
||||||
// For extra randomization, the fuzzer can
|
|
||||||
// choose to not include this token.
|
|
||||||
includeThisToken, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if !includeThisToken {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// There may be several tokens to choose from:
|
|
||||||
if len(tokens) > 1 {
|
|
||||||
chosenToken, err := chooseToken(tokens, f)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
query.WriteString(fmt.Sprintf(" %s", chosenToken))
|
|
||||||
} else {
|
|
||||||
token.WriteString(tokens[0])
|
|
||||||
|
|
||||||
// In case the token is "CUSTOM_FUZZ_STRING"
|
|
||||||
// we will then create a non-structured string
|
|
||||||
if token.String() == "CUSTOM_FUZZ_STRING" {
|
|
||||||
customFuzzString, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
query.WriteString(fmt.Sprintf(" %s", customFuzzString))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if token requires an argument.
|
|
||||||
// Tokens that take an argument can be found
|
|
||||||
// in 'needCustomString'. If so, we add a
|
|
||||||
// non-structured string to the token.
|
|
||||||
if containsString(needCustomString, token.String()) {
|
|
||||||
customFuzzString, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
token.WriteString(fmt.Sprintf(" %s", customFuzzString))
|
|
||||||
}
|
|
||||||
query.WriteString(fmt.Sprintf(" %s", token.String()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return query.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a semi-structured query. It creates a string
|
|
||||||
// that is a combination of the keywords and random strings.
|
|
||||||
func createQuery(f *ConsumeFuzzer) (string, error) {
|
|
||||||
queryLen, err := f.GetInt()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
maxLen := queryLen % 60
|
|
||||||
if maxLen == 0 {
|
|
||||||
return "", fmt.Errorf("Could not create a query")
|
|
||||||
}
|
|
||||||
var query strings.Builder
|
|
||||||
for i := 0; i < maxLen; i++ {
|
|
||||||
// Get a new token:
|
|
||||||
useKeyword, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if useKeyword {
|
|
||||||
keyword, err := getKeyword(f)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
query.WriteString(fmt.Sprintf(" %s", keyword))
|
|
||||||
} else {
|
|
||||||
customString, err := f.GetString()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
query.WriteString(fmt.Sprintf(" %s", customString))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if query.String() == "" {
|
|
||||||
return "", fmt.Errorf("Could not create a query")
|
|
||||||
}
|
|
||||||
return query.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the API that users will interact with.
|
|
||||||
// Usage:
|
|
||||||
// f := NewConsumer(data)
|
|
||||||
// sqlString, err := f.GetSQLString()
|
|
||||||
func (f *ConsumeFuzzer) GetSQLString() (string, error) {
|
|
||||||
var query string
|
|
||||||
veryStructured, err := f.GetBool()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if veryStructured {
|
|
||||||
query, err = createStmt(f)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
query, err = createQuery(f)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return query, nil
|
|
||||||
}
|
|
565
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md
generated
vendored
565
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md
generated
vendored
|
@ -1,565 +0,0 @@
|
||||||
# Release History
|
|
||||||
|
|
||||||
## 1.6.0 (2023-05-04)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added support for ARM cross-tenant authentication. Set the `AuxiliaryTenants` field of `arm.ClientOptions` to enable.
|
|
||||||
* Added `TenantID` field to `policy.TokenRequestOptions`.
|
|
||||||
|
|
||||||
## 1.5.0 (2023-04-06)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added `ShouldRetry` to `policy.RetryOptions` for finer-grained control over when to retry.
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
> These changes affect only code written against a beta version such as v1.5.0-beta.1
|
|
||||||
> These features will return in v1.6.0-beta.1.
|
|
||||||
* Removed `TokenRequestOptions.Claims` and `.TenantID`
|
|
||||||
* Removed ARM client support for CAE and cross-tenant auth.
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Added non-conformant LRO terminal states `Cancelled` and `Completed`.
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Updated to latest `internal` module.
|
|
||||||
|
|
||||||
## 1.5.0-beta.1 (2023-03-02)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* This release includes the features added in v1.4.0-beta.1
|
|
||||||
|
|
||||||
## 1.4.0 (2023-03-02)
|
|
||||||
> This release doesn't include features added in v1.4.0-beta.1. They will return in v1.5.0-beta.1.
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Add `Clone()` method for `arm/policy.ClientOptions`.
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* ARM's RP registration policy will no longer swallow unrecognized errors.
|
|
||||||
* Fixed an issue in `runtime.NewPollerFromResumeToken()` when resuming a `Poller` with a custom `PollingHandler`.
|
|
||||||
* Fixed wrong policy copy in `arm/runtime.NewPipeline()`.
|
|
||||||
|
|
||||||
## 1.4.0-beta.1 (2023-02-02)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added support for ARM cross-tenant authentication. Set the `AuxiliaryTenants` field of `arm.ClientOptions` to enable.
|
|
||||||
* Added `Claims` and `TenantID` fields to `policy.TokenRequestOptions`.
|
|
||||||
* ARM bearer token policy handles CAE challenges.
|
|
||||||
|
|
||||||
## 1.3.1 (2023-02-02)
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Update dependencies to latest versions.
|
|
||||||
|
|
||||||
## 1.3.0 (2023-01-06)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added `BearerTokenOptions.AuthorizationHandler` to enable extending `runtime.BearerTokenPolicy`
|
|
||||||
with custom authorization logic
|
|
||||||
* Added `Client` types and matching constructors to the `azcore` and `arm` packages. These represent a basic client for HTTP and ARM respectively.
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Updated `internal` module to latest version.
|
|
||||||
* `policy/Request.SetBody()` allows replacing a request's body with an empty one
|
|
||||||
|
|
||||||
## 1.2.0 (2022-11-04)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added `ClientOptions.APIVersion` field, which overrides the default version a client
|
|
||||||
requests of the service, if the client supports this (all ARM clients do).
|
|
||||||
* Added package `tracing` that contains the building blocks for distributed tracing.
|
|
||||||
* Added field `TracingProvider` to type `policy.ClientOptions` that will be used to set the per-client tracing implementation.
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Fixed an issue in `runtime.SetMultipartFormData` to properly handle slices of `io.ReadSeekCloser`.
|
|
||||||
* Fixed the MaxRetryDelay default to be 60s.
|
|
||||||
* Failure to poll the state of an LRO will now return an `*azcore.ResponseError` for poller types that require this behavior.
|
|
||||||
* Fixed a bug in `runtime.NewPipeline` that would cause pipeline-specified allowed headers and query parameters to be lost.
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Retain contents of read-only fields when sending requests.
|
|
||||||
|
|
||||||
## 1.1.4 (2022-10-06)
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Don't retry a request if the `Retry-After` delay is greater than the configured `RetryOptions.MaxRetryDelay`.
|
|
||||||
* `runtime.JoinPaths`: do not unconditionally add a forward slash before the query string
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Removed logging URL from retry policy as it's redundant.
|
|
||||||
* Retry policy logs when it exits due to a non-retriable status code.
|
|
||||||
|
|
||||||
## 1.1.3 (2022-09-01)
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Adjusted the initial retry delay to 800ms per the Azure SDK guidelines.
|
|
||||||
|
|
||||||
## 1.1.2 (2022-08-09)
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Fixed various doc bugs.
|
|
||||||
|
|
||||||
## 1.1.1 (2022-06-30)
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Avoid polling when a RELO LRO synchronously terminates.
|
|
||||||
|
|
||||||
## 1.1.0 (2022-06-03)
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* The one-second floor for `Frequency` when calling `PollUntilDone()` has been removed when running tests.
|
|
||||||
|
|
||||||
## 1.0.0 (2022-05-12)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added interface `runtime.PollingHandler` to support custom poller implementations.
|
|
||||||
* Added field `PollingHandler` of this type to `runtime.NewPollerOptions[T]` and `runtime.NewPollerFromResumeTokenOptions[T]`.
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Renamed `cloud.Configuration.LoginEndpoint` to `.ActiveDirectoryAuthorityHost`
|
|
||||||
* Renamed `cloud.AzurePublicCloud` to `cloud.AzurePublic`
|
|
||||||
* Removed `AuxiliaryTenants` field from `arm/ClientOptions` and `arm/policy/BearerTokenOptions`
|
|
||||||
* Removed `TokenRequestOptions.TenantID`
|
|
||||||
* `Poller[T].PollUntilDone()` now takes an `options *PollUntilDoneOptions` param instead of `freq time.Duration`
|
|
||||||
* Removed `arm/runtime.Poller[T]`, `arm/runtime.NewPoller[T]()` and `arm/runtime.NewPollerFromResumeToken[T]()`
|
|
||||||
* Removed `arm/runtime.FinalStateVia` and related `const` values
|
|
||||||
* Renamed `runtime.PageProcessor` to `runtime.PagingHandler`
|
|
||||||
* The `arm/runtime.ProviderRepsonse` and `arm/runtime.Provider` types are no longer exported.
|
|
||||||
* Renamed `NewRequestIdPolicy()` to `NewRequestIDPolicy()`
|
|
||||||
* `TokenCredential.GetToken` now returns `AccessToken` by value.
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* When per-try timeouts are enabled, only cancel the context after the body has been read and closed.
|
|
||||||
* The `Operation-Location` poller now properly handles `final-state-via` values.
|
|
||||||
* Improvements in `runtime.Poller[T]`
|
|
||||||
* `Poll()` shouldn't cache errors, allowing for additional retries when in a non-terminal state.
|
|
||||||
* `Result()` will cache the terminal result or error but not transient errors, allowing for additional retries.
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Updated to latest `internal` module and absorbed breaking changes.
|
|
||||||
* Use `temporal.Resource` and deleted copy.
|
|
||||||
* The internal poller implementation has been refactored.
|
|
||||||
* The implementation in `internal/pollers/poller.go` has been merged into `runtime/poller.go` with some slight modification.
|
|
||||||
* The internal poller types had their methods updated to conform to the `runtime.PollingHandler` interface.
|
|
||||||
* The creation of resume tokens has been refactored so that implementers of `runtime.PollingHandler` don't need to know about it.
|
|
||||||
* `NewPipeline()` places policies from `ClientOptions` after policies from `PipelineOptions`
|
|
||||||
* Default User-Agent headers no longer include `azcore` version information
|
|
||||||
|
|
||||||
## 0.23.1 (2022-04-14)
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Include XML header when marshalling XML content.
|
|
||||||
* Handle XML namespaces when searching for error code.
|
|
||||||
* Handle `odata.error` when searching for error code.
|
|
||||||
|
|
||||||
## 0.23.0 (2022-04-04)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added `runtime.Pager[T any]` and `runtime.Poller[T any]` supporting types for central, generic, implementations.
|
|
||||||
* Added `cloud` package with a new API for cloud configuration
|
|
||||||
* Added `FinalStateVia` field to `runtime.NewPollerOptions[T any]` type.
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Removed the `Poller` type-alias to the internal poller implementation.
|
|
||||||
* Added `Ptr[T any]` and `SliceOfPtrs[T any]` in the `to` package and removed all non-generic implementations.
|
|
||||||
* `NullValue` and `IsNullValue` now take a generic type parameter instead of an interface func parameter.
|
|
||||||
* Replaced `arm.Endpoint` with `cloud` API
|
|
||||||
* Removed the `endpoint` parameter from `NewRPRegistrationPolicy()`
|
|
||||||
* `arm/runtime.NewPipeline()` and `.NewRPRegistrationPolicy()` now return an `error`
|
|
||||||
* Refactored `NewPoller` and `NewPollerFromResumeToken` funcs in `arm/runtime` and `runtime` packages.
|
|
||||||
* Removed the `pollerID` parameter as it's no longer required.
|
|
||||||
* Created optional parameter structs and moved optional parameters into them.
|
|
||||||
* Changed `FinalStateVia` field to a `const` type.
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Converted expiring resource and dependent types to use generics.
|
|
||||||
|
|
||||||
## 0.22.0 (2022-03-03)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added header `WWW-Authenticate` to the default allow-list of headers for logging.
|
|
||||||
* Added a pipeline policy that enables the retrieval of HTTP responses from API calls.
|
|
||||||
* Added `runtime.WithCaptureResponse` to enable the policy at the API level (off by default).
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Moved `WithHTTPHeader` and `WithRetryOptions` from the `policy` package to the `runtime` package.
|
|
||||||
|
|
||||||
## 0.21.1 (2022-02-04)
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Restore response body after reading in `Poller.FinalResponse()`. (#16911)
|
|
||||||
* Fixed bug in `NullValue` that could lead to incorrect comparisons for empty maps/slices (#16969)
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* `BearerTokenPolicy` is more resilient to transient authentication failures. (#16789)
|
|
||||||
|
|
||||||
## 0.21.0 (2022-01-11)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Added `AllowedHeaders` and `AllowedQueryParams` to `policy.LogOptions` to control which headers and query parameters are written to the logger.
|
|
||||||
* Added `azcore.ResponseError` type which is returned from APIs when a non-success HTTP status code is received.
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Moved `[]policy.Policy` parameters of `arm/runtime.NewPipeline` and `runtime.NewPipeline` into a new struct, `runtime.PipelineOptions`
|
|
||||||
* Renamed `arm/ClientOptions.Host` to `.Endpoint`
|
|
||||||
* Moved `Request.SkipBodyDownload` method to function `runtime.SkipBodyDownload`
|
|
||||||
* Removed `azcore.HTTPResponse` interface type
|
|
||||||
* `arm.NewPoller()` and `runtime.NewPoller()` no longer require an `eu` parameter
|
|
||||||
* `runtime.NewResponseError()` no longer requires an `error` parameter
|
|
||||||
|
|
||||||
## 0.20.0 (2021-10-22)
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Removed `arm.Connection`
|
|
||||||
* Removed `azcore.Credential` and `.NewAnonymousCredential()`
|
|
||||||
* `NewRPRegistrationPolicy` now requires an `azcore.TokenCredential`
|
|
||||||
* `runtime.NewPipeline` has a new signature that simplifies implementing custom authentication
|
|
||||||
* `arm/runtime.RegistrationOptions` embeds `policy.ClientOptions`
|
|
||||||
* Contents in the `log` package have been slightly renamed.
|
|
||||||
* Removed `AuthenticationOptions` in favor of `policy.BearerTokenOptions`
|
|
||||||
* Changed parameters for `NewBearerTokenPolicy()`
|
|
||||||
* Moved policy config options out of `arm/runtime` and into `arm/policy`
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Updating Documentation
|
|
||||||
* Added string typdef `arm.Endpoint` to provide a hint toward expected ARM client endpoints
|
|
||||||
* `azcore.ClientOptions` contains common pipeline configuration settings
|
|
||||||
* Added support for multi-tenant authorization in `arm/runtime`
|
|
||||||
* Require one second minimum when calling `PollUntilDone()`
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
* Fixed a potential panic when creating the default Transporter.
|
|
||||||
* Close LRO initial response body when creating a poller.
|
|
||||||
* Fixed a panic when recursively cloning structs that contain time.Time.
|
|
||||||
|
|
||||||
## 0.19.0 (2021-08-25)
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Split content out of `azcore` into various packages. The intent is to separate content based on its usage (common, uncommon, SDK authors).
|
|
||||||
* `azcore` has all core functionality.
|
|
||||||
* `log` contains facilities for configuring in-box logging.
|
|
||||||
* `policy` is used for configuring pipeline options and creating custom pipeline policies.
|
|
||||||
* `runtime` contains various helpers used by SDK authors and generated content.
|
|
||||||
* `streaming` has helpers for streaming IO operations.
|
|
||||||
* `NewTelemetryPolicy()` now requires module and version parameters and the `Value` option has been removed.
|
|
||||||
* As a result, the `Request.Telemetry()` method has been removed.
|
|
||||||
* The telemetry policy now includes the SDK prefix `azsdk-go-` so callers no longer need to provide it.
|
|
||||||
* The `*http.Request` in `runtime.Request` is no longer anonymously embedded. Use the `Raw()` method to access it.
|
|
||||||
* The `UserAgent` and `Version` constants have been made internal, `Module` and `Version` respectively.
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
* Fixed an issue in the retry policy where the request body could be overwritten after a rewind.
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Moved modules `armcore` and `to` content into `arm` and `to` packages respectively.
|
|
||||||
* The `Pipeline()` method on `armcore.Connection` has been replaced by `NewPipeline()` in `arm.Connection`. It takes module and version parameters used by the telemetry policy.
|
|
||||||
* Poller logic has been consolidated across ARM and core implementations.
|
|
||||||
* This required some changes to the internal interfaces for core pollers.
|
|
||||||
* The core poller types have been improved, including more logging and test coverage.
|
|
||||||
|
|
||||||
## 0.18.1 (2021-08-20)
|
|
||||||
|
|
||||||
### Features Added
|
|
||||||
* Adds an `ETag` type for comparing etags and handling etags on requests
|
|
||||||
* Simplifies the `requestBodyProgess` and `responseBodyProgress` into a single `progress` object
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* `JoinPaths` will preserve query parameters encoded in the `root` url.
|
|
||||||
|
|
||||||
### Other Changes
|
|
||||||
* Bumps dependency on `internal` module to the latest version (v0.7.0)
|
|
||||||
|
|
||||||
## 0.18.0 (2021-07-29)
|
|
||||||
### Features Added
|
|
||||||
* Replaces methods from Logger type with two package methods for interacting with the logging functionality.
|
|
||||||
* `azcore.SetClassifications` replaces `azcore.Logger().SetClassifications`
|
|
||||||
* `azcore.SetListener` replaces `azcore.Logger().SetListener`
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Removes `Logger` type from `azcore`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.17.0 (2021-07-27)
|
|
||||||
### Features Added
|
|
||||||
* Adding TenantID to TokenRequestOptions (https://github.com/Azure/azure-sdk-for-go/pull/14879)
|
|
||||||
* Adding AuxiliaryTenants to AuthenticationOptions (https://github.com/Azure/azure-sdk-for-go/pull/15123)
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Rename `AnonymousCredential` to `NewAnonymousCredential` (https://github.com/Azure/azure-sdk-for-go/pull/15104)
|
|
||||||
* rename `AuthenticationPolicyOptions` to `AuthenticationOptions` (https://github.com/Azure/azure-sdk-for-go/pull/15103)
|
|
||||||
* Make Header constants private (https://github.com/Azure/azure-sdk-for-go/pull/15038)
|
|
||||||
|
|
||||||
|
|
||||||
## 0.16.2 (2021-05-26)
|
|
||||||
### Features Added
|
|
||||||
* Improved support for byte arrays [#14715](https://github.com/Azure/azure-sdk-for-go/pull/14715)
|
|
||||||
|
|
||||||
|
|
||||||
## 0.16.1 (2021-05-19)
|
|
||||||
### Features Added
|
|
||||||
* Add license.txt to azcore module [#14682](https://github.com/Azure/azure-sdk-for-go/pull/14682)
|
|
||||||
|
|
||||||
|
|
||||||
## 0.16.0 (2021-05-07)
|
|
||||||
### Features Added
|
|
||||||
* Remove extra `*` in UnmarshalAsByteArray() [#14642](https://github.com/Azure/azure-sdk-for-go/pull/14642)
|
|
||||||
|
|
||||||
|
|
||||||
## 0.15.1 (2021-05-06)
|
|
||||||
### Features Added
|
|
||||||
* Cache the original request body on Request [#14634](https://github.com/Azure/azure-sdk-for-go/pull/14634)
|
|
||||||
|
|
||||||
|
|
||||||
## 0.15.0 (2021-05-05)
|
|
||||||
### Features Added
|
|
||||||
* Add support for null map and slice
|
|
||||||
* Export `Response.Payload` method
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* remove `Response.UnmarshalError` as it's no longer required
|
|
||||||
|
|
||||||
|
|
||||||
## 0.14.5 (2021-04-23)
|
|
||||||
### Features Added
|
|
||||||
* Add `UnmarshalError()` on `azcore.Response`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.14.4 (2021-04-22)
|
|
||||||
### Features Added
|
|
||||||
* Support for basic LRO polling
|
|
||||||
* Added type `LROPoller` and supporting types for basic polling on long running operations.
|
|
||||||
* rename poller param and added doc comment
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Fixed content type detection bug in logging.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.14.3 (2021-03-29)
|
|
||||||
### Features Added
|
|
||||||
* Add support for multi-part form data
|
|
||||||
* Added method `WriteMultipartFormData()` to Request.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.14.2 (2021-03-17)
|
|
||||||
### Features Added
|
|
||||||
* Add support for encoding JSON null values
|
|
||||||
* Adds `NullValue()` and `IsNullValue()` functions for setting and detecting sentinel values used for encoding a JSON null.
|
|
||||||
* Documentation fixes
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Fixed improper error wrapping
|
|
||||||
|
|
||||||
|
|
||||||
## 0.14.1 (2021-02-08)
|
|
||||||
### Features Added
|
|
||||||
* Add `Pager` and `Poller` interfaces to azcore
|
|
||||||
|
|
||||||
|
|
||||||
## 0.14.0 (2021-01-12)
|
|
||||||
### Features Added
|
|
||||||
* Accept zero-value options for default values
|
|
||||||
* Specify zero-value options structs to accept default values.
|
|
||||||
* Remove `DefaultXxxOptions()` methods.
|
|
||||||
* Do not silently change TryTimeout on negative values
|
|
||||||
* make per-try timeout opt-in
|
|
||||||
|
|
||||||
|
|
||||||
## 0.13.4 (2020-11-20)
|
|
||||||
### Features Added
|
|
||||||
* Include telemetry string in User Agent
|
|
||||||
|
|
||||||
|
|
||||||
## 0.13.3 (2020-11-20)
|
|
||||||
### Features Added
|
|
||||||
* Updating response body handling on `azcore.Response`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.13.2 (2020-11-13)
|
|
||||||
### Features Added
|
|
||||||
* Remove implementation of stateless policies as first-class functions.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.13.1 (2020-11-05)
|
|
||||||
### Features Added
|
|
||||||
* Add `Telemetry()` method to `azcore.Request()`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.13.0 (2020-10-14)
|
|
||||||
### Features Added
|
|
||||||
* Rename `log` to `logger` to avoid name collision with the log package.
|
|
||||||
* Documentation improvements
|
|
||||||
* Simplified `DefaultHTTPClientTransport()` implementation
|
|
||||||
|
|
||||||
|
|
||||||
## 0.12.1 (2020-10-13)
|
|
||||||
### Features Added
|
|
||||||
* Update `internal` module dependence to `v0.5.0`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.12.0 (2020-10-08)
|
|
||||||
### Features Added
|
|
||||||
* Removed storage specific content
|
|
||||||
* Removed internal content to prevent API clutter
|
|
||||||
* Refactored various policy options to conform with our options pattern
|
|
||||||
|
|
||||||
|
|
||||||
## 0.11.0 (2020-09-22)
|
|
||||||
### Features Added
|
|
||||||
|
|
||||||
* Removed `LogError` and `LogSlowResponse`.
|
|
||||||
* Renamed `options` in `RequestLogOptions`.
|
|
||||||
* Updated `NewRequestLogPolicy()` to follow standard pattern for options.
|
|
||||||
* Refactored `requestLogPolicy.Do()` per above changes.
|
|
||||||
* Cleaned up/added logging in retry policy.
|
|
||||||
* Export `NewResponseError()`
|
|
||||||
* Fix `RequestLogOptions` comment
|
|
||||||
|
|
||||||
|
|
||||||
## 0.10.1 (2020-09-17)
|
|
||||||
### Features Added
|
|
||||||
* Add default console logger
|
|
||||||
* Default console logger writes to stderr. To enable it, set env var `AZURE_SDK_GO_LOGGING` to the value 'all'.
|
|
||||||
* Added `Logger.Writef()` to reduce the need for `ShouldLog()` checks.
|
|
||||||
* Add `LogLongRunningOperation`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.10.0 (2020-09-10)
|
|
||||||
### Features Added
|
|
||||||
* The `request` and `transport` interfaces have been refactored to align with the patterns in the standard library.
|
|
||||||
* `NewRequest()` now uses `http.NewRequestWithContext()` and performs additional validation, it also requires a context parameter.
|
|
||||||
* The `Policy` and `Transport` interfaces have had their context parameter removed as the context is associated with the underlying `http.Request`.
|
|
||||||
* `Pipeline.Do()` will validate the HTTP request before sending it through the pipeline, avoiding retries on a malformed request.
|
|
||||||
* The `Retrier` interface has been replaced with the `NonRetriableError` interface, and the retry policy updated to test for this.
|
|
||||||
* `Request.SetBody()` now requires a content type parameter for setting the request's MIME type.
|
|
||||||
* moved path concatenation into `JoinPaths()` func
|
|
||||||
|
|
||||||
|
|
||||||
## 0.9.6 (2020-08-18)
|
|
||||||
### Features Added
|
|
||||||
* Improvements to body download policy
|
|
||||||
* Always download the response body for error responses, i.e. HTTP status codes >= 400.
|
|
||||||
* Simplify variable declarations
|
|
||||||
|
|
||||||
|
|
||||||
## 0.9.5 (2020-08-11)
|
|
||||||
### Features Added
|
|
||||||
* Set the Content-Length header in `Request.SetBody`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.9.4 (2020-08-03)
|
|
||||||
### Features Added
|
|
||||||
* Fix cancellation of per try timeout
|
|
||||||
* Per try timeout is used to ensure that an HTTP operation doesn't take too long, e.g. that a GET on some URL doesn't take an inordinant amount of time.
|
|
||||||
* Once the HTTP request returns, the per try timeout should be cancelled, not when the response has been read to completion.
|
|
||||||
* Do not drain response body if there are no more retries
|
|
||||||
* Do not retry non-idempotent operations when body download fails
|
|
||||||
|
|
||||||
|
|
||||||
## 0.9.3 (2020-07-28)
|
|
||||||
### Features Added
|
|
||||||
* Add support for custom HTTP request headers
|
|
||||||
* Inserts an internal policy into the pipeline that can extract HTTP header values from the caller's context, adding them to the request.
|
|
||||||
* Use `azcore.WithHTTPHeader` to add HTTP headers to a context.
|
|
||||||
* Remove method specific to Go 1.14
|
|
||||||
|
|
||||||
|
|
||||||
## 0.9.2 (2020-07-28)
|
|
||||||
### Features Added
|
|
||||||
* Omit read-only content from request payloads
|
|
||||||
* If any field in a payload's object graph contains `azure:"ro"`, make a clone of the object graph, omitting all fields with this annotation.
|
|
||||||
* Verify no fields were dropped
|
|
||||||
* Handle embedded struct types
|
|
||||||
* Added test for cloning by value
|
|
||||||
* Add messages to failures
|
|
||||||
|
|
||||||
|
|
||||||
## 0.9.1 (2020-07-22)
|
|
||||||
### Features Added
|
|
||||||
* Updated dependency on internal module to fix race condition.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.9.0 (2020-07-09)
|
|
||||||
### Features Added
|
|
||||||
* Add `HTTPResponse` interface to be used by callers to access the raw HTTP response from an error in the event of an API call failure.
|
|
||||||
* Updated `sdk/internal` dependency to latest version.
|
|
||||||
* Rename package alias
|
|
||||||
|
|
||||||
|
|
||||||
## 0.8.2 (2020-06-29)
|
|
||||||
### Features Added
|
|
||||||
* Added missing documentation comments
|
|
||||||
|
|
||||||
### Bugs Fixed
|
|
||||||
* Fixed a bug in body download policy.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.8.1 (2020-06-26)
|
|
||||||
### Features Added
|
|
||||||
* Miscellaneous clean-up reported by linters
|
|
||||||
|
|
||||||
|
|
||||||
## 0.8.0 (2020-06-01)
|
|
||||||
### Features Added
|
|
||||||
* Differentiate between standard and URL encoding.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.7.1 (2020-05-27)
|
|
||||||
### Features Added
|
|
||||||
* Add support for for base64 encoding and decoding of payloads.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.7.0 (2020-05-12)
|
|
||||||
### Features Added
|
|
||||||
* Change `RetryAfter()` to a function.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.6.0 (2020-04-29)
|
|
||||||
### Features Added
|
|
||||||
* Updating `RetryAfter` to only return the detaion in the RetryAfter header
|
|
||||||
|
|
||||||
|
|
||||||
## 0.5.0 (2020-03-23)
|
|
||||||
### Features Added
|
|
||||||
* Export `TransportFunc`
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Removed `IterationDone`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.4.1 (2020-02-25)
|
|
||||||
### Features Added
|
|
||||||
* Ensure per-try timeout is properly cancelled
|
|
||||||
* Explicitly call cancel the per-try timeout when the response body has been read/closed by the body download policy.
|
|
||||||
* When the response body is returned to the caller for reading/closing, wrap it in a `responseBodyReader` that will cancel the timeout when the body is closed.
|
|
||||||
* `Logger.Should()` will return false if no listener is set.
|
|
||||||
|
|
||||||
|
|
||||||
## 0.4.0 (2020-02-18)
|
|
||||||
### Features Added
|
|
||||||
* Enable custom `RetryOptions` to be specified per API call
|
|
||||||
* Added `WithRetryOptions()` that adds a custom `RetryOptions` to the provided context, allowing custom settings per API call.
|
|
||||||
* Remove 429 from the list of default HTTP status codes for retry.
|
|
||||||
* Change StatusCodesForRetry to a slice so consumers can append to it.
|
|
||||||
* Added support for retry-after in HTTP-date format.
|
|
||||||
* Cleaned up some comments specific to storage.
|
|
||||||
* Remove `Request.SetQueryParam()`
|
|
||||||
* Renamed `MaxTries` to `MaxRetries`
|
|
||||||
|
|
||||||
## 0.3.0 (2020-01-16)
|
|
||||||
### Features Added
|
|
||||||
* Added `DefaultRetryOptions` to create initialized default options.
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
* Removed `Response.CheckStatusCode()`
|
|
||||||
|
|
||||||
|
|
||||||
## 0.2.0 (2020-01-15)
|
|
||||||
### Features Added
|
|
||||||
* Add support for marshalling and unmarshalling JSON
|
|
||||||
* Removed `Response.Payload` field
|
|
||||||
* Exit early when unmarsahlling if there is no payload
|
|
||||||
|
|
||||||
|
|
||||||
## 0.1.0 (2020-01-10)
|
|
||||||
### Features Added
|
|
||||||
* Initial release
|
|
21
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/LICENSE.txt
generated
vendored
21
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/LICENSE.txt
generated
vendored
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) Microsoft Corporation.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE
|
|
39
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/README.md
generated
vendored
39
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/README.md
generated
vendored
|
@ -1,39 +0,0 @@
|
||||||
# Azure Core Client Module for Go
|
|
||||||
|
|
||||||
[![PkgGoDev](https://pkg.go.dev/badge/github.com/Azure/azure-sdk-for-go/sdk/azcore)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore)
|
|
||||||
[![Build Status](https://dev.azure.com/azure-sdk/public/_apis/build/status/go/go%20-%20azcore%20-%20ci?branchName=main)](https://dev.azure.com/azure-sdk/public/_build/latest?definitionId=1843&branchName=main)
|
|
||||||
[![Code Coverage](https://img.shields.io/azure-devops/coverage/azure-sdk/public/1843/main)](https://img.shields.io/azure-devops/coverage/azure-sdk/public/1843/main)
|
|
||||||
|
|
||||||
The `azcore` module provides a set of common interfaces and types for Go SDK client modules.
|
|
||||||
These modules follow the [Azure SDK Design Guidelines for Go](https://azure.github.io/azure-sdk/golang_introduction.html).
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management.
|
|
||||||
|
|
||||||
Typically, you will not need to explicitly install `azcore` as it will be installed as a client module dependency.
|
|
||||||
To add the latest version to your `go.mod` file, execute the following command.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get github.com/Azure/azure-sdk-for-go/sdk/azcore
|
|
||||||
```
|
|
||||||
|
|
||||||
General documentation and examples can be found on [pkg.go.dev](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore).
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
This project welcomes contributions and suggestions. Most contributions require
|
|
||||||
you to agree to a Contributor License Agreement (CLA) declaring that you have
|
|
||||||
the right to, and actually do, grant us the rights to use your contribution.
|
|
||||||
For details, visit [https://cla.microsoft.com](https://cla.microsoft.com).
|
|
||||||
|
|
||||||
When you submit a pull request, a CLA-bot will automatically determine whether
|
|
||||||
you need to provide a CLA and decorate the PR appropriately (e.g., label,
|
|
||||||
comment). Simply follow the instructions provided by the bot. You will only
|
|
||||||
need to do this once across all repos using our CLA.
|
|
||||||
|
|
||||||
This project has adopted the
|
|
||||||
[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
|
||||||
For more information, see the
|
|
||||||
[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
|
||||||
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any
|
|
||||||
additional questions or comments.
|
|
29
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml
generated
vendored
29
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml
generated
vendored
|
@ -1,29 +0,0 @@
|
||||||
# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file.
|
|
||||||
trigger:
|
|
||||||
branches:
|
|
||||||
include:
|
|
||||||
- main
|
|
||||||
- feature/*
|
|
||||||
- hotfix/*
|
|
||||||
- release/*
|
|
||||||
paths:
|
|
||||||
include:
|
|
||||||
- sdk/azcore/
|
|
||||||
- eng/
|
|
||||||
|
|
||||||
pr:
|
|
||||||
branches:
|
|
||||||
include:
|
|
||||||
- main
|
|
||||||
- feature/*
|
|
||||||
- hotfix/*
|
|
||||||
- release/*
|
|
||||||
paths:
|
|
||||||
include:
|
|
||||||
- sdk/azcore/
|
|
||||||
- eng/
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml
|
|
||||||
parameters:
|
|
||||||
ServiceDirectory: azcore
|
|
44
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/cloud.go
generated
vendored
44
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/cloud.go
generated
vendored
|
@ -1,44 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package cloud
|
|
||||||
|
|
||||||
var (
|
|
||||||
// AzureChina contains configuration for Azure China.
|
|
||||||
AzureChina = Configuration{
|
|
||||||
ActiveDirectoryAuthorityHost: "https://login.chinacloudapi.cn/", Services: map[ServiceName]ServiceConfiguration{},
|
|
||||||
}
|
|
||||||
// AzureGovernment contains configuration for Azure Government.
|
|
||||||
AzureGovernment = Configuration{
|
|
||||||
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.us/", Services: map[ServiceName]ServiceConfiguration{},
|
|
||||||
}
|
|
||||||
// AzurePublic contains configuration for Azure Public Cloud.
|
|
||||||
AzurePublic = Configuration{
|
|
||||||
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.com/", Services: map[ServiceName]ServiceConfiguration{},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// ServiceName identifies a cloud service.
|
|
||||||
type ServiceName string
|
|
||||||
|
|
||||||
// ResourceManager is a global constant identifying Azure Resource Manager.
|
|
||||||
const ResourceManager ServiceName = "resourceManager"
|
|
||||||
|
|
||||||
// ServiceConfiguration configures a specific cloud service such as Azure Resource Manager.
|
|
||||||
type ServiceConfiguration struct {
|
|
||||||
// Audience is the audience the client will request for its access tokens.
|
|
||||||
Audience string
|
|
||||||
// Endpoint is the service's base URL.
|
|
||||||
Endpoint string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configuration configures a cloud.
|
|
||||||
type Configuration struct {
|
|
||||||
// ActiveDirectoryAuthorityHost is the base URL of the cloud's Azure Active Directory.
|
|
||||||
ActiveDirectoryAuthorityHost string
|
|
||||||
// Services contains configuration for the cloud's services.
|
|
||||||
Services map[ServiceName]ServiceConfiguration
|
|
||||||
}
|
|
53
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/doc.go
generated
vendored
53
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/doc.go
generated
vendored
|
@ -1,53 +0,0 @@
|
||||||
//go:build go1.16
|
|
||||||
// +build go1.16
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package cloud implements a configuration API for applications deployed to sovereign or private Azure clouds.
|
|
||||||
|
|
||||||
Azure SDK client configuration defaults are appropriate for Azure Public Cloud (sometimes referred to as
|
|
||||||
"Azure Commercial" or simply "Microsoft Azure"). This package enables applications deployed to other
|
|
||||||
Azure Clouds to configure clients appropriately.
|
|
||||||
|
|
||||||
This package contains predefined configuration for well-known sovereign clouds such as Azure Government and
|
|
||||||
Azure China. Azure SDK clients accept this configuration via the Cloud field of azcore.ClientOptions. For
|
|
||||||
example, configuring a credential and ARM client for Azure Government:
|
|
||||||
|
|
||||||
opts := azcore.ClientOptions{Cloud: cloud.AzureGovernment}
|
|
||||||
cred, err := azidentity.NewDefaultAzureCredential(
|
|
||||||
&azidentity.DefaultAzureCredentialOptions{ClientOptions: opts},
|
|
||||||
)
|
|
||||||
handle(err)
|
|
||||||
|
|
||||||
client, err := armsubscription.NewClient(
|
|
||||||
cred, &arm.ClientOptions{ClientOptions: opts},
|
|
||||||
)
|
|
||||||
handle(err)
|
|
||||||
|
|
||||||
Applications deployed to a private cloud such as Azure Stack create a Configuration object with
|
|
||||||
appropriate values:
|
|
||||||
|
|
||||||
c := cloud.Configuration{
|
|
||||||
ActiveDirectoryAuthorityHost: "https://...",
|
|
||||||
Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
|
|
||||||
cloud.ResourceManager: {
|
|
||||||
Audience: "...",
|
|
||||||
Endpoint: "https://...",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
opts := azcore.ClientOptions{Cloud: c}
|
|
||||||
|
|
||||||
cred, err := azidentity.NewDefaultAzureCredential(
|
|
||||||
&azidentity.DefaultAzureCredentialOptions{ClientOptions: opts},
|
|
||||||
)
|
|
||||||
handle(err)
|
|
||||||
|
|
||||||
client, err := armsubscription.NewClient(
|
|
||||||
cred, &arm.ClientOptions{ClientOptions: opts},
|
|
||||||
)
|
|
||||||
handle(err)
|
|
||||||
*/
|
|
||||||
package cloud
|
|
113
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/core.go
generated
vendored
113
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/core.go
generated
vendored
|
@ -1,113 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package azcore
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AccessToken represents an Azure service bearer access token with expiry information.
|
|
||||||
type AccessToken = exported.AccessToken
|
|
||||||
|
|
||||||
// TokenCredential represents a credential capable of providing an OAuth token.
|
|
||||||
type TokenCredential = exported.TokenCredential
|
|
||||||
|
|
||||||
// holds sentinel values used to send nulls
|
|
||||||
var nullables map[reflect.Type]interface{} = map[reflect.Type]interface{}{}
|
|
||||||
|
|
||||||
// NullValue is used to send an explicit 'null' within a request.
|
|
||||||
// This is typically used in JSON-MERGE-PATCH operations to delete a value.
|
|
||||||
func NullValue[T any]() T {
|
|
||||||
t := shared.TypeOfT[T]()
|
|
||||||
v, found := nullables[t]
|
|
||||||
if !found {
|
|
||||||
var o reflect.Value
|
|
||||||
if k := t.Kind(); k == reflect.Map {
|
|
||||||
o = reflect.MakeMap(t)
|
|
||||||
} else if k == reflect.Slice {
|
|
||||||
// empty slices appear to all point to the same data block
|
|
||||||
// which causes comparisons to become ambiguous. so we create
|
|
||||||
// a slice with len/cap of one which ensures a unique address.
|
|
||||||
o = reflect.MakeSlice(t, 1, 1)
|
|
||||||
} else {
|
|
||||||
o = reflect.New(t.Elem())
|
|
||||||
}
|
|
||||||
v = o.Interface()
|
|
||||||
nullables[t] = v
|
|
||||||
}
|
|
||||||
// return the sentinel object
|
|
||||||
return v.(T)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNullValue returns true if the field contains a null sentinel value.
|
|
||||||
// This is used by custom marshallers to properly encode a null value.
|
|
||||||
func IsNullValue[T any](v T) bool {
|
|
||||||
// see if our map has a sentinel object for this *T
|
|
||||||
t := reflect.TypeOf(v)
|
|
||||||
if o, found := nullables[t]; found {
|
|
||||||
o1 := reflect.ValueOf(o)
|
|
||||||
v1 := reflect.ValueOf(v)
|
|
||||||
// we found it; return true if v points to the sentinel object.
|
|
||||||
// NOTE: maps and slices can only be compared to nil, else you get
|
|
||||||
// a runtime panic. so we compare addresses instead.
|
|
||||||
return o1.Pointer() == v1.Pointer()
|
|
||||||
}
|
|
||||||
// no sentinel object for this *t
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientOptions contains configuration settings for a client's pipeline.
|
|
||||||
type ClientOptions = policy.ClientOptions
|
|
||||||
|
|
||||||
// Client is a basic HTTP client. It consists of a pipeline and tracing provider.
|
|
||||||
type Client struct {
|
|
||||||
pl runtime.Pipeline
|
|
||||||
tr tracing.Tracer
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient creates a new Client instance with the provided values.
|
|
||||||
// - clientName - the fully qualified name of the client ("package.Client"); this is used by the tracing provider when creating spans
|
|
||||||
// - moduleVersion - the semantic version of the containing module; used by the telemetry policy
|
|
||||||
// - plOpts - pipeline configuration options; can be the zero-value
|
|
||||||
// - options - optional client configurations; pass nil to accept the default values
|
|
||||||
func NewClient(clientName, moduleVersion string, plOpts runtime.PipelineOptions, options *ClientOptions) (*Client, error) {
|
|
||||||
pkg, err := shared.ExtractPackageName(clientName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if options == nil {
|
|
||||||
options = &ClientOptions{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !options.Telemetry.Disabled {
|
|
||||||
if err := shared.ValidateModVer(moduleVersion); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pl := runtime.NewPipeline(pkg, moduleVersion, plOpts, options)
|
|
||||||
|
|
||||||
tr := options.TracingProvider.NewTracer(clientName, moduleVersion)
|
|
||||||
return &Client{pl: pl, tr: tr}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pipeline returns the pipeline for this client.
|
|
||||||
func (c *Client) Pipeline() runtime.Pipeline {
|
|
||||||
return c.pl
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tracer returns the tracer for this client.
|
|
||||||
func (c *Client) Tracer() tracing.Tracer {
|
|
||||||
return c.tr
|
|
||||||
}
|
|
257
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/doc.go
generated
vendored
257
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/doc.go
generated
vendored
|
@ -1,257 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
|
||||||
// Use of this source code is governed by an MIT
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package azcore implements an HTTP request/response middleware pipeline used by Azure SDK clients.
|
|
||||||
|
|
||||||
The middleware consists of three components.
|
|
||||||
|
|
||||||
- One or more Policy instances.
|
|
||||||
- A Transporter instance.
|
|
||||||
- A Pipeline instance that combines the Policy and Transporter instances.
|
|
||||||
|
|
||||||
# Implementing the Policy Interface
|
|
||||||
|
|
||||||
A Policy can be implemented in two ways; as a first-class function for a stateless Policy, or as
|
|
||||||
a method on a type for a stateful Policy. Note that HTTP requests made via the same pipeline share
|
|
||||||
the same Policy instances, so if a Policy mutates its state it MUST be properly synchronized to
|
|
||||||
avoid race conditions.
|
|
||||||
|
|
||||||
A Policy's Do method is called when an HTTP request wants to be sent over the network. The Do method can
|
|
||||||
perform any operation(s) it desires. For example, it can log the outgoing request, mutate the URL, headers,
|
|
||||||
and/or query parameters, inject a failure, etc. Once the Policy has successfully completed its request
|
|
||||||
work, it must call the Next() method on the *policy.Request instance in order to pass the request to the
|
|
||||||
next Policy in the chain.
|
|
||||||
|
|
||||||
When an HTTP response comes back, the Policy then gets a chance to process the response/error. The Policy instance
|
|
||||||
can log the response, retry the operation if it failed due to a transient error or timeout, unmarshal the response
|
|
||||||
body, etc. Once the Policy has successfully completed its response work, it must return the *http.Response
|
|
||||||
and error instances to its caller.
|
|
||||||
|
|
||||||
Template for implementing a stateless Policy:
|
|
||||||
|
|
||||||
type policyFunc func(*policy.Request) (*http.Response, error)
|
|
||||||
|
|
||||||
// Do implements the Policy interface on policyFunc.
|
|
||||||
func (pf policyFunc) Do(req *policy.Request) (*http.Response, error) {
|
|
||||||
return pf(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMyStatelessPolicy() policy.Policy {
|
|
||||||
return policyFunc(func(req *policy.Request) (*http.Response, error) {
|
|
||||||
// TODO: mutate/process Request here
|
|
||||||
|
|
||||||
// forward Request to next Policy & get Response/error
|
|
||||||
resp, err := req.Next()
|
|
||||||
|
|
||||||
// TODO: mutate/process Response/error here
|
|
||||||
|
|
||||||
// return Response/error to previous Policy
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Template for implementing a stateful Policy:
|
|
||||||
|
|
||||||
type MyStatefulPolicy struct {
|
|
||||||
// TODO: add configuration/setting fields here
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: add initialization args to NewMyStatefulPolicy()
|
|
||||||
func NewMyStatefulPolicy() policy.Policy {
|
|
||||||
return &MyStatefulPolicy{
|
|
||||||
// TODO: initialize configuration/setting fields here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *MyStatefulPolicy) Do(req *policy.Request) (resp *http.Response, err error) {
|
|
||||||
// TODO: mutate/process Request here
|
|
||||||
|
|
||||||
// forward Request to next Policy & get Response/error
|
|
||||||
resp, err := req.Next()
|
|
||||||
|
|
||||||
// TODO: mutate/process Response/error here
|
|
||||||
|
|
||||||
// return Response/error to previous Policy
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
# Implementing the Transporter Interface
|
|
||||||
|
|
||||||
The Transporter interface is responsible for sending the HTTP request and returning the corresponding
|
|
||||||
HTTP response or error. The Transporter is invoked by the last Policy in the chain. The default Transporter
|
|
||||||
implementation uses a shared http.Client from the standard library.
|
|
||||||
|
|
||||||
The same stateful/stateless rules for Policy implementations apply to Transporter implementations.
|
|
||||||
|
|
||||||
# Using Policy and Transporter Instances Via a Pipeline
|
|
||||||
|
|
||||||
To use the Policy and Transporter instances, an application passes them to the runtime.NewPipeline function.
|
|
||||||
|
|
||||||
func NewPipeline(transport Transporter, policies ...Policy) Pipeline
|
|
||||||
|
|
||||||
The specified Policy instances form a chain and are invoked in the order provided to NewPipeline
|
|
||||||
followed by the Transporter.
|
|
||||||
|
|
||||||
Once the Pipeline has been created, create a runtime.Request instance and pass it to Pipeline's Do method.
|
|
||||||
|
|
||||||
func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error)
|
|
||||||
|
|
||||||
func (p Pipeline) Do(req *Request) (*http.Request, error)
|
|
||||||
|
|
||||||
The Pipeline.Do method sends the specified Request through the chain of Policy and Transporter
|
|
||||||
instances. The response/error is then sent through the same chain of Policy instances in reverse
|
|
||||||
order. For example, assuming there are Policy types PolicyA, PolicyB, and PolicyC along with
|
|
||||||
TransportA.
|
|
||||||
|
|
||||||
pipeline := NewPipeline(TransportA, PolicyA, PolicyB, PolicyC)
|
|
||||||
|
|
||||||
The flow of Request and Response looks like the following:
|
|
||||||
|
|
||||||
policy.Request -> PolicyA -> PolicyB -> PolicyC -> TransportA -----+
|
|
||||||
|
|
|
||||||
HTTP(S) endpoint
|
|
||||||
|
|
|
||||||
caller <--------- PolicyA <- PolicyB <- PolicyC <- http.Response-+
|
|
||||||
|
|
||||||
# Creating a Request Instance
|
|
||||||
|
|
||||||
The Request instance passed to Pipeline's Do method is a wrapper around an *http.Request. It also
|
|
||||||
contains some internal state and provides various convenience methods. You create a Request instance
|
|
||||||
by calling the runtime.NewRequest function:
|
|
||||||
|
|
||||||
func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error)
|
|
||||||
|
|
||||||
If the Request should contain a body, call the SetBody method.
|
|
||||||
|
|
||||||
func (req *Request) SetBody(body ReadSeekCloser, contentType string) error
|
|
||||||
|
|
||||||
A seekable stream is required so that upon retry, the retry Policy instance can seek the stream
|
|
||||||
back to the beginning before retrying the network request and re-uploading the body.
|
|
||||||
|
|
||||||
# Sending an Explicit Null
|
|
||||||
|
|
||||||
Operations like JSON-MERGE-PATCH send a JSON null to indicate a value should be deleted.
|
|
||||||
|
|
||||||
{
|
|
||||||
"delete-me": null
|
|
||||||
}
|
|
||||||
|
|
||||||
This requirement conflicts with the SDK's default marshalling that specifies "omitempty" as
|
|
||||||
a means to resolve the ambiguity between a field to be excluded and its zero-value.
|
|
||||||
|
|
||||||
type Widget struct {
|
|
||||||
Name *string `json:",omitempty"`
|
|
||||||
Count *int `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
In the above example, Name and Count are defined as pointer-to-type to disambiguate between
|
|
||||||
a missing value (nil) and a zero-value (0) which might have semantic differences.
|
|
||||||
|
|
||||||
In a PATCH operation, any fields left as nil are to have their values preserved. When updating
|
|
||||||
a Widget's count, one simply specifies the new value for Count, leaving Name nil.
|
|
||||||
|
|
||||||
To fulfill the requirement for sending a JSON null, the NullValue() function can be used.
|
|
||||||
|
|
||||||
w := Widget{
|
|
||||||
Count: azcore.NullValue[*int](),
|
|
||||||
}
|
|
||||||
|
|
||||||
This sends an explict "null" for Count, indicating that any current value for Count should be deleted.
|
|
||||||
|
|
||||||
# Processing the Response
|
|
||||||
|
|
||||||
When the HTTP response is received, the *http.Response is returned directly. Each Policy instance
|
|
||||||
can inspect/mutate the *http.Response.
|
|
||||||
|
|
||||||
# Built-in Logging
|
|
||||||
|
|
||||||
To enable logging, set environment variable AZURE_SDK_GO_LOGGING to "all" before executing your program.
|
|
||||||
|
|
||||||
By default the logger writes to stderr. This can be customized by calling log.SetListener, providing
|
|
||||||
a callback that writes to the desired location. Any custom logging implementation MUST provide its
|
|
||||||
own synchronization to handle concurrent invocations.
|
|
||||||
|
|
||||||
See the docs for the log package for further details.
|
|
||||||
|
|
||||||
# Pageable Operations
|
|
||||||
|
|
||||||
Pageable operations return potentially large data sets spread over multiple GET requests. The result of
|
|
||||||
each GET is a "page" of data consisting of a slice of items.
|
|
||||||
|
|
||||||
Pageable operations can be identified by their New*Pager naming convention and return type of *runtime.Pager[T].
|
|
||||||
|
|
||||||
func (c *WidgetClient) NewListWidgetsPager(o *Options) *runtime.Pager[PageResponse]
|
|
||||||
|
|
||||||
The call to WidgetClient.NewListWidgetsPager() returns an instance of *runtime.Pager[T] for fetching pages
|
|
||||||
and determining if there are more pages to fetch. No IO calls are made until the NextPage() method is invoked.
|
|
||||||
|
|
||||||
pager := widgetClient.NewListWidgetsPager(nil)
|
|
||||||
for pager.More() {
|
|
||||||
page, err := pager.NextPage(context.TODO())
|
|
||||||
// handle err
|
|
||||||
for _, widget := range page.Values {
|
|
||||||
// process widget
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Long-Running Operations
|
|
||||||
|
|
||||||
Long-running operations (LROs) are operations consisting of an initial request to start the operation followed
|
|
||||||
by polling to determine when the operation has reached a terminal state. An LRO's terminal state is one
|
|
||||||
of the following values.
|
|
||||||
|
|
||||||
- Succeeded - the LRO completed successfully
|
|
||||||
- Failed - the LRO failed to complete
|
|
||||||
- Canceled - the LRO was canceled
|
|
||||||
|
|
||||||
LROs can be identified by their Begin* prefix and their return type of *runtime.Poller[T].
|
|
||||||
|
|
||||||
func (c *WidgetClient) BeginCreateOrUpdate(ctx context.Context, w Widget, o *Options) (*runtime.Poller[Response], error)
|
|
||||||
|
|
||||||
When a call to WidgetClient.BeginCreateOrUpdate() returns a nil error, it means that the LRO has started.
|
|
||||||
It does _not_ mean that the widget has been created or updated (or failed to be created/updated).
|
|
||||||
|
|
||||||
The *runtime.Poller[T] provides APIs for determining the state of the LRO. To wait for the LRO to complete,
|
|
||||||
call the PollUntilDone() method.
|
|
||||||
|
|
||||||
poller, err := widgetClient.BeginCreateOrUpdate(context.TODO(), Widget{}, nil)
|
|
||||||
// handle err
|
|
||||||
result, err := poller.PollUntilDone(context.TODO(), nil)
|
|
||||||
// handle err
|
|
||||||
// use result
|
|
||||||
|
|
||||||
The call to PollUntilDone() will block the current goroutine until the LRO has reached a terminal state or the
|
|
||||||
context is canceled/timed out.
|
|
||||||
|
|
||||||
Note that LROs can take anywhere from several seconds to several minutes. The duration is operation-dependent. Due to
|
|
||||||
this variant behavior, pollers do _not_ have a preconfigured time-out. Use a context with the appropriate cancellation
|
|
||||||
mechanism as required.
|
|
||||||
|
|
||||||
# Resume Tokens
|
|
||||||
|
|
||||||
Pollers provide the ability to serialize their state into a "resume token" which can be used by another process to
|
|
||||||
recreate the poller. This is achieved via the runtime.Poller[T].ResumeToken() method.
|
|
||||||
|
|
||||||
token, err := poller.ResumeToken()
|
|
||||||
// handle error
|
|
||||||
|
|
||||||
Note that a token can only be obtained for a poller that's in a non-terminal state. Also note that any subsequent calls
|
|
||||||
to poller.Poll() might change the poller's state. In this case, a new token should be created.
|
|
||||||
|
|
||||||
After the token has been obtained, it can be used to recreate an instance of the originating poller.
|
|
||||||
|
|
||||||
poller, err := widgetClient.BeginCreateOrUpdate(nil, Widget{}, &Options{
|
|
||||||
ResumeToken: token,
|
|
||||||
})
|
|
||||||
|
|
||||||
When resuming a poller, no IO is performed, and zero-value arguments can be used for everything but the Options.ResumeToken.
|
|
||||||
|
|
||||||
Resume tokens are unique per service client and operation. Attempting to resume a poller for LRO BeginB() with a token from LRO
|
|
||||||
BeginA() will result in an error.
|
|
||||||
*/
|
|
||||||
package azcore
|
|
14
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/errors.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/errors.go
generated
vendored
|
@ -1,14 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package azcore
|
|
||||||
|
|
||||||
import "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
|
|
||||||
// ResponseError is returned when a request is made to a service and
|
|
||||||
// the service returns a non-success HTTP status code.
|
|
||||||
// Use errors.As() to access this type in the error chain.
|
|
||||||
type ResponseError = exported.ResponseError
|
|
48
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/etag.go
generated
vendored
48
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/etag.go
generated
vendored
|
@ -1,48 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package azcore
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ETag is a property used for optimistic concurrency during updates
|
|
||||||
// ETag is a validator based on https://tools.ietf.org/html/rfc7232#section-2.3.2
|
|
||||||
// An ETag can be empty ("").
|
|
||||||
type ETag string
|
|
||||||
|
|
||||||
// ETagAny is an ETag that represents everything, the value is "*"
|
|
||||||
const ETagAny ETag = "*"
|
|
||||||
|
|
||||||
// Equals does a strong comparison of two ETags. Equals returns true when both
|
|
||||||
// ETags are not weak and the values of the underlying strings are equal.
|
|
||||||
func (e ETag) Equals(other ETag) bool {
|
|
||||||
return !e.IsWeak() && !other.IsWeak() && e == other
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeakEquals does a weak comparison of two ETags. Two ETags are equivalent if their opaque-tags match
|
|
||||||
// character-by-character, regardless of either or both being tagged as "weak".
|
|
||||||
func (e ETag) WeakEquals(other ETag) bool {
|
|
||||||
getStart := func(e1 ETag) int {
|
|
||||||
if e1.IsWeak() {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
aStart := getStart(e)
|
|
||||||
bStart := getStart(other)
|
|
||||||
|
|
||||||
aVal := e[aStart:]
|
|
||||||
bVal := other[bStart:]
|
|
||||||
|
|
||||||
return aVal == bVal
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsWeak specifies whether the ETag is strong or weak.
|
|
||||||
func (e ETag) IsWeak() bool {
|
|
||||||
return len(e) >= 4 && strings.HasPrefix(string(e), "W/\"") && strings.HasSuffix(string(e), "\"")
|
|
||||||
}
|
|
67
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/exported.go
generated
vendored
67
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/exported.go
generated
vendored
|
@ -1,67 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package exported
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type nopCloser struct {
|
|
||||||
io.ReadSeeker
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n nopCloser) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NopCloser returns a ReadSeekCloser with a no-op close method wrapping the provided io.ReadSeeker.
|
|
||||||
// Exported as streaming.NopCloser().
|
|
||||||
func NopCloser(rs io.ReadSeeker) io.ReadSeekCloser {
|
|
||||||
return nopCloser{rs}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasStatusCode returns true if the Response's status code is one of the specified values.
|
|
||||||
// Exported as runtime.HasStatusCode().
|
|
||||||
func HasStatusCode(resp *http.Response, statusCodes ...int) bool {
|
|
||||||
if resp == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, sc := range statusCodes {
|
|
||||||
if resp.StatusCode == sc {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// AccessToken represents an Azure service bearer access token with expiry information.
|
|
||||||
// Exported as azcore.AccessToken.
|
|
||||||
type AccessToken struct {
|
|
||||||
Token string
|
|
||||||
ExpiresOn time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenRequestOptions contain specific parameter that may be used by credentials types when attempting to get a token.
|
|
||||||
// Exported as policy.TokenRequestOptions.
|
|
||||||
type TokenRequestOptions struct {
|
|
||||||
// Scopes contains the list of permission scopes required for the token.
|
|
||||||
Scopes []string
|
|
||||||
|
|
||||||
// TenantID identifies the tenant from which to request the token. azidentity credentials authenticate in
|
|
||||||
// their configured default tenants when this field isn't set.
|
|
||||||
TenantID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenCredential represents a credential capable of providing an OAuth token.
|
|
||||||
// Exported as azcore.TokenCredential.
|
|
||||||
type TokenCredential interface {
|
|
||||||
// GetToken requests an access token for the specified set of scopes.
|
|
||||||
GetToken(ctx context.Context, options TokenRequestOptions) (AccessToken, error)
|
|
||||||
}
|
|
97
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/pipeline.go
generated
vendored
97
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/pipeline.go
generated
vendored
|
@ -1,97 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package exported
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"golang.org/x/net/http/httpguts"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Policy represents an extensibility point for the Pipeline that can mutate the specified
|
|
||||||
// Request and react to the received Response.
|
|
||||||
// Exported as policy.Policy.
|
|
||||||
type Policy interface {
|
|
||||||
// Do applies the policy to the specified Request. When implementing a Policy, mutate the
|
|
||||||
// request before calling req.Next() to move on to the next policy, and respond to the result
|
|
||||||
// before returning to the caller.
|
|
||||||
Do(req *Request) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pipeline represents a primitive for sending HTTP requests and receiving responses.
|
|
||||||
// Its behavior can be extended by specifying policies during construction.
|
|
||||||
// Exported as runtime.Pipeline.
|
|
||||||
type Pipeline struct {
|
|
||||||
policies []Policy
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transporter represents an HTTP pipeline transport used to send HTTP requests and receive responses.
|
|
||||||
// Exported as policy.Transporter.
|
|
||||||
type Transporter interface {
|
|
||||||
// Do sends the HTTP request and returns the HTTP response or error.
|
|
||||||
Do(req *http.Request) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// used to adapt a TransportPolicy to a Policy
|
|
||||||
type transportPolicy struct {
|
|
||||||
trans Transporter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tp transportPolicy) Do(req *Request) (*http.Response, error) {
|
|
||||||
if tp.trans == nil {
|
|
||||||
return nil, errors.New("missing transporter")
|
|
||||||
}
|
|
||||||
resp, err := tp.trans.Do(req.Raw())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if resp == nil {
|
|
||||||
// there was no response and no error (rare but can happen)
|
|
||||||
// this ensures the retry policy will retry the request
|
|
||||||
return nil, errors.New("received nil response")
|
|
||||||
}
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPipeline creates a new Pipeline object from the specified Policies.
|
|
||||||
// Not directly exported, but used as part of runtime.NewPipeline().
|
|
||||||
func NewPipeline(transport Transporter, policies ...Policy) Pipeline {
|
|
||||||
// transport policy must always be the last in the slice
|
|
||||||
policies = append(policies, transportPolicy{trans: transport})
|
|
||||||
return Pipeline{
|
|
||||||
policies: policies,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do is called for each and every HTTP request. It passes the request through all
|
|
||||||
// the Policy objects (which can transform the Request's URL/query parameters/headers)
|
|
||||||
// and ultimately sends the transformed HTTP request over the network.
|
|
||||||
func (p Pipeline) Do(req *Request) (*http.Response, error) {
|
|
||||||
if req == nil {
|
|
||||||
return nil, errors.New("request cannot be nil")
|
|
||||||
}
|
|
||||||
// check copied from Transport.roundTrip()
|
|
||||||
for k, vv := range req.Raw().Header {
|
|
||||||
if !httpguts.ValidHeaderFieldName(k) {
|
|
||||||
if req.Raw().Body != nil {
|
|
||||||
req.Raw().Body.Close()
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("invalid header field name %q", k)
|
|
||||||
}
|
|
||||||
for _, v := range vv {
|
|
||||||
if !httpguts.ValidHeaderFieldValue(v) {
|
|
||||||
if req.Raw().Body != nil {
|
|
||||||
req.Raw().Body.Close()
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("invalid header field value %q for key %v", v, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.policies = p.policies
|
|
||||||
return req.Next()
|
|
||||||
}
|
|
182
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go
generated
vendored
182
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go
generated
vendored
|
@ -1,182 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package exported
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Request is an abstraction over the creation of an HTTP request as it passes through the pipeline.
|
|
||||||
// Don't use this type directly, use NewRequest() instead.
|
|
||||||
// Exported as policy.Request.
|
|
||||||
type Request struct {
|
|
||||||
req *http.Request
|
|
||||||
body io.ReadSeekCloser
|
|
||||||
policies []Policy
|
|
||||||
values opValues
|
|
||||||
}
|
|
||||||
|
|
||||||
type opValues map[reflect.Type]interface{}
|
|
||||||
|
|
||||||
// Set adds/changes a value
|
|
||||||
func (ov opValues) set(value interface{}) {
|
|
||||||
ov[reflect.TypeOf(value)] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get looks for a value set by SetValue first
|
|
||||||
func (ov opValues) get(value interface{}) bool {
|
|
||||||
v, ok := ov[reflect.ValueOf(value).Elem().Type()]
|
|
||||||
if ok {
|
|
||||||
reflect.ValueOf(value).Elem().Set(reflect.ValueOf(v))
|
|
||||||
}
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRequest creates a new Request with the specified input.
|
|
||||||
// Exported as runtime.NewRequest().
|
|
||||||
func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error) {
|
|
||||||
req, err := http.NewRequestWithContext(ctx, httpMethod, endpoint, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if req.URL.Host == "" {
|
|
||||||
return nil, errors.New("no Host in request URL")
|
|
||||||
}
|
|
||||||
if !(req.URL.Scheme == "http" || req.URL.Scheme == "https") {
|
|
||||||
return nil, fmt.Errorf("unsupported protocol scheme %s", req.URL.Scheme)
|
|
||||||
}
|
|
||||||
return &Request{req: req}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Body returns the original body specified when the Request was created.
|
|
||||||
func (req *Request) Body() io.ReadSeekCloser {
|
|
||||||
return req.body
|
|
||||||
}
|
|
||||||
|
|
||||||
// Raw returns the underlying HTTP request.
|
|
||||||
func (req *Request) Raw() *http.Request {
|
|
||||||
return req.req
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next calls the next policy in the pipeline.
|
|
||||||
// If there are no more policies, nil and an error are returned.
|
|
||||||
// This method is intended to be called from pipeline policies.
|
|
||||||
// To send a request through a pipeline call Pipeline.Do().
|
|
||||||
func (req *Request) Next() (*http.Response, error) {
|
|
||||||
if len(req.policies) == 0 {
|
|
||||||
return nil, errors.New("no more policies")
|
|
||||||
}
|
|
||||||
nextPolicy := req.policies[0]
|
|
||||||
nextReq := *req
|
|
||||||
nextReq.policies = nextReq.policies[1:]
|
|
||||||
return nextPolicy.Do(&nextReq)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOperationValue adds/changes a mutable key/value associated with a single operation.
|
|
||||||
func (req *Request) SetOperationValue(value interface{}) {
|
|
||||||
if req.values == nil {
|
|
||||||
req.values = opValues{}
|
|
||||||
}
|
|
||||||
req.values.set(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OperationValue looks for a value set by SetOperationValue().
|
|
||||||
func (req *Request) OperationValue(value interface{}) bool {
|
|
||||||
if req.values == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return req.values.get(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBody sets the specified ReadSeekCloser as the HTTP request body, and sets Content-Type and Content-Length
|
|
||||||
// accordingly. If the ReadSeekCloser is nil or empty, Content-Length won't be set. If contentType is "",
|
|
||||||
// Content-Type won't be set.
|
|
||||||
// Use streaming.NopCloser to turn an io.ReadSeeker into an io.ReadSeekCloser.
|
|
||||||
func (req *Request) SetBody(body io.ReadSeekCloser, contentType string) error {
|
|
||||||
var err error
|
|
||||||
var size int64
|
|
||||||
if body != nil {
|
|
||||||
size, err = body.Seek(0, io.SeekEnd) // Seek to the end to get the stream's size
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if size == 0 {
|
|
||||||
// treat an empty stream the same as a nil one: assign req a nil body
|
|
||||||
body = nil
|
|
||||||
// RFC 9110 specifies a client shouldn't set Content-Length on a request containing no content
|
|
||||||
// (Del is a no-op when the header has no value)
|
|
||||||
req.req.Header.Del(shared.HeaderContentLength)
|
|
||||||
} else {
|
|
||||||
_, err = body.Seek(0, io.SeekStart)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.req.Header.Set(shared.HeaderContentLength, strconv.FormatInt(size, 10))
|
|
||||||
req.Raw().GetBody = func() (io.ReadCloser, error) {
|
|
||||||
_, err := body.Seek(0, io.SeekStart) // Seek back to the beginning of the stream
|
|
||||||
return body, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// keep a copy of the body argument. this is to handle cases
|
|
||||||
// where req.Body is replaced, e.g. httputil.DumpRequest and friends.
|
|
||||||
req.body = body
|
|
||||||
req.req.Body = body
|
|
||||||
req.req.ContentLength = size
|
|
||||||
if contentType == "" {
|
|
||||||
// Del is a no-op when the header has no value
|
|
||||||
req.req.Header.Del(shared.HeaderContentType)
|
|
||||||
} else {
|
|
||||||
req.req.Header.Set(shared.HeaderContentType, contentType)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RewindBody seeks the request's Body stream back to the beginning so it can be resent when retrying an operation.
|
|
||||||
func (req *Request) RewindBody() error {
|
|
||||||
if req.body != nil {
|
|
||||||
// Reset the stream back to the beginning and restore the body
|
|
||||||
_, err := req.body.Seek(0, io.SeekStart)
|
|
||||||
req.req.Body = req.body
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the request body.
|
|
||||||
func (req *Request) Close() error {
|
|
||||||
if req.body == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return req.body.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clone returns a deep copy of the request with its context changed to ctx.
|
|
||||||
func (req *Request) Clone(ctx context.Context) *Request {
|
|
||||||
r2 := *req
|
|
||||||
r2.req = req.req.Clone(ctx)
|
|
||||||
return &r2
|
|
||||||
}
|
|
||||||
|
|
||||||
// not exported but dependent on Request
|
|
||||||
|
|
||||||
// PolicyFunc is a type that implements the Policy interface.
|
|
||||||
// Use this type when implementing a stateless policy as a first-class function.
|
|
||||||
type PolicyFunc func(*Request) (*http.Response, error)
|
|
||||||
|
|
||||||
// Do implements the Policy interface on policyFunc.
|
|
||||||
func (pf PolicyFunc) Do(req *Request) (*http.Response, error) {
|
|
||||||
return pf(req)
|
|
||||||
}
|
|
144
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/response_error.go
generated
vendored
144
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/response_error.go
generated
vendored
|
@ -1,144 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package exported
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/exported"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewResponseError creates a new *ResponseError from the provided HTTP response.
|
|
||||||
// Exported as runtime.NewResponseError().
|
|
||||||
func NewResponseError(resp *http.Response) error {
|
|
||||||
respErr := &ResponseError{
|
|
||||||
StatusCode: resp.StatusCode,
|
|
||||||
RawResponse: resp,
|
|
||||||
}
|
|
||||||
|
|
||||||
// prefer the error code in the response header
|
|
||||||
if ec := resp.Header.Get("x-ms-error-code"); ec != "" {
|
|
||||||
respErr.ErrorCode = ec
|
|
||||||
return respErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we didn't get x-ms-error-code, check in the response body
|
|
||||||
body, err := exported.Payload(resp, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(body) > 0 {
|
|
||||||
if code := extractErrorCodeJSON(body); code != "" {
|
|
||||||
respErr.ErrorCode = code
|
|
||||||
} else if code := extractErrorCodeXML(body); code != "" {
|
|
||||||
respErr.ErrorCode = code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return respErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractErrorCodeJSON(body []byte) string {
|
|
||||||
var rawObj map[string]interface{}
|
|
||||||
if err := json.Unmarshal(body, &rawObj); err != nil {
|
|
||||||
// not a JSON object
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if this is a wrapped error, i.e. { "error": { ... } }
|
|
||||||
// if so then unwrap it
|
|
||||||
if wrapped, ok := rawObj["error"]; ok {
|
|
||||||
unwrapped, ok := wrapped.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
rawObj = unwrapped
|
|
||||||
} else if wrapped, ok := rawObj["odata.error"]; ok {
|
|
||||||
// check if this a wrapped odata error, i.e. { "odata.error": { ... } }
|
|
||||||
unwrapped, ok := wrapped.(map[string]any)
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
rawObj = unwrapped
|
|
||||||
}
|
|
||||||
|
|
||||||
// now check for the error code
|
|
||||||
code, ok := rawObj["code"]
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
codeStr, ok := code.(string)
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return codeStr
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractErrorCodeXML(body []byte) string {
|
|
||||||
// regular expression is much easier than dealing with the XML parser
|
|
||||||
rx := regexp.MustCompile(`<(?:\w+:)?[c|C]ode>\s*(\w+)\s*<\/(?:\w+:)?[c|C]ode>`)
|
|
||||||
res := rx.FindStringSubmatch(string(body))
|
|
||||||
if len(res) != 2 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
// first submatch is the entire thing, second one is the captured error code
|
|
||||||
return res[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResponseError is returned when a request is made to a service and
|
|
||||||
// the service returns a non-success HTTP status code.
|
|
||||||
// Use errors.As() to access this type in the error chain.
|
|
||||||
// Exported as azcore.ResponseError.
|
|
||||||
type ResponseError struct {
|
|
||||||
// ErrorCode is the error code returned by the resource provider if available.
|
|
||||||
ErrorCode string
|
|
||||||
|
|
||||||
// StatusCode is the HTTP status code as defined in https://pkg.go.dev/net/http#pkg-constants.
|
|
||||||
StatusCode int
|
|
||||||
|
|
||||||
// RawResponse is the underlying HTTP response.
|
|
||||||
RawResponse *http.Response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error implements the error interface for type ResponseError.
|
|
||||||
// Note that the message contents are not contractual and can change over time.
|
|
||||||
func (e *ResponseError) Error() string {
|
|
||||||
// write the request method and URL with response status code
|
|
||||||
msg := &bytes.Buffer{}
|
|
||||||
fmt.Fprintf(msg, "%s %s://%s%s\n", e.RawResponse.Request.Method, e.RawResponse.Request.URL.Scheme, e.RawResponse.Request.URL.Host, e.RawResponse.Request.URL.Path)
|
|
||||||
fmt.Fprintln(msg, "--------------------------------------------------------------------------------")
|
|
||||||
fmt.Fprintf(msg, "RESPONSE %d: %s\n", e.RawResponse.StatusCode, e.RawResponse.Status)
|
|
||||||
if e.ErrorCode != "" {
|
|
||||||
fmt.Fprintf(msg, "ERROR CODE: %s\n", e.ErrorCode)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintln(msg, "ERROR CODE UNAVAILABLE")
|
|
||||||
}
|
|
||||||
fmt.Fprintln(msg, "--------------------------------------------------------------------------------")
|
|
||||||
body, err := exported.Payload(e.RawResponse, nil)
|
|
||||||
if err != nil {
|
|
||||||
// this really shouldn't fail at this point as the response
|
|
||||||
// body is already cached (it was read in NewResponseError)
|
|
||||||
fmt.Fprintf(msg, "Error reading response body: %v", err)
|
|
||||||
} else if len(body) > 0 {
|
|
||||||
if err := json.Indent(msg, body, "", " "); err != nil {
|
|
||||||
// failed to pretty-print so just dump it verbatim
|
|
||||||
fmt.Fprint(msg, string(body))
|
|
||||||
}
|
|
||||||
// the standard library doesn't have a pretty-printer for XML
|
|
||||||
fmt.Fprintln(msg)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintln(msg, "Response contained no body")
|
|
||||||
}
|
|
||||||
fmt.Fprintln(msg, "--------------------------------------------------------------------------------")
|
|
||||||
|
|
||||||
return msg.String()
|
|
||||||
}
|
|
38
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log/log.go
generated
vendored
38
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log/log.go
generated
vendored
|
@ -1,38 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
// This is an internal helper package to combine the complete logging APIs.
|
|
||||||
package log
|
|
||||||
|
|
||||||
import (
|
|
||||||
azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Event = log.Event
|
|
||||||
|
|
||||||
const (
|
|
||||||
EventRequest = azlog.EventRequest
|
|
||||||
EventResponse = azlog.EventResponse
|
|
||||||
EventRetryPolicy = azlog.EventRetryPolicy
|
|
||||||
EventLRO = azlog.EventLRO
|
|
||||||
)
|
|
||||||
|
|
||||||
func Write(cls log.Event, msg string) {
|
|
||||||
log.Write(cls, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Writef(cls log.Event, format string, a ...interface{}) {
|
|
||||||
log.Writef(cls, format, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetListener(lst func(Event, string)) {
|
|
||||||
log.SetListener(lst)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Should(cls log.Event) bool {
|
|
||||||
return log.Should(cls)
|
|
||||||
}
|
|
159
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async/async.go
generated
vendored
159
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async/async.go
generated
vendored
|
@ -1,159 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package async
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
|
||||||
)
|
|
||||||
|
|
||||||
// see https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/async-api-reference.md
|
|
||||||
|
|
||||||
// Applicable returns true if the LRO is using Azure-AsyncOperation.
|
|
||||||
func Applicable(resp *http.Response) bool {
|
|
||||||
return resp.Header.Get(shared.HeaderAzureAsync) != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// CanResume returns true if the token can rehydrate this poller type.
|
|
||||||
func CanResume(token map[string]interface{}) bool {
|
|
||||||
_, ok := token["asyncURL"]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poller is an LRO poller that uses the Azure-AsyncOperation pattern.
|
|
||||||
type Poller[T any] struct {
|
|
||||||
pl exported.Pipeline
|
|
||||||
|
|
||||||
resp *http.Response
|
|
||||||
|
|
||||||
// The URL from Azure-AsyncOperation header.
|
|
||||||
AsyncURL string `json:"asyncURL"`
|
|
||||||
|
|
||||||
// The URL from Location header.
|
|
||||||
LocURL string `json:"locURL"`
|
|
||||||
|
|
||||||
// The URL from the initial LRO request.
|
|
||||||
OrigURL string `json:"origURL"`
|
|
||||||
|
|
||||||
// The HTTP method from the initial LRO request.
|
|
||||||
Method string `json:"method"`
|
|
||||||
|
|
||||||
// The value of final-state-via from swagger, can be the empty string.
|
|
||||||
FinalState pollers.FinalStateVia `json:"finalState"`
|
|
||||||
|
|
||||||
// The LRO's current state.
|
|
||||||
CurState string `json:"state"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new Poller from the provided initial response and final-state type.
|
|
||||||
// Pass nil for response to create an empty Poller for rehydration.
|
|
||||||
func New[T any](pl exported.Pipeline, resp *http.Response, finalState pollers.FinalStateVia) (*Poller[T], error) {
|
|
||||||
if resp == nil {
|
|
||||||
log.Write(log.EventLRO, "Resuming Azure-AsyncOperation poller.")
|
|
||||||
return &Poller[T]{pl: pl}, nil
|
|
||||||
}
|
|
||||||
log.Write(log.EventLRO, "Using Azure-AsyncOperation poller.")
|
|
||||||
asyncURL := resp.Header.Get(shared.HeaderAzureAsync)
|
|
||||||
if asyncURL == "" {
|
|
||||||
return nil, errors.New("response is missing Azure-AsyncOperation header")
|
|
||||||
}
|
|
||||||
if !poller.IsValidURL(asyncURL) {
|
|
||||||
return nil, fmt.Errorf("invalid polling URL %s", asyncURL)
|
|
||||||
}
|
|
||||||
// check for provisioning state. if the operation is a RELO
|
|
||||||
// and terminates synchronously this will prevent extra polling.
|
|
||||||
// it's ok if there's no provisioning state.
|
|
||||||
state, _ := poller.GetProvisioningState(resp)
|
|
||||||
if state == "" {
|
|
||||||
state = poller.StatusInProgress
|
|
||||||
}
|
|
||||||
p := &Poller[T]{
|
|
||||||
pl: pl,
|
|
||||||
resp: resp,
|
|
||||||
AsyncURL: asyncURL,
|
|
||||||
LocURL: resp.Header.Get(shared.HeaderLocation),
|
|
||||||
OrigURL: resp.Request.URL.String(),
|
|
||||||
Method: resp.Request.Method,
|
|
||||||
FinalState: finalState,
|
|
||||||
CurState: state,
|
|
||||||
}
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done returns true if the LRO is in a terminal state.
|
|
||||||
func (p *Poller[T]) Done() bool {
|
|
||||||
return poller.IsTerminalState(p.CurState)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poll retrieves the current state of the LRO.
|
|
||||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
|
||||||
err := pollers.PollHelper(ctx, p.AsyncURL, p.pl, func(resp *http.Response) (string, error) {
|
|
||||||
if !poller.StatusCodeValid(resp) {
|
|
||||||
p.resp = resp
|
|
||||||
return "", exported.NewResponseError(resp)
|
|
||||||
}
|
|
||||||
state, err := poller.GetStatus(resp)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
} else if state == "" {
|
|
||||||
return "", errors.New("the response did not contain a status")
|
|
||||||
}
|
|
||||||
p.resp = resp
|
|
||||||
p.CurState = state
|
|
||||||
return p.CurState, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return p.resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
|
||||||
if p.resp.StatusCode == http.StatusNoContent {
|
|
||||||
return nil
|
|
||||||
} else if poller.Failed(p.CurState) {
|
|
||||||
return exported.NewResponseError(p.resp)
|
|
||||||
}
|
|
||||||
var req *exported.Request
|
|
||||||
var err error
|
|
||||||
if p.Method == http.MethodPatch || p.Method == http.MethodPut {
|
|
||||||
// for PATCH and PUT, the final GET is on the original resource URL
|
|
||||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL)
|
|
||||||
} else if p.Method == http.MethodPost {
|
|
||||||
if p.FinalState == pollers.FinalStateViaAzureAsyncOp {
|
|
||||||
// no final GET required
|
|
||||||
} else if p.FinalState == pollers.FinalStateViaOriginalURI {
|
|
||||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL)
|
|
||||||
} else if p.LocURL != "" {
|
|
||||||
// ideally FinalState would be set to "location" but it isn't always.
|
|
||||||
// must check last due to more permissive condition.
|
|
||||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// if a final GET request has been created, execute it
|
|
||||||
if req != nil {
|
|
||||||
resp, err := p.pl.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.resp = resp
|
|
||||||
}
|
|
||||||
|
|
||||||
return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), out)
|
|
||||||
}
|
|
135
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body/body.go
generated
vendored
135
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body/body.go
generated
vendored
|
@ -1,135 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package body
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Kind is the identifier of this type in a resume token.
|
|
||||||
const kind = "body"
|
|
||||||
|
|
||||||
// Applicable returns true if the LRO is using no headers, just provisioning state.
|
|
||||||
// This is only applicable to PATCH and PUT methods and assumes no polling headers.
|
|
||||||
func Applicable(resp *http.Response) bool {
|
|
||||||
// we can't check for absense of headers due to some misbehaving services
|
|
||||||
// like redis that return a Location header but don't actually use that protocol
|
|
||||||
return resp.Request.Method == http.MethodPatch || resp.Request.Method == http.MethodPut
|
|
||||||
}
|
|
||||||
|
|
||||||
// CanResume returns true if the token can rehydrate this poller type.
|
|
||||||
func CanResume(token map[string]interface{}) bool {
|
|
||||||
t, ok := token["type"]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
tt, ok := t.(string)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return tt == kind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poller is an LRO poller that uses the Body pattern.
|
|
||||||
type Poller[T any] struct {
|
|
||||||
pl exported.Pipeline
|
|
||||||
|
|
||||||
resp *http.Response
|
|
||||||
|
|
||||||
// The poller's type, used for resume token processing.
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// The URL for polling.
|
|
||||||
PollURL string `json:"pollURL"`
|
|
||||||
|
|
||||||
// The LRO's current state.
|
|
||||||
CurState string `json:"state"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new Poller from the provided initial response.
|
|
||||||
// Pass nil for response to create an empty Poller for rehydration.
|
|
||||||
func New[T any](pl exported.Pipeline, resp *http.Response) (*Poller[T], error) {
|
|
||||||
if resp == nil {
|
|
||||||
log.Write(log.EventLRO, "Resuming Body poller.")
|
|
||||||
return &Poller[T]{pl: pl}, nil
|
|
||||||
}
|
|
||||||
log.Write(log.EventLRO, "Using Body poller.")
|
|
||||||
p := &Poller[T]{
|
|
||||||
pl: pl,
|
|
||||||
resp: resp,
|
|
||||||
Type: kind,
|
|
||||||
PollURL: resp.Request.URL.String(),
|
|
||||||
}
|
|
||||||
// default initial state to InProgress. depending on the HTTP
|
|
||||||
// status code and provisioning state, we might change the value.
|
|
||||||
curState := poller.StatusInProgress
|
|
||||||
provState, err := poller.GetProvisioningState(resp)
|
|
||||||
if err != nil && !errors.Is(err, poller.ErrNoBody) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.StatusCode == http.StatusCreated && provState != "" {
|
|
||||||
// absense of provisioning state is ok for a 201, means the operation is in progress
|
|
||||||
curState = provState
|
|
||||||
} else if resp.StatusCode == http.StatusOK {
|
|
||||||
if provState != "" {
|
|
||||||
curState = provState
|
|
||||||
} else if provState == "" {
|
|
||||||
// for a 200, absense of provisioning state indicates success
|
|
||||||
curState = poller.StatusSucceeded
|
|
||||||
}
|
|
||||||
} else if resp.StatusCode == http.StatusNoContent {
|
|
||||||
curState = poller.StatusSucceeded
|
|
||||||
}
|
|
||||||
p.CurState = curState
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Done() bool {
|
|
||||||
return poller.IsTerminalState(p.CurState)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
|
||||||
err := pollers.PollHelper(ctx, p.PollURL, p.pl, func(resp *http.Response) (string, error) {
|
|
||||||
if !poller.StatusCodeValid(resp) {
|
|
||||||
p.resp = resp
|
|
||||||
return "", exported.NewResponseError(resp)
|
|
||||||
}
|
|
||||||
if resp.StatusCode == http.StatusNoContent {
|
|
||||||
p.resp = resp
|
|
||||||
p.CurState = poller.StatusSucceeded
|
|
||||||
return p.CurState, nil
|
|
||||||
}
|
|
||||||
state, err := poller.GetProvisioningState(resp)
|
|
||||||
if errors.Is(err, poller.ErrNoBody) {
|
|
||||||
// a missing response body in non-204 case is an error
|
|
||||||
return "", err
|
|
||||||
} else if state == "" {
|
|
||||||
// a response body without provisioning state is considered terminal success
|
|
||||||
state = poller.StatusSucceeded
|
|
||||||
} else if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
p.resp = resp
|
|
||||||
p.CurState = state
|
|
||||||
return p.CurState, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return p.resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
|
||||||
return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), out)
|
|
||||||
}
|
|
119
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc/loc.go
generated
vendored
119
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc/loc.go
generated
vendored
|
@ -1,119 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package loc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Kind is the identifier of this type in a resume token.
|
|
||||||
const kind = "loc"
|
|
||||||
|
|
||||||
// Applicable returns true if the LRO is using Location.
|
|
||||||
func Applicable(resp *http.Response) bool {
|
|
||||||
return resp.Header.Get(shared.HeaderLocation) != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// CanResume returns true if the token can rehydrate this poller type.
|
|
||||||
func CanResume(token map[string]interface{}) bool {
|
|
||||||
t, ok := token["type"]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
tt, ok := t.(string)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return tt == kind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poller is an LRO poller that uses the Location pattern.
|
|
||||||
type Poller[T any] struct {
|
|
||||||
pl exported.Pipeline
|
|
||||||
resp *http.Response
|
|
||||||
|
|
||||||
Type string `json:"type"`
|
|
||||||
PollURL string `json:"pollURL"`
|
|
||||||
CurState string `json:"state"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new Poller from the provided initial response.
|
|
||||||
// Pass nil for response to create an empty Poller for rehydration.
|
|
||||||
func New[T any](pl exported.Pipeline, resp *http.Response) (*Poller[T], error) {
|
|
||||||
if resp == nil {
|
|
||||||
log.Write(log.EventLRO, "Resuming Location poller.")
|
|
||||||
return &Poller[T]{pl: pl}, nil
|
|
||||||
}
|
|
||||||
log.Write(log.EventLRO, "Using Location poller.")
|
|
||||||
locURL := resp.Header.Get(shared.HeaderLocation)
|
|
||||||
if locURL == "" {
|
|
||||||
return nil, errors.New("response is missing Location header")
|
|
||||||
}
|
|
||||||
if !poller.IsValidURL(locURL) {
|
|
||||||
return nil, fmt.Errorf("invalid polling URL %s", locURL)
|
|
||||||
}
|
|
||||||
// check for provisioning state. if the operation is a RELO
|
|
||||||
// and terminates synchronously this will prevent extra polling.
|
|
||||||
// it's ok if there's no provisioning state.
|
|
||||||
state, _ := poller.GetProvisioningState(resp)
|
|
||||||
if state == "" {
|
|
||||||
state = poller.StatusInProgress
|
|
||||||
}
|
|
||||||
return &Poller[T]{
|
|
||||||
pl: pl,
|
|
||||||
resp: resp,
|
|
||||||
Type: kind,
|
|
||||||
PollURL: locURL,
|
|
||||||
CurState: state,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Done() bool {
|
|
||||||
return poller.IsTerminalState(p.CurState)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
|
||||||
err := pollers.PollHelper(ctx, p.PollURL, p.pl, func(resp *http.Response) (string, error) {
|
|
||||||
// location polling can return an updated polling URL
|
|
||||||
if h := resp.Header.Get(shared.HeaderLocation); h != "" {
|
|
||||||
p.PollURL = h
|
|
||||||
}
|
|
||||||
// if provisioning state is available, use that. this is only
|
|
||||||
// for some ARM LRO scenarios (e.g. DELETE with a Location header)
|
|
||||||
// so if it's missing then use HTTP status code.
|
|
||||||
provState, _ := poller.GetProvisioningState(resp)
|
|
||||||
p.resp = resp
|
|
||||||
if provState != "" {
|
|
||||||
p.CurState = provState
|
|
||||||
} else if resp.StatusCode == http.StatusAccepted {
|
|
||||||
p.CurState = poller.StatusInProgress
|
|
||||||
} else if resp.StatusCode > 199 && resp.StatusCode < 300 {
|
|
||||||
// any 2xx other than a 202 indicates success
|
|
||||||
p.CurState = poller.StatusSucceeded
|
|
||||||
} else {
|
|
||||||
p.CurState = poller.StatusFailed
|
|
||||||
}
|
|
||||||
return p.CurState, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return p.resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
|
||||||
return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), out)
|
|
||||||
}
|
|
145
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op/op.go
generated
vendored
145
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op/op.go
generated
vendored
|
@ -1,145 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package op
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Applicable returns true if the LRO is using Operation-Location.
|
|
||||||
func Applicable(resp *http.Response) bool {
|
|
||||||
return resp.Header.Get(shared.HeaderOperationLocation) != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// CanResume returns true if the token can rehydrate this poller type.
|
|
||||||
func CanResume(token map[string]interface{}) bool {
|
|
||||||
_, ok := token["oplocURL"]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poller is an LRO poller that uses the Operation-Location pattern.
|
|
||||||
type Poller[T any] struct {
|
|
||||||
pl exported.Pipeline
|
|
||||||
resp *http.Response
|
|
||||||
|
|
||||||
OpLocURL string `json:"oplocURL"`
|
|
||||||
LocURL string `json:"locURL"`
|
|
||||||
OrigURL string `json:"origURL"`
|
|
||||||
Method string `json:"method"`
|
|
||||||
FinalState pollers.FinalStateVia `json:"finalState"`
|
|
||||||
CurState string `json:"state"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new Poller from the provided initial response.
|
|
||||||
// Pass nil for response to create an empty Poller for rehydration.
|
|
||||||
func New[T any](pl exported.Pipeline, resp *http.Response, finalState pollers.FinalStateVia) (*Poller[T], error) {
|
|
||||||
if resp == nil {
|
|
||||||
log.Write(log.EventLRO, "Resuming Operation-Location poller.")
|
|
||||||
return &Poller[T]{pl: pl}, nil
|
|
||||||
}
|
|
||||||
log.Write(log.EventLRO, "Using Operation-Location poller.")
|
|
||||||
opURL := resp.Header.Get(shared.HeaderOperationLocation)
|
|
||||||
if opURL == "" {
|
|
||||||
return nil, errors.New("response is missing Operation-Location header")
|
|
||||||
}
|
|
||||||
if !poller.IsValidURL(opURL) {
|
|
||||||
return nil, fmt.Errorf("invalid Operation-Location URL %s", opURL)
|
|
||||||
}
|
|
||||||
locURL := resp.Header.Get(shared.HeaderLocation)
|
|
||||||
// Location header is optional
|
|
||||||
if locURL != "" && !poller.IsValidURL(locURL) {
|
|
||||||
return nil, fmt.Errorf("invalid Location URL %s", locURL)
|
|
||||||
}
|
|
||||||
// default initial state to InProgress. if the
|
|
||||||
// service sent us a status then use that instead.
|
|
||||||
curState := poller.StatusInProgress
|
|
||||||
status, err := poller.GetStatus(resp)
|
|
||||||
if err != nil && !errors.Is(err, poller.ErrNoBody) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if status != "" {
|
|
||||||
curState = status
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Poller[T]{
|
|
||||||
pl: pl,
|
|
||||||
resp: resp,
|
|
||||||
OpLocURL: opURL,
|
|
||||||
LocURL: locURL,
|
|
||||||
OrigURL: resp.Request.URL.String(),
|
|
||||||
Method: resp.Request.Method,
|
|
||||||
FinalState: finalState,
|
|
||||||
CurState: curState,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Done() bool {
|
|
||||||
return poller.IsTerminalState(p.CurState)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
|
||||||
err := pollers.PollHelper(ctx, p.OpLocURL, p.pl, func(resp *http.Response) (string, error) {
|
|
||||||
if !poller.StatusCodeValid(resp) {
|
|
||||||
p.resp = resp
|
|
||||||
return "", exported.NewResponseError(resp)
|
|
||||||
}
|
|
||||||
state, err := poller.GetStatus(resp)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
} else if state == "" {
|
|
||||||
return "", errors.New("the response did not contain a status")
|
|
||||||
}
|
|
||||||
p.resp = resp
|
|
||||||
p.CurState = state
|
|
||||||
return p.CurState, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return p.resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
|
||||||
var req *exported.Request
|
|
||||||
var err error
|
|
||||||
if p.FinalState == pollers.FinalStateViaLocation && p.LocURL != "" {
|
|
||||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL)
|
|
||||||
} else if p.FinalState == pollers.FinalStateViaOpLocation && p.Method == http.MethodPost {
|
|
||||||
// no final GET required, terminal response should have it
|
|
||||||
} else if rl, rlErr := poller.GetResourceLocation(p.resp); rlErr != nil && !errors.Is(rlErr, poller.ErrNoBody) {
|
|
||||||
return rlErr
|
|
||||||
} else if rl != "" {
|
|
||||||
req, err = exported.NewRequest(ctx, http.MethodGet, rl)
|
|
||||||
} else if p.Method == http.MethodPatch || p.Method == http.MethodPut {
|
|
||||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL)
|
|
||||||
} else if p.Method == http.MethodPost && p.LocURL != "" {
|
|
||||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// if a final GET request has been created, execute it
|
|
||||||
if req != nil {
|
|
||||||
resp, err := p.pl.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.resp = resp
|
|
||||||
}
|
|
||||||
|
|
||||||
return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), out)
|
|
||||||
}
|
|
24
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/poller.go
generated
vendored
24
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/poller.go
generated
vendored
|
@ -1,24 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package pollers
|
|
||||||
|
|
||||||
// FinalStateVia is the enumerated type for the possible final-state-via values.
|
|
||||||
type FinalStateVia string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// FinalStateViaAzureAsyncOp indicates the final payload comes from the Azure-AsyncOperation URL.
|
|
||||||
FinalStateViaAzureAsyncOp FinalStateVia = "azure-async-operation"
|
|
||||||
|
|
||||||
// FinalStateViaLocation indicates the final payload comes from the Location URL.
|
|
||||||
FinalStateViaLocation FinalStateVia = "location"
|
|
||||||
|
|
||||||
// FinalStateViaOriginalURI indicates the final payload comes from the original URL.
|
|
||||||
FinalStateViaOriginalURI FinalStateVia = "original-uri"
|
|
||||||
|
|
||||||
// FinalStateViaOpLocation indicates the final payload comes from the Operation-Location URL.
|
|
||||||
FinalStateViaOpLocation FinalStateVia = "operation-location"
|
|
||||||
)
|
|
187
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/util.go
generated
vendored
187
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/util.go
generated
vendored
|
@ -1,187 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package pollers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
azexported "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
|
||||||
)
|
|
||||||
|
|
||||||
// getTokenTypeName creates a type name from the type parameter T.
|
|
||||||
func getTokenTypeName[T any]() (string, error) {
|
|
||||||
tt := shared.TypeOfT[T]()
|
|
||||||
var n string
|
|
||||||
if tt.Kind() == reflect.Pointer {
|
|
||||||
n = "*"
|
|
||||||
tt = tt.Elem()
|
|
||||||
}
|
|
||||||
n += tt.Name()
|
|
||||||
if n == "" {
|
|
||||||
return "", errors.New("nameless types are not allowed")
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type resumeTokenWrapper[T any] struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Token T `json:"token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewResumeToken creates a resume token from the specified type.
|
|
||||||
// An error is returned if the generic type has no name (e.g. struct{}).
|
|
||||||
func NewResumeToken[TResult, TSource any](from TSource) (string, error) {
|
|
||||||
n, err := getTokenTypeName[TResult]()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(resumeTokenWrapper[TSource]{
|
|
||||||
Type: n,
|
|
||||||
Token: from,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtractToken returns the poller-specific token information from the provided token value.
|
|
||||||
func ExtractToken(token string) ([]byte, error) {
|
|
||||||
raw := map[string]json.RawMessage{}
|
|
||||||
if err := json.Unmarshal([]byte(token), &raw); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// this is dependent on the type resumeTokenWrapper[T]
|
|
||||||
tk, ok := raw["token"]
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("missing token value")
|
|
||||||
}
|
|
||||||
return tk, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTokenValid returns an error if the specified token isn't applicable for generic type T.
|
|
||||||
func IsTokenValid[T any](token string) error {
|
|
||||||
raw := map[string]interface{}{}
|
|
||||||
if err := json.Unmarshal([]byte(token), &raw); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t, ok := raw["type"]
|
|
||||||
if !ok {
|
|
||||||
return errors.New("missing type value")
|
|
||||||
}
|
|
||||||
tt, ok := t.(string)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("invalid type format %T", t)
|
|
||||||
}
|
|
||||||
n, err := getTokenTypeName[T]()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if tt != n {
|
|
||||||
return fmt.Errorf("cannot resume from this poller token. token is for type %s, not %s", tt, n)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// used if the operation synchronously completed
|
|
||||||
type NopPoller[T any] struct {
|
|
||||||
resp *http.Response
|
|
||||||
result T
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewNopPoller creates a NopPoller from the provided response.
|
|
||||||
// It unmarshals the response body into an instance of T.
|
|
||||||
func NewNopPoller[T any](resp *http.Response) (*NopPoller[T], error) {
|
|
||||||
np := &NopPoller[T]{resp: resp}
|
|
||||||
if resp.StatusCode == http.StatusNoContent {
|
|
||||||
return np, nil
|
|
||||||
}
|
|
||||||
payload, err := exported.Payload(resp, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(payload) == 0 {
|
|
||||||
return np, nil
|
|
||||||
}
|
|
||||||
if err = json.Unmarshal(payload, &np.result); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return np, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NopPoller[T]) Done() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *NopPoller[T]) Poll(context.Context) (*http.Response, error) {
|
|
||||||
return p.resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *NopPoller[T]) Result(ctx context.Context, out *T) error {
|
|
||||||
*out = p.result
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PollHelper creates and executes the request, calling update() with the response.
|
|
||||||
// If the request fails, the update func is not called.
|
|
||||||
// The update func returns the state of the operation for logging purposes or an error
|
|
||||||
// if it fails to extract the required state from the response.
|
|
||||||
func PollHelper(ctx context.Context, endpoint string, pl azexported.Pipeline, update func(resp *http.Response) (string, error)) error {
|
|
||||||
req, err := azexported.NewRequest(ctx, http.MethodGet, endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
resp, err := pl.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
state, err := update(resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Writef(log.EventLRO, "State %s", state)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResultHelper processes the response as success or failure.
|
|
||||||
// In the success case, it unmarshals the payload into either a new instance of T or out.
|
|
||||||
// In the failure case, it creates an *azcore.Response error from the response.
|
|
||||||
func ResultHelper[T any](resp *http.Response, failed bool, out *T) error {
|
|
||||||
// short-circuit the simple success case with no response body to unmarshal
|
|
||||||
if resp.StatusCode == http.StatusNoContent {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if !poller.StatusCodeValid(resp) || failed {
|
|
||||||
// the LRO failed. unmarshall the error and update state
|
|
||||||
return azexported.NewResponseError(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// success case
|
|
||||||
payload, err := exported.Payload(resp, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(payload) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = json.Unmarshal(payload, out); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
36
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go
generated
vendored
36
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go
generated
vendored
|
@ -1,36 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package shared
|
|
||||||
|
|
||||||
const (
|
|
||||||
ContentTypeAppJSON = "application/json"
|
|
||||||
ContentTypeAppXML = "application/xml"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
HeaderAuthorization = "Authorization"
|
|
||||||
HeaderAuxiliaryAuthorization = "x-ms-authorization-auxiliary"
|
|
||||||
HeaderAzureAsync = "Azure-AsyncOperation"
|
|
||||||
HeaderContentLength = "Content-Length"
|
|
||||||
HeaderContentType = "Content-Type"
|
|
||||||
HeaderLocation = "Location"
|
|
||||||
HeaderOperationLocation = "Operation-Location"
|
|
||||||
HeaderRetryAfter = "Retry-After"
|
|
||||||
HeaderUserAgent = "User-Agent"
|
|
||||||
HeaderWWWAuthenticate = "WWW-Authenticate"
|
|
||||||
HeaderXMSClientRequestID = "x-ms-client-request-id"
|
|
||||||
)
|
|
||||||
|
|
||||||
const BearerTokenPrefix = "Bearer "
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Module is the name of the calling module used in telemetry data.
|
|
||||||
Module = "azcore"
|
|
||||||
|
|
||||||
// Version is the semantic version (see http://semver.org) of this module.
|
|
||||||
Version = "v1.6.0"
|
|
||||||
)
|
|
92
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/shared.go
generated
vendored
92
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/shared.go
generated
vendored
|
@ -1,92 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package shared
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CtxWithHTTPHeaderKey is used as a context key for adding/retrieving http.Header.
|
|
||||||
type CtxWithHTTPHeaderKey struct{}
|
|
||||||
|
|
||||||
// CtxWithRetryOptionsKey is used as a context key for adding/retrieving RetryOptions.
|
|
||||||
type CtxWithRetryOptionsKey struct{}
|
|
||||||
|
|
||||||
// CtxIncludeResponseKey is used as a context key for retrieving the raw response.
|
|
||||||
type CtxIncludeResponseKey struct{}
|
|
||||||
|
|
||||||
// Delay waits for the duration to elapse or the context to be cancelled.
|
|
||||||
func Delay(ctx context.Context, delay time.Duration) error {
|
|
||||||
select {
|
|
||||||
case <-time.After(delay):
|
|
||||||
return nil
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetryAfter returns non-zero if the response contains a Retry-After header value.
|
|
||||||
func RetryAfter(resp *http.Response) time.Duration {
|
|
||||||
if resp == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
ra := resp.Header.Get(HeaderRetryAfter)
|
|
||||||
if ra == "" {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
// retry-after values are expressed in either number of
|
|
||||||
// seconds or an HTTP-date indicating when to try again
|
|
||||||
if retryAfter, _ := strconv.Atoi(ra); retryAfter > 0 {
|
|
||||||
return time.Duration(retryAfter) * time.Second
|
|
||||||
} else if t, err := time.Parse(time.RFC1123, ra); err == nil {
|
|
||||||
return time.Until(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// TypeOfT returns the type of the generic type param.
|
|
||||||
func TypeOfT[T any]() reflect.Type {
|
|
||||||
// you can't, at present, obtain the type of
|
|
||||||
// a type parameter, so this is the trick
|
|
||||||
return reflect.TypeOf((*T)(nil)).Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TransportFunc is a helper to use a first-class func to satisfy the Transporter interface.
|
|
||||||
type TransportFunc func(*http.Request) (*http.Response, error)
|
|
||||||
|
|
||||||
// Do implements the Transporter interface for the TransportFunc type.
|
|
||||||
func (pf TransportFunc) Do(req *http.Request) (*http.Response, error) {
|
|
||||||
return pf(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateModVer verifies that moduleVersion is a valid semver 2.0 string.
|
|
||||||
func ValidateModVer(moduleVersion string) error {
|
|
||||||
modVerRegx := regexp.MustCompile(`^v\d+\.\d+\.\d+(?:-[a-zA-Z0-9_.-]+)?$`)
|
|
||||||
if !modVerRegx.MatchString(moduleVersion) {
|
|
||||||
return fmt.Errorf("malformed moduleVersion param value %s", moduleVersion)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtractPackageName returns "package" from "package.Client".
|
|
||||||
// If clientName is malformed, an error is returned.
|
|
||||||
func ExtractPackageName(clientName string) (string, error) {
|
|
||||||
pkg, client, ok := strings.Cut(clientName, ".")
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("missing . in clientName %s", clientName)
|
|
||||||
} else if pkg == "" || client == "" {
|
|
||||||
return "", fmt.Errorf("malformed clientName %s", clientName)
|
|
||||||
}
|
|
||||||
return pkg, nil
|
|
||||||
}
|
|
10
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/doc.go
generated
vendored
10
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/doc.go
generated
vendored
|
@ -1,10 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
|
||||||
// Use of this source code is governed by an MIT
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package log contains functionality for configuring logging behavior.
|
|
||||||
// Default logging to stderr can be enabled by setting environment variable AZURE_SDK_GO_LOGGING to "all".
|
|
||||||
package log
|
|
50
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/log.go
generated
vendored
50
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/log.go
generated
vendored
|
@ -1,50 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
// Package log provides functionality for configuring logging facilities.
|
|
||||||
package log
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Event is used to group entries. Each group can be toggled on or off.
|
|
||||||
type Event = log.Event
|
|
||||||
|
|
||||||
const (
|
|
||||||
// EventRequest entries contain information about HTTP requests.
|
|
||||||
// This includes information like the URL, query parameters, and headers.
|
|
||||||
EventRequest Event = "Request"
|
|
||||||
|
|
||||||
// EventResponse entries contain information about HTTP responses.
|
|
||||||
// This includes information like the HTTP status code, headers, and request URL.
|
|
||||||
EventResponse Event = "Response"
|
|
||||||
|
|
||||||
// EventRetryPolicy entries contain information specific to the retry policy in use.
|
|
||||||
EventRetryPolicy Event = "Retry"
|
|
||||||
|
|
||||||
// EventLRO entries contain information specific to long-running operations.
|
|
||||||
// This includes information like polling location, operation state, and sleep intervals.
|
|
||||||
EventLRO Event = "LongRunningOperation"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetEvents is used to control which events are written to
|
|
||||||
// the log. By default all log events are writen.
|
|
||||||
// NOTE: this is not goroutine safe and should be called before using SDK clients.
|
|
||||||
func SetEvents(cls ...Event) {
|
|
||||||
log.SetEvents(cls...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetListener will set the Logger to write to the specified Listener.
|
|
||||||
// NOTE: this is not goroutine safe and should be called before using SDK clients.
|
|
||||||
func SetListener(lst func(Event, string)) {
|
|
||||||
log.SetListener(lst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// for testing purposes
|
|
||||||
func resetEvents() {
|
|
||||||
log.TestResetEvents()
|
|
||||||
}
|
|
10
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/doc.go
generated
vendored
10
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/doc.go
generated
vendored
|
@ -1,10 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
|
||||||
// Use of this source code is governed by an MIT
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package policy contains the definitions needed for configuring in-box pipeline policies
|
|
||||||
// and creating custom policies.
|
|
||||||
package policy
|
|
164
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go
generated
vendored
164
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go
generated
vendored
|
@ -1,164 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package policy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Policy represents an extensibility point for the Pipeline that can mutate the specified
|
|
||||||
// Request and react to the received Response.
|
|
||||||
type Policy = exported.Policy
|
|
||||||
|
|
||||||
// Transporter represents an HTTP pipeline transport used to send HTTP requests and receive responses.
|
|
||||||
type Transporter = exported.Transporter
|
|
||||||
|
|
||||||
// Request is an abstraction over the creation of an HTTP request as it passes through the pipeline.
|
|
||||||
// Don't use this type directly, use runtime.NewRequest() instead.
|
|
||||||
type Request = exported.Request
|
|
||||||
|
|
||||||
// ClientOptions contains optional settings for a client's pipeline.
|
|
||||||
// All zero-value fields will be initialized with default values.
|
|
||||||
type ClientOptions struct {
|
|
||||||
// APIVersion overrides the default version requested of the service. Set with caution as this package version has not been tested with arbitrary service versions.
|
|
||||||
APIVersion string
|
|
||||||
|
|
||||||
// Cloud specifies a cloud for the client. The default is Azure Public Cloud.
|
|
||||||
Cloud cloud.Configuration
|
|
||||||
|
|
||||||
// Logging configures the built-in logging policy.
|
|
||||||
Logging LogOptions
|
|
||||||
|
|
||||||
// Retry configures the built-in retry policy.
|
|
||||||
Retry RetryOptions
|
|
||||||
|
|
||||||
// Telemetry configures the built-in telemetry policy.
|
|
||||||
Telemetry TelemetryOptions
|
|
||||||
|
|
||||||
// TracingProvider configures the tracing provider.
|
|
||||||
// It defaults to a no-op tracer.
|
|
||||||
TracingProvider tracing.Provider
|
|
||||||
|
|
||||||
// Transport sets the transport for HTTP requests.
|
|
||||||
Transport Transporter
|
|
||||||
|
|
||||||
// PerCallPolicies contains custom policies to inject into the pipeline.
|
|
||||||
// Each policy is executed once per request.
|
|
||||||
PerCallPolicies []Policy
|
|
||||||
|
|
||||||
// PerRetryPolicies contains custom policies to inject into the pipeline.
|
|
||||||
// Each policy is executed once per request, and for each retry of that request.
|
|
||||||
PerRetryPolicies []Policy
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogOptions configures the logging policy's behavior.
|
|
||||||
type LogOptions struct {
|
|
||||||
// IncludeBody indicates if request and response bodies should be included in logging.
|
|
||||||
// The default value is false.
|
|
||||||
// NOTE: enabling this can lead to disclosure of sensitive information, use with care.
|
|
||||||
IncludeBody bool
|
|
||||||
|
|
||||||
// AllowedHeaders is the slice of headers to log with their values intact.
|
|
||||||
// All headers not in the slice will have their values REDACTED.
|
|
||||||
// Applies to request and response headers.
|
|
||||||
AllowedHeaders []string
|
|
||||||
|
|
||||||
// AllowedQueryParams is the slice of query parameters to log with their values intact.
|
|
||||||
// All query parameters not in the slice will have their values REDACTED.
|
|
||||||
AllowedQueryParams []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetryOptions configures the retry policy's behavior.
|
|
||||||
// Zero-value fields will have their specified default values applied during use.
|
|
||||||
// This allows for modification of a subset of fields.
|
|
||||||
type RetryOptions struct {
|
|
||||||
// MaxRetries specifies the maximum number of attempts a failed operation will be retried
|
|
||||||
// before producing an error.
|
|
||||||
// The default value is three. A value less than zero means one try and no retries.
|
|
||||||
MaxRetries int32
|
|
||||||
|
|
||||||
// TryTimeout indicates the maximum time allowed for any single try of an HTTP request.
|
|
||||||
// This is disabled by default. Specify a value greater than zero to enable.
|
|
||||||
// NOTE: Setting this to a small value might cause premature HTTP request time-outs.
|
|
||||||
TryTimeout time.Duration
|
|
||||||
|
|
||||||
// RetryDelay specifies the initial amount of delay to use before retrying an operation.
|
|
||||||
// The value is used only if the HTTP response does not contain a Retry-After header.
|
|
||||||
// The delay increases exponentially with each retry up to the maximum specified by MaxRetryDelay.
|
|
||||||
// The default value is four seconds. A value less than zero means no delay between retries.
|
|
||||||
RetryDelay time.Duration
|
|
||||||
|
|
||||||
// MaxRetryDelay specifies the maximum delay allowed before retrying an operation.
|
|
||||||
// Typically the value is greater than or equal to the value specified in RetryDelay.
|
|
||||||
// The default Value is 60 seconds. A value less than zero means there is no cap.
|
|
||||||
MaxRetryDelay time.Duration
|
|
||||||
|
|
||||||
// StatusCodes specifies the HTTP status codes that indicate the operation should be retried.
|
|
||||||
// A nil slice will use the following values.
|
|
||||||
// http.StatusRequestTimeout 408
|
|
||||||
// http.StatusTooManyRequests 429
|
|
||||||
// http.StatusInternalServerError 500
|
|
||||||
// http.StatusBadGateway 502
|
|
||||||
// http.StatusServiceUnavailable 503
|
|
||||||
// http.StatusGatewayTimeout 504
|
|
||||||
// Specifying values will replace the default values.
|
|
||||||
// Specifying an empty slice will disable retries for HTTP status codes.
|
|
||||||
StatusCodes []int
|
|
||||||
|
|
||||||
// ShouldRetry evaluates if the retry policy should retry the request.
|
|
||||||
// When specified, the function overrides comparison against the list of
|
|
||||||
// HTTP status codes and error checking within the retry policy. Context
|
|
||||||
// and NonRetriable errors remain evaluated before calling ShouldRetry.
|
|
||||||
// The *http.Response and error parameters are mutually exclusive, i.e.
|
|
||||||
// if one is nil, the other is not nil.
|
|
||||||
// A return value of true means the retry policy should retry.
|
|
||||||
ShouldRetry func(*http.Response, error) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// TelemetryOptions configures the telemetry policy's behavior.
|
|
||||||
type TelemetryOptions struct {
|
|
||||||
// ApplicationID is an application-specific identification string to add to the User-Agent.
|
|
||||||
// It has a maximum length of 24 characters and must not contain any spaces.
|
|
||||||
ApplicationID string
|
|
||||||
|
|
||||||
// Disabled will prevent the addition of any telemetry data to the User-Agent.
|
|
||||||
Disabled bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenRequestOptions contain specific parameter that may be used by credentials types when attempting to get a token.
|
|
||||||
type TokenRequestOptions = exported.TokenRequestOptions
|
|
||||||
|
|
||||||
// BearerTokenOptions configures the bearer token policy's behavior.
|
|
||||||
type BearerTokenOptions struct {
|
|
||||||
// AuthorizationHandler allows SDK developers to run client-specific logic when BearerTokenPolicy must authorize a request.
|
|
||||||
// When this field isn't set, the policy follows its default behavior of authorizing every request with a bearer token from
|
|
||||||
// its given credential.
|
|
||||||
AuthorizationHandler AuthorizationHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthorizationHandler allows SDK developers to insert custom logic that runs when BearerTokenPolicy must authorize a request.
|
|
||||||
type AuthorizationHandler struct {
|
|
||||||
// OnRequest is called each time the policy receives a request. Its func parameter authorizes the request with a token
|
|
||||||
// from the policy's given credential. Implementations that need to perform I/O should use the Request's context,
|
|
||||||
// available from Request.Raw().Context(). When OnRequest returns an error, the policy propagates that error and doesn't
|
|
||||||
// send the request. When OnRequest is nil, the policy follows its default behavior, authorizing the request with a
|
|
||||||
// token from its credential according to its configuration.
|
|
||||||
OnRequest func(*Request, func(TokenRequestOptions) error) error
|
|
||||||
|
|
||||||
// OnChallenge is called when the policy receives a 401 response, allowing the AuthorizationHandler to re-authorize the
|
|
||||||
// request according to an authentication challenge (the Response's WWW-Authenticate header). OnChallenge is responsible
|
|
||||||
// for parsing parameters from the challenge. Its func parameter will authorize the request with a token from the policy's
|
|
||||||
// given credential. Implementations that need to perform I/O should use the Request's context, available from
|
|
||||||
// Request.Raw().Context(). When OnChallenge returns nil, the policy will send the request again. When OnChallenge is nil,
|
|
||||||
// the policy will return any 401 response to the client.
|
|
||||||
OnChallenge func(*Request, *http.Response, func(TokenRequestOptions) error) error
|
|
||||||
}
|
|
10
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/doc.go
generated
vendored
10
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/doc.go
generated
vendored
|
@ -1,10 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
|
||||||
// Use of this source code is governed by an MIT
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package runtime contains various facilities for creating requests and handling responses.
|
|
||||||
// The content is intended for SDK authors.
|
|
||||||
package runtime
|
|
19
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/errors.go
generated
vendored
19
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/errors.go
generated
vendored
|
@ -1,19 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewResponseError creates an *azcore.ResponseError from the provided HTTP response.
|
|
||||||
// Call this when a service request returns a non-successful status code.
|
|
||||||
func NewResponseError(resp *http.Response) error {
|
|
||||||
return exported.NewResponseError(resp)
|
|
||||||
}
|
|
77
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pager.go
generated
vendored
77
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pager.go
generated
vendored
|
@ -1,77 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PagingHandler contains the required data for constructing a Pager.
|
|
||||||
type PagingHandler[T any] struct {
|
|
||||||
// More returns a boolean indicating if there are more pages to fetch.
|
|
||||||
// It uses the provided page to make the determination.
|
|
||||||
More func(T) bool
|
|
||||||
|
|
||||||
// Fetcher fetches the first and subsequent pages.
|
|
||||||
Fetcher func(context.Context, *T) (T, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pager provides operations for iterating over paged responses.
|
|
||||||
type Pager[T any] struct {
|
|
||||||
current *T
|
|
||||||
handler PagingHandler[T]
|
|
||||||
firstPage bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPager creates an instance of Pager using the specified PagingHandler.
|
|
||||||
// Pass a non-nil T for firstPage if the first page has already been retrieved.
|
|
||||||
func NewPager[T any](handler PagingHandler[T]) *Pager[T] {
|
|
||||||
return &Pager[T]{
|
|
||||||
handler: handler,
|
|
||||||
firstPage: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// More returns true if there are more pages to retrieve.
|
|
||||||
func (p *Pager[T]) More() bool {
|
|
||||||
if p.current != nil {
|
|
||||||
return p.handler.More(*p.current)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// NextPage advances the pager to the next page.
|
|
||||||
func (p *Pager[T]) NextPage(ctx context.Context) (T, error) {
|
|
||||||
var resp T
|
|
||||||
var err error
|
|
||||||
if p.current != nil {
|
|
||||||
if p.firstPage {
|
|
||||||
// we get here if it's an LRO-pager, we already have the first page
|
|
||||||
p.firstPage = false
|
|
||||||
return *p.current, nil
|
|
||||||
} else if !p.handler.More(*p.current) {
|
|
||||||
return *new(T), errors.New("no more pages")
|
|
||||||
}
|
|
||||||
resp, err = p.handler.Fetcher(ctx, p.current)
|
|
||||||
} else {
|
|
||||||
// non-LRO case, first page
|
|
||||||
p.firstPage = false
|
|
||||||
resp, err = p.handler.Fetcher(ctx, nil)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return *new(T), err
|
|
||||||
}
|
|
||||||
p.current = &resp
|
|
||||||
return *p.current, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshaler interface for Pager[T].
|
|
||||||
func (p *Pager[T]) UnmarshalJSON(data []byte) error {
|
|
||||||
return json.Unmarshal(data, &p.current)
|
|
||||||
}
|
|
66
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pipeline.go
generated
vendored
66
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pipeline.go
generated
vendored
|
@ -1,66 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PipelineOptions contains Pipeline options for SDK developers
|
|
||||||
type PipelineOptions struct {
|
|
||||||
AllowedHeaders, AllowedQueryParameters []string
|
|
||||||
APIVersion APIVersionOptions
|
|
||||||
PerCall, PerRetry []policy.Policy
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pipeline represents a primitive for sending HTTP requests and receiving responses.
|
|
||||||
// Its behavior can be extended by specifying policies during construction.
|
|
||||||
type Pipeline = exported.Pipeline
|
|
||||||
|
|
||||||
// NewPipeline creates a pipeline from connection options, with any additional policies as specified.
|
|
||||||
// Policies from ClientOptions are placed after policies from PipelineOptions.
|
|
||||||
// The module and version parameters are used by the telemetry policy, when enabled.
|
|
||||||
func NewPipeline(module, version string, plOpts PipelineOptions, options *policy.ClientOptions) Pipeline {
|
|
||||||
cp := policy.ClientOptions{}
|
|
||||||
if options != nil {
|
|
||||||
cp = *options
|
|
||||||
}
|
|
||||||
if len(plOpts.AllowedHeaders) > 0 {
|
|
||||||
headers := make([]string, len(plOpts.AllowedHeaders)+len(cp.Logging.AllowedHeaders))
|
|
||||||
copy(headers, plOpts.AllowedHeaders)
|
|
||||||
headers = append(headers, cp.Logging.AllowedHeaders...)
|
|
||||||
cp.Logging.AllowedHeaders = headers
|
|
||||||
}
|
|
||||||
if len(plOpts.AllowedQueryParameters) > 0 {
|
|
||||||
qp := make([]string, len(plOpts.AllowedQueryParameters)+len(cp.Logging.AllowedQueryParams))
|
|
||||||
copy(qp, plOpts.AllowedQueryParameters)
|
|
||||||
qp = append(qp, cp.Logging.AllowedQueryParams...)
|
|
||||||
cp.Logging.AllowedQueryParams = qp
|
|
||||||
}
|
|
||||||
// we put the includeResponsePolicy at the very beginning so that the raw response
|
|
||||||
// is populated with the final response (some policies might mutate the response)
|
|
||||||
policies := []policy.Policy{exported.PolicyFunc(includeResponsePolicy)}
|
|
||||||
if cp.APIVersion != "" {
|
|
||||||
policies = append(policies, newAPIVersionPolicy(cp.APIVersion, &plOpts.APIVersion))
|
|
||||||
}
|
|
||||||
if !cp.Telemetry.Disabled {
|
|
||||||
policies = append(policies, NewTelemetryPolicy(module, version, &cp.Telemetry))
|
|
||||||
}
|
|
||||||
policies = append(policies, plOpts.PerCall...)
|
|
||||||
policies = append(policies, cp.PerCallPolicies...)
|
|
||||||
policies = append(policies, NewRetryPolicy(&cp.Retry))
|
|
||||||
policies = append(policies, plOpts.PerRetry...)
|
|
||||||
policies = append(policies, cp.PerRetryPolicies...)
|
|
||||||
policies = append(policies, NewLogPolicy(&cp.Logging))
|
|
||||||
policies = append(policies, exported.PolicyFunc(httpHeaderPolicy), exported.PolicyFunc(bodyDownloadPolicy))
|
|
||||||
transport := cp.Transport
|
|
||||||
if transport == nil {
|
|
||||||
transport = defaultHTTPClient
|
|
||||||
}
|
|
||||||
return exported.NewPipeline(transport, policies...)
|
|
||||||
}
|
|
75
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go
generated
vendored
75
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go
generated
vendored
|
@ -1,75 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// APIVersionOptions contains options for API versions
|
|
||||||
type APIVersionOptions struct {
|
|
||||||
// Location indicates where to set the version on a request, for example in a header or query param
|
|
||||||
Location APIVersionLocation
|
|
||||||
// Name is the name of the header or query parameter, for example "api-version"
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIVersionLocation indicates which part of a request identifies the service version
|
|
||||||
type APIVersionLocation int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// APIVersionLocationQueryParam indicates a query parameter
|
|
||||||
APIVersionLocationQueryParam = 0
|
|
||||||
// APIVersionLocationHeader indicates a header
|
|
||||||
APIVersionLocationHeader = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
// newAPIVersionPolicy constructs an APIVersionPolicy. If version is "", Do will be a no-op. If version
|
|
||||||
// isn't empty and opts.Name is empty, Do will return an error.
|
|
||||||
func newAPIVersionPolicy(version string, opts *APIVersionOptions) *apiVersionPolicy {
|
|
||||||
if opts == nil {
|
|
||||||
opts = &APIVersionOptions{}
|
|
||||||
}
|
|
||||||
return &apiVersionPolicy{location: opts.Location, name: opts.Name, version: version}
|
|
||||||
}
|
|
||||||
|
|
||||||
// apiVersionPolicy enables users to set the API version of every request a client sends.
|
|
||||||
type apiVersionPolicy struct {
|
|
||||||
// location indicates whether "name" refers to a query parameter or header.
|
|
||||||
location APIVersionLocation
|
|
||||||
|
|
||||||
// name of the query param or header whose value should be overridden; provided by the client.
|
|
||||||
name string
|
|
||||||
|
|
||||||
// version is the value (provided by the user) that replaces the default version value.
|
|
||||||
version string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do sets the request's API version, if the policy is configured to do so, replacing any prior value.
|
|
||||||
func (a *apiVersionPolicy) Do(req *policy.Request) (*http.Response, error) {
|
|
||||||
if a.version != "" {
|
|
||||||
if a.name == "" {
|
|
||||||
// user set ClientOptions.APIVersion but the client ctor didn't set PipelineOptions.APIVersionOptions
|
|
||||||
return nil, errors.New("this client doesn't support overriding its API version")
|
|
||||||
}
|
|
||||||
switch a.location {
|
|
||||||
case APIVersionLocationHeader:
|
|
||||||
req.Raw().Header.Set(a.name, a.version)
|
|
||||||
case APIVersionLocationQueryParam:
|
|
||||||
q := req.Raw().URL.Query()
|
|
||||||
q.Set(a.name, a.version)
|
|
||||||
req.Raw().URL.RawQuery = q.Encode()
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown APIVersionLocation %d", a.location)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return req.Next()
|
|
||||||
}
|
|
116
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go
generated
vendored
116
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go
generated
vendored
|
@ -1,116 +0,0 @@
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/temporal"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BearerTokenPolicy authorizes requests with bearer tokens acquired from a TokenCredential.
|
|
||||||
type BearerTokenPolicy struct {
|
|
||||||
// mainResource is the resource to be retreived using the tenant specified in the credential
|
|
||||||
mainResource *temporal.Resource[exported.AccessToken, acquiringResourceState]
|
|
||||||
// the following fields are read-only
|
|
||||||
authzHandler policy.AuthorizationHandler
|
|
||||||
cred exported.TokenCredential
|
|
||||||
scopes []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type acquiringResourceState struct {
|
|
||||||
req *policy.Request
|
|
||||||
p *BearerTokenPolicy
|
|
||||||
tro policy.TokenRequestOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
// acquire acquires or updates the resource; only one
|
|
||||||
// thread/goroutine at a time ever calls this function
|
|
||||||
func acquire(state acquiringResourceState) (newResource exported.AccessToken, newExpiration time.Time, err error) {
|
|
||||||
tk, err := state.p.cred.GetToken(state.req.Raw().Context(), state.tro)
|
|
||||||
if err != nil {
|
|
||||||
return exported.AccessToken{}, time.Time{}, err
|
|
||||||
}
|
|
||||||
return tk, tk.ExpiresOn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBearerTokenPolicy creates a policy object that authorizes requests with bearer tokens.
|
|
||||||
// cred: an azcore.TokenCredential implementation such as a credential object from azidentity
|
|
||||||
// scopes: the list of permission scopes required for the token.
|
|
||||||
// opts: optional settings. Pass nil to accept default values; this is the same as passing a zero-value options.
|
|
||||||
func NewBearerTokenPolicy(cred exported.TokenCredential, scopes []string, opts *policy.BearerTokenOptions) *BearerTokenPolicy {
|
|
||||||
if opts == nil {
|
|
||||||
opts = &policy.BearerTokenOptions{}
|
|
||||||
}
|
|
||||||
return &BearerTokenPolicy{
|
|
||||||
authzHandler: opts.AuthorizationHandler,
|
|
||||||
cred: cred,
|
|
||||||
scopes: scopes,
|
|
||||||
mainResource: temporal.NewResource(acquire),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// authenticateAndAuthorize returns a function which authorizes req with a token from the policy's credential
|
|
||||||
func (b *BearerTokenPolicy) authenticateAndAuthorize(req *policy.Request) func(policy.TokenRequestOptions) error {
|
|
||||||
return func(tro policy.TokenRequestOptions) error {
|
|
||||||
as := acquiringResourceState{p: b, req: req, tro: tro}
|
|
||||||
tk, err := b.mainResource.Get(as)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.Raw().Header.Set(shared.HeaderAuthorization, shared.BearerTokenPrefix+tk.Token)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do authorizes a request with a bearer token
|
|
||||||
func (b *BearerTokenPolicy) Do(req *policy.Request) (*http.Response, error) {
|
|
||||||
var err error
|
|
||||||
if b.authzHandler.OnRequest != nil {
|
|
||||||
err = b.authzHandler.OnRequest(req, b.authenticateAndAuthorize(req))
|
|
||||||
} else {
|
|
||||||
err = b.authenticateAndAuthorize(req)(policy.TokenRequestOptions{Scopes: b.scopes})
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, ensureNonRetriable(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := req.Next()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if res.StatusCode == http.StatusUnauthorized {
|
|
||||||
b.mainResource.Expire()
|
|
||||||
if res.Header.Get("WWW-Authenticate") != "" && b.authzHandler.OnChallenge != nil {
|
|
||||||
if err = b.authzHandler.OnChallenge(req, res, b.authenticateAndAuthorize(req)); err == nil {
|
|
||||||
res, err = req.Next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res, ensureNonRetriable(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ensureNonRetriable(err error) error {
|
|
||||||
var nre errorinfo.NonRetriable
|
|
||||||
if err != nil && !errors.As(err, &nre) {
|
|
||||||
err = btpError{err}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// btpError is a wrapper that ensures RetryPolicy doesn't retry requests BearerTokenPolicy couldn't authorize
|
|
||||||
type btpError struct {
|
|
||||||
error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (btpError) NonRetriable() {}
|
|
||||||
|
|
||||||
var _ errorinfo.NonRetriable = (*btpError)(nil)
|
|
72
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_body_download.go
generated
vendored
72
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_body_download.go
generated
vendored
|
@ -1,72 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo"
|
|
||||||
)
|
|
||||||
|
|
||||||
// bodyDownloadPolicy creates a policy object that downloads the response's body to a []byte.
|
|
||||||
func bodyDownloadPolicy(req *policy.Request) (*http.Response, error) {
|
|
||||||
resp, err := req.Next()
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
var opValues bodyDownloadPolicyOpValues
|
|
||||||
// don't skip downloading error response bodies
|
|
||||||
if req.OperationValue(&opValues); opValues.Skip && resp.StatusCode < 400 {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
// Either bodyDownloadPolicyOpValues was not specified (so skip is false)
|
|
||||||
// or it was specified and skip is false: don't skip downloading the body
|
|
||||||
_, err = Payload(resp)
|
|
||||||
if err != nil {
|
|
||||||
return resp, newBodyDownloadError(err, req)
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// bodyDownloadPolicyOpValues is the struct containing the per-operation values
|
|
||||||
type bodyDownloadPolicyOpValues struct {
|
|
||||||
Skip bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type bodyDownloadError struct {
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBodyDownloadError(err error, req *policy.Request) error {
|
|
||||||
// on failure, only retry the request for idempotent operations.
|
|
||||||
// we currently identify them as DELETE, GET, and PUT requests.
|
|
||||||
if m := strings.ToUpper(req.Raw().Method); m == http.MethodDelete || m == http.MethodGet || m == http.MethodPut {
|
|
||||||
// error is safe for retry
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// wrap error to avoid retries
|
|
||||||
return &bodyDownloadError{
|
|
||||||
err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bodyDownloadError) Error() string {
|
|
||||||
return fmt.Sprintf("body download policy: %s", b.err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bodyDownloadError) NonRetriable() {
|
|
||||||
// marker method
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bodyDownloadError) Unwrap() error {
|
|
||||||
return b.err
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ errorinfo.NonRetriable = (*bodyDownloadError)(nil)
|
|
39
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_http_header.go
generated
vendored
39
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_http_header.go
generated
vendored
|
@ -1,39 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// newHTTPHeaderPolicy creates a policy object that adds custom HTTP headers to a request
|
|
||||||
func httpHeaderPolicy(req *policy.Request) (*http.Response, error) {
|
|
||||||
// check if any custom HTTP headers have been specified
|
|
||||||
if header := req.Raw().Context().Value(shared.CtxWithHTTPHeaderKey{}); header != nil {
|
|
||||||
for k, v := range header.(http.Header) {
|
|
||||||
// use Set to replace any existing value
|
|
||||||
// it also canonicalizes the header key
|
|
||||||
req.Raw().Header.Set(k, v[0])
|
|
||||||
// add any remaining values
|
|
||||||
for i := 1; i < len(v); i++ {
|
|
||||||
req.Raw().Header.Add(k, v[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return req.Next()
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithHTTPHeader adds the specified http.Header to the parent context.
|
|
||||||
// Use this to specify custom HTTP headers at the API-call level.
|
|
||||||
// Any overlapping headers will have their values replaced with the values specified here.
|
|
||||||
func WithHTTPHeader(parent context.Context, header http.Header) context.Context {
|
|
||||||
return context.WithValue(parent, shared.CtxWithHTTPHeaderKey{}, header)
|
|
||||||
}
|
|
34
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_include_response.go
generated
vendored
34
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_include_response.go
generated
vendored
|
@ -1,34 +0,0 @@
|
||||||
//go:build go1.16
|
|
||||||
// +build go1.16
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// includeResponsePolicy creates a policy that retrieves the raw HTTP response upon request
|
|
||||||
func includeResponsePolicy(req *policy.Request) (*http.Response, error) {
|
|
||||||
resp, err := req.Next()
|
|
||||||
if resp == nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
if httpOutRaw := req.Raw().Context().Value(shared.CtxIncludeResponseKey{}); httpOutRaw != nil {
|
|
||||||
httpOut := httpOutRaw.(**http.Response)
|
|
||||||
*httpOut = resp
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCaptureResponse applies the HTTP response retrieval annotation to the parent context.
|
|
||||||
// The resp parameter will contain the HTTP response after the request has completed.
|
|
||||||
func WithCaptureResponse(parent context.Context, resp **http.Response) context.Context {
|
|
||||||
return context.WithValue(parent, shared.CtxIncludeResponseKey{}, resp)
|
|
||||||
}
|
|
263
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_logging.go
generated
vendored
263
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_logging.go
generated
vendored
|
@ -1,263 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/diag"
|
|
||||||
)
|
|
||||||
|
|
||||||
type logPolicy struct {
|
|
||||||
includeBody bool
|
|
||||||
allowedHeaders map[string]struct{}
|
|
||||||
allowedQP map[string]struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLogPolicy creates a request/response logging policy object configured using the specified options.
|
|
||||||
// Pass nil to accept the default values; this is the same as passing a zero-value options.
|
|
||||||
func NewLogPolicy(o *policy.LogOptions) policy.Policy {
|
|
||||||
if o == nil {
|
|
||||||
o = &policy.LogOptions{}
|
|
||||||
}
|
|
||||||
// construct default hash set of allowed headers
|
|
||||||
allowedHeaders := map[string]struct{}{
|
|
||||||
"accept": {},
|
|
||||||
"cache-control": {},
|
|
||||||
"connection": {},
|
|
||||||
"content-length": {},
|
|
||||||
"content-type": {},
|
|
||||||
"date": {},
|
|
||||||
"etag": {},
|
|
||||||
"expires": {},
|
|
||||||
"if-match": {},
|
|
||||||
"if-modified-since": {},
|
|
||||||
"if-none-match": {},
|
|
||||||
"if-unmodified-since": {},
|
|
||||||
"last-modified": {},
|
|
||||||
"ms-cv": {},
|
|
||||||
"pragma": {},
|
|
||||||
"request-id": {},
|
|
||||||
"retry-after": {},
|
|
||||||
"server": {},
|
|
||||||
"traceparent": {},
|
|
||||||
"transfer-encoding": {},
|
|
||||||
"user-agent": {},
|
|
||||||
"www-authenticate": {},
|
|
||||||
"x-ms-request-id": {},
|
|
||||||
"x-ms-client-request-id": {},
|
|
||||||
"x-ms-return-client-request-id": {},
|
|
||||||
}
|
|
||||||
// add any caller-specified allowed headers to the set
|
|
||||||
for _, ah := range o.AllowedHeaders {
|
|
||||||
allowedHeaders[strings.ToLower(ah)] = struct{}{}
|
|
||||||
}
|
|
||||||
// now do the same thing for query params
|
|
||||||
allowedQP := getAllowedQueryParams(o.AllowedQueryParams)
|
|
||||||
return &logPolicy{
|
|
||||||
includeBody: o.IncludeBody,
|
|
||||||
allowedHeaders: allowedHeaders,
|
|
||||||
allowedQP: allowedQP,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getAllowedQueryParams merges the default set of allowed query parameters
|
|
||||||
// with a custom set (usually comes from client options).
|
|
||||||
func getAllowedQueryParams(customAllowedQP []string) map[string]struct{} {
|
|
||||||
allowedQP := map[string]struct{}{
|
|
||||||
"api-version": {},
|
|
||||||
}
|
|
||||||
for _, qp := range customAllowedQP {
|
|
||||||
allowedQP[strings.ToLower(qp)] = struct{}{}
|
|
||||||
}
|
|
||||||
return allowedQP
|
|
||||||
}
|
|
||||||
|
|
||||||
// logPolicyOpValues is the struct containing the per-operation values
|
|
||||||
type logPolicyOpValues struct {
|
|
||||||
try int32
|
|
||||||
start time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *logPolicy) Do(req *policy.Request) (*http.Response, error) {
|
|
||||||
// Get the per-operation values. These are saved in the Message's map so that they persist across each retry calling into this policy object.
|
|
||||||
var opValues logPolicyOpValues
|
|
||||||
if req.OperationValue(&opValues); opValues.start.IsZero() {
|
|
||||||
opValues.start = time.Now() // If this is the 1st try, record this operation's start time
|
|
||||||
}
|
|
||||||
opValues.try++ // The first try is #1 (not #0)
|
|
||||||
req.SetOperationValue(opValues)
|
|
||||||
|
|
||||||
// Log the outgoing request as informational
|
|
||||||
if log.Should(log.EventRequest) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
fmt.Fprintf(b, "==> OUTGOING REQUEST (Try=%d)\n", opValues.try)
|
|
||||||
p.writeRequestWithResponse(b, req, nil, nil)
|
|
||||||
var err error
|
|
||||||
if p.includeBody {
|
|
||||||
err = writeReqBody(req, b)
|
|
||||||
}
|
|
||||||
log.Write(log.EventRequest, b.String())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the time for this particular retry operation and then Do the operation.
|
|
||||||
tryStart := time.Now()
|
|
||||||
response, err := req.Next() // Make the request
|
|
||||||
tryEnd := time.Now()
|
|
||||||
tryDuration := tryEnd.Sub(tryStart)
|
|
||||||
opDuration := tryEnd.Sub(opValues.start)
|
|
||||||
|
|
||||||
if log.Should(log.EventResponse) {
|
|
||||||
// We're going to log this; build the string to log
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
fmt.Fprintf(b, "==> REQUEST/RESPONSE (Try=%d/%v, OpTime=%v) -- ", opValues.try, tryDuration, opDuration)
|
|
||||||
if err != nil { // This HTTP request did not get a response from the service
|
|
||||||
fmt.Fprint(b, "REQUEST ERROR\n")
|
|
||||||
} else {
|
|
||||||
fmt.Fprint(b, "RESPONSE RECEIVED\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
p.writeRequestWithResponse(b, req, response, err)
|
|
||||||
if err != nil {
|
|
||||||
// skip frames runtime.Callers() and runtime.StackTrace()
|
|
||||||
b.WriteString(diag.StackTrace(2, 32))
|
|
||||||
} else if p.includeBody {
|
|
||||||
err = writeRespBody(response, b)
|
|
||||||
}
|
|
||||||
log.Write(log.EventResponse, b.String())
|
|
||||||
}
|
|
||||||
return response, err
|
|
||||||
}
|
|
||||||
|
|
||||||
const redactedValue = "REDACTED"
|
|
||||||
|
|
||||||
// getSanitizedURL returns a sanitized string for the provided url.URL
|
|
||||||
func getSanitizedURL(u url.URL, allowedQueryParams map[string]struct{}) string {
|
|
||||||
// redact applicable query params
|
|
||||||
qp := u.Query()
|
|
||||||
for k := range qp {
|
|
||||||
if _, ok := allowedQueryParams[strings.ToLower(k)]; !ok {
|
|
||||||
qp.Set(k, redactedValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
u.RawQuery = qp.Encode()
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeRequestWithResponse appends a formatted HTTP request into a Buffer. If request and/or err are
|
|
||||||
// not nil, then these are also written into the Buffer.
|
|
||||||
func (p *logPolicy) writeRequestWithResponse(b *bytes.Buffer, req *policy.Request, resp *http.Response, err error) {
|
|
||||||
// Write the request into the buffer.
|
|
||||||
fmt.Fprint(b, " "+req.Raw().Method+" "+getSanitizedURL(*req.Raw().URL, p.allowedQP)+"\n")
|
|
||||||
p.writeHeader(b, req.Raw().Header)
|
|
||||||
if resp != nil {
|
|
||||||
fmt.Fprintln(b, " --------------------------------------------------------------------------------")
|
|
||||||
fmt.Fprint(b, " RESPONSE Status: "+resp.Status+"\n")
|
|
||||||
p.writeHeader(b, resp.Header)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(b, " --------------------------------------------------------------------------------")
|
|
||||||
fmt.Fprint(b, " ERROR:\n"+err.Error()+"\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// formatHeaders appends an HTTP request's or response's header into a Buffer.
|
|
||||||
func (p *logPolicy) writeHeader(b *bytes.Buffer, header http.Header) {
|
|
||||||
if len(header) == 0 {
|
|
||||||
b.WriteString(" (no headers)\n")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, len(header))
|
|
||||||
// Alphabetize the headers
|
|
||||||
for k := range header {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
for _, k := range keys {
|
|
||||||
value := header.Get(k)
|
|
||||||
// redact all header values not in the allow-list
|
|
||||||
if _, ok := p.allowedHeaders[strings.ToLower(k)]; !ok {
|
|
||||||
value = redactedValue
|
|
||||||
}
|
|
||||||
fmt.Fprintf(b, " %s: %+v\n", k, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns true if the request/response body should be logged.
|
|
||||||
// this is determined by looking at the content-type header value.
|
|
||||||
func shouldLogBody(b *bytes.Buffer, contentType string) bool {
|
|
||||||
contentType = strings.ToLower(contentType)
|
|
||||||
if strings.HasPrefix(contentType, "text") ||
|
|
||||||
strings.Contains(contentType, "json") ||
|
|
||||||
strings.Contains(contentType, "xml") {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
fmt.Fprintf(b, " Skip logging body for %s\n", contentType)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// writes to a buffer, used for logging purposes
|
|
||||||
func writeReqBody(req *policy.Request, b *bytes.Buffer) error {
|
|
||||||
if req.Raw().Body == nil {
|
|
||||||
fmt.Fprint(b, " Request contained no body\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if ct := req.Raw().Header.Get(shared.HeaderContentType); !shouldLogBody(b, ct) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
body, err := io.ReadAll(req.Raw().Body)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(b, " Failed to read request body: %s\n", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := req.RewindBody(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logBody(b, body)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// writes to a buffer, used for logging purposes
|
|
||||||
func writeRespBody(resp *http.Response, b *bytes.Buffer) error {
|
|
||||||
ct := resp.Header.Get(shared.HeaderContentType)
|
|
||||||
if ct == "" {
|
|
||||||
fmt.Fprint(b, " Response contained no body\n")
|
|
||||||
return nil
|
|
||||||
} else if !shouldLogBody(b, ct) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
body, err := Payload(resp)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(b, " Failed to read response body: %s\n", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(body) > 0 {
|
|
||||||
logBody(b, body)
|
|
||||||
} else {
|
|
||||||
fmt.Fprint(b, " Response contained no body\n")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func logBody(b *bytes.Buffer, body []byte) {
|
|
||||||
fmt.Fprintln(b, " --------------------------------------------------------------------------------")
|
|
||||||
fmt.Fprintln(b, string(body))
|
|
||||||
fmt.Fprintln(b, " --------------------------------------------------------------------------------")
|
|
||||||
}
|
|
34
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_request_id.go
generated
vendored
34
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_request_id.go
generated
vendored
|
@ -1,34 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
type requestIDPolicy struct{}
|
|
||||||
|
|
||||||
// NewRequestIDPolicy returns a policy that add the x-ms-client-request-id header
|
|
||||||
func NewRequestIDPolicy() policy.Policy {
|
|
||||||
return &requestIDPolicy{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestIDPolicy) Do(req *policy.Request) (*http.Response, error) {
|
|
||||||
if req.Raw().Header.Get(shared.HeaderXMSClientRequestID) == "" {
|
|
||||||
id, err := uuid.New()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Raw().Header.Set(shared.HeaderXMSClientRequestID, id.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
return req.Next()
|
|
||||||
}
|
|
261
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_retry.go
generated
vendored
261
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_retry.go
generated
vendored
|
@ -1,261 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"math"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/exported"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultMaxRetries = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
func setDefaults(o *policy.RetryOptions) {
|
|
||||||
if o.MaxRetries == 0 {
|
|
||||||
o.MaxRetries = defaultMaxRetries
|
|
||||||
} else if o.MaxRetries < 0 {
|
|
||||||
o.MaxRetries = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// SDK guidelines specify the default MaxRetryDelay is 60 seconds
|
|
||||||
if o.MaxRetryDelay == 0 {
|
|
||||||
o.MaxRetryDelay = 60 * time.Second
|
|
||||||
} else if o.MaxRetryDelay < 0 {
|
|
||||||
// not really an unlimited cap, but sufficiently large enough to be considered as such
|
|
||||||
o.MaxRetryDelay = math.MaxInt64
|
|
||||||
}
|
|
||||||
if o.RetryDelay == 0 {
|
|
||||||
o.RetryDelay = 800 * time.Millisecond
|
|
||||||
} else if o.RetryDelay < 0 {
|
|
||||||
o.RetryDelay = 0
|
|
||||||
}
|
|
||||||
if o.StatusCodes == nil {
|
|
||||||
// NOTE: if you change this list, you MUST update the docs in policy/policy.go
|
|
||||||
o.StatusCodes = []int{
|
|
||||||
http.StatusRequestTimeout, // 408
|
|
||||||
http.StatusTooManyRequests, // 429
|
|
||||||
http.StatusInternalServerError, // 500
|
|
||||||
http.StatusBadGateway, // 502
|
|
||||||
http.StatusServiceUnavailable, // 503
|
|
||||||
http.StatusGatewayTimeout, // 504
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func calcDelay(o policy.RetryOptions, try int32) time.Duration { // try is >=1; never 0
|
|
||||||
pow := func(number int64, exponent int32) int64 { // pow is nested helper function
|
|
||||||
var result int64 = 1
|
|
||||||
for n := int32(0); n < exponent; n++ {
|
|
||||||
result *= number
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
delay := time.Duration(pow(2, try)-1) * o.RetryDelay
|
|
||||||
|
|
||||||
// Introduce some jitter: [0.0, 1.0) / 2 = [0.0, 0.5) + 0.8 = [0.8, 1.3)
|
|
||||||
delay = time.Duration(delay.Seconds() * (rand.Float64()/2 + 0.8) * float64(time.Second)) // NOTE: We want math/rand; not crypto/rand
|
|
||||||
if delay > o.MaxRetryDelay {
|
|
||||||
delay = o.MaxRetryDelay
|
|
||||||
}
|
|
||||||
return delay
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRetryPolicy creates a policy object configured using the specified options.
|
|
||||||
// Pass nil to accept the default values; this is the same as passing a zero-value options.
|
|
||||||
func NewRetryPolicy(o *policy.RetryOptions) policy.Policy {
|
|
||||||
if o == nil {
|
|
||||||
o = &policy.RetryOptions{}
|
|
||||||
}
|
|
||||||
p := &retryPolicy{options: *o}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
type retryPolicy struct {
|
|
||||||
options policy.RetryOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *retryPolicy) Do(req *policy.Request) (resp *http.Response, err error) {
|
|
||||||
options := p.options
|
|
||||||
// check if the retry options have been overridden for this call
|
|
||||||
if override := req.Raw().Context().Value(shared.CtxWithRetryOptionsKey{}); override != nil {
|
|
||||||
options = override.(policy.RetryOptions)
|
|
||||||
}
|
|
||||||
setDefaults(&options)
|
|
||||||
// Exponential retry algorithm: ((2 ^ attempt) - 1) * delay * random(0.8, 1.2)
|
|
||||||
// When to retry: connection failure or temporary/timeout.
|
|
||||||
var rwbody *retryableRequestBody
|
|
||||||
if req.Body() != nil {
|
|
||||||
// wrap the body so we control when it's actually closed.
|
|
||||||
// do this outside the for loop so defers don't accumulate.
|
|
||||||
rwbody = &retryableRequestBody{body: req.Body()}
|
|
||||||
defer rwbody.realClose()
|
|
||||||
}
|
|
||||||
try := int32(1)
|
|
||||||
for {
|
|
||||||
resp = nil // reset
|
|
||||||
log.Writef(log.EventRetryPolicy, "=====> Try=%d", try)
|
|
||||||
|
|
||||||
// For each try, seek to the beginning of the Body stream. We do this even for the 1st try because
|
|
||||||
// the stream may not be at offset 0 when we first get it and we want the same behavior for the
|
|
||||||
// 1st try as for additional tries.
|
|
||||||
err = req.RewindBody()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// RewindBody() restores Raw().Body to its original state, so set our rewindable after
|
|
||||||
if rwbody != nil {
|
|
||||||
req.Raw().Body = rwbody
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.TryTimeout == 0 {
|
|
||||||
resp, err = req.Next()
|
|
||||||
} else {
|
|
||||||
// Set the per-try time for this particular retry operation and then Do the operation.
|
|
||||||
tryCtx, tryCancel := context.WithTimeout(req.Raw().Context(), options.TryTimeout)
|
|
||||||
clone := req.Clone(tryCtx)
|
|
||||||
resp, err = clone.Next() // Make the request
|
|
||||||
// if the body was already downloaded or there was an error it's safe to cancel the context now
|
|
||||||
if err != nil {
|
|
||||||
tryCancel()
|
|
||||||
} else if exported.PayloadDownloaded(resp) {
|
|
||||||
tryCancel()
|
|
||||||
} else {
|
|
||||||
// must cancel the context after the body has been read and closed
|
|
||||||
resp.Body = &contextCancelReadCloser{cf: tryCancel, body: resp.Body}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
log.Writef(log.EventRetryPolicy, "response %d", resp.StatusCode)
|
|
||||||
} else {
|
|
||||||
log.Writef(log.EventRetryPolicy, "error %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctxErr := req.Raw().Context().Err(); ctxErr != nil {
|
|
||||||
// don't retry if the parent context has been cancelled or its deadline exceeded
|
|
||||||
err = ctxErr
|
|
||||||
log.Writef(log.EventRetryPolicy, "abort due to %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the error is not retriable
|
|
||||||
var nre errorinfo.NonRetriable
|
|
||||||
if errors.As(err, &nre) {
|
|
||||||
// the error says it's not retriable so don't retry
|
|
||||||
log.Writef(log.EventRetryPolicy, "non-retriable error %T", nre)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.ShouldRetry != nil {
|
|
||||||
// a non-nil ShouldRetry overrides our HTTP status code check
|
|
||||||
if !options.ShouldRetry(resp, err) {
|
|
||||||
// predicate says we shouldn't retry
|
|
||||||
log.Write(log.EventRetryPolicy, "exit due to ShouldRetry")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else if err == nil && !HasStatusCode(resp, options.StatusCodes...) {
|
|
||||||
// if there is no error and the response code isn't in the list of retry codes then we're done.
|
|
||||||
log.Write(log.EventRetryPolicy, "exit due to non-retriable status code")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if try == options.MaxRetries+1 {
|
|
||||||
// max number of tries has been reached, don't sleep again
|
|
||||||
log.Writef(log.EventRetryPolicy, "MaxRetries %d exceeded", options.MaxRetries)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// use the delay from retry-after if available
|
|
||||||
delay := shared.RetryAfter(resp)
|
|
||||||
if delay <= 0 {
|
|
||||||
delay = calcDelay(options, try)
|
|
||||||
} else if delay > options.MaxRetryDelay {
|
|
||||||
// the retry-after delay exceeds the the cap so don't retry
|
|
||||||
log.Writef(log.EventRetryPolicy, "Retry-After delay %s exceeds MaxRetryDelay of %s", delay, options.MaxRetryDelay)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// drain before retrying so nothing is leaked
|
|
||||||
Drain(resp)
|
|
||||||
|
|
||||||
log.Writef(log.EventRetryPolicy, "End Try #%d, Delay=%v", try, delay)
|
|
||||||
select {
|
|
||||||
case <-time.After(delay):
|
|
||||||
try++
|
|
||||||
case <-req.Raw().Context().Done():
|
|
||||||
err = req.Raw().Context().Err()
|
|
||||||
log.Writef(log.EventRetryPolicy, "abort due to %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithRetryOptions adds the specified RetryOptions to the parent context.
|
|
||||||
// Use this to specify custom RetryOptions at the API-call level.
|
|
||||||
func WithRetryOptions(parent context.Context, options policy.RetryOptions) context.Context {
|
|
||||||
return context.WithValue(parent, shared.CtxWithRetryOptionsKey{}, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ********** The following type/methods implement the retryableRequestBody (a ReadSeekCloser)
|
|
||||||
|
|
||||||
// This struct is used when sending a body to the network
|
|
||||||
type retryableRequestBody struct {
|
|
||||||
body io.ReadSeeker // Seeking is required to support retries
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads a block of data from an inner stream and reports progress
|
|
||||||
func (b *retryableRequestBody) Read(p []byte) (n int, err error) {
|
|
||||||
return b.body.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *retryableRequestBody) Seek(offset int64, whence int) (offsetFromStart int64, err error) {
|
|
||||||
return b.body.Seek(offset, whence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *retryableRequestBody) Close() error {
|
|
||||||
// We don't want the underlying transport to close the request body on transient failures so this is a nop.
|
|
||||||
// The retry policy closes the request body upon success.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *retryableRequestBody) realClose() error {
|
|
||||||
if c, ok := b.body.(io.Closer); ok {
|
|
||||||
return c.Close()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ********** The following type/methods implement the contextCancelReadCloser
|
|
||||||
|
|
||||||
// contextCancelReadCloser combines an io.ReadCloser with a cancel func.
|
|
||||||
// it ensures the cancel func is invoked once the body has been read and closed.
|
|
||||||
type contextCancelReadCloser struct {
|
|
||||||
cf context.CancelFunc
|
|
||||||
body io.ReadCloser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *contextCancelReadCloser) Read(p []byte) (n int, err error) {
|
|
||||||
return rc.body.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *contextCancelReadCloser) Close() error {
|
|
||||||
err := rc.body.Close()
|
|
||||||
rc.cf()
|
|
||||||
return err
|
|
||||||
}
|
|
79
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_telemetry.go
generated
vendored
79
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_telemetry.go
generated
vendored
|
@ -1,79 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
)
|
|
||||||
|
|
||||||
type telemetryPolicy struct {
|
|
||||||
telemetryValue string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTelemetryPolicy creates a telemetry policy object that adds telemetry information to outgoing HTTP requests.
|
|
||||||
// The format is [<application_id> ]azsdk-go-<mod>/<ver> <platform_info>.
|
|
||||||
// Pass nil to accept the default values; this is the same as passing a zero-value options.
|
|
||||||
func NewTelemetryPolicy(mod, ver string, o *policy.TelemetryOptions) policy.Policy {
|
|
||||||
if o == nil {
|
|
||||||
o = &policy.TelemetryOptions{}
|
|
||||||
}
|
|
||||||
tp := telemetryPolicy{}
|
|
||||||
if o.Disabled {
|
|
||||||
return &tp
|
|
||||||
}
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
// normalize ApplicationID
|
|
||||||
if o.ApplicationID != "" {
|
|
||||||
o.ApplicationID = strings.ReplaceAll(o.ApplicationID, " ", "/")
|
|
||||||
if len(o.ApplicationID) > 24 {
|
|
||||||
o.ApplicationID = o.ApplicationID[:24]
|
|
||||||
}
|
|
||||||
b.WriteString(o.ApplicationID)
|
|
||||||
b.WriteRune(' ')
|
|
||||||
}
|
|
||||||
b.WriteString(formatTelemetry(mod, ver))
|
|
||||||
b.WriteRune(' ')
|
|
||||||
b.WriteString(platformInfo)
|
|
||||||
tp.telemetryValue = b.String()
|
|
||||||
return &tp
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatTelemetry(comp, ver string) string {
|
|
||||||
return fmt.Sprintf("azsdk-go-%s/%s", comp, ver)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p telemetryPolicy) Do(req *policy.Request) (*http.Response, error) {
|
|
||||||
if p.telemetryValue == "" {
|
|
||||||
return req.Next()
|
|
||||||
}
|
|
||||||
// preserve the existing User-Agent string
|
|
||||||
if ua := req.Raw().Header.Get(shared.HeaderUserAgent); ua != "" {
|
|
||||||
p.telemetryValue = fmt.Sprintf("%s %s", p.telemetryValue, ua)
|
|
||||||
}
|
|
||||||
req.Raw().Header.Set(shared.HeaderUserAgent, p.telemetryValue)
|
|
||||||
return req.Next()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: the ONLY function that should write to this variable is this func
|
|
||||||
var platformInfo = func() string {
|
|
||||||
operatingSystem := runtime.GOOS // Default OS string
|
|
||||||
switch operatingSystem {
|
|
||||||
case "windows":
|
|
||||||
operatingSystem = os.Getenv("OS") // Get more specific OS information
|
|
||||||
case "linux": // accept default OS info
|
|
||||||
case "freebsd": // accept default OS info
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("(%s; %s)", runtime.Version(), operatingSystem)
|
|
||||||
}()
|
|
327
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go
generated
vendored
327
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go
generated
vendored
|
@ -1,327 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FinalStateVia is the enumerated type for the possible final-state-via values.
|
|
||||||
type FinalStateVia = pollers.FinalStateVia
|
|
||||||
|
|
||||||
const (
|
|
||||||
// FinalStateViaAzureAsyncOp indicates the final payload comes from the Azure-AsyncOperation URL.
|
|
||||||
FinalStateViaAzureAsyncOp = pollers.FinalStateViaAzureAsyncOp
|
|
||||||
|
|
||||||
// FinalStateViaLocation indicates the final payload comes from the Location URL.
|
|
||||||
FinalStateViaLocation = pollers.FinalStateViaLocation
|
|
||||||
|
|
||||||
// FinalStateViaOriginalURI indicates the final payload comes from the original URL.
|
|
||||||
FinalStateViaOriginalURI = pollers.FinalStateViaOriginalURI
|
|
||||||
|
|
||||||
// FinalStateViaOpLocation indicates the final payload comes from the Operation-Location URL.
|
|
||||||
FinalStateViaOpLocation = pollers.FinalStateViaOpLocation
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewPollerOptions contains the optional parameters for NewPoller.
|
|
||||||
type NewPollerOptions[T any] struct {
|
|
||||||
// FinalStateVia contains the final-state-via value for the LRO.
|
|
||||||
FinalStateVia FinalStateVia
|
|
||||||
|
|
||||||
// Response contains a preconstructed response type.
|
|
||||||
// The final payload will be unmarshaled into it and returned.
|
|
||||||
Response *T
|
|
||||||
|
|
||||||
// Handler[T] contains a custom polling implementation.
|
|
||||||
Handler PollingHandler[T]
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPoller creates a Poller based on the provided initial response.
|
|
||||||
func NewPoller[T any](resp *http.Response, pl exported.Pipeline, options *NewPollerOptions[T]) (*Poller[T], error) {
|
|
||||||
if options == nil {
|
|
||||||
options = &NewPollerOptions[T]{}
|
|
||||||
}
|
|
||||||
result := options.Response
|
|
||||||
if result == nil {
|
|
||||||
result = new(T)
|
|
||||||
}
|
|
||||||
if options.Handler != nil {
|
|
||||||
return &Poller[T]{
|
|
||||||
op: options.Handler,
|
|
||||||
resp: resp,
|
|
||||||
result: result,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defer resp.Body.Close()
|
|
||||||
// this is a back-stop in case the swagger is incorrect (i.e. missing one or more status codes for success).
|
|
||||||
// ideally the codegen should return an error if the initial response failed and not even create a poller.
|
|
||||||
if !poller.StatusCodeValid(resp) {
|
|
||||||
return nil, errors.New("the operation failed or was cancelled")
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine the polling method
|
|
||||||
var opr PollingHandler[T]
|
|
||||||
var err error
|
|
||||||
if async.Applicable(resp) {
|
|
||||||
// async poller must be checked first as it can also have a location header
|
|
||||||
opr, err = async.New[T](pl, resp, options.FinalStateVia)
|
|
||||||
} else if op.Applicable(resp) {
|
|
||||||
// op poller must be checked before loc as it can also have a location header
|
|
||||||
opr, err = op.New[T](pl, resp, options.FinalStateVia)
|
|
||||||
} else if loc.Applicable(resp) {
|
|
||||||
opr, err = loc.New[T](pl, resp)
|
|
||||||
} else if body.Applicable(resp) {
|
|
||||||
// must test body poller last as it's a subset of the other pollers.
|
|
||||||
// TODO: this is ambiguous for PATCH/PUT if it returns a 200 with no polling headers (sync completion)
|
|
||||||
opr, err = body.New[T](pl, resp)
|
|
||||||
} else if m := resp.Request.Method; resp.StatusCode == http.StatusAccepted && (m == http.MethodDelete || m == http.MethodPost) {
|
|
||||||
// if we get here it means we have a 202 with no polling headers.
|
|
||||||
// for DELETE and POST this is a hard error per ARM RPC spec.
|
|
||||||
return nil, errors.New("response is missing polling URL")
|
|
||||||
} else {
|
|
||||||
opr, err = pollers.NewNopPoller[T](resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Poller[T]{
|
|
||||||
op: opr,
|
|
||||||
resp: resp,
|
|
||||||
result: result,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPollerFromResumeTokenOptions contains the optional parameters for NewPollerFromResumeToken.
|
|
||||||
type NewPollerFromResumeTokenOptions[T any] struct {
|
|
||||||
// Response contains a preconstructed response type.
|
|
||||||
// The final payload will be unmarshaled into it and returned.
|
|
||||||
Response *T
|
|
||||||
|
|
||||||
// Handler[T] contains a custom polling implementation.
|
|
||||||
Handler PollingHandler[T]
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPollerFromResumeToken creates a Poller from a resume token string.
|
|
||||||
func NewPollerFromResumeToken[T any](token string, pl exported.Pipeline, options *NewPollerFromResumeTokenOptions[T]) (*Poller[T], error) {
|
|
||||||
if options == nil {
|
|
||||||
options = &NewPollerFromResumeTokenOptions[T]{}
|
|
||||||
}
|
|
||||||
result := options.Response
|
|
||||||
if result == nil {
|
|
||||||
result = new(T)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := pollers.IsTokenValid[T](token); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
raw, err := pollers.ExtractToken(token)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var asJSON map[string]interface{}
|
|
||||||
if err := json.Unmarshal(raw, &asJSON); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
opr := options.Handler
|
|
||||||
// now rehydrate the poller based on the encoded poller type
|
|
||||||
if opr != nil {
|
|
||||||
log.Writef(log.EventLRO, "Resuming custom poller %T.", opr)
|
|
||||||
} else if async.CanResume(asJSON) {
|
|
||||||
opr, _ = async.New[T](pl, nil, "")
|
|
||||||
} else if body.CanResume(asJSON) {
|
|
||||||
opr, _ = body.New[T](pl, nil)
|
|
||||||
} else if loc.CanResume(asJSON) {
|
|
||||||
opr, _ = loc.New[T](pl, nil)
|
|
||||||
} else if op.CanResume(asJSON) {
|
|
||||||
opr, _ = op.New[T](pl, nil, "")
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("unhandled poller token %s", string(raw))
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(raw, &opr); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Poller[T]{
|
|
||||||
op: opr,
|
|
||||||
result: result,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PollingHandler[T] abstracts the differences among poller implementations.
|
|
||||||
type PollingHandler[T any] interface {
|
|
||||||
// Done returns true if the LRO has reached a terminal state.
|
|
||||||
Done() bool
|
|
||||||
|
|
||||||
// Poll fetches the latest state of the LRO.
|
|
||||||
Poll(context.Context) (*http.Response, error)
|
|
||||||
|
|
||||||
// Result is called once the LRO has reached a terminal state. It populates the out parameter
|
|
||||||
// with the result of the operation.
|
|
||||||
Result(ctx context.Context, out *T) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poller encapsulates a long-running operation, providing polling facilities until the operation reaches a terminal state.
|
|
||||||
type Poller[T any] struct {
|
|
||||||
op PollingHandler[T]
|
|
||||||
resp *http.Response
|
|
||||||
err error
|
|
||||||
result *T
|
|
||||||
done bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// PollUntilDoneOptions contains the optional values for the Poller[T].PollUntilDone() method.
|
|
||||||
type PollUntilDoneOptions struct {
|
|
||||||
// Frequency is the time to wait between polling intervals in absence of a Retry-After header. Allowed minimum is one second.
|
|
||||||
// Pass zero to accept the default value (30s).
|
|
||||||
Frequency time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// PollUntilDone will poll the service endpoint until a terminal state is reached, an error is received, or the context expires.
|
|
||||||
// It internally uses Poll(), Done(), and Result() in its polling loop, sleeping for the specified duration between intervals.
|
|
||||||
// options: pass nil to accept the default values.
|
|
||||||
// NOTE: the default polling frequency is 30 seconds which works well for most operations. However, some operations might
|
|
||||||
// benefit from a shorter or longer duration.
|
|
||||||
func (p *Poller[T]) PollUntilDone(ctx context.Context, options *PollUntilDoneOptions) (T, error) {
|
|
||||||
if options == nil {
|
|
||||||
options = &PollUntilDoneOptions{}
|
|
||||||
}
|
|
||||||
cp := *options
|
|
||||||
if cp.Frequency == 0 {
|
|
||||||
cp.Frequency = 30 * time.Second
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip the floor check when executing tests so they don't take so long
|
|
||||||
if isTest := flag.Lookup("test.v"); isTest == nil && cp.Frequency < time.Second {
|
|
||||||
return *new(T), errors.New("polling frequency minimum is one second")
|
|
||||||
}
|
|
||||||
|
|
||||||
start := time.Now()
|
|
||||||
logPollUntilDoneExit := func(v interface{}) {
|
|
||||||
log.Writef(log.EventLRO, "END PollUntilDone() for %T: %v, total time: %s", p.op, v, time.Since(start))
|
|
||||||
}
|
|
||||||
log.Writef(log.EventLRO, "BEGIN PollUntilDone() for %T", p.op)
|
|
||||||
if p.resp != nil {
|
|
||||||
// initial check for a retry-after header existing on the initial response
|
|
||||||
if retryAfter := shared.RetryAfter(p.resp); retryAfter > 0 {
|
|
||||||
log.Writef(log.EventLRO, "initial Retry-After delay for %s", retryAfter.String())
|
|
||||||
if err := shared.Delay(ctx, retryAfter); err != nil {
|
|
||||||
logPollUntilDoneExit(err)
|
|
||||||
return *new(T), err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// begin polling the endpoint until a terminal state is reached
|
|
||||||
for {
|
|
||||||
resp, err := p.Poll(ctx)
|
|
||||||
if err != nil {
|
|
||||||
logPollUntilDoneExit(err)
|
|
||||||
return *new(T), err
|
|
||||||
}
|
|
||||||
if p.Done() {
|
|
||||||
logPollUntilDoneExit("succeeded")
|
|
||||||
return p.Result(ctx)
|
|
||||||
}
|
|
||||||
d := cp.Frequency
|
|
||||||
if retryAfter := shared.RetryAfter(resp); retryAfter > 0 {
|
|
||||||
log.Writef(log.EventLRO, "Retry-After delay for %s", retryAfter.String())
|
|
||||||
d = retryAfter
|
|
||||||
} else {
|
|
||||||
log.Writef(log.EventLRO, "delay for %s", d.String())
|
|
||||||
}
|
|
||||||
if err = shared.Delay(ctx, d); err != nil {
|
|
||||||
logPollUntilDoneExit(err)
|
|
||||||
return *new(T), err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poll fetches the latest state of the LRO. It returns an HTTP response or error.
|
|
||||||
// If Poll succeeds, the poller's state is updated and the HTTP response is returned.
|
|
||||||
// If Poll fails, the poller's state is unmodified and the error is returned.
|
|
||||||
// Calling Poll on an LRO that has reached a terminal state will return the last HTTP response.
|
|
||||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
|
||||||
if p.Done() {
|
|
||||||
// the LRO has reached a terminal state, don't poll again
|
|
||||||
return p.resp, nil
|
|
||||||
}
|
|
||||||
resp, err := p.op.Poll(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
p.resp = resp
|
|
||||||
return p.resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done returns true if the LRO has reached a terminal state.
|
|
||||||
// Once a terminal state is reached, call Result().
|
|
||||||
func (p *Poller[T]) Done() bool {
|
|
||||||
return p.op.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Result returns the result of the LRO and is meant to be used in conjunction with Poll and Done.
|
|
||||||
// If the LRO completed successfully, a populated instance of T is returned.
|
|
||||||
// If the LRO failed or was canceled, an *azcore.ResponseError error is returned.
|
|
||||||
// Calling this on an LRO in a non-terminal state will return an error.
|
|
||||||
func (p *Poller[T]) Result(ctx context.Context) (T, error) {
|
|
||||||
if !p.Done() {
|
|
||||||
return *new(T), errors.New("poller is in a non-terminal state")
|
|
||||||
}
|
|
||||||
if p.done {
|
|
||||||
// the result has already been retrieved, return the cached value
|
|
||||||
if p.err != nil {
|
|
||||||
return *new(T), p.err
|
|
||||||
}
|
|
||||||
return *p.result, nil
|
|
||||||
}
|
|
||||||
err := p.op.Result(ctx, p.result)
|
|
||||||
var respErr *exported.ResponseError
|
|
||||||
if errors.As(err, &respErr) {
|
|
||||||
// the LRO failed. record the error
|
|
||||||
p.err = err
|
|
||||||
} else if err != nil {
|
|
||||||
// the call to Result failed, don't cache anything in this case
|
|
||||||
return *new(T), err
|
|
||||||
}
|
|
||||||
p.done = true
|
|
||||||
if p.err != nil {
|
|
||||||
return *new(T), p.err
|
|
||||||
}
|
|
||||||
return *p.result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResumeToken returns a value representing the poller that can be used to resume
|
|
||||||
// the LRO at a later time. ResumeTokens are unique per service operation.
|
|
||||||
// The token's format should be considered opaque and is subject to change.
|
|
||||||
// Calling this on an LRO in a terminal state will return an error.
|
|
||||||
func (p *Poller[T]) ResumeToken() (string, error) {
|
|
||||||
if p.Done() {
|
|
||||||
return "", errors.New("poller is in a terminal state")
|
|
||||||
}
|
|
||||||
tk, err := pollers.NewResumeToken[T](p.op)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return tk, err
|
|
||||||
}
|
|
248
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/request.go
generated
vendored
248
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/request.go
generated
vendored
|
@ -1,248 +0,0 @@
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"mime/multipart"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Base64Encoding is usesd to specify which base-64 encoder/decoder to use when
|
|
||||||
// encoding/decoding a slice of bytes to/from a string.
|
|
||||||
type Base64Encoding int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Base64StdFormat uses base64.StdEncoding for encoding and decoding payloads.
|
|
||||||
Base64StdFormat Base64Encoding = 0
|
|
||||||
|
|
||||||
// Base64URLFormat uses base64.RawURLEncoding for encoding and decoding payloads.
|
|
||||||
Base64URLFormat Base64Encoding = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewRequest creates a new policy.Request with the specified input.
|
|
||||||
// The endpoint MUST be properly encoded before calling this function.
|
|
||||||
func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*policy.Request, error) {
|
|
||||||
return exported.NewRequest(ctx, httpMethod, endpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// JoinPaths concatenates multiple URL path segments into one path,
|
|
||||||
// inserting path separation characters as required. JoinPaths will preserve
|
|
||||||
// query parameters in the root path
|
|
||||||
func JoinPaths(root string, paths ...string) string {
|
|
||||||
if len(paths) == 0 {
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
|
|
||||||
qps := ""
|
|
||||||
if strings.Contains(root, "?") {
|
|
||||||
splitPath := strings.Split(root, "?")
|
|
||||||
root, qps = splitPath[0], splitPath[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
p := path.Join(paths...)
|
|
||||||
// path.Join will remove any trailing slashes.
|
|
||||||
// if one was provided, preserve it.
|
|
||||||
if strings.HasSuffix(paths[len(paths)-1], "/") && !strings.HasSuffix(p, "/") {
|
|
||||||
p += "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
if qps != "" {
|
|
||||||
p = p + "?" + qps
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasSuffix(root, "/") && strings.HasPrefix(p, "/") {
|
|
||||||
root = root[:len(root)-1]
|
|
||||||
} else if !strings.HasSuffix(root, "/") && !strings.HasPrefix(p, "/") {
|
|
||||||
p = "/" + p
|
|
||||||
}
|
|
||||||
return root + p
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeByteArray will base-64 encode the byte slice v.
|
|
||||||
func EncodeByteArray(v []byte, format Base64Encoding) string {
|
|
||||||
if format == Base64URLFormat {
|
|
||||||
return base64.RawURLEncoding.EncodeToString(v)
|
|
||||||
}
|
|
||||||
return base64.StdEncoding.EncodeToString(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalAsByteArray will base-64 encode the byte slice v, then calls SetBody.
|
|
||||||
// The encoded value is treated as a JSON string.
|
|
||||||
func MarshalAsByteArray(req *policy.Request, v []byte, format Base64Encoding) error {
|
|
||||||
// send as a JSON string
|
|
||||||
encode := fmt.Sprintf("\"%s\"", EncodeByteArray(v, format))
|
|
||||||
return req.SetBody(exported.NopCloser(strings.NewReader(encode)), shared.ContentTypeAppJSON)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalAsJSON calls json.Marshal() to get the JSON encoding of v then calls SetBody.
|
|
||||||
func MarshalAsJSON(req *policy.Request, v interface{}) error {
|
|
||||||
if omit := os.Getenv("AZURE_SDK_GO_OMIT_READONLY"); omit == "true" {
|
|
||||||
v = cloneWithoutReadOnlyFields(v)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(v)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error marshalling type %T: %s", v, err)
|
|
||||||
}
|
|
||||||
return req.SetBody(exported.NopCloser(bytes.NewReader(b)), shared.ContentTypeAppJSON)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalAsXML calls xml.Marshal() to get the XML encoding of v then calls SetBody.
|
|
||||||
func MarshalAsXML(req *policy.Request, v interface{}) error {
|
|
||||||
b, err := xml.Marshal(v)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error marshalling type %T: %s", v, err)
|
|
||||||
}
|
|
||||||
// inclue the XML header as some services require it
|
|
||||||
b = []byte(xml.Header + string(b))
|
|
||||||
return req.SetBody(exported.NopCloser(bytes.NewReader(b)), shared.ContentTypeAppXML)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMultipartFormData writes the specified keys/values as multi-part form
|
|
||||||
// fields with the specified value. File content must be specified as a ReadSeekCloser.
|
|
||||||
// All other values are treated as string values.
|
|
||||||
func SetMultipartFormData(req *policy.Request, formData map[string]interface{}) error {
|
|
||||||
body := bytes.Buffer{}
|
|
||||||
writer := multipart.NewWriter(&body)
|
|
||||||
|
|
||||||
writeContent := func(fieldname, filename string, src io.Reader) error {
|
|
||||||
fd, err := writer.CreateFormFile(fieldname, filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// copy the data to the form file
|
|
||||||
if _, err = io.Copy(fd, src); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range formData {
|
|
||||||
if rsc, ok := v.(io.ReadSeekCloser); ok {
|
|
||||||
if err := writeContent(k, k, rsc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
} else if rscs, ok := v.([]io.ReadSeekCloser); ok {
|
|
||||||
for _, rsc := range rscs {
|
|
||||||
if err := writeContent(k, k, rsc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// ensure the value is in string format
|
|
||||||
s, ok := v.(string)
|
|
||||||
if !ok {
|
|
||||||
s = fmt.Sprintf("%v", v)
|
|
||||||
}
|
|
||||||
if err := writer.WriteField(k, s); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := writer.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return req.SetBody(exported.NopCloser(bytes.NewReader(body.Bytes())), writer.FormDataContentType())
|
|
||||||
}
|
|
||||||
|
|
||||||
// SkipBodyDownload will disable automatic downloading of the response body.
|
|
||||||
func SkipBodyDownload(req *policy.Request) {
|
|
||||||
req.SetOperationValue(bodyDownloadPolicyOpValues{Skip: true})
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns a clone of the object graph pointed to by v, omitting values of all read-only
|
|
||||||
// fields. if there are no read-only fields in the object graph, no clone is created.
|
|
||||||
func cloneWithoutReadOnlyFields(v interface{}) interface{} {
|
|
||||||
val := reflect.Indirect(reflect.ValueOf(v))
|
|
||||||
if val.Kind() != reflect.Struct {
|
|
||||||
// not a struct, skip
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
// first walk the graph to find any R/O fields.
|
|
||||||
// if there aren't any, skip cloning the graph.
|
|
||||||
if !recursiveFindReadOnlyField(val) {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return recursiveCloneWithoutReadOnlyFields(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns true if any field in the object graph of val contains the `azure:"ro"` tag value
|
|
||||||
func recursiveFindReadOnlyField(val reflect.Value) bool {
|
|
||||||
t := val.Type()
|
|
||||||
// iterate over the fields, looking for the "azure" tag.
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
|
||||||
field := t.Field(i)
|
|
||||||
aztag := field.Tag.Get("azure")
|
|
||||||
if azureTagIsReadOnly(aztag) {
|
|
||||||
return true
|
|
||||||
} else if reflect.Indirect(val.Field(i)).Kind() == reflect.Struct && recursiveFindReadOnlyField(reflect.Indirect(val.Field(i))) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// clones the object graph of val. all non-R/O properties are copied to the clone
|
|
||||||
func recursiveCloneWithoutReadOnlyFields(val reflect.Value) interface{} {
|
|
||||||
t := val.Type()
|
|
||||||
clone := reflect.New(t)
|
|
||||||
// iterate over the fields, looking for the "azure" tag.
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
|
||||||
field := t.Field(i)
|
|
||||||
aztag := field.Tag.Get("azure")
|
|
||||||
if azureTagIsReadOnly(aztag) {
|
|
||||||
// omit from payload
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// clone field will receive the same value as the source field...
|
|
||||||
value := val.Field(i)
|
|
||||||
v := reflect.Indirect(value)
|
|
||||||
if v.IsValid() && v.Type() != reflect.TypeOf(time.Time{}) && v.Kind() == reflect.Struct {
|
|
||||||
// ...unless the source value is a struct, in which case we recurse to clone that struct.
|
|
||||||
// (We can't recursively clone time.Time because it contains unexported fields.)
|
|
||||||
c := recursiveCloneWithoutReadOnlyFields(v)
|
|
||||||
if field.Anonymous {
|
|
||||||
// NOTE: this does not handle the case of embedded fields of unexported struct types.
|
|
||||||
// this should be ok as we don't generate any code like this at present
|
|
||||||
value = reflect.Indirect(reflect.ValueOf(c))
|
|
||||||
} else {
|
|
||||||
value = reflect.ValueOf(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reflect.Indirect(clone).Field(i).Set(value)
|
|
||||||
}
|
|
||||||
return clone.Interface()
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns true if the "azure" tag contains the option "ro"
|
|
||||||
func azureTagIsReadOnly(tag string) bool {
|
|
||||||
if tag == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
parts := strings.Split(tag, ",")
|
|
||||||
for _, part := range parts {
|
|
||||||
if part == "ro" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue