Merge pull request #55918 from dougm/vcp-vcsim

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Add vSphere Cloud Provider simulator based tests

**What this PR does / why we need it**:

Initial set of vSphere Cloud Provider functional tests against the vCenter simulator, provides test coverage without having to run against a real vCenter instance.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

The vsphere simulator recently moved from vmware/vic to govmomi, I had discussed the idea of introducing it for testing with vSphere Cloud Provider maintainers.  These tests provide 90%+ coverage for vclib/datacenter.go, but we can expand further of course.

**Release note**:

```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue 2018-01-18 17:31:04 -08:00 committed by GitHub
commit c1f2da78ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
126 changed files with 27100 additions and 934 deletions

97
Godeps/Godeps.json generated
View File

@ -1717,6 +1717,11 @@
"ImportPath": "github.com/google/gofuzz",
"Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c"
},
{
"ImportPath": "github.com/google/uuid",
"Comment": "0.2-15-g8c31c18",
"Rev": "8c31c18f31ede9fc8eae72290a7e7a8064e9b3e3"
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
@ -2640,93 +2645,113 @@
},
{
"ImportPath": "github.com/vmware/govmomi",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/find",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/list",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/nfc",
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/object",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/pbm",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/pbm/methods",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/pbm/types",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/property",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/session",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/simulator",
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/simulator/esx",
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/simulator/vpx",
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/task",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/debug",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/methods",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/mo",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/progress",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/soap",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/types",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/xml",
"Comment": "v0.14.0-11-gb8b228c",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1"
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/photon-controller-go-sdk/SSPI",

875
Godeps/LICENSES generated
View File

@ -58179,6 +58179,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
================================================================================
= vendor/github.com/google/uuid licensed under: =
Copyright (c) 2009,2014 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
= vendor/github.com/google/uuid/LICENSE 88073b6dd8ec00fe09da59e0b6dfded1
================================================================================
================================================================================
= vendor/github.com/googleapis/gnostic/compiler licensed under: =
@ -83718,6 +83753,216 @@ SOFTWARE.
================================================================================
================================================================================
= vendor/github.com/vmware/govmomi/nfc 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/object licensed under: =
@ -84978,6 +85223,636 @@ SOFTWARE.
================================================================================
================================================================================
= vendor/github.com/vmware/govmomi/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/simulator/esx 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/simulator/vpx 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/task licensed under: =

View File

@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
@ -55,3 +56,14 @@ filegroup(
],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["datacenter_test.go"],
embed = [":go_default_library"],
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib",
deps = [
"//vendor/github.com/vmware/govmomi:go_default_library",
"//vendor/github.com/vmware/govmomi/simulator:go_default_library",
],
)

View File

@ -0,0 +1,174 @@
/*
Copyright 2016 The Kubernetes Authors.
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 vclib
import (
"context"
"testing"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/simulator"
)
func TestDatacenter(t *testing.T) {
ctx := context.Background()
// vCenter model + initial set of objects (cluster, hosts, VMs, network, datastore, etc)
model := simulator.VPX()
defer model.Remove()
err := model.Create()
if err != nil {
t.Fatal(err)
}
s := model.Service.NewServer()
defer s.Close()
avm := simulator.Map.Any("VirtualMachine").(*simulator.VirtualMachine)
c, err := govmomi.NewClient(ctx, s.URL, true)
if err != nil {
t.Fatal(err)
}
vc := &VSphereConnection{GoVmomiClient: c}
_, err = GetDatacenter(ctx, vc, "enoent")
if err == nil {
t.Error("expected error")
}
dc, err := GetDatacenter(ctx, vc, "DC0")
if err != nil {
t.Error(err)
}
_, err = dc.GetVMByUUID(ctx, "enoent")
if err == nil {
t.Error("expected error")
}
_, err = dc.GetVMByUUID(ctx, avm.Summary.Config.Uuid)
if err != nil {
t.Error(err)
}
_, err = dc.GetVMByPath(ctx, "enoent")
if err == nil {
t.Error("expected error")
}
vm, err := dc.GetVMByPath(ctx, "/DC0/vm/"+avm.Name)
if err != nil {
t.Error(err)
}
_, err = dc.GetDatastoreByPath(ctx, "enoent") // invalid format
if err == nil {
t.Error("expected error")
}
_, err = dc.GetDatastoreByPath(ctx, "[enoent] no/no.vmx")
if err == nil {
t.Error("expected error")
}
_, err = dc.GetDatastoreByPath(ctx, avm.Summary.Config.VmPathName)
if err != nil {
t.Error(err)
}
_, err = dc.GetDatastoreByName(ctx, "enoent")
if err == nil {
t.Error("expected error")
}
ds, err := dc.GetDatastoreByName(ctx, "LocalDS_0")
if err != nil {
t.Error(err)
}
_, err = dc.GetFolderByPath(ctx, "enoent")
if err == nil {
t.Error("expected error")
}
_, err = dc.GetFolderByPath(ctx, "/DC0/vm")
if err != nil {
t.Error(err)
}
_, err = dc.GetVMMoList(ctx, nil, nil)
if err == nil {
t.Error("expected error")
}
_, err = dc.GetVMMoList(ctx, []*VirtualMachine{vm}, []string{"enoent"}) // invalid property
if err == nil {
t.Error("expected error")
}
_, err = dc.GetVMMoList(ctx, []*VirtualMachine{vm}, []string{"summary"})
if err != nil {
t.Error(err)
}
vmdk := ds.Path(avm.Name + "/disk1.vmdk")
_, err = dc.GetVirtualDiskPage83Data(ctx, vmdk+"-enoent")
if err == nil {
t.Error("expected error")
}
_, err = dc.GetVirtualDiskPage83Data(ctx, vmdk)
if err != nil {
t.Error(err)
}
_, err = dc.GetDatastoreMoList(ctx, nil, nil)
if err == nil {
t.Error("expected error")
}
_, err = dc.GetDatastoreMoList(ctx, []*Datastore{ds}, []string{"enoent"}) // invalid property
if err == nil {
t.Error("expected error")
}
_, err = dc.GetDatastoreMoList(ctx, []*Datastore{ds}, []string{DatastoreInfoProperty})
if err != nil {
t.Error(err)
}
nodeVolumes := map[string][]string{
avm.Name: {"enoent", vmdk},
}
attached, err := dc.CheckDisksAttached(ctx, nodeVolumes)
if err != nil {
t.Error(err)
}
if attached[avm.Name]["enoent"] {
t.Error("should not be attached")
}
if !attached[avm.Name][vmdk] {
t.Errorf("%s should be attached", vmdk)
}
}

1
vendor/BUILD vendored
View File

@ -245,6 +245,7 @@ filegroup(
"//vendor/github.com/google/cadvisor/zfs:all-srcs",
"//vendor/github.com/google/certificate-transparency/go:all-srcs",
"//vendor/github.com/google/gofuzz:all-srcs",
"//vendor/github.com/google/uuid:all-srcs",
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:all-srcs",
"//vendor/github.com/googleapis/gnostic/compiler:all-srcs",
"//vendor/github.com/googleapis/gnostic/extensions:all-srcs",

9
vendor/github.com/google/uuid/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,9 @@
language: go
go:
- 1.4.3
- 1.5.3
- tip
script:
- go test -v ./...

34
vendor/github.com/google/uuid/BUILD generated vendored Normal file
View File

@ -0,0 +1,34 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"dce.go",
"doc.go",
"hash.go",
"marshal.go",
"node.go",
"sql.go",
"time.go",
"util.go",
"uuid.go",
"version1.go",
"version4.go",
],
importpath = "github.com/google/uuid",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

10
vendor/github.com/google/uuid/CONTRIBUTING.md generated vendored Normal file
View File

@ -0,0 +1,10 @@
# How to contribute
We definitely welcome patches and contribution to this project!
### Legal requirements
In order to protect both you and ourselves, you will need to sign the
[Contributor License Agreement](https://cla.developers.google.com/clas).
You may have already signed it for other Google projects.

9
vendor/github.com/google/uuid/CONTRIBUTORS generated vendored Normal file
View File

@ -0,0 +1,9 @@
Paul Borman <borman@google.com>
bmatsuo
shawnps
theory
jboverfelt
dsymonds
cd1
wallclockbuilder
dansouza

27
vendor/github.com/google/uuid/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009,2014 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

23
vendor/github.com/google/uuid/README.md generated vendored Normal file
View File

@ -0,0 +1,23 @@
**This package is currently in development and the API may not be stable.**
The API will become stable with v1.
# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master)
The uuid package generates and inspects UUIDs based on
[RFC 4122](http://tools.ietf.org/html/rfc4122)
and DCE 1.1: Authentication and Security Services.
This package is based on the github.com/pborman/uuid package (previously named
code.google.com/p/go-uuid). It differs from these earlier packages in that
a UUID is a 16 byte array rather than a byte slice. One loss due to this
change is the ability to represent an invalid UUID (vs a NIL UUID).
###### Install
`go get github.com/google/uuid`
###### Documentation
[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid)
Full `go doc` style documentation for the package can be viewed online without
installing this package by using the GoDoc site here:
http://godoc.org/github.com/google/uuid

80
vendor/github.com/google/uuid/dce.go generated vendored Normal file
View File

@ -0,0 +1,80 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
"fmt"
"os"
)
// A Domain represents a Version 2 domain
type Domain byte
// Domain constants for DCE Security (Version 2) UUIDs.
const (
Person = Domain(0)
Group = Domain(1)
Org = Domain(2)
)
// NewDCESecurity returns a DCE Security (Version 2) UUID.
//
// The domain should be one of Person, Group or Org.
// On a POSIX system the id should be the users UID for the Person
// domain and the users GID for the Group. The meaning of id for
// the domain Org or on non-POSIX systems is site defined.
//
// For a given domain/id pair the same token may be returned for up to
// 7 minutes and 10 seconds.
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
uuid, err := NewUUID()
if err == nil {
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
uuid[9] = byte(domain)
binary.BigEndian.PutUint32(uuid[0:], id)
}
return uuid, err
}
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
// domain with the id returned by os.Getuid.
//
// NewDCESecurity(Person, uint32(os.Getuid()))
func NewDCEPerson() (UUID, error) {
return NewDCESecurity(Person, uint32(os.Getuid()))
}
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
// domain with the id returned by os.Getgid.
//
// NewDCESecurity(Group, uint32(os.Getgid()))
func NewDCEGroup() (UUID, error) {
return NewDCESecurity(Group, uint32(os.Getgid()))
}
// Domain returns the domain for a Version 2 UUID. Domains are only defined
// for Version 2 UUIDs.
func (uuid UUID) Domain() Domain {
return Domain(uuid[9])
}
// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
// UUIDs.
func (uuid UUID) ID() uint32 {
return binary.BigEndian.Uint32(uuid[0:4])
}
func (d Domain) String() string {
switch d {
case Person:
return "Person"
case Group:
return "Group"
case Org:
return "Org"
}
return fmt.Sprintf("Domain%d", int(d))
}

12
vendor/github.com/google/uuid/doc.go generated vendored Normal file
View File

@ -0,0 +1,12 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package uuid generates and inspects UUIDs.
//
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security
// Services.
//
// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to
// maps or compared directly.
package uuid

53
vendor/github.com/google/uuid/hash.go generated vendored Normal file
View File

@ -0,0 +1,53 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"crypto/md5"
"crypto/sha1"
"hash"
)
// Well known namespace IDs and UUIDs
var (
NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
Nil UUID // empty UUID, all zeros
)
// NewHash returns a new UUID derived from the hash of space concatenated with
// data generated by h. The hash should be at least 16 byte in length. The
// first 16 bytes of the hash are used to form the UUID. The version of the
// UUID will be the lower 4 bits of version. NewHash is used to implement
// NewMD5 and NewSHA1.
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
h.Reset()
h.Write(space[:])
h.Write([]byte(data))
s := h.Sum(nil)
var uuid UUID
copy(uuid[:], s)
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
return uuid
}
// NewMD5 returns a new MD5 (Version 3) UUID based on the
// supplied name space and data. It is the same as calling:
//
// NewHash(md5.New(), space, data, 3)
func NewMD5(space UUID, data []byte) UUID {
return NewHash(md5.New(), space, data, 3)
}
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
// supplied name space and data. It is the same as calling:
//
// NewHash(sha1.New(), space, data, 5)
func NewSHA1(space UUID, data []byte) UUID {
return NewHash(sha1.New(), space, data, 5)
}

39
vendor/github.com/google/uuid/marshal.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import "fmt"
// MarshalText implements encoding.TextMarshaler.
func (uuid UUID) MarshalText() ([]byte, error) {
var js [36]byte
encodeHex(js[:], uuid)
return js[:], nil
}
// UnmarshalText implements encoding.TextUnmarshaler.
func (uuid *UUID) UnmarshalText(data []byte) error {
// See comment in ParseBytes why we do this.
// id, err := ParseBytes(data)
id, err := ParseBytes(data)
if err == nil {
*uuid = id
}
return err
}
// MarshalBinary implements encoding.BinaryMarshaler.
func (uuid UUID) MarshalBinary() ([]byte, error) {
return uuid[:], nil
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (uuid *UUID) UnmarshalBinary(data []byte) error {
if len(data) != 16 {
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
}
copy(uuid[:], data)
return nil
}

100
vendor/github.com/google/uuid/node.go generated vendored Normal file
View File

@ -0,0 +1,100 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"net"
"sync"
)
var (
nodeMu sync.Mutex
interfaces []net.Interface // cached list of interfaces
ifname string // name of interface being used
nodeID [6]byte // hardware for version 1 UUIDs
zeroID [6]byte // nodeID with only 0's
)
// NodeInterface returns the name of the interface from which the NodeID was
// derived. The interface "user" is returned if the NodeID was set by
// SetNodeID.
func NodeInterface() string {
defer nodeMu.Unlock()
nodeMu.Lock()
return ifname
}
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
// If name is "" then the first usable interface found will be used or a random
// Node ID will be generated. If a named interface cannot be found then false
// is returned.
//
// SetNodeInterface never fails when name is "".
func SetNodeInterface(name string) bool {
defer nodeMu.Unlock()
nodeMu.Lock()
return setNodeInterface(name)
}
func setNodeInterface(name string) bool {
if interfaces == nil {
var err error
interfaces, err = net.Interfaces()
if err != nil && name != "" {
return false
}
}
for _, ifs := range interfaces {
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
copy(nodeID[:], ifs.HardwareAddr)
ifname = ifs.Name
return true
}
}
// We found no interfaces with a valid hardware address. If name
// does not specify a specific interface generate a random Node ID
// (section 4.1.6)
if name == "" {
randomBits(nodeID[:])
return true
}
return false
}
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
// if not already set.
func NodeID() []byte {
defer nodeMu.Unlock()
nodeMu.Lock()
if nodeID == zeroID {
setNodeInterface("")
}
nid := nodeID
return nid[:]
}
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
// of id are used. If id is less than 6 bytes then false is returned and the
// Node ID is not set.
func SetNodeID(id []byte) bool {
if len(id) < 6 {
return false
}
defer nodeMu.Unlock()
nodeMu.Lock()
copy(nodeID[:], id)
ifname = "user"
return true
}
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
func (uuid UUID) NodeID() []byte {
var node [6]byte
copy(node[:], uuid[10:])
return node[:]
}

59
vendor/github.com/google/uuid/sql.go generated vendored Normal file
View File

@ -0,0 +1,59 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"database/sql/driver"
"fmt"
)
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
// Currently, database types that map to string and []byte are supported. Please
// consult database-specific driver documentation for matching types.
func (uuid *UUID) Scan(src interface{}) error {
switch src := src.(type) {
case nil:
return nil
case string:
// if an empty UUID comes from a table, we return a null UUID
if src == "" {
return nil
}
// see Parse for required string format
u, err := Parse(src)
if err != nil {
return fmt.Errorf("Scan: %v", err)
}
*uuid = u
case []byte:
// if an empty UUID comes from a table, we return a null UUID
if len(src) == 0 {
return nil
}
// assumes a simple slice of bytes if 16 bytes
// otherwise attempts to parse
if len(src) != 16 {
return uuid.Scan(string(src))
}
copy((*uuid)[:], src)
default:
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
}
return nil
}
// Value implements sql.Valuer so that UUIDs can be written to databases
// transparently. Currently, UUIDs map to strings. Please consult
// database-specific driver documentation for matching types.
func (uuid UUID) Value() (driver.Value, error) {
return uuid.String(), nil
}

123
vendor/github.com/google/uuid/time.go generated vendored Normal file
View File

@ -0,0 +1,123 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
"sync"
"time"
)
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
// 1582.
type Time int64
const (
lillian = 2299160 // Julian day of 15 Oct 1582
unix = 2440587 // Julian day of 1 Jan 1970
epoch = unix - lillian // Days between epochs
g1582 = epoch * 86400 // seconds between epochs
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
)
var (
timeMu sync.Mutex
lasttime uint64 // last time we returned
clockSeq uint16 // clock sequence for this run
timeNow = time.Now // for testing
)
// UnixTime converts t the number of seconds and nanoseconds using the Unix
// epoch of 1 Jan 1970.
func (t Time) UnixTime() (sec, nsec int64) {
sec = int64(t - g1582ns100)
nsec = (sec % 10000000) * 100
sec /= 10000000
return sec, nsec
}
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
// clock sequence as well as adjusting the clock sequence as needed. An error
// is returned if the current time cannot be determined.
func GetTime() (Time, uint16, error) {
defer timeMu.Unlock()
timeMu.Lock()
return getTime()
}
func getTime() (Time, uint16, error) {
t := timeNow()
// If we don't have a clock sequence already, set one.
if clockSeq == 0 {
setClockSequence(-1)
}
now := uint64(t.UnixNano()/100) + g1582ns100
// If time has gone backwards with this clock sequence then we
// increment the clock sequence
if now <= lasttime {
clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000
}
lasttime = now
return Time(now), clockSeq, nil
}
// ClockSequence returns the current clock sequence, generating one if not
// already set. The clock sequence is only used for Version 1 UUIDs.
//
// The uuid package does not use global static storage for the clock sequence or
// the last time a UUID was generated. Unless SetClockSequence is used, a new
// random clock sequence is generated the first time a clock sequence is
// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1)
func ClockSequence() int {
defer timeMu.Unlock()
timeMu.Lock()
return clockSequence()
}
func clockSequence() int {
if clockSeq == 0 {
setClockSequence(-1)
}
return int(clockSeq & 0x3fff)
}
// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
// -1 causes a new sequence to be generated.
func SetClockSequence(seq int) {
defer timeMu.Unlock()
timeMu.Lock()
setClockSequence(seq)
}
func setClockSequence(seq int) {
if seq == -1 {
var b [2]byte
randomBits(b[:]) // clock sequence
seq = int(b[0])<<8 | int(b[1])
}
old_seq := clockSeq
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
if old_seq != clockSeq {
lasttime = 0
}
}
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
// uuid. The time is only defined for version 1 and 2 UUIDs.
func (uuid UUID) Time() Time {
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
return Time(time)
}
// ClockSequence returns the clock sequence encoded in uuid.
// The clock sequence is only well defined for version 1 and 2 UUIDs.
func (uuid UUID) ClockSequence() int {
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff
}

43
vendor/github.com/google/uuid/util.go generated vendored Normal file
View File

@ -0,0 +1,43 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"io"
)
// randomBits completely fills slice b with random data.
func randomBits(b []byte) {
if _, err := io.ReadFull(rander, b); err != nil {
panic(err.Error()) // rand should never fail
}
}
// xvalues returns the value of a byte as a hexadecimal digit or 255.
var xvalues = [256]byte{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
}
// xtob converts hex characters x1 and x2 into a byte.
func xtob(x1, x2 byte) (byte, bool) {
b1 := xvalues[x1]
b2 := xvalues[x2]
return (b1 << 4) | b2, b1 != 255 && b2 != 255
}

198
vendor/github.com/google/uuid/uuid.go generated vendored Normal file
View File

@ -0,0 +1,198 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"bytes"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"strings"
)
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
// 4122.
type UUID [16]byte
// A Version represents a UUID's version.
type Version byte
// A Variant represents a UUID's variant.
type Variant byte
// Constants returned by Variant.
const (
Invalid = Variant(iota) // Invalid UUID
RFC4122 // The variant specified in RFC4122
Reserved // Reserved, NCS backward compatibility.
Microsoft // Reserved, Microsoft Corporation backward compatibility.
Future // Reserved for future definition.
)
var rander = rand.Reader // random function
// Parse decodes s into a UUID or returns an error. Both the UUID form of
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded.
func Parse(s string) (UUID, error) {
var uuid UUID
if len(s) != 36 {
if len(s) != 36+9 {
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
}
if strings.ToLower(s[:9]) != "urn:uuid:" {
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
}
s = s[9:]
}
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
return uuid, errors.New("invalid UUID format")
}
for i, x := range [16]int{
0, 2, 4, 6,
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34} {
if v, ok := xtob(s[x], s[x+1]); !ok {
return uuid, errors.New("invalid UUID format")
} else {
uuid[i] = v
}
}
return uuid, nil
}
// ParseBytes is like Parse, except it parses a byte slice instead of a string.
func ParseBytes(b []byte) (UUID, error) {
var uuid UUID
if len(b) != 36 {
if len(b) != 36+9 {
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
}
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
}
b = b[9:]
}
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
return uuid, errors.New("invalid UUID format")
}
for i, x := range [16]int{
0, 2, 4, 6,
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34} {
if v, ok := xtob(b[x], b[x+1]); !ok {
return uuid, errors.New("invalid UUID format")
} else {
uuid[i] = v
}
}
return uuid, nil
}
// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
// does not have a length of 16. The bytes are copied from the slice.
func FromBytes(b []byte) (uuid UUID, err error) {
err = uuid.UnmarshalBinary(b)
return uuid, err
}
// Must returns uuid if err is nil and panics otherwise.
func Must(uuid UUID, err error) UUID {
if err != nil {
panic(err)
}
return uuid
}
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
// , or "" if uuid is invalid.
func (uuid UUID) String() string {
var buf [36]byte
encodeHex(buf[:], uuid)
return string(buf[:])
}
// URN returns the RFC 2141 URN form of uuid,
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
func (uuid UUID) URN() string {
var buf [36 + 9]byte
copy(buf[:], "urn:uuid:")
encodeHex(buf[9:], uuid)
return string(buf[:])
}
func encodeHex(dst []byte, uuid UUID) {
hex.Encode(dst[:], uuid[:4])
dst[8] = '-'
hex.Encode(dst[9:13], uuid[4:6])
dst[13] = '-'
hex.Encode(dst[14:18], uuid[6:8])
dst[18] = '-'
hex.Encode(dst[19:23], uuid[8:10])
dst[23] = '-'
hex.Encode(dst[24:], uuid[10:])
}
// Variant returns the variant encoded in uuid.
func (uuid UUID) Variant() Variant {
switch {
case (uuid[8] & 0xc0) == 0x80:
return RFC4122
case (uuid[8] & 0xe0) == 0xc0:
return Microsoft
case (uuid[8] & 0xe0) == 0xe0:
return Future
default:
return Reserved
}
}
// Version returns the version of uuid.
func (uuid UUID) Version() Version {
return Version(uuid[6] >> 4)
}
func (v Version) String() string {
if v > 15 {
return fmt.Sprintf("BAD_VERSION_%d", v)
}
return fmt.Sprintf("VERSION_%d", v)
}
func (v Variant) String() string {
switch v {
case RFC4122:
return "RFC4122"
case Reserved:
return "Reserved"
case Microsoft:
return "Microsoft"
case Future:
return "Future"
case Invalid:
return "Invalid"
}
return fmt.Sprintf("BadVariant%d", int(v))
}
// SetRand sets the random number generator to r, which implements io.Reader.
// If r.Read returns an error when the package requests random data then
// a panic will be issued.
//
// Calling SetRand with nil sets the random number generator to the default
// generator.
func SetRand(r io.Reader) {
if r == nil {
rander = rand.Reader
return
}
rander = r
}

44
vendor/github.com/google/uuid/version1.go generated vendored Normal file
View File

@ -0,0 +1,44 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
)
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
// sequence, and the current time. If the NodeID has not been set by SetNodeID
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
// be set NewUUID returns nil. If clock sequence has not been set by
// SetClockSequence then it will be set automatically. If GetTime fails to
// return the current NewUUID returns nil and an error.
//
// In most cases, New should be used.
func NewUUID() (UUID, error) {
nodeMu.Lock()
if nodeID == zeroID {
setNodeInterface("")
}
nodeMu.Unlock()
var uuid UUID
now, seq, err := GetTime()
if err != nil {
return uuid, err
}
timeLow := uint32(now & 0xffffffff)
timeMid := uint16((now >> 32) & 0xffff)
timeHi := uint16((now >> 48) & 0x0fff)
timeHi |= 0x1000 // Version 1
binary.BigEndian.PutUint32(uuid[0:], timeLow)
binary.BigEndian.PutUint16(uuid[4:], timeMid)
binary.BigEndian.PutUint16(uuid[6:], timeHi)
binary.BigEndian.PutUint16(uuid[8:], seq)
copy(uuid[10:], nodeID[:])
return uuid, nil
}

38
vendor/github.com/google/uuid/version4.go generated vendored Normal file
View File

@ -0,0 +1,38 @@
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import "io"
// New creates a new random UUID or panics. New is equivalent to
// the expression
//
// uuid.Must(uuid.NewRandom())
func New() UUID {
return Must(NewRandom())
}
// NewRandom returns a Random (Version 4) UUID or panics.
//
// The strength of the UUIDs is based on the strength of the crypto/rand
// package.
//
// A note about uniqueness derived from the UUID Wikipedia entry:
//
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
// hit by a meteorite is estimated to be one chance in 17 billion, that
// means the probability is about 0.00000000006 (6 × 1011),
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
// year and having one duplicate.
func NewRandom() (UUID, error) {
var uuid UUID
_, err := io.ReadFull(rander, uuid[:])
if err != nil {
return Nil, err
}
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
return uuid, nil
}

View File

@ -1 +0,0 @@
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.kK6pryC8R-O1R0Gj9ydLvQuIZlcYLGze23WdW7xbpiEEKdz6nweJrMm7ysy8lgu1tM47JVo19p2_b26bNKSQshCUOETvd7Hb2UMZOjnyUnqdyAAyoi6UkIquXfUUbHTNS0iMxwSxxW9KMp2GXNq8-o6T8xQZTDirBJFKKd8ZNUasTaoa5j8U9IfdR1aCavTBuOhvk8IVs-jSbY5TVJMJiE0IOPXois7aRJ6uAiANQBk9VKLegEcZD_qAewecXHDsHi-u0jbmg3o3PPaJaK_Qv5dsPlR2M-E2kE3AGUn0-zn5zYRngoAZ8WZr2O4GvLdltJKq9i2z7jOrdOzzRcDRow.96qvwl_E1Hj15u7Q.hWs-jQ8FsqQFD7pE9N-UEP1BWQ9rsJIcCaPvQRIp8Fukm_vvlw9YEaEq0ERLrsUWsJWpd1ca8_h8x7xD6f_d5YppwRqRHIeGIsdBOTMhNs0lG8ikkQXLat-UroCpy8EC17nuUtDE2E2Kdxrk4Cdd6Bk-dKk0Ta4w3Ud0YBKa.P8zrO7xizgv0i98eVWWzEg

View File

@ -1,17 +0,0 @@
clone:
tags: true
path: github.com/vmware/govmomi
build:
image: golang:1.7
pull: true
environment:
- GOVC_TEST_URL=$$GOVC_TEST_URL
- GOVC_INSECURE=1
- VCA=1
commands:
- make all install
- git clone https://github.com/sstephenson/bats.git /tmp/bats
- /tmp/bats/install.sh /usr/local
- apt-get -qq update && apt-get install -yqq uuid-runtime bsdmainutils jq
- govc/test/images/update.sh
- bats govc/test

View File

@ -13,4 +13,7 @@ Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
Takaaki Furukawa <takaaki.frkw@gmail.com> takaaki.furukawa <takaaki.furukawa@mail.rakuten.com>
Takaaki Furukawa <takaaki.frkw@gmail.com> tkak <takaaki.frkw@gmail.com>
Vadim Egorov <vegorov@vmware.com> <egorovv@gmail.com>
Anfernee Yongkun Gui <agui@vmware.com> <anfernee.gui@gmail.com>
Anfernee Yongkun Gui <agui@vmware.com> Yongkun Anfernee Gui <agui@vmware.com>
Zach Tucker <ztucker@vmware.com> <jzt@users.noreply.github.com>
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>

View File

@ -3,7 +3,7 @@ sudo: false
language: go
go:
- 1.7
- 1.8
before_install:
- make vendor

View File

@ -27,10 +27,12 @@ filegroup(
":package-srcs",
"//vendor/github.com/vmware/govmomi/find:all-srcs",
"//vendor/github.com/vmware/govmomi/list:all-srcs",
"//vendor/github.com/vmware/govmomi/nfc:all-srcs",
"//vendor/github.com/vmware/govmomi/object:all-srcs",
"//vendor/github.com/vmware/govmomi/pbm:all-srcs",
"//vendor/github.com/vmware/govmomi/property:all-srcs",
"//vendor/github.com/vmware/govmomi/session:all-srcs",
"//vendor/github.com/vmware/govmomi/simulator:all-srcs",
"//vendor/github.com/vmware/govmomi/task:all-srcs",
"//vendor/github.com/vmware/govmomi/vim25:all-srcs",
],

View File

@ -1,5 +1,36 @@
# changelog
### 0.16.0 (2017-11-08)
* Add support for SOAP request operation ID header
* Moved ovf helpers from govc import.ovf command to ovf and nfc packages
* Added guest/toolbox (client) package
* Added toolbox package and toolbox command
* Added simulator package and vcsim command
### 0.15.0 (2017-06-19)
* WaitOptions.MaxWaitSeconds is now optional
* Support removal of ExtraConfig entries
* GuestPosixFileAttributes OwnerId and GroupId fields are now pointers,
rather than omitempty ints to allow chown with root uid:gid
* Updated examples/ using view package
* Add DatastoreFile.TailFunc method
* Export VirtualMachine.FindSnapshot method
* Add AuthorizationManager {Enable,Disable}Methods
* Add PBM client
### 0.14.0 (2017-04-08)
* Add view.ContainerView type and methods

View File

@ -17,6 +17,16 @@ git remote add $USER git@github.com:$USER/govmomi.git
git fetch $USER
```
## Installing from source
Compile the govmomi libraries and install govc using:
``` shell
go install -v github.com/vmware/govmomi/govc
```
Note that **govc/build.sh** is only used for building release binaries.
## Contribution flow
This is a rough outline of what a contributor's workflow looks like:

