From 5816a8bc18b5d3684df85a3eb54a6d6353f04cfe Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 22 Aug 2018 11:11:11 -0700 Subject: [PATCH] godeps: update vmware/govmomi 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 --- Godeps/Godeps.json | 135 ++-- Godeps/LICENSES | 630 ++++++++++++++++++ pkg/cloudprovider/providers/vsphere/BUILD | 2 + .../providers/vsphere/vsphere.go | 1 + .../providers/vsphere/vsphere_test.go | 1 + vendor/github.com/vmware/govmomi/BUILD | 3 + vendor/github.com/vmware/govmomi/README.md | 2 +- .../govmomi/simulator/session_manager.go | 4 + .../vmware/govmomi/vapi/internal/BUILD | 27 + .../vmware/govmomi/vapi/internal/internal.go | 126 ++++ .../github.com/vmware/govmomi/vapi/rest/BUILD | 28 + .../vmware/govmomi/vapi/rest/client.go | 105 +++ .../vmware/govmomi/vapi/simulator/BUILD | 29 + .../govmomi/vapi/simulator/simulator.go | 354 ++++++++++ .../github.com/vmware/govmomi/vapi/tags/BUILD | 6 +- .../vmware/govmomi/vapi/tags/categories.go | 326 ++++----- .../vmware/govmomi/vapi/tags/rest_client.go | 272 -------- .../govmomi/vapi/tags/tag_association.go | 213 +++--- .../vmware/govmomi/vapi/tags/tags.go | 388 +++++------ .../vmware/govmomi/vim25/soap/client.go | 118 ++-- .../vmware/govmomi/vim25/soap/debug.go | 13 +- 21 files changed, 1853 insertions(+), 930 deletions(-) create mode 100644 vendor/github.com/vmware/govmomi/vapi/internal/BUILD create mode 100644 vendor/github.com/vmware/govmomi/vapi/internal/internal.go create mode 100644 vendor/github.com/vmware/govmomi/vapi/rest/BUILD create mode 100644 vendor/github.com/vmware/govmomi/vapi/rest/client.go create mode 100644 vendor/github.com/vmware/govmomi/vapi/simulator/BUILD create mode 100644 vendor/github.com/vmware/govmomi/vapi/simulator/simulator.go delete mode 100644 vendor/github.com/vmware/govmomi/vapi/tags/rest_client.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index a6abd865a1e..aa50deacd83 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -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", diff --git a/Godeps/LICENSES b/Godeps/LICENSES index 1630af36444..e8af706acf9 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -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: = diff --git a/pkg/cloudprovider/providers/vsphere/BUILD b/pkg/cloudprovider/providers/vsphere/BUILD index 3eaca85d629..fa4970a4fcc 100644 --- a/pkg/cloudprovider/providers/vsphere/BUILD +++ b/pkg/cloudprovider/providers/vsphere/BUILD @@ -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", ], ) diff --git a/pkg/cloudprovider/providers/vsphere/vsphere.go b/pkg/cloudprovider/providers/vsphere/vsphere.go index 6222cb0559f..441c46ec718 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere.go @@ -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" diff --git a/pkg/cloudprovider/providers/vsphere/vsphere_test.go b/pkg/cloudprovider/providers/vsphere/vsphere_test.go index 1b0becca6e3..fc659e2d0e6 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere_test.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere_test.go @@ -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" diff --git a/vendor/github.com/vmware/govmomi/BUILD b/vendor/github.com/vmware/govmomi/BUILD index 8a4e487f0a7..f09517ddbaa 100644 --- a/vendor/github.com/vmware/govmomi/BUILD +++ b/vendor/github.com/vmware/govmomi/BUILD @@ -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", ], diff --git a/vendor/github.com/vmware/govmomi/README.md b/vendor/github.com/vmware/govmomi/README.md index 08bc8df8089..5cd8c5adf66 100644 --- a/vendor/github.com/vmware/govmomi/README.md +++ b/vendor/github.com/vmware/govmomi/README.md @@ -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). diff --git a/vendor/github.com/vmware/govmomi/simulator/session_manager.go b/vendor/github.com/vmware/govmomi/simulator/session_manager.go index 7039b7efc80..743b14dd3f7 100644 --- a/vendor/github.com/vmware/govmomi/simulator/session_manager.go +++ b/vendor/github.com/vmware/govmomi/simulator/session_manager.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/vapi/internal/BUILD b/vendor/github.com/vmware/govmomi/vapi/internal/BUILD new file mode 100644 index 00000000000..7d3bb346e13 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vapi/internal/BUILD @@ -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"], +) diff --git a/vendor/github.com/vmware/govmomi/vapi/internal/internal.go b/vendor/github.com/vmware/govmomi/vapi/internal/internal.go new file mode 100644 index 00000000000..d9e38c224af --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vapi/internal/internal.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/vapi/rest/BUILD b/vendor/github.com/vmware/govmomi/vapi/rest/BUILD new file mode 100644 index 00000000000..2004583df0a --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vapi/rest/BUILD @@ -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"], +) diff --git a/vendor/github.com/vmware/govmomi/vapi/rest/client.go b/vendor/github.com/vmware/govmomi/vapi/rest/client.go new file mode 100644 index 00000000000..fca579884a0 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vapi/rest/client.go @@ -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) +} diff --git a/vendor/github.com/vmware/govmomi/vapi/simulator/BUILD b/vendor/github.com/vmware/govmomi/vapi/simulator/BUILD new file mode 100644 index 00000000000..f98c9186009 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vapi/simulator/BUILD @@ -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"], +) diff --git a/vendor/github.com/vmware/govmomi/vapi/simulator/simulator.go b/vendor/github.com/vmware/govmomi/vapi/simulator/simulator.go new file mode 100644 index 00000000000..768b0d52f57 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vapi/simulator/simulator.go @@ -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) + } +} diff --git a/vendor/github.com/vmware/govmomi/vapi/tags/BUILD b/vendor/github.com/vmware/govmomi/vapi/tags/BUILD index 6e0bd91114a..d3c2d33bb09 100644 --- a/vendor/github.com/vmware/govmomi/vapi/tags/BUILD +++ b/vendor/github.com/vmware/govmomi/vapi/tags/BUILD @@ -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", ], ) diff --git a/vendor/github.com/vmware/govmomi/vapi/tags/categories.go b/vendor/github.com/vmware/govmomi/vapi/tags/categories.go index ab23b1b8b98..119b9650621 100644 --- a/vendor/github.com/vmware/govmomi/vapi/tags/categories.go +++ b/vendor/github.com/vmware/govmomi/vapi/tags/categories.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/vapi/tags/rest_client.go b/vendor/github.com/vmware/govmomi/vapi/tags/rest_client.go deleted file mode 100644 index 6c70ae69cb9..00000000000 --- a/vendor/github.com/vmware/govmomi/vapi/tags/rest_client.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/vmware/govmomi/vapi/tags/tag_association.go b/vendor/github.com/vmware/govmomi/vapi/tags/tag_association.go index 3751ee4fe93..609d214f71f 100755 --- a/vendor/github.com/vmware/govmomi/vapi/tags/tag_association.go +++ b/vendor/github.com/vmware/govmomi/vapi/tags/tag_association.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/vapi/tags/tags.go b/vendor/github.com/vmware/govmomi/vapi/tags/tags.go index 8a4e8d6d4f7..b0c4ec69f09 100644 --- a/vendor/github.com/vmware/govmomi/vapi/tags/tags.go +++ b/vendor/github.com/vmware/govmomi/vapi/tags/tags.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/client.go b/vendor/github.com/vmware/govmomi/vim25/soap/client.go index 7553a83d85b..a51f61189a1 100644 --- a/vendor/github.com/vmware/govmomi/vim25/soap/client.go +++ b/vendor/github.com/vmware/govmomi/vim25/soap/client.go @@ -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() { diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/debug.go b/vendor/github.com/vmware/govmomi/vim25/soap/debug.go index 63518abca3a..844581b99ce 100644 --- a/vendor/github.com/vmware/govmomi/vim25/soap/debug.go +++ b/vendor/github.com/vmware/govmomi/vim25/soap/debug.go @@ -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