mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
Merge pull request #67722 from dougm/vcp-zones
Automatic merge from submit-queue (batch tested with PRs 66973, 67704, 67722, 67723, 63512). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. godeps: update vmware/govmomi **What this PR does / why we need it**: Update required to continue work on #64021 - The govmomi tag API changed - Pulling in the new vapi/simulator package for testing the VCP Zones impl **Release note**: ```release-note NONE ```
This commit is contained in:
commit
0198e3a311
135
Godeps/Godeps.json
generated
135
Godeps/Godeps.json
generated
@ -2977,153 +2977,168 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/find",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/list",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/lookup",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/lookup/methods",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/lookup/simulator",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/lookup/types",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/nfc",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/object",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/pbm",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/pbm/methods",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/pbm/types",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/property",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/session",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/simulator",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/simulator/esx",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/simulator/vpx",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/sts",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/sts/internal",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/sts/simulator",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/task",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vapi/internal",
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vapi/rest",
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vapi/simulator",
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vapi/tags",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/debug",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/methods",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/mo",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/progress",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/soap",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/types",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/xml",
|
||||
"Comment": "v0.18.0-40-gbbd9953",
|
||||
"Rev": "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
"Comment": "v0.18.0-48-g22f7465",
|
||||
"Rev": "22f74650cf39ba4649fba45e770df0f44df6f758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/photon-controller-go-sdk/SSPI",
|
||||
|
630
Godeps/LICENSES
generated
630
Godeps/LICENSES
generated
@ -90411,6 +90411,636 @@ SOFTWARE.
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/vmware/govmomi/vapi/internal licensed under: =
|
||||
|
||||
|
||||
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.
|
||||
|
||||
= vendor/github.com/vmware/govmomi/LICENSE.txt 3b83ef96387f14655fc854ddc3c6bd57
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/vmware/govmomi/vapi/rest licensed under: =
|
||||
|
||||
|
||||
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.
|
||||
|
||||
= vendor/github.com/vmware/govmomi/LICENSE.txt 3b83ef96387f14655fc854ddc3c6bd57
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/vmware/govmomi/vapi/simulator licensed under: =
|
||||
|
||||
|
||||
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.
|
||||
|
||||
= vendor/github.com/vmware/govmomi/LICENSE.txt 3b83ef96387f14655fc854ddc3c6bd57
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/vmware/govmomi/vapi/tags licensed under: =
|
||||
|
||||
|
@ -29,6 +29,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/rest:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/tags:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vim25:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vim25/mo:go_default_library",
|
||||
@ -59,6 +60,7 @@ go_test(
|
||||
"//vendor/github.com/vmware/govmomi/simulator:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/simulator/vpx:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/sts/simulator:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/simulator:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"gopkg.in/gcfg.v1"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/vmware/govmomi/vapi/rest"
|
||||
"github.com/vmware/govmomi/vapi/tags"
|
||||
"k8s.io/api/core/v1"
|
||||
k8stypes "k8s.io/apimachinery/pkg/types"
|
||||
@ -1318,11 +1319,10 @@ func (vs *VSphere) NodeManager() (nodeManager *NodeManager) {
|
||||
return vs.nodeManager
|
||||
}
|
||||
|
||||
func withTagsClient(ctx context.Context, connection *vclib.VSphereConnection, f func(c *tags.RestClient) error) error {
|
||||
vsURL := connection.Client.URL()
|
||||
vsURL.User = url.UserPassword(connection.Username, connection.Password)
|
||||
c := tags.NewClient(vsURL, connection.Insecure, "")
|
||||
if err := c.Login(ctx); err != nil {
|
||||
func withTagsClient(ctx context.Context, connection *vclib.VSphereConnection, f func(c *rest.Client) error) error {
|
||||
c := rest.NewClient(connection.Client)
|
||||
user := url.UserPassword(connection.Username, connection.Password)
|
||||
if err := c.Login(ctx, user); err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
@ -1353,7 +1353,8 @@ func (vs *VSphere) GetZone(ctx context.Context) (cloudprovider.Zone, error) {
|
||||
return cloudprovider.Zone{}, err
|
||||
}
|
||||
client := vsi.conn
|
||||
err = withTagsClient(ctx, client, func(client *tags.RestClient) error {
|
||||
err = withTagsClient(ctx, client, func(c *rest.Client) error {
|
||||
client := tags.NewManager(c)
|
||||
tags, err := client.ListAttachedTags(ctx, vmHost)
|
||||
if err != nil {
|
||||
glog.Errorf("Cannot list attached tags. Get zone for node %s error", nodeName)
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
"github.com/vmware/govmomi/simulator"
|
||||
"github.com/vmware/govmomi/simulator/vpx"
|
||||
sts "github.com/vmware/govmomi/sts/simulator"
|
||||
_ "github.com/vmware/govmomi/vapi/simulator"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/rand"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
|
3
vendor/github.com/vmware/govmomi/BUILD
generated
vendored
3
vendor/github.com/vmware/govmomi/BUILD
generated
vendored
@ -37,6 +37,9 @@ filegroup(
|
||||
"//vendor/github.com/vmware/govmomi/simulator:all-srcs",
|
||||
"//vendor/github.com/vmware/govmomi/sts:all-srcs",
|
||||
"//vendor/github.com/vmware/govmomi/task:all-srcs",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/internal:all-srcs",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/rest:all-srcs",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/simulator:all-srcs",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/tags:all-srcs",
|
||||
"//vendor/github.com/vmware/govmomi/vim25:all-srcs",
|
||||
],
|
||||
|
2
vendor/github.com/vmware/govmomi/README.md
generated
vendored
2
vendor/github.com/vmware/govmomi/README.md
generated
vendored
@ -83,4 +83,4 @@ Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes.
|
||||
|
||||
## License
|
||||
|
||||
govmomi is available under the [Apache 2 license](LICENSE).
|
||||
govmomi is available under the [Apache 2 license](LICENSE.txt).
|
||||
|
4
vendor/github.com/vmware/govmomi/simulator/session_manager.go
generated
vendored
4
vendor/github.com/vmware/govmomi/simulator/session_manager.go
generated
vendored
@ -137,8 +137,12 @@ func (s *SessionManager) LoginByToken(ctx *Context, req *types.LoginByToken) soa
|
||||
func (s *SessionManager) Logout(ctx *Context, _ *types.Logout) soap.HasFault {
|
||||
session := ctx.Session
|
||||
delete(s.sessions, session.Key)
|
||||
pc := Map.content().PropertyCollector
|
||||
|
||||
for ref, obj := range ctx.Session.Registry.objects {
|
||||
if ref == pc {
|
||||
continue // don't unregister the PropertyCollector singleton
|
||||
}
|
||||
if _, ok := obj.(RegisterObject); ok {
|
||||
ctx.Map.Remove(ref) // Remove RegisterObject handlers
|
||||
}
|
||||
|
27
vendor/github.com/vmware/govmomi/vapi/internal/BUILD
generated
vendored
Normal file
27
vendor/github.com/vmware/govmomi/vapi/internal/BUILD
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["internal.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/vmware/govmomi/vapi/internal",
|
||||
importpath = "github.com/vmware/govmomi/vapi/internal",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/vmware/govmomi/vim25/mo:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vim25/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
126
vendor/github.com/vmware/govmomi/vapi/internal/internal.go
generated
vendored
Normal file
126
vendor/github.com/vmware/govmomi/vapi/internal/internal.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
Copyright (c) 2018 VMware, Inc. All Rights Reserved.
|
||||
|
||||
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 (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
const (
|
||||
Path = "/rest/com/vmware"
|
||||
SessionPath = "/cis/session"
|
||||
CategoryPath = "/cis/tagging/category"
|
||||
TagPath = "/cis/tagging/tag"
|
||||
AssociationPath = "/cis/tagging/tag-association"
|
||||
SessionCookieName = "vmware-api-session-id"
|
||||
)
|
||||
|
||||
// AssociatedObject is the same structure as types.ManagedObjectReference,
|
||||
// just with a different field name (ID instead of Value).
|
||||
// In the API we use mo.Reference, this type is only used for wire transfer.
|
||||
type AssociatedObject struct {
|
||||
Type string `json:"type"`
|
||||
Value string `json:"id"`
|
||||
}
|
||||
|
||||
// Reference implements mo.Reference
|
||||
func (o AssociatedObject) Reference() types.ManagedObjectReference {
|
||||
return types.ManagedObjectReference(o)
|
||||
}
|
||||
|
||||
// Association for tag-association requests.
|
||||
type Association struct {
|
||||
TagID string `json:"tag_id,omitempty"`
|
||||
ObjectID *AssociatedObject `json:"object_id,omitempty"`
|
||||
}
|
||||
|
||||
// NewAssociation returns an Association, converting ref to an AssociatedObject.
|
||||
func NewAssociation(tagID string, ref mo.Reference) Association {
|
||||
obj := AssociatedObject(ref.Reference())
|
||||
return Association{
|
||||
TagID: tagID,
|
||||
ObjectID: &obj,
|
||||
}
|
||||
}
|
||||
|
||||
type CloneURL interface {
|
||||
URL() *url.URL
|
||||
}
|
||||
|
||||
// Resource wraps url.URL with helpers
|
||||
type Resource struct {
|
||||
u *url.URL
|
||||
}
|
||||
|
||||
func URL(c CloneURL, path string) *Resource {
|
||||
r := &Resource{u: c.URL()}
|
||||
r.u.Path = Path + path
|
||||
return r
|
||||
}
|
||||
|
||||
// WithID appends id to the URL.Path
|
||||
func (r *Resource) WithID(id string) *Resource {
|
||||
r.u.Path += "/id:" + id
|
||||
return r
|
||||
}
|
||||
|
||||
// WithAction sets adds action to the URL.RawQuery
|
||||
func (r *Resource) WithAction(action string) *Resource {
|
||||
r.u.RawQuery = url.Values{
|
||||
"~action": []string{action},
|
||||
}.Encode()
|
||||
return r
|
||||
}
|
||||
|
||||
// Request returns a new http.Request for the given method.
|
||||
// An optional body can be provided for POST and PATCH methods.
|
||||
func (r *Resource) Request(method string, body ...interface{}) *http.Request {
|
||||
rdr := io.MultiReader() // empty body by default
|
||||
if len(body) != 0 {
|
||||
rdr = encode(body[0])
|
||||
}
|
||||
req, err := http.NewRequest(method, r.u.String(), rdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return req
|
||||
}
|
||||
|
||||
type errorReader struct {
|
||||
e error
|
||||
}
|
||||
|
||||
func (e errorReader) Read([]byte) (int, error) {
|
||||
return -1, e.e
|
||||
}
|
||||
|
||||
// encode body as JSON, deferring any errors until io.Reader is used.
|
||||
func encode(body interface{}) io.Reader {
|
||||
var b bytes.Buffer
|
||||
err := json.NewEncoder(&b).Encode(body)
|
||||
if err != nil {
|
||||
return errorReader{err}
|
||||
}
|
||||
return &b
|
||||
}
|
28
vendor/github.com/vmware/govmomi/vapi/rest/BUILD
generated
vendored
Normal file
28
vendor/github.com/vmware/govmomi/vapi/rest/BUILD
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["client.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/vmware/govmomi/vapi/rest",
|
||||
importpath = "github.com/vmware/govmomi/vapi/rest",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/vmware/govmomi/vapi/internal:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vim25:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vim25/soap:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
105
vendor/github.com/vmware/govmomi/vapi/rest/client.go
generated
vendored
Normal file
105
vendor/github.com/vmware/govmomi/vapi/rest/client.go
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
Copyright (c) 2018 VMware, Inc. All Rights Reserved.
|
||||
|
||||
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 rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/vmware/govmomi/vapi/internal"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
)
|
||||
|
||||
// Client extends soap.Client to support JSON encoding, while inheriting security features, debug tracing and session persistence.
|
||||
type Client struct {
|
||||
*soap.Client
|
||||
}
|
||||
|
||||
// NewClient creates a new Client instance.
|
||||
func NewClient(c *vim25.Client) *Client {
|
||||
sc := c.Client.NewServiceClient(internal.Path, "")
|
||||
|
||||
return &Client{sc}
|
||||
}
|
||||
|
||||
// Do sends the http.Request, decoding resBody if provided.
|
||||
func (c *Client) Do(ctx context.Context, req *http.Request, resBody interface{}) error {
|
||||
switch req.Method {
|
||||
case http.MethodPost, http.MethodPatch:
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
return c.Client.Do(ctx, req, func(res *http.Response) error {
|
||||
switch res.StatusCode {
|
||||
case http.StatusOK:
|
||||
case http.StatusBadRequest:
|
||||
// TODO: structured error types
|
||||
detail, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%s: %s", res.Status, bytes.TrimSpace(detail))
|
||||
default:
|
||||
return fmt.Errorf("%s %s: %s", req.Method, req.URL, res.Status)
|
||||
}
|
||||
|
||||
if resBody == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch b := resBody.(type) {
|
||||
case io.Writer:
|
||||
_, err := io.Copy(b, res.Body)
|
||||
return err
|
||||
default:
|
||||
val := struct {
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
}{
|
||||
resBody,
|
||||
}
|
||||
return json.NewDecoder(res.Body).Decode(&val)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Login creates a new session via Basic Authentication with the given url.Userinfo.
|
||||
func (c *Client) Login(ctx context.Context, user *url.Userinfo) error {
|
||||
req := internal.URL(c, internal.SessionPath).Request(http.MethodPost)
|
||||
|
||||
if user != nil {
|
||||
if password, ok := user.Password(); ok {
|
||||
req.SetBasicAuth(user.Username(), password)
|
||||
}
|
||||
}
|
||||
|
||||
return c.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// Logout deletes the current session.
|
||||
func (c *Client) Logout(ctx context.Context) error {
|
||||
req := internal.URL(c, internal.SessionPath).Request(http.MethodDelete)
|
||||
return c.Do(ctx, req, nil)
|
||||
}
|
29
vendor/github.com/vmware/govmomi/vapi/simulator/BUILD
generated
vendored
Normal file
29
vendor/github.com/vmware/govmomi/vapi/simulator/BUILD
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["simulator.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/vmware/govmomi/vapi/simulator",
|
||||
importpath = "github.com/vmware/govmomi/vapi/simulator",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/google/uuid:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/internal:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/tags:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vim25/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
354
vendor/github.com/vmware/govmomi/vapi/simulator/simulator.go
generated
vendored
Normal file
354
vendor/github.com/vmware/govmomi/vapi/simulator/simulator.go
generated
vendored
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
Copyright (c) 2018 VMware, Inc. All Rights Reserved.
|
||||
|
||||
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 simulator
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/vmware/govmomi/vapi/internal"
|
||||
"github.com/vmware/govmomi/vapi/tags"
|
||||
vim "github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
*http.ServeMux
|
||||
sync.Mutex
|
||||
Category map[string]*tags.Category
|
||||
Tag map[string]*tags.Tag
|
||||
Association map[string]map[internal.AssociatedObject]bool
|
||||
}
|
||||
|
||||
// New creates a vAPI simulator.
|
||||
func New(u *url.URL, settings []vim.BaseOptionValue) (string, http.Handler) {
|
||||
s := &handler{
|
||||
ServeMux: http.NewServeMux(),
|
||||
Category: make(map[string]*tags.Category),
|
||||
Tag: make(map[string]*tags.Tag),
|
||||
Association: make(map[string]map[internal.AssociatedObject]bool),
|
||||
}
|
||||
|
||||
handlers := []struct {
|
||||
p string
|
||||
m http.HandlerFunc
|
||||
}{
|
||||
{internal.SessionPath, s.session},
|
||||
{internal.CategoryPath, s.category},
|
||||
{internal.CategoryPath + "/", s.categoryID},
|
||||
{internal.TagPath, s.tag},
|
||||
{internal.TagPath + "/", s.tagID},
|
||||
{internal.AssociationPath, s.association},
|
||||
}
|
||||
|
||||
for i := range handlers {
|
||||
h := handlers[i]
|
||||
s.HandleFunc(internal.Path+h.p, func(w http.ResponseWriter, r *http.Request) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
h.m(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
return internal.Path + "/", s
|
||||
}
|
||||
|
||||
// ok responds with http.StatusOK and json encodes val if given.
|
||||
func (s *handler) ok(w http.ResponseWriter, val ...interface{}) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
if len(val) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
err := json.NewEncoder(w).Encode(struct {
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
}{
|
||||
val[0],
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *handler) fail(w http.ResponseWriter, kind string) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
|
||||
err := json.NewEncoder(w).Encode(struct {
|
||||
Type string `json:"type"`
|
||||
Value struct {
|
||||
Messages []string `json:"messages,omitempty"`
|
||||
} `json:"value,omitempty"`
|
||||
}{
|
||||
Type: kind,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// ServeHTTP handles vAPI requests.
|
||||
func (s *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodPost, http.MethodDelete, http.MethodGet, http.MethodPatch:
|
||||
default:
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
h, _ := s.Handler(r)
|
||||
h.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (s *handler) decode(r *http.Request, w http.ResponseWriter, val interface{}) bool {
|
||||
defer r.Body.Close()
|
||||
err := json.NewDecoder(r.Body).Decode(val)
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", r.Method, r.RequestURI, err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *handler) session(w http.ResponseWriter, r *http.Request) {
|
||||
var id string
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
id = uuid.New().String()
|
||||
// TODO: save session
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: internal.SessionCookieName,
|
||||
Value: id,
|
||||
})
|
||||
s.ok(w)
|
||||
case http.MethodDelete:
|
||||
// TODO: delete session
|
||||
s.ok(w)
|
||||
case http.MethodGet:
|
||||
// TODO: test is session is valid
|
||||
s.ok(w, id)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *handler) action(r *http.Request) string {
|
||||
return r.URL.Query().Get("~action")
|
||||
}
|
||||
|
||||
func (s *handler) id(r *http.Request) string {
|
||||
id := path.Base(r.URL.Path)
|
||||
return strings.TrimPrefix(id, "id:")
|
||||
}
|
||||
|
||||
func newID(kind string) string {
|
||||
return fmt.Sprintf("urn:vmomi:InventoryService%s:%s:GLOBAL", kind, uuid.New().String())
|
||||
}
|
||||
|
||||
func (s *handler) category(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
var spec struct {
|
||||
Category tags.Category `json:"create_spec"`
|
||||
}
|
||||
if s.decode(r, w, &spec) {
|
||||
for _, category := range s.Category {
|
||||
if category.Name == spec.Category.Name {
|
||||
s.fail(w, "com.vmware.vapi.std.errors.already_exists")
|
||||
return
|
||||
}
|
||||
}
|
||||
id := newID("Category")
|
||||
spec.Category.ID = id
|
||||
s.Category[id] = &spec.Category
|
||||
s.ok(w, id)
|
||||
}
|
||||
case http.MethodGet:
|
||||
var ids []string
|
||||
for id := range s.Category {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
|
||||
s.ok(w, ids)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *handler) categoryID(w http.ResponseWriter, r *http.Request) {
|
||||
id := s.id(r)
|
||||
|
||||
o, ok := s.Category[id]
|
||||
if !ok {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodDelete:
|
||||
delete(s.Category, id)
|
||||
for ix, tag := range s.Tag {
|
||||
if tag.CategoryID == id {
|
||||
delete(s.Tag, ix)
|
||||
delete(s.Association, ix)
|
||||
}
|
||||
}
|
||||
s.ok(w)
|
||||
case http.MethodPatch:
|
||||
var spec struct {
|
||||
Category tags.Category `json:"update_spec"`
|
||||
}
|
||||
if s.decode(r, w, &spec) {
|
||||
ntypes := len(spec.Category.AssociableTypes)
|
||||
if ntypes != 0 {
|
||||
// Validate that AssociableTypes is only appended to.
|
||||
etypes := len(o.AssociableTypes)
|
||||
fail := ntypes < etypes
|
||||
if !fail {
|
||||
fail = !reflect.DeepEqual(o.AssociableTypes, spec.Category.AssociableTypes[:etypes])
|
||||
}
|
||||
if fail {
|
||||
s.fail(w, "com.vmware.vapi.std.errors.invalid_argument")
|
||||
return
|
||||
}
|
||||
}
|
||||
o.Patch(&spec.Category)
|
||||
s.ok(w)
|
||||
}
|
||||
case http.MethodGet:
|
||||
s.ok(w, o)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *handler) tag(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
var spec struct {
|
||||
Tag tags.Tag `json:"create_spec"`
|
||||
}
|
||||
if s.decode(r, w, &spec) {
|
||||
for _, tag := range s.Tag {
|
||||
if tag.Name == spec.Tag.Name {
|
||||
s.fail(w, "com.vmware.vapi.std.errors.already_exists")
|
||||
return
|
||||
}
|
||||
}
|
||||
id := newID("Tag")
|
||||
spec.Tag.ID = id
|
||||
s.Tag[id] = &spec.Tag
|
||||
s.Association[id] = make(map[internal.AssociatedObject]bool)
|
||||
s.ok(w, id)
|
||||
}
|
||||
case http.MethodGet:
|
||||
var ids []string
|
||||
for id := range s.Tag {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
s.ok(w, ids)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *handler) tagID(w http.ResponseWriter, r *http.Request) {
|
||||
id := s.id(r)
|
||||
|
||||
switch s.action(r) {
|
||||
case "list-tags-for-category":
|
||||
var ids []string
|
||||
for _, tag := range s.Tag {
|
||||
if tag.CategoryID == id {
|
||||
ids = append(ids, tag.ID)
|
||||
}
|
||||
}
|
||||
s.ok(w, ids)
|
||||
return
|
||||
}
|
||||
|
||||
o, ok := s.Tag[id]
|
||||
if !ok {
|
||||
log.Printf("tag not found: %s", id)
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodDelete:
|
||||
delete(s.Tag, id)
|
||||
delete(s.Association, id)
|
||||
s.ok(w)
|
||||
case http.MethodPatch:
|
||||
var spec struct {
|
||||
Tag tags.Tag `json:"update_spec"`
|
||||
}
|
||||
if s.decode(r, w, &spec) {
|
||||
o.Patch(&spec.Tag)
|
||||
s.ok(w)
|
||||
}
|
||||
case http.MethodGet:
|
||||
s.ok(w, o)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *handler) association(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
var spec internal.Association
|
||||
if !s.decode(r, w, &spec) {
|
||||
return
|
||||
}
|
||||
|
||||
if spec.TagID != "" {
|
||||
if _, exists := s.Association[spec.TagID]; !exists {
|
||||
log.Printf("association tag not found: %s", spec.TagID)
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch s.action(r) {
|
||||
case "attach":
|
||||
s.Association[spec.TagID][*spec.ObjectID] = true
|
||||
s.ok(w)
|
||||
case "detach":
|
||||
delete(s.Association[spec.TagID], *spec.ObjectID)
|
||||
s.ok(w)
|
||||
case "list-attached-tags":
|
||||
var ids []string
|
||||
for id, objs := range s.Association {
|
||||
if objs[*spec.ObjectID] {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
s.ok(w, ids)
|
||||
case "list-attached-objects":
|
||||
var ids []internal.AssociatedObject
|
||||
for id := range s.Association[spec.TagID] {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
s.ok(w, ids)
|
||||
}
|
||||
}
|
6
vendor/github.com/vmware/govmomi/vapi/tags/BUILD
generated
vendored
6
vendor/github.com/vmware/govmomi/vapi/tags/BUILD
generated
vendored
@ -4,7 +4,6 @@ go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"categories.go",
|
||||
"rest_client.go",
|
||||
"tag_association.go",
|
||||
"tags.go",
|
||||
],
|
||||
@ -12,8 +11,9 @@ go_library(
|
||||
importpath = "github.com/vmware/govmomi/vapi/tags",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/vmware/govmomi/vim25/soap:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vim25/types:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/internal:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vapi/rest:go_default_library",
|
||||
"//vendor/github.com/vmware/govmomi/vim25/mo:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
326
vendor/github.com/vmware/govmomi/vapi/tags/categories.go
generated
vendored
326
vendor/github.com/vmware/govmomi/vapi/tags/categories.go
generated
vendored
@ -1,226 +1,162 @@
|
||||
// Copyright 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright (c) 2018 VMware, Inc. All Rights Reserved.
|
||||
|
||||
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 tags
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/vapi/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
CategoryURL = "/com/vmware/cis/tagging/category"
|
||||
ErrAlreadyExists = "already_exists"
|
||||
)
|
||||
|
||||
type CategoryCreateSpec struct {
|
||||
CreateSpec CategoryCreate `json:"create_spec"`
|
||||
}
|
||||
|
||||
type CategoryUpdateSpec struct {
|
||||
UpdateSpec CategoryUpdate `json:"update_spec,omitempty"`
|
||||
}
|
||||
|
||||
type CategoryCreate struct {
|
||||
AssociableTypes []string `json:"associable_types"`
|
||||
Cardinality string `json:"cardinality"`
|
||||
Description string `json:"description"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type CategoryUpdate struct {
|
||||
AssociableTypes []string `json:"associable_types,omitempty"`
|
||||
Cardinality string `json:"cardinality,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// Category provides methods to create, read, update, delete, and enumerate categories.
|
||||
type Category struct {
|
||||
ID string `json:"id"`
|
||||
Description string `json:"description"`
|
||||
Name string `json:"name"`
|
||||
Cardinality string `json:"cardinality"`
|
||||
AssociableTypes []string `json:"associable_types"`
|
||||
UsedBy []string `json:"used_by"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Cardinality string `json:"cardinality,omitempty"`
|
||||
AssociableTypes []string `json:"associable_types,omitempty"`
|
||||
UsedBy []string `json:"used_by,omitempty"`
|
||||
}
|
||||
|
||||
type CategoryInfo struct {
|
||||
Name string
|
||||
CategoryID string
|
||||
}
|
||||
|
||||
func (c *RestClient) CreateCategoryIfNotExist(ctx context.Context, name string, description string, categoryType string, multiValue bool) (*string, error) {
|
||||
categories, err := c.GetCategoriesByName(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if categories == nil {
|
||||
var multiValueStr string
|
||||
if multiValue {
|
||||
multiValueStr = "MULTIPLE"
|
||||
} else {
|
||||
multiValueStr = "SINGLE"
|
||||
func (c *Category) hasType(kind string) bool {
|
||||
for _, k := range c.AssociableTypes {
|
||||
if kind == k {
|
||||
return true
|
||||
}
|
||||
categoryCreate := CategoryCreate{[]string{categoryType}, multiValueStr, description, name}
|
||||
spec := CategoryCreateSpec{categoryCreate}
|
||||
id, err := c.CreateCategory(ctx, &spec)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Patch merges Category changes from the given src.
|
||||
// AssociableTypes can only be appended to and cannot shrink.
|
||||
func (c *Category) Patch(src *Category) {
|
||||
if src.Name != "" {
|
||||
c.Name = src.Name
|
||||
}
|
||||
if src.Description != "" {
|
||||
c.Description = src.Description
|
||||
}
|
||||
if src.Cardinality != "" {
|
||||
c.Cardinality = src.Cardinality
|
||||
}
|
||||
// Note that in order to append to AssociableTypes any existing types must be included in their original order.
|
||||
for _, kind := range src.AssociableTypes {
|
||||
if !c.hasType(kind) {
|
||||
c.AssociableTypes = append(c.AssociableTypes, kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CreateCategory creates a new category and returns the category ID.
|
||||
func (c *Manager) CreateCategory(ctx context.Context, category *Category) (string, error) {
|
||||
// create avoids the annoyance of CreateTag requiring field keys to be included in the request,
|
||||
// even though the field value can be empty.
|
||||
type create struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Cardinality string `json:"cardinality"`
|
||||
AssociableTypes []string `json:"associable_types"`
|
||||
}
|
||||
spec := struct {
|
||||
Category create `json:"create_spec"`
|
||||
}{
|
||||
Category: create{
|
||||
Name: category.Name,
|
||||
Description: category.Description,
|
||||
Cardinality: category.Cardinality,
|
||||
AssociableTypes: category.AssociableTypes,
|
||||
},
|
||||
}
|
||||
if spec.Category.AssociableTypes == nil {
|
||||
// otherwise create fails with invalid_argument
|
||||
spec.Category.AssociableTypes = []string{}
|
||||
}
|
||||
url := internal.URL(c, internal.CategoryPath)
|
||||
var res string
|
||||
return res, c.Do(ctx, url.Request(http.MethodPost, spec), &res)
|
||||
}
|
||||
|
||||
// UpdateCategory can update one or more of the AssociableTypes, Cardinality, Description and Name fields.
|
||||
func (c *Manager) UpdateCategory(ctx context.Context, category *Category) error {
|
||||
spec := struct {
|
||||
Category Category `json:"update_spec"`
|
||||
}{
|
||||
Category: Category{
|
||||
AssociableTypes: category.AssociableTypes,
|
||||
Cardinality: category.Cardinality,
|
||||
Description: category.Description,
|
||||
Name: category.Name,
|
||||
},
|
||||
}
|
||||
url := internal.URL(c, internal.CategoryPath).WithID(category.ID)
|
||||
return c.Do(ctx, url.Request(http.MethodPatch, spec), nil)
|
||||
}
|
||||
|
||||
// DeleteCategory deletes an existing category.
|
||||
func (c *Manager) DeleteCategory(ctx context.Context, category *Category) error {
|
||||
url := internal.URL(c, internal.CategoryPath).WithID(category.ID)
|
||||
return c.Do(ctx, url.Request(http.MethodDelete), nil)
|
||||
}
|
||||
|
||||
// GetCategory fetches the category information for the given identifier.
|
||||
// The id parameter can be a Category ID or Category Name.
|
||||
func (c *Manager) GetCategory(ctx context.Context, id string) (*Category, error) {
|
||||
if isName(id) {
|
||||
cat, err := c.GetCategories(ctx)
|
||||
if err != nil {
|
||||
// in case there are two docker daemon try to create inventory category, query the category once again
|
||||
if strings.Contains(err.Error(), "ErrAlreadyExists") {
|
||||
if categories, err = c.GetCategoriesByName(ctx, name); err != nil {
|
||||
return nil, fmt.Errorf("failed to get inventory category for %s", err)
|
||||
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("failed to create inventory category for %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range cat {
|
||||
if cat[i].Name == id {
|
||||
return &cat[i], nil
|
||||
}
|
||||
} else {
|
||||
return id, nil
|
||||
}
|
||||
}
|
||||
if categories != nil {
|
||||
return &categories[0].ID, nil
|
||||
}
|
||||
// should not happen
|
||||
return nil, fmt.Errorf("failed to create inventory for it's existed, but could not query back. Please check system")
|
||||
|
||||
url := internal.URL(c, internal.CategoryPath).WithID(id)
|
||||
var res Category
|
||||
return &res, c.Do(ctx, url.Request(http.MethodGet), &res)
|
||||
}
|
||||
|
||||
func (c *RestClient) CreateCategory(ctx context.Context, spec *CategoryCreateSpec) (*string, error) {
|
||||
stream, _, status, err := c.call(ctx, http.MethodPost, CategoryURL, spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("create category failed with status code: %d, error message: %s", status, err)
|
||||
|
||||
}
|
||||
|
||||
type RespValue struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
var pID RespValue
|
||||
if err := json.NewDecoder(stream).Decode(&pID); err != nil {
|
||||
return nil, fmt.Errorf("decode response body failed for: %s", err)
|
||||
|
||||
}
|
||||
return &(pID.Value), nil
|
||||
// ListCategories returns all category IDs in the system.
|
||||
func (c *Manager) ListCategories(ctx context.Context) ([]string, error) {
|
||||
url := internal.URL(c, internal.CategoryPath)
|
||||
var res []string
|
||||
return res, c.Do(ctx, url.Request(http.MethodGet), &res)
|
||||
}
|
||||
|
||||
func (c *RestClient) GetCategory(ctx context.Context, id string) (*Category, error) {
|
||||
|
||||
stream, _, status, err := c.call(ctx, http.MethodGet, fmt.Sprintf("%s/id:%s", CategoryURL, id), nil, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("get category failed with status code: %d, error message: %s", status, err)
|
||||
|
||||
}
|
||||
|
||||
type RespValue struct {
|
||||
Value Category
|
||||
}
|
||||
|
||||
var pCategory RespValue
|
||||
if err := json.NewDecoder(stream).Decode(&pCategory); err != nil {
|
||||
return nil, fmt.Errorf("decode response body failed for: %s", err)
|
||||
|
||||
}
|
||||
return &(pCategory.Value), nil
|
||||
}
|
||||
|
||||
func (c *RestClient) UpdateCategory(ctx context.Context, id string, spec *CategoryUpdateSpec) error {
|
||||
_, _, status, err := c.call(ctx, http.MethodPatch, fmt.Sprintf("%s/id:%s", CategoryURL, id), spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return fmt.Errorf("update category failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestClient) DeleteCategory(ctx context.Context, id string) error {
|
||||
|
||||
_, _, status, err := c.call(ctx, http.MethodDelete, fmt.Sprintf("%s/id:%s", CategoryURL, id), nil, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return fmt.Errorf("delete category failed with status code: %d, error message: %s", status, err)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestClient) ListCategories(ctx context.Context) ([]string, error) {
|
||||
|
||||
stream, _, status, err := c.call(ctx, http.MethodGet, CategoryURL, nil, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("get categories failed with status code: %d, error message: %s", status, err)
|
||||
|
||||
}
|
||||
|
||||
type Categories struct {
|
||||
Value []string
|
||||
}
|
||||
|
||||
var pCategories Categories
|
||||
if err := json.NewDecoder(stream).Decode(&pCategories); err != nil {
|
||||
return nil, fmt.Errorf("decode response body failed for: %s", err)
|
||||
|
||||
}
|
||||
return pCategories.Value, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) ListCategoriesByName(ctx context.Context) ([]CategoryInfo, error) {
|
||||
categoryIds, err := c.ListCategories(ctx)
|
||||
// GetCategories fetches an array of category information in the system.
|
||||
func (c *Manager) GetCategories(ctx context.Context) ([]Category, error) {
|
||||
ids, err := c.ListCategories(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get category failed for: %s", err)
|
||||
}
|
||||
|
||||
var categoryInfoSlice []CategoryInfo
|
||||
for _, cID := range categoryIds {
|
||||
category, err := c.GetCategory(ctx, cID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get category %s failed for %s", cID, err)
|
||||
}
|
||||
categoryCreate := &CategoryInfo{Name: category.Name, CategoryID: category.ID}
|
||||
|
||||
categoryInfoSlice = append(categoryInfoSlice, *categoryCreate)
|
||||
|
||||
}
|
||||
return categoryInfoSlice, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) GetCategoriesByName(ctx context.Context, name string) ([]Category, error) {
|
||||
categoryIds, err := c.ListCategories(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get category failed for: %s", err)
|
||||
|
||||
return nil, fmt.Errorf("list categories: %s", err)
|
||||
}
|
||||
|
||||
var categories []Category
|
||||
for _, cID := range categoryIds {
|
||||
category, err := c.GetCategory(ctx, cID)
|
||||
for _, id := range ids {
|
||||
category, err := c.GetCategory(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get category %s failed for %s", cID, err)
|
||||
}
|
||||
if category.Name == name {
|
||||
categories = append(categories, *category)
|
||||
return nil, fmt.Errorf("get category %s: %s", id, err)
|
||||
}
|
||||
|
||||
categories = append(categories, *category)
|
||||
|
||||
}
|
||||
return categories, nil
|
||||
}
|
||||
|
272
vendor/github.com/vmware/govmomi/vapi/tags/rest_client.go
generated
vendored
272
vendor/github.com/vmware/govmomi/vapi/tags/rest_client.go
generated
vendored
@ -1,272 +0,0 @@
|
||||
// Copyright 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 tags
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
)
|
||||
|
||||
const (
|
||||
RestPrefix = "/rest"
|
||||
loginURL = "/com/vmware/cis/session"
|
||||
sessionIDCookieName = "vmware-api-session-id"
|
||||
)
|
||||
|
||||
type RestClient struct {
|
||||
mu sync.Mutex
|
||||
host string
|
||||
scheme string
|
||||
endpoint *url.URL
|
||||
user *url.Userinfo
|
||||
HTTP *http.Client
|
||||
cookies []*http.Cookie
|
||||
}
|
||||
|
||||
func NewClient(u *url.URL, insecure bool, thumbprint string) *RestClient {
|
||||
endpoint := &url.URL{}
|
||||
*endpoint = *u
|
||||
endpoint.Path = RestPrefix
|
||||
// Ignore "#" anchor
|
||||
endpoint.Fragment = ""
|
||||
|
||||
sc := soap.NewClient(endpoint, insecure)
|
||||
if thumbprint != "" {
|
||||
sc.SetThumbprint(endpoint.Host, thumbprint)
|
||||
}
|
||||
|
||||
user := endpoint.User
|
||||
endpoint.User = nil
|
||||
|
||||
return &RestClient{
|
||||
endpoint: endpoint,
|
||||
user: user,
|
||||
host: endpoint.Host,
|
||||
scheme: endpoint.Scheme,
|
||||
HTTP: &sc.Client,
|
||||
}
|
||||
}
|
||||
|
||||
// NewClientWithSessionID creates a new REST client with a supplied session ID
|
||||
// to re-connect to existing sessions.
|
||||
//
|
||||
// Note that the session is not checked for validity - to check for a valid
|
||||
// session after creating the client, use the Valid method. If the session is
|
||||
// no longer valid and the session needs to be re-saved, Login should be called
|
||||
// again before calling SessionID to extract the new session ID. Clients
|
||||
// created with this function function work in the exact same way as clients
|
||||
// created with NewClient, including supporting re-login on invalid sessions on
|
||||
// all SDK calls.
|
||||
func NewClientWithSessionID(u *url.URL, insecure bool, thumbprint string, sessionID string) *RestClient {
|
||||
c := NewClient(u, insecure, thumbprint)
|
||||
c.SetSessionID(sessionID)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *RestClient) encodeData(data interface{}) (*bytes.Buffer, error) {
|
||||
params := bytes.NewBuffer(nil)
|
||||
if data != nil {
|
||||
if err := json.NewEncoder(params).Encode(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) call(ctx context.Context, method, path string, data interface{}, headers map[string][]string) (io.ReadCloser, http.Header, int, error) {
|
||||
// Logger.Debugf("%s: %s, headers: %+v", method, path, headers)
|
||||
params, err := c.encodeData(data)
|
||||
if err != nil {
|
||||
return nil, nil, -1, err
|
||||
}
|
||||
|
||||
if data != nil {
|
||||
if headers == nil {
|
||||
headers = make(map[string][]string)
|
||||
}
|
||||
headers["Content-Type"] = []string{"application/json"}
|
||||
}
|
||||
|
||||
body, hdr, statusCode, err := c.clientRequest(ctx, method, path, params, headers)
|
||||
if statusCode == http.StatusUnauthorized && strings.Contains(err.Error(), "This method requires authentication") {
|
||||
c.Login(ctx)
|
||||
return c.clientRequest(ctx, method, path, params, headers)
|
||||
}
|
||||
|
||||
return body, hdr, statusCode, err
|
||||
}
|
||||
|
||||
func (c *RestClient) clientRequest(ctx context.Context, method, path string, in io.Reader, headers map[string][]string) (io.ReadCloser, http.Header, int, error) {
|
||||
expectedPayload := (method == http.MethodPost || method == http.MethodPut)
|
||||
if expectedPayload && in == nil {
|
||||
in = bytes.NewReader([]byte{})
|
||||
}
|
||||
|
||||
req, err := c.newRequest(method, path, in)
|
||||
if err != nil {
|
||||
return nil, nil, -1, err
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
c.mu.Lock()
|
||||
if c.cookies != nil {
|
||||
req.AddCookie(c.cookies[0])
|
||||
}
|
||||
c.mu.Unlock()
|
||||
|
||||
if headers != nil {
|
||||
for k, v := range headers {
|
||||
req.Header[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
if expectedPayload && req.Header.Get("Content-Type") == "" {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
resp, err := c.HTTP.Do(req)
|
||||
return c.handleResponse(resp, err)
|
||||
}
|
||||
|
||||
func (c *RestClient) handleResponse(resp *http.Response, err error) (io.ReadCloser, http.Header, int, error) {
|
||||
statusCode := -1
|
||||
if resp != nil {
|
||||
statusCode = resp.StatusCode
|
||||
}
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
return nil, nil, statusCode, err
|
||||
}
|
||||
return nil, nil, statusCode, err
|
||||
}
|
||||
|
||||
if statusCode < http.StatusOK || statusCode >= http.StatusBadRequest {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, nil, statusCode, err
|
||||
}
|
||||
if len(body) == 0 {
|
||||
return nil, nil, statusCode, err
|
||||
}
|
||||
return nil, nil, statusCode, fmt.Errorf("error response: %s", bytes.TrimSpace(body))
|
||||
|
||||
}
|
||||
|
||||
return resp.Body, resp.Header, statusCode, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) Login(ctx context.Context) error {
|
||||
|
||||
request, err := c.newRequest(http.MethodPost, loginURL, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c.user != nil {
|
||||
password, _ := c.user.Password()
|
||||
request.SetBasicAuth(c.user.Username(), password)
|
||||
}
|
||||
resp, err := c.HTTP.Do(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp == nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
resp.Body.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
c.cookies = resp.Cookies()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestClient) Logout(ctx context.Context) error {
|
||||
_, _, status, err := c.call(ctx, http.MethodDelete, loginURL, nil, nil)
|
||||
if status != http.StatusOK || err != nil {
|
||||
return err
|
||||
}
|
||||
c.SetSessionID("")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestClient) newRequest(method, urlStr string, body io.Reader) (*http.Request, error) {
|
||||
return http.NewRequest(method, c.endpoint.String()+urlStr, body)
|
||||
}
|
||||
|
||||
// SessionID returns the current session ID of the REST client. An empty string
|
||||
// means there was no session cookie currently loaded.
|
||||
func (c *RestClient) SessionID() string {
|
||||
for _, cookie := range c.cookies {
|
||||
if cookie.Name == sessionIDCookieName {
|
||||
return cookie.Value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// SetSessionID sets the session cookie with the supplied session ID.
|
||||
//
|
||||
// This does not necessarily mean the session is valid. The session should be
|
||||
// checked with Valid before proceeding, and logged back in if it has expired.
|
||||
//
|
||||
// This function will overwrite any existing session.
|
||||
func (c *RestClient) SetSessionID(sessionID string) {
|
||||
idx := -1
|
||||
for i, cookie := range c.cookies {
|
||||
if cookie.Name == sessionIDCookieName {
|
||||
idx = i
|
||||
}
|
||||
}
|
||||
sessionCookie := &http.Cookie{
|
||||
Name: sessionIDCookieName,
|
||||
Value: sessionID,
|
||||
Path: RestPrefix,
|
||||
}
|
||||
if idx > -1 {
|
||||
c.cookies[idx] = sessionCookie
|
||||
} else {
|
||||
c.cookies = append(c.cookies, sessionCookie)
|
||||
}
|
||||
}
|
||||
|
||||
// Valid checks to see if the session cookies in a REST client are still valid.
|
||||
// This should be used when restoring a session to determine if a new login is
|
||||
// necessary.
|
||||
func (c *RestClient) Valid(ctx context.Context) bool {
|
||||
_, _, statusCode, err := c.clientRequest(ctx, http.MethodPost, loginURL+"?~action=get", nil, nil)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if statusCode == http.StatusOK {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
213
vendor/github.com/vmware/govmomi/vapi/tags/tag_association.go
generated
vendored
213
vendor/github.com/vmware/govmomi/vapi/tags/tag_association.go
generated
vendored
@ -1,139 +1,108 @@
|
||||
// Copyright 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright (c) 2018 VMware, Inc. All Rights Reserved.
|
||||
|
||||
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
|
||||
|
||||
vUnless 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 tags
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"github.com/vmware/govmomi/vapi/internal"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
)
|
||||
|
||||
const (
|
||||
TagAssociationURL = "/com/vmware/cis/tagging/tag-association"
|
||||
)
|
||||
|
||||
type AssociatedObject struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type TagAssociationSpec struct {
|
||||
ObjectID *AssociatedObject `json:"object_id,omitempty"`
|
||||
TagID *string `json:"tag_id,omitempty"`
|
||||
}
|
||||
|
||||
type AttachedTagsInfo struct {
|
||||
Name string
|
||||
TagID string
|
||||
}
|
||||
|
||||
func (c *RestClient) getAssociatedObject(ref *types.ManagedObjectReference) *AssociatedObject {
|
||||
if ref == nil {
|
||||
return nil
|
||||
}
|
||||
object := AssociatedObject{
|
||||
ID: ref.Value,
|
||||
Type: ref.Type,
|
||||
}
|
||||
return &object
|
||||
}
|
||||
|
||||
func (c *RestClient) getAssociationSpec(tagID *string, ref *types.ManagedObjectReference) *TagAssociationSpec {
|
||||
object := c.getAssociatedObject(ref)
|
||||
spec := TagAssociationSpec{
|
||||
TagID: tagID,
|
||||
ObjectID: object,
|
||||
}
|
||||
return &spec
|
||||
}
|
||||
|
||||
func (c *RestClient) AttachTagToObject(ctx context.Context, tagID string, ref *types.ManagedObjectReference) error {
|
||||
spec := c.getAssociationSpec(&tagID, ref)
|
||||
_, _, status, err := c.call(ctx, http.MethodPost, fmt.Sprintf("%s?~action=attach", TagAssociationURL), *spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return fmt.Errorf("attach tag failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestClient) DetachTagFromObject(ctx context.Context, tagID string, ref *types.ManagedObjectReference) error {
|
||||
spec := c.getAssociationSpec(&tagID, ref)
|
||||
_, _, status, err := c.call(ctx, http.MethodPost, fmt.Sprintf("%s?~action=detach", TagAssociationURL), *spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return fmt.Errorf("detach tag failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestClient) ListAttachedTags(ctx context.Context, ref *types.ManagedObjectReference) ([]string, error) {
|
||||
spec := c.getAssociationSpec(nil, ref)
|
||||
stream, _, status, err := c.call(ctx, http.MethodPost, fmt.Sprintf("%s?~action=list-attached-tags", TagAssociationURL), *spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("detach tag failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
|
||||
type RespValue struct {
|
||||
Value []string
|
||||
}
|
||||
|
||||
var pTag RespValue
|
||||
if err := json.NewDecoder(stream).Decode(&pTag); err != nil {
|
||||
return nil, fmt.Errorf("decode response body failed for: %s", err)
|
||||
}
|
||||
return pTag.Value, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) ListAttachedTagsByName(ctx context.Context, ref *types.ManagedObjectReference) ([]AttachedTagsInfo, error) {
|
||||
tagIds, err := c.ListAttachedTags(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get attached tag failed for: %s", err)
|
||||
}
|
||||
|
||||
var attachedTagsInfoSlice []AttachedTagsInfo
|
||||
for _, cID := range tagIds {
|
||||
tag, err := c.GetTag(ctx, cID)
|
||||
func (c *Manager) tagID(ctx context.Context, id string) (string, error) {
|
||||
if isName(id) {
|
||||
tag, err := c.GetTag(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get tag %s failed for %s", cID, err)
|
||||
return "", err
|
||||
}
|
||||
attachedTagsCreate := &AttachedTagsInfo{Name: tag.Name, TagID: tag.ID}
|
||||
attachedTagsInfoSlice = append(attachedTagsInfoSlice, *attachedTagsCreate)
|
||||
return tag.ID, nil
|
||||
}
|
||||
return attachedTagsInfoSlice, nil
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) ListAttachedObjects(ctx context.Context, tagID string) ([]AssociatedObject, error) {
|
||||
spec := c.getAssociationSpec(&tagID, nil)
|
||||
stream, _, status, err := c.call(ctx, http.MethodPost, fmt.Sprintf("%s?~action=list-attached-objects", TagAssociationURL), *spec, nil)
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("list object failed with status code: %d, error message: %s", status, err)
|
||||
// AttachTag attaches a tag ID to a managed object.
|
||||
func (c *Manager) AttachTag(ctx context.Context, tagID string, ref mo.Reference) error {
|
||||
id, err := c.tagID(ctx, tagID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type RespValue struct {
|
||||
Value []AssociatedObject
|
||||
}
|
||||
|
||||
var pTag RespValue
|
||||
if err := json.NewDecoder(stream).Decode(&pTag); err != nil {
|
||||
return nil, fmt.Errorf("decode response body failed for: %s", err)
|
||||
}
|
||||
|
||||
return pTag.Value, nil
|
||||
spec := internal.NewAssociation(id, ref)
|
||||
url := internal.URL(c, internal.AssociationPath).WithAction("attach")
|
||||
return c.Do(ctx, url.Request(http.MethodPost, spec), nil)
|
||||
}
|
||||
|
||||
// DetachTag detaches a tag ID from a managed object.
|
||||
// If the tag is already removed from the object, then this operation is a no-op and an error will not be thrown.
|
||||
func (c *Manager) DetachTag(ctx context.Context, tagID string, ref mo.Reference) error {
|
||||
id, err := c.tagID(ctx, tagID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spec := internal.NewAssociation(id, ref)
|
||||
url := internal.URL(c, internal.AssociationPath).WithAction("detach")
|
||||
return c.Do(ctx, url.Request(http.MethodPost, spec), nil)
|
||||
}
|
||||
|
||||
// ListAttachedTags fetches the array of tag IDs attached to the given object.
|
||||
func (c *Manager) ListAttachedTags(ctx context.Context, ref mo.Reference) ([]string, error) {
|
||||
spec := internal.NewAssociation("", ref)
|
||||
url := internal.URL(c, internal.AssociationPath).WithAction("list-attached-tags")
|
||||
var res []string
|
||||
return res, c.Do(ctx, url.Request(http.MethodPost, spec), &res)
|
||||
}
|
||||
|
||||
// GetAttachedTags fetches the array of tags attached to the given object.
|
||||
func (c *Manager) GetAttachedTags(ctx context.Context, ref mo.Reference) ([]Tag, error) {
|
||||
ids, err := c.ListAttachedTags(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get attached tags %s: %s", ref, err)
|
||||
}
|
||||
|
||||
var info []Tag
|
||||
for _, id := range ids {
|
||||
tag, err := c.GetTag(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get tag %s: %s", id, err)
|
||||
}
|
||||
info = append(info, *tag)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// ListAttachedObjects fetches the array of attached objects for the given tag ID.
|
||||
func (c *Manager) ListAttachedObjects(ctx context.Context, tagID string) ([]mo.Reference, error) {
|
||||
id, err := c.tagID(ctx, tagID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
spec := internal.Association{
|
||||
TagID: id,
|
||||
}
|
||||
url := internal.URL(c, internal.AssociationPath).WithAction("list-attached-objects")
|
||||
var res []internal.AssociatedObject
|
||||
if err := c.Do(ctx, url.Request(http.MethodPost, spec), &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
refs := make([]mo.Reference, len(res))
|
||||
for i := range res {
|
||||
refs[i] = res[i]
|
||||
}
|
||||
return refs, nil
|
||||
}
|
||||
|
388
vendor/github.com/vmware/govmomi/vapi/tags/tags.go
generated
vendored
388
vendor/github.com/vmware/govmomi/vapi/tags/tags.go
generated
vendored
@ -1,252 +1,202 @@
|
||||
// Copyright 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright (c) 2018 VMware, Inc. All Rights Reserved.
|
||||
|
||||
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 tags
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/vapi/internal"
|
||||
"github.com/vmware/govmomi/vapi/rest"
|
||||
)
|
||||
|
||||
const (
|
||||
TagURL = "/com/vmware/cis/tagging/tag"
|
||||
)
|
||||
|
||||
type TagCreateSpec struct {
|
||||
CreateSpec TagCreate `json:"create_spec"`
|
||||
// Manager extends rest.Client, adding tag related methods.
|
||||
type Manager struct {
|
||||
*rest.Client
|
||||
}
|
||||
|
||||
type TagCreate struct {
|
||||
CategoryID string `json:"category_id"`
|
||||
Description string `json:"description"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type TagUpdateSpec struct {
|
||||
UpdateSpec TagUpdate `json:"update_spec,omitempty"`
|
||||
}
|
||||
|
||||
type TagUpdate struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
type Tag struct {
|
||||
ID string `json:"id"`
|
||||
Description string `json:"description"`
|
||||
Name string `json:"name"`
|
||||
CategoryID string `json:"category_id"`
|
||||
UsedBy []string `json:"used_by"`
|
||||
}
|
||||
|
||||
func (c *RestClient) CreateTagIfNotExist(ctx context.Context, name string, description string, categoryID string) (*string, error) {
|
||||
tagCreate := TagCreate{categoryID, description, name}
|
||||
spec := TagCreateSpec{tagCreate}
|
||||
id, err := c.CreateTag(ctx, &spec)
|
||||
if err == nil {
|
||||
return id, nil
|
||||
// NewManager creates a new Manager instance with the given client.
|
||||
func NewManager(client *rest.Client) *Manager {
|
||||
return &Manager{
|
||||
Client: client,
|
||||
}
|
||||
// if already exists, query back
|
||||
if strings.Contains(err.Error(), ErrAlreadyExists) {
|
||||
tagObjs, err := c.GetTagByNameForCategory(ctx, name, categoryID)
|
||||
}
|
||||
|
||||
// isName returns true if the id is not a urn.
|
||||
func isName(id string) bool {
|
||||
return !strings.HasPrefix(id, "urn:")
|
||||
}
|
||||
|
||||
// Tag provides methods to create, read, update, delete, and enumerate tags.
|
||||
type Tag struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
CategoryID string `json:"category_id,omitempty"`
|
||||
UsedBy []string `json:"used_by,omitempty"`
|
||||
}
|
||||
|
||||
// Patch merges updates from the given src.
|
||||
func (t *Tag) Patch(src *Tag) {
|
||||
if src.Name != "" {
|
||||
t.Name = src.Name
|
||||
}
|
||||
if src.Description != "" {
|
||||
t.Description = src.Description
|
||||
}
|
||||
if src.CategoryID != "" {
|
||||
t.CategoryID = src.CategoryID
|
||||
}
|
||||
}
|
||||
|
||||
// CreateTag creates a new tag with the given Name, Description and CategoryID.
|
||||
func (c *Manager) CreateTag(ctx context.Context, tag *Tag) (string, error) {
|
||||
// create avoids the annoyance of CreateTag requiring a "description" key to be included in the request,
|
||||
// even though the field value can be empty.
|
||||
type create struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
CategoryID string `json:"category_id"`
|
||||
}
|
||||
spec := struct {
|
||||
Tag create `json:"create_spec"`
|
||||
}{
|
||||
Tag: create{
|
||||
Name: tag.Name,
|
||||
Description: tag.Description,
|
||||
CategoryID: tag.CategoryID,
|
||||
},
|
||||
}
|
||||
if isName(tag.CategoryID) {
|
||||
cat, err := c.GetCategory(ctx, tag.CategoryID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
spec.Tag.CategoryID = cat.ID
|
||||
}
|
||||
url := internal.URL(c, internal.TagPath)
|
||||
var res string
|
||||
return res, c.Do(ctx, url.Request(http.MethodPost, spec), &res)
|
||||
}
|
||||
|
||||
// UpdateTag can update one or both of the tag Description and Name fields.
|
||||
func (c *Manager) UpdateTag(ctx context.Context, tag *Tag) error {
|
||||
spec := struct {
|
||||
Tag Tag `json:"update_spec"`
|
||||
}{
|
||||
Tag: Tag{
|
||||
Name: tag.Name,
|
||||
Description: tag.Description,
|
||||
},
|
||||
}
|
||||
url := internal.URL(c, internal.TagPath).WithID(tag.ID)
|
||||
return c.Do(ctx, url.Request(http.MethodPatch, spec), nil)
|
||||
}
|
||||
|
||||
// DeleteTag deletes an existing tag.
|
||||
func (c *Manager) DeleteTag(ctx context.Context, tag *Tag) error {
|
||||
url := internal.URL(c, internal.TagPath).WithID(tag.ID)
|
||||
return c.Do(ctx, url.Request(http.MethodDelete), nil)
|
||||
}
|
||||
|
||||
// GetTag fetches the tag information for the given identifier.
|
||||
// The id parameter can be a Tag ID or Tag Name.
|
||||
func (c *Manager) GetTag(ctx context.Context, id string) (*Tag, error) {
|
||||
if isName(id) {
|
||||
tags, err := c.GetTags(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tagObjs != nil {
|
||||
return &tagObjs[0].ID, nil
|
||||
|
||||
for i := range tags {
|
||||
if tags[i].Name == id {
|
||||
return &tags[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
// should not happen
|
||||
return nil, fmt.Errorf("failed to create tag for it's existed, but could not query back. Please check system")
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("created tag failed for %s", err)
|
||||
url := internal.URL(c, internal.TagPath).WithID(id)
|
||||
var res Tag
|
||||
return &res, c.Do(ctx, url.Request(http.MethodGet), &res)
|
||||
|
||||
}
|
||||
|
||||
func (c *RestClient) DeleteTagIfNoObjectAttached(ctx context.Context, id string) error {
|
||||
objs, err := c.ListAttachedObjects(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(objs) > 0 {
|
||||
return fmt.Errorf("tag %s related objects is not empty, do not delete it", id)
|
||||
}
|
||||
return c.DeleteTag(ctx, id)
|
||||
// ListTags returns all tag IDs in the system.
|
||||
func (c *Manager) ListTags(ctx context.Context) ([]string, error) {
|
||||
url := internal.URL(c, internal.TagPath)
|
||||
var res []string
|
||||
return res, c.Do(ctx, url.Request(http.MethodGet), &res)
|
||||
}
|
||||
|
||||
func (c *RestClient) CreateTag(ctx context.Context, spec *TagCreateSpec) (*string, error) {
|
||||
stream, _, status, err := c.call(ctx, http.MethodPost, TagURL, spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("create tag failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
|
||||
type RespValue struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
var pID RespValue
|
||||
if err := json.NewDecoder(stream).Decode(&pID); err != nil {
|
||||
return nil, fmt.Errorf("decode response body failed for: %s", err)
|
||||
}
|
||||
return &pID.Value, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) GetTag(ctx context.Context, id string) (*Tag, error) {
|
||||
stream, _, status, err := c.call(ctx, http.MethodGet, fmt.Sprintf("%s/id:%s", TagURL, id), nil, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("get tag failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
|
||||
type RespValue struct {
|
||||
Value Tag
|
||||
}
|
||||
|
||||
var pTag RespValue
|
||||
if err := json.NewDecoder(stream).Decode(&pTag); err != nil {
|
||||
return nil, fmt.Errorf("decode response body failed for: %s", err)
|
||||
}
|
||||
return &(pTag.Value), nil
|
||||
}
|
||||
|
||||
func (c *RestClient) UpdateTag(ctx context.Context, id string, spec *TagUpdateSpec) error {
|
||||
_, _, status, err := c.call(ctx, http.MethodPatch, fmt.Sprintf("%s/id:%s", TagURL, id), spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return fmt.Errorf("update tag failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestClient) DeleteTag(ctx context.Context, id string) error {
|
||||
_, _, status, err := c.call(ctx, http.MethodDelete, fmt.Sprintf("%s/id:%s", TagURL, id), nil, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return fmt.Errorf("delete tag failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestClient) ListTags(ctx context.Context) ([]string, error) {
|
||||
stream, _, status, err := c.call(ctx, http.MethodGet, TagURL, nil, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("get tags failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
|
||||
return c.handleTagIDList(stream)
|
||||
}
|
||||
|
||||
type TagsInfo struct {
|
||||
Name string
|
||||
TagID string
|
||||
}
|
||||
|
||||
func (c *RestClient) ListTagsByName(ctx context.Context) ([]TagsInfo, error) {
|
||||
tagIds, err := c.ListTags(ctx)
|
||||
// GetTags fetches an array of tag information in the system.
|
||||
func (c *Manager) GetTags(ctx context.Context) ([]Tag, error) {
|
||||
ids, err := c.ListTags(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get tags failed for: %s", err)
|
||||
}
|
||||
|
||||
var tagsInfoSlice []TagsInfo
|
||||
for _, cID := range tagIds {
|
||||
tag, err := c.GetTag(ctx, cID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get category %s failed for %s", cID, err)
|
||||
}
|
||||
tagsCreate := &TagsInfo{Name: tag.Name, TagID: tag.ID}
|
||||
|
||||
tagsInfoSlice = append(tagsInfoSlice, *tagsCreate)
|
||||
|
||||
}
|
||||
return tagsInfoSlice, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) ListTagsForCategory(ctx context.Context, id string) ([]string, error) {
|
||||
|
||||
type PostCategory struct {
|
||||
ID string `json:"category_id"`
|
||||
}
|
||||
spec := PostCategory{id}
|
||||
stream, _, status, err := c.call(ctx, http.MethodPost, fmt.Sprintf("%s/id:%s?~action=list-tags-for-category", TagURL, id), spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("list tags for category failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
|
||||
return c.handleTagIDList(stream)
|
||||
}
|
||||
|
||||
func (c *RestClient) ListTagsInfoForCategory(ctx context.Context, id string) ([]TagsInfo, error) {
|
||||
|
||||
type PostCategory struct {
|
||||
ID string `json:"category_id"`
|
||||
}
|
||||
spec := PostCategory{id}
|
||||
stream, _, status, err := c.call(ctx, http.MethodPost, fmt.Sprintf("%s/id:%s?~action=list-tags-for-category", TagURL, id), spec, nil)
|
||||
|
||||
if status != http.StatusOK || err != nil {
|
||||
return nil, fmt.Errorf("list tags for category failed with status code: %d, error message: %s", status, err)
|
||||
}
|
||||
var tagsInfoSlice []TagsInfo
|
||||
tmp, err := c.handleTagIDList(stream)
|
||||
for _, item := range tmp {
|
||||
tag, err := c.GetTag(ctx, item)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get category %s failed for %s", item, err)
|
||||
}
|
||||
tagsCreate := &TagsInfo{Name: tag.Name, TagID: tag.ID}
|
||||
|
||||
tagsInfoSlice = append(tagsInfoSlice, *tagsCreate)
|
||||
}
|
||||
return tagsInfoSlice, nil
|
||||
}
|
||||
|
||||
func (c *RestClient) handleTagIDList(stream io.ReadCloser) ([]string, error) {
|
||||
type Tags struct {
|
||||
Value []string
|
||||
}
|
||||
|
||||
var pTags Tags
|
||||
if err := json.NewDecoder(stream).Decode(&pTags); err != nil {
|
||||
return nil, fmt.Errorf("decode response body failed for: %s", err)
|
||||
}
|
||||
return pTags.Value, nil
|
||||
}
|
||||
|
||||
// Get tag through tag name and category id
|
||||
func (c *RestClient) GetTagByNameForCategory(ctx context.Context, name string, id string) ([]Tag, error) {
|
||||
tagIds, err := c.ListTagsForCategory(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get tag failed for %s", err)
|
||||
}
|
||||
|
||||
var tags []Tag
|
||||
for _, tID := range tagIds {
|
||||
tag, err := c.GetTag(ctx, tID)
|
||||
for _, id := range ids {
|
||||
tag, err := c.GetTag(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get tag %s failed for %s", tID, err)
|
||||
}
|
||||
if tag.Name == name {
|
||||
tags = append(tags, *tag)
|
||||
return nil, fmt.Errorf("get category %s failed for %s", id, err)
|
||||
}
|
||||
|
||||
tags = append(tags, *tag)
|
||||
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
// The id parameter can be a Category ID or Category Name.
|
||||
func (c *Manager) ListTagsForCategory(ctx context.Context, id string) ([]string, error) {
|
||||
if isName(id) {
|
||||
cat, err := c.GetCategory(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id = cat.ID
|
||||
}
|
||||
|
||||
body := struct {
|
||||
ID string `json:"category_id"`
|
||||
}{id}
|
||||
url := internal.URL(c, internal.TagPath).WithID(id).WithAction("list-tags-for-category")
|
||||
var res []string
|
||||
return res, c.Do(ctx, url.Request(http.MethodPost, body), &res)
|
||||
}
|
||||
|
||||
// The id parameter can be a Category ID or Category Name.
|
||||
func (c *Manager) GetTagsForCategory(ctx context.Context, id string) ([]Tag, error) {
|
||||
ids, err := c.ListTagsForCategory(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tags []Tag
|
||||
for _, id := range ids {
|
||||
tag, err := c.GetTag(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get tag %s: %s", id, err)
|
||||
}
|
||||
|
||||
tags = append(tags, *tag)
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
|
118
vendor/github.com/vmware/govmomi/vim25/soap/client.go
generated
vendored
118
vendor/github.com/vmware/govmomi/vim25/soap/client.go
generated
vendored
@ -449,12 +449,51 @@ func (c *Client) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) {
|
||||
if nil == ctx || nil == ctx.Done() { // ctx.Done() is for ctx
|
||||
return c.Client.Do(req)
|
||||
type kindContext struct{}
|
||||
|
||||
func (c *Client) Do(ctx context.Context, req *http.Request, f func(*http.Response) error) error {
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
// Create debugging context for this round trip
|
||||
d := c.d.newRoundTrip()
|
||||
if d.enabled() {
|
||||
defer d.done()
|
||||
}
|
||||
|
||||
return c.Client.Do(req.WithContext(ctx))
|
||||
if c.UserAgent != "" {
|
||||
req.Header.Set(`User-Agent`, c.UserAgent)
|
||||
}
|
||||
|
||||
if d.enabled() {
|
||||
d.debugRequest(req)
|
||||
}
|
||||
|
||||
tstart := time.Now()
|
||||
res, err := c.Client.Do(req.WithContext(ctx))
|
||||
tstop := time.Now()
|
||||
|
||||
if d.enabled() {
|
||||
var name string
|
||||
if kind, ok := ctx.Value(kindContext{}).(HasFault); ok {
|
||||
name = fmt.Sprintf("%T", kind)
|
||||
} else {
|
||||
name = fmt.Sprintf("%s %s", req.Method, req.URL)
|
||||
}
|
||||
d.logf("%6dms (%s)", tstop.Sub(tstart)/time.Millisecond, name)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
if d.enabled() {
|
||||
d.debugResponse(res)
|
||||
}
|
||||
|
||||
return f(res)
|
||||
}
|
||||
|
||||
// Signer can be implemented by soap.Header.Security to sign requests.
|
||||
@ -493,12 +532,6 @@ func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error
|
||||
reqEnv.Header = &h // XML marshal header only if a field is set
|
||||
}
|
||||
|
||||
// Create debugging context for this round trip
|
||||
d := c.d.newRoundTrip()
|
||||
if d.enabled() {
|
||||
defer d.done()
|
||||
}
|
||||
|
||||
if signer, ok := h.Security.(Signer); ok {
|
||||
b, err = signer.Sign(reqEnv)
|
||||
if err != nil {
|
||||
@ -517,8 +550,6 @@ func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
|
||||
|
||||
action := h.Action
|
||||
@ -527,54 +558,29 @@ func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error
|
||||
}
|
||||
req.Header.Set(`SOAPAction`, action)
|
||||
|
||||
if c.UserAgent != "" {
|
||||
req.Header.Set(`User-Agent`, c.UserAgent)
|
||||
}
|
||||
return c.Do(context.WithValue(ctx, kindContext{}, resBody), req, func(res *http.Response) error {
|
||||
switch res.StatusCode {
|
||||
case http.StatusOK:
|
||||
// OK
|
||||
case http.StatusInternalServerError:
|
||||
// Error, but typically includes a body explaining the error
|
||||
default:
|
||||
return errors.New(res.Status)
|
||||
}
|
||||
|
||||
if d.enabled() {
|
||||
d.debugRequest(req)
|
||||
}
|
||||
dec := xml.NewDecoder(res.Body)
|
||||
dec.TypeFunc = types.TypeFunc()
|
||||
err = dec.Decode(&resEnv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tstart := time.Now()
|
||||
res, err := c.do(ctx, req)
|
||||
tstop := time.Now()
|
||||
if f := resBody.Fault(); f != nil {
|
||||
return WrapSoapFault(f)
|
||||
}
|
||||
|
||||
if d.enabled() {
|
||||
d.logf("%6dms (%T)", tstop.Sub(tstart)/time.Millisecond, resBody)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.enabled() {
|
||||
d.debugResponse(res)
|
||||
}
|
||||
|
||||
// Close response regardless of what happens next
|
||||
defer res.Body.Close()
|
||||
|
||||
switch res.StatusCode {
|
||||
case http.StatusOK:
|
||||
// OK
|
||||
case http.StatusInternalServerError:
|
||||
// Error, but typically includes a body explaining the error
|
||||
default:
|
||||
return errors.New(res.Status)
|
||||
}
|
||||
|
||||
dec := xml.NewDecoder(res.Body)
|
||||
dec.TypeFunc = types.TypeFunc()
|
||||
err = dec.Decode(&resEnv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if f := resBody.Fault(); f != nil {
|
||||
return WrapSoapFault(f)
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Client) CloseIdleConnections() {
|
||||
|
13
vendor/github.com/vmware/govmomi/vim25/soap/debug.go
generated
vendored
13
vendor/github.com/vmware/govmomi/vim25/soap/debug.go
generated
vendored
@ -21,6 +21,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
@ -69,6 +70,14 @@ func (d *debugRoundTrip) newFile(suffix string) io.WriteCloser {
|
||||
return debug.NewFile(fmt.Sprintf("%d-%04d.%s", d.cn, d.rn, suffix))
|
||||
}
|
||||
|
||||
func (d *debugRoundTrip) ext(h http.Header) string {
|
||||
ext := "xml"
|
||||
if strings.Contains(h.Get("Content-Type"), "/json") {
|
||||
ext = "json"
|
||||
}
|
||||
return ext
|
||||
}
|
||||
|
||||
func (d *debugRoundTrip) debugRequest(req *http.Request) {
|
||||
if d == nil {
|
||||
return
|
||||
@ -83,7 +92,7 @@ func (d *debugRoundTrip) debugRequest(req *http.Request) {
|
||||
wc.Close()
|
||||
|
||||
// Capture body
|
||||
wc = d.newFile("req.xml")
|
||||
wc = d.newFile("req." + d.ext(req.Header))
|
||||
req.Body = newTeeReader(req.Body, wc)
|
||||
|
||||
// Delay closing until marked done
|
||||
@ -104,7 +113,7 @@ func (d *debugRoundTrip) debugResponse(res *http.Response) {
|
||||
wc.Close()
|
||||
|
||||
// Capture body
|
||||
wc = d.newFile("res.xml")
|
||||
wc = d.newFile("res." + d.ext(res.Header))
|
||||
res.Body = newTeeReader(res.Body, wc)
|
||||
|
||||
// Delay closing until marked done
|
||||
|
Loading…
Reference in New Issue
Block a user