mirror of
https://github.com/docker/docs.git
synced 2026-11-05 00:14:17 +03:00
Godeps save and enable commands
Signed-off-by: Fabio Rapposelli <frapposelli@vmware.com>
This commit is contained in:
5
Godeps/Godeps.json
generated
5
Godeps/Godeps.json
generated
@@ -129,6 +129,11 @@
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/googleapi",
|
||||
"Rev": "aa91ac681e18e52b1a0dfe29b9d8354e88c0dcf5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govcloudair",
|
||||
"Comment": "v0.0.1-1-g9672590",
|
||||
"Rev": "9672590d5e5795b2d29fce97084fd5810665fc27"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
25
Godeps/_workspace/src/github.com/vmware/govcloudair/.gitignore
generated
vendored
Normal file
25
Godeps/_workspace/src/github.com/vmware/govcloudair/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
.cover
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
10
Godeps/_workspace/src/github.com/vmware/govcloudair/.travis.yml
generated
vendored
Normal file
10
Godeps/_workspace/src/github.com/vmware/govcloudair/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
language: go
|
||||
|
||||
install:
|
||||
- go get -t ./...
|
||||
- go get code.google.com/p/go.tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
script:
|
||||
- PATH="$HOME/gopath/bin:$PATH"
|
||||
- script/coverage --coveralls
|
||||
569
Godeps/_workspace/src/github.com/vmware/govcloudair/LICENSE
generated
vendored
Normal file
569
Godeps/_workspace/src/github.com/vmware/govcloudair/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,569 @@
|
||||
govcloudair is distributed under the Apache License 2.0
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2014 Fabio Rapposelli
|
||||
|
||||
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.
|
||||
|
||||
|
||||
testutil/http.go is distributed with a Mozilla Public License 2.0
|
||||
|
||||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
7
Godeps/_workspace/src/github.com/vmware/govcloudair/Readme.md
generated
vendored
Normal file
7
Godeps/_workspace/src/github.com/vmware/govcloudair/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
## govcloudair
|
||||
|
||||
This package provides the `govcloudair` package which offers an interface to the vCloud Air 5.6 API.
|
||||
|
||||
It serves as a foundation for a project currently in development, there are plans to make it a general purpose API in the future.
|
||||
|
||||
The API is currently under heavy development, its coverage is extremely limited at the moment.
|
||||
404
Godeps/_workspace/src/github.com/vmware/govcloudair/api.go
generated
vendored
Normal file
404
Godeps/_workspace/src/github.com/vmware/govcloudair/api.go
generated
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
// Package govcloudair provides a simple binding for vCloud Air REST APIs.
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
// Client provides a client to vCloud Air, values can be populated automatically using the Authenticate method.
|
||||
type Client struct {
|
||||
VAToken string // vCloud Air authorization token
|
||||
VAEndpoint url.URL // vCloud Air API endpoint
|
||||
Region string // Region where the compute resource lives.
|
||||
VCDToken string // Access Token (authorization header)
|
||||
VCDAuthHeader string // Authorization header
|
||||
VCDVDCHREF url.URL // HREF of the backend VDC you're using
|
||||
Http http.Client // HttpClient is the client to use. Default will be used if not provided.
|
||||
}
|
||||
|
||||
// VCHS API
|
||||
|
||||
type services struct {
|
||||
Service []struct {
|
||||
Region string `xml:"region,attr"`
|
||||
ServiceID string `xml:"serviceId,attr"`
|
||||
ServiceType string `xml:"serviceType,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
HREF string `xml:"href,attr"`
|
||||
} `xml:"Service"`
|
||||
}
|
||||
|
||||
type session struct {
|
||||
Link []*types.Link `xml:"Link"`
|
||||
}
|
||||
|
||||
type computeResources struct {
|
||||
VdcRef []struct {
|
||||
Status string `xml:"status,attr"`
|
||||
Name string `xml:"name,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
HREF string `xml:"href,attr"`
|
||||
Link []*types.Link `xml:"Link"`
|
||||
} `xml:"VdcRef"`
|
||||
}
|
||||
|
||||
type vCloudSession struct {
|
||||
VdcLink []struct {
|
||||
AuthorizationToken string `xml:"authorizationToken,attr"`
|
||||
AuthorizationHeader string `xml:"authorizationHeader,attr"`
|
||||
Name string `xml:"name,attr"`
|
||||
HREF string `xml:"href,attr"`
|
||||
} `xml:"VdcLink"`
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
func (c *Client) vaauthorize(user, pass string) (u url.URL, err error) {
|
||||
|
||||
if user == "" {
|
||||
user = os.Getenv("VCLOUDAIR_USERNAME")
|
||||
}
|
||||
|
||||
if pass == "" {
|
||||
pass = os.Getenv("VCLOUDAIR_PASSWORD")
|
||||
}
|
||||
|
||||
s := c.VAEndpoint
|
||||
s.Path += "/vchs/sessions"
|
||||
|
||||
// No point in checking for errors here
|
||||
req := c.NewRequest(map[string]string{}, "POST", s, nil)
|
||||
|
||||
// Set Basic Authentication Header
|
||||
req.SetBasicAuth(user, pass)
|
||||
|
||||
// Add the Accept header for vCA
|
||||
req.Header.Add("Accept", "application/xml;version=5.6")
|
||||
|
||||
resp, err := checkResp(c.Http.Do(req))
|
||||
if err != nil {
|
||||
return url.URL{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Store the authentication header
|
||||
c.VAToken = resp.Header.Get("X-Vchs-Authorization")
|
||||
|
||||
session := new(session)
|
||||
|
||||
if err = decodeBody(resp, session); err != nil {
|
||||
return url.URL{}, fmt.Errorf("error decoding session response: %s", err)
|
||||
}
|
||||
|
||||
// Loop in the session struct to find right service and compute resource.
|
||||
for _, s := range session.Link {
|
||||
if s.Type == "application/xml;class=vnd.vmware.vchs.servicelist" && s.Rel == "down" {
|
||||
u, err := url.ParseRequestURI(s.HREF)
|
||||
return *u, err
|
||||
}
|
||||
}
|
||||
return url.URL{}, fmt.Errorf("couldn't find a Service List in current session")
|
||||
}
|
||||
|
||||
func (c *Client) vaacquireservice(s url.URL, cid string) (u url.URL, err error) {
|
||||
|
||||
if cid == "" {
|
||||
cid = os.Getenv("VCLOUDAIR_COMPUTEID")
|
||||
}
|
||||
|
||||
req := c.NewRequest(map[string]string{}, "GET", s, nil)
|
||||
|
||||
// Add the Accept header for vCA
|
||||
req.Header.Add("Accept", "application/xml;version=5.6")
|
||||
|
||||
// Set Authorization Header for vCA
|
||||
req.Header.Add("x-vchs-authorization", c.VAToken)
|
||||
|
||||
resp, err := checkResp(c.Http.Do(req))
|
||||
if err != nil {
|
||||
return url.URL{}, fmt.Errorf("error processing compute action: %s", err)
|
||||
}
|
||||
|
||||
services := new(services)
|
||||
|
||||
if err = decodeBody(resp, services); err != nil {
|
||||
return url.URL{}, fmt.Errorf("error decoding services response: %s", err)
|
||||
}
|
||||
|
||||
// Loop in the Services struct to find right service and compute resource.
|
||||
for _, s := range services.Service {
|
||||
if s.ServiceID == cid {
|
||||
c.Region = s.Region
|
||||
u, err := url.ParseRequestURI(s.HREF)
|
||||
return *u, err
|
||||
}
|
||||
}
|
||||
return url.URL{}, fmt.Errorf("couldn't find a Compute Resource in current service list")
|
||||
}
|
||||
|
||||
func (c *Client) vaacquirecompute(s url.URL, vid string) (u url.URL, err error) {
|
||||
|
||||
if vid == "" {
|
||||
vid = os.Getenv("VCLOUDAIR_VDCID")
|
||||
}
|
||||
|
||||
req := c.NewRequest(map[string]string{}, "GET", s, nil)
|
||||
|
||||
// Add the Accept header for vCA
|
||||
req.Header.Add("Accept", "application/xml;version=5.6")
|
||||
|
||||
// Set Authorization Header
|
||||
req.Header.Add("x-vchs-authorization", c.VAToken)
|
||||
|
||||
// TODO: wrap into checkresp to parse error
|
||||
resp, err := checkResp(c.Http.Do(req))
|
||||
if err != nil {
|
||||
return url.URL{}, fmt.Errorf("error processing compute action: %s", err)
|
||||
}
|
||||
|
||||
computeresources := new(computeResources)
|
||||
|
||||
if err = decodeBody(resp, computeresources); err != nil {
|
||||
return url.URL{}, fmt.Errorf("error decoding computeresources response: %s", err)
|
||||
}
|
||||
|
||||
// Iterate through the ComputeResources struct searching for the right
|
||||
// backend server
|
||||
for _, s := range computeresources.VdcRef {
|
||||
if s.Name == vid {
|
||||
for _, t := range s.Link {
|
||||
if t.Name == vid {
|
||||
u, err := url.ParseRequestURI(t.HREF)
|
||||
return *u, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return url.URL{}, fmt.Errorf("couldn't find a VDC Resource in current Compute list")
|
||||
}
|
||||
|
||||
func (c *Client) vagetbackendauth(s url.URL, cid string) error {
|
||||
|
||||
if cid == "" {
|
||||
cid = os.Getenv("VCLOUDAIR_COMPUTEID")
|
||||
}
|
||||
|
||||
req := c.NewRequest(map[string]string{}, "POST", s, nil)
|
||||
|
||||
// Add the Accept header for vCA
|
||||
req.Header.Add("Accept", "application/xml;version=5.6")
|
||||
|
||||
// Set Authorization Header
|
||||
req.Header.Add("x-vchs-authorization", c.VAToken)
|
||||
|
||||
// TODO: wrap into checkresp to parse error
|
||||
resp, err := checkResp(c.Http.Do(req))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error processing backend url action: %s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
vcloudsession := new(vCloudSession)
|
||||
|
||||
if err = decodeBody(resp, vcloudsession); err != nil {
|
||||
return fmt.Errorf("error decoding vcloudsession response: %s", err)
|
||||
}
|
||||
|
||||
// Get the backend session information
|
||||
for _, s := range vcloudsession.VdcLink {
|
||||
if s.Name == cid {
|
||||
// Fetch the authorization token
|
||||
c.VCDToken = s.AuthorizationToken
|
||||
|
||||
// Fetch the authorization header
|
||||
c.VCDAuthHeader = s.AuthorizationHeader
|
||||
|
||||
u, err := url.ParseRequestURI(s.HREF)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error decoding href: %s", err)
|
||||
}
|
||||
c.VCDVDCHREF = *u
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("error finding the right backend resource")
|
||||
}
|
||||
|
||||
// NewClient returns a new empty client to authenticate against the vCloud Air
|
||||
// service, the vCloud Air endpoint can be overridden by setting the
|
||||
// VCLOUDAIR_ENDPOINT environment variable.
|
||||
func NewClient() (*Client, error) {
|
||||
|
||||
var u *url.URL
|
||||
var err error
|
||||
|
||||
if os.Getenv("VCLOUDAIR_ENDPOINT") != "" {
|
||||
u, err = url.ParseRequestURI(os.Getenv("VCLOUDAIR_ENDPOINT"))
|
||||
if err != nil {
|
||||
return &Client{}, fmt.Errorf("cannot parse endpoint coming from VCLOUDAIR_ENDPOINT")
|
||||
}
|
||||
} else {
|
||||
// Implicitly trust this URL parse.
|
||||
u, _ = url.ParseRequestURI("https://vchs.vmware.com/api")
|
||||
}
|
||||
|
||||
Client := Client{
|
||||
VAEndpoint: *u,
|
||||
// Patching things up as we're hitting several TLS timeouts.
|
||||
Http: http.Client{Transport: &http.Transport{TLSHandshakeTimeout: 120 * time.Second}},
|
||||
}
|
||||
return &Client, nil
|
||||
}
|
||||
|
||||
// Authenticate is an helper function that performs a complete login in vCloud
|
||||
// Air and in the backend vCloud Director instance.
|
||||
func (c *Client) Authenticate(username, password, computeid, vdcid string) (Vdc, error) {
|
||||
// Authorize
|
||||
vaservicehref, err := c.vaauthorize(username, password)
|
||||
if err != nil {
|
||||
return Vdc{}, fmt.Errorf("error Authorizing: %s", err)
|
||||
}
|
||||
|
||||
// Get Service
|
||||
vacomputehref, err := c.vaacquireservice(vaservicehref, computeid)
|
||||
if err != nil {
|
||||
return Vdc{}, fmt.Errorf("error Acquiring Service: %s", err)
|
||||
}
|
||||
|
||||
// Get Compute
|
||||
vavdchref, err := c.vaacquirecompute(vacomputehref, vdcid)
|
||||
if err != nil {
|
||||
return Vdc{}, fmt.Errorf("error Acquiring Compute: %s", err)
|
||||
}
|
||||
|
||||
// Get Backend Authorization
|
||||
if err = c.vagetbackendauth(vavdchref, computeid); err != nil {
|
||||
return Vdc{}, fmt.Errorf("error Acquiring Backend Authorization: %s", err)
|
||||
}
|
||||
|
||||
v, err := c.retrieveVDC()
|
||||
if err != nil {
|
||||
return Vdc{}, fmt.Errorf("error Acquiring VDC: %s", err)
|
||||
}
|
||||
|
||||
return v, nil
|
||||
|
||||
}
|
||||
|
||||
// NewRequest creates a new HTTP request and applies necessary auth headers if
|
||||
// set.
|
||||
func (c *Client) NewRequest(params map[string]string, method string, u url.URL, body io.Reader) *http.Request {
|
||||
|
||||
p := url.Values{}
|
||||
|
||||
// Build up our request parameters
|
||||
for k, v := range params {
|
||||
p.Add(k, v)
|
||||
}
|
||||
|
||||
// Add the params to our URL
|
||||
u.RawQuery = p.Encode()
|
||||
|
||||
// Build the request, no point in checking for errors here as we're just
|
||||
// passing a string version of an url.URL struct and http.NewRequest returns
|
||||
// error only if can't process an url.ParseRequestURI().
|
||||
req, _ := http.NewRequest(method, u.String(), body)
|
||||
|
||||
if c.VCDAuthHeader != "" && c.VCDToken != "" {
|
||||
// Add the authorization header
|
||||
req.Header.Add(c.VCDAuthHeader, c.VCDToken)
|
||||
// Add the Accept header for VCD
|
||||
req.Header.Add("Accept", "application/*+xml;version=5.6")
|
||||
}
|
||||
|
||||
return req
|
||||
|
||||
}
|
||||
|
||||
// Disconnect performs a disconnection from the vCloud Air API endpoint.
|
||||
func (c *Client) Disconnect() error {
|
||||
if c.VCDToken == "" && c.VCDAuthHeader == "" && c.VAToken == "" {
|
||||
return fmt.Errorf("cannot disconnect, client is not authenticated")
|
||||
}
|
||||
|
||||
s := c.VAEndpoint
|
||||
s.Path += "/vchs/session"
|
||||
|
||||
req := c.NewRequest(map[string]string{}, "DELETE", s, nil)
|
||||
|
||||
// Add the Accept header for vCA
|
||||
req.Header.Add("Accept", "application/xml;version=5.6")
|
||||
|
||||
// Set Authorization Header
|
||||
req.Header.Add("x-vchs-authorization", c.VAToken)
|
||||
|
||||
if _, err := checkResp(c.Http.Do(req)); err != nil {
|
||||
return fmt.Errorf("error processing session delete for vchs: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseErr takes an error XML resp and returns a single string for use in error messages.
|
||||
func parseErr(resp *http.Response) error {
|
||||
|
||||
errBody := new(types.Error)
|
||||
|
||||
// if there was an error decoding the body, just return that
|
||||
if err := decodeBody(resp, errBody); err != nil {
|
||||
return fmt.Errorf("error parsing error body for non-200 request: %s", err)
|
||||
}
|
||||
|
||||
return fmt.Errorf("API Error: %d: %s", errBody.MajorErrorCode, errBody.Message)
|
||||
}
|
||||
|
||||
// decodeBody is used to XML decode a response body
|
||||
func decodeBody(resp *http.Response, out interface{}) error {
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Unmarshal the XML.
|
||||
if err = xml.Unmarshal(body, &out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkResp wraps http.Client.Do() and verifies the request, if status code
|
||||
// is 2XX it passes back the response, if it's a known invalid status code it
|
||||
// parses the resultant XML error and returns a descriptive error, if the
|
||||
// status code is not handled it returns a generic error with the status code.
|
||||
func checkResp(resp *http.Response, err error) (*http.Response, error) {
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
switch i := resp.StatusCode; {
|
||||
// Valid request, return the response.
|
||||
case i == 200 || i == 201 || i == 202 || i == 204:
|
||||
return resp, nil
|
||||
// Invalid request, parse the XML error returned and return it.
|
||||
case i == 400 || i == 401 || i == 403 || i == 404 || i == 405 || i == 406 || i == 409 || i == 415 || i == 500 || i == 503 || i == 504:
|
||||
return nil, parseErr(resp)
|
||||
// Unhandled response.
|
||||
default:
|
||||
return nil, fmt.Errorf("unhandled API response, please report this issue, status code: %s", resp.Status)
|
||||
}
|
||||
}
|
||||
749
Godeps/_workspace/src/github.com/vmware/govcloudair/api_test.go
generated
vendored
Normal file
749
Godeps/_workspace/src/github.com/vmware/govcloudair/api_test.go
generated
vendored
Normal file
@@ -0,0 +1,749 @@
|
||||
/*
|
||||
* @Author: frapposelli
|
||||
* @Project: govcloudair
|
||||
* @Filename: api_test.go
|
||||
* @Last Modified by: frapposelli
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/vmware/govcloudair/testutil"
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
var au, _ = url.ParseRequestURI("http://localhost:4444/api")
|
||||
var aus, _ = url.ParseRequestURI("http://localhost:4444/api/vchs/services")
|
||||
var auc, _ = url.ParseRequestURI("http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000")
|
||||
var aucs, _ = url.ParseRequestURI("http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession")
|
||||
|
||||
func Test(t *testing.T) { TestingT(t) }
|
||||
|
||||
type S struct {
|
||||
client *Client
|
||||
vdc Vdc
|
||||
vapp *VApp
|
||||
}
|
||||
|
||||
var _ = Suite(&S{})
|
||||
|
||||
var testServer = testutil.NewHTTPServer()
|
||||
|
||||
var authheader = map[string]string{"x-vchs-authorization": "012345678901234567890123456789"}
|
||||
|
||||
func (s *S) SetUpSuite(c *C) {
|
||||
testServer.Start()
|
||||
var err error
|
||||
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
|
||||
s.client, err = NewClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
testServer.ResponseMap(5, testutil.ResponseMap{
|
||||
"/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization},
|
||||
"/api/vchs/services": testutil.Response{200, nil, vaservices},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
})
|
||||
|
||||
s.vdc, err = s.client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789")
|
||||
s.vapp = NewVApp(s.client)
|
||||
_ = testServer.WaitRequests(5)
|
||||
testServer.Flush()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *S) TearDownTest(c *C) {
|
||||
testServer.Flush()
|
||||
}
|
||||
|
||||
func TestClient_vaauthorize(t *testing.T) {
|
||||
testServer.Start()
|
||||
var err error
|
||||
|
||||
// Set up a working client
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Set up a correct conversation
|
||||
testServer.Response(201, authheader, vaauthorization)
|
||||
_, err = client.vaauthorize("username", "password")
|
||||
_ = testServer.WaitRequest()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Test if token is correctly set on client.
|
||||
if client.VAToken != "012345678901234567890123456789" {
|
||||
t.Fatalf("VAtoken not set on client: %s", client.VAToken)
|
||||
}
|
||||
|
||||
// Test client errors
|
||||
|
||||
// Test a correct response with a wrong status code
|
||||
testServer.Response(404, authheader, notfoundErr)
|
||||
_, err = client.vaauthorize("username", "password")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
// Test an API error
|
||||
testServer.Response(500, authheader, vcdError)
|
||||
_, err = client.vaauthorize("username", "password")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
// Test an API response that doesn't contain the param we're looking for.
|
||||
testServer.Response(200, authheader, vaauthorizationErr)
|
||||
_, err = client.vaauthorize("username", "password")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
// Test an un-parsable response.
|
||||
testServer.Response(200, authheader, notfoundErr)
|
||||
_, err = client.vaauthorize("username", "password")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_vaacquireservice(t *testing.T) {
|
||||
testServer.Start()
|
||||
var err error
|
||||
|
||||
// Set up a working client
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
client.VAToken = "012345678901234567890123456789"
|
||||
|
||||
// Test a correct conversation
|
||||
testServer.Response(200, nil, vaservices)
|
||||
vacomputehref, err := client.vaacquireservice(*aus, "CI123456-789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if vacomputehref.String() != "http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000" {
|
||||
t.Fatalf("VAComputeHREF not set on client: %s", vacomputehref)
|
||||
}
|
||||
|
||||
if client.Region != "US - Anywhere" {
|
||||
t.Fatalf("Region not set on client: %s", client.Region)
|
||||
}
|
||||
|
||||
// Test client errors
|
||||
|
||||
// Test a 404
|
||||
testServer.Response(404, nil, notfoundErr)
|
||||
_, err = client.vaacquireservice(*aus, "CI123456-789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
// Test an API error
|
||||
testServer.Response(500, nil, vcdError)
|
||||
_, err = client.vaacquireservice(*aus, "CI123456-789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
// Test an unknown Compute ID
|
||||
testServer.Response(200, nil, vaservices)
|
||||
_, err = client.vaacquireservice(*aus, "NOTVALID-789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
// Test an un-parsable response
|
||||
testServer.Response(200, nil, notfoundErr)
|
||||
_, err = client.vaacquireservice(*aus, "CI123456-789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_vaacquirecompute(t *testing.T) {
|
||||
testServer.Start()
|
||||
var err error
|
||||
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
client.VAToken = "012345678901234567890123456789"
|
||||
client.Region = "US - Anywhere"
|
||||
|
||||
testServer.Response(200, nil, vacompute)
|
||||
vavdchref, err := client.vaacquirecompute(*auc, "VDC12345-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if vavdchref.String() != "http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession" {
|
||||
t.Fatalf("VAVDCHREF not set on client: %s", vavdchref)
|
||||
}
|
||||
|
||||
// Test client errors
|
||||
|
||||
// Test a 404
|
||||
testServer.Response(404, nil, notfoundErr)
|
||||
_, err = client.vaacquirecompute(*auc, "VDC12345-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
// Test an API error
|
||||
testServer.Response(500, nil, vcdError)
|
||||
_, err = client.vaacquirecompute(*auc, "VDC12345-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
// Test an unknown VDC ID
|
||||
testServer.Response(200, nil, vacompute)
|
||||
_, err = client.vaacquirecompute(*auc, "INVALID-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
// Test an un-parsable response
|
||||
testServer.Response(200, nil, notfoundErr)
|
||||
_, err = client.vaacquirecompute(*auc, "VDC12345-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_vagetbackendauth(t *testing.T) {
|
||||
testServer.Start()
|
||||
var err error
|
||||
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
client.VAToken = "012345678901234567890123456789"
|
||||
client.Region = "US - Anywhere"
|
||||
|
||||
testServer.Response(201, nil, vabackend)
|
||||
err = client.vagetbackendauth(*aucs, "CI123456-789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if client.VCDToken != "01234567890123456789012345678901" {
|
||||
t.Fatalf("VCDToken not set on client: %s", client.VCDToken)
|
||||
}
|
||||
if client.VCDAuthHeader != "x-vcloud-authorization" {
|
||||
t.Fatalf("VCDAuthHeader not set on client: %s", client.VCDAuthHeader)
|
||||
}
|
||||
if client.VCDVDCHREF.String() != "http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" {
|
||||
t.Fatalf("VDC not set on client: %s", client.VCDVDCHREF)
|
||||
}
|
||||
|
||||
// Test client errors
|
||||
|
||||
// Test a 404
|
||||
testServer.Response(404, nil, notfoundErr)
|
||||
err = client.vagetbackendauth(*aucs, "VDC12345-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
// Test an API error
|
||||
testServer.Response(500, nil, vcdError)
|
||||
err = client.vagetbackendauth(*aucs, "VDC12345-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
// Test an unknown backend VDC IC
|
||||
testServer.Response(201, nil, vabackend)
|
||||
err = client.vagetbackendauth(*aucs, "INVALID-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
// Test an un-parsable response
|
||||
testServer.Response(201, nil, notfoundErr)
|
||||
err = client.vagetbackendauth(*aucs, "VDC12345-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
// Test a botched backend VDC IC
|
||||
testServer.Response(201, nil, vabackendErr)
|
||||
err = client.vagetbackendauth(*aucs, "VDC12345-6789")
|
||||
_ = testServer.WaitRequest()
|
||||
if err == nil {
|
||||
t.Fatalf("Request error not caught: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Env variable tests
|
||||
|
||||
func TestClient_vaauthorize_env(t *testing.T) {
|
||||
|
||||
os.Setenv("VCLOUDAIR_USERNAME", "username")
|
||||
os.Setenv("VCLOUDAIR_PASSWORD", "password")
|
||||
|
||||
testServer.Start()
|
||||
var err error
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
testServer.Response(201, authheader, vaauthorization)
|
||||
_, err = client.vaauthorize("", "")
|
||||
_ = testServer.WaitRequest()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if client.VAToken != "012345678901234567890123456789" {
|
||||
t.Fatalf("VAtoken not set on client: %s", client.VAToken)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_vaacquireservice_env(t *testing.T) {
|
||||
|
||||
os.Setenv("VCLOUDAIR_COMPUTEID", "CI123456-789")
|
||||
|
||||
testServer.Start()
|
||||
var err error
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
client.VAToken = "012345678901234567890123456789"
|
||||
|
||||
testServer.Response(200, nil, vaservices)
|
||||
vacomputehref, err := client.vaacquireservice(*aus, "")
|
||||
_ = testServer.WaitRequest()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if vacomputehref.String() != "http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000" {
|
||||
t.Fatalf("VAComputeHREF not set on client: %s", vacomputehref)
|
||||
}
|
||||
|
||||
if client.Region != "US - Anywhere" {
|
||||
t.Fatalf("Region not set on client: %s", client.Region)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_vaacquirecompute_env(t *testing.T) {
|
||||
|
||||
os.Setenv("VCLOUDAIR_VDCID", "VDC12345-6789")
|
||||
|
||||
testServer.Start()
|
||||
var err error
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
client.VAToken = "012345678901234567890123456789"
|
||||
client.Region = "US - Anywhere"
|
||||
|
||||
testServer.Response(200, nil, vacompute)
|
||||
vavdchref, err := client.vaacquirecompute(*auc, "")
|
||||
_ = testServer.WaitRequest()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if vavdchref.String() != "http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession" {
|
||||
t.Fatalf("VAVDCHREF not set on client: %s", vavdchref)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_vagetbackendauth_env(t *testing.T) {
|
||||
|
||||
os.Setenv("VCLOUDAIR_VDCID", "VDC12345-6789")
|
||||
|
||||
testServer.Start()
|
||||
var err error
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
client.VAToken = "012345678901234567890123456789"
|
||||
client.Region = "US - Anywhere"
|
||||
|
||||
testServer.Response(201, nil, vabackend)
|
||||
err = client.vagetbackendauth(*aucs, "")
|
||||
_ = testServer.WaitRequest()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if client.VCDToken != "01234567890123456789012345678901" {
|
||||
t.Fatalf("VCDToken not set on client: %s", client.VCDToken)
|
||||
}
|
||||
if client.VCDAuthHeader != "x-vcloud-authorization" {
|
||||
t.Fatalf("VCDAuthHeader not set on client: %s", client.VCDAuthHeader)
|
||||
}
|
||||
if client.VCDVDCHREF.String() != "http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" {
|
||||
t.Fatalf("VDC not set on client: %s", client.VCDVDCHREF)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_NewClient(t *testing.T) {
|
||||
|
||||
var err error
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "")
|
||||
if _, err = NewClient(); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "💩")
|
||||
if _, err = NewClient(); err == nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_Disconnect(t *testing.T) {
|
||||
|
||||
testServer.Start()
|
||||
var err error
|
||||
|
||||
// Test an authenticated client
|
||||
c := makeClient(t)
|
||||
testServer.Response(201, nil, "")
|
||||
err = c.Disconnect()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Test an empty client
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
err = client.Disconnect()
|
||||
if err == nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_Authenticate(t *testing.T) {
|
||||
|
||||
testServer.Start()
|
||||
var err error
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Botched auth
|
||||
testServer.ResponseMap(5, testutil.ResponseMap{
|
||||
"/api/vchs/sessions": testutil.Response{401, nil, vcdError},
|
||||
"/api/vchs/services": testutil.Response{200, nil, vaservices},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
})
|
||||
|
||||
_, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789")
|
||||
_ = testServer.WaitRequests(1)
|
||||
testServer.Flush()
|
||||
if err == nil {
|
||||
t.Fatalf("Uncatched error: %v", err)
|
||||
}
|
||||
|
||||
// Botched services
|
||||
testServer.ResponseMap(5, testutil.ResponseMap{
|
||||
"/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization},
|
||||
"/api/vchs/services": testutil.Response{500, nil, vcdError},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
})
|
||||
|
||||
_, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789")
|
||||
_ = testServer.WaitRequests(2)
|
||||
testServer.Flush()
|
||||
if err == nil {
|
||||
t.Fatalf("Uncatched error: %v", err)
|
||||
}
|
||||
|
||||
// Botched compute
|
||||
testServer.ResponseMap(5, testutil.ResponseMap{
|
||||
"/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization},
|
||||
"/api/vchs/services": testutil.Response{200, nil, vaservices},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{500, nil, vcdError},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
})
|
||||
|
||||
_, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789")
|
||||
_ = testServer.WaitRequests(3)
|
||||
testServer.Flush()
|
||||
if err == nil {
|
||||
t.Fatalf("Uncatched error: %v", err)
|
||||
}
|
||||
|
||||
// Botched backend
|
||||
testServer.ResponseMap(5, testutil.ResponseMap{
|
||||
"/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization},
|
||||
"/api/vchs/services": testutil.Response{200, nil, vaservices},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{500, nil, vcdError},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
})
|
||||
|
||||
_, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789")
|
||||
_ = testServer.WaitRequests(4)
|
||||
testServer.Flush()
|
||||
if err == nil {
|
||||
t.Fatalf("Uncatched error: %v", err)
|
||||
}
|
||||
|
||||
// Botched vdc
|
||||
testServer.ResponseMap(5, testutil.ResponseMap{
|
||||
"/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization},
|
||||
"/api/vchs/services": testutil.Response{200, nil, vaservices},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{500, nil, vcdError},
|
||||
})
|
||||
|
||||
_, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789")
|
||||
_ = testServer.WaitRequests(5)
|
||||
testServer.Flush()
|
||||
if err == nil {
|
||||
t.Fatalf("Uncatched error: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func makeClient(t *testing.T) Client {
|
||||
|
||||
testServer.Start()
|
||||
var err error
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
testServer.ResponseMap(5, testutil.ResponseMap{
|
||||
"/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization},
|
||||
"/api/vchs/services": testutil.Response{200, nil, vaservices},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
})
|
||||
|
||||
_, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789")
|
||||
|
||||
_ = testServer.WaitRequests(5)
|
||||
testServer.Flush()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if client.VAToken != "012345678901234567890123456789" {
|
||||
t.Fatalf("VAtoken not set on client: %s", client.VAToken)
|
||||
}
|
||||
|
||||
if client.Region != "US - Anywhere" {
|
||||
t.Fatalf("Region not set on client: %s", client.Region)
|
||||
}
|
||||
|
||||
if client.VCDToken != "01234567890123456789012345678901" {
|
||||
t.Fatalf("VCDToken not set on client: %s", client.VCDToken)
|
||||
}
|
||||
if client.VCDAuthHeader != "x-vcloud-authorization" {
|
||||
t.Fatalf("VCDAuthHeader not set on client: %s", client.VCDAuthHeader)
|
||||
}
|
||||
if client.VCDVDCHREF.String() != "http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" {
|
||||
t.Fatalf("VDC not set on client: %s", client.VCDVDCHREF)
|
||||
}
|
||||
|
||||
return *client
|
||||
}
|
||||
|
||||
func TestClient_parseErr(t *testing.T) {
|
||||
testServer.Start()
|
||||
var err error
|
||||
os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api")
|
||||
client, err := NewClient()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// I'M A TEAPOT!
|
||||
testServer.ResponseMap(5, testutil.ResponseMap{
|
||||
"/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization},
|
||||
"/api/vchs/services": testutil.Response{200, nil, vaservices},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute},
|
||||
"/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{418, nil, notfoundErr},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
})
|
||||
|
||||
_, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789")
|
||||
|
||||
_ = testServer.WaitRequests(4)
|
||||
testServer.Flush()
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("Uncatched error: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClient_NewRequest(t *testing.T) {
|
||||
c := makeClient(t)
|
||||
|
||||
params := map[string]string{
|
||||
"foo": "bar",
|
||||
"baz": "bar",
|
||||
}
|
||||
|
||||
uri, _ := url.ParseRequestURI("http://localhost:4444/api/bar")
|
||||
|
||||
req := c.NewRequest(params, "POST", *uri, nil)
|
||||
|
||||
encoded := req.URL.Query()
|
||||
if encoded.Get("foo") != "bar" {
|
||||
t.Fatalf("bad: %v", encoded)
|
||||
}
|
||||
|
||||
if encoded.Get("baz") != "bar" {
|
||||
t.Fatalf("bad: %v", encoded)
|
||||
}
|
||||
|
||||
if req.URL.String() != "http://localhost:4444/api/bar?baz=bar&foo=bar" {
|
||||
t.Fatalf("bad base url: %v", req.URL.String())
|
||||
}
|
||||
|
||||
if req.Header.Get("x-vcloud-authorization") != "01234567890123456789012345678901" {
|
||||
t.Fatalf("bad auth header: %v", req.Header)
|
||||
}
|
||||
|
||||
if req.Method != "POST" {
|
||||
t.Fatalf("bad method: %v", req.Method)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// status: 404
|
||||
var notfoundErr = `
|
||||
<html>
|
||||
<head><title>404 Not Found</title></head>
|
||||
<body bgcolor="white">
|
||||
<center><h1>404 Not Found</h1></center>
|
||||
<hr><center>nginx/1.4.6 (Ubuntu)</center>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
// status: 201
|
||||
var vaauthorization = `
|
||||
<?xml version="1.0" ?>
|
||||
<Session href="http://localhost:4444/api/vchs/session" type="application/xml;class=vnd.vmware.vchs.session" xmlns="http://www.vmware.com/vchs/v5.6" xmlns:tns="http://www.vmware.com/vchs/v5.6" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Link href="http://localhost:4444/api/vchs/services" rel="down" type="application/xml;class=vnd.vmware.vchs.servicelist"/>
|
||||
<Link href="http://localhost:4444/api/vchs/session" rel="remove"/>
|
||||
</Session>
|
||||
`
|
||||
var vaauthorizationErr = `
|
||||
<?xml version="1.0" ?>
|
||||
<Session href="http://localhost:4444/api/vchs/session" type="application/xml;class=vnd.vmware.vchs.session" xmlns="http://www.vmware.com/vchs/v5.6" xmlns:tns="http://www.vmware.com/vchs/v5.6" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Link href="http://localhost:4444/api/vchs/session" rel="remove"/>
|
||||
</Session>
|
||||
`
|
||||
|
||||
// status: 200
|
||||
var vaservices = `
|
||||
<?xml version="1.0" ?>
|
||||
<Services href="http://localhost:4444/api/vchs/services" type="application/xml;class=vnd.vmware.vchs.servicelist" xmlns="http://www.vmware.com/vchs/v5.6" xmlns:tns="http://www.vmware.com/vchs/v5.6" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Service href="http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000" region="US - Anywhere" serviceId="CI123456-789" serviceType="compute:vpc" type="application/xml;class=vnd.vmware.vchs.compute"/>
|
||||
</Services>
|
||||
`
|
||||
|
||||
// status: 200
|
||||
var vacompute = `
|
||||
<?xml version="1.0" ?>
|
||||
<Compute href="http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000" serviceId="CI123456-789" serviceType="compute:vpc" type="application/xml;class=vnd.vmware.vchs.compute" xmlns="http://www.vmware.com/vchs/v5.6" xmlns:tns="http://www.vmware.com/vchs/v5.6" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Link href="http://localhost:4444/api/vchs/services" name="services" rel="up" type="application/xml;class=vnd.vmware.vchs.servicelist"/>
|
||||
<VdcRef href="http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000" name="VDC12345-6789" status="Active" type="application/xml;class=vnd.vmware.vchs.vdcref">
|
||||
<Link href="http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession" name="VDC12345-6789" rel="down" type="application/xml;class=vnd.vmware.vchs.vcloudsession"/>
|
||||
</VdcRef>
|
||||
</Compute>
|
||||
`
|
||||
|
||||
// status: 201
|
||||
var vabackend = `
|
||||
<?xml version="1.0" ?>
|
||||
<VCloudSession href="http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession" name="CI123456-789-session" type="application/xml;class=vnd.vmware.vchs.vcloudsession" xmlns="http://www.vmware.com/vchs/v5.6" xmlns:tns="http://www.vmware.com/vchs/v5.6" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Link href="http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000" name="vdc" rel="up" type="application/xml;class=vnd.vmware.vchs.vdcref"/>
|
||||
<VdcLink authorizationHeader="x-vcloud-authorization" authorizationToken="01234567890123456789012345678901" href="http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" name="CI123456-789" rel="vcloudvdc" type="application/vnd.vmware.vcloud.vdc+xml"/>
|
||||
</VCloudSession>
|
||||
`
|
||||
|
||||
// status: 201
|
||||
var vabackendErr = `
|
||||
<?xml version="1.0" ?>
|
||||
<VCloudSession href="http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession" name="CI123456-789-session" type="application/xml;class=vnd.vmware.vchs.vcloudsession" xmlns="http://www.vmware.com/vchs/v5.6" xmlns:tns="http://www.vmware.com/vchs/v5.6" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Link href="http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000" name="vdc" rel="up" type="application/xml;class=vnd.vmware.vchs.vdcref"/>
|
||||
<VdcLink authorizationHeader="x-vcloud-authorization" authorizationToken="01234567890123456789012345678901" href="http://$£$%£%$:4444/api/vdc/00000000-0000-0000-0000-000000000000" name="CI123456-789" rel="vcloudvdc" type="application/vnd.vmware.vcloud.vdc+xml"/>
|
||||
</VCloudSession>
|
||||
`
|
||||
|
||||
var vcdError = `
|
||||
<Error xmlns="http://www.vmware.com/vcloud/v1.5" message="Error Message" majorErrorCode="500" minorErrorCode="Server Error" vendorSpecificErrorCode="NoSpecificError" stackTrace="Hello my name is Stack Trace"/>
|
||||
`
|
||||
57
Godeps/_workspace/src/github.com/vmware/govcloudair/catalog.go
generated
vendored
Normal file
57
Godeps/_workspace/src/github.com/vmware/govcloudair/catalog.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type Catalog struct {
|
||||
Catalog *types.Catalog
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewCatalog(c *Client) *Catalog {
|
||||
return &Catalog{
|
||||
Catalog: new(types.Catalog),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Catalog) FindCatalogItem(catalogitem string) (CatalogItem, error) {
|
||||
|
||||
for _, cis := range c.Catalog.CatalogItems {
|
||||
for _, ci := range cis.CatalogItem {
|
||||
if ci.Name == catalogitem && ci.Type == "application/vnd.vmware.vcloud.catalogItem+xml" {
|
||||
u, err := url.ParseRequestURI(ci.HREF)
|
||||
|
||||
if err != nil {
|
||||
return CatalogItem{}, fmt.Errorf("error decoding catalog response: %s", err)
|
||||
}
|
||||
|
||||
req := c.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(c.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return CatalogItem{}, fmt.Errorf("error retreiving catalog: %s", err)
|
||||
}
|
||||
|
||||
cat := NewCatalogItem(c.c)
|
||||
|
||||
if err = decodeBody(resp, cat.CatalogItem); err != nil {
|
||||
return CatalogItem{}, fmt.Errorf("error decoding catalog response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *cat, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CatalogItem{}, fmt.Errorf("can't find catalog item: %s", catalogitem)
|
||||
}
|
||||
68
Godeps/_workspace/src/github.com/vmware/govcloudair/catalog_test.go
generated
vendored
Normal file
68
Godeps/_workspace/src/github.com/vmware/govcloudair/catalog_test.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *S) Test_FindCatalogItem(c *C) {
|
||||
|
||||
// Get the Org populated
|
||||
testServer.Response(200, nil, orgExample)
|
||||
org, err := s.vdc.GetVDCOrg()
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog
|
||||
testServer.Response(200, nil, catalogExample)
|
||||
cat, err := org.FindCatalog("Public Catalog")
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
|
||||
// Find Catalog Item
|
||||
testServer.Response(200, nil, catalogitemExample)
|
||||
catitem, err := cat.FindCatalogItem("CentOS64-32bit")
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(catitem.CatalogItem.HREF, Equals, "http://localhost:4444/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae")
|
||||
c.Assert(catitem.CatalogItem.Description, Equals, "id: cts-6.4-32bit")
|
||||
|
||||
// Test non-existant catalog item
|
||||
catitem, err = cat.FindCatalogItem("INVALID")
|
||||
c.Assert(err, NotNil)
|
||||
|
||||
}
|
||||
|
||||
var catalogExample = `
|
||||
<?xml version="1.0" ?>
|
||||
<Catalog href="http://localhost:4444/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854" id="urn:vcloud:catalog:e8a20fdf-8a78-440c-ac71-0420db59f854" name="Public Catalog" type="application/vnd.vmware.vcloud.catalog+xml" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Link href="http://localhost:4444/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854/metadata" rel="down" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Description>vCHS service catalog</Description>
|
||||
<CatalogItems>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/013d1994-f009-4c40-ac48-517fe7d952a0" id="013d1994-f009-4c40-ac48-517fe7d952a0" name="W2K12-STD-64BIT" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/05384603-e07e-4f00-a95e-776b427f22d9" id="05384603-e07e-4f00-a95e-776b427f22d9" name="W2K12-STD-R2-SQL2K14-WEB" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae" id="1176e485-8858-4e15-94e5-ae4face605ae" name="CentOS64-32bit" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/1a729040-71b6-412c-bda9-20b9085f9882" id="1a729040-71b6-412c-bda9-20b9085f9882" name="W2K8-STD-R2-64BIT-SQL2K8-STD-R2-SP2" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/222624b5-e62a-4f5b-a2af-b33a4664005e" id="222624b5-e62a-4f5b-a2af-b33a4664005e" name="W2K12-STD-64BIT-SQL2K12-STD-SP1" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/54cb2af1-4439-48fe-85b6-4c9524930ce6" id="54cb2af1-4439-48fe-85b6-4c9524930ce6" name="Ubuntu Server 12.04 LTS (amd64 20140619)" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/693f342b-d872-41d1-983b-fd5cc2c15f7c" id="693f342b-d872-41d1-983b-fd5cc2c15f7c" name="W2K8-STD-R2-64BIT" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/8d4edd11-393f-4cda-ace4-d5b8f1548928" id="8d4edd11-393f-4cda-ace4-d5b8f1548928" name="CentOS64-64bit" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/bfca201c-e8f3-49f8-a828-397e16fa6cfe" id="bfca201c-e8f3-49f8-a828-397e16fa6cfe" name="W2K12-STD-R2-64BIT" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/cb508cd9-664a-4fec-8eb1-ae5934aad6ad" id="cb508cd9-664a-4fec-8eb1-ae5934aad6ad" name="W2K12-STD-64BIT-SQL2K12-WEB-SP1" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/d0be59f3-ef80-4298-bd4c-f2258a3fec37" id="d0be59f3-ef80-4298-bd4c-f2258a3fec37" name="W2K8-STD-R2-64BIT-SQL2K8-WEB-R2-SP2" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/dbbf4633-64a3-4ac1-b9e0-7f923efa3f13" id="dbbf4633-64a3-4ac1-b9e0-7f923efa3f13" name="Ubuntu Server 12.04 LTS (i386 20140619)" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/ed996ae8-3081-4e16-a7b6-4bed1c462aa4" id="ed996ae8-3081-4e16-a7b6-4bed1c462aa4" name="CentOS63-64bit" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/f4dc0f92-74ae-413e-8e0f-25e6568a8195" id="f4dc0f92-74ae-413e-8e0f-25e6568a8195" name="W2K12-STD-R2-SQL2K14-STD" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/ff9c9b63-ca3b-4e39-ab72-7eb9049f8b05" id="ff9c9b63-ca3b-4e39-ab72-7eb9049f8b05" name="CentOS63-32bit" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
</CatalogItems>
|
||||
<IsPublished>true</IsPublished>
|
||||
<DateCreated>2013-10-15T01:14:22.370Z</DateCreated>
|
||||
<VersionNumber>60</VersionNumber>
|
||||
</Catalog>
|
||||
`
|
||||
49
Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem.go
generated
vendored
Normal file
49
Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type CatalogItem struct {
|
||||
CatalogItem *types.CatalogItem
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewCatalogItem(c *Client) *CatalogItem {
|
||||
return &CatalogItem{
|
||||
CatalogItem: new(types.CatalogItem),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (ci *CatalogItem) GetVAppTemplate() (VAppTemplate, error) {
|
||||
url, err := url.ParseRequestURI(ci.CatalogItem.Entity.HREF)
|
||||
|
||||
if err != nil {
|
||||
return VAppTemplate{}, fmt.Errorf("error decoding catalogitem response: %s", err)
|
||||
}
|
||||
|
||||
req := ci.c.NewRequest(map[string]string{}, "GET", *url, nil)
|
||||
|
||||
resp, err := checkResp(ci.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return VAppTemplate{}, fmt.Errorf("error retreiving vapptemplate: %s", err)
|
||||
}
|
||||
|
||||
cat := NewVAppTemplate(ci.c)
|
||||
|
||||
if err = decodeBody(resp, cat.VAppTemplate); err != nil {
|
||||
return VAppTemplate{}, fmt.Errorf("error decoding vapptemplate response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *cat, nil
|
||||
|
||||
}
|
||||
55
Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem_test.go
generated
vendored
Normal file
55
Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem_test.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *S) Test_GetVAppTemplate(c *C) {
|
||||
|
||||
// Get the Org populated
|
||||
testServer.Response(200, nil, orgExample)
|
||||
org, err := s.vdc.GetVDCOrg()
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog
|
||||
testServer.Response(200, nil, catalogExample)
|
||||
cat, err := org.FindCatalog("Public Catalog")
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
|
||||
// Populate Catalog Item
|
||||
testServer.Response(200, nil, catalogitemExample)
|
||||
catitem, err := cat.FindCatalogItem("CentOS64-32bit")
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
|
||||
// Get VAppTemplate
|
||||
testServer.Response(200, nil, vapptemplateExample)
|
||||
vapptemplate, err := catitem.GetVAppTemplate()
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(vapptemplate.VAppTemplate.HREF, Equals, "http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5")
|
||||
c.Assert(vapptemplate.VAppTemplate.Name, Equals, "CentOS64-32bit")
|
||||
c.Assert(vapptemplate.VAppTemplate.Description, Equals, "id: cts-6.4-32bit")
|
||||
|
||||
}
|
||||
|
||||
var catalogitemExample = `
|
||||
<?xml version="1.0" ?>
|
||||
<CatalogItem href="http://localhost:4444/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae" id="urn:vcloud:catalogitem:1176e485-8858-4e15-94e5-ae4face605ae" name="CentOS64-32bit" size="0" type="application/vnd.vmware.vcloud.catalogItem+xml" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Link href="http://localhost:4444/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854" rel="up" type="application/vnd.vmware.vcloud.catalog+xml"/>
|
||||
<Link href="http://localhost:4444/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae/metadata" rel="down" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Description>id: cts-6.4-32bit</Description>
|
||||
<Entity href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5" name="CentOS64-32bit" type="application/vnd.vmware.vcloud.vAppTemplate+xml"/>
|
||||
<DateCreated>2014-06-04T21:06:43.750Z</DateCreated>
|
||||
<VersionNumber>4</VersionNumber>
|
||||
</CatalogItem>
|
||||
`
|
||||
311
Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway.go
generated
vendored
Normal file
311
Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway.go
generated
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type EdgeGateway struct {
|
||||
EdgeGateway *types.EdgeGateway
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewEdgeGateway(c *Client) *EdgeGateway {
|
||||
return &EdgeGateway{
|
||||
EdgeGateway: new(types.EdgeGateway),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EdgeGateway) Refresh() error {
|
||||
|
||||
if e.EdgeGateway == nil {
|
||||
return fmt.Errorf("cannot refresh, Object is empty")
|
||||
}
|
||||
|
||||
u, _ := url.ParseRequestURI(e.EdgeGateway.HREF)
|
||||
|
||||
req := e.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(e.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retreiving Edge Gateway: %s", err)
|
||||
}
|
||||
|
||||
// Empty struct before a new unmarshal, otherwise we end up with duplicate
|
||||
// elements in slices.
|
||||
e.EdgeGateway = &types.EdgeGateway{}
|
||||
|
||||
if err = decodeBody(resp, e.EdgeGateway); err != nil {
|
||||
return fmt.Errorf("error decoding Edge Gateway response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EdgeGateway) Remove1to1Mapping(internal, external string) (Task, error) {
|
||||
|
||||
// Refresh EdgeGateway rules
|
||||
err := e.Refresh()
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
var uplinkif string
|
||||
for _, gifs := range e.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface {
|
||||
if gifs.InterfaceType == "uplink" {
|
||||
uplinkif = gifs.Network.HREF
|
||||
}
|
||||
}
|
||||
|
||||
newedgeconfig := e.EdgeGateway.Configuration.EdgeGatewayServiceConfiguration
|
||||
|
||||
// Take care of the NAT service
|
||||
newnatservice := &types.NatService{}
|
||||
|
||||
// Copy over the NAT configuration
|
||||
newnatservice.IsEnabled = newedgeconfig.NatService.IsEnabled
|
||||
newnatservice.NatType = newedgeconfig.NatService.NatType
|
||||
newnatservice.Policy = newedgeconfig.NatService.Policy
|
||||
newnatservice.ExternalIP = newedgeconfig.NatService.ExternalIP
|
||||
|
||||
for k, v := range newedgeconfig.NatService.NatRule {
|
||||
|
||||
// Kludgy IF to avoid deleting DNAT rules not created by us.
|
||||
// If matches, let's skip it and continue the loop
|
||||
if v.RuleType == "DNAT" &&
|
||||
v.GatewayNatRule.OriginalIP == external &&
|
||||
v.GatewayNatRule.TranslatedIP == internal &&
|
||||
v.GatewayNatRule.OriginalPort == "any" &&
|
||||
v.GatewayNatRule.TranslatedPort == "any" &&
|
||||
v.GatewayNatRule.Protocol == "any" &&
|
||||
v.GatewayNatRule.Interface.HREF == uplinkif {
|
||||
continue
|
||||
}
|
||||
|
||||
// Kludgy IF to avoid deleting SNAT rules not created by us.
|
||||
// If matches, let's skip it and continue the loop
|
||||
if v.RuleType == "SNAT" &&
|
||||
v.GatewayNatRule.OriginalIP == internal &&
|
||||
v.GatewayNatRule.TranslatedIP == external &&
|
||||
v.GatewayNatRule.Interface.HREF == uplinkif {
|
||||
continue
|
||||
}
|
||||
|
||||
// If doesn't match the above IFs, it's something we need to preserve,
|
||||
// let's add it to the new NatService struct
|
||||
newnatservice.NatRule = append(newnatservice.NatRule, newedgeconfig.NatService.NatRule[k])
|
||||
|
||||
}
|
||||
|
||||
// Fill the new NatService Section
|
||||
newedgeconfig.NatService = newnatservice
|
||||
|
||||
// Take care of the Firewall service
|
||||
newfwservice := &types.FirewallService{}
|
||||
|
||||
// Copy over the firewall configuration
|
||||
newfwservice.IsEnabled = newedgeconfig.FirewallService.IsEnabled
|
||||
newfwservice.DefaultAction = newedgeconfig.FirewallService.DefaultAction
|
||||
newfwservice.LogDefaultAction = newedgeconfig.FirewallService.LogDefaultAction
|
||||
|
||||
for k, v := range newedgeconfig.FirewallService.FirewallRule {
|
||||
|
||||
// Kludgy IF to avoid deleting inbound FW rules not created by us.
|
||||
// If matches, let's skip it and continue the loop
|
||||
if v.Policy == "allow" &&
|
||||
v.Protocols.Any == true &&
|
||||
v.DestinationPortRange == "Any" &&
|
||||
v.SourcePortRange == "Any" &&
|
||||
v.SourceIP == "Any" &&
|
||||
v.DestinationIP == external {
|
||||
continue
|
||||
}
|
||||
|
||||
// Kludgy IF to avoid deleting outbound FW rules not created by us.
|
||||
// If matches, let's skip it and continue the loop
|
||||
if v.Policy == "allow" &&
|
||||
v.Protocols.Any == true &&
|
||||
v.DestinationPortRange == "Any" &&
|
||||
v.SourcePortRange == "Any" &&
|
||||
v.SourceIP == internal &&
|
||||
v.DestinationIP == "Any" {
|
||||
continue
|
||||
}
|
||||
|
||||
// If doesn't match the above IFs, it's something we need to preserve,
|
||||
// let's add it to the new FirewallService struct
|
||||
newfwservice.FirewallRule = append(newfwservice.FirewallRule, newedgeconfig.FirewallService.FirewallRule[k])
|
||||
|
||||
}
|
||||
|
||||
// Fill the new FirewallService Section
|
||||
newedgeconfig.FirewallService = newfwservice
|
||||
|
||||
// Fix
|
||||
newedgeconfig.NatService.IsEnabled = true
|
||||
|
||||
output, err := xml.MarshalIndent(newedgeconfig, " ", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
|
||||
|
||||
if debug == "true" {
|
||||
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString(xml.Header + string(output))
|
||||
|
||||
s, _ := url.ParseRequestURI(e.EdgeGateway.HREF)
|
||||
s.Path += "/action/configureServices"
|
||||
|
||||
req := e.c.NewRequest(map[string]string{}, "POST", *s, b)
|
||||
|
||||
req.Header.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")
|
||||
|
||||
resp, err := checkResp(e.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error reconfiguring Edge Gateway: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(e.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (e *EdgeGateway) Create1to1Mapping(internal, external, description string) (Task, error) {
|
||||
|
||||
// Refresh EdgeGateway rules
|
||||
err := e.Refresh()
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
var uplinkif string
|
||||
for _, gifs := range e.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface {
|
||||
if gifs.InterfaceType == "uplink" {
|
||||
uplinkif = gifs.Network.HREF
|
||||
}
|
||||
}
|
||||
|
||||
newedgeconfig := e.EdgeGateway.Configuration.EdgeGatewayServiceConfiguration
|
||||
|
||||
snat := &types.NatRule{
|
||||
Description: description,
|
||||
RuleType: "SNAT",
|
||||
IsEnabled: true,
|
||||
GatewayNatRule: &types.GatewayNatRule{
|
||||
Interface: &types.Reference{
|
||||
HREF: uplinkif,
|
||||
},
|
||||
OriginalIP: internal,
|
||||
TranslatedIP: external,
|
||||
Protocol: "any",
|
||||
},
|
||||
}
|
||||
|
||||
newedgeconfig.NatService.NatRule = append(newedgeconfig.NatService.NatRule, snat)
|
||||
|
||||
dnat := &types.NatRule{
|
||||
Description: description,
|
||||
RuleType: "DNAT",
|
||||
IsEnabled: true,
|
||||
GatewayNatRule: &types.GatewayNatRule{
|
||||
Interface: &types.Reference{
|
||||
HREF: uplinkif,
|
||||
},
|
||||
OriginalIP: external,
|
||||
OriginalPort: "any",
|
||||
TranslatedIP: internal,
|
||||
TranslatedPort: "any",
|
||||
Protocol: "any",
|
||||
},
|
||||
}
|
||||
|
||||
newedgeconfig.NatService.NatRule = append(newedgeconfig.NatService.NatRule, dnat)
|
||||
|
||||
fwin := &types.FirewallRule{
|
||||
Description: description,
|
||||
IsEnabled: true,
|
||||
Policy: "allow",
|
||||
Protocols: &types.FirewallRuleProtocols{
|
||||
Any: true,
|
||||
},
|
||||
DestinationPortRange: "Any",
|
||||
DestinationIP: external,
|
||||
SourcePortRange: "Any",
|
||||
SourceIP: "Any",
|
||||
EnableLogging: false,
|
||||
}
|
||||
|
||||
newedgeconfig.FirewallService.FirewallRule = append(newedgeconfig.FirewallService.FirewallRule, fwin)
|
||||
|
||||
fwout := &types.FirewallRule{
|
||||
Description: description,
|
||||
IsEnabled: true,
|
||||
Policy: "allow",
|
||||
Protocols: &types.FirewallRuleProtocols{
|
||||
Any: true,
|
||||
},
|
||||
DestinationPortRange: "Any",
|
||||
DestinationIP: "Any",
|
||||
SourcePortRange: "Any",
|
||||
SourceIP: internal,
|
||||
EnableLogging: false,
|
||||
}
|
||||
|
||||
newedgeconfig.FirewallService.FirewallRule = append(newedgeconfig.FirewallService.FirewallRule, fwout)
|
||||
|
||||
output, err := xml.MarshalIndent(newedgeconfig, " ", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
|
||||
|
||||
if debug == "true" {
|
||||
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString(xml.Header + string(output))
|
||||
|
||||
s, _ := url.ParseRequestURI(e.EdgeGateway.HREF)
|
||||
s.Path += "/action/configureServices"
|
||||
|
||||
req := e.c.NewRequest(map[string]string{}, "POST", *s, b)
|
||||
|
||||
req.Header.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")
|
||||
|
||||
resp, err := checkResp(e.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error reconfiguring Edge Gateway: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(e.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
374
Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway_test.go
generated
vendored
Normal file
374
Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway_test.go
generated
vendored
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"github.com/vmware/govcloudair/testutil"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *S) Test_Refresh(c *C) {
|
||||
|
||||
// Get the Org populated
|
||||
testServer.ResponseMap(2, testutil.ResponseMap{
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000/edgeGateways": testutil.Response{200, nil, edgegatewayqueryresultsExample},
|
||||
"/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, edgegatewayExample},
|
||||
})
|
||||
|
||||
edge, err := s.vdc.FindEdgeGateway("M916272752-5793")
|
||||
_ = testServer.WaitRequests(2)
|
||||
testServer.Flush()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(edge.EdgeGateway.Name, Equals, "M916272752-5793")
|
||||
|
||||
testServer.Response(200, nil, edgegatewayExample)
|
||||
err = edge.Refresh()
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(edge.EdgeGateway.Name, Equals, "M916272752-5793")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_1to1Mappings(c *C) {
|
||||
|
||||
testServer.ResponseMap(2, testutil.ResponseMap{
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000/edgeGateways": testutil.Response{200, nil, edgegatewayqueryresultsExample},
|
||||
"/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, edgegatewayExample},
|
||||
})
|
||||
|
||||
edge, err := s.vdc.FindEdgeGateway("M916272752-5793")
|
||||
_ = testServer.WaitRequests(2)
|
||||
testServer.Flush()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(edge.EdgeGateway.Name, Equals, "M916272752-5793")
|
||||
|
||||
testServer.ResponseMap(2, testutil.ResponseMap{
|
||||
"/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, edgegatewayExample},
|
||||
"/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000/action/configureServices": testutil.Response{200, nil, taskExample},
|
||||
})
|
||||
|
||||
_, err = edge.Create1to1Mapping("10.0.0.1", "20.0.0.2", "description")
|
||||
_ = testServer.WaitRequests(2)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
testServer.ResponseMap(2, testutil.ResponseMap{
|
||||
"/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, edgegatewayExample},
|
||||
"/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000/action/configureServices": testutil.Response{200, nil, taskExample},
|
||||
})
|
||||
|
||||
_, err = edge.Remove1to1Mapping("10.0.0.1", "20.0.0.2")
|
||||
_ = testServer.WaitRequests(2)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
}
|
||||
|
||||
var edgegatewayqueryresultsExample = `
|
||||
<QueryResultRecords xmlns="http://www.vmware.com/vcloud/v1.5" name="edgeGateway" page="1" pageSize="25" total="1" href="http://localhost:4444/api/admin/vdc/00000000-0000-0000-0000-000000000000/edgeGateways?page=1&pageSize=25&format=records" type="application/vnd.vmware.vcloud.query.records+xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Link rel="alternate" href="http://localhost:4444/api/admin/vdc/00000000-0000-0000-0000-000000000000/edgeGateways?page=1&pageSize=25&format=references" type="application/vnd.vmware.vcloud.query.references+xml"/>
|
||||
<Link rel="alternate" href="http://localhost:4444/api/admin/vdc/00000000-0000-0000-0000-000000000000/edgeGateways?page=1&pageSize=25&format=idrecords" type="application/vnd.vmware.vcloud.query.idrecords+xml"/>
|
||||
<EdgeGatewayRecord gatewayStatus="READY" haStatus="UP" isBusy="false" name="M916272752-5793" numberOfExtNetworks="1" numberOfOrgNetworks="2" vdc="http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" href="http://localhost:4444/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000" isSyslogServerSettingInSync="true" taskStatus="success" taskOperation="networkConfigureEdgeGatewayServices" task="http://localhost:4444/api/task/eca0d70f-36e0-428a-93c2-311b792f3326" taskDetails=" "/>
|
||||
</QueryResultRecords>
|
||||
`
|
||||
|
||||
var edgegatewayExample = `
|
||||
<EdgeGateway xmlns="http://www.vmware.com/vcloud/v1.5" status="1" name="M916272752-5793" id="urn:vcloud:gateway:00000000-0000-0000-0000-000000000000" href="http://localhost:4444/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000" type="application/vnd.vmware.admin.edgeGateway+xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Link rel="up" href="http://localhost:4444/api/vdc/214cd6b2-3f7a-4ee5-9b0a-52b4001a4a84" type="application/vnd.vmware.vcloud.vdc+xml"/>
|
||||
<Link rel="edgeGateway:redeploy" href="http://localhost:4444/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000/action/redeploy"/>
|
||||
<Link rel="edgeGateway:configureServices" href="http://localhost:4444/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000/action/configureServices" type="application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml"/>
|
||||
<Link rel="edgeGateway:reapplyServices" href="http://localhost:4444/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000/action/reapplyServices"/>
|
||||
<Link rel="edgeGateway:syncSyslogSettings" href="http://localhost:4444/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000/action/syncSyslogServerSettings"/>
|
||||
<Configuration>
|
||||
<GatewayBackingConfig>compact</GatewayBackingConfig>
|
||||
<GatewayInterfaces>
|
||||
<GatewayInterface>
|
||||
<Name>JGray Network</Name>
|
||||
<DisplayName>JGray Network</DisplayName>
|
||||
<Network href="http://localhost:4444/api/admin/network/32e903a4-c726-497f-9ec7-e4a43b58bdbc" name="JGray Network" type="application/vnd.vmware.admin.network+xml"/>
|
||||
<InterfaceType>internal</InterfaceType>
|
||||
<SubnetParticipation>
|
||||
<Gateway>192.168.108.1</Gateway>
|
||||
<Netmask>255.255.255.0</Netmask>
|
||||
<IpAddress>192.168.108.1</IpAddress>
|
||||
</SubnetParticipation>
|
||||
<ApplyRateLimit>false</ApplyRateLimit>
|
||||
<UseForDefaultRoute>false</UseForDefaultRoute>
|
||||
</GatewayInterface>
|
||||
<GatewayInterface>
|
||||
<Name>M916272752-5793-default-routed</Name>
|
||||
<DisplayName>M916272752-5793-default-routed</DisplayName>
|
||||
<Network href="http://localhost:4444/api/admin/network/cb0f4c9e-1a46-49d4-9fcb-d228000a6bc1" name="M916272752-5793-default-routed" type="application/vnd.vmware.admin.network+xml"/>
|
||||
<InterfaceType>internal</InterfaceType>
|
||||
<SubnetParticipation>
|
||||
<Gateway>192.168.109.1</Gateway>
|
||||
<Netmask>255.255.255.0</Netmask>
|
||||
<IpAddress>192.168.109.1</IpAddress>
|
||||
</SubnetParticipation>
|
||||
<ApplyRateLimit>false</ApplyRateLimit>
|
||||
<UseForDefaultRoute>false</UseForDefaultRoute>
|
||||
</GatewayInterface>
|
||||
<GatewayInterface>
|
||||
<Name>d2p3-ext</Name>
|
||||
<DisplayName>d2p3-ext</DisplayName>
|
||||
<Network href="http://localhost:4444/api/admin/network/6254f107-9876-4d03-986f-8bec7a4bcb3f" name="d2p3-ext" type="application/vnd.vmware.admin.network+xml"/>
|
||||
<InterfaceType>uplink</InterfaceType>
|
||||
<SubnetParticipation>
|
||||
<Gateway>23.92.224.1</Gateway>
|
||||
<Netmask>255.255.254.0</Netmask>
|
||||
<IpAddress>23.92.225.51</IpAddress>
|
||||
<IpRanges>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.73</StartAddress>
|
||||
<EndAddress>23.92.225.75</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.27</StartAddress>
|
||||
<EndAddress>23.92.225.27</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.11</StartAddress>
|
||||
<EndAddress>23.92.225.11</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.54</StartAddress>
|
||||
<EndAddress>23.92.225.54</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.224.34</StartAddress>
|
||||
<EndAddress>23.92.224.34</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.5</StartAddress>
|
||||
<EndAddress>23.92.225.5</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.34</StartAddress>
|
||||
<EndAddress>23.92.225.34</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.224.255</StartAddress>
|
||||
<EndAddress>23.92.224.255</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.49</StartAddress>
|
||||
<EndAddress>23.92.225.51</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.62</StartAddress>
|
||||
<EndAddress>23.92.225.62</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.43</StartAddress>
|
||||
<EndAddress>23.92.225.43</EndAddress>
|
||||
</IpRange>
|
||||
<IpRange>
|
||||
<StartAddress>23.92.225.30</StartAddress>
|
||||
<EndAddress>23.92.225.30</EndAddress>
|
||||
</IpRange>
|
||||
</IpRanges>
|
||||
</SubnetParticipation>
|
||||
<ApplyRateLimit>true</ApplyRateLimit>
|
||||
<InRateLimit>1024.0</InRateLimit>
|
||||
<OutRateLimit>1024.0</OutRateLimit>
|
||||
<UseForDefaultRoute>true</UseForDefaultRoute>
|
||||
</GatewayInterface>
|
||||
</GatewayInterfaces>
|
||||
<EdgeGatewayServiceConfiguration>
|
||||
<FirewallService>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<DefaultAction>drop</DefaultAction>
|
||||
<LogDefaultAction>false</LogDefaultAction>
|
||||
<FirewallRule>
|
||||
<Id>1</Id>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<MatchOnTranslate>false</MatchOnTranslate>
|
||||
<Description>ssh prd-001</Description>
|
||||
<Policy>allow</Policy>
|
||||
<Protocols>
|
||||
<Tcp>true</Tcp>
|
||||
</Protocols>
|
||||
<Port>999</Port>
|
||||
<DestinationPortRange>999</DestinationPortRange>
|
||||
<DestinationIp>23.92.225.51</DestinationIp>
|
||||
<SourcePort>-1</SourcePort>
|
||||
<SourcePortRange>Any</SourcePortRange>
|
||||
<SourceIp>60.241.110.111</SourceIp>
|
||||
<EnableLogging>false</EnableLogging>
|
||||
</FirewallRule>
|
||||
<FirewallRule>
|
||||
<Id>2</Id>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<MatchOnTranslate>false</MatchOnTranslate>
|
||||
<Description>inet prd-001</Description>
|
||||
<Policy>allow</Policy>
|
||||
<Protocols>
|
||||
<Any>true</Any>
|
||||
</Protocols>
|
||||
<Port>-1</Port>
|
||||
<DestinationPortRange>Any</DestinationPortRange>
|
||||
<DestinationIp>Any</DestinationIp>
|
||||
<SourcePort>-1</SourcePort>
|
||||
<SourcePortRange>Any</SourcePortRange>
|
||||
<SourceIp>192.168.109.8</SourceIp>
|
||||
<EnableLogging>false</EnableLogging>
|
||||
</FirewallRule>
|
||||
<FirewallRule>
|
||||
<Id>3</Id>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<MatchOnTranslate>false</MatchOnTranslate>
|
||||
<Description>suppah megah rulez creati0nz</Description>
|
||||
<Policy>allow</Policy>
|
||||
<Protocols>
|
||||
<Any>true</Any>
|
||||
</Protocols>
|
||||
<Port>-1</Port>
|
||||
<DestinationPortRange>Any</DestinationPortRange>
|
||||
<DestinationIp>23.92.224.255</DestinationIp>
|
||||
<SourcePort>-1</SourcePort>
|
||||
<SourcePortRange>Any</SourcePortRange>
|
||||
<SourceIp>Any</SourceIp>
|
||||
<EnableLogging>false</EnableLogging>
|
||||
</FirewallRule>
|
||||
<FirewallRule>
|
||||
<Id>4</Id>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<MatchOnTranslate>false</MatchOnTranslate>
|
||||
<Description>suppah megah rulez creati0nz</Description>
|
||||
<Policy>allow</Policy>
|
||||
<Protocols>
|
||||
<Any>true</Any>
|
||||
</Protocols>
|
||||
<Port>-1</Port>
|
||||
<DestinationPortRange>Any</DestinationPortRange>
|
||||
<DestinationIp>Any</DestinationIp>
|
||||
<SourcePort>-1</SourcePort>
|
||||
<SourcePortRange>Any</SourcePortRange>
|
||||
<SourceIp>192.168.109.3</SourceIp>
|
||||
<EnableLogging>false</EnableLogging>
|
||||
</FirewallRule>
|
||||
</FirewallService>
|
||||
<NatService>
|
||||
<IsEnabled>false</IsEnabled>
|
||||
<NatRule>
|
||||
<RuleType>DNAT</RuleType>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<Id>65537</Id>
|
||||
<GatewayNatRule>
|
||||
<Interface href="http://localhost:4444/api/admin/network/6254f107-9876-4d03-986f-8bec7a4bcb3f" name="d2p3-ext" type="application/vnd.vmware.admin.network+xml"/>
|
||||
<OriginalIp>23.92.225.51</OriginalIp>
|
||||
<OriginalPort>999</OriginalPort>
|
||||
<TranslatedIp>192.168.109.8</TranslatedIp>
|
||||
<TranslatedPort>22</TranslatedPort>
|
||||
<Protocol>Tcp</Protocol>
|
||||
</GatewayNatRule>
|
||||
</NatRule>
|
||||
<NatRule>
|
||||
<RuleType>SNAT</RuleType>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<Id>65538</Id>
|
||||
<GatewayNatRule>
|
||||
<Interface href="http://localhost:4444/api/admin/network/6254f107-9876-4d03-986f-8bec7a4bcb3f" name="d2p3-ext" type="application/vnd.vmware.admin.network+xml"/>
|
||||
<OriginalIp>192.168.109.8</OriginalIp>
|
||||
<TranslatedIp>23.92.225.51</TranslatedIp>
|
||||
</GatewayNatRule>
|
||||
</NatRule>
|
||||
<NatRule>
|
||||
<RuleType>SNAT</RuleType>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<Id>65539</Id>
|
||||
<GatewayNatRule>
|
||||
<Interface href="http://localhost:4444/api/admin/network/6254f107-9876-4d03-986f-8bec7a4bcb3f" name="d2p3-ext" type="application/vnd.vmware.admin.network+xml"/>
|
||||
<OriginalIp>192.168.109.3</OriginalIp>
|
||||
<TranslatedIp>23.92.224.255</TranslatedIp>
|
||||
</GatewayNatRule>
|
||||
</NatRule>
|
||||
<NatRule>
|
||||
<RuleType>DNAT</RuleType>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<Id>65540</Id>
|
||||
<GatewayNatRule>
|
||||
<Interface href="http://localhost:4444/api/admin/network/6254f107-9876-4d03-986f-8bec7a4bcb3f" name="d2p3-ext" type="application/vnd.vmware.admin.network+xml"/>
|
||||
<OriginalIp>23.92.224.255</OriginalIp>
|
||||
<OriginalPort>any</OriginalPort>
|
||||
<TranslatedIp>192.168.109.3</TranslatedIp>
|
||||
<TranslatedPort>any</TranslatedPort>
|
||||
<Protocol>any</Protocol>
|
||||
</GatewayNatRule>
|
||||
</NatRule>
|
||||
</NatService>
|
||||
<GatewayIpsecVpnService>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<Tunnel>
|
||||
<Name>Test VPN Alpha</Name>
|
||||
<Description>For OC Pod Testing</Description>
|
||||
<IpsecVpnThirdPartyPeer>
|
||||
<PeerId>192.168.110.99</PeerId>
|
||||
</IpsecVpnThirdPartyPeer>
|
||||
<PeerIpAddress>64.184.133.62</PeerIpAddress>
|
||||
<PeerId>192.168.110.99</PeerId>
|
||||
<LocalIpAddress>23.92.225.51</LocalIpAddress>
|
||||
<LocalId>23.92.225.51</LocalId>
|
||||
<LocalSubnet>
|
||||
<Name>M916272752-5793-default-routed</Name>
|
||||
<Gateway>192.168.109.1</Gateway>
|
||||
<Netmask>255.255.255.0</Netmask>
|
||||
</LocalSubnet>
|
||||
<PeerSubnet>
|
||||
<Name>192.168.120.0/24</Name>
|
||||
<Gateway>192.168.120.0</Gateway>
|
||||
<Netmask>255.255.255.0</Netmask>
|
||||
</PeerSubnet>
|
||||
<SharedSecret>Blah1Blah2Blah3Blah1Blah2Blah3Blah1Blah2Blah3</SharedSecret>
|
||||
<SharedSecretEncrypted>false</SharedSecretEncrypted>
|
||||
<EncryptionProtocol>AES256</EncryptionProtocol>
|
||||
<Mtu>1500</Mtu>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<IsOperational>false</IsOperational>
|
||||
</Tunnel>
|
||||
<Tunnel>
|
||||
<Name>JGray VPN</Name>
|
||||
<IpsecVpnThirdPartyPeer>
|
||||
<PeerId>67.172.148.74</PeerId>
|
||||
</IpsecVpnThirdPartyPeer>
|
||||
<PeerIpAddress>67.172.148.74</PeerIpAddress>
|
||||
<PeerId>67.172.148.74</PeerId>
|
||||
<LocalIpAddress>23.92.225.51</LocalIpAddress>
|
||||
<LocalId>23.92.225.51</LocalId>
|
||||
<LocalSubnet>
|
||||
<Name>JGray Network</Name>
|
||||
<Gateway>192.168.108.1</Gateway>
|
||||
<Netmask>255.255.255.0</Netmask>
|
||||
</LocalSubnet>
|
||||
<PeerSubnet>
|
||||
<Name>192.168.1.0/24</Name>
|
||||
<Gateway>192.168.1.0</Gateway>
|
||||
<Netmask>255.255.255.0</Netmask>
|
||||
</PeerSubnet>
|
||||
<SharedSecret>fM7puHkGbg6tqpd4jKNhBo45mbs8fw3yapgt3H7f97a2jrkLyYjP9eSH4oGwps7u</SharedSecret>
|
||||
<SharedSecretEncrypted>false</SharedSecretEncrypted>
|
||||
<EncryptionProtocol>AES256</EncryptionProtocol>
|
||||
<Mtu>1500</Mtu>
|
||||
<IsEnabled>false</IsEnabled>
|
||||
<IsOperational>false</IsOperational>
|
||||
</Tunnel>
|
||||
</GatewayIpsecVpnService>
|
||||
<StaticRoutingService>
|
||||
<IsEnabled>false</IsEnabled>
|
||||
</StaticRoutingService>
|
||||
<LoadBalancerService>
|
||||
<IsEnabled>false</IsEnabled>
|
||||
</LoadBalancerService>
|
||||
</EdgeGatewayServiceConfiguration>
|
||||
<HaEnabled>true</HaEnabled>
|
||||
<UseDefaultRouteForDnsRelay>true</UseDefaultRouteForDnsRelay>
|
||||
</Configuration>
|
||||
</EdgeGateway>
|
||||
`
|
||||
56
Godeps/_workspace/src/github.com/vmware/govcloudair/org.go
generated
vendored
Normal file
56
Godeps/_workspace/src/github.com/vmware/govcloudair/org.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type Org struct {
|
||||
Org *types.Org
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewOrg(c *Client) *Org {
|
||||
return &Org{
|
||||
Org: new(types.Org),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Org) FindCatalog(catalog string) (Catalog, error) {
|
||||
|
||||
for _, av := range o.Org.Link {
|
||||
if av.Rel == "down" && av.Type == "application/vnd.vmware.vcloud.catalog+xml" && av.Name == catalog {
|
||||
u, err := url.ParseRequestURI(av.HREF)
|
||||
|
||||
if err != nil {
|
||||
return Catalog{}, fmt.Errorf("error decoding org response: %s", err)
|
||||
}
|
||||
|
||||
req := o.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(o.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Catalog{}, fmt.Errorf("error retreiving catalog: %s", err)
|
||||
}
|
||||
|
||||
cat := NewCatalog(o.c)
|
||||
|
||||
if err = decodeBody(resp, cat.Catalog); err != nil {
|
||||
return Catalog{}, fmt.Errorf("error decoding catalog response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *cat, nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return Catalog{}, fmt.Errorf("can't find catalog: %s", catalog)
|
||||
}
|
||||
55
Godeps/_workspace/src/github.com/vmware/govcloudair/org_test.go
generated
vendored
Normal file
55
Godeps/_workspace/src/github.com/vmware/govcloudair/org_test.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *S) Test_FindCatalog(c *C) {
|
||||
|
||||
// Get the Org populated
|
||||
testServer.Response(200, nil, orgExample)
|
||||
org, err := s.vdc.GetVDCOrg()
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Find Catalog
|
||||
testServer.Response(200, nil, catalogExample)
|
||||
cat, err := org.FindCatalog("Public Catalog")
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(cat.Catalog.Description, Equals, "vCHS service catalog")
|
||||
|
||||
}
|
||||
|
||||
var orgExample = `
|
||||
<?xml version="1.0" ?>
|
||||
<Org href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57" id="urn:vcloud:org:23bd2339-c55f-403c-baf3-13109e8c8d57" name="M916272752-5793" type="application/vnd.vmware.vcloud.org+xml" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Link href="http://localhost:4444/api/vdc/214cd6b2-3f7a-4ee5-9b0a-52b4001a4a84" name="M916272752-5793" rel="down" type="application/vnd.vmware.vcloud.vdc+xml"/>
|
||||
<Link href="http://localhost:4444/api/tasksList/23bd2339-c55f-403c-baf3-13109e8c8d57" rel="down" type="application/vnd.vmware.vcloud.tasksList+xml"/>
|
||||
<Link href="http://localhost:4444/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854" name="Public Catalog" rel="down" type="application/vnd.vmware.vcloud.catalog+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854/controlAccess/" rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/catalog/5cb6451b-8091-4c89-930d-1ff9653cb12d" name="PSE" rel="down" type="application/vnd.vmware.vcloud.catalog+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/catalog/5cb6451b-8091-4c89-930d-1ff9653cb12d/controlAccess/" rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/catalog/5cb6451b-8091-4c89-930d-1ff9653cb12d/action/controlAccess" rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/catalog/8715ed97-348a-4bdd-aea3-e13e84213e6f" name="GCoE" rel="down" type="application/vnd.vmware.vcloud.catalog+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/catalog/8715ed97-348a-4bdd-aea3-e13e84213e6f/controlAccess/" rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/catalog/8715ed97-348a-4bdd-aea3-e13e84213e6f/action/controlAccess" rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/catalog/92d4ad5a-217e-4bd1-8bcf-be9cc70dcfa6" name="Vagrant" rel="down" type="application/vnd.vmware.vcloud.catalog+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/catalog/92d4ad5a-217e-4bd1-8bcf-be9cc70dcfa6/controlAccess/" rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/catalog/92d4ad5a-217e-4bd1-8bcf-be9cc70dcfa6/action/controlAccess" rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/admin/org/23bd2339-c55f-403c-baf3-13109e8c8d57/catalogs" rel="add" type="application/vnd.vmware.admin.catalog+xml"/>
|
||||
<Link href="http://localhost:4444/api/network/8d0cbfe2-25b3-4a1f-b608-5ffeabc7a53d" name="M916272752-5793-default-isolated" rel="down" type="application/vnd.vmware.vcloud.orgNetwork+xml"/>
|
||||
<Link href="http://localhost:4444/api/network/cb0f4c9e-1a46-49d4-9fcb-d228000a6bc1" name="networkName" rel="down" type="application/vnd.vmware.vcloud.orgNetwork+xml"/>
|
||||
<Link href="http://localhost:4444/api/supportedSystemsInfo/" rel="down" type="application/vnd.vmware.vcloud.supportedSystemsInfo+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/metadata" rel="down" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Link href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57/hybrid" rel="down" type="application/vnd.vmware.vcloud.hybridOrg+xml"/>
|
||||
<Description/>
|
||||
<FullName>OrganizationName</FullName>
|
||||
</Org>
|
||||
`
|
||||
21
Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork.go
generated
vendored
Normal file
21
Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type OrgVDCNetwork struct {
|
||||
OrgVDCNetwork *types.OrgVDCNetwork
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewOrgVDCNetwork(c *Client) *OrgVDCNetwork {
|
||||
return &OrgVDCNetwork{
|
||||
OrgVDCNetwork: new(types.OrgVDCNetwork),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
34
Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork_test.go
generated
vendored
Normal file
34
Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork_test.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
var orgvdcnetExample = `
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<OrgVdcNetwork xmlns="http://www.vmware.com/vcloud/v1.5" status="1" name="networkName" id="urn:vcloud:network:cb0f4c9e-1a46-49d4-9fcb-d228000a6bc1" href="http://localhost:4444/api/network/cb0f4c9e-1a46-49d4-9fcb-d228000a6bc1" type="application/vnd.vmware.vcloud.orgVdcNetwork+xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Link rel="up" href="http://localhost:4444/api/vdc/214cd6b2-3f7a-4ee5-9b0a-52b4001a4a84" type="application/vnd.vmware.vcloud.vdc+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/network/cb0f4c9e-1a46-49d4-9fcb-d228000a6bc1/metadata" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/network/cb0f4c9e-1a46-49d4-9fcb-d228000a6bc1/allocatedAddresses/" type="application/vnd.vmware.vcloud.allocatedNetworkAddress+xml"/>
|
||||
<Description>This routed network was created with Create VDC.</Description>
|
||||
<Configuration>
|
||||
<IpScopes>
|
||||
<IpScope>
|
||||
<IsInherited>false</IsInherited>
|
||||
<Gateway>192.168.109.1</Gateway>
|
||||
<Netmask>255.255.255.0</Netmask>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<IpRanges>
|
||||
<IpRange>
|
||||
<StartAddress>192.168.109.2</StartAddress>
|
||||
<EndAddress>192.168.109.100</EndAddress>
|
||||
</IpRange>
|
||||
</IpRanges>
|
||||
</IpScope>
|
||||
</IpScopes>
|
||||
<FenceMode>natRouted</FenceMode>
|
||||
<RetainNetInfoAcrossDeployments>false</RetainNetInfoAcrossDeployments>
|
||||
</Configuration>
|
||||
<IsShared>false</IsShared>
|
||||
</OrgVdcNetwork>
|
||||
`
|
||||
52
Godeps/_workspace/src/github.com/vmware/govcloudair/script/coverage
generated
vendored
Executable file
52
Godeps/_workspace/src/github.com/vmware/govcloudair/script/coverage
generated
vendored
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
# Generate test coverage statistics for Go packages.
|
||||
#
|
||||
# Works around the fact that `go test -coverprofile` currently does not work
|
||||
# with multiple packages, see https://code.google.com/p/go/issues/detail?id=6909
|
||||
#
|
||||
# Usage: script/coverage [--html|--coveralls]
|
||||
#
|
||||
# --html Additionally create HTML report and open it in browser
|
||||
# --coveralls Push coverage statistics to coveralls.io
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
workdir=.cover
|
||||
profile="$workdir/cover.out"
|
||||
mode=count
|
||||
|
||||
generate_cover_data() {
|
||||
rm -rf "$workdir"
|
||||
mkdir "$workdir"
|
||||
|
||||
for pkg in "$@"; do
|
||||
f="$workdir/$(echo $pkg | tr / -).cover"
|
||||
go test -covermode="$mode" -coverprofile="$f" "$pkg"
|
||||
done
|
||||
|
||||
echo "mode: $mode" >"$profile"
|
||||
grep -h -v "^mode:" "$workdir"/*.cover >>"$profile"
|
||||
}
|
||||
|
||||
show_cover_report() {
|
||||
go tool cover -${1}="$profile"
|
||||
}
|
||||
|
||||
push_to_coveralls() {
|
||||
echo "Pushing coverage statistics to coveralls.io"
|
||||
goveralls -coverprofile="$profile"
|
||||
}
|
||||
|
||||
generate_cover_data $(go list ./...)
|
||||
show_cover_report func
|
||||
case "$1" in
|
||||
"")
|
||||
;;
|
||||
--html)
|
||||
show_cover_report html ;;
|
||||
--coveralls)
|
||||
push_to_coveralls ;;
|
||||
*)
|
||||
echo >&2 "error: invalid option: $1"; exit 1 ;;
|
||||
esac
|
||||
77
Godeps/_workspace/src/github.com/vmware/govcloudair/task.go
generated
vendored
Normal file
77
Godeps/_workspace/src/github.com/vmware/govcloudair/task.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type Task struct {
|
||||
Task *types.Task
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewTask(c *Client) *Task {
|
||||
return &Task{
|
||||
Task: new(types.Task),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Task) Refresh() error {
|
||||
|
||||
if t.Task == nil {
|
||||
return fmt.Errorf("cannot refresh, Object is empty")
|
||||
}
|
||||
|
||||
u, _ := url.ParseRequestURI(t.Task.HREF)
|
||||
|
||||
req := t.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(t.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving task: %s", err)
|
||||
}
|
||||
|
||||
// Empty struct before a new unmarshal, otherwise we end up with duplicate
|
||||
// elements in slices.
|
||||
t.Task = &types.Task{}
|
||||
|
||||
if err = decodeBody(resp, t.Task); err != nil {
|
||||
return fmt.Errorf("error decoding task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Task) WaitTaskCompletion() error {
|
||||
|
||||
if t.Task == nil {
|
||||
return fmt.Errorf("cannot refresh, Object is empty")
|
||||
}
|
||||
|
||||
for {
|
||||
err := t.Refresh()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retreiving task: %s", err)
|
||||
}
|
||||
|
||||
// If task is not in a waiting status we're done, check if there's an error and return it.
|
||||
if t.Task.Status != "queued" && t.Task.Status != "preRunning" && t.Task.Status != "running" {
|
||||
if t.Task.Status == "error" {
|
||||
return fmt.Errorf("task did not complete succesfully: %s", t.Task.Description)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sleep for 3 seconds and try again.
|
||||
time.Sleep(3 * time.Second)
|
||||
}
|
||||
}
|
||||
35
Godeps/_workspace/src/github.com/vmware/govcloudair/task_test.go
generated
vendored
Normal file
35
Godeps/_workspace/src/github.com/vmware/govcloudair/task_test.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *S) Test_WaitTaskCompletion(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.Deploy()
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
err = task.WaitTaskCompletion()
|
||||
_ = testServer.WaitRequest()
|
||||
testServer.Flush()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
}
|
||||
|
||||
var taskExample = `
|
||||
<Task cancelRequested="false" endTime="2014-11-10T09:09:31.483Z" expiryTime="2015-02-08T09:09:16.627Z" href="http://localhost:4444/api/task/1b8f926c-eff5-4bea-9b13-4e49bdd50c05" id="urn:vcloud:task:1b8f926c-eff5-4bea-9b13-4e49bdd50c05" name="task" operation="Composed Virtual Application Test API GO4(fdb86157-2e1f-4889-9942-0463836d10e1)" operationName="vdcComposeVapp" serviceNamespace="com.vmware.vcloud" startTime="2014-11-10T09:09:16.627Z" status="success" type="application/vnd.vmware.vcloud.task+xml" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Owner href="http://localhost:4444/api/vApp/vapp-fdb86157-2e1f-4889-9942-0463836d10e1" name="Test API GO4" type="application/vnd.vmware.vcloud.vApp+xml"/>
|
||||
<User href="http://localhost:4444/api/admin/user/d8ac278a-5b49-4c85-9a81-468838e89eb9" name="frapposelli1@gts-vchs.com" type="application/vnd.vmware.admin.user+xml"/>
|
||||
<Organization href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57" name="M916272752-5793" type="application/vnd.vmware.vcloud.org+xml"/>
|
||||
<Progress>100</Progress>
|
||||
<Details/>
|
||||
</Task>
|
||||
`
|
||||
186
Godeps/_workspace/src/github.com/vmware/govcloudair/testutil/http.go
generated
vendored
Normal file
186
Godeps/_workspace/src/github.com/vmware/govcloudair/testutil/http.go
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
//
|
||||
// The software in this package is published under the terms of the Mozilla
|
||||
// Public License, version 2.0 a copy of which has been included with this
|
||||
// distribution in the LICENSE file.
|
||||
//
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type HTTPServer struct {
|
||||
URL string
|
||||
Timeout time.Duration
|
||||
started bool
|
||||
request chan *http.Request
|
||||
response chan ResponseFunc
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Status int
|
||||
Headers map[string]string
|
||||
Body string
|
||||
}
|
||||
|
||||
var DefaultClient = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
},
|
||||
}
|
||||
|
||||
func NewHTTPServer() *HTTPServer {
|
||||
return &HTTPServer{URL: "http://localhost:4444", Timeout: 5 * time.Second}
|
||||
}
|
||||
|
||||
type ResponseFunc func(path string) Response
|
||||
|
||||
func (s *HTTPServer) Start() {
|
||||
if s.started {
|
||||
return
|
||||
}
|
||||
s.started = true
|
||||
s.request = make(chan *http.Request, 1024)
|
||||
s.response = make(chan ResponseFunc, 1024)
|
||||
u, err := url.Parse(s.URL)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
l, err := net.Listen("tcp", u.Host)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go http.Serve(l, s)
|
||||
|
||||
s.Response(203, nil, "")
|
||||
for {
|
||||
// Wait for it to be up.
|
||||
resp, err := http.Get(s.URL)
|
||||
if err == nil && resp.StatusCode == 203 {
|
||||
break
|
||||
}
|
||||
time.Sleep(1e8)
|
||||
}
|
||||
s.WaitRequest() // Consume dummy request.
|
||||
}
|
||||
|
||||
// Flush discards all pending requests and responses.
|
||||
func (s *HTTPServer) Flush() {
|
||||
for {
|
||||
select {
|
||||
case <-s.request:
|
||||
case <-s.response:
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func body(req *http.Request) string {
|
||||
data, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func (s *HTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
req.ParseMultipartForm(1e6)
|
||||
data, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
req.Body = ioutil.NopCloser(bytes.NewBuffer(data))
|
||||
s.request <- req
|
||||
var resp Response
|
||||
select {
|
||||
case respFunc := <-s.response:
|
||||
resp = respFunc(req.URL.Path)
|
||||
case <-time.After(s.Timeout):
|
||||
const msg = "ERROR: Timeout waiting for test to prepare a response\n"
|
||||
fmt.Fprintf(os.Stderr, msg)
|
||||
resp = Response{500, nil, msg}
|
||||
}
|
||||
if resp.Headers != nil {
|
||||
h := w.Header()
|
||||
for k, v := range resp.Headers {
|
||||
h.Set(k, v)
|
||||
}
|
||||
}
|
||||
if resp.Status != 0 {
|
||||
w.WriteHeader(resp.Status)
|
||||
}
|
||||
w.Write([]byte(resp.Body))
|
||||
}
|
||||
|
||||
// WaitRequests returns the next n requests made to the http server from
|
||||
// the queue. If not enough requests were previously made, it waits until
|
||||
// the timeout value for them to be made.
|
||||
func (s *HTTPServer) WaitRequests(n int) []*http.Request {
|
||||
reqs := make([]*http.Request, 0, n)
|
||||
for i := 0; i < n; i++ {
|
||||
select {
|
||||
case req := <-s.request:
|
||||
reqs = append(reqs, req)
|
||||
case <-time.After(s.Timeout):
|
||||
panic("Timeout waiting for request")
|
||||
}
|
||||
}
|
||||
return reqs
|
||||
}
|
||||
|
||||
// WaitRequest returns the next request made to the http server from
|
||||
// the queue. If no requests were previously made, it waits until the
|
||||
// timeout value for one to be made.
|
||||
func (s *HTTPServer) WaitRequest() *http.Request {
|
||||
return s.WaitRequests(1)[0]
|
||||
}
|
||||
|
||||
// ResponseFunc prepares the test server to respond the following n
|
||||
// requests using f to build each response.
|
||||
func (s *HTTPServer) ResponseFunc(n int, f ResponseFunc) {
|
||||
for i := 0; i < n; i++ {
|
||||
s.response <- f
|
||||
}
|
||||
}
|
||||
|
||||
// ResponseMap maps request paths to responses.
|
||||
type ResponseMap map[string]Response
|
||||
|
||||
// ResponseMap prepares the test server to respond the following n
|
||||
// requests using the m to obtain the responses.
|
||||
func (s *HTTPServer) ResponseMap(n int, m ResponseMap) {
|
||||
f := func(path string) Response {
|
||||
for rpath, resp := range m {
|
||||
if rpath == path {
|
||||
return resp
|
||||
}
|
||||
}
|
||||
body := "Path not found in response map: " + path
|
||||
return Response{Status: 500, Body: body}
|
||||
}
|
||||
s.ResponseFunc(n, f)
|
||||
}
|
||||
|
||||
// Responses prepares the test server to respond the following n requests
|
||||
// using the provided response parameters.
|
||||
func (s *HTTPServer) Responses(n int, status int, headers map[string]string, body string) {
|
||||
f := func(path string) Response {
|
||||
return Response{status, headers, body}
|
||||
}
|
||||
s.ResponseFunc(n, f)
|
||||
}
|
||||
|
||||
// Response prepares the test server to respond the following request
|
||||
// using the provided response parameters.
|
||||
func (s *HTTPServer) Response(status int, headers map[string]string, body string) {
|
||||
s.Responses(1, status, headers, body)
|
||||
}
|
||||
1394
Godeps/_workspace/src/github.com/vmware/govcloudair/types/v56/types.go
generated
vendored
Normal file
1394
Godeps/_workspace/src/github.com/vmware/govcloudair/types/v56/types.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
602
Godeps/_workspace/src/github.com/vmware/govcloudair/vapp.go
generated
vendored
Normal file
602
Godeps/_workspace/src/github.com/vmware/govcloudair/vapp.go
generated
vendored
Normal file
@@ -0,0 +1,602 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type VApp struct {
|
||||
VApp *types.VApp
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewVApp(c *Client) *VApp {
|
||||
return &VApp{
|
||||
VApp: new(types.VApp),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (v *VApp) Refresh() error {
|
||||
|
||||
if v.VApp.HREF == "" {
|
||||
return fmt.Errorf("cannot refresh, Object is empty")
|
||||
}
|
||||
|
||||
u, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving task: %s", err)
|
||||
}
|
||||
|
||||
// Empty struct before a new unmarshal, otherwise we end up with duplicate
|
||||
// elements in slices.
|
||||
v.VApp = &types.VApp{}
|
||||
|
||||
if err = decodeBody(resp, v.VApp); err != nil {
|
||||
return fmt.Errorf("error decoding task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *VApp) ComposeVApp(orgvdcnetwork OrgVDCNetwork, vapptemplate VAppTemplate, name string, description string) (Task, error) {
|
||||
|
||||
if vapptemplate.VAppTemplate.Children == nil || orgvdcnetwork.OrgVDCNetwork == nil {
|
||||
return Task{}, fmt.Errorf("can't compose a new vApp, objects passed are not valid")
|
||||
}
|
||||
|
||||
// Build request XML
|
||||
vcomp := &types.ComposeVAppParams{
|
||||
Ovf: "http://schemas.dmtf.org/ovf/envelope/1",
|
||||
Xsi: "http://www.w3.org/2001/XMLSchema-instance",
|
||||
Xmlns: "http://www.vmware.com/vcloud/v1.5",
|
||||
Deploy: false,
|
||||
Name: name,
|
||||
PowerOn: false,
|
||||
Description: description,
|
||||
InstantiationParams: &types.InstantiationParams{
|
||||
NetworkConfigSection: &types.NetworkConfigSection{
|
||||
Info: "Configuration parameters for logical networks",
|
||||
NetworkConfig: &types.VAppNetworkConfiguration{
|
||||
NetworkName: orgvdcnetwork.OrgVDCNetwork.Name,
|
||||
Configuration: &types.NetworkConfiguration{
|
||||
FenceMode: "bridged",
|
||||
ParentNetwork: &types.Reference{
|
||||
HREF: orgvdcnetwork.OrgVDCNetwork.HREF,
|
||||
Name: orgvdcnetwork.OrgVDCNetwork.Name,
|
||||
Type: orgvdcnetwork.OrgVDCNetwork.Type,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
SourcedItem: &types.SourcedCompositionItemParam{
|
||||
Source: &types.Reference{
|
||||
HREF: vapptemplate.VAppTemplate.Children.VM[0].HREF,
|
||||
Name: vapptemplate.VAppTemplate.Children.VM[0].Name,
|
||||
},
|
||||
InstantiationParams: &types.InstantiationParams{
|
||||
NetworkConnectionSection: &types.NetworkConnectionSection{
|
||||
Type: vapptemplate.VAppTemplate.Children.VM[0].NetworkConnectionSection.Type,
|
||||
HREF: vapptemplate.VAppTemplate.Children.VM[0].NetworkConnectionSection.HREF,
|
||||
Info: "Network config for sourced item",
|
||||
PrimaryNetworkConnectionIndex: vapptemplate.VAppTemplate.Children.VM[0].NetworkConnectionSection.PrimaryNetworkConnectionIndex,
|
||||
NetworkConnection: &types.NetworkConnection{
|
||||
Network: orgvdcnetwork.OrgVDCNetwork.Name,
|
||||
NetworkConnectionIndex: vapptemplate.VAppTemplate.Children.VM[0].NetworkConnectionSection.NetworkConnection.NetworkConnectionIndex,
|
||||
IsConnected: true,
|
||||
IPAddressAllocationMode: "POOL",
|
||||
},
|
||||
},
|
||||
},
|
||||
NetworkAssignment: &types.NetworkAssignment{
|
||||
InnerNetwork: orgvdcnetwork.OrgVDCNetwork.Name,
|
||||
ContainerNetwork: orgvdcnetwork.OrgVDCNetwork.Name,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
output, err := xml.MarshalIndent(vcomp, " ", " ")
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error marshaling vapp compose: %s", err)
|
||||
}
|
||||
|
||||
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
|
||||
|
||||
if debug == "true" {
|
||||
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString(xml.Header + string(output))
|
||||
|
||||
s := v.c.VCDVDCHREF
|
||||
s.Path += "/action/composeVApp"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", s, b)
|
||||
|
||||
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.composeVAppParams+xml")
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error instantiating a new vApp: %s", err)
|
||||
}
|
||||
|
||||
if err = decodeBody(resp, v.VApp); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding vApp response: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
task.Task = v.VApp.Tasks.Task[0]
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) PowerOn() (Task, error) {
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
s.Path += "/power/action/powerOn"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", *s, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error powering on vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) PowerOff() (Task, error) {
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
s.Path += "/power/action/powerOff"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", *s, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error powering off vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) Reboot() (Task, error) {
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
s.Path += "/power/action/reboot"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", *s, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error rebooting vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) Reset() (Task, error) {
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
s.Path += "/power/action/reset"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", *s, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error resetting vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) Suspend() (Task, error) {
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
s.Path += "/power/action/suspend"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", *s, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error suspending vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) Shutdown() (Task, error) {
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
s.Path += "/power/action/shutdown"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", *s, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error shutting down vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) Undeploy() (Task, error) {
|
||||
|
||||
vu := &types.UndeployVAppParams{
|
||||
Xmlns: "http://www.vmware.com/vcloud/v1.5",
|
||||
UndeployPowerAction: "powerOff",
|
||||
}
|
||||
|
||||
output, err := xml.MarshalIndent(vu, " ", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
|
||||
|
||||
if debug == "true" {
|
||||
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString(xml.Header + string(output))
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
s.Path += "/action/undeploy"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", *s, b)
|
||||
|
||||
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.undeployVAppParams+xml")
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error undeploy vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) Deploy() (Task, error) {
|
||||
|
||||
vu := &types.DeployVAppParams{
|
||||
Xmlns: "http://www.vmware.com/vcloud/v1.5",
|
||||
PowerOn: false,
|
||||
}
|
||||
|
||||
output, err := xml.MarshalIndent(vu, " ", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
|
||||
|
||||
if debug == "true" {
|
||||
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString(xml.Header + string(output))
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
s.Path += "/action/deploy"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "POST", *s, b)
|
||||
|
||||
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.deployVAppParams+xml")
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error undeploy vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) Delete() (Task, error) {
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.HREF)
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "DELETE", *s, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error deleting vApp: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) RunCustomizationScript(computername, script string) (Task, error) {
|
||||
|
||||
err := v.Refresh()
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error refreshing vapp before running customization: %v", err)
|
||||
}
|
||||
|
||||
// Check if VApp Children is populated
|
||||
if v.VApp.Children == nil {
|
||||
return Task{}, fmt.Errorf("vApp doesn't contain any children, aborting customization")
|
||||
}
|
||||
|
||||
vu := &types.GuestCustomizationSection{
|
||||
Ovf: "http://schemas.dmtf.org/ovf/envelope/1",
|
||||
Xsi: "http://www.w3.org/2001/XMLSchema-instance",
|
||||
Xmlns: "http://www.vmware.com/vcloud/v1.5",
|
||||
|
||||
HREF: v.VApp.Children.VM[0].HREF,
|
||||
Type: "application/vnd.vmware.vcloud.guestCustomizationSection+xml",
|
||||
Info: "Specifies Guest OS Customization Settings",
|
||||
Enabled: true,
|
||||
ComputerName: computername,
|
||||
CustomizationScript: script,
|
||||
}
|
||||
|
||||
output, err := xml.MarshalIndent(vu, " ", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
|
||||
|
||||
if debug == "true" {
|
||||
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString(xml.Header + string(output))
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.Children.VM[0].HREF)
|
||||
s.Path += "/guestCustomizationSection/"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "PUT", *s, b)
|
||||
|
||||
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.guestCustomizationSection+xml")
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error customizing VM: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) GetStatus() (string, error) {
|
||||
err := v.Refresh()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error refreshing vapp: %v", err)
|
||||
}
|
||||
return types.VAppStatuses[v.VApp.Status], nil
|
||||
}
|
||||
|
||||
func (v *VApp) ChangeCPUcount(size int) (Task, error) {
|
||||
|
||||
err := v.Refresh()
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error refreshing vapp before running customization: %v", err)
|
||||
}
|
||||
|
||||
// Check if VApp Children is populated
|
||||
if v.VApp.Children == nil {
|
||||
return Task{}, fmt.Errorf("vApp doesn't contain any children, aborting customization")
|
||||
}
|
||||
|
||||
newcpu := &types.OVFItem{
|
||||
XmlnsRasd: "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData",
|
||||
XmlnsVCloud: "http://www.vmware.com/vcloud/v1.5",
|
||||
XmlnsXsi: "http://www.w3.org/2001/XMLSchema-instance",
|
||||
VCloudHREF: v.VApp.Children.VM[0].HREF + "/virtualHardwareSection/cpu",
|
||||
VCloudType: "application/vnd.vmware.vcloud.rasdItem+xml",
|
||||
AllocationUnits: "hertz * 10^6",
|
||||
Description: "Number of Virtual CPUs",
|
||||
ElementName: strconv.Itoa(size) + " virtual CPU(s)",
|
||||
InstanceID: 4,
|
||||
Reservation: 0,
|
||||
ResourceType: 3,
|
||||
VirtualQuantity: size,
|
||||
Weight: 0,
|
||||
Link: &types.Link{
|
||||
HREF: v.VApp.Children.VM[0].HREF + "/virtualHardwareSection/cpu",
|
||||
Rel: "edit",
|
||||
Type: "application/vnd.vmware.vcloud.rasdItem+xml",
|
||||
},
|
||||
}
|
||||
|
||||
output, err := xml.MarshalIndent(newcpu, " ", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
|
||||
|
||||
if debug == "true" {
|
||||
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString(xml.Header + string(output))
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.Children.VM[0].HREF)
|
||||
s.Path += "/virtualHardwareSection/cpu"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "PUT", *s, b)
|
||||
|
||||
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.rasdItem+xml")
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error customizing VM: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
|
||||
func (v *VApp) ChangeMemorySize(size int) (Task, error) {
|
||||
|
||||
err := v.Refresh()
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error refreshing vapp before running customization: %v", err)
|
||||
}
|
||||
|
||||
// Check if VApp Children is populated
|
||||
if v.VApp.Children == nil {
|
||||
return Task{}, fmt.Errorf("vApp doesn't contain any children, aborting customization")
|
||||
}
|
||||
|
||||
newmem := &types.OVFItem{
|
||||
XmlnsRasd: "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData",
|
||||
XmlnsVCloud: "http://www.vmware.com/vcloud/v1.5",
|
||||
XmlnsXsi: "http://www.w3.org/2001/XMLSchema-instance",
|
||||
VCloudHREF: v.VApp.Children.VM[0].HREF + "/virtualHardwareSection/memory",
|
||||
VCloudType: "application/vnd.vmware.vcloud.rasdItem+xml",
|
||||
AllocationUnits: "byte * 2^20",
|
||||
Description: "Memory Size",
|
||||
ElementName: strconv.Itoa(size) + " MB of memory",
|
||||
InstanceID: 5,
|
||||
Reservation: 0,
|
||||
ResourceType: 4,
|
||||
VirtualQuantity: size,
|
||||
Weight: 0,
|
||||
Link: &types.Link{
|
||||
HREF: v.VApp.Children.VM[0].HREF + "/virtualHardwareSection/memory",
|
||||
Rel: "edit",
|
||||
Type: "application/vnd.vmware.vcloud.rasdItem+xml",
|
||||
},
|
||||
}
|
||||
|
||||
output, err := xml.MarshalIndent(newmem, " ", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
||||
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
|
||||
|
||||
if debug == "true" {
|
||||
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString(xml.Header + string(output))
|
||||
|
||||
s, _ := url.ParseRequestURI(v.VApp.Children.VM[0].HREF)
|
||||
s.Path += "/virtualHardwareSection/memory"
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "PUT", *s, b)
|
||||
|
||||
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.rasdItem+xml")
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Task{}, fmt.Errorf("error customizing VM: %s", err)
|
||||
}
|
||||
|
||||
task := NewTask(v.c)
|
||||
|
||||
if err = decodeBody(resp, task.Task); err != nil {
|
||||
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *task, nil
|
||||
|
||||
}
|
||||
597
Godeps/_workspace/src/github.com/vmware/govcloudair/vapp_test.go
generated
vendored
Normal file
597
Godeps/_workspace/src/github.com/vmware/govcloudair/vapp_test.go
generated
vendored
Normal file
@@ -0,0 +1,597 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"github.com/vmware/govcloudair/testutil"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *S) Test_ComposeVApp(c *C) {
|
||||
|
||||
testServer.ResponseMap(7, testutil.ResponseMap{
|
||||
"/api/org/11111111-1111-1111-1111-111111111111": testutil.Response{200, nil, orgExample},
|
||||
"/api/network/44444444-4444-4444-4444-4444444444444": testutil.Response{200, nil, orgvdcnetExample},
|
||||
"/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854": testutil.Response{200, nil, catalogExample},
|
||||
"/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae": testutil.Response{200, nil, catalogitemExample},
|
||||
"/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5": testutil.Response{200, nil, vapptemplateExample},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000/action/composeVApp": testutil.Response{200, nil, instantiatedvappExample},
|
||||
"/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample},
|
||||
})
|
||||
|
||||
// Get the Org populated
|
||||
org, err := s.vdc.GetVDCOrg()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate OrgVDCNetwork
|
||||
net, err := s.vdc.FindVDCNetwork("networkName")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog
|
||||
cat, err := org.FindCatalog("Public Catalog")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog Item
|
||||
catitem, err := cat.FindCatalogItem("CentOS64-32bit")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Get VAppTemplate
|
||||
vapptemplate, err := catitem.GetVAppTemplate()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Compose VApp
|
||||
task, err := s.vapp.ComposeVApp(net, vapptemplate, "name", "description")
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.OperationName, Equals, "vdcInstantiateVapp")
|
||||
c.Assert(s.vapp.VApp.HREF, Equals, "http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000")
|
||||
|
||||
status, err := s.vapp.GetStatus()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(status, Equals, "POWERED_OFF")
|
||||
|
||||
_ = testServer.WaitRequests(7)
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_PowerOn(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.PowerOn()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_PowerOff(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.PowerOff()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_Reboot(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.Reboot()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_Reset(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.Reset()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_Suspend(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.Suspend()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_Shutdown(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.Shutdown()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_Undeploy(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.Undeploy()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_Deploy(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.Deploy()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_Delete(c *C) {
|
||||
|
||||
testServer.Response(200, nil, taskExample)
|
||||
task, err := s.vapp.Delete()
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_RunCustomizationScript(c *C) {
|
||||
|
||||
testServer.ResponseMap(8, testutil.ResponseMap{
|
||||
"/api/org/11111111-1111-1111-1111-111111111111": testutil.Response{200, nil, orgExample},
|
||||
"/api/network/44444444-4444-4444-4444-4444444444444": testutil.Response{200, nil, orgvdcnetExample},
|
||||
"/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854": testutil.Response{200, nil, catalogExample},
|
||||
"/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae": testutil.Response{200, nil, catalogitemExample},
|
||||
"/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5": testutil.Response{200, nil, vapptemplateExample},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000/action/composeVApp": testutil.Response{200, nil, instantiatedvappExample},
|
||||
"/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample},
|
||||
"/api/vApp/vm-00000000-0000-0000-0000-000000000000/guestCustomizationSection/": testutil.Response{200, nil, taskExample},
|
||||
})
|
||||
|
||||
// Get the Org populated
|
||||
org, err := s.vdc.GetVDCOrg()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate OrgVDCNetwork
|
||||
net, err := s.vdc.FindVDCNetwork("networkName")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog
|
||||
cat, err := org.FindCatalog("Public Catalog")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog Item
|
||||
catitem, err := cat.FindCatalogItem("CentOS64-32bit")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Get VAppTemplate
|
||||
vapptemplate, err := catitem.GetVAppTemplate()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Compose VApp
|
||||
task, err := s.vapp.ComposeVApp(net, vapptemplate, "name", "description")
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.OperationName, Equals, "vdcInstantiateVapp")
|
||||
c.Assert(s.vapp.VApp.HREF, Equals, "http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000")
|
||||
|
||||
task, err = s.vapp.RunCustomizationScript("computername", "this is my script")
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
_ = testServer.WaitRequests(8)
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_ChangeCPUcount(c *C) {
|
||||
|
||||
testServer.ResponseMap(8, testutil.ResponseMap{
|
||||
"/api/org/11111111-1111-1111-1111-111111111111": testutil.Response{200, nil, orgExample},
|
||||
"/api/network/44444444-4444-4444-4444-4444444444444": testutil.Response{200, nil, orgvdcnetExample},
|
||||
"/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854": testutil.Response{200, nil, catalogExample},
|
||||
"/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae": testutil.Response{200, nil, catalogitemExample},
|
||||
"/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5": testutil.Response{200, nil, vapptemplateExample},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000/action/composeVApp": testutil.Response{200, nil, instantiatedvappExample},
|
||||
"/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample},
|
||||
"/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/cpu": testutil.Response{200, nil, taskExample},
|
||||
})
|
||||
|
||||
// Get the Org populated
|
||||
org, err := s.vdc.GetVDCOrg()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate OrgVDCNetwork
|
||||
net, err := s.vdc.FindVDCNetwork("networkName")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog
|
||||
cat, err := org.FindCatalog("Public Catalog")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog Item
|
||||
catitem, err := cat.FindCatalogItem("CentOS64-32bit")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Get VAppTemplate
|
||||
vapptemplate, err := catitem.GetVAppTemplate()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Compose VApp
|
||||
task, err := s.vapp.ComposeVApp(net, vapptemplate, "name", "description")
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.OperationName, Equals, "vdcInstantiateVapp")
|
||||
c.Assert(s.vapp.VApp.HREF, Equals, "http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000")
|
||||
|
||||
task, err = s.vapp.ChangeCPUcount(2)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
_ = testServer.WaitRequests(8)
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_ChangeMemorySize(c *C) {
|
||||
|
||||
testServer.ResponseMap(8, testutil.ResponseMap{
|
||||
"/api/org/11111111-1111-1111-1111-111111111111": testutil.Response{200, nil, orgExample},
|
||||
"/api/network/44444444-4444-4444-4444-4444444444444": testutil.Response{200, nil, orgvdcnetExample},
|
||||
"/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854": testutil.Response{200, nil, catalogExample},
|
||||
"/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae": testutil.Response{200, nil, catalogitemExample},
|
||||
"/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5": testutil.Response{200, nil, vapptemplateExample},
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000/action/composeVApp": testutil.Response{200, nil, instantiatedvappExample},
|
||||
"/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample},
|
||||
"/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/memory": testutil.Response{200, nil, taskExample},
|
||||
})
|
||||
|
||||
// Get the Org populated
|
||||
org, err := s.vdc.GetVDCOrg()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate OrgVDCNetwork
|
||||
net, err := s.vdc.FindVDCNetwork("networkName")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog
|
||||
cat, err := org.FindCatalog("Public Catalog")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Populate Catalog Item
|
||||
catitem, err := cat.FindCatalogItem("CentOS64-32bit")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Get VAppTemplate
|
||||
vapptemplate, err := catitem.GetVAppTemplate()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// Compose VApp
|
||||
task, err := s.vapp.ComposeVApp(net, vapptemplate, "name", "description")
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.OperationName, Equals, "vdcInstantiateVapp")
|
||||
c.Assert(s.vapp.VApp.HREF, Equals, "http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000")
|
||||
|
||||
task, err = s.vapp.ChangeMemorySize(4096)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(task.Task.Status, Equals, "success")
|
||||
|
||||
_ = testServer.WaitRequests(8)
|
||||
|
||||
}
|
||||
|
||||
var instantiatedvappExample = `
|
||||
<?xml version="1.0" ?>
|
||||
<VApp deployed="false" href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000" id="urn:vcloud:vapp:00000000-0000-0000-0000-000000000000" name="myVApp" ovfDescriptorUploaded="true" status="0" type="application/vnd.vmware.vcloud.vApp+xml" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Link href="http://localhost:4444/api/network/f869430c-7490-4d32-bf34-4208b6059c21" name="M916272752-5793-default-routed" rel="down" type="application/vnd.vmware.vcloud.vAppNetwork+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/controlAccess/" rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/vdc/214cd6b2-3f7a-4ee5-9b0a-52b4001a4a84" rel="up" type="application/vnd.vmware.vcloud.vdc+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/owner" rel="down" type="application/vnd.vmware.vcloud.owner+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/metadata" rel="down" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/ovf" rel="ovf" type="text/xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/productSections/" rel="down" type="application/vnd.vmware.vcloud.productSections+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/00000000-0000-0000-0000-000000000000/backups" rel="add" type="application/vnd.emc.vcp.adhocBackupParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/00000000-0000-0000-0000-000000000000/backups" rel="add" type="application/vnd.emc.vcp.adhocBackupParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/metrics/historic" rel="advancedmetrics" type="application/vnd.vmware.vcloud.metrics.historicUsageList+xml"/>
|
||||
<Description>My vApp to be deployed</Description>
|
||||
<Tasks>
|
||||
<Task cancelRequested="false" expiryTime="2015-01-22T15:26:59.824Z" href="http://localhost:4444/api/task/b3ff4b8c-9292-41a5-8dc8-22aba49bb02d" id="urn:vcloud:task:b3ff4b8c-9292-41a5-8dc8-22aba49bb02d" name="task" operation="Creating Virtual Application My vApp 2(00000000-0000-0000-0000-000000000000)" operationName="vdcInstantiateVapp" serviceNamespace="com.vmware.vcloud" startTime="2014-10-24T15:26:59.824Z" status="running" type="application/vnd.vmware.vcloud.task+xml">
|
||||
<Link href="http://localhost:4444/api/task/b3ff4b8c-9292-41a5-8dc8-22aba49bb02d/action/cancel" rel="task:cancel"/>
|
||||
<Owner href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000" name="My vApp 2" type="application/vnd.vmware.vcloud.vApp+xml"/>
|
||||
<User href="http://localhost:4444/api/admin/user/d8ac278a-5b49-4c85-9a81-468838e89eb9" name="frapposelli1@gts-vchs.com" type="application/vnd.vmware.admin.user+xml"/>
|
||||
<Organization href="http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57" name="M916272752-5793" type="application/vnd.vmware.vcloud.org+xml"/>
|
||||
<Progress>1</Progress>
|
||||
<Details/>
|
||||
</Task>
|
||||
</Tasks>
|
||||
<DateCreated>2014-10-24T15:26:59.067Z</DateCreated>
|
||||
<Owner type="application/vnd.vmware.vcloud.owner+xml">
|
||||
<User href="http://localhost:4444/api/admin/user/d8ac278a-5b49-4c85-9a81-468838e89eb9" name="frapposelli1@gts-vchs.com" type="application/vnd.vmware.admin.user+xml"/>
|
||||
</Owner>
|
||||
<InMaintenanceMode>false</InMaintenanceMode>
|
||||
</VApp>
|
||||
`
|
||||
|
||||
var vappExample = `
|
||||
<?xml version="1.0" ?>
|
||||
<VApp deployed="false" href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000" id="urn:vcloud:vapp:00000000-0000-0000-0000-000000000000" name="Test API GO4" ovfDescriptorUploaded="true" status="8" type="application/vnd.vmware.vcloud.vApp+xml" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vmw="http://www.vmware.com/schema/ovf" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_VirtualSystemSettingData.xsd http://www.vmware.com/schema/ovf http://www.vmware.com/schema/ovf http://schemas.dmtf.org/ovf/envelope/1http://schemas.dmtf.org/ovf/envelope/1/dsp8023_1.1.0.xsd http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_ResourceAllocationSettingData.xsd">
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/power/action/powerOn" rel="power:powerOn"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/action/deploy" rel="deploy" type="application/vnd.vmware.vcloud.deployVAppParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/network/e68434e9-a9ae-47d8-b809-743e70307085" name="M916272752-5793-default-isolated" rel="down" type="application/vnd.vmware.vcloud.vAppNetwork+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/controlAccess/" rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/action/controlAccess" rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/action/recomposeVApp" rel="recompose" type="application/vnd.vmware.vcloud.recomposeVAppParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vdc/214cd6b2-3f7a-4ee5-9b0a-52b4001a4a84" rel="up" type="application/vnd.vmware.vcloud.vdc+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000" rel="edit" type="application/vnd.vmware.vcloud.vApp+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000" rel="remove"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/action/enableDownload" rel="enable"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/action/disableDownload" rel="disable"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/owner" rel="down" type="application/vnd.vmware.vcloud.owner+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/metadata" rel="down" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/ovf" rel="ovf" type="text/xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/productSections/" rel="down" type="application/vnd.vmware.vcloud.productSections+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/action/createSnapshot" rel="snapshot:create" type="application/vnd.vmware.vcloud.createSnapshotParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/00000000-0000-0000-0000-000000000000/backups" rel="add" type="application/vnd.emc.vcp.adhocBackupParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/00000000-0000-0000-0000-000000000000/backups" rel="add" type="application/vnd.emc.vcp.adhocBackupParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/metrics/historic" rel="advancedmetrics" type="application/vnd.vmware.vcloud.metrics.historicUsageList+xml"/>
|
||||
<Description>Test API GO4444!</Description>
|
||||
<LeaseSettingsSection href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/leaseSettingsSection/" ovf:required="false" type="application/vnd.vmware.vcloud.leaseSettingsSection+xml">
|
||||
<ovf:Info>Lease settings section</ovf:Info>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/leaseSettingsSection/" rel="edit" type="application/vnd.vmware.vcloud.leaseSettingsSection+xml"/>
|
||||
<DeploymentLeaseInSeconds>0</DeploymentLeaseInSeconds>
|
||||
<StorageLeaseInSeconds>0</StorageLeaseInSeconds>
|
||||
</LeaseSettingsSection>
|
||||
<ovf:StartupSection vcloud:href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/startupSection/" vcloud:type="application/vnd.vmware.vcloud.startupSection+xml" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
|
||||
<ovf:Info>VApp startup section</ovf:Info>
|
||||
<ovf:Item ovf:id="CentOS64-32bit" ovf:order="0" ovf:startAction="powerOn" ovf:startDelay="0" ovf:stopAction="powerOff" ovf:stopDelay="0"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/startupSection/" rel="edit" type="application/vnd.vmware.vcloud.startupSection+xml"/>
|
||||
</ovf:StartupSection>
|
||||
<ovf:NetworkSection vcloud:href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/networkSection/" vcloud:type="application/vnd.vmware.vcloud.networkSection+xml" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
|
||||
<ovf:Info>The list of logical networks</ovf:Info>
|
||||
<ovf:Network ovf:name="M916272752-5793-default-isolated">
|
||||
<ovf:Description>This isolated network was created with Create VDC.</ovf:Description>
|
||||
</ovf:Network>
|
||||
<ovf:Network ovf:name="none">
|
||||
<ovf:Description>This is a special place-holder used for disconnected network interfaces.</ovf:Description>
|
||||
</ovf:Network>
|
||||
</ovf:NetworkSection>
|
||||
<NetworkConfigSection href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/networkConfigSection/" ovf:required="false" type="application/vnd.vmware.vcloud.networkConfigSection+xml">
|
||||
<ovf:Info>The configuration parameters for logical networks</ovf:Info>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/networkConfigSection/" rel="edit" type="application/vnd.vmware.vcloud.networkConfigSection+xml"/>
|
||||
<NetworkConfig networkName="M916272752-5793-default-isolated">
|
||||
<Link href="http://localhost:4444/api/admin/network/e68434e9-a9ae-47d8-b809-743e70307085/action/reset" rel="repair"/>
|
||||
<Description>This isolated network was created with Create VDC.</Description>
|
||||
<Configuration>
|
||||
<IpScopes>
|
||||
<IpScope>
|
||||
<IsInherited>true</IsInherited>
|
||||
<Gateway>192.168.99.1</Gateway>
|
||||
<Netmask>255.255.255.0</Netmask>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<IpRanges>
|
||||
<IpRange>
|
||||
<StartAddress>192.168.99.2</StartAddress>
|
||||
<EndAddress>192.168.99.100</EndAddress>
|
||||
</IpRange>
|
||||
</IpRanges>
|
||||
</IpScope>
|
||||
</IpScopes>
|
||||
<ParentNetwork href="http://localhost:4444/api/admin/network/8d0cbfe2-25b3-4a1f-b608-5ffeabc7a53d" id="8d0cbfe2-25b3-4a1f-b608-5ffeabc7a53d" name="M916272752-5793-default-isolated"/>
|
||||
<FenceMode>bridged</FenceMode>
|
||||
<RetainNetInfoAcrossDeployments>false</RetainNetInfoAcrossDeployments>
|
||||
</Configuration>
|
||||
<IsDeployed>false</IsDeployed>
|
||||
</NetworkConfig>
|
||||
<NetworkConfig networkName="none">
|
||||
<Description>This is a special place-holder used for disconnected network interfaces.</Description>
|
||||
<Configuration>
|
||||
<IpScopes>
|
||||
<IpScope>
|
||||
<IsInherited>false</IsInherited>
|
||||
<Gateway>196.254.254.254</Gateway>
|
||||
<Netmask>255.255.0.0</Netmask>
|
||||
<Dns1>196.254.254.254</Dns1>
|
||||
</IpScope>
|
||||
</IpScopes>
|
||||
<FenceMode>isolated</FenceMode>
|
||||
</Configuration>
|
||||
<IsDeployed>false</IsDeployed>
|
||||
</NetworkConfig>
|
||||
</NetworkConfigSection>
|
||||
<SnapshotSection href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000/snapshotSection" ovf:required="false" type="application/vnd.vmware.vcloud.snapshotSection+xml">
|
||||
<ovf:Info>Snapshot information section</ovf:Info>
|
||||
</SnapshotSection>
|
||||
<DateCreated>2014-11-06T22:24:43.913Z</DateCreated>
|
||||
<Owner type="application/vnd.vmware.vcloud.owner+xml">
|
||||
<User href="http://localhost:4444/api/admin/user/d8ac278a-5b49-4c85-9a81-468838e89eb9" name="frapposelli1@gts-vchs.com" type="application/vnd.vmware.admin.user+xml"/>
|
||||
</Owner>
|
||||
<InMaintenanceMode>false</InMaintenanceMode>
|
||||
<Children>
|
||||
<Vm deployed="false" href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000" id="urn:vcloud:vm:00000000-0000-0000-0000-000000000000" name="CentOS64-32bit" needsCustomization="true" nestedHypervisorEnabled="false" status="8" type="application/vnd.vmware.vcloud.vm+xml">
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/power/action/powerOn" rel="power:powerOn"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/action/deploy" rel="deploy" type="application/vnd.vmware.vcloud.deployVAppParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000" rel="edit" type="application/vnd.vmware.vcloud.vm+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000" rel="remove"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/metadata" rel="down" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/productSections/" rel="down" type="application/vnd.vmware.vcloud.productSections+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/metrics/historic" rel="down" type="application/vnd.vmware.vcloud.metrics.historicUsageSpec+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/metrics/historic" rel="metrics" type="application/vnd.vmware.vcloud.metrics.historicUsageSpec+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/screen" rel="screen:thumbnail"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/media/action/insertMedia" rel="media:insertMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/media/action/ejectMedia" rel="media:ejectMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/disk/action/attach" rel="disk:attach" type="application/vnd.vmware.vcloud.diskAttachOrDetachParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/disk/action/detach" rel="disk:detach" type="application/vnd.vmware.vcloud.diskAttachOrDetachParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/action/upgradeHardwareVersion" rel="upgrade"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/action/enableNestedHypervisor" rel="enable"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/action/customizeAtNextPowerOn" rel="customizeAtNextPowerOn"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/action/createSnapshot" rel="snapshot:create" type="application/vnd.vmware.vcloud.createSnapshotParams+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/action/reconfigureVm" name="CentOS64-32bit" rel="reconfigureVm" type="application/vnd.vmware.vcloud.vm+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000" rel="up" type="application/vnd.vmware.vcloud.vApp+xml"/>
|
||||
<Description>id: cts-6.4-32bit</Description>
|
||||
<ovf:VirtualHardwareSection ovf:transport="" vcloud:href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/" vcloud:type="application/vnd.vmware.vcloud.virtualHardwareSection+xml" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
|
||||
<ovf:Info>Virtual hardware requirements</ovf:Info>
|
||||
<ovf:System>
|
||||
<vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
|
||||
<vssd:InstanceID>0</vssd:InstanceID>
|
||||
<vssd:VirtualSystemIdentifier>CentOS64-32bit</vssd:VirtualSystemIdentifier>
|
||||
<vssd:VirtualSystemType>vmx-09</vssd:VirtualSystemType>
|
||||
</ovf:System>
|
||||
<ovf:Item>
|
||||
<rasd:Address>00:50:56:02:0b:36</rasd:Address>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:Connection vcloud:ipAddressingMode="NONE" vcloud:primaryNetworkConnection="true">none</rasd:Connection>
|
||||
<rasd:Description>E1000 ethernet adapter on "none"</rasd:Description>
|
||||
<rasd:ElementName>Network adapter 0</rasd:ElementName>
|
||||
<rasd:InstanceID>1</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>E1000</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>10</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:Address>0</rasd:Address>
|
||||
<rasd:Description>SCSI Controller</rasd:Description>
|
||||
<rasd:ElementName>SCSI Controller 0</rasd:ElementName>
|
||||
<rasd:InstanceID>2</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>6</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:Description>Hard disk</rasd:Description>
|
||||
<rasd:ElementName>Hard disk 1</rasd:ElementName>
|
||||
<rasd:HostResource vcloud:busSubType="lsilogic" vcloud:busType="6" vcloud:capacity="20480" vcloud:storageProfileHref="http://localhost:4444/api/vdcStorageProfile/816409e1-6207-4a1f-bd45-947cd03d6452" vcloud:storageProfileOverrideVmDefault="false"/>
|
||||
<rasd:InstanceID>2000</rasd:InstanceID>
|
||||
<rasd:Parent>2</rasd:Parent>
|
||||
<rasd:ResourceType>17</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:Address>1</rasd:Address>
|
||||
<rasd:Description>IDE Controller</rasd:Description>
|
||||
<rasd:ElementName>IDE Controller 1</rasd:ElementName>
|
||||
<rasd:InstanceID>3</rasd:InstanceID>
|
||||
<rasd:ResourceType>5</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:Description>CD/DVD Drive</rasd:Description>
|
||||
<rasd:ElementName>CD/DVD Drive 1</rasd:ElementName>
|
||||
<rasd:HostResource/>
|
||||
<rasd:InstanceID>3002</rasd:InstanceID>
|
||||
<rasd:Parent>3</rasd:Parent>
|
||||
<rasd:ResourceType>15</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:Description>Floppy Drive</rasd:Description>
|
||||
<rasd:ElementName>Floppy Drive 1</rasd:ElementName>
|
||||
<rasd:HostResource/>
|
||||
<rasd:InstanceID>8000</rasd:InstanceID>
|
||||
<rasd:ResourceType>14</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item vcloud:href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/cpu" vcloud:type="application/vnd.vmware.vcloud.rasdItem+xml">
|
||||
<rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
|
||||
<rasd:Description>Number of Virtual CPUs</rasd:Description>
|
||||
<rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>
|
||||
<rasd:InstanceID>4</rasd:InstanceID>
|
||||
<rasd:Reservation>0</rasd:Reservation>
|
||||
<rasd:ResourceType>3</rasd:ResourceType>
|
||||
<rasd:VirtualQuantity>1</rasd:VirtualQuantity>
|
||||
<rasd:Weight>0</rasd:Weight>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/cpu" rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml"/>
|
||||
</ovf:Item>
|
||||
<ovf:Item vcloud:href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/memory" vcloud:type="application/vnd.vmware.vcloud.rasdItem+xml">
|
||||
<rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
|
||||
<rasd:Description>Memory Size</rasd:Description>
|
||||
<rasd:ElementName>1024 MB of memory</rasd:ElementName>
|
||||
<rasd:InstanceID>5</rasd:InstanceID>
|
||||
<rasd:Reservation>0</rasd:Reservation>
|
||||
<rasd:ResourceType>4</rasd:ResourceType>
|
||||
<rasd:VirtualQuantity>1024</rasd:VirtualQuantity>
|
||||
<rasd:Weight>0</rasd:Weight>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/memory" rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml"/>
|
||||
</ovf:Item>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/" rel="edit" type="application/vnd.vmware.vcloud.virtualHardwareSection+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/cpu" rel="down" type="application/vnd.vmware.vcloud.rasdItem+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/cpu" rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/memory" rel="down" type="application/vnd.vmware.vcloud.rasdItem+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/memory" rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/disks" rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/disks" rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/media" rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/networkCards" rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/networkCards" rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/serialPorts" rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/serialPorts" rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
</ovf:VirtualHardwareSection>
|
||||
<ovf:OperatingSystemSection ovf:id="36" vcloud:href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/operatingSystemSection/" vcloud:type="application/vnd.vmware.vcloud.operatingSystemSection+xml" vmw:osType="centosGuest" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
|
||||
<ovf:Info>Specifies the operating system installed</ovf:Info>
|
||||
<ovf:Description>CentOS 4/5/6 (32-bit)</ovf:Description>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/operatingSystemSection/" rel="edit" type="application/vnd.vmware.vcloud.operatingSystemSection+xml"/>
|
||||
</ovf:OperatingSystemSection>
|
||||
<NetworkConnectionSection href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/networkConnectionSection/" ovf:required="false" type="application/vnd.vmware.vcloud.networkConnectionSection+xml">
|
||||
<ovf:Info>Specifies the available VM network connections</ovf:Info>
|
||||
<PrimaryNetworkConnectionIndex>0</PrimaryNetworkConnectionIndex>
|
||||
<NetworkConnection needsCustomization="true" network="none">
|
||||
<NetworkConnectionIndex>0</NetworkConnectionIndex>
|
||||
<IsConnected>false</IsConnected>
|
||||
<MACAddress>00:50:56:02:0b:36</MACAddress>
|
||||
<IpAddressAllocationMode>NONE</IpAddressAllocationMode>
|
||||
</NetworkConnection>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/networkConnectionSection/" rel="edit" type="application/vnd.vmware.vcloud.networkConnectionSection+xml"/>
|
||||
</NetworkConnectionSection>
|
||||
<GuestCustomizationSection href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/guestCustomizationSection/" ovf:required="false" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml">
|
||||
<ovf:Info>Specifies Guest OS Customization Settings</ovf:Info>
|
||||
<Enabled>true</Enabled>
|
||||
<ChangeSid>false</ChangeSid>
|
||||
<VirtualMachineId>00000000-0000-0000-0000-000000000000</VirtualMachineId>
|
||||
<JoinDomainEnabled>false</JoinDomainEnabled>
|
||||
<UseOrgSettings>false</UseOrgSettings>
|
||||
<AdminPasswordEnabled>true</AdminPasswordEnabled>
|
||||
<AdminPasswordAuto>true</AdminPasswordAuto>
|
||||
<AdminAutoLogonEnabled>false</AdminAutoLogonEnabled>
|
||||
<AdminAutoLogonCount>0</AdminAutoLogonCount>
|
||||
<ResetPasswordRequired>true</ResetPasswordRequired>
|
||||
<ComputerName>cts-6.4-32bit</ComputerName>
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/guestCustomizationSection/" rel="edit" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml"/>
|
||||
</GuestCustomizationSection>
|
||||
<RuntimeInfoSection vcloud:href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/runtimeInfoSection" vcloud:type="application/vnd.vmware.vcloud.virtualHardwareSection+xml" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
|
||||
<ovf:Info>Specifies Runtime info</ovf:Info>
|
||||
<VMWareTools version="9283"/>
|
||||
</RuntimeInfoSection>
|
||||
<SnapshotSection href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/snapshotSection" ovf:required="false" type="application/vnd.vmware.vcloud.snapshotSection+xml">
|
||||
<ovf:Info>Snapshot information section</ovf:Info>
|
||||
</SnapshotSection>
|
||||
<VAppScopedLocalId>CentOS64-32bit</VAppScopedLocalId>
|
||||
<VmCapabilities href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/vmCapabilities/" type="application/vnd.vmware.vcloud.vmCapabilitiesSection+xml">
|
||||
<Link href="http://localhost:4444/api/vApp/vm-00000000-0000-0000-0000-000000000000/vmCapabilities/" rel="edit" type="application/vnd.vmware.vcloud.vmCapabilitiesSection+xml"/>
|
||||
<MemoryHotAddEnabled>false</MemoryHotAddEnabled>
|
||||
<CpuHotAddEnabled>false</CpuHotAddEnabled>
|
||||
</VmCapabilities>
|
||||
<StorageProfile href="http://localhost:4444/api/vdcStorageProfile/816409e1-6207-4a1f-bd45-947cd03d6452" name="SSD-Accelerated" type="application/vnd.vmware.vcloud.vdcStorageProfile+xml"/>
|
||||
</Vm>
|
||||
</Children>
|
||||
</VApp>
|
||||
`
|
||||
21
Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate.go
generated
vendored
Normal file
21
Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type VAppTemplate struct {
|
||||
VAppTemplate *types.VAppTemplate
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewVAppTemplate(c *Client) *VAppTemplate {
|
||||
return &VAppTemplate{
|
||||
VAppTemplate: new(types.VAppTemplate),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
183
Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate_test.go
generated
vendored
Normal file
183
Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate_test.go
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
var vapptemplateExample = `
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<VAppTemplate xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vmw="http://www.vmware.com/schema/ovf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" goldMaster="false" ovfDescriptorUploaded="true" status="8" name="CentOS64-32bit" id="urn:vcloud:vapptemplate:40cb9721-5f1a-44f9-b5c3-98c5f518c4f5" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5" type="application/vnd.vmware.vcloud.vAppTemplate+xml" xsi:schemaLocation="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_VirtualSystemSettingData.xsd http://www.vmware.com/schema/ovf http://www.vmware.com/schema/ovf http://schemas.dmtf.org/ovf/envelope/1 http://schemas.dmtf.org/ovf/envelope/1/dsp8023_1.1.0.xsd http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_ResourceAllocationSettingData.xsd">
|
||||
<Link rel="catalogItem" href="http://localhost:4444/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae" type="application/vnd.vmware.vcloud.catalogItem+xml"/>
|
||||
<Link rel="enable" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/action/enableDownload"/>
|
||||
<Link rel="disable" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/action/disableDownload"/>
|
||||
<Link rel="ovf" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/ovf" type="text/xml"/>
|
||||
<Link rel="storageProfile" href="http://localhost:4444/api/vdcStorageProfile/9ae2c9f2-d711-4de9-a108-e4c064c33b60" name="SSD-Accelerated" type="application/vnd.vmware.vcloud.vdcStorageProfile+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/owner" type="application/vnd.vmware.vcloud.owner+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/metadata" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/productSections/" type="application/vnd.vmware.vcloud.productSections+xml"/>
|
||||
<Description>id: cts-6.4-32bit</Description>
|
||||
<Owner type="application/vnd.vmware.vcloud.owner+xml">
|
||||
<User href="http://localhost:4444/api/admin/user/db5e3e0c-61ac-4e1e-93f3-d6096dde2517" name="system" type="application/vnd.vmware.admin.user+xml"/>
|
||||
</Owner>
|
||||
<Children>
|
||||
<Vm goldMaster="false" status="8" name="CentOS64-32bit" id="urn:vcloud:vm:3a3934d2-1f3f-4782-a911-f143da27e88c" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c" type="application/vnd.vmware.vcloud.vm+xml">
|
||||
<Link rel="up" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5" type="application/vnd.vmware.vcloud.vAppTemplate+xml"/>
|
||||
<Link rel="storageProfile" href="http://localhost:4444/api/vdcStorageProfile/9ae2c9f2-d711-4de9-a108-e4c064c33b60" type="application/vnd.vmware.vcloud.vdcStorageProfile+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/metadata" type="application/vnd.vmware.vcloud.metadata+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/productSections/" type="application/vnd.vmware.vcloud.productSections+xml"/>
|
||||
<Description>id: cts-6.4-32bit</Description>
|
||||
<NetworkConnectionSection href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/networkConnectionSection/" type="application/vnd.vmware.vcloud.networkConnectionSection+xml" ovf:required="false">
|
||||
<ovf:Info>Specifies the available VM network connections</ovf:Info>
|
||||
<PrimaryNetworkConnectionIndex>0</PrimaryNetworkConnectionIndex>
|
||||
<NetworkConnection needsCustomization="true" network="none">
|
||||
<NetworkConnectionIndex>0</NetworkConnectionIndex>
|
||||
<IsConnected>false</IsConnected>
|
||||
<MACAddress>00:50:56:02:00:39</MACAddress>
|
||||
<IpAddressAllocationMode>NONE</IpAddressAllocationMode>
|
||||
</NetworkConnection>
|
||||
</NetworkConnectionSection>
|
||||
<GuestCustomizationSection href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/guestCustomizationSection/" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" ovf:required="false">
|
||||
<ovf:Info>Specifies Guest OS Customization Settings</ovf:Info>
|
||||
<Enabled>true</Enabled>
|
||||
<ChangeSid>false</ChangeSid>
|
||||
<VirtualMachineId>3a3934d2-1f3f-4782-a911-f143da27e88c</VirtualMachineId>
|
||||
<JoinDomainEnabled>false</JoinDomainEnabled>
|
||||
<UseOrgSettings>false</UseOrgSettings>
|
||||
<AdminPasswordEnabled>true</AdminPasswordEnabled>
|
||||
<AdminPasswordAuto>true</AdminPasswordAuto>
|
||||
<AdminAutoLogonEnabled>false</AdminAutoLogonEnabled>
|
||||
<AdminAutoLogonCount>0</AdminAutoLogonCount>
|
||||
<ResetPasswordRequired>true</ResetPasswordRequired>
|
||||
<ComputerName>cts-6.4-32bit</ComputerName>
|
||||
</GuestCustomizationSection>
|
||||
<ovf:VirtualHardwareSection xmlns:vcloud="http://www.vmware.com/vcloud/v1.5" ovf:transport="" vcloud:href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/virtualHardwareSection/" vcloud:type="application/vnd.vmware.vcloud.virtualHardwareSection+xml">
|
||||
<ovf:Info>Virtual hardware requirements</ovf:Info>
|
||||
<ovf:System>
|
||||
<vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
|
||||
<vssd:InstanceID>0</vssd:InstanceID>
|
||||
<vssd:VirtualSystemIdentifier>CentOS64-32bit</vssd:VirtualSystemIdentifier>
|
||||
<vssd:VirtualSystemType>vmx-09</vssd:VirtualSystemType>
|
||||
</ovf:System>
|
||||
<ovf:Item>
|
||||
<rasd:Address>00:50:56:02:00:39</rasd:Address>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:Connection vcloud:primaryNetworkConnection="true" vcloud:ipAddressingMode="NONE">none</rasd:Connection>
|
||||
<rasd:Description>E1000 ethernet adapter on "none"</rasd:Description>
|
||||
<rasd:ElementName>Network adapter 0</rasd:ElementName>
|
||||
<rasd:InstanceID>1</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>E1000</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>10</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:Address>0</rasd:Address>
|
||||
<rasd:Description>SCSI Controller</rasd:Description>
|
||||
<rasd:ElementName>SCSI Controller 0</rasd:ElementName>
|
||||
<rasd:InstanceID>2</rasd:InstanceID>
|
||||
<rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>
|
||||
<rasd:ResourceType>6</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:Description>Hard disk</rasd:Description>
|
||||
<rasd:ElementName>Hard disk 1</rasd:ElementName>
|
||||
<rasd:HostResource vcloud:capacity="20480" vcloud:storageProfileOverrideVmDefault="false" vcloud:busSubType="lsilogic" vcloud:storageProfileHref="http://localhost:4444/api/vdcStorageProfile/9ae2c9f2-d711-4de9-a108-e4c064c33b60" vcloud:busType="6"/>
|
||||
<rasd:InstanceID>2000</rasd:InstanceID>
|
||||
<rasd:Parent>2</rasd:Parent>
|
||||
<rasd:ResourceType>17</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:Address>1</rasd:Address>
|
||||
<rasd:Description>IDE Controller</rasd:Description>
|
||||
<rasd:ElementName>IDE Controller 1</rasd:ElementName>
|
||||
<rasd:InstanceID>3</rasd:InstanceID>
|
||||
<rasd:ResourceType>5</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:Description>CD/DVD Drive</rasd:Description>
|
||||
<rasd:ElementName>CD/DVD Drive 1</rasd:ElementName>
|
||||
<rasd:HostResource/>
|
||||
<rasd:InstanceID>3002</rasd:InstanceID>
|
||||
<rasd:Parent>3</rasd:Parent>
|
||||
<rasd:ResourceType>15</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:AddressOnParent>0</rasd:AddressOnParent>
|
||||
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
|
||||
<rasd:Description>Floppy Drive</rasd:Description>
|
||||
<rasd:ElementName>Floppy Drive 1</rasd:ElementName>
|
||||
<rasd:HostResource/>
|
||||
<rasd:InstanceID>8000</rasd:InstanceID>
|
||||
<rasd:ResourceType>14</rasd:ResourceType>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
|
||||
<rasd:Description>Number of Virtual CPUs</rasd:Description>
|
||||
<rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>
|
||||
<rasd:InstanceID>4</rasd:InstanceID>
|
||||
<rasd:Reservation>0</rasd:Reservation>
|
||||
<rasd:ResourceType>3</rasd:ResourceType>
|
||||
<rasd:VirtualQuantity>1</rasd:VirtualQuantity>
|
||||
<rasd:Weight>0</rasd:Weight>
|
||||
<vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
|
||||
</ovf:Item>
|
||||
<ovf:Item>
|
||||
<rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
|
||||
<rasd:Description>Memory Size</rasd:Description>
|
||||
<rasd:ElementName>1024 MB of memory</rasd:ElementName>
|
||||
<rasd:InstanceID>5</rasd:InstanceID>
|
||||
<rasd:Reservation>0</rasd:Reservation>
|
||||
<rasd:ResourceType>4</rasd:ResourceType>
|
||||
<rasd:VirtualQuantity>1024</rasd:VirtualQuantity>
|
||||
<rasd:Weight>0</rasd:Weight>
|
||||
</ovf:Item>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/virtualHardwareSection/cpu" type="application/vnd.vmware.vcloud.rasdItem+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/virtualHardwareSection/memory" type="application/vnd.vmware.vcloud.rasdItem+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/virtualHardwareSection/disks" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/virtualHardwareSection/media" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/virtualHardwareSection/networkCards" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
<Link rel="down" href="http://localhost:4444/api/vAppTemplate/vm-3a3934d2-1f3f-4782-a911-f143da27e88c/virtualHardwareSection/serialPorts" type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
|
||||
</ovf:VirtualHardwareSection>
|
||||
<VAppScopedLocalId>CentOS64-32bit</VAppScopedLocalId>
|
||||
<DateCreated>2014-06-04T21:06:43.547Z</DateCreated>
|
||||
</Vm>
|
||||
</Children>
|
||||
<ovf:NetworkSection xmlns:vcloud="http://www.vmware.com/vcloud/v1.5" vcloud:href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/networkSection/" vcloud:type="application/vnd.vmware.vcloud.networkSection+xml">
|
||||
<ovf:Info>The list of logical networks</ovf:Info>
|
||||
<ovf:Network ovf:name="none">
|
||||
<ovf:Description>This is a special place-holder used for disconnected network interfaces.</ovf:Description>
|
||||
</ovf:Network>
|
||||
</ovf:NetworkSection>
|
||||
<NetworkConfigSection href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/networkConfigSection/" type="application/vnd.vmware.vcloud.networkConfigSection+xml" ovf:required="false">
|
||||
<ovf:Info>The configuration parameters for logical networks</ovf:Info>
|
||||
<NetworkConfig networkName="none">
|
||||
<Description>This is a special place-holder used for disconnected network interfaces.</Description>
|
||||
<Configuration>
|
||||
<IpScopes>
|
||||
<IpScope>
|
||||
<IsInherited>false</IsInherited>
|
||||
<Gateway>196.254.254.254</Gateway>
|
||||
<Netmask>255.255.0.0</Netmask>
|
||||
<Dns1>196.254.254.254</Dns1>
|
||||
</IpScope>
|
||||
</IpScopes>
|
||||
<FenceMode>isolated</FenceMode>
|
||||
</Configuration>
|
||||
<IsDeployed>false</IsDeployed>
|
||||
</NetworkConfig>
|
||||
</NetworkConfigSection>
|
||||
<LeaseSettingsSection href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/leaseSettingsSection/" type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" ovf:required="false">
|
||||
<ovf:Info>Lease settings section</ovf:Info>
|
||||
<Link rel="edit" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/leaseSettingsSection/" type="application/vnd.vmware.vcloud.leaseSettingsSection+xml"/>
|
||||
<StorageLeaseInSeconds>0</StorageLeaseInSeconds>
|
||||
</LeaseSettingsSection>
|
||||
<CustomizationSection goldMaster="false" href="http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5/customizationSection/" type="application/vnd.vmware.vcloud.customizationSection+xml" ovf:required="false">
|
||||
<ovf:Info>VApp template customization section</ovf:Info>
|
||||
<CustomizeOnInstantiate>true</CustomizeOnInstantiate>
|
||||
</CustomizationSection>
|
||||
<DateCreated>2014-06-04T21:06:43.547Z</DateCreated>
|
||||
</VAppTemplate>
|
||||
|
||||
`
|
||||
277
Godeps/_workspace/src/github.com/vmware/govcloudair/vdc.go
generated
vendored
Normal file
277
Godeps/_workspace/src/github.com/vmware/govcloudair/vdc.go
generated
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
types "github.com/vmware/govcloudair/types/v56"
|
||||
)
|
||||
|
||||
type Vdc struct {
|
||||
Vdc *types.Vdc
|
||||
c *Client
|
||||
}
|
||||
|
||||
func NewVdc(c *Client) *Vdc {
|
||||
return &Vdc{
|
||||
Vdc: new(types.Vdc),
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) retrieveVDC() (Vdc, error) {
|
||||
|
||||
req := c.NewRequest(map[string]string{}, "GET", c.VCDVDCHREF, nil)
|
||||
|
||||
resp, err := checkResp(c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Vdc{}, fmt.Errorf("error retreiving vdc: %s", err)
|
||||
}
|
||||
|
||||
vdc := NewVdc(c)
|
||||
|
||||
if err = decodeBody(resp, vdc.Vdc); err != nil {
|
||||
return Vdc{}, fmt.Errorf("error decoding vdc response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *vdc, nil
|
||||
}
|
||||
|
||||
func (v *Vdc) Refresh() error {
|
||||
|
||||
if v.Vdc.HREF == "" {
|
||||
return fmt.Errorf("cannot refresh, Object is empty")
|
||||
}
|
||||
|
||||
u, _ := url.ParseRequestURI(v.Vdc.HREF)
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retreiving Edge Gateway: %s", err)
|
||||
}
|
||||
|
||||
// Empty struct before a new unmarshal, otherwise we end up with duplicate
|
||||
// elements in slices.
|
||||
v.Vdc = &types.Vdc{}
|
||||
|
||||
if err = decodeBody(resp, v.Vdc); err != nil {
|
||||
return fmt.Errorf("error decoding Edge Gateway response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Vdc) FindVDCNetwork(network string) (OrgVDCNetwork, error) {
|
||||
|
||||
for _, an := range v.Vdc.AvailableNetworks {
|
||||
for _, n := range an.Network {
|
||||
if n.Name == network {
|
||||
u, err := url.ParseRequestURI(n.HREF)
|
||||
if err != nil {
|
||||
return OrgVDCNetwork{}, fmt.Errorf("error decoding vdc response: %s", err)
|
||||
}
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return OrgVDCNetwork{}, fmt.Errorf("error retreiving orgvdcnetwork: %s", err)
|
||||
}
|
||||
|
||||
orgnet := NewOrgVDCNetwork(v.c)
|
||||
|
||||
if err = decodeBody(resp, orgnet.OrgVDCNetwork); err != nil {
|
||||
return OrgVDCNetwork{}, fmt.Errorf("error decoding orgvdcnetwork response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *orgnet, nil
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OrgVDCNetwork{}, fmt.Errorf("can't find VDC Network: %s", network)
|
||||
}
|
||||
|
||||
func (v *Vdc) GetVDCOrg() (Org, error) {
|
||||
|
||||
for _, av := range v.Vdc.Link {
|
||||
if av.Rel == "up" && av.Type == "application/vnd.vmware.vcloud.org+xml" {
|
||||
u, err := url.ParseRequestURI(av.HREF)
|
||||
|
||||
if err != nil {
|
||||
return Org{}, fmt.Errorf("error decoding vdc response: %s", err)
|
||||
}
|
||||
|
||||
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return Org{}, fmt.Errorf("error retreiving org: %s", err)
|
||||
}
|
||||
|
||||
org := NewOrg(v.c)
|
||||
|
||||
if err = decodeBody(resp, org.Org); err != nil {
|
||||
return Org{}, fmt.Errorf("error decoding org response: %s", err)
|
||||
}
|
||||
|
||||
// The request was successful
|
||||
return *org, nil
|
||||
|
||||
}
|
||||
}
|
||||
return Org{}, fmt.Errorf("can't find VDC Org")
|
||||
}
|
||||
|
||||
func (v *Vdc) FindEdgeGateway(edgegateway string) (EdgeGateway, error) {
|
||||
|
||||
for _, av := range v.Vdc.Link {
|
||||
if av.Rel == "edgeGateways" && av.Type == "application/vnd.vmware.vcloud.query.records+xml" {
|
||||
u, err := url.ParseRequestURI(av.HREF)
|
||||
|
||||
if err != nil {
|
||||
return EdgeGateway{}, fmt.Errorf("error decoding vdc response: %s", err)
|
||||
}
|
||||
|
||||
// Querying the Result list
|
||||
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return EdgeGateway{}, fmt.Errorf("error retrieving edge gateway records: %s", err)
|
||||
}
|
||||
|
||||
query := new(types.QueryResultEdgeGatewayRecordsType)
|
||||
|
||||
if err = decodeBody(resp, query); err != nil {
|
||||
return EdgeGateway{}, fmt.Errorf("error decoding edge gateway query response: %s", err)
|
||||
}
|
||||
|
||||
u, err = url.ParseRequestURI(query.EdgeGatewayRecord.HREF)
|
||||
if err != nil {
|
||||
return EdgeGateway{}, fmt.Errorf("error decoding edge gateway query response: %s", err)
|
||||
}
|
||||
|
||||
// Querying the Result list
|
||||
req = v.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err = checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return EdgeGateway{}, fmt.Errorf("error retrieving edge gateway: %s", err)
|
||||
}
|
||||
|
||||
edge := NewEdgeGateway(v.c)
|
||||
|
||||
if err = decodeBody(resp, edge.EdgeGateway); err != nil {
|
||||
return EdgeGateway{}, fmt.Errorf("error decoding edge gateway response: %s", err)
|
||||
}
|
||||
|
||||
return *edge, nil
|
||||
|
||||
}
|
||||
}
|
||||
return EdgeGateway{}, fmt.Errorf("can't find Edge Gateway")
|
||||
|
||||
}
|
||||
|
||||
func (v *Vdc) FindVAppByName(vapp string) (VApp, error) {
|
||||
|
||||
err := v.Refresh()
|
||||
if err != nil {
|
||||
return VApp{}, fmt.Errorf("error refreshing vdc: %s", err)
|
||||
}
|
||||
|
||||
for _, resents := range v.Vdc.ResourceEntities {
|
||||
for _, resent := range resents.ResourceEntity {
|
||||
|
||||
if resent.Name == vapp && resent.Type == "application/vnd.vmware.vcloud.vApp+xml" {
|
||||
|
||||
u, err := url.ParseRequestURI(resent.HREF)
|
||||
|
||||
if err != nil {
|
||||
return VApp{}, fmt.Errorf("error decoding vdc response: %s", err)
|
||||
}
|
||||
|
||||
// Querying the VApp
|
||||
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return VApp{}, fmt.Errorf("error retrieving vApp: %s", err)
|
||||
}
|
||||
|
||||
newvapp := NewVApp(v.c)
|
||||
|
||||
if err = decodeBody(resp, newvapp.VApp); err != nil {
|
||||
return VApp{}, fmt.Errorf("error decoding vApp response: %s", err)
|
||||
}
|
||||
|
||||
return *newvapp, nil
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return VApp{}, fmt.Errorf("can't find vApp: %s", vapp)
|
||||
}
|
||||
|
||||
func (v *Vdc) FindVAppByID(vappid string) (VApp, error) {
|
||||
|
||||
// Horrible hack to fetch a vapp with its id.
|
||||
// urn:vcloud:vapp:00000000-0000-0000-0000-000000000000
|
||||
|
||||
err := v.Refresh()
|
||||
if err != nil {
|
||||
return VApp{}, fmt.Errorf("error refreshing vdc: %s", err)
|
||||
}
|
||||
|
||||
urnslice := strings.SplitAfter(vappid, ":")
|
||||
urnid := urnslice[len(urnslice)-1]
|
||||
|
||||
for _, resents := range v.Vdc.ResourceEntities {
|
||||
for _, resent := range resents.ResourceEntity {
|
||||
|
||||
hrefslice := strings.SplitAfter(resent.HREF, "/")
|
||||
hrefslice = strings.SplitAfter(hrefslice[len(hrefslice)-1], "-")
|
||||
res := strings.Join(hrefslice[1:], "")
|
||||
|
||||
if res == urnid && resent.Type == "application/vnd.vmware.vcloud.vApp+xml" {
|
||||
|
||||
u, err := url.ParseRequestURI(resent.HREF)
|
||||
|
||||
if err != nil {
|
||||
return VApp{}, fmt.Errorf("error decoding vdc response: %s", err)
|
||||
}
|
||||
|
||||
// Querying the VApp
|
||||
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
|
||||
|
||||
resp, err := checkResp(v.c.Http.Do(req))
|
||||
if err != nil {
|
||||
return VApp{}, fmt.Errorf("error retrieving vApp: %s", err)
|
||||
}
|
||||
|
||||
newvapp := NewVApp(v.c)
|
||||
|
||||
if err = decodeBody(resp, newvapp.VApp); err != nil {
|
||||
return VApp{}, fmt.Errorf("error decoding vApp response: %s", err)
|
||||
}
|
||||
|
||||
return *newvapp, nil
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return VApp{}, fmt.Errorf("can't find vApp")
|
||||
|
||||
}
|
||||
178
Godeps/_workspace/src/github.com/vmware/govcloudair/vdc_test.go
generated
vendored
Normal file
178
Godeps/_workspace/src/github.com/vmware/govcloudair/vdc_test.go
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
|
||||
*/
|
||||
|
||||
package govcloudair
|
||||
|
||||
import (
|
||||
"github.com/vmware/govcloudair/testutil"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *S) Test_FindVDCNetwork(c *C) {
|
||||
|
||||
testServer.Response(200, nil, orgvdcnetExample)
|
||||
|
||||
net, err := s.vdc.FindVDCNetwork("networkName")
|
||||
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(net, NotNil)
|
||||
c.Assert(net.OrgVDCNetwork.HREF, Equals, "http://localhost:4444/api/network/cb0f4c9e-1a46-49d4-9fcb-d228000a6bc1")
|
||||
|
||||
// find Invalid Network
|
||||
net, err = s.vdc.FindVDCNetwork("INVALID")
|
||||
c.Assert(err, NotNil)
|
||||
}
|
||||
|
||||
func (s *S) Test_GetVDCOrg(c *C) {
|
||||
|
||||
testServer.Response(200, nil, orgExample)
|
||||
|
||||
org, err := s.vdc.GetVDCOrg()
|
||||
|
||||
_ = testServer.WaitRequest()
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(org, NotNil)
|
||||
c.Assert(org.Org.HREF, Equals, "http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57")
|
||||
}
|
||||
|
||||
func (s *S) Test_NewVdc(c *C) {
|
||||
|
||||
testServer.Response(200, nil, vdcExample)
|
||||
err := s.vdc.Refresh()
|
||||
_ = testServer.WaitRequest()
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
c.Assert(s.vdc.Vdc.Link[0].Rel, Equals, "up")
|
||||
c.Assert(s.vdc.Vdc.Link[0].Type, Equals, "application/vnd.vmware.vcloud.org+xml")
|
||||
c.Assert(s.vdc.Vdc.Link[0].HREF, Equals, "http://localhost:4444/api/org/11111111-1111-1111-1111-111111111111")
|
||||
|
||||
c.Assert(s.vdc.Vdc.AllocationModel, Equals, "AllocationPool")
|
||||
|
||||
for _, v := range s.vdc.Vdc.ComputeCapacity {
|
||||
c.Assert(v.CPU.Units, Equals, "MHz")
|
||||
c.Assert(v.CPU.Allocated, Equals, int64(30000))
|
||||
c.Assert(v.CPU.Limit, Equals, int64(30000))
|
||||
c.Assert(v.CPU.Reserved, Equals, int64(15000))
|
||||
c.Assert(v.CPU.Used, Equals, int64(0))
|
||||
c.Assert(v.CPU.Overhead, Equals, int64(0))
|
||||
c.Assert(v.Memory.Units, Equals, "MB")
|
||||
c.Assert(v.Memory.Allocated, Equals, int64(61440))
|
||||
c.Assert(v.Memory.Limit, Equals, int64(61440))
|
||||
c.Assert(v.Memory.Reserved, Equals, int64(61440))
|
||||
c.Assert(v.Memory.Used, Equals, int64(6144))
|
||||
c.Assert(v.Memory.Overhead, Equals, int64(95))
|
||||
}
|
||||
|
||||
c.Assert(s.vdc.Vdc.ResourceEntities[0].ResourceEntity[0].Name, Equals, "vAppTemplate")
|
||||
c.Assert(s.vdc.Vdc.ResourceEntities[0].ResourceEntity[0].Type, Equals, "application/vnd.vmware.vcloud.vAppTemplate+xml")
|
||||
c.Assert(s.vdc.Vdc.ResourceEntities[0].ResourceEntity[0].HREF, Equals, "http://localhost:4444/api/vAppTemplate/vappTemplate-22222222-2222-2222-2222-222222222222")
|
||||
|
||||
for _, v := range s.vdc.Vdc.AvailableNetworks {
|
||||
for _, v2 := range v.Network {
|
||||
c.Assert(v2.Name, Equals, "networkName")
|
||||
c.Assert(v2.Type, Equals, "application/vnd.vmware.vcloud.network+xml")
|
||||
c.Assert(v2.HREF, Equals, "http://localhost:4444/api/network/44444444-4444-4444-4444-4444444444444")
|
||||
}
|
||||
}
|
||||
|
||||
c.Assert(s.vdc.Vdc.NicQuota, Equals, 0)
|
||||
c.Assert(s.vdc.Vdc.NetworkQuota, Equals, 20)
|
||||
c.Assert(s.vdc.Vdc.UsedNetworkCount, Equals, 0)
|
||||
c.Assert(s.vdc.Vdc.VMQuota, Equals, 0)
|
||||
c.Assert(s.vdc.Vdc.IsEnabled, Equals, true)
|
||||
|
||||
for _, v := range s.vdc.Vdc.VdcStorageProfiles {
|
||||
for _, v2 := range v.VdcStorageProfile {
|
||||
c.Assert(v2.Name, Equals, "storageProfile")
|
||||
c.Assert(v2.Type, Equals, "application/vnd.vmware.vcloud.vdcStorageProfile+xml")
|
||||
c.Assert(v2.HREF, Equals, "http://localhost:4444/api/vdcStorageProfile/88888888-8888-8888-8888-888888888888")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *S) Test_FindVApp(c *C) {
|
||||
|
||||
// testServer.Response(200, nil, vappExample)
|
||||
|
||||
// vapp, err := s.vdc.FindVAppByID("")
|
||||
|
||||
// _ = testServer.WaitRequest()
|
||||
// testServer.Flush()
|
||||
// c.Assert(err, IsNil)
|
||||
|
||||
testServer.ResponseMap(2, testutil.ResponseMap{
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
"/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample},
|
||||
})
|
||||
|
||||
_, err := s.vdc.FindVAppByName("myVApp")
|
||||
|
||||
_ = testServer.WaitRequests(2)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
testServer.ResponseMap(2, testutil.ResponseMap{
|
||||
"/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample},
|
||||
"/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample},
|
||||
})
|
||||
|
||||
_, err = s.vdc.FindVAppByID("urn:vcloud:vapp:00000000-0000-0000-0000-000000000000")
|
||||
|
||||
_ = testServer.WaitRequests(2)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
}
|
||||
|
||||
var vdcExample = `
|
||||
<?xml version="1.0" ?>
|
||||
<Vdc href="http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" id="urn:vcloud:vdc:00000000-0000-0000-0000-000000000000" name="M916272752-5793" status="1" type="application/vnd.vmware.vcloud.vdc+xml" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-in stance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.6.32.3/api/v1.5/schema/master.xsd">
|
||||
<Link href="http://localhost:4444/api/org/11111111-1111-1111-1111-111111111111" rel="up" type="application/vnd.vmware.vcloud.org+xml"/>
|
||||
<Link href="http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000/edgeGateways" rel="edgeGateways" type="application/vnd.vmware.vcloud.query.records+xml"/>
|
||||
<AllocationModel>AllocationPool</AllocationModel>
|
||||
<ComputeCapacity>
|
||||
<Cpu>
|
||||
<Units>MHz</Units>
|
||||
<Allocated>30000</Allocated>
|
||||
<Limit>30000</Limit>
|
||||
<Reserved>15000</Reserved>
|
||||
<Used>0</Used>
|
||||
<Overhead>0</Overhead>
|
||||
</Cpu>
|
||||
<Memory>
|
||||
<Units>MB</Units>
|
||||
<Allocated>61440</Allocated>
|
||||
<Limit>61440</Limit>
|
||||
<Reserved>61440</Reserved>
|
||||
<Used>6144</Used>
|
||||
<Overhead>95</Overhead>
|
||||
</Memory>
|
||||
</ComputeCapacity>
|
||||
<ResourceEntities>
|
||||
<ResourceEntity href="http://localhost:4444/api/vAppTemplate/vappTemplate-22222222-2222-2222-2222-222222222222" name="vAppTemplate" type="application/vnd.vmware.vcloud.vAppTemplate+xml"/>
|
||||
<ResourceEntity href="http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000" name="myVApp" type="application/vnd.vmware.vcloud.vApp+xml"/>
|
||||
</ResourceEntities>
|
||||
<AvailableNetworks>
|
||||
<Network href="http://localhost:4444/api/network/44444444-4444-4444-4444-4444444444444" name="networkName" type="application/vnd.vmware.vcloud.network+xml"/>
|
||||
</AvailableNetworks>
|
||||
<Capabilities>
|
||||
<SupportedHardwareVersions>
|
||||
<SupportedHardwareVersion>vmx-10</SupportedHardwareVersion>
|
||||
</SupportedHardwareVersions>
|
||||
</Capabilities>
|
||||
<NicQuota>0</NicQuota>
|
||||
<NetworkQuota>20</NetworkQuota>
|
||||
<UsedNetworkCount>0</UsedNetworkCount>
|
||||
<VmQuota>0</VmQuota>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<VdcStorageProfiles>
|
||||
<VdcStorageProfile href="http://localhost:4444/api/vdcStorageProfile/88888888-8888-8888-8888-888888888888" name="storageProfile" type="application/vnd.vmware.vcloud.vdcStorageProfile+xml"/>
|
||||
</VdcStorageProfiles>
|
||||
</Vdc>
|
||||
`
|
||||
@@ -19,6 +19,9 @@ import (
|
||||
_ "github.com/docker/machine/drivers/google"
|
||||
_ "github.com/docker/machine/drivers/none"
|
||||
_ "github.com/docker/machine/drivers/virtualbox"
|
||||
_ "github.com/docker/machine/drivers/vmwarefusion"
|
||||
_ "github.com/docker/machine/drivers/vmwarevcloudair"
|
||||
_ "github.com/docker/machine/drivers/vmwarevsphere"
|
||||
"github.com/docker/machine/state"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user