View File

@ -3,12 +3,20 @@
# This script is generated by contributors.sh
#
Abhijeet Kasurde <akasurde@redhat.com>
abrarshivani <abrarshivani@users.noreply.github.com>
Adam Shannon <adamkshannon@gmail.com>
Alvaro Miranda <kikitux@gmail.com>
amandahla <amanda.andrade@serpro.gov.br>
Amit Bathla <abathla@.vmware.com>
amit bezalel <amit.bezalel@hpe.com>
Andrew Chin <andrew@andrewtchin.com>
Anfernee Yongkun Gui <agui@vmware.com>
aniketGslab <aniket.shinde@gslab.com>
Arran Walker <arran.walker@zopa.com>
Aryeh Weinreb <aryehweinreb@gmail.com>
Austin Parker <aparker@apprenda.com>
Balu Dontu <bdontu@vmware.com>
bastienbc <bastien.barbe.creuly@gmail.com>
Bob Killen <killen.bob@gmail.com>
Brad Fitzpatrick <bradfitz@golang.org>
@ -35,8 +43,10 @@ gthombare <gthombare@vmware.com>
Hasan Mahmood <mahmoodh@vmware.com>
Henrik Hodne <henrik@travis-ci.com>
Isaac Rodman <isaac@eyz.us>
Ivan Porto Carrero <icarrero@vmware.com>
Jason Kincl <jkincl@gmail.com>
Jeremy Canady <jcanady@jackhenry.com>
João Pereira <joaodrp@gmail.com>
Louie Jiang <jiangl@vmware.com>
Marc Carmier <mcarmier@gmail.com>
Mevan Samaratunga <mevansam@gmail.com>
@ -47,7 +57,9 @@ S.Çağlar Onur <conur@vmware.com>
Sergey Ignatov <sergey.ignatov@jetbrains.com>
Steve Purcell <steve@sanityinc.com>
Takaaki Furukawa <takaaki.frkw@gmail.com>
tanishi <tanishi503@gmail.com>
Ted Zlatanov <tzz@lifelogs.com>
Thibaut Ackermann <thibaut.ackermann@alcatel-lucent.com>
Vadim Egorov <vegorov@vmware.com>
Yang Yang <yangy@vmware.com>
Yuya Kusakabe <yuya.kusakabe@gmail.com>

View File

@ -11,13 +11,19 @@ goimports:
govet:
@echo checking go vet...
@go tool vet -structtags=false -methods=false .
test:
go test -v $(TEST_OPTS) ./...
@go tool vet -structtags=false -methods=false $$(find . -mindepth 1 -maxdepth 1 -type d -not -name vendor)
install:
go install github.com/vmware/govmomi/govc
go install -v github.com/vmware/govmomi/govc
go install -v github.com/vmware/govmomi/vcsim
go-test:
go test -v $(TEST_OPTS) ./...
govc-test: install
(cd govc/test && ./vendor/github.com/sstephenson/bats/libexec/bats -t .)
test: go-test govc-test
doc: install
./govc/usage.sh > ./govc/USAGE.md

View File

@ -5,14 +5,19 @@
A Go library for interacting with VMware vSphere APIs (ESXi and/or vCenter).
For `govc`, a CLI built on top of govmomi, check out the [govc](./govc) directory and [USAGE](./govc/USAGE.md) document.
In addition to the vSphere API client, this repository includes:
* [govc](./govc) - vSphere CLI
* [vcsim](./vcsim) - vSphere API mock framework
* [toolbox](./toolbox) - VM guest tools framework
## Compatibility
This library is built for and tested against ESXi and vCenter 5.5, 6.0 and 6.5.
This library is built for and tested against ESXi and vCenter 6.0 and 6.5.
If you're able to use it against older versions of ESXi and/or vCenter, please
leave a note and we'll include it in this compatibility list.
It should work with versions 5.5 and 5.1, but neither are officially supported.
## Documentation
@ -23,19 +28,14 @@ The code in the `govmomi` package is a wrapper for the code that is generated fr
It primarily provides convenience functions for working with the vSphere API.
See [godoc.org][godoc] for documentation.
[apiref]:http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
[apiref]:http://pubs.vmware.com/vsphere-6-5/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
[godoc]:http://godoc.org/github.com/vmware/govmomi
[drone]:https://drone.io
[dronesrc]:https://github.com/drone/drone
[dronecli]:http://readme.drone.io/devs/cli/
#### Building with CI
Merges to this repository will trigger builds in both Travis and [Drone][drone].
## Installation
To build locally with Drone:
- Ensure that you have Docker 1.6 or higher installed.
- Install the [Drone command line tools][dronecli].
- Run `drone exec` from within the root directory of the govmomi repository.
```sh
go get -u github.com/vmware/govmomi
```
## Discussion
@ -53,9 +53,17 @@ Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes.
* [Docker Machine](https://github.com/docker/machine/tree/master/drivers/vmwarevsphere)
* [Docker InfraKit](https://github.com/docker/infrakit/tree/master/pkg/provider/vsphere)
* [Docker LinuxKit](https://github.com/linuxkit/linuxkit/tree/master/src/cmd/linuxkit)
* [Kubernetes](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/vsphere)
* [Terraform](https://github.com/hashicorp/terraform/tree/master/builtin/providers/vsphere)
* [Kubernetes kops](https://github.com/kubernetes/kops/tree/master/upup/pkg/fi/cloudup/vsphere)
* [Terraform](https://github.com/terraform-providers/terraform-provider-vsphere)
* [Packer](https://github.com/jetbrains-infra/packer-builder-vsphere)
* [VMware VIC Engine](https://github.com/vmware/vic)

View File

@ -20,6 +20,7 @@ import (
"context"
"os"
"path"
"strings"
"github.com/vmware/govmomi/list"
"github.com/vmware/govmomi/object"
@ -177,6 +178,7 @@ func (r recurser) List(ctx context.Context, s *spec, root list.Element, parts []
return in, nil
}
all := parts
pattern := parts[0]
parts = parts[1:]
@ -188,6 +190,12 @@ func (r recurser) List(ctx context.Context, s *spec, root list.Element, parts []
}
if !matched {
matched = strings.HasSuffix(e.Path, "/"+path.Join(all...))
if matched {
// name contains a '/'
out = append(out, e)
}
continue
}

34
vendor/github.com/vmware/govmomi/nfc/BUILD generated vendored Normal file
View File

@ -0,0 +1,34 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"lease.go",
"lease_updater.go",
],
importpath = "github.com/vmware/govmomi/nfc",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/vmware/govmomi/property:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/methods:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/mo:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/progress:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/soap: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"],
)

238
vendor/github.com/vmware/govmomi/nfc/lease.go generated vendored Normal file
View File

@ -0,0 +1,238 @@
/*
Copyright (c) 2015-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 nfc
import (
"context"
"errors"
"fmt"
"io"
"path"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type Lease struct {
types.ManagedObjectReference
c *vim25.Client
}
func NewLease(c *vim25.Client, ref types.ManagedObjectReference) *Lease {
return &Lease{ref, c}
}
// Abort wraps methods.Abort
func (l *Lease) Abort(ctx context.Context, fault *types.LocalizedMethodFault) error {
req := types.HttpNfcLeaseAbort{
This: l.Reference(),
Fault: fault,
}
_, err := methods.HttpNfcLeaseAbort(ctx, l.c, &req)
if err != nil {
return err
}
return nil
}
// Complete wraps methods.Complete
func (l *Lease) Complete(ctx context.Context) error {
req := types.HttpNfcLeaseComplete{
This: l.Reference(),
}
_, err := methods.HttpNfcLeaseComplete(ctx, l.c, &req)
if err != nil {
return err
}
return nil
}
// GetManifest wraps methods.GetManifest
func (l *Lease) GetManifest(ctx context.Context) error {
req := types.HttpNfcLeaseGetManifest{
This: l.Reference(),
}
_, err := methods.HttpNfcLeaseGetManifest(ctx, l.c, &req)
if err != nil {
return err
}
return nil
}
// Progress wraps methods.Progress
func (l *Lease) Progress(ctx context.Context, percent int32) error {
req := types.HttpNfcLeaseProgress{
This: l.Reference(),
Percent: percent,
}
_, err := methods.HttpNfcLeaseProgress(ctx, l.c, &req)
if err != nil {
return err
}
return nil
}
type LeaseInfo struct {
types.HttpNfcLeaseInfo
Items []FileItem
}
func (l *Lease) newLeaseInfo(li *types.HttpNfcLeaseInfo, items []types.OvfFileItem) (*LeaseInfo, error) {
info := &LeaseInfo{
HttpNfcLeaseInfo: *li,
}
for _, device := range li.DeviceUrl {
u, err := l.c.ParseURL(device.Url)
if err != nil {
return nil, err
}
if device.SslThumbprint != "" {
// TODO: prefer host management IP
l.c.SetThumbprint(u.Host, device.SslThumbprint)
}
if len(items) == 0 {
// this is an export
item := types.OvfFileItem{
DeviceId: device.Key,
Path: device.TargetId,
Size: device.FileSize,
}
if item.Size == 0 {
item.Size = li.TotalDiskCapacityInKB * 1024
}
if item.Path == "" {
item.Path = path.Base(device.Url)
}
info.Items = append(info.Items, NewFileItem(u, item))
continue
}
// this is an import
for _, item := range items {
if device.ImportKey == item.DeviceId {
info.Items = append(info.Items, NewFileItem(u, item))
break
}
}
}
return info, nil
}
func (l *Lease) Wait(ctx context.Context, items []types.OvfFileItem) (*LeaseInfo, error) {
var lease mo.HttpNfcLease
pc := property.DefaultCollector(l.c)
err := property.Wait(ctx, pc, l.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool {
done := false
for _, c := range pc {
if c.Val == nil {
continue
}
switch c.Name {
case "error":
val := c.Val.(types.LocalizedMethodFault)
lease.Error = &val
done = true
case "info":
val := c.Val.(types.HttpNfcLeaseInfo)
lease.Info = &val
case "state":
lease.State = c.Val.(types.HttpNfcLeaseState)
if lease.State != types.HttpNfcLeaseStateInitializing {
done = true
}
}
}
return done
})
if err != nil {
return nil, err
}
if lease.State == types.HttpNfcLeaseStateReady {
return l.newLeaseInfo(lease.Info, items)
}
if lease.Error != nil {
return nil, errors.New(lease.Error.LocalizedMessage)
}
return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State)
}
func (l *Lease) StartUpdater(ctx context.Context, info *LeaseInfo) *LeaseUpdater {
return newLeaseUpdater(ctx, l, info)
}
func (l *Lease) Upload(ctx context.Context, item FileItem, f io.Reader, opts soap.Upload) error {
if opts.Progress == nil {
opts.Progress = item
} else {
opts.Progress = progress.Tee(item, opts.Progress)
}
// Non-disk files (such as .iso) use the PUT method.
// Overwrite: t header is also required in this case (ovftool does the same)
if item.Create {
opts.Method = "PUT"
opts.Headers = map[string]string{
"Overwrite": "t",
}
} else {
opts.Method = "POST"
opts.Type = "application/x-vnd.vmware-streamVmdk"
}
return l.c.Upload(f, item.URL, &opts)
}
func (l *Lease) DownloadFile(ctx context.Context, file string, item FileItem, opts soap.Download) error {
if opts.Progress == nil {
opts.Progress = item
} else {
opts.Progress = progress.Tee(item, opts.Progress)
}
return l.c.DownloadFile(file, item.URL, &opts)
}

146
vendor/github.com/vmware/govmomi/nfc/lease_updater.go generated vendored Normal file
View File

@ -0,0 +1,146 @@
/*
Copyright (c) 2014-2015 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 nfc
import (
"context"
"log"
"net/url"
"sync"
"sync/atomic"
"time"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types"
)
type FileItem struct {
types.OvfFileItem
URL *url.URL
ch chan progress.Report
}
func NewFileItem(u *url.URL, item types.OvfFileItem) FileItem {
return FileItem{
OvfFileItem: item,
URL: u,
ch: make(chan progress.Report),
}
}
func (o FileItem) Sink() chan<- progress.Report {
return o.ch
}
// File converts the FileItem.OvfFileItem to an OvfFile
func (o FileItem) File() types.OvfFile {
return types.OvfFile{
DeviceId: o.DeviceId,
Path: o.Path,
Size: o.Size,
}
}
type LeaseUpdater struct {
lease *Lease
pos int64 // Number of bytes
total int64 // Total number of bytes
done chan struct{} // When lease updater should stop
wg sync.WaitGroup // Track when update loop is done
}
func newLeaseUpdater(ctx context.Context, lease *Lease, info *LeaseInfo) *LeaseUpdater {
l := LeaseUpdater{
lease: lease,
done: make(chan struct{}),
}
for _, item := range info.Items {
l.total += item.Size
go l.waitForProgress(item)
}
// Kickstart update loop
l.wg.Add(1)
go l.run()
return &l
}
func (l *LeaseUpdater) waitForProgress(item FileItem) {
var pos, total int64
total = item.Size
for {
select {
case <-l.done:
return
case p, ok := <-item.ch:
// Return in case of error
if ok && p.Error() != nil {
return
}
if !ok {
// Last element on the channel, add to total
atomic.AddInt64(&l.pos, total-pos)
return
}
// Approximate progress in number of bytes
x := int64(float32(total) * (p.Percentage() / 100.0))
atomic.AddInt64(&l.pos, x-pos)
pos = x
}
}
}
func (l *LeaseUpdater) run() {
defer l.wg.Done()
tick := time.NewTicker(2 * time.Second)
defer tick.Stop()
for {
select {
case <-l.done:
return
case <-tick.C:
// From the vim api HttpNfcLeaseProgress(percent) doc, percent ==
// "Completion status represented as an integer in the 0-100 range."
// Always report the current value of percent, as it will renew the
// lease even if the value hasn't changed or is 0.
percent := int32(float32(100*atomic.LoadInt64(&l.pos)) / float32(l.total))
err := l.lease.Progress(context.TODO(), percent)
if err != nil {
log.Printf("NFC lease progress: %s", err)
return
}
}
}
}
func (l *LeaseUpdater) Done() {
close(l.done)
l.wg.Wait()
}

View File

@ -38,13 +38,11 @@ go_library(
"host_virtual_nic_manager.go",
"host_vsan_internal_system.go",
"host_vsan_system.go",
"http_nfc_lease.go",
"namespace_manager.go",
"network.go",
"network_reference.go",
"opaque_network.go",
"option_manager.go",
"ovf_manager.go",
"resource_pool.go",
"search_index.go",
"storage_pod.go",
@ -61,6 +59,7 @@ go_library(
importpath = "github.com/vmware/govmomi/object",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/vmware/govmomi/nfc:go_default_library",
"//vendor/github.com/vmware/govmomi/property:go_default_library",
"//vendor/github.com/vmware/govmomi/session:go_default_library",
"//vendor/github.com/vmware/govmomi/task:go_default_library",

View File

@ -80,17 +80,24 @@ func (c *Common) SetInventoryPath(p string) {
func (c Common) ObjectName(ctx context.Context) (string, error) {
var o mo.ManagedEntity
name := c.Name()
if name != "" {
return name, nil
}
err := c.Properties(ctx, c.Reference(), []string{"name"}, &o)
if err != nil {
return "", err
}
return o.Name, nil
if o.Name != "" {
return o.Name, nil
}
// Network has its own "name" field...
var n mo.Network
err = c.Properties(ctx, c.Reference(), []string{"name"}, &n)
if err != nil {
return "", err
}
return n.Name, nil
}
func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error {

View File

@ -102,7 +102,9 @@ func (m CustomFieldsManager) Set(ctx context.Context, entity types.ManagedObject
return err
}
func (m CustomFieldsManager) Field(ctx context.Context) ([]types.CustomFieldDef, error) {
type CustomFieldDefList []types.CustomFieldDef
func (m CustomFieldsManager) Field(ctx context.Context) (CustomFieldDefList, error) {
var fm mo.CustomFieldsManager
err := m.Properties(ctx, m.Reference(), []string{"field"}, &fm)
@ -113,19 +115,19 @@ func (m CustomFieldsManager) Field(ctx context.Context) ([]types.CustomFieldDef,
return fm.Field, nil
}
func (m CustomFieldsManager) FindKey(ctx context.Context, key string) (int32, error) {
func (m CustomFieldsManager) FindKey(ctx context.Context, name string) (int32, error) {
field, err := m.Field(ctx)
if err != nil {
return -1, err
}
for _, def := range field {
if def.Name == key {
if def.Name == name {
return def.Key, nil
}
}
k, err := strconv.Atoi(key)
k, err := strconv.Atoi(name)
if err == nil {
// assume literal int key
return int32(k), nil
@ -133,3 +135,12 @@ func (m CustomFieldsManager) FindKey(ctx context.Context, key string) (int32, er
return -1, ErrKeyNameNotFound
}
func (l CustomFieldDefList) ByKey(key int32) *types.CustomFieldDef {
for _, def := range l {
if def.Key == key {
return &def
}
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Copyright (c) 2016-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.
@ -25,6 +25,7 @@ import (
"net/http"
"os"
"path"
"sync"
"time"
"github.com/vmware/govmomi/vim25/soap"
@ -232,8 +233,9 @@ func (f *DatastoreFile) get() (io.Reader, error) {
return f.body, nil
}
func lastIndexLines(s []byte, n *int) int64 {
func lastIndexLines(s []byte, line *int, include func(l int, m string) bool) (int64, bool) {
i := len(s) - 1
done := false
for i > 0 {
o := bytes.LastIndexByte(s[:i], '\n')
@ -241,18 +243,27 @@ func lastIndexLines(s []byte, n *int) int64 {
break
}
i = o
*n--
if *n == 0 {
msg := string(s[o+1 : i+1])
if !include(*line, msg) {
done = true
break
} else {
i = o
*line++
}
}
return int64(i)
return int64(i), done
}
// Tail seeks to the position of the last N lines of the file.
func (f *DatastoreFile) Tail(n int) error {
return f.TailFunc(n, func(line int, _ string) bool { return n > line })
}
// TailFunc will seek backwards in the datastore file until it hits a line that does
// not satisfy the supplied `include` function.
func (f *DatastoreFile) TailFunc(lines int, include func(line int, message string) bool) error {
// Read the file in reverse using bsize chunks
const bsize = int64(1024 * 16)
@ -261,13 +272,14 @@ func (f *DatastoreFile) Tail(n int) error {
return err
}
if n == 0 {
if lines == 0 {
return nil
}
chunk := int64(-1)
buf := bytes.NewBuffer(make([]byte, 0, bsize))
line := 0
for {
var eof bool
@ -298,19 +310,19 @@ func (f *DatastoreFile) Tail(n int) error {
}
b := buf.Bytes()
idx := lastIndexLines(b, &n) + 1
idx, done := lastIndexLines(b, &line, include)
if n == 0 {
if done {
if chunk == -1 {
// We found all N lines in the last chunk of the file.
// The seek offset is also now at the current end of file.
// Save this buffer to avoid another GET request when Read() is called.
buf.Next(int(idx))
buf.Next(int(idx + 1))
f.buf = buf
return nil
}
if _, err = f.Seek(pos+idx, io.SeekStart); err != nil {
if _, err = f.Seek(pos+idx+1, io.SeekStart); err != nil {
return err
}
@ -336,6 +348,7 @@ type followDatastoreFile struct {
r *DatastoreFile
c chan struct{}
i time.Duration
o sync.Once
}
// Read reads up to len(b) bytes from the DatastoreFile being followed.
@ -387,11 +400,15 @@ func (f *followDatastoreFile) Read(p []byte) (int, error) {
// Close will stop Follow polling and close the underlying DatastoreFile.
func (f *followDatastoreFile) Close() error {
close(f.c)
f.o.Do(func() { close(f.c) })
return nil
}
// Follow returns an io.ReadCloser to stream the file contents as data is appended.
func (f *DatastoreFile) Follow(interval time.Duration) io.ReadCloser {
return &followDatastoreFile{f, make(chan struct{}), interval}
return &followDatastoreFile{
r: f,
c: make(chan struct{}),
i: interval,
}
}

View File

@ -97,6 +97,25 @@ func (m *DatastoreFileManager) DeleteVirtualDisk(ctx context.Context, name strin
return task.Wait(ctx)
}
// Move dispatches to the appropriate Move method based on file name extension
func (m *DatastoreFileManager) Move(ctx context.Context, src string, dst string) error {
srcp := m.Path(src)
dstp := m.Path(dst)
f := m.FileManager.MoveDatastoreFile
if srcp.IsVMDK() {
f = m.VirtualDiskManager.MoveVirtualDisk
}
task, err := f(ctx, srcp.String(), m.Datacenter, dstp.String(), m.Datacenter, m.Force)
if err != nil {
return err
}
return task.Wait(ctx)
}
// Path converts path name to a DatastorePath
func (m *DatastoreFileManager) Path(name string) *DatastorePath {
var p DatastorePath

View File

@ -18,6 +18,7 @@ package object
import (
"fmt"
"path"
"strings"
)
@ -63,3 +64,8 @@ func (p *DatastorePath) String() string {
return strings.Join([]string{s, p.Path}, " ")
}
// IsVMDK returns true if Path has a ".vmdk" extension
func (p *DatastorePath) IsVMDK() bool {
return path.Ext(p.Path) == ".vmdk"
}

View File

@ -38,7 +38,7 @@ func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectRefe
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this DistributedVirtualPortgroup
func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
var dvp mo.DistributedVirtualPortgroup
var dvs mo.VmwareDistributedVirtualSwitch // TODO: should be mo.BaseDistributedVirtualSwitch
var dvs mo.DistributedVirtualSwitch
if err := p.Properties(ctx, p.Reference(), []string{"key", "config.distributedVirtualSwitch"}, &dvp); err != nil {
return nil, err

View File

@ -65,3 +65,15 @@ func (s DistributedVirtualSwitch) AddPortgroup(ctx context.Context, spec []types
return NewTask(s.Client(), res.Returnval), nil
}
func (s DistributedVirtualSwitch) FetchDVPorts(ctx context.Context) ([]types.DistributedVirtualPort, error) {
req := &types.FetchDVPorts{
This: s.Reference(),
}
res, err := methods.FetchDVPorts(ctx, s.Client(), req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}

View File

@ -88,6 +88,15 @@ func (s HostStorageSystem) RescanAllHba(ctx context.Context) error {
return err
}
func (s HostStorageSystem) Refresh(ctx context.Context) error {
req := types.RefreshStorageSystem{
This: s.Reference(),
}
_, err := methods.RefreshStorageSystem(ctx, s.c, &req)
return err
}
func (s HostStorageSystem) MarkAsSsd(ctx context.Context, uuid string) (*Task, error) {
req := types.MarkAsSsd_Task{
This: s.Reference(),

View File

@ -42,7 +42,7 @@ func (m HostVsanInternalSystem) QueryVsanObjectUuidsByFilter(ctx context.Context
req := types.QueryVsanObjectUuidsByFilter{
This: m.Reference(),
Uuids: uuids,
Limit: limit,
Limit: &limit,
Version: version,
}

View File

@ -1,143 +0,0 @@
/*
Copyright (c) 2015 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 object
import (
"context"
"errors"
"fmt"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
type HttpNfcLease struct {
Common
}
func NewHttpNfcLease(c *vim25.Client, ref types.ManagedObjectReference) *HttpNfcLease {
return &HttpNfcLease{
Common: NewCommon(c, ref),
}
}
// HttpNfcLeaseAbort wraps methods.HttpNfcLeaseAbort
func (o HttpNfcLease) HttpNfcLeaseAbort(ctx context.Context, fault *types.LocalizedMethodFault) error {
req := types.HttpNfcLeaseAbort{
This: o.Reference(),
Fault: fault,
}
_, err := methods.HttpNfcLeaseAbort(ctx, o.c, &req)
if err != nil {
return err
}
return nil
}
// HttpNfcLeaseComplete wraps methods.HttpNfcLeaseComplete
func (o HttpNfcLease) HttpNfcLeaseComplete(ctx context.Context) error {
req := types.HttpNfcLeaseComplete{
This: o.Reference(),
}
_, err := methods.HttpNfcLeaseComplete(ctx, o.c, &req)
if err != nil {
return err
}
return nil
}
// HttpNfcLeaseGetManifest wraps methods.HttpNfcLeaseGetManifest
func (o HttpNfcLease) HttpNfcLeaseGetManifest(ctx context.Context) error {
req := types.HttpNfcLeaseGetManifest{
This: o.Reference(),
}
_, err := methods.HttpNfcLeaseGetManifest(ctx, o.c, &req)
if err != nil {
return err
}
return nil
}
// HttpNfcLeaseProgress wraps methods.HttpNfcLeaseProgress
func (o HttpNfcLease) HttpNfcLeaseProgress(ctx context.Context, percent int32) error {
req := types.HttpNfcLeaseProgress{
This: o.Reference(),
Percent: percent,
}
_, err := methods.HttpNfcLeaseProgress(ctx, o.c, &req)
if err != nil {
return err
}
return nil
}
func (o HttpNfcLease) Wait(ctx context.Context) (*types.HttpNfcLeaseInfo, error) {
var lease mo.HttpNfcLease
pc := property.DefaultCollector(o.c)
err := property.Wait(ctx, pc, o.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool {
done := false
for _, c := range pc {
if c.Val == nil {
continue
}
switch c.Name {
case "error":
val := c.Val.(types.LocalizedMethodFault)
lease.Error = &val
done = true
case "info":
val := c.Val.(types.HttpNfcLeaseInfo)
lease.Info = &val
case "state":
lease.State = c.Val.(types.HttpNfcLeaseState)
if lease.State != types.HttpNfcLeaseStateInitializing {
done = true
}
}
}
return done
})
if err != nil {
return nil, err
}
if lease.State == types.HttpNfcLeaseStateReady {
return lease.Info, nil
}
if lease.Error != nil {
return nil, errors.New(lease.Error.LocalizedMessage)
}
return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State)
}

View File

@ -20,6 +20,7 @@ import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
@ -34,12 +35,20 @@ func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network {
}
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
func (n Network) EthernetCardBackingInfo(_ context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
name := n.Name()
func (n Network) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
var e mo.Network
// Use Network.Name rather than Common.Name as the latter does not return the complete name if it contains a '/'
// We can't use Common.ObjectName here either as we need the ManagedEntity.Name field is not set since mo.Network
// has its own Name field.
err := n.Properties(ctx, n.Reference(), []string{"name"}, &e)
if err != nil {
return nil, err
}
backing := &types.VirtualEthernetCardNetworkBackingInfo{
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
DeviceName: name,
DeviceName: e.Name,
},
}

View File

@ -1,104 +0,0 @@
/*
Copyright (c) 2015 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 object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
)
type OvfManager struct {
Common
}
func NewOvfManager(c *vim25.Client) *OvfManager {
o := OvfManager{
Common: NewCommon(c, *c.ServiceContent.OvfManager),
}
return &o
}
// CreateDescriptor wraps methods.CreateDescriptor
func (o OvfManager) CreateDescriptor(ctx context.Context, obj Reference, cdp types.OvfCreateDescriptorParams) (*types.OvfCreateDescriptorResult, error) {
req := types.CreateDescriptor{
This: o.Reference(),
Obj: obj.Reference(),
Cdp: cdp,
}
res, err := methods.CreateDescriptor(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// CreateImportSpec wraps methods.CreateImportSpec
func (o OvfManager) CreateImportSpec(ctx context.Context, ovfDescriptor string, resourcePool Reference, datastore Reference, cisp types.OvfCreateImportSpecParams) (*types.OvfCreateImportSpecResult, error) {
req := types.CreateImportSpec{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
ResourcePool: resourcePool.Reference(),
Datastore: datastore.Reference(),
Cisp: cisp,
}
res, err := methods.CreateImportSpec(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// ParseDescriptor wraps methods.ParseDescriptor
func (o OvfManager) ParseDescriptor(ctx context.Context, ovfDescriptor string, pdp types.OvfParseDescriptorParams) (*types.OvfParseDescriptorResult, error) {
req := types.ParseDescriptor{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
Pdp: pdp,
}
res, err := methods.ParseDescriptor(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// ValidateHost wraps methods.ValidateHost
func (o OvfManager) ValidateHost(ctx context.Context, ovfDescriptor string, host Reference, vhp types.OvfValidateHostParams) (*types.OvfValidateHostResult, error) {
req := types.ValidateHost{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
Host: host.Reference(),
Vhp: vhp,
}
res, err := methods.ValidateHost(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}

View File

@ -19,6 +19,7 @@ package object
import (
"context"
"github.com/vmware/govmomi/nfc"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
@ -34,7 +35,7 @@ func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *Resourc
}
}
func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*HttpNfcLease, error) {
func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*nfc.Lease, error) {
req := types.ImportVApp{
This: p.Reference(),
Spec: spec,
@ -55,7 +56,7 @@ func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec,
return nil, err
}
return NewHttpNfcLease(p.c, res.Returnval), nil
return nfc.NewLease(p.c, res.Returnval), nil
}
func (p ResourcePool) Create(ctx context.Context, name string, spec types.ResourceConfigSpec) (*ResourcePool, error) {

View File

@ -22,6 +22,7 @@ import (
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/task"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types"
)
@ -51,3 +52,11 @@ func (t *Task) WaitForResult(ctx context.Context, s progress.Sinker) (*types.Tas
p := property.DefaultCollector(t.c)
return task.Wait(ctx, t.Reference(), p, s)
}
func (t *Task) Cancel(ctx context.Context) error {
_, err := methods.CancelTask(ctx, t.Client(), &types.CancelTask{
This: t.Reference(),
})
return err
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2015-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.
@ -30,6 +30,7 @@ import (
// Type values for use in BootOrder
const (
DeviceTypeNone = "-"
DeviceTypeCdrom = "cdrom"
DeviceTypeDisk = "disk"
DeviceTypeEthernet = "ethernet"
@ -754,6 +755,9 @@ func (l VirtualDeviceList) PrimaryMacAddress() string {
// convert a BaseVirtualDevice to a BaseVirtualMachineBootOptionsBootableDevice
var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice{
DeviceTypeNone: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice {
return &types.VirtualMachineBootOptionsBootableDevice{}
},
DeviceTypeCdrom: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice {
return &types.VirtualMachineBootOptionsBootableCdromDevice{}
},
@ -773,17 +777,23 @@ var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.Base
}
// BootOrder returns a list of devices which can be used to set boot order via VirtualMachine.SetBootOptions.
// The order can any of "ethernet", "cdrom", "floppy" or "disk" or by specific device name.
// The order can be any of "ethernet", "cdrom", "floppy" or "disk" or by specific device name.
// A value of "-" will clear the existing boot order on the VC/ESX side.
func (l VirtualDeviceList) BootOrder(order []string) []types.BaseVirtualMachineBootOptionsBootableDevice {
var devices []types.BaseVirtualMachineBootOptionsBootableDevice
for _, name := range order {
if kind, ok := bootableDevices[name]; ok {
if name == DeviceTypeNone {
// Not covered in the API docs, nor obvious, but this clears the boot order on the VC/ESX side.
devices = append(devices, new(types.VirtualMachineBootOptionsBootableDevice))
continue
}
for _, device := range l {
if l.Type(device) == name {
devices = append(devices, kind(device))
}
}
continue
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2015-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.
@ -23,6 +23,7 @@ import (
"net"
"path"
"github.com/vmware/govmomi/nfc"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
@ -464,6 +465,20 @@ func (v VirtualMachine) Answer(ctx context.Context, id, answer string) error {
return nil
}
func (v VirtualMachine) AcquireTicket(ctx context.Context, kind string) (*types.VirtualMachineTicket, error) {
req := types.AcquireTicket{
This: v.Reference(),
TicketType: kind,
}
res, err := methods.AcquireTicket(ctx, v.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// CreateSnapshot creates a new snapshot of a virtual machine.
func (v VirtualMachine) CreateSnapshot(ctx context.Context, name string, description string, memory bool, quiesce bool) (*Task, error) {
req := types.CreateSnapshot_Task{
@ -497,7 +512,7 @@ func (v VirtualMachine) RemoveAllSnapshot(ctx context.Context, consolidate *bool
return NewTask(v.c, res.Returnval), nil
}
type snapshotMap map[string][]Reference
type snapshotMap map[string][]types.ManagedObjectReference
func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree) {
for i, st := range tree {
@ -511,18 +526,18 @@ func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree)
}
for _, name := range names {
m[name] = append(m[name], &tree[i].Snapshot)
m[name] = append(m[name], tree[i].Snapshot)
}
m.add(sname, st.ChildSnapshotList)
}
}
// findSnapshot supports snapshot lookup by name, where name can be:
// FindSnapshot supports snapshot lookup by name, where name can be:
// 1) snapshot ManagedObjectReference.Value (unique)
// 2) snapshot name (may not be unique)
// 3) snapshot tree path (may not be unique)
func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Reference, error) {
func (v VirtualMachine) FindSnapshot(ctx context.Context, name string) (*types.ManagedObjectReference, error) {
var o mo.VirtualMachine
err := v.Properties(ctx, v.Reference(), []string{"snapshot"}, &o)
@ -542,7 +557,7 @@ func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Referenc
case 0:
return nil, fmt.Errorf("snapshot %q not found", name)
case 1:
return s[0], nil
return &s[0], nil
default:
return nil, fmt.Errorf("%q resolves to %d snapshots", name, len(s))
}
@ -550,7 +565,7 @@ func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Referenc
// RemoveSnapshot removes a named snapshot
func (v VirtualMachine) RemoveSnapshot(ctx context.Context, name string, removeChildren bool, consolidate *bool) (*Task, error) {
snapshot, err := v.findSnapshot(ctx, name)
snapshot, err := v.FindSnapshot(ctx, name)
if err != nil {
return nil, err
}
@ -586,7 +601,7 @@ func (v VirtualMachine) RevertToCurrentSnapshot(ctx context.Context, suppressPow
// RevertToSnapshot reverts to a named snapshot
func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) {
snapshot, err := v.findSnapshot(ctx, name)
snapshot, err := v.FindSnapshot(ctx, name)
if err != nil {
return nil, err
}
@ -757,3 +772,30 @@ func (v VirtualMachine) UpgradeTools(ctx context.Context, options string) (*Task
return NewTask(v.c, res.Returnval), nil
}
func (v VirtualMachine) Export(ctx context.Context) (*nfc.Lease, error) {
req := types.ExportVm{
This: v.Reference(),
}
res, err := methods.ExportVm(ctx, v.Client(), &req)
if err != nil {
return nil, err
}
return nfc.NewLease(v.c, res.Returnval), nil
}
func (v VirtualMachine) UpgradeVM(ctx context.Context, version string) (*Task, error) {
req := types.UpgradeVM_Task{
This: v.Reference(),
Version: version,
}
res, err := methods.UpgradeVM_Task(ctx, v.Client(), &req)
if err != nil {
return nil, err
}
return NewTask(v.c, res.Returnval), nil
}

View File

@ -30,7 +30,7 @@ import (
// Collector models the PropertyCollector managed object.
//
// For more information, see:
// http://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vmodl.query.PropertyCollector.html
// http://pubs.vmware.com/vsphere-60/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.html
//
type Collector struct {
roundTripper soap.RoundTripper

View File

@ -18,7 +18,7 @@ package property
import (
"fmt"
"path/filepath"
"path"
"reflect"
"strconv"
"strings"
@ -103,7 +103,11 @@ func (f Filter) MatchProperty(prop types.DynamicProperty) bool {
switch pval := prop.Val.(type) {
case string:
m, _ := filepath.Match(match.(string), pval)
s := match.(string)
if s == "*" {
return true // TODO: path.Match fails if s contains a '/'
}
m, _ := path.Match(s, pval)
return m
default:
return reflect.DeepEqual(match, pval)

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2015-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.
@ -22,7 +22,50 @@ import (
"github.com/vmware/govmomi/vim25/types"
)
// Wait waits for any of the specified properties of the specified managed
// WaitFilter provides helpers to construct a types.CreateFilter for use with property.Wait
type WaitFilter struct {
types.CreateFilter
}
// Add a new ObjectSpec and PropertySpec to the WaitFilter
func (f *WaitFilter) Add(obj types.ManagedObjectReference, kind string, ps []string, set ...types.BaseSelectionSpec) *WaitFilter {
spec := types.ObjectSpec{
Obj: obj,
SelectSet: set,
}
pset := types.PropertySpec{
Type: kind,
PathSet: ps,
}
if len(ps) == 0 {
pset.All = types.NewBool(true)
}
f.Spec.ObjectSet = append(f.Spec.ObjectSet, spec)
f.Spec.PropSet = append(f.Spec.PropSet, pset)
return f
}
// Wait creates a new WaitFilter and calls the specified function for each ObjectUpdate via WaitForUpdates
func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error {
filter := new(WaitFilter).Add(obj, obj.Type, ps)
return WaitForUpdates(ctx, c, filter, func(updates []types.ObjectUpdate) bool {
for _, update := range updates {
if f(update.ChangeSet) {
return true
}
}
return false
})
}
// WaitForUpdates waits for any of the specified properties of the specified managed
// object to change. It calls the specified function for every update it
// receives. If this function returns false, it continues waiting for
// subsequent updates. If this function returns true, it stops waiting and
@ -35,7 +78,7 @@ import (
// The newly created collector is destroyed before this function returns (both
// in case of success or error).
//
func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error {
func WaitForUpdates(ctx context.Context, c *Collector, filter *WaitFilter, f func([]types.ObjectUpdate) bool) error {
p, err := c.Create(ctx)
if err != nil {
return err
@ -45,91 +88,13 @@ func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, p
// specified context may have timed out or have been cancelled.
defer p.Destroy(context.Background())
req := types.CreateFilter{
Spec: types.PropertyFilterSpec{
ObjectSet: []types.ObjectSpec{
{
Obj: obj,
},
},
PropSet: []types.PropertySpec{
{
PathSet: ps,
Type: obj.Type,
},
},
},
}
if len(ps) == 0 {
req.Spec.PropSet[0].All = types.NewBool(true)
}
err = p.CreateFilter(ctx, req)
if err != nil {
return err
}
return waitLoop(ctx, p, func(_ types.ManagedObjectReference, pc []types.PropertyChange) bool {
return f(pc)
})
}
// WaitForView waits for any of the specified properties of the managed
// objects in the View to change. It calls the specified function for every update it
// receives. If this function returns false, it continues waiting for
// subsequent updates. If this function returns true, it stops waiting and
// returns.
//
// To only receive updates for the View's specified managed objects, the function
// creates a new property collector and calls CreateFilter. A new property
// collector is required because filters can only be added, not removed.
//
// The newly created collector is destroyed before this function returns (both
// in case of success or error).
//
// The code assumes that all objects in the View are the same type
func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectReference, obj types.ManagedObjectReference, ps []string, f func(types.ManagedObjectReference, []types.PropertyChange) bool) error {
p, err := c.Create(ctx)
err = p.CreateFilter(ctx, filter.CreateFilter)
if err != nil {
return err
}
// Attempt to destroy the collector using the background context, as the
// specified context may have timed out or have been cancelled.
defer p.Destroy(context.Background())
req := types.CreateFilter{
Spec: types.PropertyFilterSpec{
ObjectSet: []types.ObjectSpec{
{
Obj: view,
SelectSet: []types.BaseSelectionSpec{
&types.TraversalSpec{
SelectionSpec: types.SelectionSpec{
Name: "traverseEntities",
},
Path: "view",
Type: view.Type}},
},
},
PropSet: []types.PropertySpec{
{
Type: obj.Type,
PathSet: ps,
},
},
}}
err = p.CreateFilter(ctx, req)
if err != nil {
return err
}
return waitLoop(ctx, p, f)
}
func waitLoop(ctx context.Context, c *Collector, f func(types.ManagedObjectReference, []types.PropertyChange) bool) error {
for version := ""; ; {
res, err := c.WaitForUpdates(ctx, version)
res, err := p.WaitForUpdates(ctx, version)
if err != nil {
return err
}
@ -142,12 +107,9 @@ func waitLoop(ctx context.Context, c *Collector, f func(types.ManagedObjectRefer
version = res.Version
for _, fs := range res.FilterSet {
for _, os := range fs.ObjectSet {
if f(os.Obj, os.ChangeSet) {
return nil
}
if f(fs.ObjectSet) {
return nil
}
}
}
}

View File

@ -199,3 +199,31 @@ func (sm *Manager) AcquireLocalTicket(ctx context.Context, userName string) (*ty
return &res.Returnval, nil
}
func (sm *Manager) AcquireCloneTicket(ctx context.Context) (string, error) {
req := types.AcquireCloneTicket{
This: sm.Reference(),
}
res, err := methods.AcquireCloneTicket(ctx, sm.client, &req)
if err != nil {
return "", err
}
return res.Returnval, nil
}
func (sm *Manager) CloneSession(ctx context.Context, ticket string) error {
req := types.CloneSession{
This: sm.Reference(),
CloneTicket: ticket,
}
res, err := methods.CloneSession(ctx, sm.client, &req)
if err != nil {
return err
}
sm.userSession = &res.Returnval
return nil
}

84
vendor/github.com/vmware/govmomi/simulator/BUILD generated vendored Normal file
View File

@ -0,0 +1,84 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"authorization_manager.go",
"cluster_compute_resource.go",
"custom_fields_manager.go",
"datacenter.go",
"datastore.go",
"doc.go",
"dvs.go",
"entity.go",
"file_manager.go",
"folder.go",
"guest_id.go",
"host_datastore_browser.go",
"host_datastore_system.go",
"host_firewall_system.go",
"host_network_system.go",
"host_system.go",
"ip_pool_manager.go",
"license_manager.go",
"model.go",
"option_manager.go",
"os_unix.go",
"performance_manager.go",
"portgroup.go",
"property_collector.go",
"property_filter.go",
"registry.go",
"resource_pool.go",
"search_index.go",
"service_instance.go",
"session_manager.go",
"simulator.go",
"snapshot.go",
"task.go",
"task_manager.go",
"user_directory.go",
"view_manager.go",
"virtual_disk_manager.go",
"virtual_machine.go",
] + select({
"@io_bazel_rules_go//go/platform:windows": [
"os_windows.go",
],
"//conditions:default": [],
}),
importpath = "github.com/vmware/govmomi/simulator",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/google/uuid:go_default_library",
"//vendor/github.com/vmware/govmomi/find:go_default_library",
"//vendor/github.com/vmware/govmomi/object:go_default_library",
"//vendor/github.com/vmware/govmomi/session:go_default_library",
"//vendor/github.com/vmware/govmomi/simulator/esx:go_default_library",
"//vendor/github.com/vmware/govmomi/simulator/vpx:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/methods:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/mo:go_default_library",
"//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/vim25/xml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/vmware/govmomi/simulator/esx:all-srcs",
"//vendor/github.com/vmware/govmomi/simulator/vpx:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,257 @@
/*
Copyright (c) 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 simulator
import (
"strings"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type AuthorizationManager struct {
mo.AuthorizationManager
permissions map[types.ManagedObjectReference][]types.Permission
privileges map[string]struct{}
system []string
nextID int32
}
func NewAuthorizationManager(ref types.ManagedObjectReference) object.Reference {
m := &AuthorizationManager{}
m.Self = ref
m.RoleList = esx.RoleList
m.permissions = make(map[types.ManagedObjectReference][]types.Permission)
l := object.AuthorizationRoleList(m.RoleList)
m.system = l.ByName("ReadOnly").Privilege
admin := l.ByName("Admin")
m.privileges = make(map[string]struct{}, len(admin.Privilege))
for _, id := range admin.Privilege {
m.privileges[id] = struct{}{}
}
root := Map.content().RootFolder
for _, u := range DefaultUserGroup {
m.permissions[root] = append(m.permissions[root], types.Permission{
Entity: &root,
Principal: u.Principal,
Group: u.Group,
RoleId: admin.RoleId,
Propagate: true,
})
}
return m
}
func (m *AuthorizationManager) RetrieveEntityPermissions(req *types.RetrieveEntityPermissions) soap.HasFault {
e := Map.Get(req.Entity).(mo.Entity)
p := m.permissions[e.Reference()]
if req.Inherited {
for {
parent := e.Entity().Parent
if parent == nil {
break
}
e = Map.Get(parent.Reference()).(mo.Entity)
p = append(p, m.permissions[e.Reference()]...)
}
}
return &methods.RetrieveEntityPermissionsBody{
Res: &types.RetrieveEntityPermissionsResponse{
Returnval: p,
},
}
}
func (m *AuthorizationManager) RetrieveAllPermissions(req *types.RetrieveAllPermissions) soap.HasFault {
var p []types.Permission
for _, v := range m.permissions {
p = append(p, v...)
}
return &methods.RetrieveAllPermissionsBody{
Res: &types.RetrieveAllPermissionsResponse{
Returnval: p,
},
}
}
func (m *AuthorizationManager) RemoveEntityPermission(req *types.RemoveEntityPermission) soap.HasFault {
var p []types.Permission
for _, v := range m.permissions[req.Entity] {
if v.Group == req.IsGroup && v.Principal == req.User {
continue
}
p = append(p, v)
}
m.permissions[req.Entity] = p
return &methods.RemoveEntityPermissionBody{
Res: &types.RemoveEntityPermissionResponse{},
}
}
func (m *AuthorizationManager) SetEntityPermissions(req *types.SetEntityPermissions) soap.HasFault {
m.permissions[req.Entity] = req.Permission
return &methods.SetEntityPermissionsBody{
Res: &types.SetEntityPermissionsResponse{},
}
}
func (m *AuthorizationManager) RetrieveRolePermissions(req *types.RetrieveRolePermissions) soap.HasFault {
var p []types.Permission
for _, set := range m.permissions {
for _, v := range set {
if v.RoleId == req.RoleId {
p = append(p, v)
}
}
}
return &methods.RetrieveRolePermissionsBody{
Res: &types.RetrieveRolePermissionsResponse{
Returnval: p,
},
}
}
func (m *AuthorizationManager) AddAuthorizationRole(req *types.AddAuthorizationRole) soap.HasFault {
body := &methods.AddAuthorizationRoleBody{}
for _, role := range m.RoleList {
if role.Name == req.Name {
body.Fault_ = Fault("", &types.AlreadyExists{})
return body
}
}
ids, err := m.privIDs(req.PrivIds)
if err != nil {
body.Fault_ = err
return body
}
m.RoleList = append(m.RoleList, types.AuthorizationRole{
Info: &types.Description{
Label: req.Name,
Summary: req.Name,
},
RoleId: m.nextID,
Privilege: ids,
Name: req.Name,
System: false,
})
m.nextID++
body.Res = &types.AddAuthorizationRoleResponse{}
return body
}
func (m *AuthorizationManager) UpdateAuthorizationRole(req *types.UpdateAuthorizationRole) soap.HasFault {
body := &methods.UpdateAuthorizationRoleBody{}
for _, role := range m.RoleList {
if role.Name == req.NewName && role.RoleId != req.RoleId {
body.Fault_ = Fault("", &types.AlreadyExists{})
return body
}
}
for i, role := range m.RoleList {
if role.RoleId == req.RoleId {
if len(req.PrivIds) != 0 {
ids, err := m.privIDs(req.PrivIds)
if err != nil {
body.Fault_ = err
return body
}
m.RoleList[i].Privilege = ids
}
m.RoleList[i].Name = req.NewName
body.Res = &types.UpdateAuthorizationRoleResponse{}
return body
}
}
body.Fault_ = Fault("", &types.NotFound{})
return body
}
func (m *AuthorizationManager) RemoveAuthorizationRole(req *types.RemoveAuthorizationRole) soap.HasFault {
body := &methods.RemoveAuthorizationRoleBody{}
for i, role := range m.RoleList {
if role.RoleId == req.RoleId {
m.RoleList = append(m.RoleList[:i], m.RoleList[i+1:]...)
body.Res = &types.RemoveAuthorizationRoleResponse{}
return body
}
}
body.Fault_ = Fault("", &types.NotFound{})
return body
}
func (m *AuthorizationManager) privIDs(ids []string) ([]string, *soap.Fault) {
system := make(map[string]struct{}, len(m.system))
for _, id := range ids {
if _, ok := m.privileges[id]; !ok {
return nil, Fault("", &types.InvalidArgument{InvalidProperty: "privIds"})
}
if strings.HasPrefix(id, "System.") {
system[id] = struct{}{}
}
}
for _, id := range m.system {
if _, ok := system[id]; ok {
continue
}
ids = append(ids, id)
}
return ids, nil
}

View File

@ -0,0 +1,98 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type ClusterComputeResource struct {
mo.ClusterComputeResource
}
type addHost struct {
*ClusterComputeResource
req *types.AddHost_Task
}
func (add *addHost) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
spec := add.req.Spec
if spec.HostName == "" {
return nil, &types.NoHost{}
}
host := NewHostSystem(esx.HostSystem)
host.Summary.Config.Name = spec.HostName
host.Name = host.Summary.Config.Name
host.Runtime.ConnectionState = types.HostSystemConnectionStateDisconnected
cr := add.ClusterComputeResource
Map.PutEntity(cr, Map.NewEntity(host))
cr.Host = append(cr.Host, host.Reference())
if add.req.AsConnected {
host.Runtime.ConnectionState = types.HostSystemConnectionStateConnected
}
addComputeResource(add.ClusterComputeResource.Summary.GetComputeResourceSummary(), host)
return host.Reference(), nil
}
func (c *ClusterComputeResource) AddHostTask(add *types.AddHost_Task) soap.HasFault {
return &methods.AddHost_TaskBody{
Res: &types.AddHost_TaskResponse{
Returnval: NewTask(&addHost{c, add}).Run(),
},
}
}
func CreateClusterComputeResource(f *Folder, name string, spec types.ClusterConfigSpecEx) (*ClusterComputeResource, types.BaseMethodFault) {
if e := Map.FindByName(name, f.ChildEntity); e != nil {
return nil, &types.DuplicateName{
Name: e.Entity().Name,
Object: e.Reference(),
}
}
cluster := &ClusterComputeResource{}
cluster.Name = name
cluster.Summary = &types.ClusterComputeResourceSummary{
UsageSummary: new(types.ClusterUsageSummary),
}
config := &types.ClusterConfigInfoEx{}
cluster.ConfigurationEx = config
config.DrsConfig.Enabled = types.NewBool(true)
pool := NewResourcePool()
Map.PutEntity(cluster, Map.NewEntity(pool))
cluster.ResourcePool = &pool.Self
f.putChild(cluster)
pool.Owner = cluster.Self
return cluster, nil
}

View File

@ -0,0 +1,111 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type CustomFieldsManager struct {
mo.CustomFieldsManager
nextKey int32
}
func NewCustomFieldsManager(ref types.ManagedObjectReference) object.Reference {
m := &CustomFieldsManager{}
m.Self = ref
return m
}
func (c *CustomFieldsManager) find(key int32) (int, *types.CustomFieldDef) {
for i, field := range c.Field {
if field.Key == key {
return i, &c.Field[i]
}
}
return -1, nil
}
func (c *CustomFieldsManager) AddCustomFieldDef(req *types.AddCustomFieldDef) soap.HasFault {
body := &methods.AddCustomFieldDefBody{}
def := types.CustomFieldDef{
Key: c.nextKey,
Name: req.Name,
ManagedObjectType: req.MoType,
Type: req.MoType,
FieldDefPrivileges: req.FieldDefPolicy,
FieldInstancePrivileges: req.FieldPolicy,
}
c.Field = append(c.Field, def)
c.nextKey++
body.Res = &types.AddCustomFieldDefResponse{
Returnval: def,
}
return body
}
func (c *CustomFieldsManager) RemoveCustomFieldDef(req *types.RemoveCustomFieldDef) soap.HasFault {
body := &methods.RemoveCustomFieldDefBody{}
i, field := c.find(req.Key)
if field == nil {
body.Fault_ = Fault("", &types.NotFound{})
return body
}
c.Field = append(c.Field[:i], c.Field[i+1:]...)
body.Res = &types.RemoveCustomFieldDefResponse{}
return body
}
func (c *CustomFieldsManager) RenameCustomFieldDef(req *types.RenameCustomFieldDef) soap.HasFault {
body := &methods.RenameCustomFieldDefBody{}
_, field := c.find(req.Key)
if field == nil {
body.Fault_ = Fault("", &types.NotFound{})
return body
}
field.Name = req.Name
body.Res = &types.RenameCustomFieldDefResponse{}
return body
}
func (c *CustomFieldsManager) SetField(req *types.SetField) soap.HasFault {
body := &methods.SetFieldBody{}
entity := Map.Get(req.Entity).(mo.Entity).Entity()
entity.CustomValue = append(entity.CustomValue, &types.CustomFieldStringValue{
CustomFieldValue: types.CustomFieldValue{Key: req.Key},
Value: req.Value,
})
body.Res = &types.SetFieldResponse{}
return body
}

View File

@ -0,0 +1,76 @@
/*
Copyright (c) 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 simulator
import (
"strings"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// Create Datacenter Folders.
// Every Datacenter has 4 inventory Folders: Vm, Host, Datastore and Network.
// The ESX folder child types are limited to 1 type.
// The VC folders have additional child types, including nested folders.
func createDatacenterFolders(dc *mo.Datacenter, isVC bool) {
folders := []struct {
ref *types.ManagedObjectReference
name string
types []string
}{
{&dc.VmFolder, "vm", []string{"VirtualMachine", "VirtualApp", "Folder"}},
{&dc.HostFolder, "host", []string{"ComputeResource", "Folder"}},
{&dc.DatastoreFolder, "datastore", []string{"Datastore", "StoragePod", "Folder"}},
{&dc.NetworkFolder, "network", []string{"Network", "DistributedVirtualSwitch", "Folder"}},
}
for _, f := range folders {
folder := &Folder{}
folder.Name = f.name
if isVC {
folder.ChildType = f.types
e := Map.PutEntity(dc, folder)
// propagate the generated morefs to Datacenter
ref := e.Reference()
f.ref.Type = ref.Type
f.ref.Value = ref.Value
} else {
folder.ChildType = f.types[:1]
folder.Self = *f.ref
Map.PutEntity(dc, folder)
}
}
net := Map.Get(dc.NetworkFolder).(*Folder)
for _, ref := range esx.Datacenter.Network {
// Add VM Network by default to each Datacenter
network := &mo.Network{}
network.Self = ref
network.Name = strings.Split(ref.Value, "-")[1]
network.Entity().Name = network.Name
if isVC {
network.Self.Value = "" // we want a different moid per-DC
}
net.putChild(network)
}
}

View File

@ -0,0 +1,59 @@
/*
Copyright (c) 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 simulator
import (
"time"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type Datastore struct {
mo.Datastore
}
func parseDatastorePath(dsPath string) (*object.DatastorePath, types.BaseMethodFault) {
var p object.DatastorePath
if p.FromString(dsPath) {
return &p, nil
}
return nil, &types.InvalidDatastorePath{DatastorePath: dsPath}
}
func (ds *Datastore) RefreshDatastore(*types.RefreshDatastore) soap.HasFault {
r := &methods.RefreshDatastoreBody{}
err := ds.stat()
if err != nil {
r.Fault_ = Fault(err.Error(), &types.HostConfigFault{})
return r
}
info := ds.Info.GetDatastoreInfo()
now := time.Now()
info.Timestamp = &now
return r
}

22
vendor/github.com/vmware/govmomi/simulator/doc.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
/*
Copyright (c) 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 simulator is a mock framework for the vSphere API.
See also: https://github.com/vmware/govmomi/blob/master/vcsim/README.md
*/
package simulator

187
vendor/github.com/vmware/govmomi/simulator/dvs.go generated vendored Normal file
View File

@ -0,0 +1,187 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type DistributedVirtualSwitch struct {
mo.DistributedVirtualSwitch
}
func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Task) soap.HasFault {
task := CreateTask(s, "addDVPortgroup", func(t *Task) (types.AnyType, types.BaseMethodFault) {
f := Map.getEntityParent(s, "Folder").(*Folder)
for _, spec := range c.Spec {
pg := &DistributedVirtualPortgroup{}
pg.Name = spec.Name
pg.Entity().Name = pg.Name
if obj := Map.FindByName(pg.Name, f.ChildEntity); obj != nil {
return nil, &types.DuplicateName{
Name: pg.Name,
Object: obj.Reference(),
}
}
f.putChild(pg)
pg.Key = pg.Self.Value
pg.Config = types.DVPortgroupConfigInfo{
Key: pg.Key,
Name: pg.Name,
NumPorts: spec.NumPorts,
DistributedVirtualSwitch: &s.Self,
DefaultPortConfig: spec.DefaultPortConfig,
Description: spec.Description,
Type: spec.Type,
Policy: spec.Policy,
PortNameFormat: spec.PortNameFormat,
Scope: spec.Scope,
VendorSpecificConfig: spec.VendorSpecificConfig,
ConfigVersion: spec.ConfigVersion,
AutoExpand: spec.AutoExpand,
VmVnicNetworkResourcePoolKey: spec.VmVnicNetworkResourcePoolKey,
}
s.Portgroup = append(s.Portgroup, pg.Self)
s.Summary.PortgroupName = append(s.Summary.PortgroupName, pg.Name)
for _, h := range s.Summary.HostMember {
pg.Host = AddReference(h, pg.Host)
host := Map.Get(h).(*HostSystem)
host.Network = append(host.Network, pg.Reference())
}
}
return nil, nil
})
return &methods.AddDVPortgroup_TaskBody{
Res: &types.AddDVPortgroup_TaskResponse{
Returnval: task.Run(),
},
}
}
func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_Task) soap.HasFault {
task := CreateTask(s, "reconfigureDvs", func(t *Task) (types.AnyType, types.BaseMethodFault) {
spec := req.Spec.GetDVSConfigSpec()
for _, member := range spec.Host {
h := Map.Get(member.Host)
if h == nil {
return nil, &types.ManagedObjectNotFound{Obj: member.Host}
}
host := h.(*HostSystem)
switch types.ConfigSpecOperation(member.Operation) {
case types.ConfigSpecOperationAdd:
if FindReference(host.Network, s.Self) != nil {
return nil, &types.AlreadyExists{Name: host.Name}
}
host.Network = append(host.Network, s.Self)
host.Network = append(host.Network, s.Portgroup...)
s.Summary.HostMember = append(s.Summary.HostMember, member.Host)
for _, ref := range s.Portgroup {
pg := Map.Get(ref).(*DistributedVirtualPortgroup)
pg.Host = AddReference(member.Host, pg.Host)
}
case types.ConfigSpecOperationRemove:
if pg := FindReference(host.Network, s.Portgroup...); pg != nil {
return nil, &types.ResourceInUse{
Type: pg.Type,
Name: pg.Value,
}
}
host.Network = RemoveReference(s.Self, host.Network)
s.Summary.HostMember = RemoveReference(s.Self, s.Summary.HostMember)
case types.ConfigSpecOperationEdit:
return nil, &types.NotSupported{}
}
}
return nil, nil
})
return &methods.ReconfigureDvs_TaskBody{
Res: &types.ReconfigureDvs_TaskResponse{
Returnval: task.Run(),
},
}
}
func (s *DistributedVirtualSwitch) FetchDVPorts(req *types.FetchDVPorts) soap.HasFault {
body := &methods.FetchDVPortsBody{}
body.Res = &types.FetchDVPortsResponse{
Returnval: s.dvPortgroups(req.Criteria),
}
return body
}
func (s *DistributedVirtualSwitch) DestroyTask(req *types.Destroy_Task) soap.HasFault {
task := CreateTask(s, "destroy", func(t *Task) (types.AnyType, types.BaseMethodFault) {
f := Map.getEntityParent(s, "Folder").(*Folder)
f.removeChild(s.Reference())
return nil, nil
})
return &methods.Destroy_TaskBody{
Res: &types.Destroy_TaskResponse{
Returnval: task.Run(),
},
}
}
func (s *DistributedVirtualSwitch) dvPortgroups(_ *types.DistributedVirtualSwitchPortCriteria) []types.DistributedVirtualPort {
// TODO(agui): Filter is not implemented yet
var res []types.DistributedVirtualPort
for _, ref := range s.Portgroup {
pg := Map.Get(ref).(*DistributedVirtualPortgroup)
res = append(res, types.DistributedVirtualPort{
DvsUuid: s.Uuid,
Key: pg.Key,
Config: types.DVPortConfigInfo{
Setting: pg.Config.DefaultPortConfig,
},
})
if pg.PortKeys == nil {
continue
}
for _, key := range pg.PortKeys {
res = append(res, types.DistributedVirtualPort{
DvsUuid: s.Uuid,
Key: key,
Config: types.DVPortConfigInfo{
Setting: pg.Config.DefaultPortConfig,
},
})
}
}
return res
}

46
vendor/github.com/vmware/govmomi/simulator/entity.go generated vendored Normal file
View File

@ -0,0 +1,46 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
func RenameTask(e mo.Entity, r *types.Rename_Task) soap.HasFault {
task := CreateTask(e, "rename", func(t *Task) (types.AnyType, types.BaseMethodFault) {
obj := Map.Get(r.This).(mo.Entity).Entity()
if parent, ok := Map.Get(*obj.Parent).(*Folder); ok {
if Map.FindByName(r.NewName, parent.ChildEntity) != nil {
return nil, &types.InvalidArgument{InvalidProperty: "name"}
}
}
obj.Name = r.NewName
return nil, nil
})
return &methods.Rename_TaskBody{
Res: &types.Rename_TaskResponse{
Returnval: task.Run(),
},
}
}

41
vendor/github.com/vmware/govmomi/simulator/esx/BUILD generated vendored Normal file
View File

@ -0,0 +1,41 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"authorization_manager.go",
"datacenter.go",
"doc.go",
"host_config_info.go",
"host_firewall_system.go",
"host_hardware_info.go",
"host_storage_device_info.go",
"host_system.go",
"performance_manager.go",
"resource_pool.go",
"root_folder.go",
"service_content.go",
"setting.go",
"virtual_device.go",
],
importpath = "github.com/vmware/govmomi/simulator/esx",
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"],
)

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,60 @@
/*
Copyright (c) 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 esx
import (
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// Datacenter is the default template for Datacenter properties.
// Capture method:
// govc datacenter.info -dump
var Datacenter = mo.Datacenter{
ManagedEntity: mo.ManagedEntity{
ExtensibleManagedObject: mo.ExtensibleManagedObject{
Self: types.ManagedObjectReference{Type: "Datacenter", Value: "ha-datacenter"},
Value: nil,
AvailableField: nil,
},
Parent: (*types.ManagedObjectReference)(nil),
CustomValue: nil,
OverallStatus: "",
ConfigStatus: "",
ConfigIssue: nil,
EffectiveRole: nil,
Permission: nil,
Name: "ha-datacenter",
DisabledMethod: nil,
RecentTask: nil,
DeclaredAlarmState: nil,
TriggeredAlarmState: nil,
AlarmActionsEnabled: (*bool)(nil),
Tag: nil,
},
VmFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-vm"},
HostFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-host"},
DatastoreFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-datastore"},
NetworkFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-network"},
Datastore: []types.ManagedObjectReference{
{Type: "Datastore", Value: "57089c25-85e3ccd4-17b6-000c29d0beb3"},
},
Network: []types.ManagedObjectReference{
{Type: "Network", Value: "HaNetwork-VM Network"},
},
Configuration: types.DatacenterConfigInfo{},
}

20
vendor/github.com/vmware/govmomi/simulator/esx/doc.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
/*
Copyright (c) 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 esx contains SOAP responses from an ESX server, captured using `govc ... -dump`.
*/
package esx

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,864 @@
/*
Copyright (c) 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 esx
import (
"time"
"github.com/vmware/govmomi/vim25/types"
)
// HostHardwareInfo is the default template for the HostSystem hardware property.
// Capture method:
// govc object.collect -s -dump HostSystem:ha-host hardware
var HostHardwareInfo = &types.HostHardwareInfo{
SystemInfo: types.HostSystemInfo{
Vendor: "VMware, Inc.",
Model: "VMware Virtual Platform",
Uuid: "e88d4d56-9f1e-3ea1-71fa-13a8e1a7fd70",
OtherIdentifyingInfo: []types.HostSystemIdentificationInfo{
{
IdentifierValue: " No Asset Tag",
IdentifierType: &types.ElementDescription{
Description: types.Description{
Label: "Asset Tag",
Summary: "Asset tag of the system",
},
Key: "AssetTag",
},
},
{
IdentifierValue: "[MS_VM_CERT/SHA1/27d66596a61c48dd3dc7216fd715126e33f59ae7]",
IdentifierType: &types.ElementDescription{
Description: types.Description{
Label: "OEM specific string",
Summary: "OEM specific string",
},
Key: "OemSpecificString",
},
},
{
IdentifierValue: "Welcome to the Virtual Machine",
IdentifierType: &types.ElementDescription{
Description: types.Description{
Label: "OEM specific string",
Summary: "OEM specific string",
},
Key: "OemSpecificString",
},
},
{
IdentifierValue: "VMware-56 4d 8d e8 1e 9f a1 3e-71 fa 13 a8 e1 a7 fd 70",
IdentifierType: &types.ElementDescription{
Description: types.Description{
Label: "Service tag",
Summary: "Service tag of the system",
},
Key: "ServiceTag",
},
},
},
},
CpuPowerManagementInfo: &types.HostCpuPowerManagementInfo{
CurrentPolicy: "Balanced",
HardwareSupport: "",
},
CpuInfo: types.HostCpuInfo{
NumCpuPackages: 2,
NumCpuCores: 2,
NumCpuThreads: 2,
Hz: 3591345000,
},
CpuPkg: []types.HostCpuPackage{
{
Index: 0,
Vendor: "intel",
Hz: 3591345000,
BusHz: 115849838,
Description: "Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz",
ThreadId: []int16{0},
CpuFeature: []types.HostCpuIdInfo{
{
Level: 0,
Vendor: "",
Eax: "0000:0000:0000:0000:0000:0000:0000:1101",
Ebx: "0111:0101:0110:1110:0110:0101:0100:0111",
Ecx: "0110:1100:0110:0101:0111:0100:0110:1110",
Edx: "0100:1001:0110:0101:0110:1110:0110:1001",
},
{
Level: 1,
Vendor: "",
Eax: "0000:0000:0000:0010:0000:0110:1101:0111",
Ebx: "0000:0000:0000:0001:0000:1000:0000:0000",
Ecx: "1001:0111:1011:1010:0010:0010:0010:1011",
Edx: "0000:1111:1010:1011:1111:1011:1111:1111",
},
{
Level: -2147483648,
Vendor: "",
Eax: "1000:0000:0000:0000:0000:0000:0000:1000",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0000",
Edx: "0000:0000:0000:0000:0000:0000:0000:0000",
},
{
Level: -2147483647,
Vendor: "",
Eax: "0000:0000:0000:0000:0000:0000:0000:0000",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0001",
Edx: "0010:1000:0001:0000:0000:1000:0000:0000",
},
{
Level: -2147483640,
Vendor: "",
Eax: "0000:0000:0000:0000:0011:0000:0010:1010",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0000",
Edx: "0000:0000:0000:0000:0000:0000:0000:0000",
},
},
},
{
Index: 1,
Vendor: "intel",
Hz: 3591345000,
BusHz: 115849838,
Description: "Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz",
ThreadId: []int16{1},
CpuFeature: []types.HostCpuIdInfo{
{
Level: 0,
Vendor: "",
Eax: "0000:0000:0000:0000:0000:0000:0000:1101",
Ebx: "0111:0101:0110:1110:0110:0101:0100:0111",
Ecx: "0110:1100:0110:0101:0111:0100:0110:1110",
Edx: "0100:1001:0110:0101:0110:1110:0110:1001",
},
{
Level: 1,
Vendor: "",
Eax: "0000:0000:0000:0010:0000:0110:1101:0111",
Ebx: "0000:0010:0000:0001:0000:1000:0000:0000",
Ecx: "1001:0111:1011:1010:0010:0010:0010:1011",
Edx: "0000:1111:1010:1011:1111:1011:1111:1111",
},
{
Level: -2147483648,
Vendor: "",
Eax: "1000:0000:0000:0000:0000:0000:0000:1000",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0000",
Edx: "0000:0000:0000:0000:0000:0000:0000:0000",
},
{
Level: -2147483647,
Vendor: "",
Eax: "0000:0000:0000:0000:0000:0000:0000:0000",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0001",
Edx: "0010:1000:0001:0000:0000:1000:0000:0000",
},
{
Level: -2147483640,
Vendor: "",
Eax: "0000:0000:0000:0000:0011:0000:0010:1010",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0000",
Edx: "0000:0000:0000:0000:0000:0000:0000:0000",
},
},
},
},
MemorySize: 4294430720,
NumaInfo: &types.HostNumaInfo{
Type: "NUMA",
NumNodes: 1,
NumaNode: []types.HostNumaNode{
{
TypeId: 0x0,
CpuID: []int16{1, 0},
MemoryRangeBegin: 4294967296,
MemoryRangeLength: 1073741824,
},
},
},
SmcPresent: types.NewBool(false),
PciDevice: []types.HostPciDevice{
{
Id: "0000:00:00.0",
ClassId: 1536,
Bus: 0x0,
Slot: 0x0,
Function: 0x0,
VendorId: -32634,
SubVendorId: 5549,
VendorName: "Intel Corporation",
DeviceId: 29072,
SubDeviceId: 6518,
ParentBridge: "",
DeviceName: "Virtual Machine Chipset",
},
{
Id: "0000:00:01.0",
ClassId: 1540,
Bus: 0x0,
Slot: 0x1,
Function: 0x0,
VendorId: -32634,
SubVendorId: 0,
VendorName: "Intel Corporation",
DeviceId: 29073,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "440BX/ZX/DX - 82443BX/ZX/DX AGP bridge",
},
{
Id: "0000:00:07.0",
ClassId: 1537,
Bus: 0x0,
Slot: 0x7,
Function: 0x0,
VendorId: -32634,
SubVendorId: 5549,
VendorName: "Intel Corporation",
DeviceId: 28944,
SubDeviceId: 6518,
ParentBridge: "",
DeviceName: "Virtual Machine Chipset",
},
{
Id: "0000:00:07.1",
ClassId: 257,
Bus: 0x0,
Slot: 0x7,
Function: 0x1,
VendorId: -32634,
SubVendorId: 5549,
VendorName: "Intel Corporation",
DeviceId: 28945,
SubDeviceId: 6518,
ParentBridge: "",
DeviceName: "PIIX4 for 430TX/440BX/MX IDE Controller",
},
{
Id: "0000:00:07.3",
ClassId: 1664,
Bus: 0x0,
Slot: 0x7,
Function: 0x3,
VendorId: -32634,
SubVendorId: 5549,
VendorName: "Intel Corporation",
DeviceId: 28947,
SubDeviceId: 6518,
ParentBridge: "",
DeviceName: "Virtual Machine Chipset",
},
{
Id: "0000:00:07.7",
ClassId: 2176,
Bus: 0x0,
Slot: 0x7,
Function: 0x7,
VendorId: 5549,
SubVendorId: 5549,
VendorName: "VMware",
DeviceId: 1856,
SubDeviceId: 1856,
ParentBridge: "",
DeviceName: "Virtual Machine Communication Interface",
},
{
Id: "0000:00:0f.0",
ClassId: 768,
Bus: 0x0,
Slot: 0xf,
Function: 0x0,
VendorId: 5549,
SubVendorId: 5549,
VendorName: "VMware",
DeviceId: 1029,
SubDeviceId: 1029,
ParentBridge: "",
DeviceName: "SVGA II Adapter",
},
{
Id: "0000:00:11.0",
ClassId: 1540,
Bus: 0x0,
Slot: 0x11,
Function: 0x0,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1936,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI bridge",
},
{
Id: "0000:00:15.0",
ClassId: 1540,
Bus: 0x0,
Slot: 0x15,
Function: 0x0,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:15.1",
ClassId: 1540,
Bus: 0x0,
Slot: 0x15,
Function: 0x1,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:15.2",
ClassId: 1540,
Bus: 0x0,
Slot: 0x15,
Function: 0x2,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:15.3",
ClassId: 1540,
Bus: 0x0,
Slot: 0x15,
Function: 0x3,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:15.4",
ClassId: 1540,
Bus: 0x0,
Slot: 0x15,
Function: 0x4,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:15.5",
ClassId: 1540,
Bus: 0x0,
Slot: 0x15,
Function: 0x5,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:15.6",
ClassId: 1540,
Bus: 0x0,
Slot: 0x15,
Function: 0x6,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:15.7",
ClassId: 1540,
Bus: 0x0,
Slot: 0x15,
Function: 0x7,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:16.0",
ClassId: 1540,
Bus: 0x0,
Slot: 0x16,
Function: 0x0,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:16.1",
ClassId: 1540,
Bus: 0x0,
Slot: 0x16,
Function: 0x1,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:16.2",
ClassId: 1540,
Bus: 0x0,
Slot: 0x16,
Function: 0x2,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:16.3",
ClassId: 1540,
Bus: 0x0,
Slot: 0x16,
Function: 0x3,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:16.4",
ClassId: 1540,
Bus: 0x0,
Slot: 0x16,
Function: 0x4,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:16.5",
ClassId: 1540,
Bus: 0x0,
Slot: 0x16,
Function: 0x5,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:16.6",
ClassId: 1540,
Bus: 0x0,
Slot: 0x16,
Function: 0x6,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:16.7",
ClassId: 1540,
Bus: 0x0,
Slot: 0x16,
Function: 0x7,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:17.0",
ClassId: 1540,
Bus: 0x0,
Slot: 0x17,
Function: 0x0,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:17.1",
ClassId: 1540,
Bus: 0x0,
Slot: 0x17,
Function: 0x1,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:17.2",
ClassId: 1540,
Bus: 0x0,
Slot: 0x17,
Function: 0x2,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:17.3",
ClassId: 1540,
Bus: 0x0,
Slot: 0x17,
Function: 0x3,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:17.4",
ClassId: 1540,
Bus: 0x0,
Slot: 0x17,
Function: 0x4,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:17.5",
ClassId: 1540,
Bus: 0x0,
Slot: 0x17,
Function: 0x5,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:17.6",
ClassId: 1540,
Bus: 0x0,
Slot: 0x17,
Function: 0x6,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:17.7",
ClassId: 1540,
Bus: 0x0,
Slot: 0x17,
Function: 0x7,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:18.0",
ClassId: 1540,
Bus: 0x0,
Slot: 0x18,
Function: 0x0,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:18.1",
ClassId: 1540,
Bus: 0x0,
Slot: 0x18,
Function: 0x1,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:18.2",
ClassId: 1540,
Bus: 0x0,
Slot: 0x18,
Function: 0x2,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:18.3",
ClassId: 1540,
Bus: 0x0,
Slot: 0x18,
Function: 0x3,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:18.4",
ClassId: 1540,
Bus: 0x0,
Slot: 0x18,
Function: 0x4,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:18.5",
ClassId: 1540,
Bus: 0x0,
Slot: 0x18,
Function: 0x5,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:18.6",
ClassId: 1540,
Bus: 0x0,
Slot: 0x18,
Function: 0x6,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:00:18.7",
ClassId: 1540,
Bus: 0x0,
Slot: 0x18,
Function: 0x7,
VendorId: 5549,
SubVendorId: 0,
VendorName: "VMware",
DeviceId: 1952,
SubDeviceId: 0,
ParentBridge: "",
DeviceName: "PCI Express Root Port",
},
{
Id: "0000:03:00.0",
ClassId: 263,
Bus: 0x3,
Slot: 0x0,
Function: 0x0,
VendorId: 5549,
SubVendorId: 5549,
VendorName: "VMware",
DeviceId: 1984,
SubDeviceId: 1984,
ParentBridge: "0000:00:15.0",
DeviceName: "PVSCSI SCSI Controller",
},
{
Id: "0000:0b:00.0",
ClassId: 512,
Bus: 0xb,
Slot: 0x0,
Function: 0x0,
VendorId: 5549,
SubVendorId: 5549,
VendorName: "VMware Inc.",
DeviceId: 1968,
SubDeviceId: 1968,
ParentBridge: "0000:00:16.0",
DeviceName: "vmxnet3 Virtual Ethernet Controller",
},
{
Id: "0000:13:00.0",
ClassId: 512,
Bus: 0x13,
Slot: 0x0,
Function: 0x0,
VendorId: 5549,
SubVendorId: 5549,
VendorName: "VMware Inc.",
DeviceId: 1968,
SubDeviceId: 1968,
ParentBridge: "0000:00:17.0",
DeviceName: "vmxnet3 Virtual Ethernet Controller",
},
},
CpuFeature: []types.HostCpuIdInfo{
{
Level: 0,
Vendor: "",
Eax: "0000:0000:0000:0000:0000:0000:0000:1101",
Ebx: "0111:0101:0110:1110:0110:0101:0100:0111",
Ecx: "0110:1100:0110:0101:0111:0100:0110:1110",
Edx: "0100:1001:0110:0101:0110:1110:0110:1001",
},
{
Level: 1,
Vendor: "",
Eax: "0000:0000:0000:0010:0000:0110:1101:0111",
Ebx: "0000:0000:0000:0001:0000:1000:0000:0000",
Ecx: "1001:0111:1011:1010:0010:0010:0010:1011",
Edx: "0000:1111:1010:1011:1111:1011:1111:1111",
},
{
Level: -2147483648,
Vendor: "",
Eax: "1000:0000:0000:0000:0000:0000:0000:1000",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0000",
Edx: "0000:0000:0000:0000:0000:0000:0000:0000",
},
{
Level: -2147483647,
Vendor: "",
Eax: "0000:0000:0000:0000:0000:0000:0000:0000",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0001",
Edx: "0010:1000:0001:0000:0000:1000:0000:0000",
},
{
Level: -2147483640,
Vendor: "",
Eax: "0000:0000:0000:0000:0011:0000:0010:1010",
Ebx: "0000:0000:0000:0000:0000:0000:0000:0000",
Ecx: "0000:0000:0000:0000:0000:0000:0000:0000",
Edx: "0000:0000:0000:0000:0000:0000:0000:0000",
},
},
BiosInfo: &types.HostBIOSInfo{
BiosVersion: "6.00",
ReleaseDate: nil,
Vendor: "",
MajorRelease: 0,
MinorRelease: 0,
FirmwareMajorRelease: 0,
FirmwareMinorRelease: 0,
},
ReliableMemoryInfo: &types.HostReliableMemoryInfo{},
}
func init() {
date, _ := time.Parse("2006-01-02", "2015-07-02")
HostHardwareInfo.BiosInfo.ReleaseDate = &date
}

View File

@ -0,0 +1,346 @@
/*
Copyright (c) 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 esx
import "github.com/vmware/govmomi/vim25/types"
// HostStorageDeviceInfo is the default template for the HostSystem config.storageDevice property.
// Capture method:
// govc object.collect -s -dump HostSystem:ha-host config.storageDevice
var HostStorageDeviceInfo = types.HostStorageDeviceInfo{
HostBusAdapter: []types.BaseHostHostBusAdapter{
&types.HostParallelScsiHba{
HostHostBusAdapter: types.HostHostBusAdapter{
Key: "key-vim.host.ParallelScsiHba-vmhba0",
Device: "vmhba0",
Bus: 3,
Status: "unknown",
Model: "PVSCSI SCSI Controller",
Driver: "pvscsi",
Pci: "0000:03:00.0",
},
},
&types.HostBlockHba{
HostHostBusAdapter: types.HostHostBusAdapter{
Key: "key-vim.host.BlockHba-vmhba1",
Device: "vmhba1",
Bus: 0,
Status: "unknown",
Model: "PIIX4 for 430TX/440BX/MX IDE Controller",
Driver: "vmkata",
Pci: "0000:00:07.1",
},
},
&types.HostBlockHba{
HostHostBusAdapter: types.HostHostBusAdapter{
Key: "key-vim.host.BlockHba-vmhba64",
Device: "vmhba64",
Bus: 0,
Status: "unknown",
Model: "PIIX4 for 430TX/440BX/MX IDE Controller",
Driver: "vmkata",
Pci: "0000:00:07.1",
},
},
},
ScsiLun: []types.BaseScsiLun{
&types.ScsiLun{
HostDevice: types.HostDevice{
DeviceName: "/vmfs/devices/cdrom/mpx.vmhba1:C0:T0:L0",
DeviceType: "cdrom",
},
Key: "key-vim.host.ScsiLun-0005000000766d686261313a303a30",
Uuid: "0005000000766d686261313a303a30",
Descriptor: []types.ScsiLunDescriptor{
{
Quality: "lowQuality",
Id: "mpx.vmhba1:C0:T0:L0",
},
{
Quality: "lowQuality",
Id: "vml.0005000000766d686261313a303a30",
},
{
Quality: "lowQuality",
Id: "0005000000766d686261313a303a30",
},
},
CanonicalName: "mpx.vmhba1:C0:T0:L0",
DisplayName: "Local NECVMWar CD-ROM (mpx.vmhba1:C0:T0:L0)",
LunType: "cdrom",
Vendor: "NECVMWar",
Model: "VMware IDE CDR00",
Revision: "1.00",
ScsiLevel: 5,
SerialNumber: "unavailable",
DurableName: (*types.ScsiLunDurableName)(nil),
AlternateName: []types.ScsiLunDurableName{
{
Namespace: "GENERIC_VPD",
NamespaceId: 0x5,
Data: []uint8{0x2d, 0x37, 0x39},
},
{
Namespace: "GENERIC_VPD",
NamespaceId: 0x5,
Data: []uint8{0x30},
},
},
StandardInquiry: []uint8{0x30},
QueueDepth: 0,
OperationalState: []string{"ok"},
Capabilities: &types.ScsiLunCapabilities{},
VStorageSupport: "vStorageUnsupported",
ProtocolEndpoint: types.NewBool(false),
},
&types.HostScsiDisk{
ScsiLun: types.ScsiLun{
HostDevice: types.HostDevice{
DeviceName: "/vmfs/devices/disks/mpx.vmhba0:C0:T0:L0",
DeviceType: "disk",
},
Key: "key-vim.host.ScsiDisk-0000000000766d686261303a303a30",
Uuid: "0000000000766d686261303a303a30",
Descriptor: []types.ScsiLunDescriptor{
{
Quality: "lowQuality",
Id: "mpx.vmhba0:C0:T0:L0",
},
{
Quality: "lowQuality",
Id: "vml.0000000000766d686261303a303a30",
},
{
Quality: "lowQuality",
Id: "0000000000766d686261303a303a30",
},
},
CanonicalName: "mpx.vmhba0:C0:T0:L0",
DisplayName: "Local VMware, Disk (mpx.vmhba0:C0:T0:L0)",
LunType: "disk",
Vendor: "VMware, ",
Model: "VMware Virtual S",
Revision: "1.0 ",
ScsiLevel: 2,
SerialNumber: "unavailable",
DurableName: (*types.ScsiLunDurableName)(nil),
AlternateName: []types.ScsiLunDurableName{
{
Namespace: "GENERIC_VPD",
NamespaceId: 0x5,
Data: []uint8{0x2d, 0x37, 0x39},
},
{
Namespace: "GENERIC_VPD",
NamespaceId: 0x5,
Data: []uint8{0x30},
},
},
StandardInquiry: []uint8{0x30},
QueueDepth: 1024,
OperationalState: []string{"ok"},
Capabilities: &types.ScsiLunCapabilities{},
VStorageSupport: "vStorageUnsupported",
ProtocolEndpoint: types.NewBool(false),
},
Capacity: types.HostDiskDimensionsLba{
BlockSize: 512,
Block: 67108864,
},
DevicePath: "/vmfs/devices/disks/mpx.vmhba0:C0:T0:L0",
Ssd: types.NewBool(true),
LocalDisk: types.NewBool(true),
PhysicalLocation: nil,
EmulatedDIXDIFEnabled: types.NewBool(false),
VsanDiskInfo: (*types.VsanHostVsanDiskInfo)(nil),
ScsiDiskType: "native512",
},
},
ScsiTopology: &types.HostScsiTopology{
Adapter: []types.HostScsiTopologyInterface{
{
Key: "key-vim.host.ScsiTopology.Interface-vmhba0",
Adapter: "key-vim.host.ParallelScsiHba-vmhba0",
Target: []types.HostScsiTopologyTarget{
{
Key: "key-vim.host.ScsiTopology.Target-vmhba0:0:0",
Target: 0,
Lun: []types.HostScsiTopologyLun{
{
Key: "key-vim.host.ScsiTopology.Lun-0000000000766d686261303a303a30",
Lun: 0,
ScsiLun: "key-vim.host.ScsiDisk-0000000000766d686261303a303a30",
},
},
Transport: &types.HostParallelScsiTargetTransport{},
},
},
},
{
Key: "key-vim.host.ScsiTopology.Interface-vmhba1",
Adapter: "key-vim.host.BlockHba-vmhba1",
Target: []types.HostScsiTopologyTarget{
{
Key: "key-vim.host.ScsiTopology.Target-vmhba1:0:0",
Target: 0,
Lun: []types.HostScsiTopologyLun{
{
Key: "key-vim.host.ScsiTopology.Lun-0005000000766d686261313a303a30",
Lun: 0,
ScsiLun: "key-vim.host.ScsiLun-0005000000766d686261313a303a30",
},
},
Transport: &types.HostBlockAdapterTargetTransport{},
},
},
},
{
Key: "key-vim.host.ScsiTopology.Interface-vmhba64",
Adapter: "key-vim.host.BlockHba-vmhba64",
Target: nil,
},
},
},
MultipathInfo: &types.HostMultipathInfo{
Lun: []types.HostMultipathInfoLogicalUnit{
{
Key: "key-vim.host.MultipathInfo.LogicalUnit-0005000000766d686261313a303a30",
Id: "0005000000766d686261313a303a30",
Lun: "key-vim.host.ScsiLun-0005000000766d686261313a303a30",
Path: []types.HostMultipathInfoPath{
{
Key: "key-vim.host.MultipathInfo.Path-vmhba1:C0:T0:L0",
Name: "vmhba1:C0:T0:L0",
PathState: "active",
State: "active",
IsWorkingPath: types.NewBool(true),
Adapter: "key-vim.host.BlockHba-vmhba1",
Lun: "key-vim.host.MultipathInfo.LogicalUnit-0005000000766d686261313a303a30",
Transport: &types.HostBlockAdapterTargetTransport{},
},
},
Policy: &types.HostMultipathInfoFixedLogicalUnitPolicy{
HostMultipathInfoLogicalUnitPolicy: types.HostMultipathInfoLogicalUnitPolicy{
Policy: "VMW_PSP_FIXED",
},
Prefer: "vmhba1:C0:T0:L0",
},
StorageArrayTypePolicy: &types.HostMultipathInfoLogicalUnitStorageArrayTypePolicy{
Policy: "VMW_SATP_LOCAL",
},
},
{
Key: "key-vim.host.MultipathInfo.LogicalUnit-0000000000766d686261303a303a30",
Id: "0000000000766d686261303a303a30",
Lun: "key-vim.host.ScsiDisk-0000000000766d686261303a303a30",
Path: []types.HostMultipathInfoPath{
{
Key: "key-vim.host.MultipathInfo.Path-vmhba0:C0:T0:L0",
Name: "vmhba0:C0:T0:L0",
PathState: "active",
State: "active",
IsWorkingPath: types.NewBool(true),
Adapter: "key-vim.host.ParallelScsiHba-vmhba0",
Lun: "key-vim.host.MultipathInfo.LogicalUnit-0000000000766d686261303a303a30",
Transport: &types.HostParallelScsiTargetTransport{},
},
},
Policy: &types.HostMultipathInfoFixedLogicalUnitPolicy{
HostMultipathInfoLogicalUnitPolicy: types.HostMultipathInfoLogicalUnitPolicy{
Policy: "VMW_PSP_FIXED",
},
Prefer: "vmhba0:C0:T0:L0",
},
StorageArrayTypePolicy: &types.HostMultipathInfoLogicalUnitStorageArrayTypePolicy{
Policy: "VMW_SATP_LOCAL",
},
},
},
},
PlugStoreTopology: &types.HostPlugStoreTopology{
Adapter: []types.HostPlugStoreTopologyAdapter{
{
Key: "key-vim.host.PlugStoreTopology.Adapter-vmhba0",
Adapter: "key-vim.host.ParallelScsiHba-vmhba0",
Path: []string{"key-vim.host.PlugStoreTopology.Path-vmhba0:C0:T0:L0"},
},
{
Key: "key-vim.host.PlugStoreTopology.Adapter-vmhba1",
Adapter: "key-vim.host.BlockHba-vmhba1",
Path: []string{"key-vim.host.PlugStoreTopology.Path-vmhba1:C0:T0:L0"},
},
{
Key: "key-vim.host.PlugStoreTopology.Adapter-vmhba64",
Adapter: "key-vim.host.BlockHba-vmhba64",
Path: nil,
},
},
Path: []types.HostPlugStoreTopologyPath{
{
Key: "key-vim.host.PlugStoreTopology.Path-vmhba0:C0:T0:L0",
Name: "vmhba0:C0:T0:L0",
ChannelNumber: 0,
TargetNumber: 0,
LunNumber: 0,
Adapter: "key-vim.host.PlugStoreTopology.Adapter-vmhba0",
Target: "key-vim.host.PlugStoreTopology.Target-pscsi.0:0",
Device: "key-vim.host.PlugStoreTopology.Device-0000000000766d686261303a303a30",
},
{
Key: "key-vim.host.PlugStoreTopology.Path-vmhba1:C0:T0:L0",
Name: "vmhba1:C0:T0:L0",
ChannelNumber: 0,
TargetNumber: 0,
LunNumber: 0,
Adapter: "key-vim.host.PlugStoreTopology.Adapter-vmhba1",
Target: "key-vim.host.PlugStoreTopology.Target-ide.0:0",
Device: "key-vim.host.PlugStoreTopology.Device-0005000000766d686261313a303a30",
},
},
Target: []types.HostPlugStoreTopologyTarget{
{
Key: "key-vim.host.PlugStoreTopology.Target-pscsi.0:0",
Transport: &types.HostParallelScsiTargetTransport{},
},
{
Key: "key-vim.host.PlugStoreTopology.Target-ide.0:0",
Transport: &types.HostBlockAdapterTargetTransport{},
},
},
Device: []types.HostPlugStoreTopologyDevice{
{
Key: "key-vim.host.PlugStoreTopology.Device-0005000000766d686261313a303a30",
Lun: "key-vim.host.ScsiLun-0005000000766d686261313a303a30",
Path: []string{"key-vim.host.PlugStoreTopology.Path-vmhba1:C0:T0:L0"},
},
{
Key: "key-vim.host.PlugStoreTopology.Device-0000000000766d686261303a303a30",
Lun: "key-vim.host.ScsiDisk-0000000000766d686261303a303a30",
Path: []string{"key-vim.host.PlugStoreTopology.Path-vmhba0:C0:T0:L0"},
},
},
Plugin: []types.HostPlugStoreTopologyPlugin{
{
Key: "key-vim.host.PlugStoreTopology.Plugin-NMP",
Name: "NMP",
Device: []string{"key-vim.host.PlugStoreTopology.Device-0005000000766d686261313a303a30", "key-vim.host.PlugStoreTopology.Device-0000000000766d686261303a303a30"},
ClaimedPath: []string{"key-vim.host.PlugStoreTopology.Path-vmhba0:C0:T0:L0", "key-vim.host.PlugStoreTopology.Path-vmhba1:C0:T0:L0"},
},
},
},
SoftwareInternetScsiEnabled: false,
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,165 @@
/*
Copyright (c) 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 esx
import (
"time"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// ResourcePool is the default template for ResourcePool properties.
// Capture method:
// govc pool.info "*" -dump
var ResourcePool = mo.ResourcePool{
ManagedEntity: mo.ManagedEntity{
ExtensibleManagedObject: mo.ExtensibleManagedObject{
Self: types.ManagedObjectReference{Type: "ResourcePool", Value: "ha-root-pool"},
Value: nil,
AvailableField: nil,
},
Parent: &types.ManagedObjectReference{Type: "ComputeResource", Value: "ha-compute-res"},
CustomValue: nil,
OverallStatus: "green",
ConfigStatus: "green",
ConfigIssue: nil,
EffectiveRole: []int32{-1},
Permission: nil,
Name: "Resources",
DisabledMethod: []string{"CreateVApp", "CreateChildVM_Task"},
RecentTask: nil,
DeclaredAlarmState: nil,
TriggeredAlarmState: nil,
AlarmActionsEnabled: (*bool)(nil),
Tag: nil,
},
Summary: &types.ResourcePoolSummary{
DynamicData: types.DynamicData{},
Name: "Resources",
Config: types.ResourceConfigSpec{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "ResourcePool", Value: "ha-root-pool"},
ChangeVersion: "",
LastModified: (*time.Time)(nil),
CpuAllocation: types.ResourceAllocationInfo{
DynamicData: types.DynamicData{},
Reservation: types.NewInt64(4121),
ExpandableReservation: types.NewBool(false),
Limit: types.NewInt64(4121),
Shares: &types.SharesInfo{
DynamicData: types.DynamicData{},
Shares: 9000,
Level: "custom",
},
OverheadLimit: nil,
},
MemoryAllocation: types.ResourceAllocationInfo{
DynamicData: types.DynamicData{},
Reservation: types.NewInt64(961),
ExpandableReservation: types.NewBool(false),
Limit: types.NewInt64(961),
Shares: &types.SharesInfo{
DynamicData: types.DynamicData{},
Shares: 9000,
Level: "custom",
},
OverheadLimit: nil,
},
},
Runtime: types.ResourcePoolRuntimeInfo{
DynamicData: types.DynamicData{},
Memory: types.ResourcePoolResourceUsage{
DynamicData: types.DynamicData{},
ReservationUsed: 0,
ReservationUsedForVm: 0,
UnreservedForPool: 1007681536,
UnreservedForVm: 1007681536,
OverallUsage: 0,
MaxUsage: 1007681536,
},
Cpu: types.ResourcePoolResourceUsage{
DynamicData: types.DynamicData{},
ReservationUsed: 0,
ReservationUsedForVm: 0,
UnreservedForPool: 4121,
UnreservedForVm: 4121,
OverallUsage: 0,
MaxUsage: 4121,
},
OverallStatus: "green",
},
QuickStats: (*types.ResourcePoolQuickStats)(nil),
ConfiguredMemoryMB: 0,
},
Runtime: types.ResourcePoolRuntimeInfo{
DynamicData: types.DynamicData{},
Memory: types.ResourcePoolResourceUsage{
DynamicData: types.DynamicData{},
ReservationUsed: 0,
ReservationUsedForVm: 0,
UnreservedForPool: 1007681536,
UnreservedForVm: 1007681536,
OverallUsage: 0,
MaxUsage: 1007681536,
},
Cpu: types.ResourcePoolResourceUsage{
DynamicData: types.DynamicData{},
ReservationUsed: 0,
ReservationUsedForVm: 0,
UnreservedForPool: 4121,
UnreservedForVm: 4121,
OverallUsage: 0,
MaxUsage: 4121,
},
OverallStatus: "green",
},
Owner: types.ManagedObjectReference{Type: "ComputeResource", Value: "ha-compute-res"},
ResourcePool: nil,
Vm: nil,
Config: types.ResourceConfigSpec{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "ResourcePool", Value: "ha-root-pool"},
ChangeVersion: "",
LastModified: (*time.Time)(nil),
CpuAllocation: types.ResourceAllocationInfo{
DynamicData: types.DynamicData{},
Reservation: types.NewInt64(4121),
ExpandableReservation: types.NewBool(false),
Limit: types.NewInt64(4121),
Shares: &types.SharesInfo{
DynamicData: types.DynamicData{},
Shares: 9000,
Level: "custom",
},
OverheadLimit: nil,
},
MemoryAllocation: types.ResourceAllocationInfo{
DynamicData: types.DynamicData{},
Reservation: types.NewInt64(961),
ExpandableReservation: types.NewBool(false),
Limit: types.NewInt64(961),
Shares: &types.SharesInfo{
DynamicData: types.DynamicData{},
Shares: 9000,
Level: "custom",
},
OverheadLimit: nil,
},
},
ChildConfiguration: nil,
}

View File

@ -0,0 +1,76 @@
/*
Copyright (c) 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 esx
import (
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// RootFolder is the default template for the ServiceContent rootFolder property.
// Capture method:
// govc folder.info -dump /
var RootFolder = mo.Folder{
ManagedEntity: mo.ManagedEntity{
ExtensibleManagedObject: mo.ExtensibleManagedObject{
Self: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
Value: nil,
AvailableField: nil,
},
Parent: (*types.ManagedObjectReference)(nil),
CustomValue: nil,
OverallStatus: "green",
ConfigStatus: "green",
ConfigIssue: nil,
EffectiveRole: []int32{-1},
Permission: []types.Permission{
{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
Principal: "vpxuser",
Group: false,
RoleId: -1,
Propagate: true,
},
{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
Principal: "dcui",
Group: false,
RoleId: -1,
Propagate: true,
},
{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
Principal: "root",
Group: false,
RoleId: -1,
Propagate: true,
},
},
Name: "ha-folder-root",
DisabledMethod: nil,
RecentTask: nil,
DeclaredAlarmState: nil,
TriggeredAlarmState: nil,
AlarmActionsEnabled: (*bool)(nil),
Tag: nil,
},
ChildType: []string{"Datacenter"},
ChildEntity: nil,
}

View File

@ -0,0 +1,86 @@
/*
Copyright (c) 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 esx
import "github.com/vmware/govmomi/vim25/types"
// ServiceContent is the default template for the ServiceInstance content property.
// Capture method:
// govc object.collect -s -dump - content
var ServiceContent = types.ServiceContent{
RootFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
PropertyCollector: types.ManagedObjectReference{Type: "PropertyCollector", Value: "ha-property-collector"},
ViewManager: &types.ManagedObjectReference{Type: "ViewManager", Value: "ViewManager"},
About: types.AboutInfo{
Name: "VMware ESXi",
FullName: "VMware ESXi 6.5.0 build-5969303",
Vendor: "VMware, Inc.",
Version: "6.5.0",
Build: "5969303",
LocaleVersion: "INTL",
LocaleBuild: "000",
OsType: "vmnix-x86",
ProductLineId: "embeddedEsx",
ApiType: "HostAgent",
ApiVersion: "6.5",
InstanceUuid: "",
LicenseProductName: "VMware ESX Server",
LicenseProductVersion: "6.0",
},
Setting: &types.ManagedObjectReference{Type: "OptionManager", Value: "HostAgentSettings"},
UserDirectory: &types.ManagedObjectReference{Type: "UserDirectory", Value: "ha-user-directory"},
SessionManager: &types.ManagedObjectReference{Type: "SessionManager", Value: "ha-sessionmgr"},
AuthorizationManager: &types.ManagedObjectReference{Type: "AuthorizationManager", Value: "ha-authmgr"},
ServiceManager: &types.ManagedObjectReference{Type: "ServiceManager", Value: "ha-servicemanager"},
PerfManager: &types.ManagedObjectReference{Type: "PerformanceManager", Value: "ha-perfmgr"},
ScheduledTaskManager: (*types.ManagedObjectReference)(nil),
AlarmManager: (*types.ManagedObjectReference)(nil),
EventManager: &types.ManagedObjectReference{Type: "EventManager", Value: "ha-eventmgr"},
TaskManager: &types.ManagedObjectReference{Type: "TaskManager", Value: "ha-taskmgr"},
ExtensionManager: (*types.ManagedObjectReference)(nil),
CustomizationSpecManager: (*types.ManagedObjectReference)(nil),
CustomFieldsManager: (*types.ManagedObjectReference)(nil),
AccountManager: &types.ManagedObjectReference{Type: "HostLocalAccountManager", Value: "ha-localacctmgr"},
DiagnosticManager: &types.ManagedObjectReference{Type: "DiagnosticManager", Value: "ha-diagnosticmgr"},
LicenseManager: &types.ManagedObjectReference{Type: "LicenseManager", Value: "ha-license-manager"},
SearchIndex: &types.ManagedObjectReference{Type: "SearchIndex", Value: "ha-searchindex"},
FileManager: &types.ManagedObjectReference{Type: "FileManager", Value: "ha-nfc-file-manager"},
DatastoreNamespaceManager: &types.ManagedObjectReference{Type: "DatastoreNamespaceManager", Value: "ha-datastore-namespace-manager"},
VirtualDiskManager: &types.ManagedObjectReference{Type: "VirtualDiskManager", Value: "ha-vdiskmanager"},
VirtualizationManager: (*types.ManagedObjectReference)(nil),
SnmpSystem: (*types.ManagedObjectReference)(nil),
VmProvisioningChecker: (*types.ManagedObjectReference)(nil),
VmCompatibilityChecker: (*types.ManagedObjectReference)(nil),
OvfManager: &types.ManagedObjectReference{Type: "OvfManager", Value: "ha-ovf-manager"},
IpPoolManager: (*types.ManagedObjectReference)(nil),
DvSwitchManager: &types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "ha-dvsmanager"},
HostProfileManager: (*types.ManagedObjectReference)(nil),
ClusterProfileManager: (*types.ManagedObjectReference)(nil),
ComplianceManager: (*types.ManagedObjectReference)(nil),
LocalizationManager: &types.ManagedObjectReference{Type: "LocalizationManager", Value: "ha-l10n-manager"},
StorageResourceManager: &types.ManagedObjectReference{Type: "StorageResourceManager", Value: "ha-storage-resource-manager"},
GuestOperationsManager: &types.ManagedObjectReference{Type: "GuestOperationsManager", Value: "ha-guest-operations-manager"},
OverheadMemoryManager: (*types.ManagedObjectReference)(nil),
CertificateManager: (*types.ManagedObjectReference)(nil),
IoFilterManager: (*types.ManagedObjectReference)(nil),
VStorageObjectManager: &types.ManagedObjectReference{Type: "HostVStorageObjectManager", Value: "ha-vstorage-object-manager"},
HostSpecManager: (*types.ManagedObjectReference)(nil),
CryptoManager: &types.ManagedObjectReference{Type: "CryptoManager", Value: "ha-crypto-manager"},
HealthUpdateManager: (*types.ManagedObjectReference)(nil),
FailoverClusterConfigurator: (*types.ManagedObjectReference)(nil),
FailoverClusterManager: (*types.ManagedObjectReference)(nil),
}

View File

@ -0,0 +1,30 @@
/*
Copyright (c) 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 esx
import "github.com/vmware/govmomi/vim25/types"
// Setting is captured from ESX's HostSystem.configManager.advancedOption
// Capture method:
// govc object.collect -s -dump $(govc object.collect -s HostSystem:ha-host configManager.advancedOption) setting
var Setting = []types.BaseOptionValue{
// This list is currently pruned to include a single option for testing
&types.OptionValue{
Key: "Config.HostAgent.log.level",
Value: "info",
},
}

View File

@ -0,0 +1,242 @@
/*
Copyright (c) 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 esx
import "github.com/vmware/govmomi/vim25/types"
// VirtualDevice is the default set of VirtualDevice types created for a VirtualMachine
// Capture method:
// govc vm.create foo
// govc object.collect -s -dump vm/foo config.hardware.device
var VirtualDevice = []types.BaseVirtualDevice{
&types.VirtualIDEController{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 200,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "IDE 0",
Summary: "IDE 0",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 0,
Device: nil,
},
},
&types.VirtualIDEController{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 201,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "IDE 1",
Summary: "IDE 1",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 1,
Device: nil,
},
},
&types.VirtualPS2Controller{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 300,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "PS2 controller 0",
Summary: "PS2 controller 0",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 0,
Device: []int32{600, 700},
},
},
&types.VirtualPCIController{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 100,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "PCI controller 0",
Summary: "PCI controller 0",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 0,
Device: []int32{500, 12000},
},
},
&types.VirtualSIOController{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 400,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "SIO controller 0",
Summary: "SIO controller 0",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 0,
Device: nil,
},
},
&types.VirtualKeyboard{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 600,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "Keyboard ",
Summary: "Keyboard",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 300,
UnitNumber: types.NewInt32(0),
},
},
&types.VirtualPointingDevice{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 700,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "Pointing device",
Summary: "Pointing device; Device",
},
Backing: &types.VirtualPointingDeviceDeviceBackingInfo{
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{},
DeviceName: "",
UseAutoDetect: types.NewBool(false),
},
HostPointingDevice: "autodetect",
},
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 300,
UnitNumber: types.NewInt32(1),
},
},
&types.VirtualMachineVideoCard{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 500,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "Video card ",
Summary: "Video card",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 100,
UnitNumber: types.NewInt32(0),
},
VideoRamSizeInKB: 4096,
NumDisplays: 1,
UseAutoDetect: types.NewBool(false),
Enable3DSupport: types.NewBool(false),
Use3dRenderer: "automatic",
GraphicsMemorySizeInKB: 262144,
},
&types.VirtualMachineVMCIDevice{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 12000,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "VMCI device",
Summary: "Device on the virtual machine PCI bus that provides support for the virtual machine communication interface",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 100,
UnitNumber: types.NewInt32(17),
},
Id: -1,
AllowUnrestrictedCommunication: types.NewBool(false),
FilterEnable: types.NewBool(true),
FilterInfo: (*types.VirtualMachineVMCIDeviceFilterInfo)(nil),
},
}
// EthernetCard template for types.VirtualEthernetCard
var EthernetCard = types.VirtualE1000{
VirtualEthernetCard: types.VirtualEthernetCard{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 4000,
Backing: &types.VirtualEthernetCardNetworkBackingInfo{
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{},
DeviceName: "VM Network",
UseAutoDetect: types.NewBool(false),
},
Network: (*types.ManagedObjectReference)(nil),
InPassthroughMode: types.NewBool(false),
},
Connectable: &types.VirtualDeviceConnectInfo{
DynamicData: types.DynamicData{},
StartConnected: true,
AllowGuestControl: true,
Connected: false,
Status: "untried",
},
SlotInfo: &types.VirtualDevicePciBusSlotInfo{
VirtualDeviceBusSlotInfo: types.VirtualDeviceBusSlotInfo{},
PciSlotNumber: 32,
},
ControllerKey: 100,
UnitNumber: types.NewInt32(7),
},
AddressType: "generated",
MacAddress: "",
WakeOnLanEnabled: types.NewBool(true),
},
}

View File

@ -0,0 +1,251 @@
/*
Copyright (c) 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 simulator
import (
"io"
"os"
"path"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type FileManager struct {
mo.FileManager
}
func NewFileManager(ref types.ManagedObjectReference) object.Reference {
m := &FileManager{}
m.Self = ref
return m
}
func (f *FileManager) findDatastore(ref mo.Reference, name string) (*Datastore, types.BaseMethodFault) {
var refs []types.ManagedObjectReference
switch obj := ref.(type) {
case *Folder:
refs = obj.ChildEntity
case *StoragePod:
refs = obj.ChildEntity
}
for _, ref := range refs {
switch obj := Map.Get(ref).(type) {
case *Datastore:
if obj.Name == name {
return obj, nil
}
case *Folder, *StoragePod:
ds, _ := f.findDatastore(obj, name)
if ds != nil {
return ds, nil
}
}
}
return nil, &types.InvalidDatastore{Name: name}
}
func (f *FileManager) resolve(dc *types.ManagedObjectReference, name string) (string, types.BaseMethodFault) {
p, fault := parseDatastorePath(name)
if fault != nil {
return "", fault
}
if dc == nil {
if Map.IsESX() {
dc = &esx.Datacenter.Self
} else {
return "", &types.InvalidArgument{InvalidProperty: "dc"}
}
}
folder := Map.Get(*dc).(*mo.Datacenter).DatastoreFolder
ds, fault := f.findDatastore(Map.Get(folder), p.Datastore)
if fault != nil {
return "", fault
}
dir := ds.Info.GetDatastoreInfo().Url
return path.Join(dir, p.Path), nil
}
func (f *FileManager) fault(name string, err error, fault types.BaseFileFault) types.BaseMethodFault {
switch {
case os.IsNotExist(err):
fault = new(types.FileNotFound)
case os.IsExist(err):
fault = new(types.FileAlreadyExists)
}
fault.GetFileFault().File = name
return fault.(types.BaseMethodFault)
}
func (f *FileManager) deleteDatastoreFile(req *types.DeleteDatastoreFile_Task) types.BaseMethodFault {
file, fault := f.resolve(req.Datacenter, req.Name)
if fault != nil {
return fault
}
_, err := os.Stat(file)
if err != nil {
if os.IsNotExist(err) {
return f.fault(file, err, new(types.CannotDeleteFile))
}
}
err = os.RemoveAll(file)
if err != nil {
return f.fault(file, err, new(types.CannotDeleteFile))
}
return nil
}
func (f *FileManager) DeleteDatastoreFileTask(req *types.DeleteDatastoreFile_Task) soap.HasFault {
task := CreateTask(f, "deleteDatastoreFile", func(*Task) (types.AnyType, types.BaseMethodFault) {
return nil, f.deleteDatastoreFile(req)
})
return &methods.DeleteDatastoreFile_TaskBody{
Res: &types.DeleteDatastoreFile_TaskResponse{
Returnval: task.Run(),
},
}
}
func (f *FileManager) MakeDirectory(req *types.MakeDirectory) soap.HasFault {
body := &methods.MakeDirectoryBody{}
name, fault := f.resolve(req.Datacenter, req.Name)
if fault != nil {
body.Fault_ = Fault("", fault)
return body
}
mkdir := os.Mkdir
if isTrue(req.CreateParentDirectories) {
mkdir = os.MkdirAll
}
err := mkdir(name, 0700)
if err != nil {
fault = f.fault(req.Name, err, new(types.CannotCreateFile))
body.Fault_ = Fault(err.Error(), fault)
return body
}
return body
}
func (f *FileManager) moveDatastoreFile(req *types.MoveDatastoreFile_Task) types.BaseMethodFault {
src, fault := f.resolve(req.SourceDatacenter, req.SourceName)
if fault != nil {
return fault
}
dst, fault := f.resolve(req.DestinationDatacenter, req.DestinationName)
if fault != nil {
return fault
}
if !isTrue(req.Force) {
_, err := os.Stat(dst)
if err == nil {
return f.fault(dst, nil, new(types.FileAlreadyExistsFault))
}
}
err := os.Rename(src, dst)
if err != nil {
return f.fault(src, err, new(types.CannotAccessFile))
}
return nil
}
func (f *FileManager) MoveDatastoreFileTask(req *types.MoveDatastoreFile_Task) soap.HasFault {
task := CreateTask(f, "moveDatastoreFile", func(*Task) (types.AnyType, types.BaseMethodFault) {
return nil, f.moveDatastoreFile(req)
})
return &methods.MoveDatastoreFile_TaskBody{
Res: &types.MoveDatastoreFile_TaskResponse{
Returnval: task.Run(),
},
}
}
func (f *FileManager) copyDatastoreFile(req *types.CopyDatastoreFile_Task) types.BaseMethodFault {
src, fault := f.resolve(req.SourceDatacenter, req.SourceName)
if fault != nil {
return fault
}
dst, fault := f.resolve(req.DestinationDatacenter, req.DestinationName)
if fault != nil {
return fault
}
if !isTrue(req.Force) {
_, err := os.Stat(dst)
if err == nil {
return f.fault(dst, nil, new(types.FileAlreadyExistsFault))
}
}
r, err := os.Open(src)
if err != nil {
return f.fault(dst, err, new(types.CannotAccessFile))
}
defer r.Close()
w, err := os.Create(dst)
if err != nil {
return f.fault(dst, err, new(types.CannotCreateFile))
}
defer w.Close()
if _, err = io.Copy(w, r); err != nil {
return f.fault(dst, err, new(types.CannotCreateFile))
}
return nil
}
func (f *FileManager) CopyDatastoreFileTask(req *types.CopyDatastoreFile_Task) soap.HasFault {
task := CreateTask(f, "copyDatastoreFile", func(*Task) (types.AnyType, types.BaseMethodFault) {
return nil, f.copyDatastoreFile(req)
})
return &methods.CopyDatastoreFile_TaskBody{
Res: &types.CopyDatastoreFile_TaskResponse{
Returnval: task.Run(),
},
}
}

471
vendor/github.com/vmware/govmomi/simulator/folder.go generated vendored Normal file
View File

@ -0,0 +1,471 @@
/*
Copyright (c) 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 simulator
import (
"fmt"
"math/rand"
"path"
"sync"
"github.com/google/uuid"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type Folder struct {
mo.Folder
m sync.Mutex
}
// update references when objects are added/removed from a Folder
func (f *Folder) update(o mo.Reference, u func(types.ManagedObjectReference, []types.ManagedObjectReference) []types.ManagedObjectReference) {
ref := o.Reference()
if f.Parent == nil {
return // this is the root folder
}
switch ref.Type {
case "Datacenter", "Folder":
return // nothing to update
}
dc := Map.getEntityDatacenter(f)
switch ref.Type {
case "Network", "DistributedVirtualSwitch", "DistributedVirtualPortgroup":
dc.Network = u(ref, dc.Network)
case "Datastore":
dc.Datastore = u(ref, dc.Datastore)
}
}
func networkSummary(n *mo.Network) *types.NetworkSummary {
return &types.NetworkSummary{
Network: &n.Self,
Name: n.Name,
Accessible: true,
}
}
func (f *Folder) putChild(o mo.Entity) {
Map.PutEntity(f, o)
f.m.Lock()
defer f.m.Unlock()
f.ChildEntity = AddReference(o.Reference(), f.ChildEntity)
f.update(o, AddReference)
switch e := o.(type) {
case *mo.Network:
e.Summary = networkSummary(e)
case *mo.OpaqueNetwork:
e.Summary = networkSummary(&e.Network)
case *DistributedVirtualPortgroup:
e.Summary = networkSummary(&e.Network)
}
}
func (f *Folder) removeChild(o mo.Reference) {
Map.Remove(o.Reference())
f.m.Lock()
defer f.m.Unlock()
f.ChildEntity = RemoveReference(o.Reference(), f.ChildEntity)
f.update(o, RemoveReference)
}
func (f *Folder) hasChildType(kind string) bool {
for _, t := range f.ChildType {
if t == kind {
return true
}
}
return false
}
func (f *Folder) typeNotSupported() *soap.Fault {
return Fault(fmt.Sprintf("%s supports types: %#v", f.Self, f.ChildType), &types.NotSupported{})
}
type addStandaloneHost struct {
*Folder
req *types.AddStandaloneHost_Task
}
func (add *addStandaloneHost) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
host, err := CreateStandaloneHost(add.Folder, add.req.Spec)
if err != nil {
return nil, err
}
if add.req.AddConnected {
host.Runtime.ConnectionState = types.HostSystemConnectionStateConnected
}
return host.Reference(), nil
}
func (f *Folder) AddStandaloneHostTask(a *types.AddStandaloneHost_Task) soap.HasFault {
r := &methods.AddStandaloneHost_TaskBody{}
if f.hasChildType("ComputeResource") && f.hasChildType("Folder") {
r.Res = &types.AddStandaloneHost_TaskResponse{
Returnval: NewTask(&addStandaloneHost{f, a}).Run(),
}
} else {
r.Fault_ = f.typeNotSupported()
}
return r
}
func (f *Folder) CreateFolder(c *types.CreateFolder) soap.HasFault {
r := &methods.CreateFolderBody{}
if f.hasChildType("Folder") {
folder := &Folder{}
folder.Name = c.Name
folder.ChildType = f.ChildType
f.putChild(folder)
r.Res = &types.CreateFolderResponse{
Returnval: folder.Self,
}
} else {
r.Fault_ = f.typeNotSupported()
}
return r
}
// StoragePod aka "Datastore Cluster"
type StoragePod struct {
mo.StoragePod
}
func (f *Folder) CreateStoragePod(c *types.CreateStoragePod) soap.HasFault {
r := &methods.CreateStoragePodBody{}
if f.hasChildType("StoragePod") {
pod := &StoragePod{}
pod.Name = c.Name
pod.ChildType = []string{"Datastore"}
f.putChild(pod)
r.Res = &types.CreateStoragePodResponse{
Returnval: pod.Self,
}
} else {
r.Fault_ = f.typeNotSupported()
}
return r
}
func (p *StoragePod) MoveIntoFolderTask(c *types.MoveIntoFolder_Task) soap.HasFault {
return (&Folder{Folder: p.Folder}).MoveIntoFolderTask(c)
}
func (f *Folder) CreateDatacenter(c *types.CreateDatacenter) soap.HasFault {
r := &methods.CreateDatacenterBody{}
if f.hasChildType("Datacenter") && f.hasChildType("Folder") {
dc := &mo.Datacenter{}
dc.Name = c.Name
f.putChild(dc)
createDatacenterFolders(dc, true)
r.Res = &types.CreateDatacenterResponse{
Returnval: dc.Self,
}
} else {
r.Fault_ = f.typeNotSupported()
}
return r
}
func (f *Folder) CreateClusterEx(c *types.CreateClusterEx) soap.HasFault {
r := &methods.CreateClusterExBody{}
if f.hasChildType("ComputeResource") && f.hasChildType("Folder") {
cluster, err := CreateClusterComputeResource(f, c.Name, c.Spec)
if err != nil {
r.Fault_ = Fault("", err)
return r
}
r.Res = &types.CreateClusterExResponse{
Returnval: cluster.Self,
}
} else {
r.Fault_ = f.typeNotSupported()
}
return r
}
type createVM struct {
*Folder
req *types.CreateVM_Task
register bool
}
func (c *createVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
vm, err := NewVirtualMachine(c.Folder.Self, &c.req.Config)
if err != nil {
return nil, err
}
vm.ResourcePool = &c.req.Pool
if c.req.Host == nil {
var hosts []types.ManagedObjectReference
pool := Map.Get(c.req.Pool).(mo.Entity)
switch cr := Map.getEntityComputeResource(pool).(type) {
case *mo.ComputeResource:
hosts = cr.Host
case *ClusterComputeResource:
hosts = cr.Host
}
// Assuming for now that all hosts have access to the datastore
host := hosts[rand.Intn(len(hosts))]
vm.Runtime.Host = &host
} else {
vm.Runtime.Host = c.req.Host
}
vm.Guest = &types.GuestInfo{
ToolsStatus: types.VirtualMachineToolsStatusToolsNotInstalled,
ToolsVersion: "0",
}
vm.Summary.Guest = &types.VirtualMachineGuestSummary{
ToolsStatus: vm.Guest.ToolsStatus,
}
vm.Summary.Config.VmPathName = vm.Config.Files.VmPathName
vm.Summary.Runtime.Host = vm.Runtime.Host
err = vm.create(&c.req.Config, c.register)
if err != nil {
return nil, err
}
c.Folder.putChild(vm)
host := Map.Get(*vm.Runtime.Host).(*HostSystem)
host.Vm = append(host.Vm, vm.Self)
for i := range vm.Datastore {
ds := Map.Get(vm.Datastore[i]).(*Datastore)
ds.Vm = append(ds.Vm, vm.Self)
}
switch rp := Map.Get(*vm.ResourcePool).(type) {
case *ResourcePool:
rp.Vm = append(rp.Vm, vm.Self)
case *VirtualApp:
rp.Vm = append(rp.Vm, vm.Self)
}
return vm.Reference(), nil
}
func (f *Folder) CreateVMTask(c *types.CreateVM_Task) soap.HasFault {
return &methods.CreateVM_TaskBody{
Res: &types.CreateVM_TaskResponse{
Returnval: NewTask(&createVM{f, c, false}).Run(),
},
}
}
type registerVM struct {
*Folder
req *types.RegisterVM_Task
}
func (c *registerVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
host := c.req.Host
pool := c.req.Pool
if c.req.AsTemplate {
if host == nil {
return nil, &types.InvalidArgument{InvalidProperty: "host"}
} else if pool != nil {
return nil, &types.InvalidArgument{InvalidProperty: "pool"}
}
pool = hostParent(&Map.Get(*host).(*HostSystem).HostSystem).ResourcePool
} else {
if pool == nil {
return nil, &types.InvalidArgument{InvalidProperty: "pool"}
}
}
if c.req.Path == "" {
return nil, &types.InvalidArgument{InvalidProperty: "path"}
}
s := Map.SearchIndex()
r := s.FindByDatastorePath(&types.FindByDatastorePath{
This: s.Reference(),
Path: c.req.Path,
Datacenter: Map.getEntityDatacenter(c.Folder).Reference(),
})
if ref := r.(*methods.FindByDatastorePathBody).Res.Returnval; ref != nil {
return nil, &types.AlreadyExists{Name: ref.Value}
}
if c.req.Name == "" {
p, err := parseDatastorePath(c.req.Path)
if err != nil {
return nil, err
}
c.req.Name = path.Dir(p.Path)
}
create := NewTask(&createVM{
Folder: c.Folder,
register: true,
req: &types.CreateVM_Task{
This: c.Folder.Reference(),
Config: types.VirtualMachineConfigSpec{
Name: c.req.Name,
Files: &types.VirtualMachineFileInfo{
VmPathName: c.req.Path,
},
},
Pool: *pool,
Host: host,
},
})
create.Run()
if create.Info.Error != nil {
return nil, create.Info.Error.Fault
}
return create.Info.Result, nil
}
func (f *Folder) RegisterVMTask(c *types.RegisterVM_Task) soap.HasFault {
return &methods.RegisterVM_TaskBody{
Res: &types.RegisterVM_TaskResponse{
Returnval: NewTask(&registerVM{f, c}).Run(),
},
}
}
func (f *Folder) MoveIntoFolderTask(c *types.MoveIntoFolder_Task) soap.HasFault {
task := CreateTask(f, "moveIntoFolder", func(t *Task) (types.AnyType, types.BaseMethodFault) {
for _, ref := range c.List {
obj := Map.Get(ref).(mo.Entity)
parent, ok := Map.Get(*(obj.Entity()).Parent).(*Folder)
if !ok || !f.hasChildType(ref.Type) {
return nil, &types.NotSupported{}
}
parent.removeChild(ref)
f.putChild(obj)
}
return nil, nil
})
return &methods.MoveIntoFolder_TaskBody{
Res: &types.MoveIntoFolder_TaskResponse{
Returnval: task.Run(),
},
}
}
func (f *Folder) CreateDVSTask(req *types.CreateDVS_Task) soap.HasFault {
task := CreateTask(f, "createDVS", func(t *Task) (types.AnyType, types.BaseMethodFault) {
spec := req.Spec.ConfigSpec.GetDVSConfigSpec()
dvs := &DistributedVirtualSwitch{}
dvs.Name = spec.Name
dvs.Entity().Name = dvs.Name
if Map.FindByName(dvs.Name, f.ChildEntity) != nil {
return nil, &types.InvalidArgument{InvalidProperty: "name"}
}
dvs.Uuid = uuid.New().String()
f.putChild(dvs)
dvs.Summary = types.DVSSummary{
Name: dvs.Name,
Uuid: dvs.Uuid,
NumPorts: spec.NumStandalonePorts,
ProductInfo: req.Spec.ProductInfo,
Description: spec.Description,
}
if dvs.Summary.ProductInfo == nil {
product := Map.content().About
dvs.Summary.ProductInfo = &types.DistributedVirtualSwitchProductSpec{
Name: "DVS",
Vendor: product.Vendor,
Version: product.Version,
Build: product.Build,
ForwardingClass: "etherswitch",
}
}
return dvs.Reference(), nil
})
return &methods.CreateDVS_TaskBody{
Res: &types.CreateDVS_TaskResponse{
Returnval: task.Run(),
},
}
}
func (f *Folder) RenameTask(r *types.Rename_Task) soap.HasFault {
return RenameTask(f, r)
}

171
vendor/github.com/vmware/govmomi/simulator/guest_id.go generated vendored Normal file
View File

@ -0,0 +1,171 @@
/*
Copyright (c) 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 simulator
import "github.com/vmware/govmomi/vim25/types"
// GuestID is the list of valid types.VirtualMachineGuestOsIdentifier
var GuestID = []types.VirtualMachineGuestOsIdentifier{
types.VirtualMachineGuestOsIdentifierDosGuest,
types.VirtualMachineGuestOsIdentifierWin31Guest,
types.VirtualMachineGuestOsIdentifierWin95Guest,
types.VirtualMachineGuestOsIdentifierWin98Guest,
types.VirtualMachineGuestOsIdentifierWinMeGuest,
types.VirtualMachineGuestOsIdentifierWinNTGuest,
types.VirtualMachineGuestOsIdentifierWin2000ProGuest,
types.VirtualMachineGuestOsIdentifierWin2000ServGuest,
types.VirtualMachineGuestOsIdentifierWin2000AdvServGuest,
types.VirtualMachineGuestOsIdentifierWinXPHomeGuest,
types.VirtualMachineGuestOsIdentifierWinXPProGuest,
types.VirtualMachineGuestOsIdentifierWinXPPro64Guest,
types.VirtualMachineGuestOsIdentifierWinNetWebGuest,
types.VirtualMachineGuestOsIdentifierWinNetStandardGuest,
types.VirtualMachineGuestOsIdentifierWinNetEnterpriseGuest,
types.VirtualMachineGuestOsIdentifierWinNetDatacenterGuest,
types.VirtualMachineGuestOsIdentifierWinNetBusinessGuest,
types.VirtualMachineGuestOsIdentifierWinNetStandard64Guest,
types.VirtualMachineGuestOsIdentifierWinNetEnterprise64Guest,
types.VirtualMachineGuestOsIdentifierWinLonghornGuest,
types.VirtualMachineGuestOsIdentifierWinLonghorn64Guest,
types.VirtualMachineGuestOsIdentifierWinNetDatacenter64Guest,
types.VirtualMachineGuestOsIdentifierWinVistaGuest,
types.VirtualMachineGuestOsIdentifierWinVista64Guest,
types.VirtualMachineGuestOsIdentifierWindows7Guest,
types.VirtualMachineGuestOsIdentifierWindows7_64Guest,
types.VirtualMachineGuestOsIdentifierWindows7Server64Guest,
types.VirtualMachineGuestOsIdentifierWindows8Guest,
types.VirtualMachineGuestOsIdentifierWindows8_64Guest,
types.VirtualMachineGuestOsIdentifierWindows8Server64Guest,
types.VirtualMachineGuestOsIdentifierWindows9Guest,
types.VirtualMachineGuestOsIdentifierWindows9_64Guest,
types.VirtualMachineGuestOsIdentifierWindows9Server64Guest,
types.VirtualMachineGuestOsIdentifierWindowsHyperVGuest,
types.VirtualMachineGuestOsIdentifierFreebsdGuest,
types.VirtualMachineGuestOsIdentifierFreebsd64Guest,
types.VirtualMachineGuestOsIdentifierRedhatGuest,
types.VirtualMachineGuestOsIdentifierRhel2Guest,
types.VirtualMachineGuestOsIdentifierRhel3Guest,
types.VirtualMachineGuestOsIdentifierRhel3_64Guest,
types.VirtualMachineGuestOsIdentifierRhel4Guest,
types.VirtualMachineGuestOsIdentifierRhel4_64Guest,
types.VirtualMachineGuestOsIdentifierRhel5Guest,
types.VirtualMachineGuestOsIdentifierRhel5_64Guest,
types.VirtualMachineGuestOsIdentifierRhel6Guest,
types.VirtualMachineGuestOsIdentifierRhel6_64Guest,
types.VirtualMachineGuestOsIdentifierRhel7Guest,
types.VirtualMachineGuestOsIdentifierRhel7_64Guest,
types.VirtualMachineGuestOsIdentifierCentosGuest,
types.VirtualMachineGuestOsIdentifierCentos64Guest,
types.VirtualMachineGuestOsIdentifierCentos6Guest,
types.VirtualMachineGuestOsIdentifierCentos6_64Guest,
types.VirtualMachineGuestOsIdentifierCentos7Guest,
types.VirtualMachineGuestOsIdentifierCentos7_64Guest,
types.VirtualMachineGuestOsIdentifierOracleLinuxGuest,
types.VirtualMachineGuestOsIdentifierOracleLinux64Guest,
types.VirtualMachineGuestOsIdentifierOracleLinux6Guest,
types.VirtualMachineGuestOsIdentifierOracleLinux6_64Guest,
types.VirtualMachineGuestOsIdentifierOracleLinux7Guest,
types.VirtualMachineGuestOsIdentifierOracleLinux7_64Guest,
types.VirtualMachineGuestOsIdentifierSuseGuest,
types.VirtualMachineGuestOsIdentifierSuse64Guest,
types.VirtualMachineGuestOsIdentifierSlesGuest,
types.VirtualMachineGuestOsIdentifierSles64Guest,
types.VirtualMachineGuestOsIdentifierSles10Guest,
types.VirtualMachineGuestOsIdentifierSles10_64Guest,
types.VirtualMachineGuestOsIdentifierSles11Guest,
types.VirtualMachineGuestOsIdentifierSles11_64Guest,
types.VirtualMachineGuestOsIdentifierSles12Guest,
types.VirtualMachineGuestOsIdentifierSles12_64Guest,
types.VirtualMachineGuestOsIdentifierNld9Guest,
types.VirtualMachineGuestOsIdentifierOesGuest,
types.VirtualMachineGuestOsIdentifierSjdsGuest,
types.VirtualMachineGuestOsIdentifierMandrakeGuest,
types.VirtualMachineGuestOsIdentifierMandrivaGuest,
types.VirtualMachineGuestOsIdentifierMandriva64Guest,
types.VirtualMachineGuestOsIdentifierTurboLinuxGuest,
types.VirtualMachineGuestOsIdentifierTurboLinux64Guest,
types.VirtualMachineGuestOsIdentifierUbuntuGuest,
types.VirtualMachineGuestOsIdentifierUbuntu64Guest,
types.VirtualMachineGuestOsIdentifierDebian4Guest,
types.VirtualMachineGuestOsIdentifierDebian4_64Guest,
types.VirtualMachineGuestOsIdentifierDebian5Guest,
types.VirtualMachineGuestOsIdentifierDebian5_64Guest,
types.VirtualMachineGuestOsIdentifierDebian6Guest,
types.VirtualMachineGuestOsIdentifierDebian6_64Guest,
types.VirtualMachineGuestOsIdentifierDebian7Guest,
types.VirtualMachineGuestOsIdentifierDebian7_64Guest,
types.VirtualMachineGuestOsIdentifierDebian8Guest,
types.VirtualMachineGuestOsIdentifierDebian8_64Guest,
types.VirtualMachineGuestOsIdentifierDebian9Guest,
types.VirtualMachineGuestOsIdentifierDebian9_64Guest,
types.VirtualMachineGuestOsIdentifierDebian10Guest,
types.VirtualMachineGuestOsIdentifierDebian10_64Guest,
types.VirtualMachineGuestOsIdentifierAsianux3Guest,
types.VirtualMachineGuestOsIdentifierAsianux3_64Guest,
types.VirtualMachineGuestOsIdentifierAsianux4Guest,
types.VirtualMachineGuestOsIdentifierAsianux4_64Guest,
types.VirtualMachineGuestOsIdentifierAsianux5_64Guest,
types.VirtualMachineGuestOsIdentifierAsianux7_64Guest,
types.VirtualMachineGuestOsIdentifierOpensuseGuest,
types.VirtualMachineGuestOsIdentifierOpensuse64Guest,
types.VirtualMachineGuestOsIdentifierFedoraGuest,
types.VirtualMachineGuestOsIdentifierFedora64Guest,
types.VirtualMachineGuestOsIdentifierCoreos64Guest,
types.VirtualMachineGuestOsIdentifierVmwarePhoton64Guest,
types.VirtualMachineGuestOsIdentifierOther24xLinuxGuest,
types.VirtualMachineGuestOsIdentifierOther26xLinuxGuest,
types.VirtualMachineGuestOsIdentifierOtherLinuxGuest,
types.VirtualMachineGuestOsIdentifierOther3xLinuxGuest,
types.VirtualMachineGuestOsIdentifierGenericLinuxGuest,
types.VirtualMachineGuestOsIdentifierOther24xLinux64Guest,
types.VirtualMachineGuestOsIdentifierOther26xLinux64Guest,
types.VirtualMachineGuestOsIdentifierOther3xLinux64Guest,
types.VirtualMachineGuestOsIdentifierOtherLinux64Guest,
types.VirtualMachineGuestOsIdentifierSolaris6Guest,
types.VirtualMachineGuestOsIdentifierSolaris7Guest,
types.VirtualMachineGuestOsIdentifierSolaris8Guest,
types.VirtualMachineGuestOsIdentifierSolaris9Guest,
types.VirtualMachineGuestOsIdentifierSolaris10Guest,
types.VirtualMachineGuestOsIdentifierSolaris10_64Guest,
types.VirtualMachineGuestOsIdentifierSolaris11_64Guest,
types.VirtualMachineGuestOsIdentifierOs2Guest,
types.VirtualMachineGuestOsIdentifierEComStationGuest,
types.VirtualMachineGuestOsIdentifierEComStation2Guest,
types.VirtualMachineGuestOsIdentifierNetware4Guest,
types.VirtualMachineGuestOsIdentifierNetware5Guest,
types.VirtualMachineGuestOsIdentifierNetware6Guest,
types.VirtualMachineGuestOsIdentifierOpenServer5Guest,
types.VirtualMachineGuestOsIdentifierOpenServer6Guest,
types.VirtualMachineGuestOsIdentifierUnixWare7Guest,
types.VirtualMachineGuestOsIdentifierDarwinGuest,
types.VirtualMachineGuestOsIdentifierDarwin64Guest,
types.VirtualMachineGuestOsIdentifierDarwin10Guest,
types.VirtualMachineGuestOsIdentifierDarwin10_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin11Guest,
types.VirtualMachineGuestOsIdentifierDarwin11_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin12_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin13_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin14_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin15_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin16_64Guest,
types.VirtualMachineGuestOsIdentifierVmkernelGuest,
types.VirtualMachineGuestOsIdentifierVmkernel5Guest,
types.VirtualMachineGuestOsIdentifierVmkernel6Guest,
types.VirtualMachineGuestOsIdentifierVmkernel65Guest,
types.VirtualMachineGuestOsIdentifierOtherGuest,
types.VirtualMachineGuestOsIdentifierOtherGuest64,
}

35
vendor/github.com/vmware/govmomi/simulator/guest_id.sh generated vendored Executable file
View File

@ -0,0 +1,35 @@
#!/bin/bash -e
pushd "$(dirname "$0")" >/dev/null
{
cat <<EOF
/*
Copyright (c) 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 simulator
// GuestID is the list of valid types.VirtualMachineGuestOsIdentifier
var GuestID = []types.VirtualMachineGuestOsIdentifier{
EOF
ids=($(grep 'VirtualMachineGuestOsIdentifier(' ../vim25/types/enum.go | grep = | awk '{print $1}'))
printf "types.%s,\n" "${ids[@]}"
echo "}"
} > guest_id.go
goimports -w guest_id.go

View File

@ -0,0 +1,254 @@
/*
Copyright (c) 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 simulator
import (
"io/ioutil"
"log"
"os"
"path"
"strings"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type HostDatastoreBrowser struct {
mo.HostDatastoreBrowser
}
type searchDatastore struct {
*HostDatastoreBrowser
DatastorePath string
SearchSpec *types.HostDatastoreBrowserSearchSpec
res []types.HostDatastoreBrowserSearchResults
recurse bool
}
func (s *searchDatastore) addFile(file os.FileInfo, res *types.HostDatastoreBrowserSearchResults) {
details := s.SearchSpec.Details
if details == nil {
details = new(types.FileQueryFlags)
}
name := file.Name()
info := types.FileInfo{
Path: name,
}
var finfo types.BaseFileInfo = &info
if details.FileSize {
info.FileSize = file.Size()
}
if details.Modification {
mtime := file.ModTime()
info.Modification = &mtime
}
if isTrue(details.FileOwner) {
// Assume for now this process created all files in the datastore
user := os.Getenv("USER")
info.Owner = user
}
if file.IsDir() {
finfo = &types.FolderFileInfo{FileInfo: info}
} else if details.FileType {
switch path.Ext(name) {
case ".img":
finfo = &types.FloppyImageFileInfo{FileInfo: info}
case ".iso":
finfo = &types.IsoImageFileInfo{FileInfo: info}
case ".log":
finfo = &types.VmLogFileInfo{FileInfo: info}
case ".nvram":
finfo = &types.VmNvramFileInfo{FileInfo: info}
case ".vmdk":
// TODO: lookup device to set other fields
finfo = &types.VmDiskFileInfo{FileInfo: info}
case ".vmx":
finfo = &types.VmConfigFileInfo{FileInfo: info}
}
}
res.File = append(res.File, finfo)
}
func (s *searchDatastore) queryMatch(file os.FileInfo) bool {
if len(s.SearchSpec.Query) == 0 {
return true
}
name := file.Name()
ext := path.Ext(name)
for _, q := range s.SearchSpec.Query {
switch q.(type) {
case *types.FileQuery:
return true
case *types.FolderFileQuery:
if file.IsDir() {
return true
}
case *types.FloppyImageFileQuery:
if ext == ".img" {
return true
}
case *types.IsoImageFileQuery:
if ext == ".iso" {
return true
}
case *types.VmConfigFileQuery:
if ext == ".vmx" {
// TODO: check Filter and Details fields
return true
}
case *types.VmDiskFileQuery:
if ext == ".vmdk" {
if strings.HasSuffix(name, "-flat.vmdk") {
// only matches the descriptor, not the backing file(s)
return false
}
// TODO: check Filter and Details fields
return true
}
case *types.VmLogFileQuery:
if ext == ".log" {
return strings.HasPrefix(name, "vmware")
}
case *types.VmNvramFileQuery:
if ext == ".nvram" {
return true
}
case *types.VmSnapshotFileQuery:
if ext == ".vmsn" {
return true
}
}
}
return false
}
func (s *searchDatastore) search(ds *types.ManagedObjectReference, folder string, dir string) error {
files, err := ioutil.ReadDir(dir)
if err != nil {
log.Printf("search %s: %s", dir, err)
return err
}
res := types.HostDatastoreBrowserSearchResults{
Datastore: ds,
FolderPath: folder,
}
for _, file := range files {
name := file.Name()
if s.queryMatch(file) {
for _, m := range s.SearchSpec.MatchPattern {
if ok, _ := path.Match(m, name); ok {
s.addFile(file, &res)
break
}
}
}
if s.recurse && file.IsDir() {
_ = s.search(ds, path.Join(folder, name), path.Join(dir, name))
}
}
s.res = append(s.res, res)
return nil
}
func (s *searchDatastore) Run(Task *Task) (types.AnyType, types.BaseMethodFault) {
p, fault := parseDatastorePath(s.DatastorePath)
if fault != nil {
return nil, fault
}
ref := Map.FindByName(p.Datastore, s.Datastore)
if ref == nil {
return nil, &types.InvalidDatastore{Name: p.Datastore}
}
ds := ref.(*Datastore)
dir := path.Join(ds.Info.GetDatastoreInfo().Url, p.Path)
err := s.search(&ds.Self, s.DatastorePath, dir)
if err != nil {
ff := types.FileFault{
File: p.Path,
}
if os.IsNotExist(err) {
return nil, &types.FileNotFound{FileFault: ff}
}
return nil, &types.InvalidArgument{InvalidProperty: p.Path}
}
if s.recurse {
return types.ArrayOfHostDatastoreBrowserSearchResults{
HostDatastoreBrowserSearchResults: s.res,
}, nil
}
return s.res[0], nil
}
func (b *HostDatastoreBrowser) SearchDatastoreTask(s *types.SearchDatastore_Task) soap.HasFault {
task := NewTask(&searchDatastore{
HostDatastoreBrowser: b,
DatastorePath: s.DatastorePath,
SearchSpec: s.SearchSpec,
})
return &methods.SearchDatastore_TaskBody{
Res: &types.SearchDatastore_TaskResponse{
Returnval: task.Run(),
},
}
}
func (b *HostDatastoreBrowser) SearchDatastoreSubFoldersTask(s *types.SearchDatastoreSubFolders_Task) soap.HasFault {
task := NewTask(&searchDatastore{
HostDatastoreBrowser: b,
DatastorePath: s.DatastorePath,
SearchSpec: s.SearchSpec,
recurse: true,
})
return &methods.SearchDatastoreSubFolders_TaskBody{
Res: &types.SearchDatastoreSubFolders_TaskResponse{
Returnval: task.Run(),
},
}
}

View File

@ -0,0 +1,161 @@
/*
Copyright (c) 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 simulator
import (
"os"
"path"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type HostDatastoreSystem struct {
mo.HostDatastoreSystem
Host *mo.HostSystem
}
func (dss *HostDatastoreSystem) add(ds *Datastore) *soap.Fault {
info := ds.Info.GetDatastoreInfo()
info.Name = ds.Name
if e := Map.FindByName(ds.Name, dss.Datastore); e != nil {
return Fault(e.Reference().Value, &types.DuplicateName{
Name: ds.Name,
Object: e.Reference(),
})
}
fi, err := os.Stat(info.Url)
if err == nil && !fi.IsDir() {
err = os.ErrInvalid
}
if err != nil {
switch {
case os.IsNotExist(err):
return Fault(err.Error(), &types.NotFound{})
default:
return Fault(err.Error(), &types.HostConfigFault{})
}
}
folder := Map.getEntityFolder(dss.Host, "datastore")
ds.Self.Type = typeName(ds)
// Datastore is the only type where create methods do not include the parent (Folder in this case),
// but we need the moref to be unique per DC/datastoreFolder, but not per-HostSystem.
ds.Self.Value += "@" + folder.Self.Value
// TODO: name should be made unique in the case of Local ds type
ds.Summary.Datastore = &ds.Self
ds.Summary.Name = ds.Name
ds.Summary.Url = info.Url
dss.Datastore = append(dss.Datastore, ds.Self)
dss.Host.Datastore = dss.Datastore
parent := hostParent(dss.Host)
parent.Datastore = AddReference(ds.Self, parent.Datastore)
browser := &HostDatastoreBrowser{}
browser.Datastore = dss.Datastore
ds.Browser = Map.Put(browser).Reference()
folder.putChild(ds)
return nil
}
func (dss *HostDatastoreSystem) CreateLocalDatastore(c *types.CreateLocalDatastore) soap.HasFault {
r := &methods.CreateLocalDatastoreBody{}
ds := &Datastore{}
ds.Name = c.Name
ds.Self.Value = c.Path
ds.Info = &types.LocalDatastoreInfo{
DatastoreInfo: types.DatastoreInfo{
Name: c.Name,
Url: c.Path,
},
Path: c.Path,
}
ds.Summary.Type = "local"
if err := dss.add(ds); err != nil {
r.Fault_ = err
return r
}
ds.Host = append(ds.Host, types.DatastoreHostMount{
Key: dss.Host.Reference(),
MountInfo: types.HostMountInfo{
AccessMode: string(types.HostMountModeReadWrite),
Mounted: types.NewBool(true),
Accessible: types.NewBool(true),
},
})
_ = ds.RefreshDatastore(&types.RefreshDatastore{This: ds.Self})
r.Res = &types.CreateLocalDatastoreResponse{
Returnval: ds.Self,
}
return r
}
func (dss *HostDatastoreSystem) CreateNasDatastore(c *types.CreateNasDatastore) soap.HasFault {
r := &methods.CreateNasDatastoreBody{}
ds := &Datastore{}
ds.Name = path.Base(c.Spec.LocalPath)
ds.Self.Value = c.Spec.RemoteHost + ":" + c.Spec.RemotePath
ds.Info = &types.NasDatastoreInfo{
DatastoreInfo: types.DatastoreInfo{
Url: c.Spec.LocalPath,
},
Nas: &types.HostNasVolume{
HostFileSystemVolume: types.HostFileSystemVolume{
Name: c.Spec.LocalPath,
Type: c.Spec.Type,
},
RemoteHost: c.Spec.RemoteHost,
RemotePath: c.Spec.RemotePath,
},
}
ds.Summary.Type = c.Spec.Type
if err := dss.add(ds); err != nil {
r.Fault_ = err
return r
}
_ = ds.RefreshDatastore(&types.RefreshDatastore{This: ds.Self})
r.Res = &types.CreateNasDatastoreResponse{
Returnval: ds.Self,
}
return r
}

View File

@ -0,0 +1,87 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type HostFirewallSystem struct {
mo.HostFirewallSystem
}
func NewHostFirewallSystem(_ *mo.HostSystem) *HostFirewallSystem {
info := esx.HostFirewallInfo
return &HostFirewallSystem{
HostFirewallSystem: mo.HostFirewallSystem{
FirewallInfo: &info,
},
}
}
func DisableRuleset(info *types.HostFirewallInfo, id string) bool {
for i := range info.Ruleset {
if info.Ruleset[i].Key == id {
info.Ruleset[i].Enabled = false
return true
}
}
return false
}
func (s *HostFirewallSystem) DisableRuleset(req *types.DisableRuleset) soap.HasFault {
body := &methods.DisableRulesetBody{}
if DisableRuleset(s.HostFirewallSystem.FirewallInfo, req.Id) {
body.Res = new(types.DisableRulesetResponse)
return body
}
body.Fault_ = Fault("", &types.NotFound{})
return body
}
func EnableRuleset(info *types.HostFirewallInfo, id string) bool {
for i := range info.Ruleset {
if info.Ruleset[i].Key == id {
info.Ruleset[i].Enabled = true
return true
}
}
return false
}
func (s *HostFirewallSystem) EnableRuleset(req *types.EnableRuleset) soap.HasFault {
body := &methods.EnableRulesetBody{}
if EnableRuleset(s.HostFirewallSystem.FirewallInfo, req.Id) {
body.Res = new(types.EnableRulesetResponse)
return body
}
body.Fault_ = Fault("", &types.NotFound{})
return body
}

View File

@ -0,0 +1,171 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type HostNetworkSystem struct {
mo.HostNetworkSystem
Host *mo.HostSystem
}
func NewHostNetworkSystem(host *mo.HostSystem) *HostNetworkSystem {
return &HostNetworkSystem{
Host: host,
HostNetworkSystem: mo.HostNetworkSystem{
NetworkInfo: &types.HostNetworkInfo{
Vswitch: []types.HostVirtualSwitch{
{
Name: "vSwitch0",
Portgroup: []string{"VM Network"},
},
},
},
},
}
}
func (s *HostNetworkSystem) folder() *Folder {
f := Map.getEntityDatacenter(s.Host).NetworkFolder
return Map.Get(f).(*Folder)
}
func (s *HostNetworkSystem) AddVirtualSwitch(c *types.AddVirtualSwitch) soap.HasFault {
r := &methods.AddVirtualSwitchBody{}
for _, vswitch := range s.NetworkInfo.Vswitch {
if vswitch.Name == c.VswitchName {
r.Fault_ = Fault("", &types.AlreadyExists{Name: c.VswitchName})
return r
}
}
s.NetworkInfo.Vswitch = append(s.NetworkInfo.Vswitch, types.HostVirtualSwitch{
Name: c.VswitchName,
})
r.Res = &types.AddVirtualSwitchResponse{}
return r
}
func (s *HostNetworkSystem) RemoveVirtualSwitch(c *types.RemoveVirtualSwitch) soap.HasFault {
r := &methods.RemoveVirtualSwitchBody{}
vs := s.NetworkInfo.Vswitch
for i, v := range vs {
if v.Name == c.VswitchName {
s.NetworkInfo.Vswitch = append(vs[:i], vs[i+1:]...)
r.Res = &types.RemoveVirtualSwitchResponse{}
return r
}
}
r.Fault_ = Fault("", &types.NotFound{})
return r
}
func (s *HostNetworkSystem) AddPortGroup(c *types.AddPortGroup) soap.HasFault {
var vswitch *types.HostVirtualSwitch
r := &methods.AddPortGroupBody{}
if c.Portgrp.Name == "" {
r.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "name"})
return r
}
for i := range s.NetworkInfo.Vswitch {
if s.NetworkInfo.Vswitch[i].Name == c.Portgrp.VswitchName {
vswitch = &s.NetworkInfo.Vswitch[i]
break
}
}
if vswitch == nil {
r.Fault_ = Fault("", &types.NotFound{})
return r
}
network := &mo.Network{}
network.Name = c.Portgrp.Name
network.Entity().Name = network.Name
folder := s.folder()
if obj := Map.FindByName(c.Portgrp.Name, folder.ChildEntity); obj != nil {
r.Fault_ = Fault("", &types.DuplicateName{
Name: c.Portgrp.Name,
Object: obj.Reference(),
})
return r
}
folder.putChild(network)
vswitch.Portgroup = append(vswitch.Portgroup, c.Portgrp.Name)
r.Res = &types.AddPortGroupResponse{}
return r
}
func (s *HostNetworkSystem) RemovePortGroup(c *types.RemovePortGroup) soap.HasFault {
var vswitch *types.HostVirtualSwitch
r := &methods.RemovePortGroupBody{}
for i, v := range s.NetworkInfo.Vswitch {
for j, pg := range v.Portgroup {
if pg == c.PgName {
vswitch = &s.NetworkInfo.Vswitch[i]
vswitch.Portgroup = append(vswitch.Portgroup[:j], vswitch.Portgroup[j+1:]...)
}
}
}
if vswitch == nil {
r.Fault_ = Fault("", &types.NotFound{})
return r
}
folder := s.folder()
e := Map.FindByName(c.PgName, folder.ChildEntity)
folder.removeChild(e.Reference())
r.Res = &types.RemovePortGroupResponse{}
return r
}
func (s *HostNetworkSystem) UpdateNetworkConfig(req *types.UpdateNetworkConfig) soap.HasFault {
s.NetworkConfig = &req.Config
return &methods.UpdateNetworkConfigBody{
Res: &types.UpdateNetworkConfigResponse{
Returnval: types.HostNetworkConfigResult{},
},
}
}

View File

@ -0,0 +1,180 @@
/*
Copyright (c) 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 simulator
import (
"time"
"github.com/google/uuid"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type HostSystem struct {
mo.HostSystem
}
func NewHostSystem(host mo.HostSystem) *HostSystem {
now := time.Now()
hs := &HostSystem{
HostSystem: host,
}
hs.Name = hs.Summary.Config.Name
hs.Summary.Runtime = &hs.Runtime
hs.Summary.Runtime.BootTime = &now
id := uuid.New().String()
hardware := *host.Summary.Hardware
hs.Summary.Hardware = &hardware
hs.Summary.Hardware.Uuid = id
info := *esx.HostHardwareInfo
info.SystemInfo.Uuid = id
hs.Hardware = &info
config := []struct {
ref **types.ManagedObjectReference
obj mo.Reference
}{
{&hs.ConfigManager.DatastoreSystem, &HostDatastoreSystem{Host: &hs.HostSystem}},
{&hs.ConfigManager.NetworkSystem, NewHostNetworkSystem(&hs.HostSystem)},
{&hs.ConfigManager.AdvancedOption, NewOptionManager(nil, esx.Setting)},
{&hs.ConfigManager.FirewallSystem, NewHostFirewallSystem(&hs.HostSystem)},
}
for _, c := range config {
ref := Map.Put(c.obj).Reference()
*c.ref = &ref
}
return hs
}
func hostParent(host *mo.HostSystem) *mo.ComputeResource {
switch parent := Map.Get(*host.Parent).(type) {
case *mo.ComputeResource:
return parent
case *ClusterComputeResource:
return &parent.ComputeResource
default:
return nil
}
}
func addComputeResource(s *types.ComputeResourceSummary, h *HostSystem) {
s.TotalCpu += h.Summary.Hardware.CpuMhz
s.TotalMemory += h.Summary.Hardware.MemorySize
s.NumCpuCores += h.Summary.Hardware.NumCpuCores
s.NumCpuThreads += h.Summary.Hardware.NumCpuThreads
s.EffectiveCpu += h.Summary.Hardware.CpuMhz
s.EffectiveMemory += h.Summary.Hardware.MemorySize
s.NumHosts++
s.NumEffectiveHosts++
s.OverallStatus = types.ManagedEntityStatusGreen
}
// CreateDefaultESX creates a standalone ESX
// Adds objects of type: Datacenter, Network, ComputeResource, ResourcePool and HostSystem
func CreateDefaultESX(f *Folder) {
dc := &esx.Datacenter
f.putChild(dc)
createDatacenterFolders(dc, false)
host := NewHostSystem(esx.HostSystem)
summary := new(types.ComputeResourceSummary)
addComputeResource(summary, host)
cr := &mo.ComputeResource{Summary: summary}
cr.Self = *host.Parent
cr.Name = host.Name
cr.Host = append(cr.Host, host.Reference())
Map.PutEntity(cr, host)
pool := NewResourcePool()
cr.ResourcePool = &pool.Self
Map.PutEntity(cr, pool)
pool.Owner = cr.Self
Map.Get(dc.HostFolder).(*Folder).putChild(cr)
}
// CreateStandaloneHost uses esx.HostSystem as a template, applying the given spec
// and creating the ComputeResource parent and ResourcePool sibling.
func CreateStandaloneHost(f *Folder, spec types.HostConnectSpec) (*HostSystem, types.BaseMethodFault) {
if spec.HostName == "" {
return nil, &types.NoHost{}
}
pool := NewResourcePool()
host := NewHostSystem(esx.HostSystem)
host.Summary.Config.Name = spec.HostName
host.Name = host.Summary.Config.Name
host.Runtime.ConnectionState = types.HostSystemConnectionStateDisconnected
summary := new(types.ComputeResourceSummary)
addComputeResource(summary, host)
cr := &mo.ComputeResource{Summary: summary}
Map.PutEntity(cr, Map.NewEntity(host))
Map.PutEntity(cr, Map.NewEntity(pool))
cr.Name = host.Name
cr.Host = append(cr.Host, host.Reference())
cr.ResourcePool = &pool.Self
f.putChild(cr)
pool.Owner = cr.Self
return host, nil
}
func (h *HostSystem) EnterMaintenanceModeTask(spec *types.EnterMaintenanceMode_Task) soap.HasFault {
task := CreateTask(h, "enterMaintenanceMode", func(t *Task) (types.AnyType, types.BaseMethodFault) {
h.Runtime.InMaintenanceMode = true
return nil, nil
})
return &methods.EnterMaintenanceMode_TaskBody{
Res: &types.EnterMaintenanceMode_TaskResponse{
Returnval: task.Run(),
},
}
}
func (h *HostSystem) ExitMaintenanceModeTask(spec *types.ExitMaintenanceMode_Task) soap.HasFault {
task := CreateTask(h, "exitMaintenanceMode", func(t *Task) (types.AnyType, types.BaseMethodFault) {
h.Runtime.InMaintenanceMode = false
return nil, nil
})
return &methods.ExitMaintenanceMode_TaskBody{
Res: &types.ExitMaintenanceMode_TaskResponse{
Returnval: task.Run(),
},
}
}

View File

@ -0,0 +1,392 @@
/*
Copyright (c) 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 simulator
import (
"errors"
"fmt"
"net"
"strconv"
"strings"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
var ipPool = MustNewIpPool(&types.IpPool{
Id: 1,
Name: "ip-pool",
AvailableIpv4Addresses: 250,
AvailableIpv6Addresses: 250,
AllocatedIpv6Addresses: 0,
AllocatedIpv4Addresses: 0,
Ipv4Config: &types.IpPoolIpPoolConfigInfo{
Netmask: "10.10.10.255",
Gateway: "10.10.10.1",
SubnetAddress: "10.10.10.0",
Range: "10.10.10.2#250",
},
Ipv6Config: &types.IpPoolIpPoolConfigInfo{
Netmask: "2001:4860:0:2001::ff",
Gateway: "2001:4860:0:2001::1",
SubnetAddress: "2001:4860:0:2001::0",
Range: "2001:4860:0:2001::2#250",
},
})
// IpPoolManager implements a simple IP Pool manager in which all pools are shared
// across different datacenters.
type IpPoolManager struct {
mo.IpPoolManager
pools map[int32]*IpPool
nextPoolId int32
}
func NewIpPoolManager(ref types.ManagedObjectReference) *IpPoolManager {
m := &IpPoolManager{}
m.Self = ref
m.pools = map[int32]*IpPool{
1: ipPool,
}
m.nextPoolId = 2
return m
}
func (m *IpPoolManager) CreateIpPool(req *types.CreateIpPool) soap.HasFault {
body := &methods.CreateIpPoolBody{}
id := m.nextPoolId
var err error
m.pools[id], err = NewIpPool(&req.Pool)
if err != nil {
body.Fault_ = Fault("", &types.RuntimeFault{})
return body
}
m.nextPoolId++
body.Res = &types.CreateIpPoolResponse{
Returnval: id,
}
return body
}
func (m *IpPoolManager) DestroyIpPool(req *types.DestroyIpPool) soap.HasFault {
delete(m.pools, req.Id)
return &methods.DestroyIpPoolBody{
Res: &types.DestroyIpPoolResponse{},
}
}
func (m *IpPoolManager) QueryIpPools(req *types.QueryIpPools) soap.HasFault {
pools := []types.IpPool{}
for i := int32(1); i < m.nextPoolId; i++ {
if p, ok := m.pools[i]; ok {
pools = append(pools, *p.config)
}
}
return &methods.QueryIpPoolsBody{
Res: &types.QueryIpPoolsResponse{
Returnval: pools,
},
}
}
func (m *IpPoolManager) UpdateIpPool(req *types.UpdateIpPool) soap.HasFault {
body := &methods.UpdateIpPoolBody{}
var pool *IpPool
var err error
var ok bool
if pool, ok = m.pools[req.Pool.Id]; !ok {
body.Fault_ = Fault("", &types.NotFoundFault{})
return body
}
if pool.config.AllocatedIpv4Addresses+pool.config.AllocatedIpv6Addresses != 0 {
body.Fault_ = Fault("update a pool has been used is not supported", &types.RuntimeFault{})
return body
}
m.pools[req.Pool.Id], err = NewIpPool(&req.Pool)
if err != nil {
body.Fault_ = Fault(err.Error(), &types.RuntimeFault{})
return body
}
body.Res = &types.UpdateIpPoolResponse{}
return body
}
func (m *IpPoolManager) AllocateIpv4Address(req *types.AllocateIpv4Address) soap.HasFault {
body := &methods.AllocateIpv4AddressBody{}
pool, ok := m.pools[req.PoolId]
if !ok {
body.Fault_ = Fault("", &types.InvalidArgument{})
return body
}
ip, err := pool.AllocateIPv4(req.AllocationId)
if err != nil {
body.Fault_ = Fault(err.Error(), &types.RuntimeFault{})
return body
}
body.Res = &types.AllocateIpv4AddressResponse{
Returnval: ip,
}
return body
}
func (m *IpPoolManager) AllocateIpv6Address(req *types.AllocateIpv6Address) soap.HasFault {
body := &methods.AllocateIpv6AddressBody{}
pool, ok := m.pools[req.PoolId]
if !ok {
body.Fault_ = Fault("", &types.InvalidArgument{})
return body
}
ip, err := pool.AllocateIpv6(req.AllocationId)
if err != nil {
body.Fault_ = Fault(err.Error(), &types.RuntimeFault{})
return body
}
body.Res = &types.AllocateIpv6AddressResponse{
Returnval: ip,
}
return body
}
func (m *IpPoolManager) ReleaseIpAllocation(req *types.ReleaseIpAllocation) soap.HasFault {
body := &methods.ReleaseIpAllocationBody{}
pool, ok := m.pools[req.PoolId]
if !ok {
body.Fault_ = Fault("", &types.InvalidArgument{})
return body
}
pool.ReleaseIpv4(req.AllocationId)
pool.ReleaseIpv6(req.AllocationId)
body.Res = &types.ReleaseIpAllocationResponse{}
return body
}
func (m *IpPoolManager) QueryIPAllocations(req *types.QueryIPAllocations) soap.HasFault {
body := &methods.QueryIPAllocationsBody{}
pool, ok := m.pools[req.PoolId]
if !ok {
body.Fault_ = Fault("", &types.InvalidArgument{})
return body
}
body.Res = &types.QueryIPAllocationsResponse{}
ipv4, ok := pool.ipv4Allocation[req.ExtensionKey]
if ok {
body.Res.Returnval = append(body.Res.Returnval, types.IpPoolManagerIpAllocation{
IpAddress: ipv4,
AllocationId: req.ExtensionKey,
})
}
ipv6, ok := pool.ipv6Allocation[req.ExtensionKey]
if ok {
body.Res.Returnval = append(body.Res.Returnval, types.IpPoolManagerIpAllocation{
IpAddress: ipv6,
AllocationId: req.ExtensionKey,
})
}
return body
}
var (
errNoIpAvailable = errors.New("no ip address available")
errInvalidAllocation = errors.New("allocation id not recognized")
)
type IpPool struct {
config *types.IpPool
ipv4Allocation map[string]string
ipv6Allocation map[string]string
ipv4Pool []string
ipv6Pool []string
}
func MustNewIpPool(config *types.IpPool) *IpPool {
pool, err := NewIpPool(config)
if err != nil {
panic(err)
}
return pool
}
func NewIpPool(config *types.IpPool) (*IpPool, error) {
pool := &IpPool{
config: config,
ipv4Allocation: make(map[string]string),
ipv6Allocation: make(map[string]string),
}
return pool, pool.init()
}
func (p *IpPool) init() error {
// IPv4 range
if p.config.Ipv4Config != nil {
ranges := strings.Split(p.config.Ipv4Config.Range, ",")
for _, r := range ranges {
sp := strings.Split(r, "#")
if len(sp) != 2 {
return fmt.Errorf("format of range should be ip#number; got %q", r)
}
ip := net.ParseIP(strings.TrimSpace(sp[0])).To4()
if ip == nil {
return fmt.Errorf("bad ip format: %q", sp[0])
}
length, err := strconv.Atoi(sp[1])
if err != nil {
return err
}
for i := 0; i < length; i++ {
p.ipv4Pool = append(p.ipv4Pool, net.IPv4(ip[0], ip[1], ip[2], ip[3]+byte(i)).String())
}
}
}
// IPv6 range
if p.config.Ipv6Config != nil {
ranges := strings.Split(p.config.Ipv6Config.Range, ",")
for _, r := range ranges {
sp := strings.Split(r, "#")
if len(sp) != 2 {
return fmt.Errorf("format of range should be ip#number; got %q", r)
}
ip := net.ParseIP(strings.TrimSpace(sp[0])).To16()
if ip == nil {
return fmt.Errorf("bad ip format: %q", sp[0])
}
length, err := strconv.Atoi(sp[1])
if err != nil {
return err
}
for i := 0; i < length; i++ {
var ipv6 [16]byte
copy(ipv6[:], ip)
ipv6[15] += byte(i)
p.ipv6Pool = append(p.ipv6Pool, net.IP(ipv6[:]).String())
}
}
}
return nil
}
func (p *IpPool) AllocateIPv4(allocation string) (string, error) {
if ip, ok := p.ipv4Allocation[allocation]; ok {
return ip, nil
}
l := len(p.ipv4Pool)
if l == 0 {
return "", errNoIpAvailable
}
ip := p.ipv4Pool[l-1]
p.config.AvailableIpv4Addresses--
p.config.AllocatedIpv4Addresses++
p.ipv4Pool = p.ipv4Pool[:l-1]
p.ipv4Allocation[allocation] = ip
return ip, nil
}
func (p *IpPool) ReleaseIpv4(allocation string) error {
ip, ok := p.ipv4Allocation[allocation]
if !ok {
return errInvalidAllocation
}
delete(p.ipv4Allocation, allocation)
p.config.AvailableIpv4Addresses++
p.config.AllocatedIpv4Addresses--
p.ipv4Pool = append(p.ipv4Pool, ip)
return nil
}
func (p *IpPool) AllocateIpv6(allocation string) (string, error) {
if ip, ok := p.ipv6Allocation[allocation]; ok {
return ip, nil
}
l := len(p.ipv6Pool)
if l == 0 {
return "", errNoIpAvailable
}
ip := p.ipv6Pool[l-1]
p.config.AvailableIpv6Addresses--
p.config.AllocatedIpv6Addresses++
p.ipv6Pool = p.ipv6Pool[:l-1]
p.ipv6Allocation[allocation] = ip
return ip, nil
}
func (p *IpPool) ReleaseIpv6(allocation string) error {
ip, ok := p.ipv6Allocation[allocation]
if !ok {
return errInvalidAllocation
}
delete(p.ipv6Allocation, allocation)
p.config.AvailableIpv6Addresses++
p.config.AllocatedIpv6Addresses--
p.ipv6Pool = append(p.ipv6Pool, ip)
return nil
}

View File

@ -0,0 +1,156 @@
/*
Copyright (c) 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 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 simulator
import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
// EvalLicense is the default license
var EvalLicense = types.LicenseManagerLicenseInfo{
LicenseKey: "00000-00000-00000-00000-00000",
EditionKey: "eval",
Name: "Evaluation Mode",
Properties: []types.KeyAnyValue{
{
Key: "feature",
Value: types.KeyValue{
Key: "serialuri:2",
Value: "Remote virtual Serial Port Concentrator",
},
},
{
Key: "feature",
Value: types.KeyValue{
Key: "dvs",
Value: "vSphere Distributed Switch",
},
},
},
}
type LicenseManager struct {
mo.LicenseManager
}
func NewLicenseManager(ref types.ManagedObjectReference) object.Reference {
m := &LicenseManager{}
m.Self = ref
m.Licenses = []types.LicenseManagerLicenseInfo{EvalLicense}
if Map.IsVPX() {
am := Map.Put(&LicenseAssignmentManager{}).Reference()
m.LicenseAssignmentManager = &am
}
return m
}
func (m *LicenseManager) AddLicense(req *types.AddLicense) soap.HasFault {
body := &methods.AddLicenseBody{
Res: &types.AddLicenseResponse{},
}
for _, license := range m.Licenses {
if license.LicenseKey == req.LicenseKey {
body.Res.Returnval = licenseInfo(license.LicenseKey, license.Labels)
return body
}
}
m.Licenses = append(m.Licenses, types.LicenseManagerLicenseInfo{
LicenseKey: req.LicenseKey,
Labels: req.Labels,
})
body.Res.Returnval = licenseInfo(req.LicenseKey, req.Labels)
return body
}
func (m *LicenseManager) RemoveLicense(req *types.RemoveLicense) soap.HasFault {
body := &methods.RemoveLicenseBody{
Res: &types.RemoveLicenseResponse{},
}
for i, license := range m.Licenses {
if req.LicenseKey == license.LicenseKey {
m.Licenses = append(m.Licenses[:i], m.Licenses[i+1:]...)
return body
}
}
return body
}
type LicenseAssignmentManager struct {
mo.LicenseAssignmentManager
}
func (m *LicenseAssignmentManager) QueryAssignedLicenses(req *types.QueryAssignedLicenses) soap.HasFault {
body := &methods.QueryAssignedLicensesBody{
Res: &types.QueryAssignedLicensesResponse{},
}
// EntityId can be a HostSystem or the vCenter InstanceUuid
if req.EntityId != "" {
if req.EntityId != Map.content().About.InstanceUuid {
id := types.ManagedObjectReference{
Type: "HostSystem",
Value: req.EntityId,
}
if Map.Get(id) == nil {
return body
}
}
}
body.Res.Returnval = []types.LicenseAssignmentManagerLicenseAssignment{
{
EntityId: req.EntityId,
AssignedLicense: EvalLicense,
},
}
return body
}
func licenseInfo(key string, labels []types.KeyValue) types.LicenseManagerLicenseInfo {
info := EvalLicense
info.LicenseKey = key
info.Labels = labels
return info
}

484
vendor/github.com/vmware/govmomi/simulator/model.go generated vendored Normal file
View File

@ -0,0 +1,484 @@
/*
Copyright (c) 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 simulator
import (
"context"
"fmt"
"io/ioutil"
"os"
"path"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/simulator/vpx"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// Model is used to populate a Model with an initial set of managed entities.
// This is a simple helper for tests running against a simulator, to populate an inventory
// with commonly used models.
type Model struct {
Service *Service
ServiceContent types.ServiceContent
RootFolder mo.Folder
// Autostart will power on Model created VMs when true
Autostart bool
// Datacenter specifies the number of Datacenter entities to create
Datacenter int
// Portgroup specifies the number of DistributedVirtualPortgroup entities to create per Datacenter
Portgroup int
// Host specifies the number of standalone HostSystems entities to create per Datacenter
Host int
// Cluster specifies the number of ClusterComputeResource entities to create per Datacenter
Cluster int
// ClusterHost specifies the number of HostSystems entities to create within a Cluster
ClusterHost int
// Pool specifies the number of ResourcePool entities to create per Cluster
Pool int
// Datastore specifies the number of Datastore entities to create
// Each Datastore will have temporary local file storage and will be mounted
// on every HostSystem created by the ModelConfig
Datastore int
// Machine specifies the number of VirtualMachine entities to create per ResourcePool
Machine int
// Folder specifies the number of Datacenter to place within a Folder.
// This includes a folder for the Datacenter itself and its host, vm, network and datastore folders.
// All resources for the Datacenter are placed within these folders, rather than the top-level folders.
Folder int
// App specifies the number of VirtualApp to create per Cluster
App int
// Pod specifies the number of StoragePod to create per Cluster
Pod int
// total number of inventory objects, set by Count()
total int
dirs []string
}
// ESX is the default Model for a standalone ESX instance
func ESX() *Model {
return &Model{
ServiceContent: esx.ServiceContent,
RootFolder: esx.RootFolder,
Autostart: true,
Datastore: 1,
Machine: 2,
}
}
// VPX is the default Model for a vCenter instance
func VPX() *Model {
return &Model{
ServiceContent: vpx.ServiceContent,
RootFolder: vpx.RootFolder,
Autostart: true,
Datacenter: 1,
Portgroup: 1,
Host: 1,
Cluster: 1,
ClusterHost: 3,
Datastore: 1,
Machine: 2,
}
}
// Count returns a Model with total number of each existing type
func (m *Model) Count() Model {
count := Model{}
for ref, obj := range Map.objects {
if _, ok := obj.(mo.Entity); !ok {
continue
}
count.total++
switch ref.Type {
case "Datacenter":
count.Datacenter++
case "DistributedVirtualPortgroup":
count.Portgroup++
case "ClusterComputeResource":
count.Cluster++
case "Datastore":
count.Datastore++
case "HostSystem":
count.Host++
case "VirtualMachine":
count.Machine++
case "ResourcePool":
count.Pool++
case "VirtualApp":
count.App++
case "Folder":
count.Folder++
case "StoragePod":
count.Pod++
}
}
return count
}
func (*Model) fmtName(prefix string, num int) string {
return fmt.Sprintf("%s%d", prefix, num)
}
// Create populates the Model with the given ModelConfig
func (m *Model) Create() error {
m.Service = New(NewServiceInstance(m.ServiceContent, m.RootFolder))
ctx := context.Background()
client := m.Service.client
root := object.NewRootFolder(client)
// After all hosts are created, this var is used to mount the host datastores.
var hosts []*object.HostSystem
// We need to defer VM creation until after the datastores are created.
var vms []func() error
// 1 DVS per DC, added to all hosts
var dvs *object.DistributedVirtualSwitch
// 1 NIC per VM, backed by a DVPG if Model.Portgroup > 0
vmnet := esx.EthernetCard.Backing
// addHost adds a cluster host or a stanalone host.
addHost := func(name string, f func(types.HostConnectSpec) (*object.Task, error)) (*object.HostSystem, error) {
spec := types.HostConnectSpec{
HostName: name,
}
task, err := f(spec)
if err != nil {
return nil, err
}
info, err := task.WaitForResult(context.Background(), nil)
if err != nil {
return nil, err
}
host := object.NewHostSystem(client, info.Result.(types.ManagedObjectReference))
hosts = append(hosts, host)
if dvs != nil {
config := &types.DVSConfigSpec{
Host: []types.DistributedVirtualSwitchHostMemberConfigSpec{{
Operation: string(types.ConfigSpecOperationAdd),
Host: host.Reference(),
}},
}
_, _ = dvs.Reconfigure(ctx, config)
}
return host, nil
}
// addMachine returns a func to create a VM.
addMachine := func(prefix string, host *object.HostSystem, pool *object.ResourcePool, folders *object.DatacenterFolders) {
nic := esx.EthernetCard
nic.Backing = vmnet
ds := types.ManagedObjectReference{}
f := func() error {
for i := 0; i < m.Machine; i++ {
name := m.fmtName(prefix+"_VM", i)
config := types.VirtualMachineConfigSpec{
Name: name,
GuestId: string(types.VirtualMachineGuestOsIdentifierOtherGuest),
Files: &types.VirtualMachineFileInfo{
VmPathName: "[LocalDS_0]",
},
}
if pool == nil {
pool, _ = host.ResourcePool(ctx)
}
var devices object.VirtualDeviceList
scsi, _ := devices.CreateSCSIController("pvscsi")
ide, _ := devices.CreateIDEController()
cdrom, _ := devices.CreateCdrom(ide.(*types.VirtualIDEController))
disk := devices.CreateDisk(scsi.(types.BaseVirtualController), ds,
config.Files.VmPathName+" "+path.Join(name, "disk1.vmdk"))
devices = append(devices, scsi, cdrom, disk, &nic)
config.DeviceChange, _ = devices.ConfigSpec(types.VirtualDeviceConfigSpecOperationAdd)
task, err := folders.VmFolder.CreateVM(ctx, config, pool, host)
if err != nil {
return err
}
info, err := task.WaitForResult(ctx, nil)
if err != nil {
return err
}
vm := object.NewVirtualMachine(client, info.Result.(types.ManagedObjectReference))
if m.Autostart {
_, _ = vm.PowerOn(ctx)
}
}
return nil
}
vms = append(vms, f)
}
nfolder := 0
for ndc := 0; ndc < m.Datacenter; ndc++ {
dcName := m.fmtName("DC", ndc)
folder := root
fName := m.fmtName("F", nfolder)
// If Datacenter > Folder, don't create folders for the first N DCs.
if nfolder < m.Folder && ndc >= (m.Datacenter-m.Folder) {
f, err := folder.CreateFolder(ctx, fName)
if err != nil {
return err
}
folder = f
}
dc, err := folder.CreateDatacenter(ctx, dcName)
if err != nil {
return err
}
folders, err := dc.Folders(ctx)
if err != nil {
return err
}
if m.Pod > 0 {
for pod := 0; pod < m.Pod; pod++ {
_, _ = folders.DatastoreFolder.CreateStoragePod(ctx, m.fmtName(dcName+"_POD", pod))
}
}
if folder != root {
// Create sub-folders and use them to create any resources that follow
subs := []**object.Folder{&folders.DatastoreFolder, &folders.HostFolder, &folders.NetworkFolder, &folders.VmFolder}
for _, sub := range subs {
f, err := (*sub).CreateFolder(ctx, fName)
if err != nil {
return err
}
*sub = f
}
nfolder++
}
if m.Portgroup > 0 {
var spec types.DVSCreateSpec
spec.ConfigSpec = &types.VMwareDVSConfigSpec{}
spec.ConfigSpec.GetDVSConfigSpec().Name = m.fmtName("DVS", 0)
task, err := folders.NetworkFolder.CreateDVS(ctx, spec)
if err != nil {
return err
}
info, err := task.WaitForResult(ctx, nil)
if err != nil {
return err
}
dvs = object.NewDistributedVirtualSwitch(client, info.Result.(types.ManagedObjectReference))
for npg := 0; npg < m.Portgroup; npg++ {
name := m.fmtName(dcName+"_DVPG", npg)
task, err = dvs.AddPortgroup(ctx, []types.DVPortgroupConfigSpec{{Name: name}})
if err != nil {
return err
}
err = task.Wait(ctx)
if err != nil {
return err
}
// Use the 1st DVPG for the VMs eth0 backing
if npg == 0 {
// AddPortgroup_Task does not return the moid, so we look it up by name
net := Map.Get(folders.NetworkFolder.Reference()).(*Folder)
pg := Map.FindByName(name, net.ChildEntity)
vmnet, _ = object.NewDistributedVirtualPortgroup(client, pg.Reference()).EthernetCardBackingInfo(ctx)
}
}
}
for nhost := 0; nhost < m.Host; nhost++ {
name := m.fmtName(dcName+"_H", nhost)
host, err := addHost(name, func(spec types.HostConnectSpec) (*object.Task, error) {
return folders.HostFolder.AddStandaloneHost(ctx, spec, true, nil, nil)
})
if err != nil {
return err
}
addMachine(name, host, nil, folders)
}
for ncluster := 0; ncluster < m.Cluster; ncluster++ {
clusterName := m.fmtName(dcName+"_C", ncluster)
cluster, err := folders.HostFolder.CreateCluster(ctx, clusterName, types.ClusterConfigSpecEx{})
if err != nil {
return err
}
for nhost := 0; nhost < m.ClusterHost; nhost++ {
name := m.fmtName(clusterName+"_H", nhost)
_, err = addHost(name, func(spec types.HostConnectSpec) (*object.Task, error) {
return cluster.AddHost(ctx, spec, true, nil, nil)
})
if err != nil {
return err
}
}
pool, err := cluster.ResourcePool(ctx)
if err != nil {
return err
}
prefix := clusterName + "_RP"
addMachine(prefix+"0", nil, pool, folders)
for npool := 1; npool <= m.Pool; npool++ {
spec := types.DefaultResourceConfigSpec()
_, err = pool.Create(ctx, m.fmtName(prefix, npool), spec)
if err != nil {
return err
}
}
prefix = clusterName + "_APP"
for napp := 0; napp < m.App; napp++ {
rspec := types.DefaultResourceConfigSpec()
vspec := NewVAppConfigSpec()
name := m.fmtName(prefix, napp)
vapp, err := pool.CreateVApp(ctx, name, rspec, vspec, nil)
if err != nil {
return err
}
addMachine(name, nil, vapp.ResourcePool, folders)
}
}
}
if m.ServiceContent.RootFolder == esx.RootFolder.Reference() {
// ESX model
host := object.NewHostSystem(client, esx.HostSystem.Reference())
hosts = append(hosts, host)
dc := object.NewDatacenter(client, esx.Datacenter.Reference())
folders, err := dc.Folders(ctx)
if err != nil {
return err
}
addMachine(host.Reference().Value, host, nil, folders)
}
for i := 0; i < m.Datastore; i++ {
err := m.createLocalDatastore(m.fmtName("LocalDS_", i), hosts)
if err != nil {
return err
}
}
for _, createVM := range vms {
err := createVM()
if err != nil {
return err
}
}
return nil
}
var tempDir = func() (string, error) {
return ioutil.TempDir("", "govcsim-")
}
func (m *Model) createLocalDatastore(name string, hosts []*object.HostSystem) error {
ctx := context.Background()
dir, err := tempDir()
if err != nil {
return err
}
m.dirs = append(m.dirs, dir)
for _, host := range hosts {
dss, err := host.ConfigManager().DatastoreSystem(ctx)
if err != nil {
return err
}
_, err = dss.CreateLocalDatastore(ctx, name, dir)
if err != nil {
return err
}
}
return nil
}
// Remove cleans up items created by the Model, such as local datastore directories
func (m *Model) Remove() {
for _, dir := range m.dirs {
_ = os.RemoveAll(dir)
}
}

View File

@ -0,0 +1,59 @@
/*
Copyright (c) 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 simulator
import (
"strings"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type OptionManager struct {
mo.OptionManager
}
func NewOptionManager(ref *types.ManagedObjectReference, setting []types.BaseOptionValue) object.Reference {
s := &OptionManager{}
if ref != nil {
s.Self = *ref
}
s.Setting = setting
return s
}
func (m *OptionManager) QueryOptions(req *types.QueryOptions) soap.HasFault {
body := &methods.QueryOptionsBody{}
res := &types.QueryOptionsResponse{}
for _, opt := range m.Setting {
if strings.HasPrefix(opt.GetOptionValue().Key, req.Name) {
res.Returnval = append(res.Returnval, opt)
}
}
if len(res.Returnval) == 0 {
body.Fault_ = Fault("", &types.InvalidName{Name: req.Name})
} else {
body.Res = res
}
return body
}

38
vendor/github.com/vmware/govmomi/simulator/os_unix.go generated vendored Normal file
View File

@ -0,0 +1,38 @@
/*
Copyright (c) 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 simulator
import "syscall"
func (ds *Datastore) stat() error {
info := ds.Info.GetDatastoreInfo()
var stat syscall.Statfs_t
err := syscall.Statfs(info.Url, &stat)
if err != nil {
return err
}
bsize := uint64(stat.Bsize) / 512
info.FreeSpace = int64(stat.Bfree*bsize) >> 1
ds.Summary.FreeSpace = info.FreeSpace
ds.Summary.Capacity = int64(stat.Blocks*bsize) >> 1
return nil
}

View File

@ -0,0 +1,26 @@
/*
Copyright (c) 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 simulator
import "os"
func (ds *Datastore) stat() error {
info := ds.Info.GetDatastoreInfo()
_, err := os.Stat(info.Url)
return err
}

View File

@ -0,0 +1,35 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
type PerformanceManager struct {
mo.PerformanceManager
}
func NewPerformanceManager(ref types.ManagedObjectReference) object.Reference {
m := &PerformanceManager{}
m.Self = ref
m.PerfCounter = esx.PerfCounter
return m
}

View File

@ -0,0 +1,82 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type DistributedVirtualPortgroup struct {
mo.DistributedVirtualPortgroup
}
func (s *DistributedVirtualPortgroup) ReconfigureDVPortgroupTask(req *types.ReconfigureDVPortgroup_Task) soap.HasFault {
task := CreateTask(s, "reconfigureDvPortgroup", func(t *Task) (types.AnyType, types.BaseMethodFault) {
s.Config.DefaultPortConfig = req.Spec.DefaultPortConfig
s.Config.NumPorts = req.Spec.NumPorts
s.Config.AutoExpand = req.Spec.AutoExpand
s.Config.Type = req.Spec.Type
s.Config.Description = req.Spec.Description
s.Config.DynamicData = req.Spec.DynamicData
s.Config.Name = req.Spec.Name
s.Config.Policy = req.Spec.Policy
s.Config.PortNameFormat = req.Spec.PortNameFormat
s.Config.VmVnicNetworkResourcePoolKey = req.Spec.VmVnicNetworkResourcePoolKey
return nil, nil
})
return &methods.ReconfigureDVPortgroup_TaskBody{
Res: &types.ReconfigureDVPortgroup_TaskResponse{
Returnval: task.Run(),
},
}
}
func (s *DistributedVirtualPortgroup) DestroyTask(req *types.Destroy_Task) soap.HasFault {
task := CreateTask(s, "destroy", func(t *Task) (types.AnyType, types.BaseMethodFault) {
vswitch := Map.Get(*s.Config.DistributedVirtualSwitch).(*DistributedVirtualSwitch)
for i, pg := range vswitch.Portgroup {
if pg.Reference() == s.Reference() {
vswitch.Portgroup = append(vswitch.Portgroup[:i], vswitch.Portgroup[i+1:]...)
break
}
}
f := Map.getEntityParent(vswitch, "Folder").(*Folder)
f.removeChild(s.Reference())
for i, name := range vswitch.Summary.PortgroupName {
if name == s.Name {
vswitch.Summary.PortgroupName = append(vswitch.Summary.PortgroupName[:i],
vswitch.Summary.PortgroupName[i+1:]...)
}
}
return nil, nil
})
return &methods.Destroy_TaskBody{
Res: &types.Destroy_TaskResponse{
Returnval: task.Run(),
},
}
}

View File

@ -0,0 +1,548 @@
/*
Copyright (c) 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 simulator
import (
"errors"
"log"
"path"
"reflect"
"strings"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type PropertyCollector struct {
mo.PropertyCollector
}
func NewPropertyCollector(ref types.ManagedObjectReference) object.Reference {
s := &PropertyCollector{}
s.Self = ref
return s
}
var errMissingField = errors.New("missing field")
var errEmptyField = errors.New("empty field")
func getObject(ref types.ManagedObjectReference) (reflect.Value, bool) {
obj := Map.Get(ref)
if obj == nil {
return reflect.Value{}, false
}
rval := reflect.ValueOf(obj).Elem()
rtype := rval.Type()
// PropertyCollector is for Managed Object types only (package mo).
// If the registry object is not in the mo package, assume it is a wrapper
// type where the first field is an embedded mo type.
// We need to dig out the mo type for PropSet.All to work properly and
// for the case where the type has a field of the same name, for example:
// mo.ResourcePool.ResourcePool
for {
if path.Base(rtype.PkgPath()) != "mo" {
if rtype.Kind() != reflect.Struct || rtype.NumField() == 0 {
log.Printf("%#v does not have an embedded mo type", ref)
return reflect.Value{}, false
}
rval = rval.Field(0)
rtype = rval.Type()
} else {
break
}
}
return rval, true
}
func fieldValueInterface(f reflect.StructField, rval reflect.Value) interface{} {
if rval.Kind() == reflect.Ptr {
rval = rval.Elem()
}
pval := rval.Interface()
if rval.Kind() == reflect.Slice {
// Convert slice to types.ArrayOf*
switch v := pval.(type) {
case []string:
pval = &types.ArrayOfString{
String: v,
}
case []int32:
pval = &types.ArrayOfInt{
Int: v,
}
default:
kind := f.Type.Elem().Name()
// Remove govmomi interface prefix name
if strings.HasPrefix(kind, "Base") {
kind = kind[4:]
}
akind, _ := typeFunc("ArrayOf" + kind)
a := reflect.New(akind)
a.Elem().FieldByName(kind).Set(rval)
pval = a.Interface()
}
}
return pval
}
func fieldValue(rval reflect.Value, p string) (interface{}, error) {
var value interface{}
fields := strings.Split(p, ".")
for i, name := range fields {
kind := rval.Type().Kind()
if kind == reflect.Interface {
if rval.IsNil() {
continue
}
rval = rval.Elem()
kind = rval.Type().Kind()
}
if kind == reflect.Ptr {
if rval.IsNil() {
continue
}
rval = rval.Elem()
}
x := ucFirst(name)
val := rval.FieldByName(x)
if !val.IsValid() {
return nil, errMissingField
}
if isEmpty(val) {
return nil, errEmptyField
}
if i == len(fields)-1 {
ftype, _ := rval.Type().FieldByName(x)
value = fieldValueInterface(ftype, val)
break
}
rval = val
}
return value, nil
}
func fieldRefs(f interface{}) []types.ManagedObjectReference {
switch fv := f.(type) {
case types.ManagedObjectReference:
return []types.ManagedObjectReference{fv}
case *types.ArrayOfManagedObjectReference:
return fv.ManagedObjectReference
case nil:
// empty field
}
return nil
}
func isEmpty(rval reflect.Value) bool {
switch rval.Kind() {
case reflect.Ptr:
return rval.IsNil()
case reflect.String, reflect.Slice:
return rval.Len() == 0
}
return false
}
func isTrue(v *bool) bool {
return v != nil && *v
}
func isFalse(v *bool) bool {
return v == nil || *v == false
}
func lcFirst(s string) string {
return strings.ToLower(s[:1]) + s[1:]
}
func ucFirst(s string) string {
return strings.ToUpper(s[:1]) + s[1:]
}
type retrieveResult struct {
*types.RetrieveResult
req *types.RetrievePropertiesEx
collected map[types.ManagedObjectReference]bool
specs map[string]*types.TraversalSpec
}
func (rr *retrieveResult) collectAll(rval reflect.Value, rtype reflect.Type, content *types.ObjectContent) {
for i := 0; i < rval.NumField(); i++ {
val := rval.Field(i)
f := rtype.Field(i)
if isEmpty(val) || f.Name == "Self" {
continue
}
if f.Anonymous {
// recurse into embedded field
rr.collectAll(val, f.Type, content)
continue
}
content.PropSet = append(content.PropSet, types.DynamicProperty{
Name: lcFirst(f.Name),
Val: fieldValueInterface(f, val),
})
}
}
func (rr *retrieveResult) collectFields(rval reflect.Value, fields []string, content *types.ObjectContent) {
seen := make(map[string]bool)
for i := range content.PropSet {
seen[content.PropSet[i].Name] = true // mark any already collected via embedded field
}
for _, name := range fields {
if seen[name] {
// rvc 'ls' includes the "name" property twice, then fails with no error message or stack trace
// in RbVmomi::VIM::ObjectContent.to_hash_uncached when it sees the 2nd "name" property.
continue
}
seen[name] = true
val, err := fieldValue(rval, name)
if err == nil {
prop := types.DynamicProperty{
Name: name,
Val: val,
}
content.PropSet = append(content.PropSet, prop)
continue
}
switch err {
case errEmptyField:
// ok
case errMissingField:
content.MissingSet = append(content.MissingSet, types.MissingProperty{
Path: name,
Fault: types.LocalizedMethodFault{Fault: &types.InvalidProperty{
Name: name,
}},
})
}
}
}
func (rr *retrieveResult) collect(ref types.ManagedObjectReference) {
if rr.collected[ref] {
return
}
content := types.ObjectContent{
Obj: ref,
}
rval, ok := getObject(ref)
if !ok {
// Possible if a test uses Map.Remove instead of Destroy_Task
log.Printf("object %s no longer exists", ref)
return
}
rtype := rval.Type()
for _, spec := range rr.req.SpecSet {
for _, p := range spec.PropSet {
if p.Type != ref.Type {
// e.g. ManagedEntity, ComputeResource
field, ok := rtype.FieldByName(p.Type)
if !(ok && field.Anonymous) {
continue
}
}
if isTrue(p.All) {
rr.collectAll(rval, rtype, &content)
continue
}
rr.collectFields(rval, p.PathSet, &content)
}
}
if len(content.PropSet) != 0 || len(content.MissingSet) != 0 {
rr.Objects = append(rr.Objects, content)
}
rr.collected[ref] = true
}
func (rr *retrieveResult) selectSet(obj reflect.Value, s []types.BaseSelectionSpec, refs *[]types.ManagedObjectReference) types.BaseMethodFault {
for _, ss := range s {
ts, ok := ss.(*types.TraversalSpec)
if ok {
if ts.Name != "" {
rr.specs[ts.Name] = ts
}
}
}
for _, ss := range s {
ts, ok := ss.(*types.TraversalSpec)
if !ok {
ts = rr.specs[ss.GetSelectionSpec().Name]
if ts == nil {
return &types.InvalidArgument{InvalidProperty: "undefined TraversalSpec name"}
}
}
f, _ := fieldValue(obj, ts.Path)
for _, ref := range fieldRefs(f) {
if isFalse(ts.Skip) {
*refs = append(*refs, ref)
}
rval, ok := getObject(ref)
if ok {
if err := rr.selectSet(rval, ts.SelectSet, refs); err != nil {
return err
}
}
}
}
return nil
}
func (pc *PropertyCollector) collect(r *types.RetrievePropertiesEx) (*types.RetrieveResult, types.BaseMethodFault) {
var refs []types.ManagedObjectReference
rr := &retrieveResult{
RetrieveResult: &types.RetrieveResult{},
req: r,
collected: make(map[types.ManagedObjectReference]bool),
specs: make(map[string]*types.TraversalSpec),
}
// Select object references
for _, spec := range r.SpecSet {
for _, o := range spec.ObjectSet {
rval, ok := getObject(o.Obj)
if !ok {
if isFalse(spec.ReportMissingObjectsInResults) {
return nil, &types.ManagedObjectNotFound{Obj: o.Obj}
}
continue
}
if o.SelectSet == nil || isFalse(o.Skip) {
refs = append(refs, o.Obj)
}
if err := rr.selectSet(rval, o.SelectSet, &refs); err != nil {
return nil, err
}
}
}
for _, ref := range refs {
rr.collect(ref)
}
return rr.RetrieveResult, nil
}
func (pc *PropertyCollector) CreateFilter(c *types.CreateFilter) soap.HasFault {
body := &methods.CreateFilterBody{}
filter := &PropertyFilter{pc: pc}
filter.PartialUpdates = c.PartialUpdates
filter.Spec = c.Spec
pc.Filter = append(pc.Filter, Map.Put(filter).Reference())
body.Res = &types.CreateFilterResponse{
Returnval: filter.Self,
}
return body
}
func (pc *PropertyCollector) CreatePropertyCollector(c *types.CreatePropertyCollector) soap.HasFault {
body := &methods.CreatePropertyCollectorBody{}
cpc := &PropertyCollector{}
body.Res = &types.CreatePropertyCollectorResponse{
Returnval: Map.Put(cpc).Reference(),
}
return body
}
func (pc *PropertyCollector) DestroyPropertyCollector(c *types.DestroyPropertyCollector) soap.HasFault {
body := &methods.DestroyPropertyCollectorBody{}
for _, ref := range pc.Filter {
filter := Map.Get(ref).(*PropertyFilter)
filter.DestroyPropertyFilter(&types.DestroyPropertyFilter{This: ref})
}
Map.Remove(c.This)
body.Res = &types.DestroyPropertyCollectorResponse{}
return body
}
func (pc *PropertyCollector) RetrievePropertiesEx(r *types.RetrievePropertiesEx) soap.HasFault {
body := &methods.RetrievePropertiesExBody{}
res, fault := pc.collect(r)
if fault != nil {
body.Fault_ = Fault("", fault)
} else {
body.Res = &types.RetrievePropertiesExResponse{
Returnval: res,
}
}
return body
}
// RetrieveProperties is deprecated, but govmomi is still using it at the moment.
func (pc *PropertyCollector) RetrieveProperties(r *types.RetrieveProperties) soap.HasFault {
body := &methods.RetrievePropertiesBody{}
res := pc.RetrievePropertiesEx(&types.RetrievePropertiesEx{
This: r.This,
SpecSet: r.SpecSet,
})
if res.Fault() != nil {
body.Fault_ = res.Fault()
} else {
body.Res = &types.RetrievePropertiesResponse{
Returnval: res.(*methods.RetrievePropertiesExBody).Res.Returnval.Objects,
}
}
return body
}
func (pc *PropertyCollector) CancelWaitForUpdates(r *types.CancelWaitForUpdates) soap.HasFault {
return &methods.CancelWaitForUpdatesBody{Res: new(types.CancelWaitForUpdatesResponse)}
}
func (pc *PropertyCollector) WaitForUpdatesEx(r *types.WaitForUpdatesEx) soap.HasFault {
body := &methods.WaitForUpdatesExBody{}
// At the moment we need to support Task completion. Handlers can simply set the Task
// state before returning and the non-incremental update is enough for the client.
// We can wait for incremental updates to simulate timeouts, etc.
if r.Version != "" {
body.Fault_ = Fault("incremental updates not supported yet", &types.NotSupported{})
return body
}
update := &types.UpdateSet{
Version: "-",
}
for _, ref := range pc.Filter {
filter := Map.Get(ref).(*PropertyFilter)
r := &types.RetrievePropertiesEx{}
r.SpecSet = append(r.SpecSet, filter.Spec)
res, fault := pc.collect(r)
if fault != nil {
body.Fault_ = Fault("", fault)
return body
}
fu := types.PropertyFilterUpdate{
Filter: ref,
}
for _, o := range res.Objects {
ou := types.ObjectUpdate{
Obj: o.Obj,
Kind: types.ObjectUpdateKindEnter,
}
for _, p := range o.PropSet {
ou.ChangeSet = append(ou.ChangeSet, types.PropertyChange{
Op: types.PropertyChangeOpAssign,
Name: p.Name,
Val: p.Val,
})
}
fu.ObjectSet = append(fu.ObjectSet, ou)
}
update.FilterSet = append(update.FilterSet, fu)
}
body.Res = &types.WaitForUpdatesExResponse{
Returnval: update,
}
return body
}
// WaitForUpdates is deprecated, but pyvmomi is still using it at the moment.
func (pc *PropertyCollector) WaitForUpdates(r *types.WaitForUpdates) soap.HasFault {
body := &methods.WaitForUpdatesBody{}
res := pc.WaitForUpdatesEx(&types.WaitForUpdatesEx{
This: r.This,
Version: r.Version,
})
if res.Fault() != nil {
body.Fault_ = res.Fault()
} else {
body.Res = &types.WaitForUpdatesResponse{
Returnval: *res.(*methods.WaitForUpdatesExBody).Res.Returnval,
}
}
return body
}

View File

@ -0,0 +1,42 @@
/*
Copyright (c) 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 simulator
import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type PropertyFilter struct {
mo.PropertyFilter
pc *PropertyCollector
}
func (f *PropertyFilter) DestroyPropertyFilter(c *types.DestroyPropertyFilter) soap.HasFault {
body := &methods.DestroyPropertyFilterBody{}
f.pc.Filter = RemoveReference(c.This, f.pc.Filter)
Map.Remove(c.This)
body.Res = &types.DestroyPropertyFilterResponse{}
return body
}

Some files were not shown because too many files have changed in this diff Show More