mirror of https://github.com/k3s-io/k3s
Update to latest gophercloud
Change-Id: I0145b899576f76e7116152fee978bc04b05080f8pull/564/head
parent
aba3161f8a
commit
55a8dbcbfb
|
@ -2101,123 +2101,127 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud",
|
"ImportPath": "github.com/gophercloud/gophercloud",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/common/extensions",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/common/extensions",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/images",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/images",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies",
|
||||||
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/networks",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/networks",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
|
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gorilla/websocket",
|
"ImportPath": "github.com/gorilla/websocket",
|
||||||
|
|
|
@ -65927,6 +65927,205 @@ specific language governing permissions and limitations under the License.
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies licensed under: =
|
||||||
|
|
||||||
|
Copyright 2012-2013 Rackspace, Inc.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
= vendor/github.com/gophercloud/gophercloud/LICENSE dd19699707373c2ca31531a659130416
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners licensed under: =
|
= vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners licensed under: =
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,7 @@ func (volumes *VolumesV1) deleteVolume(volumeID string) error {
|
||||||
|
|
||||||
func (volumes *VolumesV2) deleteVolume(volumeID string) error {
|
func (volumes *VolumesV2) deleteVolume(volumeID string) error {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
err := volumes_v2.Delete(volumes.blockstorage, volumeID).ExtractErr()
|
err := volumes_v2.Delete(volumes.blockstorage, volumeID, nil).ExtractErr()
|
||||||
timeTaken := time.Since(startTime).Seconds()
|
timeTaken := time.Since(startTime).Seconds()
|
||||||
recordOpenstackOperationMetric("delete_v2_volume", timeTaken, err)
|
recordOpenstackOperationMetric("delete_v2_volume", timeTaken, err)
|
||||||
return err
|
return err
|
||||||
|
@ -264,7 +264,7 @@ func (volumes *VolumesV2) deleteVolume(volumeID string) error {
|
||||||
|
|
||||||
func (volumes *VolumesV3) deleteVolume(volumeID string) error {
|
func (volumes *VolumesV3) deleteVolume(volumeID string) error {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
err := volumes_v3.Delete(volumes.blockstorage, volumeID).ExtractErr()
|
err := volumes_v3.Delete(volumes.blockstorage, volumeID, nil).ExtractErr()
|
||||||
timeTaken := time.Since(startTime).Seconds()
|
timeTaken := time.Since(startTime).Seconds()
|
||||||
recordOpenstackOperationMetric("delete_v3_volume", timeTaken, err)
|
recordOpenstackOperationMetric("delete_v3_volume", timeTaken, err)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -112,31 +112,31 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud",
|
"ImportPath": "github.com/gophercloud/gophercloud",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
|
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
|
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
|
||||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
"Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gregjones/httpcache",
|
"ImportPath": "github.com/gregjones/httpcache",
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
**/*.swp
|
**/*.swp
|
||||||
.idea
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
|
@ -7,8 +7,8 @@ install:
|
||||||
- go get github.com/mattn/goveralls
|
- go get github.com/mattn/goveralls
|
||||||
- go get golang.org/x/tools/cmd/goimports
|
- go get golang.org/x/tools/cmd/goimports
|
||||||
go:
|
go:
|
||||||
- 1.8
|
- "1.10"
|
||||||
- tip
|
- "tip"
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ="
|
- secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ="
|
||||||
|
|
|
@ -1,3 +1,73 @@
|
||||||
|
- job:
|
||||||
|
name: gophercloud-unittest
|
||||||
|
parent: golang-test
|
||||||
|
description: |
|
||||||
|
Run gophercloud unit test
|
||||||
|
run: .zuul/playbooks/gophercloud-unittest/run.yaml
|
||||||
|
nodeset: ubuntu-xenial-ut
|
||||||
|
|
||||||
|
- job:
|
||||||
|
name: gophercloud-acceptance-test
|
||||||
|
parent: golang-test
|
||||||
|
description: |
|
||||||
|
Run gophercloud acceptance test on master branch
|
||||||
|
run: .zuul/playbooks/gophercloud-acceptance-test/run.yaml
|
||||||
|
|
||||||
|
- job:
|
||||||
|
name: gophercloud-acceptance-test-queens
|
||||||
|
parent: gophercloud-acceptance-test
|
||||||
|
description: |
|
||||||
|
Run gophercloud acceptance test on queens branch
|
||||||
|
vars:
|
||||||
|
global_env:
|
||||||
|
OS_BRANCH: stable/queens
|
||||||
|
|
||||||
|
- job:
|
||||||
|
name: gophercloud-acceptance-test-rocky
|
||||||
|
parent: gophercloud-acceptance-test
|
||||||
|
description: |
|
||||||
|
Run gophercloud acceptance test on rocky branch
|
||||||
|
vars:
|
||||||
|
global_env:
|
||||||
|
OS_BRANCH: stable/rocky
|
||||||
|
|
||||||
|
- job:
|
||||||
|
name: gophercloud-acceptance-test-pike
|
||||||
|
parent: gophercloud-acceptance-test
|
||||||
|
description: |
|
||||||
|
Run gophercloud acceptance test on pike branch
|
||||||
|
vars:
|
||||||
|
global_env:
|
||||||
|
OS_BRANCH: stable/pike
|
||||||
|
|
||||||
|
- job:
|
||||||
|
name: gophercloud-acceptance-test-ocata
|
||||||
|
parent: gophercloud-acceptance-test
|
||||||
|
description: |
|
||||||
|
Run gophercloud acceptance test on ocata branch
|
||||||
|
vars:
|
||||||
|
global_env:
|
||||||
|
OS_BRANCH: stable/ocata
|
||||||
|
|
||||||
|
- job:
|
||||||
|
name: gophercloud-acceptance-test-newton
|
||||||
|
parent: gophercloud-acceptance-test
|
||||||
|
description: |
|
||||||
|
Run gophercloud acceptance test on newton branch
|
||||||
|
vars:
|
||||||
|
global_env:
|
||||||
|
OS_BRANCH: stable/newton
|
||||||
|
|
||||||
|
- job:
|
||||||
|
name: gophercloud-acceptance-test-mitaka
|
||||||
|
parent: gophercloud-acceptance-test
|
||||||
|
description: |
|
||||||
|
Run gophercloud acceptance test on mitaka branch
|
||||||
|
vars:
|
||||||
|
global_env:
|
||||||
|
OS_BRANCH: stable/mitaka
|
||||||
|
nodeset: ubuntu-trusty
|
||||||
|
|
||||||
- project:
|
- project:
|
||||||
name: gophercloud/gophercloud
|
name: gophercloud/gophercloud
|
||||||
check:
|
check:
|
||||||
|
@ -7,6 +77,22 @@
|
||||||
recheck-mitaka:
|
recheck-mitaka:
|
||||||
jobs:
|
jobs:
|
||||||
- gophercloud-acceptance-test-mitaka
|
- gophercloud-acceptance-test-mitaka
|
||||||
|
recheck-newton:
|
||||||
|
jobs:
|
||||||
|
- gophercloud-acceptance-test-newton
|
||||||
|
recheck-ocata:
|
||||||
|
jobs:
|
||||||
|
- gophercloud-acceptance-test-ocata
|
||||||
recheck-pike:
|
recheck-pike:
|
||||||
jobs:
|
jobs:
|
||||||
- gophercloud-acceptance-test-pike
|
- gophercloud-acceptance-test-pike
|
||||||
|
recheck-queens:
|
||||||
|
jobs:
|
||||||
|
- gophercloud-acceptance-test-queens
|
||||||
|
recheck-rocky:
|
||||||
|
jobs:
|
||||||
|
- gophercloud-acceptance-test-rocky
|
||||||
|
periodic:
|
||||||
|
jobs:
|
||||||
|
- gophercloud-unittest
|
||||||
|
- gophercloud-acceptance-test
|
||||||
|
|
|
@ -1,148 +0,0 @@
|
||||||
# Tips
|
|
||||||
|
|
||||||
## Implementing default logging and re-authentication attempts
|
|
||||||
|
|
||||||
You can implement custom logging and/or limit re-auth attempts by creating a custom HTTP client
|
|
||||||
like the following and setting it as the provider client's HTTP Client (via the
|
|
||||||
`gophercloud.ProviderClient.HTTPClient` field):
|
|
||||||
|
|
||||||
```go
|
|
||||||
//...
|
|
||||||
|
|
||||||
// LogRoundTripper satisfies the http.RoundTripper interface and is used to
|
|
||||||
// customize the default Gophercloud RoundTripper to allow for logging.
|
|
||||||
type LogRoundTripper struct {
|
|
||||||
rt http.RoundTripper
|
|
||||||
numReauthAttempts int
|
|
||||||
}
|
|
||||||
|
|
||||||
// newHTTPClient return a custom HTTP client that allows for logging relevant
|
|
||||||
// information before and after the HTTP request.
|
|
||||||
func newHTTPClient() http.Client {
|
|
||||||
return http.Client{
|
|
||||||
Transport: &LogRoundTripper{
|
|
||||||
rt: http.DefaultTransport,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RoundTrip performs a round-trip HTTP request and logs relevant information about it.
|
|
||||||
func (lrt *LogRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
|
|
||||||
glog.Infof("Request URL: %s\n", request.URL)
|
|
||||||
|
|
||||||
response, err := lrt.rt.RoundTrip(request)
|
|
||||||
if response == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if response.StatusCode == http.StatusUnauthorized {
|
|
||||||
if lrt.numReauthAttempts == 3 {
|
|
||||||
return response, fmt.Errorf("Tried to re-authenticate 3 times with no success.")
|
|
||||||
}
|
|
||||||
lrt.numReauthAttempts++
|
|
||||||
}
|
|
||||||
|
|
||||||
glog.Debugf("Response Status: %s\n", response.Status)
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
endpoint := "https://127.0.0.1/auth"
|
|
||||||
pc := openstack.NewClient(endpoint)
|
|
||||||
pc.HTTPClient = newHTTPClient()
|
|
||||||
|
|
||||||
//...
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Implementing custom objects
|
|
||||||
|
|
||||||
OpenStack request/response objects may differ among variable names or types.
|
|
||||||
|
|
||||||
### Custom request objects
|
|
||||||
|
|
||||||
To pass custom options to a request, implement the desired `<ACTION>OptsBuilder` interface. For
|
|
||||||
example, to pass in
|
|
||||||
|
|
||||||
```go
|
|
||||||
type MyCreateServerOpts struct {
|
|
||||||
Name string
|
|
||||||
Size int
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
to `servers.Create`, simply implement the `servers.CreateOptsBuilder` interface:
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (o MyCreateServeropts) ToServerCreateMap() (map[string]interface{}, error) {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"name": o.Name,
|
|
||||||
"size": o.Size,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
create an instance of your custom options object, and pass it to `servers.Create`:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// ...
|
|
||||||
myOpts := MyCreateServerOpts{
|
|
||||||
Name: "s1",
|
|
||||||
Size: "100",
|
|
||||||
}
|
|
||||||
server, err := servers.Create(computeClient, myOpts).Extract()
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom response objects
|
|
||||||
|
|
||||||
Some OpenStack services have extensions. Extensions that are supported in Gophercloud can be
|
|
||||||
combined to create a custom object:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// ...
|
|
||||||
type MyVolume struct {
|
|
||||||
volumes.Volume
|
|
||||||
tenantattr.VolumeExt
|
|
||||||
}
|
|
||||||
|
|
||||||
var v struct {
|
|
||||||
MyVolume `json:"volume"`
|
|
||||||
}
|
|
||||||
|
|
||||||
err := volumes.Get(client, volID).ExtractInto(&v)
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Overriding default `UnmarshalJSON` method
|
|
||||||
|
|
||||||
For some response objects, a field may be a custom type or may be allowed to take on
|
|
||||||
different types. In these cases, overriding the default `UnmarshalJSON` method may be
|
|
||||||
necessary. To do this, declare the JSON `struct` field tag as "-" and create an `UnmarshalJSON`
|
|
||||||
method on the type:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// ...
|
|
||||||
type MyVolume struct {
|
|
||||||
ID string `json: "id"`
|
|
||||||
TimeCreated time.Time `json: "-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *MyVolume) UnmarshalJSON(b []byte) error {
|
|
||||||
type tmp MyVolume
|
|
||||||
var s struct {
|
|
||||||
tmp
|
|
||||||
TimeCreated gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
|
||||||
}
|
|
||||||
err := json.Unmarshal(b, &s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*r = Volume(s.tmp)
|
|
||||||
|
|
||||||
r.TimeCreated = time.Time(s.CreatedAt)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// ...
|
|
||||||
```
|
|
|
@ -1,32 +0,0 @@
|
||||||
# Compute
|
|
||||||
|
|
||||||
## Floating IPs
|
|
||||||
|
|
||||||
* `github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingip` is now `github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips`
|
|
||||||
* `floatingips.Associate` and `floatingips.Disassociate` have been removed.
|
|
||||||
* `floatingips.DisassociateOpts` is now required to disassociate a Floating IP.
|
|
||||||
|
|
||||||
## Security Groups
|
|
||||||
|
|
||||||
* `secgroups.AddServerToGroup` is now `secgroups.AddServer`.
|
|
||||||
* `secgroups.RemoveServerFromGroup` is now `secgroups.RemoveServer`.
|
|
||||||
|
|
||||||
## Servers
|
|
||||||
|
|
||||||
* `servers.Reboot` now requires a `servers.RebootOpts` struct:
|
|
||||||
|
|
||||||
```golang
|
|
||||||
rebootOpts := &servers.RebootOpts{
|
|
||||||
Type: servers.SoftReboot,
|
|
||||||
}
|
|
||||||
res := servers.Reboot(client, server.ID, rebootOpts)
|
|
||||||
```
|
|
||||||
|
|
||||||
# Identity
|
|
||||||
|
|
||||||
## V3
|
|
||||||
|
|
||||||
### Tokens
|
|
||||||
|
|
||||||
* `Token.ExpiresAt` is now of type `gophercloud.JSONRFC3339Milli` instead of
|
|
||||||
`time.Time`
|
|
|
@ -127,7 +127,7 @@ new resource in the `server` variable (a
|
||||||
|
|
||||||
## Advanced Usage
|
## Advanced Usage
|
||||||
|
|
||||||
Have a look at the [FAQ](./FAQ.md) for some tips on customizing the way Gophercloud works.
|
Have a look at the [FAQ](./docs/FAQ.md) for some tips on customizing the way Gophercloud works.
|
||||||
|
|
||||||
## Backwards-Compatibility Guarantees
|
## Backwards-Compatibility Guarantees
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ See the [contributing guide](./.github/CONTRIBUTING.md).
|
||||||
## Help and feedback
|
## Help and feedback
|
||||||
|
|
||||||
If you're struggling with something or have spotted a potential bug, feel free
|
If you're struggling with something or have spotted a potential bug, feel free
|
||||||
to submit an issue to our [bug tracker](/issues).
|
to submit an issue to our [bug tracker](https://github.com/gophercloud/gophercloud/issues).
|
||||||
|
|
||||||
## Thank You
|
## Thank You
|
||||||
|
|
||||||
|
@ -148,12 +148,12 @@ We'd like to extend special thanks and appreciation to the following:
|
||||||
|
|
||||||
### OpenLab
|
### OpenLab
|
||||||
|
|
||||||
<a href="http://openlabtesting.org/"><img src="assets/openlab.png" width="600px"></a>
|
<a href="http://openlabtesting.org/"><img src="./docs/assets/openlab.png" width="600px"></a>
|
||||||
|
|
||||||
OpenLab is providing a full CI environment to test each PR and merge for a variety of OpenStack releases.
|
OpenLab is providing a full CI environment to test each PR and merge for a variety of OpenStack releases.
|
||||||
|
|
||||||
### VEXXHOST
|
### VEXXHOST
|
||||||
|
|
||||||
<a href="https://vexxhost.com/"><img src="assets/vexxhost.png" width="600px"></a>
|
<a href="https://vexxhost.com/"><img src="./docs/assets/vexxhost.png" width="600px"></a>
|
||||||
|
|
||||||
VEXXHOST is providing their services to assist with the development and testing of Gophercloud.
|
VEXXHOST is providing their services to assist with the development and testing of Gophercloud.
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
|
|
||||||
## On Pull Requests
|
|
||||||
|
|
||||||
- Please make sure to read our [contributing guide](/.github/CONTRIBUTING.md).
|
|
||||||
|
|
||||||
- Before you start a PR there needs to be a Github issue and a discussion about it
|
|
||||||
on that issue with a core contributor, even if it's just a 'SGTM'.
|
|
||||||
|
|
||||||
- A PR's description must reference the issue it closes with a `For <ISSUE NUMBER>` (e.g. For #293).
|
|
||||||
|
|
||||||
- A PR's description must contain link(s) to the line(s) in the OpenStack
|
|
||||||
source code (on Github) that prove(s) the PR code to be valid. Links to documentation
|
|
||||||
are not good enough. The link(s) should be to a non-`master` branch. For example,
|
|
||||||
a pull request implementing the creation of a Neutron v2 subnet might put the
|
|
||||||
following link in the description:
|
|
||||||
|
|
||||||
https://github.com/openstack/neutron/blob/stable/mitaka/neutron/api/v2/attributes.py#L749
|
|
||||||
|
|
||||||
From that link, a reviewer (or user) can verify the fields in the request/response
|
|
||||||
objects in the PR.
|
|
||||||
|
|
||||||
- A PR that is in-progress should have `[wip]` in front of the PR's title. When
|
|
||||||
ready for review, remove the `[wip]` and ping a core contributor with an `@`.
|
|
||||||
|
|
||||||
- Forcing PRs to be small can have the effect of users submitting PRs in a hierarchical chain, with
|
|
||||||
one depending on the next. If a PR depends on another one, it should have a [Pending #PRNUM]
|
|
||||||
prefix in the PR title. In addition, it will be the PR submitter's responsibility to remove the
|
|
||||||
[Pending #PRNUM] tag once the PR has been updated with the merged, dependent PR. That will
|
|
||||||
let reviewers know it is ready to review.
|
|
||||||
|
|
||||||
- A PR should be small. Even if you intend on implementing an entire
|
|
||||||
service, a PR should only be one route of that service
|
|
||||||
(e.g. create server or get server, but not both).
|
|
||||||
|
|
||||||
- Unless explicitly asked, do not squash commits in the middle of a review; only
|
|
||||||
append. It makes it difficult for the reviewer to see what's changed from one
|
|
||||||
review to the next.
|
|
||||||
|
|
||||||
- See [#583](https://github.com/gophercloud/gophercloud/issues/583) as an example of a
|
|
||||||
well-formatted issue which contains all relevant information we need to review and approve.
|
|
||||||
|
|
||||||
## On Code
|
|
||||||
|
|
||||||
- In re design: follow as closely as is reasonable the code already in the library.
|
|
||||||
Most operations (e.g. create, delete) admit the same design.
|
|
||||||
|
|
||||||
- Unit tests and acceptance (integration) tests must be written to cover each PR.
|
|
||||||
Tests for operations with several options (e.g. list, create) should include all
|
|
||||||
the options in the tests. This will allow users to verify an operation on their
|
|
||||||
own infrastructure and see an example of usage.
|
|
||||||
|
|
||||||
- If in doubt, ask in-line on the PR.
|
|
||||||
|
|
||||||
### File Structure
|
|
||||||
|
|
||||||
- The following should be used in most cases:
|
|
||||||
|
|
||||||
- `requests.go`: contains all the functions that make HTTP requests and the
|
|
||||||
types associated with the HTTP request (parameters for URL, body, etc)
|
|
||||||
- `results.go`: contains all the response objects and their methods
|
|
||||||
- `urls.go`: contains the endpoints to which the requests are made
|
|
||||||
|
|
||||||
### Naming
|
|
||||||
|
|
||||||
- For methods on a type in `results.go`, the receiver should be named `r` and the
|
|
||||||
variable into which it will be unmarshalled `s`.
|
|
||||||
|
|
||||||
- Functions in `requests.go`, with the exception of functions that return a
|
|
||||||
`pagination.Pager`, should be named returns of the name `r`.
|
|
||||||
|
|
||||||
- Functions in `requests.go` that accept request bodies should accept as their
|
|
||||||
last parameter an `interface` named `<Action>OptsBuilder` (eg `CreateOptsBuilder`).
|
|
||||||
This `interface` should have at the least a method named `To<Resource><Action>Map`
|
|
||||||
(eg `ToPortCreateMap`).
|
|
||||||
|
|
||||||
- Functions in `requests.go` that accept query strings should accept as their
|
|
||||||
last parameter an `interface` named `<Action>OptsBuilder` (eg `ListOptsBuilder`).
|
|
||||||
This `interface` should have at the least a method named `To<Resource><Action>Query`
|
|
||||||
(eg `ToServerListQuery`).
|
|
|
@ -81,6 +81,23 @@ type AuthOptions struct {
|
||||||
// TokenID allows users to authenticate (possibly as another user) with an
|
// TokenID allows users to authenticate (possibly as another user) with an
|
||||||
// authentication token ID.
|
// authentication token ID.
|
||||||
TokenID string `json:"-"`
|
TokenID string `json:"-"`
|
||||||
|
|
||||||
|
// Scope determines the scoping of the authentication request.
|
||||||
|
Scope *AuthScope `json:"-"`
|
||||||
|
|
||||||
|
// Authentication through Application Credentials requires supplying name, project and secret
|
||||||
|
// For project we can use TenantID
|
||||||
|
ApplicationCredentialID string `json:"-"`
|
||||||
|
ApplicationCredentialName string `json:"-"`
|
||||||
|
ApplicationCredentialSecret string `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthScope allows a created token to be limited to a specific domain or project.
|
||||||
|
type AuthScope struct {
|
||||||
|
ProjectID string
|
||||||
|
ProjectName string
|
||||||
|
DomainID string
|
||||||
|
DomainName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
||||||
|
@ -131,7 +148,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
type userReq struct {
|
type userReq struct {
|
||||||
ID *string `json:"id,omitempty"`
|
ID *string `json:"id,omitempty"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password,omitempty"`
|
||||||
Domain *domainReq `json:"domain,omitempty"`
|
Domain *domainReq `json:"domain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,10 +160,18 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type applicationCredentialReq struct {
|
||||||
|
ID *string `json:"id,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
User *userReq `json:"user,omitempty"`
|
||||||
|
Secret *string `json:"secret,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type identityReq struct {
|
type identityReq struct {
|
||||||
Methods []string `json:"methods"`
|
Methods []string `json:"methods"`
|
||||||
Password *passwordReq `json:"password,omitempty"`
|
Password *passwordReq `json:"password,omitempty"`
|
||||||
Token *tokenReq `json:"token,omitempty"`
|
Token *tokenReq `json:"token,omitempty"`
|
||||||
|
ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type authReq struct {
|
type authReq struct {
|
||||||
|
@ -183,8 +208,68 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
req.Auth.Identity.Token = &tokenReq{
|
req.Auth.Identity.Token = &tokenReq{
|
||||||
ID: opts.TokenID,
|
ID: opts.TokenID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if opts.ApplicationCredentialID != "" {
|
||||||
|
// Configure the request for ApplicationCredentialID authentication.
|
||||||
|
// https://github.com/openstack/keystoneauth/blob/stable/rocky/keystoneauth1/identity/v3/application_credential.py#L48-L67
|
||||||
|
// There are three kinds of possible application_credential requests
|
||||||
|
// 1. application_credential id + secret
|
||||||
|
// 2. application_credential name + secret + user_id
|
||||||
|
// 3. application_credential name + secret + username + domain_id / domain_name
|
||||||
|
if opts.ApplicationCredentialSecret == "" {
|
||||||
|
return nil, ErrAppCredMissingSecret{}
|
||||||
|
}
|
||||||
|
req.Auth.Identity.Methods = []string{"application_credential"}
|
||||||
|
req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{
|
||||||
|
ID: &opts.ApplicationCredentialID,
|
||||||
|
Secret: &opts.ApplicationCredentialSecret,
|
||||||
|
}
|
||||||
|
} else if opts.ApplicationCredentialName != "" {
|
||||||
|
if opts.ApplicationCredentialSecret == "" {
|
||||||
|
return nil, ErrAppCredMissingSecret{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var userRequest *userReq
|
||||||
|
|
||||||
|
if opts.UserID != "" {
|
||||||
|
// UserID could be used without the domain information
|
||||||
|
userRequest = &userReq{
|
||||||
|
ID: &opts.UserID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if userRequest == nil && opts.Username == "" {
|
||||||
|
// Make sure that Username or UserID are provided
|
||||||
|
return nil, ErrUsernameOrUserID{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if userRequest == nil && opts.DomainID != "" {
|
||||||
|
userRequest = &userReq{
|
||||||
|
Name: &opts.Username,
|
||||||
|
Domain: &domainReq{ID: &opts.DomainID},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if userRequest == nil && opts.DomainName != "" {
|
||||||
|
userRequest = &userReq{
|
||||||
|
Name: &opts.Username,
|
||||||
|
Domain: &domainReq{Name: &opts.DomainName},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that DomainID or DomainName are provided among Username
|
||||||
|
if userRequest == nil {
|
||||||
|
return nil, ErrDomainIDOrDomainName{}
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Auth.Identity.Methods = []string{"application_credential"}
|
||||||
|
req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{
|
||||||
|
Name: &opts.ApplicationCredentialName,
|
||||||
|
User: userRequest,
|
||||||
|
Secret: &opts.ApplicationCredentialSecret,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no password or token ID are available, authentication can't continue.
|
// If no password or token ID or ApplicationCredential are available, authentication can't continue.
|
||||||
return nil, ErrMissingPassword{}
|
return nil, ErrMissingPassword{}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -263,85 +348,83 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||||
|
// For backwards compatibility.
|
||||||
var scope struct {
|
// If AuthOptions.Scope was not set, try to determine it.
|
||||||
ProjectID string
|
// This works well for common scenarios.
|
||||||
ProjectName string
|
if opts.Scope == nil {
|
||||||
DomainID string
|
opts.Scope = new(AuthScope)
|
||||||
DomainName string
|
if opts.TenantID != "" {
|
||||||
}
|
opts.Scope.ProjectID = opts.TenantID
|
||||||
|
} else {
|
||||||
if opts.TenantID != "" {
|
if opts.TenantName != "" {
|
||||||
scope.ProjectID = opts.TenantID
|
opts.Scope.ProjectName = opts.TenantName
|
||||||
} else {
|
opts.Scope.DomainID = opts.DomainID
|
||||||
if opts.TenantName != "" {
|
opts.Scope.DomainName = opts.DomainName
|
||||||
scope.ProjectName = opts.TenantName
|
}
|
||||||
scope.DomainID = opts.DomainID
|
|
||||||
scope.DomainName = opts.DomainName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.ProjectName != "" {
|
if opts.Scope.ProjectName != "" {
|
||||||
// ProjectName provided: either DomainID or DomainName must also be supplied.
|
// ProjectName provided: either DomainID or DomainName must also be supplied.
|
||||||
// ProjectID may not be supplied.
|
// ProjectID may not be supplied.
|
||||||
if scope.DomainID == "" && scope.DomainName == "" {
|
if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" {
|
||||||
return nil, ErrScopeDomainIDOrDomainName{}
|
return nil, ErrScopeDomainIDOrDomainName{}
|
||||||
}
|
}
|
||||||
if scope.ProjectID != "" {
|
if opts.Scope.ProjectID != "" {
|
||||||
return nil, ErrScopeProjectIDOrProjectName{}
|
return nil, ErrScopeProjectIDOrProjectName{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.DomainID != "" {
|
if opts.Scope.DomainID != "" {
|
||||||
// ProjectName + DomainID
|
// ProjectName + DomainID
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"project": map[string]interface{}{
|
"project": map[string]interface{}{
|
||||||
"name": &scope.ProjectName,
|
"name": &opts.Scope.ProjectName,
|
||||||
"domain": map[string]interface{}{"id": &scope.DomainID},
|
"domain": map[string]interface{}{"id": &opts.Scope.DomainID},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.DomainName != "" {
|
if opts.Scope.DomainName != "" {
|
||||||
// ProjectName + DomainName
|
// ProjectName + DomainName
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"project": map[string]interface{}{
|
"project": map[string]interface{}{
|
||||||
"name": &scope.ProjectName,
|
"name": &opts.Scope.ProjectName,
|
||||||
"domain": map[string]interface{}{"name": &scope.DomainName},
|
"domain": map[string]interface{}{"name": &opts.Scope.DomainName},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
} else if scope.ProjectID != "" {
|
} else if opts.Scope.ProjectID != "" {
|
||||||
// ProjectID provided. ProjectName, DomainID, and DomainName may not be provided.
|
// ProjectID provided. ProjectName, DomainID, and DomainName may not be provided.
|
||||||
if scope.DomainID != "" {
|
if opts.Scope.DomainID != "" {
|
||||||
return nil, ErrScopeProjectIDAlone{}
|
return nil, ErrScopeProjectIDAlone{}
|
||||||
}
|
}
|
||||||
if scope.DomainName != "" {
|
if opts.Scope.DomainName != "" {
|
||||||
return nil, ErrScopeProjectIDAlone{}
|
return nil, ErrScopeProjectIDAlone{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProjectID
|
// ProjectID
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"project": map[string]interface{}{
|
"project": map[string]interface{}{
|
||||||
"id": &scope.ProjectID,
|
"id": &opts.Scope.ProjectID,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
} else if scope.DomainID != "" {
|
} else if opts.Scope.DomainID != "" {
|
||||||
// DomainID provided. ProjectID, ProjectName, and DomainName may not be provided.
|
// DomainID provided. ProjectID, ProjectName, and DomainName may not be provided.
|
||||||
if scope.DomainName != "" {
|
if opts.Scope.DomainName != "" {
|
||||||
return nil, ErrScopeDomainIDOrDomainName{}
|
return nil, ErrScopeDomainIDOrDomainName{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DomainID
|
// DomainID
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"domain": map[string]interface{}{
|
"domain": map[string]interface{}{
|
||||||
"id": &scope.DomainID,
|
"id": &opts.Scope.DomainID,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
} else if scope.DomainName != "" {
|
} else if opts.Scope.DomainName != "" {
|
||||||
// DomainName
|
// DomainName
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"domain": map[string]interface{}{
|
"domain": map[string]interface{}{
|
||||||
"name": &scope.DomainName,
|
"name": &opts.Scope.DomainName,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ pass in the parent provider, like so:
|
||||||
|
|
||||||
opts := gophercloud.EndpointOpts{Region: "RegionOne"}
|
opts := gophercloud.EndpointOpts{Region: "RegionOne"}
|
||||||
|
|
||||||
client := openstack.NewComputeV2(provider, opts)
|
client, err := openstack.NewComputeV2(provider, opts)
|
||||||
|
|
||||||
Resources
|
Resources
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package gophercloud
|
package gophercloud
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// BaseError is an error type that all other error types embed.
|
// BaseError is an error type that all other error types embed.
|
||||||
type BaseError struct {
|
type BaseError struct {
|
||||||
|
@ -43,6 +46,33 @@ func (e ErrInvalidInput) Error() string {
|
||||||
return e.choseErrString()
|
return e.choseErrString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrMissingEnvironmentVariable is the error when environment variable is required
|
||||||
|
// in a particular situation but not provided by the user
|
||||||
|
type ErrMissingEnvironmentVariable struct {
|
||||||
|
BaseError
|
||||||
|
EnvironmentVariable string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrMissingEnvironmentVariable) Error() string {
|
||||||
|
e.DefaultErrString = fmt.Sprintf("Missing environment variable [%s]", e.EnvironmentVariable)
|
||||||
|
return e.choseErrString()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrMissingAnyoneOfEnvironmentVariables is the error when anyone of the environment variables
|
||||||
|
// is required in a particular situation but not provided by the user
|
||||||
|
type ErrMissingAnyoneOfEnvironmentVariables struct {
|
||||||
|
BaseError
|
||||||
|
EnvironmentVariables []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrMissingAnyoneOfEnvironmentVariables) Error() string {
|
||||||
|
e.DefaultErrString = fmt.Sprintf(
|
||||||
|
"Missing one of the following environment variables [%s]",
|
||||||
|
strings.Join(e.EnvironmentVariables, ", "),
|
||||||
|
)
|
||||||
|
return e.choseErrString()
|
||||||
|
}
|
||||||
|
|
||||||
// ErrUnexpectedResponseCode is returned by the Request method when a response code other than
|
// ErrUnexpectedResponseCode is returned by the Request method when a response code other than
|
||||||
// those listed in OkCodes is encountered.
|
// those listed in OkCodes is encountered.
|
||||||
type ErrUnexpectedResponseCode struct {
|
type ErrUnexpectedResponseCode struct {
|
||||||
|
@ -108,7 +138,11 @@ type ErrDefault503 struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e ErrDefault400) Error() string {
|
func (e ErrDefault400) Error() string {
|
||||||
return "Invalid request due to incorrect syntax or missing required parameters."
|
e.DefaultErrString = fmt.Sprintf(
|
||||||
|
"Bad request with: [%s %s], error message: %s",
|
||||||
|
e.Method, e.URL, e.Body,
|
||||||
|
)
|
||||||
|
return e.choseErrString()
|
||||||
}
|
}
|
||||||
func (e ErrDefault401) Error() string {
|
func (e ErrDefault401) Error() string {
|
||||||
return "Authentication failed"
|
return "Authentication failed"
|
||||||
|
@ -417,3 +451,10 @@ type ErrScopeEmpty struct{ BaseError }
|
||||||
func (e ErrScopeEmpty) Error() string {
|
func (e ErrScopeEmpty) Error() string {
|
||||||
return "You must provide either a Project or Domain in a Scope"
|
return "You must provide either a Project or Domain in a Scope"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrAppCredMissingSecret indicates that no Application Credential Secret was provided with Application Credential ID or Name
|
||||||
|
type ErrAppCredMissingSecret struct{ BaseError }
|
||||||
|
|
||||||
|
func (e ErrAppCredMissingSecret) Error() string {
|
||||||
|
return "You must provide an Application Credential Secret"
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,9 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
||||||
tenantName := os.Getenv("OS_TENANT_NAME")
|
tenantName := os.Getenv("OS_TENANT_NAME")
|
||||||
domainID := os.Getenv("OS_DOMAIN_ID")
|
domainID := os.Getenv("OS_DOMAIN_ID")
|
||||||
domainName := os.Getenv("OS_DOMAIN_NAME")
|
domainName := os.Getenv("OS_DOMAIN_NAME")
|
||||||
|
applicationCredentialID := os.Getenv("OS_APPLICATION_CREDENTIAL_ID")
|
||||||
|
applicationCredentialName := os.Getenv("OS_APPLICATION_CREDENTIAL_NAME")
|
||||||
|
applicationCredentialSecret := os.Getenv("OS_APPLICATION_CREDENTIAL_SECRET")
|
||||||
|
|
||||||
// If OS_PROJECT_ID is set, overwrite tenantID with the value.
|
// If OS_PROJECT_ID is set, overwrite tenantID with the value.
|
||||||
if v := os.Getenv("OS_PROJECT_ID"); v != "" {
|
if v := os.Getenv("OS_PROJECT_ID"); v != "" {
|
||||||
|
@ -50,29 +53,61 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if authURL == "" {
|
if authURL == "" {
|
||||||
err := gophercloud.ErrMissingInput{Argument: "authURL"}
|
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||||
|
EnvironmentVariable: "OS_AUTH_URL",
|
||||||
|
}
|
||||||
return nilOptions, err
|
return nilOptions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if username == "" && userID == "" {
|
if userID == "" && username == "" {
|
||||||
err := gophercloud.ErrMissingInput{Argument: "username"}
|
// Empty username and userID could be ignored, when applicationCredentialID and applicationCredentialSecret are set
|
||||||
|
if applicationCredentialID == "" && applicationCredentialSecret == "" {
|
||||||
|
err := gophercloud.ErrMissingAnyoneOfEnvironmentVariables{
|
||||||
|
EnvironmentVariables: []string{"OS_USERID", "OS_USERNAME"},
|
||||||
|
}
|
||||||
|
return nilOptions, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if password == "" && applicationCredentialID == "" && applicationCredentialName == "" {
|
||||||
|
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||||
|
EnvironmentVariable: "OS_PASSWORD",
|
||||||
|
}
|
||||||
return nilOptions, err
|
return nilOptions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if password == "" {
|
if (applicationCredentialID != "" || applicationCredentialName != "") && applicationCredentialSecret == "" {
|
||||||
err := gophercloud.ErrMissingInput{Argument: "password"}
|
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||||
|
EnvironmentVariable: "OS_APPLICATION_CREDENTIAL_SECRET",
|
||||||
|
}
|
||||||
return nilOptions, err
|
return nilOptions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if applicationCredentialID == "" && applicationCredentialName != "" && applicationCredentialSecret != "" {
|
||||||
|
if userID == "" && username == "" {
|
||||||
|
return nilOptions, gophercloud.ErrMissingAnyoneOfEnvironmentVariables{
|
||||||
|
EnvironmentVariables: []string{"OS_USERID", "OS_USERNAME"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if username != "" && domainID == "" && domainName == "" {
|
||||||
|
return nilOptions, gophercloud.ErrMissingAnyoneOfEnvironmentVariables{
|
||||||
|
EnvironmentVariables: []string{"OS_DOMAIN_ID", "OS_DOMAIN_NAME"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ao := gophercloud.AuthOptions{
|
ao := gophercloud.AuthOptions{
|
||||||
IdentityEndpoint: authURL,
|
IdentityEndpoint: authURL,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
Username: username,
|
Username: username,
|
||||||
Password: password,
|
Password: password,
|
||||||
TenantID: tenantID,
|
TenantID: tenantID,
|
||||||
TenantName: tenantName,
|
TenantName: tenantName,
|
||||||
DomainID: domainID,
|
DomainID: domainID,
|
||||||
DomainName: domainName,
|
DomainName: domainName,
|
||||||
|
ApplicationCredentialID: applicationCredentialID,
|
||||||
|
ApplicationCredentialName: applicationCredentialName,
|
||||||
|
ApplicationCredentialSecret: applicationCredentialSecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ao, nil
|
return ao, nil
|
||||||
|
|
11
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go
generated
vendored
11
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go
generated
vendored
|
@ -110,8 +110,8 @@ type UpdateOptsBuilder interface {
|
||||||
// to the volumes.Update function. For more information about the parameters, see
|
// to the volumes.Update function. For more information about the parameters, see
|
||||||
// the Volume object.
|
// the Volume object.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
Name string `json:"display_name,omitempty"`
|
Name *string `json:"display_name,omitempty"`
|
||||||
Description string `json:"display_description,omitempty"`
|
Description *string `json:"display_description,omitempty"`
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,12 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
pages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
58
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go
generated
vendored
58
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go
generated
vendored
|
@ -61,9 +61,37 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Delete request.
|
||||||
|
type DeleteOptsBuilder interface {
|
||||||
|
ToVolumeDeleteQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOpts contains options for deleting a Volume. This object is passed to
|
||||||
|
// the volumes.Delete function.
|
||||||
|
type DeleteOpts struct {
|
||||||
|
// Delete all snapshots of this volume as well.
|
||||||
|
Cascade bool `q:"cascade"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToLoadBalancerDeleteQuery formats a DeleteOpts into a query string.
|
||||||
|
func (opts DeleteOpts) ToVolumeDeleteQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
// Delete will delete the existing Volume with the provided ID.
|
// Delete will delete the existing Volume with the provided ID.
|
||||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
func Delete(client *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
url := deleteURL(client, id)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToVolumeDeleteQuery()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
_, r.Err = client.Delete(url, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +126,19 @@ type ListOpts struct {
|
||||||
// TenantID will filter by a specific tenant/project ID.
|
// TenantID will filter by a specific tenant/project ID.
|
||||||
// Setting AllTenants is required for this.
|
// Setting AllTenants is required for this.
|
||||||
TenantID string `q:"project_id"`
|
TenantID string `q:"project_id"`
|
||||||
|
|
||||||
|
// Comma-separated list of sort keys and optional sort directions in the
|
||||||
|
// form of <key>[:<direction>].
|
||||||
|
Sort string `q:"sort"`
|
||||||
|
|
||||||
|
// Requests a page size of items.
|
||||||
|
Limit int `q:"limit"`
|
||||||
|
|
||||||
|
// Used in conjunction with limit to return a slice of items.
|
||||||
|
Offset int `q:"offset"`
|
||||||
|
|
||||||
|
// The ID of the last-seen item.
|
||||||
|
Marker string `q:"marker"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToVolumeListQuery formats a ListOpts into a query string.
|
// ToVolumeListQuery formats a ListOpts into a query string.
|
||||||
|
@ -118,7 +159,7 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa
|
||||||
}
|
}
|
||||||
|
|
||||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
return VolumePage{pagination.SinglePageBase(r)}
|
return VolumePage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +173,8 @@ type UpdateOptsBuilder interface {
|
||||||
// to the volumes.Update function. For more information about the parameters, see
|
// to the volumes.Update function. For more information about the parameters, see
|
||||||
// the Volume object.
|
// the Volume object.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +202,12 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
pages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
15
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go
generated
vendored
15
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go
generated
vendored
|
@ -98,7 +98,7 @@ func (r *Volume) UnmarshalJSON(b []byte) error {
|
||||||
|
|
||||||
// VolumePage is a pagination.pager that is returned from a call to the List function.
|
// VolumePage is a pagination.pager that is returned from a call to the List function.
|
||||||
type VolumePage struct {
|
type VolumePage struct {
|
||||||
pagination.SinglePageBase
|
pagination.LinkedPageBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty returns true if a ListResult contains no Volumes.
|
// IsEmpty returns true if a ListResult contains no Volumes.
|
||||||
|
@ -107,6 +107,19 @@ func (r VolumePage) IsEmpty() (bool, error) {
|
||||||
return len(volumes) == 0, err
|
return len(volumes) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextPageURL uses the response's embedded link reference to navigate to the
|
||||||
|
// next page of results.
|
||||||
|
func (r VolumePage) NextPageURL() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Links []gophercloud.Link `json:"volumes_links"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return gophercloud.ExtractNextURL(s.Links)
|
||||||
|
}
|
||||||
|
|
||||||
// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call.
|
// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call.
|
||||||
func ExtractVolumes(r pagination.Page) ([]Volume, error) {
|
func ExtractVolumes(r pagination.Page) ([]Volume, error) {
|
||||||
var s []Volume
|
var s []Volume
|
||||||
|
|
45
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go
generated
vendored
45
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go
generated
vendored
|
@ -38,6 +38,8 @@ type CreateOpts struct {
|
||||||
ImageID string `json:"imageRef,omitempty"`
|
ImageID string `json:"imageRef,omitempty"`
|
||||||
// The associated volume type
|
// The associated volume type
|
||||||
VolumeType string `json:"volume_type,omitempty"`
|
VolumeType string `json:"volume_type,omitempty"`
|
||||||
|
// Multiattach denotes if the volume is multi-attach capable.
|
||||||
|
Multiattach bool `json:"multiattach,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToVolumeCreateMap assembles a request body based on the contents of a
|
// ToVolumeCreateMap assembles a request body based on the contents of a
|
||||||
|
@ -61,9 +63,37 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Delete request.
|
||||||
|
type DeleteOptsBuilder interface {
|
||||||
|
ToVolumeDeleteQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOpts contains options for deleting a Volume. This object is passed to
|
||||||
|
// the volumes.Delete function.
|
||||||
|
type DeleteOpts struct {
|
||||||
|
// Delete all snapshots of this volume as well.
|
||||||
|
Cascade bool `q:"cascade"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToLoadBalancerDeleteQuery formats a DeleteOpts into a query string.
|
||||||
|
func (opts DeleteOpts) ToVolumeDeleteQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
// Delete will delete the existing Volume with the provided ID.
|
// Delete will delete the existing Volume with the provided ID.
|
||||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
func Delete(client *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
url := deleteURL(client, id)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToVolumeDeleteQuery()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
_, r.Err = client.Delete(url, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +175,8 @@ type UpdateOptsBuilder interface {
|
||||||
// to the volumes.Update function. For more information about the parameters, see
|
// to the volumes.Update function. For more information about the parameters, see
|
||||||
// the Volume object.
|
// the Volume object.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +204,12 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
pages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,7 @@ package openstack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
||||||
|
@ -38,21 +35,11 @@ A basic example of using this would be:
|
||||||
client, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{})
|
client, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{})
|
||||||
*/
|
*/
|
||||||
func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
|
func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
|
||||||
u, err := url.Parse(endpoint)
|
base, err := utils.BaseEndpoint(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
u.RawQuery, u.Fragment = "", ""
|
|
||||||
|
|
||||||
var base string
|
|
||||||
versionRe := regexp.MustCompile("v[0-9.]+/?")
|
|
||||||
if version := versionRe.FindString(u.Path); version != "" {
|
|
||||||
base = strings.Replace(u.String(), version, "", -1)
|
|
||||||
} else {
|
|
||||||
base = u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
endpoint = gophercloud.NormalizeURL(endpoint)
|
endpoint = gophercloud.NormalizeURL(endpoint)
|
||||||
base = gophercloud.NormalizeURL(base)
|
base = gophercloud.NormalizeURL(base)
|
||||||
|
|
||||||
|
@ -163,6 +150,7 @@ func v2auth(client *gophercloud.ProviderClient, endpoint string, options gopherc
|
||||||
// with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`,
|
// with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`,
|
||||||
// this should retry authentication only once
|
// this should retry authentication only once
|
||||||
tac := *client
|
tac := *client
|
||||||
|
tac.IsThrowaway = true
|
||||||
tac.ReauthFunc = nil
|
tac.ReauthFunc = nil
|
||||||
tac.TokenID = ""
|
tac.TokenID = ""
|
||||||
tao := options
|
tao := options
|
||||||
|
@ -219,6 +207,7 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
|
||||||
// with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`,
|
// with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`,
|
||||||
// this should retry authentication only once
|
// this should retry authentication only once
|
||||||
tac := *client
|
tac := *client
|
||||||
|
tac.IsThrowaway = true
|
||||||
tac.ReauthFunc = nil
|
tac.ReauthFunc = nil
|
||||||
tac.TokenID = ""
|
tac.TokenID = ""
|
||||||
var tao tokens3.AuthOptionsBuilder
|
var tao tokens3.AuthOptionsBuilder
|
||||||
|
@ -287,11 +276,17 @@ func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOp
|
||||||
|
|
||||||
// Ensure endpoint still has a suffix of v3.
|
// Ensure endpoint still has a suffix of v3.
|
||||||
// This is because EndpointLocator might have found a versionless
|
// This is because EndpointLocator might have found a versionless
|
||||||
// endpoint and requests will fail unless targeted at /v3.
|
// endpoint or the published endpoint is still /v2.0. In both
|
||||||
if !strings.HasSuffix(endpoint, "v3/") {
|
// cases, we need to fix the endpoint to point to /v3.
|
||||||
endpoint = endpoint + "v3/"
|
base, err := utils.BaseEndpoint(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base = gophercloud.NormalizeURL(base)
|
||||||
|
|
||||||
|
endpoint = base + "v3/"
|
||||||
|
|
||||||
return &gophercloud.ServiceClient{
|
return &gophercloud.ServiceClient{
|
||||||
ProviderClient: client,
|
ProviderClient: client,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
|
@ -400,3 +395,35 @@ func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.Endpoi
|
||||||
func NewClusteringV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
func NewClusteringV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
return initClientOpts(client, eo, "clustering")
|
return initClientOpts(client, eo, "clustering")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewMessagingV2 creates a ServiceClient that may be used with the v2 messaging
|
||||||
|
// service.
|
||||||
|
func NewMessagingV2(client *gophercloud.ProviderClient, clientID string, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
|
sc, err := initClientOpts(client, eo, "messaging")
|
||||||
|
sc.MoreHeaders = map[string]string{"Client-ID": clientID}
|
||||||
|
return sc, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContainerV1 creates a ServiceClient that may be used with v1 container package
|
||||||
|
func NewContainerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
|
return initClientOpts(client, eo, "container")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyManagerV1 creates a ServiceClient that may be used with the v1 key
|
||||||
|
// manager service.
|
||||||
|
func NewKeyManagerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
|
sc, err := initClientOpts(client, eo, "key-manager")
|
||||||
|
sc.ResourceBase = sc.Endpoint + "v1/"
|
||||||
|
return sc, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContainerInfraV1 creates a ServiceClient that may be used with the v1 container infra management
|
||||||
|
// package.
|
||||||
|
func NewContainerInfraV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
|
return initClientOpts(client, eo, "container-infra")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWorkflowV2 creates a ServiceClient that may be used with the v2 workflow management package.
|
||||||
|
func NewWorkflowV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
|
return initClientOpts(client, eo, "workflowv2")
|
||||||
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ type CreateOptsBuilder interface {
|
||||||
|
|
||||||
// CreateOpts specifies parameters of a new interface attachment.
|
// CreateOpts specifies parameters of a new interface attachment.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
|
|
||||||
// PortID is the ID of the port for which you want to create an interface.
|
// PortID is the ID of the port for which you want to create an interface.
|
||||||
// The NetworkID and PortID parameters are mutually exclusive.
|
// The NetworkID and PortID parameters are mutually exclusive.
|
||||||
// If you do not specify the PortID parameter, the OpenStack Networking API
|
// If you do not specify the PortID parameter, the OpenStack Networking API
|
||||||
|
@ -43,6 +42,7 @@ type CreateOpts struct {
|
||||||
|
|
||||||
// Slice of FixedIPs. If you request a specific FixedIP address without a
|
// Slice of FixedIPs. If you request a specific FixedIP address without a
|
||||||
// NetworkID, the request returns a Bad Request (400) response code.
|
// NetworkID, the request returns a Bad Request (400) response code.
|
||||||
|
// Note: this uses the FixedIP struct, but only the IPAddress field can be used.
|
||||||
FixedIPs []FixedIP `json:"fixed_ips,omitempty"`
|
FixedIPs []FixedIP `json:"fixed_ips,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,10 @@ type DeleteResult struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FixedIP represents a Fixed IP Address.
|
// FixedIP represents a Fixed IP Address.
|
||||||
|
// This struct is also used when creating an attachment,
|
||||||
|
// but it is not possible to specify a SubnetID.
|
||||||
type FixedIP struct {
|
type FixedIP struct {
|
||||||
SubnetID string `json:"subnet_id"`
|
SubnetID string `json:"subnet_id,omitempty"`
|
||||||
IPAddress string `json:"ip_address"`
|
IPAddress string `json:"ip_address"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
generated
vendored
8
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
generated
vendored
|
@ -52,6 +52,14 @@ type ListOpts struct {
|
||||||
MinDisk int `q:"minDisk"`
|
MinDisk int `q:"minDisk"`
|
||||||
MinRAM int `q:"minRam"`
|
MinRAM int `q:"minRam"`
|
||||||
|
|
||||||
|
// SortDir allows to select sort direction.
|
||||||
|
// It can be "asc" or "desc" (default).
|
||||||
|
SortDir string `q:"sort_dir"`
|
||||||
|
|
||||||
|
// SortKey allows to sort by one of the flavors attributes.
|
||||||
|
// Default is flavorid.
|
||||||
|
SortKey string `q:"sort_key"`
|
||||||
|
|
||||||
// Marker and Limit control paging.
|
// Marker and Limit control paging.
|
||||||
// Marker instructs List where to start listing from.
|
// Marker instructs List where to start listing from.
|
||||||
Marker string `q:"marker"`
|
Marker string `q:"marker"`
|
||||||
|
|
2
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go
generated
vendored
2
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go
generated
vendored
|
@ -59,7 +59,7 @@ type Flavor struct {
|
||||||
RxTxFactor float64 `json:"rxtx_factor"`
|
RxTxFactor float64 `json:"rxtx_factor"`
|
||||||
|
|
||||||
// Swap is the amount of swap space, measured in MB.
|
// Swap is the amount of swap space, measured in MB.
|
||||||
Swap int `json:"swap"`
|
Swap int `json:"-"`
|
||||||
|
|
||||||
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
|
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
|
||||||
VCPUs int `json:"vcpus"`
|
VCPUs int `json:"vcpus"`
|
||||||
|
|
73
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
generated
vendored
73
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
generated
vendored
|
@ -383,7 +383,7 @@ type RebootOpts struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToServerRebootMap builds a body for the reboot request.
|
// ToServerRebootMap builds a body for the reboot request.
|
||||||
func (opts *RebootOpts) ToServerRebootMap() (map[string]interface{}, error) {
|
func (opts RebootOpts) ToServerRebootMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "reboot")
|
return gophercloud.BuildRequestBody(opts, "reboot")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,39 +545,6 @@ func RevertResize(client *gophercloud.ServiceClient, id string) (r ActionResult)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RescueOptsBuilder is an interface that allows extensions to override the
|
|
||||||
// default structure of a Rescue request.
|
|
||||||
type RescueOptsBuilder interface {
|
|
||||||
ToServerRescueMap() (map[string]interface{}, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RescueOpts represents the configuration options used to control a Rescue
|
|
||||||
// option.
|
|
||||||
type RescueOpts struct {
|
|
||||||
// AdminPass is the desired administrative password for the instance in
|
|
||||||
// RESCUE mode. If it's left blank, the server will generate a password.
|
|
||||||
AdminPass string `json:"adminPass,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToServerRescueMap formats a RescueOpts as a map that can be used as a JSON
|
|
||||||
// request body for the Rescue request.
|
|
||||||
func (opts RescueOpts) ToServerRescueMap() (map[string]interface{}, error) {
|
|
||||||
return gophercloud.BuildRequestBody(opts, "rescue")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rescue instructs the provider to place the server into RESCUE mode.
|
|
||||||
func Rescue(client *gophercloud.ServiceClient, id string, opts RescueOptsBuilder) (r RescueResult) {
|
|
||||||
b, err := opts.ToServerRescueMap()
|
|
||||||
if err != nil {
|
|
||||||
r.Err = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
|
||||||
OkCodes: []int{200},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResetMetadataOptsBuilder allows extensions to add additional parameters to
|
// ResetMetadataOptsBuilder allows extensions to add additional parameters to
|
||||||
// the Reset request.
|
// the Reset request.
|
||||||
type ResetMetadataOptsBuilder interface {
|
type ResetMetadataOptsBuilder interface {
|
||||||
|
@ -756,7 +723,12 @@ func CreateImage(client *gophercloud.ServiceClient, id string, opts CreateImageO
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
allPages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -789,3 +761,34 @@ func GetPassword(client *gophercloud.ServiceClient, serverId string) (r GetPassw
|
||||||
_, r.Err = client.Get(passwordURL(client, serverId), &r.Body, nil)
|
_, r.Err = client.Get(passwordURL(client, serverId), &r.Body, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShowConsoleOutputOptsBuilder is the interface types must satisfy in order to be
|
||||||
|
// used as ShowConsoleOutput options
|
||||||
|
type ShowConsoleOutputOptsBuilder interface {
|
||||||
|
ToServerShowConsoleOutputMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShowConsoleOutputOpts satisfies the ShowConsoleOutputOptsBuilder
|
||||||
|
type ShowConsoleOutputOpts struct {
|
||||||
|
// The number of lines to fetch from the end of console log.
|
||||||
|
// All lines will be returned if this is not specified.
|
||||||
|
Length int `json:"length,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToServerShowConsoleOutputMap formats a ShowConsoleOutputOpts structure into a request body.
|
||||||
|
func (opts ShowConsoleOutputOpts) ToServerShowConsoleOutputMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "os-getConsoleOutput")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShowConsoleOutput makes a request against the nova API to get console log from the server
|
||||||
|
func ShowConsoleOutput(client *gophercloud.ServiceClient, id string, opts ShowConsoleOutputOptsBuilder) (r ShowConsoleOutputResult) {
|
||||||
|
b, err := opts.ToServerShowConsoleOutputMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
30
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
generated
vendored
30
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
generated
vendored
|
@ -68,18 +68,27 @@ type ActionResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// RescueResult is the response from a Rescue operation. Call its ExtractErr
|
|
||||||
// method to determine if the call succeeded or failed.
|
|
||||||
type RescueResult struct {
|
|
||||||
ActionResult
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateImageResult is the response from a CreateImage operation. Call its
|
// CreateImageResult is the response from a CreateImage operation. Call its
|
||||||
// ExtractImageID method to retrieve the ID of the newly created image.
|
// ExtractImageID method to retrieve the ID of the newly created image.
|
||||||
type CreateImageResult struct {
|
type CreateImageResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShowConsoleOutputResult represents the result of console output from a server
|
||||||
|
type ShowConsoleOutputResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract will return the console output from a ShowConsoleOutput request.
|
||||||
|
func (r ShowConsoleOutputResult) Extract() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Output string `json:"output"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.Output, err
|
||||||
|
}
|
||||||
|
|
||||||
// GetPasswordResult represent the result of a get os-server-password operation.
|
// GetPasswordResult represent the result of a get os-server-password operation.
|
||||||
// Call its ExtractPassword method to retrieve the password.
|
// Call its ExtractPassword method to retrieve the password.
|
||||||
type GetPasswordResult struct {
|
type GetPasswordResult struct {
|
||||||
|
@ -134,15 +143,6 @@ func (r CreateImageResult) ExtractImageID() (string, error) {
|
||||||
return imageID, nil
|
return imageID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract interprets any RescueResult as an AdminPass, if possible.
|
|
||||||
func (r RescueResult) Extract() (string, error) {
|
|
||||||
var s struct {
|
|
||||||
AdminPass string `json:"adminPass"`
|
|
||||||
}
|
|
||||||
err := r.ExtractInto(&s)
|
|
||||||
return s.AdminPass, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server represents a server/instance in the OpenStack cloud.
|
// Server represents a server/instance in the OpenStack cloud.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
// ID uniquely identifies this server amongst all other servers,
|
// ID uniquely identifies this server amongst all other servers,
|
||||||
|
|
2
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
generated
vendored
2
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
generated
vendored
|
@ -85,7 +85,7 @@ type UpdateOpts struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
|
||||||
// Description is the description of the tenant.
|
// Description is the description of the tenant.
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
|
|
||||||
// Enabled sets the tenant status to enabled or disabled.
|
// Enabled sets the tenant status to enabled or disabled.
|
||||||
Enabled *bool `json:"enabled,omitempty"`
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
|
94
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
generated
vendored
94
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
generated
vendored
|
@ -52,19 +52,28 @@ type AuthOptions struct {
|
||||||
// authentication token ID.
|
// authentication token ID.
|
||||||
TokenID string `json:"-"`
|
TokenID string `json:"-"`
|
||||||
|
|
||||||
|
// Authentication through Application Credentials requires supplying name, project and secret
|
||||||
|
// For project we can use TenantID
|
||||||
|
ApplicationCredentialID string `json:"-"`
|
||||||
|
ApplicationCredentialName string `json:"-"`
|
||||||
|
ApplicationCredentialSecret string `json:"-"`
|
||||||
|
|
||||||
Scope Scope `json:"-"`
|
Scope Scope `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToTokenV3CreateMap builds a request body from AuthOptions.
|
// ToTokenV3CreateMap builds a request body from AuthOptions.
|
||||||
func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
|
func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
|
||||||
gophercloudAuthOpts := gophercloud.AuthOptions{
|
gophercloudAuthOpts := gophercloud.AuthOptions{
|
||||||
Username: opts.Username,
|
Username: opts.Username,
|
||||||
UserID: opts.UserID,
|
UserID: opts.UserID,
|
||||||
Password: opts.Password,
|
Password: opts.Password,
|
||||||
DomainID: opts.DomainID,
|
DomainID: opts.DomainID,
|
||||||
DomainName: opts.DomainName,
|
DomainName: opts.DomainName,
|
||||||
AllowReauth: opts.AllowReauth,
|
AllowReauth: opts.AllowReauth,
|
||||||
TokenID: opts.TokenID,
|
TokenID: opts.TokenID,
|
||||||
|
ApplicationCredentialID: opts.ApplicationCredentialID,
|
||||||
|
ApplicationCredentialName: opts.ApplicationCredentialName,
|
||||||
|
ApplicationCredentialSecret: opts.ApplicationCredentialSecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
return gophercloudAuthOpts.ToTokenV3CreateMap(scope)
|
return gophercloudAuthOpts.ToTokenV3CreateMap(scope)
|
||||||
|
@ -72,72 +81,15 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
|
|
||||||
// ToTokenV3CreateMap builds a scope request body from AuthOptions.
|
// ToTokenV3CreateMap builds a scope request body from AuthOptions.
|
||||||
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||||
if opts.Scope.ProjectName != "" {
|
scope := gophercloud.AuthScope(opts.Scope)
|
||||||
// ProjectName provided: either DomainID or DomainName must also be supplied.
|
|
||||||
// ProjectID may not be supplied.
|
|
||||||
if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" {
|
|
||||||
return nil, gophercloud.ErrScopeDomainIDOrDomainName{}
|
|
||||||
}
|
|
||||||
if opts.Scope.ProjectID != "" {
|
|
||||||
return nil, gophercloud.ErrScopeProjectIDOrProjectName{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Scope.DomainID != "" {
|
gophercloudAuthOpts := gophercloud.AuthOptions{
|
||||||
// ProjectName + DomainID
|
Scope: &scope,
|
||||||
return map[string]interface{}{
|
DomainID: opts.DomainID,
|
||||||
"project": map[string]interface{}{
|
DomainName: opts.DomainName,
|
||||||
"name": &opts.Scope.ProjectName,
|
|
||||||
"domain": map[string]interface{}{"id": &opts.Scope.DomainID},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Scope.DomainName != "" {
|
|
||||||
// ProjectName + DomainName
|
|
||||||
return map[string]interface{}{
|
|
||||||
"project": map[string]interface{}{
|
|
||||||
"name": &opts.Scope.ProjectName,
|
|
||||||
"domain": map[string]interface{}{"name": &opts.Scope.DomainName},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
} else if opts.Scope.ProjectID != "" {
|
|
||||||
// ProjectID provided. ProjectName, DomainID, and DomainName may not be provided.
|
|
||||||
if opts.Scope.DomainID != "" {
|
|
||||||
return nil, gophercloud.ErrScopeProjectIDAlone{}
|
|
||||||
}
|
|
||||||
if opts.Scope.DomainName != "" {
|
|
||||||
return nil, gophercloud.ErrScopeProjectIDAlone{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectID
|
|
||||||
return map[string]interface{}{
|
|
||||||
"project": map[string]interface{}{
|
|
||||||
"id": &opts.Scope.ProjectID,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
} else if opts.Scope.DomainID != "" {
|
|
||||||
// DomainID provided. ProjectID, ProjectName, and DomainName may not be provided.
|
|
||||||
if opts.Scope.DomainName != "" {
|
|
||||||
return nil, gophercloud.ErrScopeDomainIDOrDomainName{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DomainID
|
|
||||||
return map[string]interface{}{
|
|
||||||
"domain": map[string]interface{}{
|
|
||||||
"id": &opts.Scope.DomainID,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
} else if opts.Scope.DomainName != "" {
|
|
||||||
// DomainName
|
|
||||||
return map[string]interface{}{
|
|
||||||
"domain": map[string]interface{}{
|
|
||||||
"name": &opts.Scope.DomainName,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return gophercloudAuthOpts.ToTokenV3ScopeMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opts *AuthOptions) CanReauth() bool {
|
func (opts *AuthOptions) CanReauth() bool {
|
||||||
|
@ -190,7 +142,7 @@ func Get(c *gophercloud.ServiceClient, token string) (r GetResult) {
|
||||||
|
|
||||||
// Validate determines if a specified token is valid or not.
|
// Validate determines if a specified token is valid or not.
|
||||||
func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
|
func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
|
||||||
resp, err := c.Request("HEAD", tokenURL(c), &gophercloud.RequestOpts{
|
resp, err := c.Head(tokenURL(c), &gophercloud.RequestOpts{
|
||||||
MoreHeaders: subjectTokenHeaders(c, token),
|
MoreHeaders: subjectTokenHeaders(c, token),
|
||||||
OkCodes: []int{200, 204, 404},
|
OkCodes: []int{200, 204, 404},
|
||||||
})
|
})
|
||||||
|
|
1
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/BUILD
generated
vendored
1
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/BUILD
generated
vendored
|
@ -27,6 +27,7 @@ filegroup(
|
||||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external:all-srcs",
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external:all-srcs",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips:all-srcs",
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips:all-srcs",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers:all-srcs",
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers:all-srcs",
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies:all-srcs",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners:all-srcs",
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners:all-srcs",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers:all-srcs",
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers:all-srcs",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors:all-srcs",
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors:all-srcs",
|
||||||
|
|
|
@ -10,7 +10,10 @@ go_library(
|
||||||
importmap = "k8s.io/kubernetes/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external",
|
importmap = "k8s.io/kubernetes/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external",
|
||||||
importpath = "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external",
|
importpath = "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = ["//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks:go_default_library"],
|
deps = [
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
|
|
@ -4,6 +4,13 @@ extension for the OpenStack Networking service.
|
||||||
|
|
||||||
Example to List Networks with External Information
|
Example to List Networks with External Information
|
||||||
|
|
||||||
|
iTrue := true
|
||||||
|
networkListOpts := networks.ListOpts{}
|
||||||
|
listOpts := external.ListOptsExt{
|
||||||
|
ListOptsBuilder: networkListOpts,
|
||||||
|
External: &iTrue,
|
||||||
|
}
|
||||||
|
|
||||||
type NetworkWithExternalExt struct {
|
type NetworkWithExternalExt struct {
|
||||||
networks.Network
|
networks.Network
|
||||||
external.NetworkExternalExt
|
external.NetworkExternalExt
|
||||||
|
@ -11,7 +18,7 @@ Example to List Networks with External Information
|
||||||
|
|
||||||
var allNetworks []NetworkWithExternalExt
|
var allNetworks []NetworkWithExternalExt
|
||||||
|
|
||||||
allPages, err := networks.List(networkClient, nil).AllPages()
|
allPages, err := networks.List(networkClient, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,37 @@
|
||||||
package external
|
package external
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
|
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ListOptsExt adds the external network options to the base ListOpts.
|
||||||
|
type ListOptsExt struct {
|
||||||
|
networks.ListOptsBuilder
|
||||||
|
External *bool `q:"router:external"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToNetworkListQuery adds the router:external option to the base network
|
||||||
|
// list options.
|
||||||
|
func (opts ListOptsExt) ToNetworkListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts.ListOptsBuilder)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
params := q.Query()
|
||||||
|
if opts.External != nil {
|
||||||
|
v := strconv.FormatBool(*opts.External)
|
||||||
|
params.Add("router:external", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
q = &url.URL{RawQuery: params.Encode()}
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
// CreateOptsExt is the structure used when creating new external network
|
// CreateOptsExt is the structure used when creating new external network
|
||||||
// resources. It embeds networks.CreateOpts and so inherits all of its required
|
// resources. It embeds networks.CreateOpts and so inherits all of its required
|
||||||
// and optional fields, with the addition of the External field.
|
// and optional fields, with the addition of the External field.
|
||||||
|
|
|
@ -52,7 +52,7 @@ Example to Disassociate a Floating IP with a Port
|
||||||
fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
|
fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
|
||||||
|
|
||||||
updateOpts := floatingips.UpdateOpts{
|
updateOpts := floatingips.UpdateOpts{
|
||||||
PortID: nil,
|
PortID: new(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract()
|
fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract()
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
// either `asc' or `desc'. Marker and Limit are used for pagination.
|
// either `asc' or `desc'. Marker and Limit are used for pagination.
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
ID string `q:"id"`
|
ID string `q:"id"`
|
||||||
|
Description string `q:"description"`
|
||||||
FloatingNetworkID string `q:"floating_network_id"`
|
FloatingNetworkID string `q:"floating_network_id"`
|
||||||
PortID string `q:"port_id"`
|
PortID string `q:"port_id"`
|
||||||
FixedIP string `q:"fixed_ip_address"`
|
FixedIP string `q:"fixed_ip_address"`
|
||||||
|
@ -24,6 +25,10 @@ type ListOpts struct {
|
||||||
SortDir string `q:"sort_dir"`
|
SortDir string `q:"sort_dir"`
|
||||||
RouterID string `q:"router_id"`
|
RouterID string `q:"router_id"`
|
||||||
Status string `q:"status"`
|
Status string `q:"status"`
|
||||||
|
Tags string `q:"tags"`
|
||||||
|
TagsAny string `q:"tags-any"`
|
||||||
|
NotTags string `q:"not-tags"`
|
||||||
|
NotTagsAny string `q:"not-tags-any"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a Pager which allows you to iterate over a collection of
|
// List returns a Pager which allows you to iterate over a collection of
|
||||||
|
@ -50,6 +55,7 @@ type CreateOptsBuilder interface {
|
||||||
// resource. The only required fields are FloatingNetworkID and PortID which
|
// resource. The only required fields are FloatingNetworkID and PortID which
|
||||||
// refer to the external network and internal port respectively.
|
// refer to the external network and internal port respectively.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
FloatingNetworkID string `json:"floating_network_id" required:"true"`
|
FloatingNetworkID string `json:"floating_network_id" required:"true"`
|
||||||
FloatingIP string `json:"floating_ip_address,omitempty"`
|
FloatingIP string `json:"floating_ip_address,omitempty"`
|
||||||
PortID string `json:"port_id,omitempty"`
|
PortID string `json:"port_id,omitempty"`
|
||||||
|
@ -116,13 +122,23 @@ type UpdateOptsBuilder interface {
|
||||||
// linked to. To associate the floating IP with a new internal port, provide its
|
// linked to. To associate the floating IP with a new internal port, provide its
|
||||||
// ID. To disassociate the floating IP from all ports, provide an empty string.
|
// ID. To disassociate the floating IP from all ports, provide an empty string.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
PortID *string `json:"port_id"`
|
Description *string `json:"description,omitempty"`
|
||||||
|
PortID *string `json:"port_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToFloatingIPUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder
|
// ToFloatingIPUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder
|
||||||
// interface
|
// interface
|
||||||
func (opts UpdateOpts) ToFloatingIPUpdateMap() (map[string]interface{}, error) {
|
func (opts UpdateOpts) ToFloatingIPUpdateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "floatingip")
|
b, err := gophercloud.BuildRequestBody(opts, "floatingip")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m := b["floatingip"].(map[string]interface{}); m["port_id"] == "" {
|
||||||
|
m["port_id"] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update allows floating IP resources to be updated. Currently, the only way to
|
// Update allows floating IP resources to be updated. Currently, the only way to
|
||||||
|
|
|
@ -15,6 +15,9 @@ type FloatingIP struct {
|
||||||
// ID is the unique identifier for the floating IP instance.
|
// ID is the unique identifier for the floating IP instance.
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// Description for the floating IP instance.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
// FloatingNetworkID is the UUID of the external network where the floating
|
// FloatingNetworkID is the UUID of the external network where the floating
|
||||||
// IP is to be created.
|
// IP is to be created.
|
||||||
FloatingNetworkID string `json:"floating_network_id"`
|
FloatingNetworkID string `json:"floating_network_id"`
|
||||||
|
@ -42,6 +45,9 @@ type FloatingIP struct {
|
||||||
|
|
||||||
// RouterID is the ID of the router used for this floating IP.
|
// RouterID is the ID of the router used for this floating IP.
|
||||||
RouterID string `json:"router_id"`
|
RouterID string `json:"router_id"`
|
||||||
|
|
||||||
|
// Tags optionally set via extensions/attributestags
|
||||||
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type commonResult struct {
|
type commonResult struct {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
ID string `q:"id"`
|
ID string `q:"id"`
|
||||||
Name string `q:"name"`
|
Name string `q:"name"`
|
||||||
|
Description string `q:"description"`
|
||||||
AdminStateUp *bool `q:"admin_state_up"`
|
AdminStateUp *bool `q:"admin_state_up"`
|
||||||
Distributed *bool `q:"distributed"`
|
Distributed *bool `q:"distributed"`
|
||||||
Status string `q:"status"`
|
Status string `q:"status"`
|
||||||
|
@ -22,6 +23,10 @@ type ListOpts struct {
|
||||||
Marker string `q:"marker"`
|
Marker string `q:"marker"`
|
||||||
SortKey string `q:"sort_key"`
|
SortKey string `q:"sort_key"`
|
||||||
SortDir string `q:"sort_dir"`
|
SortDir string `q:"sort_dir"`
|
||||||
|
Tags string `q:"tags"`
|
||||||
|
TagsAny string `q:"tags-any"`
|
||||||
|
NotTags string `q:"not-tags"`
|
||||||
|
NotTagsAny string `q:"not-tags-any"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a Pager which allows you to iterate over a collection of
|
// List returns a Pager which allows you to iterate over a collection of
|
||||||
|
@ -51,6 +56,7 @@ type CreateOptsBuilder interface {
|
||||||
// no required values.
|
// no required values.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
Distributed *bool `json:"distributed,omitempty"`
|
Distributed *bool `json:"distributed,omitempty"`
|
||||||
TenantID string `json:"tenant_id,omitempty"`
|
TenantID string `json:"tenant_id,omitempty"`
|
||||||
|
@ -97,6 +103,7 @@ type UpdateOptsBuilder interface {
|
||||||
// UpdateOpts contains the values used when updating a router.
|
// UpdateOpts contains the values used when updating a router.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
Distributed *bool `json:"distributed,omitempty"`
|
Distributed *bool `json:"distributed,omitempty"`
|
||||||
GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"`
|
GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"`
|
||||||
|
|
|
@ -16,7 +16,7 @@ type GatewayInfo struct {
|
||||||
// ExternalFixedIP is the IP address and subnet ID of the external gateway of a
|
// ExternalFixedIP is the IP address and subnet ID of the external gateway of a
|
||||||
// router.
|
// router.
|
||||||
type ExternalFixedIP struct {
|
type ExternalFixedIP struct {
|
||||||
IPAddress string `json:"ip_address"`
|
IPAddress string `json:"ip_address,omitempty"`
|
||||||
SubnetID string `json:"subnet_id"`
|
SubnetID string `json:"subnet_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,9 @@ type Router struct {
|
||||||
// unique.
|
// unique.
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Description for the router.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
// ID is the unique identifier for the router.
|
// ID is the unique identifier for the router.
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
@ -67,6 +70,9 @@ type Router struct {
|
||||||
// Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others.
|
// Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others.
|
||||||
// Used to make network resources highly available.
|
// Used to make network resources highly available.
|
||||||
AvailabilityZoneHints []string `json:"availability_zone_hints"`
|
AvailabilityZoneHints []string `json:"availability_zone_hints"`
|
||||||
|
|
||||||
|
// Tags optionally set via extensions/attributestags
|
||||||
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouterPage is the page returned by a pager when traversing over a
|
// RouterPage is the page returned by a pager when traversing over a
|
||||||
|
|
32
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/BUILD
generated
vendored
Normal file
32
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/BUILD
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"doc.go",
|
||||||
|
"requests.go",
|
||||||
|
"results.go",
|
||||||
|
"urls.go",
|
||||||
|
],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies",
|
||||||
|
importpath = "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
123
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/doc.go
generated
vendored
Normal file
123
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
Package l7policies provides information and interaction with L7Policies and
|
||||||
|
Rules of the LBaaS v2 extension for the OpenStack Networking service.
|
||||||
|
|
||||||
|
Example to Create a L7Policy
|
||||||
|
|
||||||
|
createOpts := l7policies.CreateOpts{
|
||||||
|
Name: "redirect-example.com",
|
||||||
|
ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d",
|
||||||
|
Action: l7policies.ActionRedirectToURL,
|
||||||
|
RedirectURL: "http://www.example.com",
|
||||||
|
}
|
||||||
|
l7policy, err := l7policies.Create(lbClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to List L7Policies
|
||||||
|
|
||||||
|
listOpts := l7policies.ListOpts{
|
||||||
|
ListenerID: "c79a4468-d788-410c-bf79-9a8ef6354852",
|
||||||
|
}
|
||||||
|
allPages, err := l7policies.List(lbClient, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
allL7Policies, err := l7policies.ExtractL7Policies(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for _, l7policy := range allL7Policies {
|
||||||
|
fmt.Printf("%+v\n", l7policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Get a L7Policy
|
||||||
|
|
||||||
|
l7policy, err := l7policies.Get(lbClient, "023f2e34-7806-443b-bfae-16c324569a3d").Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a L7Policy
|
||||||
|
|
||||||
|
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
|
err := l7policies.Delete(lbClient, l7policyID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Update a L7Policy
|
||||||
|
|
||||||
|
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
|
name := "new-name"
|
||||||
|
updateOpts := l7policies.UpdateOpts{
|
||||||
|
Name: &name,
|
||||||
|
}
|
||||||
|
l7policy, err := l7policies.Update(lbClient, l7policyID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Rule
|
||||||
|
|
||||||
|
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
|
createOpts := l7policies.CreateRuleOpts{
|
||||||
|
RuleType: l7policies.TypePath,
|
||||||
|
CompareType: l7policies.CompareTypeRegex,
|
||||||
|
Value: "/images*",
|
||||||
|
}
|
||||||
|
rule, err := l7policies.CreateRule(lbClient, l7policyID, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to List L7 Rules
|
||||||
|
|
||||||
|
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
|
listOpts := l7policies.ListRulesOpts{
|
||||||
|
RuleType: l7policies.TypePath,
|
||||||
|
}
|
||||||
|
allPages, err := l7policies.ListRules(lbClient, l7policyID, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
allRules, err := l7policies.ExtractRules(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for _, rule := allRules {
|
||||||
|
fmt.Printf("%+v\n", rule)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Get a l7 rule
|
||||||
|
|
||||||
|
l7rule, err := l7policies.GetRule(lbClient, "023f2e34-7806-443b-bfae-16c324569a3d", "53ad8ab8-40fa-11e8-a508-00224d6b7bc1").Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a l7 rule
|
||||||
|
|
||||||
|
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
|
ruleID := "64dba99f-8af8-4200-8882-e32a0660f23e"
|
||||||
|
err := l7policies.DeleteRule(lbClient, l7policyID, ruleID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Update a Rule
|
||||||
|
|
||||||
|
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
|
ruleID := "64dba99f-8af8-4200-8882-e32a0660f23e"
|
||||||
|
updateOpts := l7policies.UpdateRuleOpts{
|
||||||
|
RuleType: l7policies.TypePath,
|
||||||
|
CompareType: l7policies.CompareTypeRegex,
|
||||||
|
Value: "/images/special*",
|
||||||
|
}
|
||||||
|
rule, err := l7policies.UpdateRule(lbClient, l7policyID, ruleID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package l7policies
|
376
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/requests.go
generated
vendored
Normal file
376
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,376 @@
|
||||||
|
package l7policies
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Create request.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToL7PolicyCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Action string
|
||||||
|
type RuleType string
|
||||||
|
type CompareType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActionRedirectToPool Action = "REDIRECT_TO_POOL"
|
||||||
|
ActionRedirectToURL Action = "REDIRECT_TO_URL"
|
||||||
|
ActionReject Action = "REJECT"
|
||||||
|
|
||||||
|
TypeCookie RuleType = "COOKIE"
|
||||||
|
TypeFileType RuleType = "FILE_TYPE"
|
||||||
|
TypeHeader RuleType = "HEADER"
|
||||||
|
TypeHostName RuleType = "HOST_NAME"
|
||||||
|
TypePath RuleType = "PATH"
|
||||||
|
|
||||||
|
CompareTypeContains CompareType = "CONTAINS"
|
||||||
|
CompareTypeEndWith CompareType = "ENDS_WITH"
|
||||||
|
CompareTypeEqual CompareType = "EQUAL_TO"
|
||||||
|
CompareTypeRegex CompareType = "REGEX"
|
||||||
|
CompareTypeStartWith CompareType = "STARTS_WITH"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateOpts is the common options struct used in this package's Create
|
||||||
|
// operation.
|
||||||
|
type CreateOpts struct {
|
||||||
|
// Name of the L7 policy.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
|
||||||
|
// The ID of the listener.
|
||||||
|
ListenerID string `json:"listener_id" required:"true"`
|
||||||
|
|
||||||
|
// The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT.
|
||||||
|
Action Action `json:"action" required:"true"`
|
||||||
|
|
||||||
|
// The position of this policy on the listener.
|
||||||
|
Position int32 `json:"position,omitempty"`
|
||||||
|
|
||||||
|
// A human-readable description for the resource.
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// TenantID is the UUID of the tenant who owns the L7 policy in octavia.
|
||||||
|
// Only administrative users can specify a project UUID other than their own.
|
||||||
|
TenantID string `json:"tenant_id,omitempty"`
|
||||||
|
|
||||||
|
// Requests matching this policy will be redirected to the pool with this ID.
|
||||||
|
// Only valid if action is REDIRECT_TO_POOL.
|
||||||
|
RedirectPoolID string `json:"redirect_pool_id,omitempty"`
|
||||||
|
|
||||||
|
// Requests matching this policy will be redirected to this URL.
|
||||||
|
// Only valid if action is REDIRECT_TO_URL.
|
||||||
|
RedirectURL string `json:"redirect_url,omitempty"`
|
||||||
|
|
||||||
|
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||||
|
// or false (DOWN).
|
||||||
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToL7PolicyCreateMap builds a request body from CreateOpts.
|
||||||
|
func (opts CreateOpts) ToL7PolicyCreateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "l7policy")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create accepts a CreateOpts struct and uses the values to create a new l7policy.
|
||||||
|
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToL7PolicyCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// List request.
|
||||||
|
type ListOptsBuilder interface {
|
||||||
|
ToL7PolicyListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOpts allows the filtering and sorting of paginated collections through
|
||||||
|
// the API.
|
||||||
|
type ListOpts struct {
|
||||||
|
Name string `q:"name"`
|
||||||
|
Description string `q:"description"`
|
||||||
|
ListenerID string `q:"listener_id"`
|
||||||
|
Action string `q:"action"`
|
||||||
|
TenantID string `q:"tenant_id"`
|
||||||
|
RedirectPoolID string `q:"redirect_pool_id"`
|
||||||
|
RedirectURL string `q:"redirect_url"`
|
||||||
|
Position int32 `q:"position"`
|
||||||
|
AdminStateUp bool `q:"admin_state_up"`
|
||||||
|
ID string `q:"id"`
|
||||||
|
Limit int `q:"limit"`
|
||||||
|
Marker string `q:"marker"`
|
||||||
|
SortKey string `q:"sort_key"`
|
||||||
|
SortDir string `q:"sort_dir"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToL7PolicyListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListOpts) ToL7PolicyListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns a Pager which allows you to iterate over a collection of
|
||||||
|
// l7policies. It accepts a ListOpts struct, which allows you to filter and sort
|
||||||
|
// the returned collection for greater efficiency.
|
||||||
|
//
|
||||||
|
// Default policy settings return only those l7policies that are owned by the
|
||||||
|
// project who submits the request, unless an admin user submits the request.
|
||||||
|
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := rootURL(c)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToL7PolicyListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return L7PolicyPage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves a particular l7policy based on its unique ID.
|
||||||
|
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
|
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete will permanently delete a particular l7policy based on its unique ID.
|
||||||
|
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
|
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Update request.
|
||||||
|
type UpdateOptsBuilder interface {
|
||||||
|
ToL7PolicyUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOpts is the common options struct used in this package's Update
|
||||||
|
// operation.
|
||||||
|
type UpdateOpts struct {
|
||||||
|
// Name of the L7 policy, empty string is allowed.
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
|
||||||
|
// The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT.
|
||||||
|
Action Action `json:"action,omitempty"`
|
||||||
|
|
||||||
|
// The position of this policy on the listener.
|
||||||
|
Position int32 `json:"position,omitempty"`
|
||||||
|
|
||||||
|
// A human-readable description for the resource, empty string is allowed.
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// Requests matching this policy will be redirected to the pool with this ID.
|
||||||
|
// Only valid if action is REDIRECT_TO_POOL.
|
||||||
|
RedirectPoolID *string `json:"redirect_pool_id,omitempty"`
|
||||||
|
|
||||||
|
// Requests matching this policy will be redirected to this URL.
|
||||||
|
// Only valid if action is REDIRECT_TO_URL.
|
||||||
|
RedirectURL *string `json:"redirect_url,omitempty"`
|
||||||
|
|
||||||
|
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||||
|
// or false (DOWN).
|
||||||
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToL7PolicyUpdateMap builds a request body from UpdateOpts.
|
||||||
|
func (opts UpdateOpts) ToL7PolicyUpdateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "l7policy")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := b["l7policy"].(map[string]interface{})
|
||||||
|
|
||||||
|
if m["redirect_pool_id"] == "" {
|
||||||
|
m["redirect_pool_id"] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if m["redirect_url"] == "" {
|
||||||
|
m["redirect_url"] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update allows l7policy to be updated.
|
||||||
|
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||||
|
b, err := opts.ToL7PolicyUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRuleOpts is the common options struct used in this package's CreateRule
|
||||||
|
// operation.
|
||||||
|
type CreateRuleOpts struct {
|
||||||
|
// The L7 rule type. One of COOKIE, FILE_TYPE, HEADER, HOST_NAME, or PATH.
|
||||||
|
RuleType RuleType `json:"type" required:"true"`
|
||||||
|
|
||||||
|
// The comparison type for the L7 rule. One of CONTAINS, ENDS_WITH, EQUAL_TO, REGEX, or STARTS_WITH.
|
||||||
|
CompareType CompareType `json:"compare_type" required:"true"`
|
||||||
|
|
||||||
|
// The value to use for the comparison. For example, the file type to compare.
|
||||||
|
Value string `json:"value" required:"true"`
|
||||||
|
|
||||||
|
// TenantID is the UUID of the tenant who owns the rule in octavia.
|
||||||
|
// Only administrative users can specify a project UUID other than their own.
|
||||||
|
TenantID string `json:"tenant_id,omitempty"`
|
||||||
|
|
||||||
|
// The key to use for the comparison. For example, the name of the cookie to evaluate.
|
||||||
|
Key string `json:"key,omitempty"`
|
||||||
|
|
||||||
|
// When true the logic of the rule is inverted. For example, with invert true,
|
||||||
|
// equal to would become not equal to. Default is false.
|
||||||
|
Invert bool `json:"invert,omitempty"`
|
||||||
|
|
||||||
|
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||||
|
// or false (DOWN).
|
||||||
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRuleCreateMap builds a request body from CreateRuleOpts.
|
||||||
|
func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "rule")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRule will create and associate a Rule with a particular L7Policy.
|
||||||
|
func CreateRule(c *gophercloud.ServiceClient, policyID string, opts CreateRuleOpts) (r CreateRuleResult) {
|
||||||
|
b, err := opts.ToRuleCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = c.Post(ruleRootURL(c, policyID), b, &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRulesOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// ListRules request.
|
||||||
|
type ListRulesOptsBuilder interface {
|
||||||
|
ToRulesListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRulesOpts allows the filtering and sorting of paginated collections
|
||||||
|
// through the API.
|
||||||
|
type ListRulesOpts struct {
|
||||||
|
RuleType RuleType `q:"type"`
|
||||||
|
TenantID string `q:"tenant_id"`
|
||||||
|
CompareType CompareType `q:"compare_type"`
|
||||||
|
Value string `q:"value"`
|
||||||
|
Key string `q:"key"`
|
||||||
|
Invert bool `q:"invert"`
|
||||||
|
AdminStateUp bool `q:"admin_state_up"`
|
||||||
|
ID string `q:"id"`
|
||||||
|
Limit int `q:"limit"`
|
||||||
|
Marker string `q:"marker"`
|
||||||
|
SortKey string `q:"sort_key"`
|
||||||
|
SortDir string `q:"sort_dir"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRulesListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListRulesOpts) ToRulesListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRules returns a Pager which allows you to iterate over a collection of
|
||||||
|
// rules. It accepts a ListRulesOptsBuilder, which allows you to filter and
|
||||||
|
// sort the returned collection for greater efficiency.
|
||||||
|
//
|
||||||
|
// Default policy settings return only those rules that are owned by the
|
||||||
|
// project who submits the request, unless an admin user submits the request.
|
||||||
|
func ListRules(c *gophercloud.ServiceClient, policyID string, opts ListRulesOptsBuilder) pagination.Pager {
|
||||||
|
url := ruleRootURL(c, policyID)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToRulesListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return RulePage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRule retrieves a particular L7Policy Rule based on its unique ID.
|
||||||
|
func GetRule(c *gophercloud.ServiceClient, policyID string, ruleID string) (r GetRuleResult) {
|
||||||
|
_, r.Err = c.Get(ruleResourceURL(c, policyID, ruleID), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRule will remove a Rule from a particular L7Policy.
|
||||||
|
func DeleteRule(c *gophercloud.ServiceClient, policyID string, ruleID string) (r DeleteRuleResult) {
|
||||||
|
_, r.Err = c.Delete(ruleResourceURL(c, policyID, ruleID), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRuleOptsBuilder allows to add additional parameters to the PUT request.
|
||||||
|
type UpdateRuleOptsBuilder interface {
|
||||||
|
ToRuleUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRuleOpts is the common options struct used in this package's Update
|
||||||
|
// operation.
|
||||||
|
type UpdateRuleOpts struct {
|
||||||
|
// The L7 rule type. One of COOKIE, FILE_TYPE, HEADER, HOST_NAME, or PATH.
|
||||||
|
RuleType RuleType `json:"type,omitempty"`
|
||||||
|
|
||||||
|
// The comparison type for the L7 rule. One of CONTAINS, ENDS_WITH, EQUAL_TO, REGEX, or STARTS_WITH.
|
||||||
|
CompareType CompareType `json:"compare_type,omitempty"`
|
||||||
|
|
||||||
|
// The value to use for the comparison. For example, the file type to compare.
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
|
||||||
|
// The key to use for the comparison. For example, the name of the cookie to evaluate.
|
||||||
|
Key *string `json:"key,omitempty"`
|
||||||
|
|
||||||
|
// When true the logic of the rule is inverted. For example, with invert true,
|
||||||
|
// equal to would become not equal to. Default is false.
|
||||||
|
Invert *bool `json:"invert,omitempty"`
|
||||||
|
|
||||||
|
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||||
|
// or false (DOWN).
|
||||||
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRuleUpdateMap builds a request body from UpdateRuleOpts.
|
||||||
|
func (opts UpdateRuleOpts) ToRuleUpdateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "rule")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m := b["rule"].(map[string]interface{}); m["key"] == "" {
|
||||||
|
m["key"] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRule allows Rule to be updated.
|
||||||
|
func UpdateRule(c *gophercloud.ServiceClient, policyID string, ruleID string, opts UpdateRuleOptsBuilder) (r UpdateRuleResult) {
|
||||||
|
b, err := opts.ToRuleUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = c.Put(ruleResourceURL(c, policyID, ruleID), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200, 201, 202},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
245
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/results.go
generated
vendored
Normal file
245
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/results.go
generated
vendored
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
package l7policies
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// L7Policy is a collection of L7 rules associated with a Listener, and which
|
||||||
|
// may also have an association to a back-end pool.
|
||||||
|
type L7Policy struct {
|
||||||
|
// The unique ID for the L7 policy.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// Name of the L7 policy.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// The ID of the listener.
|
||||||
|
ListenerID string `json:"listener_id"`
|
||||||
|
|
||||||
|
// The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT.
|
||||||
|
Action string `json:"action"`
|
||||||
|
|
||||||
|
// The position of this policy on the listener.
|
||||||
|
Position int32 `json:"position"`
|
||||||
|
|
||||||
|
// A human-readable description for the resource.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// TenantID is the UUID of the tenant who owns the L7 policy in octavia.
|
||||||
|
// Only administrative users can specify a project UUID other than their own.
|
||||||
|
TenantID string `json:"tenant_id"`
|
||||||
|
|
||||||
|
// Requests matching this policy will be redirected to the pool with this ID.
|
||||||
|
// Only valid if action is REDIRECT_TO_POOL.
|
||||||
|
RedirectPoolID string `json:"redirect_pool_id"`
|
||||||
|
|
||||||
|
// Requests matching this policy will be redirected to this URL.
|
||||||
|
// Only valid if action is REDIRECT_TO_URL.
|
||||||
|
RedirectURL string `json:"redirect_url"`
|
||||||
|
|
||||||
|
// The administrative state of the L7 policy, which is up (true) or down (false).
|
||||||
|
AdminStateUp bool `json:"admin_state_up"`
|
||||||
|
|
||||||
|
// The provisioning status of the L7 policy.
|
||||||
|
// This value is ACTIVE, PENDING_* or ERROR.
|
||||||
|
// This field seems to only be returned during a call to a load balancer's /status
|
||||||
|
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||||
|
ProvisioningStatus string `json:"provisioning_status"`
|
||||||
|
|
||||||
|
// The operating status of the L7 policy.
|
||||||
|
// This field seems to only be returned during a call to a load balancer's /status
|
||||||
|
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||||
|
OperatingStatus string `json:"operating_status"`
|
||||||
|
|
||||||
|
// Rules are List of associated L7 rule IDs.
|
||||||
|
Rules []Rule `json:"rules"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rule represents layer 7 load balancing rule.
|
||||||
|
type Rule struct {
|
||||||
|
// The unique ID for the L7 rule.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// The L7 rule type. One of COOKIE, FILE_TYPE, HEADER, HOST_NAME, or PATH.
|
||||||
|
RuleType string `json:"type"`
|
||||||
|
|
||||||
|
// The comparison type for the L7 rule. One of CONTAINS, ENDS_WITH, EQUAL_TO, REGEX, or STARTS_WITH.
|
||||||
|
CompareType string `json:"compare_type"`
|
||||||
|
|
||||||
|
// The value to use for the comparison. For example, the file type to compare.
|
||||||
|
Value string `json:"value"`
|
||||||
|
|
||||||
|
// TenantID is the UUID of the tenant who owns the rule in octavia.
|
||||||
|
// Only administrative users can specify a project UUID other than their own.
|
||||||
|
TenantID string `json:"tenant_id"`
|
||||||
|
|
||||||
|
// The key to use for the comparison. For example, the name of the cookie to evaluate.
|
||||||
|
Key string `json:"key"`
|
||||||
|
|
||||||
|
// When true the logic of the rule is inverted. For example, with invert true,
|
||||||
|
// equal to would become not equal to. Default is false.
|
||||||
|
Invert bool `json:"invert"`
|
||||||
|
|
||||||
|
// The administrative state of the L7 rule, which is up (true) or down (false).
|
||||||
|
AdminStateUp bool `json:"admin_state_up"`
|
||||||
|
|
||||||
|
// The provisioning status of the L7 rule.
|
||||||
|
// This value is ACTIVE, PENDING_* or ERROR.
|
||||||
|
// This field seems to only be returned during a call to a load balancer's /status
|
||||||
|
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||||
|
ProvisioningStatus string `json:"provisioning_status"`
|
||||||
|
|
||||||
|
// The operating status of the L7 policy.
|
||||||
|
// This field seems to only be returned during a call to a load balancer's /status
|
||||||
|
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||||
|
OperatingStatus string `json:"operating_status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type commonResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract is a function that accepts a result and extracts a l7policy.
|
||||||
|
func (r commonResult) Extract() (*L7Policy, error) {
|
||||||
|
var s struct {
|
||||||
|
L7Policy *L7Policy `json:"l7policy"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.L7Policy, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateResult represents the result of a Create operation. Call its Extract
|
||||||
|
// method to interpret the result as a L7Policy.
|
||||||
|
type CreateResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// L7PolicyPage is the page returned by a pager when traversing over a
|
||||||
|
// collection of l7policies.
|
||||||
|
type L7PolicyPage struct {
|
||||||
|
pagination.LinkedPageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextPageURL is invoked when a paginated collection of l7policies has reached
|
||||||
|
// the end of a page and the pager seeks to traverse over a new one. In order
|
||||||
|
// to do this, it needs to construct the next page's URL.
|
||||||
|
func (r L7PolicyPage) NextPageURL() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Links []gophercloud.Link `json:"l7policies_links"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return gophercloud.ExtractNextURL(s.Links)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty checks whether a L7PolicyPage struct is empty.
|
||||||
|
func (r L7PolicyPage) IsEmpty() (bool, error) {
|
||||||
|
is, err := ExtractL7Policies(r)
|
||||||
|
return len(is) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractL7Policies accepts a Page struct, specifically a L7PolicyPage struct,
|
||||||
|
// and extracts the elements into a slice of L7Policy structs. In other words,
|
||||||
|
// a generic collection is mapped into a relevant slice.
|
||||||
|
func ExtractL7Policies(r pagination.Page) ([]L7Policy, error) {
|
||||||
|
var s struct {
|
||||||
|
L7Policies []L7Policy `json:"l7policies"`
|
||||||
|
}
|
||||||
|
err := (r.(L7PolicyPage)).ExtractInto(&s)
|
||||||
|
return s.L7Policies, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResult represents the result of a Get operation. Call its Extract
|
||||||
|
// method to interpret the result as a L7Policy.
|
||||||
|
type GetResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteResult represents the result of a Delete operation. Call its
|
||||||
|
// ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResult represents the result of an Update operation. Call its Extract
|
||||||
|
// method to interpret the result as a L7Policy.
|
||||||
|
type UpdateResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
type commonRuleResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract is a function that accepts a result and extracts a rule.
|
||||||
|
func (r commonRuleResult) Extract() (*Rule, error) {
|
||||||
|
var s struct {
|
||||||
|
Rule *Rule `json:"rule"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.Rule, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRuleResult represents the result of a CreateRule operation.
|
||||||
|
// Call its Extract method to interpret it as a Rule.
|
||||||
|
type CreateRuleResult struct {
|
||||||
|
commonRuleResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// RulePage is the page returned by a pager when traversing over a
|
||||||
|
// collection of Rules in a L7Policy.
|
||||||
|
type RulePage struct {
|
||||||
|
pagination.LinkedPageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextPageURL is invoked when a paginated collection of rules has reached
|
||||||
|
// the end of a page and the pager seeks to traverse over a new one. In order
|
||||||
|
// to do this, it needs to construct the next page's URL.
|
||||||
|
func (r RulePage) NextPageURL() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Links []gophercloud.Link `json:"rules_links"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return gophercloud.ExtractNextURL(s.Links)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty checks whether a RulePage struct is empty.
|
||||||
|
func (r RulePage) IsEmpty() (bool, error) {
|
||||||
|
is, err := ExtractRules(r)
|
||||||
|
return len(is) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractRules accepts a Page struct, specifically a RulePage struct,
|
||||||
|
// and extracts the elements into a slice of Rules structs. In other words,
|
||||||
|
// a generic collection is mapped into a relevant slice.
|
||||||
|
func ExtractRules(r pagination.Page) ([]Rule, error) {
|
||||||
|
var s struct {
|
||||||
|
Rules []Rule `json:"rules"`
|
||||||
|
}
|
||||||
|
err := (r.(RulePage)).ExtractInto(&s)
|
||||||
|
return s.Rules, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRuleResult represents the result of a GetRule operation.
|
||||||
|
// Call its Extract method to interpret it as a Rule.
|
||||||
|
type GetRuleResult struct {
|
||||||
|
commonRuleResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRuleResult represents the result of a DeleteRule operation.
|
||||||
|
// Call its ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type DeleteRuleResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRuleResult represents the result of an UpdateRule operation.
|
||||||
|
// Call its Extract method to interpret it as a Rule.
|
||||||
|
type UpdateRuleResult struct {
|
||||||
|
commonRuleResult
|
||||||
|
}
|
25
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/urls.go
generated
vendored
Normal file
25
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package l7policies
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
const (
|
||||||
|
rootPath = "lbaas"
|
||||||
|
resourcePath = "l7policies"
|
||||||
|
rulePath = "rules"
|
||||||
|
)
|
||||||
|
|
||||||
|
func rootURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return c.ServiceURL(rootPath, resourcePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return c.ServiceURL(rootPath, resourcePath, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ruleRootURL(c *gophercloud.ServiceClient, policyID string) string {
|
||||||
|
return c.ServiceURL(rootPath, resourcePath, policyID, rulePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ruleResourceURL(c *gophercloud.ServiceClient, policyID string, ruleID string) string {
|
||||||
|
return c.ServiceURL(rootPath, resourcePath, policyID, rulePath, ruleID)
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ go_library(
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies:go_default_library",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools:go_default_library",
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools:go_default_library",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
|
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
|
||||||
],
|
],
|
||||||
|
|
|
@ -10,9 +10,10 @@ type Protocol string
|
||||||
|
|
||||||
// Supported attributes for create/update operations.
|
// Supported attributes for create/update operations.
|
||||||
const (
|
const (
|
||||||
ProtocolTCP Protocol = "TCP"
|
ProtocolTCP Protocol = "TCP"
|
||||||
ProtocolHTTP Protocol = "HTTP"
|
ProtocolHTTP Protocol = "HTTP"
|
||||||
ProtocolHTTPS Protocol = "HTTPS"
|
ProtocolHTTPS Protocol = "HTTPS"
|
||||||
|
ProtocolTerminatedHTTPS Protocol = "TERMINATED_HTTPS"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
@ -154,10 +155,13 @@ type UpdateOptsBuilder interface {
|
||||||
// UpdateOpts represents options for updating a Listener.
|
// UpdateOpts represents options for updating a Listener.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
// Human-readable name for the Listener. Does not have to be unique.
|
// Human-readable name for the Listener. Does not have to be unique.
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
|
|
||||||
|
// The ID of the default pool with which the Listener is associated.
|
||||||
|
DefaultPoolID *string `json:"default_pool_id,omitempty"`
|
||||||
|
|
||||||
// Human-readable description for the Listener.
|
// Human-readable description for the Listener.
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
|
|
||||||
// The maximum number of connections allowed for the Listener.
|
// The maximum number of connections allowed for the Listener.
|
||||||
ConnLimit *int `json:"connection_limit,omitempty"`
|
ConnLimit *int `json:"connection_limit,omitempty"`
|
||||||
|
@ -175,7 +179,16 @@ type UpdateOpts struct {
|
||||||
|
|
||||||
// ToListenerUpdateMap builds a request body from UpdateOpts.
|
// ToListenerUpdateMap builds a request body from UpdateOpts.
|
||||||
func (opts UpdateOpts) ToListenerUpdateMap() (map[string]interface{}, error) {
|
func (opts UpdateOpts) ToListenerUpdateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "listener")
|
b, err := gophercloud.BuildRequestBody(opts, "listener")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m := b["listener"].(map[string]interface{}); m["default_pool_id"] == "" {
|
||||||
|
m["default_pool_id"] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update is an operation which modifies the attributes of the specified
|
// Update is an operation which modifies the attributes of the specified
|
||||||
|
|
|
@ -2,6 +2,7 @@ package listeners
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies"
|
||||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools"
|
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
@ -54,6 +55,15 @@ type Listener struct {
|
||||||
|
|
||||||
// Pools are the pools which are part of this listener.
|
// Pools are the pools which are part of this listener.
|
||||||
Pools []pools.Pool `json:"pools"`
|
Pools []pools.Pool `json:"pools"`
|
||||||
|
|
||||||
|
// L7policies are the L7 policies which are part of this listener.
|
||||||
|
// This field seems to only be returned during a call to a load balancer's /status
|
||||||
|
// see: https://github.com/gophercloud/gophercloud/issues/1352
|
||||||
|
L7Policies []l7policies.L7Policy `json:"l7policies"`
|
||||||
|
|
||||||
|
// The provisioning status of the listener.
|
||||||
|
// This value is ACTIVE, PENDING_* or ERROR.
|
||||||
|
ProvisioningStatus string `json:"provisioning_status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenerPage is the page returned by a pager when traversing over a
|
// ListenerPage is the page returned by a pager when traversing over a
|
||||||
|
|
|
@ -14,6 +14,7 @@ go_library(
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners:go_default_library",
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners:go_default_library",
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools:go_default_library",
|
||||||
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
|
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -67,5 +67,13 @@ Example to Get the Status of a Load Balancer
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Example to Get the Statistics of a Load Balancer
|
||||||
|
|
||||||
|
lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
|
stats, err := loadbalancers.GetStats(networkClient, LBID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
package loadbalancers
|
package loadbalancers
|
||||||
|
|
|
@ -141,10 +141,10 @@ type UpdateOptsBuilder interface {
|
||||||
// operation.
|
// operation.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
// Human-readable name for the Loadbalancer. Does not have to be unique.
|
// Human-readable name for the Loadbalancer. Does not have to be unique.
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
|
|
||||||
// Human-readable description for the Loadbalancer.
|
// Human-readable description for the Loadbalancer.
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
|
|
||||||
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||||
// or false (DOWN).
|
// or false (DOWN).
|
||||||
|
@ -196,3 +196,9 @@ func GetStatuses(c *gophercloud.ServiceClient, id string) (r GetStatusesResult)
|
||||||
_, r.Err = c.Get(statusRootURL(c, id), &r.Body, nil)
|
_, r.Err = c.Get(statusRootURL(c, id), &r.Body, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetStats will return the shows the current statistics of a particular LoadBalancer.
|
||||||
|
func GetStats(c *gophercloud.ServiceClient, id string) (r StatsResult) {
|
||||||
|
_, r.Err = c.Get(statisticsRootURL(c, id), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package loadbalancers
|
||||||
import (
|
import (
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners"
|
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,6 +52,9 @@ type LoadBalancer struct {
|
||||||
|
|
||||||
// Listeners are the listeners related to this Loadbalancer.
|
// Listeners are the listeners related to this Loadbalancer.
|
||||||
Listeners []listeners.Listener `json:"listeners"`
|
Listeners []listeners.Listener `json:"listeners"`
|
||||||
|
|
||||||
|
// Pools are the pools related to this Loadbalancer.
|
||||||
|
Pools []pools.Pool `json:"pools"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// StatusTree represents the status of a loadbalancer.
|
// StatusTree represents the status of a loadbalancer.
|
||||||
|
@ -58,6 +62,23 @@ type StatusTree struct {
|
||||||
Loadbalancer *LoadBalancer `json:"loadbalancer"`
|
Loadbalancer *LoadBalancer `json:"loadbalancer"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Stats struct {
|
||||||
|
// The currently active connections.
|
||||||
|
ActiveConnections int `json:"active_connections"`
|
||||||
|
|
||||||
|
// The total bytes received.
|
||||||
|
BytesIn int `json:"bytes_in"`
|
||||||
|
|
||||||
|
// The total bytes sent.
|
||||||
|
BytesOut int `json:"bytes_out"`
|
||||||
|
|
||||||
|
// The total requests that were unable to be fulfilled.
|
||||||
|
RequestErrors int `json:"request_errors"`
|
||||||
|
|
||||||
|
// The total connections handled.
|
||||||
|
TotalConnections int `json:"total_connections"`
|
||||||
|
}
|
||||||
|
|
||||||
// LoadBalancerPage is the page returned by a pager when traversing over a
|
// LoadBalancerPage is the page returned by a pager when traversing over a
|
||||||
// collection of load balancers.
|
// collection of load balancers.
|
||||||
type LoadBalancerPage struct {
|
type LoadBalancerPage struct {
|
||||||
|
@ -124,6 +145,22 @@ func (r GetStatusesResult) Extract() (*StatusTree, error) {
|
||||||
return s.Statuses, err
|
return s.Statuses, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StatsResult represents the result of a GetStats operation.
|
||||||
|
// Call its Extract method to interpret it as a Stats.
|
||||||
|
type StatsResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract is a function that accepts a result and extracts the status of
|
||||||
|
// a Loadbalancer.
|
||||||
|
func (r StatsResult) Extract() (*Stats, error) {
|
||||||
|
var s struct {
|
||||||
|
Stats *Stats `json:"stats"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.Stats, err
|
||||||
|
}
|
||||||
|
|
||||||
// CreateResult represents the result of a create operation. Call its Extract
|
// CreateResult represents the result of a create operation. Call its Extract
|
||||||
// method to interpret it as a LoadBalancer.
|
// method to interpret it as a LoadBalancer.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
|
|
|
@ -3,9 +3,10 @@ package loadbalancers
|
||||||
import "github.com/gophercloud/gophercloud"
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
rootPath = "lbaas"
|
rootPath = "lbaas"
|
||||||
resourcePath = "loadbalancers"
|
resourcePath = "loadbalancers"
|
||||||
statusPath = "statuses"
|
statusPath = "statuses"
|
||||||
|
statisticsPath = "stats"
|
||||||
)
|
)
|
||||||
|
|
||||||
func rootURL(c *gophercloud.ServiceClient) string {
|
func rootURL(c *gophercloud.ServiceClient) string {
|
||||||
|
@ -19,3 +20,7 @@ func resourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
func statusRootURL(c *gophercloud.ServiceClient, id string) string {
|
func statusRootURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
return c.ServiceURL(rootPath, resourcePath, id, statusPath)
|
return c.ServiceURL(rootPath, resourcePath, id, statusPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func statisticsRootURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return c.ServiceURL(rootPath, resourcePath, id, statisticsPath)
|
||||||
|
}
|
||||||
|
|
|
@ -223,7 +223,7 @@ type UpdateOpts struct {
|
||||||
ExpectedCodes string `json:"expected_codes,omitempty"`
|
ExpectedCodes string `json:"expected_codes,omitempty"`
|
||||||
|
|
||||||
// The Name of the Monitor.
|
// The Name of the Monitor.
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
|
|
||||||
// The administrative state of the Monitor. A valid value is true (UP)
|
// The administrative state of the Monitor. A valid value is true (UP)
|
||||||
// or false (DOWN).
|
// or false (DOWN).
|
||||||
|
|
|
@ -70,6 +70,10 @@ type Monitor struct {
|
||||||
|
|
||||||
// List of pools that are associated with the health monitor.
|
// List of pools that are associated with the health monitor.
|
||||||
Pools []PoolID `json:"pools"`
|
Pools []PoolID `json:"pools"`
|
||||||
|
|
||||||
|
// The provisioning status of the monitor.
|
||||||
|
// This value is ACTIVE, PENDING_* or ERROR.
|
||||||
|
ProvisioningStatus string `json:"provisioning_status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MonitorPage is the page returned by a pager when traversing over a
|
// MonitorPage is the page returned by a pager when traversing over a
|
||||||
|
|
|
@ -13,7 +13,7 @@ Example to List Pools
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
allPools, err := pools.ExtractMonitors(allPages)
|
allPools, err := pools.ExtractPools(allPages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -83,12 +83,13 @@ Example to Create a Member
|
||||||
|
|
||||||
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
|
|
||||||
|
weight := 10
|
||||||
createOpts := pools.CreateMemberOpts{
|
createOpts := pools.CreateMemberOpts{
|
||||||
Name: "db",
|
Name: "db",
|
||||||
SubnetID: "1981f108-3c48-48d2-b908-30f7d28532c9",
|
SubnetID: "1981f108-3c48-48d2-b908-30f7d28532c9",
|
||||||
Address: "10.0.2.11",
|
Address: "10.0.2.11",
|
||||||
ProtocolPort: 80,
|
ProtocolPort: 80,
|
||||||
Weight: 10,
|
Weight: &weight,
|
||||||
}
|
}
|
||||||
|
|
||||||
member, err := pools.CreateMember(networkClient, poolID, createOpts).Extract()
|
member, err := pools.CreateMember(networkClient, poolID, createOpts).Extract()
|
||||||
|
@ -101,9 +102,10 @@ Example to Update a Member
|
||||||
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||||
memberID := "64dba99f-8af8-4200-8882-e32a0660f23e"
|
memberID := "64dba99f-8af8-4200-8882-e32a0660f23e"
|
||||||
|
|
||||||
|
weight := 4
|
||||||
updateOpts := pools.UpdateMemberOpts{
|
updateOpts := pools.UpdateMemberOpts{
|
||||||
Name: "new-name",
|
Name: "new-name",
|
||||||
Weight: 4,
|
Weight: &weight,
|
||||||
}
|
}
|
||||||
|
|
||||||
member, err := pools.UpdateMember(networkClient, poolID, memberID, updateOpts).Extract()
|
member, err := pools.UpdateMember(networkClient, poolID, memberID, updateOpts).Extract()
|
||||||
|
|
|
@ -154,10 +154,10 @@ type UpdateOptsBuilder interface {
|
||||||
// operation.
|
// operation.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
// Name of the pool.
|
// Name of the pool.
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
|
|
||||||
// Human-readable description for the pool.
|
// Human-readable description for the pool.
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
|
|
||||||
// The algorithm used to distribute load between the members of the pool. The
|
// The algorithm used to distribute load between the members of the pool. The
|
||||||
// current specification supports LBMethodRoundRobin, LBMethodLeastConnections
|
// current specification supports LBMethodRoundRobin, LBMethodLeastConnections
|
||||||
|
@ -274,7 +274,7 @@ type CreateMemberOpts struct {
|
||||||
// that this member should receive from the pool. For example, a member with
|
// that this member should receive from the pool. For example, a member with
|
||||||
// a weight of 10 receives five times as much traffic as a member with a
|
// a weight of 10 receives five times as much traffic as a member with a
|
||||||
// weight of 2.
|
// weight of 2.
|
||||||
Weight int `json:"weight,omitempty"`
|
Weight *int `json:"weight,omitempty"`
|
||||||
|
|
||||||
// If you omit this parameter, LBaaS uses the vip_subnet_id parameter value
|
// If you omit this parameter, LBaaS uses the vip_subnet_id parameter value
|
||||||
// for the subnet UUID.
|
// for the subnet UUID.
|
||||||
|
@ -317,13 +317,13 @@ type UpdateMemberOptsBuilder interface {
|
||||||
// operation.
|
// operation.
|
||||||
type UpdateMemberOpts struct {
|
type UpdateMemberOpts struct {
|
||||||
// Name of the Member.
|
// Name of the Member.
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
|
|
||||||
// A positive integer value that indicates the relative portion of traffic
|
// A positive integer value that indicates the relative portion of traffic
|
||||||
// that this member should receive from the pool. For example, a member with
|
// that this member should receive from the pool. For example, a member with
|
||||||
// a weight of 10 receives five times as much traffic as a member with a
|
// a weight of 10 receives five times as much traffic as a member with a
|
||||||
// weight of 2.
|
// weight of 2.
|
||||||
Weight int `json:"weight,omitempty"`
|
Weight *int `json:"weight,omitempty"`
|
||||||
|
|
||||||
// The administrative state of the Pool. A valid value is true (UP)
|
// The administrative state of the Pool. A valid value is true (UP)
|
||||||
// or false (DOWN).
|
// or false (DOWN).
|
||||||
|
|
|
@ -92,6 +92,15 @@ type Pool struct {
|
||||||
|
|
||||||
// The Monitor associated with this Pool.
|
// The Monitor associated with this Pool.
|
||||||
Monitor monitors.Monitor `json:"healthmonitor"`
|
Monitor monitors.Monitor `json:"healthmonitor"`
|
||||||
|
|
||||||
|
// The provisioning status of the pool.
|
||||||
|
// This value is ACTIVE, PENDING_* or ERROR.
|
||||||
|
ProvisioningStatus string `json:"provisioning_status"`
|
||||||
|
|
||||||
|
// The operating status of the pool.
|
||||||
|
// This field seems to only be returned during a call to a load balancer's /status
|
||||||
|
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||||
|
OperatingStatus string `json:"operating_status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PoolPage is the page returned by a pager when traversing over a
|
// PoolPage is the page returned by a pager when traversing over a
|
||||||
|
@ -196,6 +205,15 @@ type Member struct {
|
||||||
|
|
||||||
// The unique ID for the Member.
|
// The unique ID for the Member.
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// The provisioning status of the member.
|
||||||
|
// This value is ACTIVE, PENDING_* or ERROR.
|
||||||
|
ProvisioningStatus string `json:"provisioning_status"`
|
||||||
|
|
||||||
|
// The operating status of the member.
|
||||||
|
// This field seems to only be returned during a call to a load balancer's /status
|
||||||
|
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||||
|
OperatingStatus string `json:"operating_status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemberPage is the page returned by a pager when traversing over a
|
// MemberPage is the page returned by a pager when traversing over a
|
||||||
|
|
|
@ -11,14 +11,19 @@ import (
|
||||||
// sort by a particular network attribute. SortDir sets the direction, and is
|
// sort by a particular network attribute. SortDir sets the direction, and is
|
||||||
// either `asc' or `desc'. Marker and Limit are used for pagination.
|
// either `asc' or `desc'. Marker and Limit are used for pagination.
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
ID string `q:"id"`
|
ID string `q:"id"`
|
||||||
Name string `q:"name"`
|
Name string `q:"name"`
|
||||||
TenantID string `q:"tenant_id"`
|
Description string `q:"description"`
|
||||||
ProjectID string `q:"project_id"`
|
TenantID string `q:"tenant_id"`
|
||||||
Limit int `q:"limit"`
|
ProjectID string `q:"project_id"`
|
||||||
Marker string `q:"marker"`
|
Limit int `q:"limit"`
|
||||||
SortKey string `q:"sort_key"`
|
Marker string `q:"marker"`
|
||||||
SortDir string `q:"sort_dir"`
|
SortKey string `q:"sort_key"`
|
||||||
|
SortDir string `q:"sort_dir"`
|
||||||
|
Tags string `q:"tags"`
|
||||||
|
TagsAny string `q:"tags-any"`
|
||||||
|
NotTags string `q:"not-tags"`
|
||||||
|
NotTagsAny string `q:"not-tags-any"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a Pager which allows you to iterate over a collection of
|
// List returns a Pager which allows you to iterate over a collection of
|
||||||
|
@ -88,7 +93,7 @@ type UpdateOpts struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
|
||||||
// Describes the security group.
|
// Describes the security group.
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToSecGroupUpdateMap builds a request body from UpdateOpts.
|
// ToSecGroupUpdateMap builds a request body from UpdateOpts.
|
||||||
|
@ -128,7 +133,12 @@ func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
pages, err := List(client, ListOpts{}).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ type SecGroup struct {
|
||||||
|
|
||||||
// ProjectID is the project owner of the security group.
|
// ProjectID is the project owner of the security group.
|
||||||
ProjectID string `json:"project_id"`
|
ProjectID string `json:"project_id"`
|
||||||
|
|
||||||
|
// Tags optionally set via extensions/attributestags
|
||||||
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecGroupPage is the page returned by a pager when traversing over a
|
// SecGroupPage is the page returned by a pager when traversing over a
|
||||||
|
|
|
@ -14,6 +14,7 @@ type ListOpts struct {
|
||||||
Direction string `q:"direction"`
|
Direction string `q:"direction"`
|
||||||
EtherType string `q:"ethertype"`
|
EtherType string `q:"ethertype"`
|
||||||
ID string `q:"id"`
|
ID string `q:"id"`
|
||||||
|
Description string `q:"description"`
|
||||||
PortRangeMax int `q:"port_range_max"`
|
PortRangeMax int `q:"port_range_max"`
|
||||||
PortRangeMin int `q:"port_range_min"`
|
PortRangeMin int `q:"port_range_min"`
|
||||||
Protocol string `q:"protocol"`
|
Protocol string `q:"protocol"`
|
||||||
|
@ -88,6 +89,9 @@ type CreateOpts struct {
|
||||||
// group rule is applied.
|
// group rule is applied.
|
||||||
Direction RuleDirection `json:"direction" required:"true"`
|
Direction RuleDirection `json:"direction" required:"true"`
|
||||||
|
|
||||||
|
// String description of each rule, optional
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
|
||||||
// Must be "IPv4" or "IPv6", and addresses represented in CIDR must match the
|
// Must be "IPv4" or "IPv6", and addresses represented in CIDR must match the
|
||||||
// ingress or egress rules.
|
// ingress or egress rules.
|
||||||
EtherType RuleEtherType `json:"ethertype" required:"true"`
|
EtherType RuleEtherType `json:"ethertype" required:"true"`
|
||||||
|
|
|
@ -17,6 +17,9 @@ type SecGroupRule struct {
|
||||||
// instance. An egress rule is applied to traffic leaving the instance.
|
// instance. An egress rule is applied to traffic leaving the instance.
|
||||||
Direction string
|
Direction string
|
||||||
|
|
||||||
|
// Descripton of the rule
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
// Must be IPv4 or IPv6, and addresses represented in CIDR must match the
|
// Must be IPv4 or IPv6, and addresses represented in CIDR must match the
|
||||||
// ingress or egress rules.
|
// ingress or egress rules.
|
||||||
EtherType string `json:"ethertype"`
|
EtherType string `json:"ethertype"`
|
||||||
|
|
20
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go
generated
vendored
20
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go
generated
vendored
|
@ -19,6 +19,7 @@ type ListOptsBuilder interface {
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
Status string `q:"status"`
|
Status string `q:"status"`
|
||||||
Name string `q:"name"`
|
Name string `q:"name"`
|
||||||
|
Description string `q:"description"`
|
||||||
AdminStateUp *bool `q:"admin_state_up"`
|
AdminStateUp *bool `q:"admin_state_up"`
|
||||||
TenantID string `q:"tenant_id"`
|
TenantID string `q:"tenant_id"`
|
||||||
ProjectID string `q:"project_id"`
|
ProjectID string `q:"project_id"`
|
||||||
|
@ -28,6 +29,10 @@ type ListOpts struct {
|
||||||
Limit int `q:"limit"`
|
Limit int `q:"limit"`
|
||||||
SortKey string `q:"sort_key"`
|
SortKey string `q:"sort_key"`
|
||||||
SortDir string `q:"sort_dir"`
|
SortDir string `q:"sort_dir"`
|
||||||
|
Tags string `q:"tags"`
|
||||||
|
TagsAny string `q:"tags-any"`
|
||||||
|
NotTags string `q:"not-tags"`
|
||||||
|
NotTagsAny string `q:"not-tags-any"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToNetworkListQuery formats a ListOpts into a query string.
|
// ToNetworkListQuery formats a ListOpts into a query string.
|
||||||
|
@ -69,6 +74,7 @@ type CreateOptsBuilder interface {
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
Shared *bool `json:"shared,omitempty"`
|
Shared *bool `json:"shared,omitempty"`
|
||||||
TenantID string `json:"tenant_id,omitempty"`
|
TenantID string `json:"tenant_id,omitempty"`
|
||||||
ProjectID string `json:"project_id,omitempty"`
|
ProjectID string `json:"project_id,omitempty"`
|
||||||
|
@ -105,9 +111,10 @@ type UpdateOptsBuilder interface {
|
||||||
|
|
||||||
// UpdateOpts represents options used to update a network.
|
// UpdateOpts represents options used to update a network.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Shared *bool `json:"shared,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
|
Shared *bool `json:"shared,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToNetworkUpdateMap builds a request body from UpdateOpts.
|
// ToNetworkUpdateMap builds a request body from UpdateOpts.
|
||||||
|
@ -140,7 +147,12 @@ func Delete(c *gophercloud.ServiceClient, networkID string) (r DeleteResult) {
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
pages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@ type Network struct {
|
||||||
// Human-readable name for the network. Might not be unique.
|
// Human-readable name for the network. Might not be unique.
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Description for the network
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
// The administrative state of network. If false (down), the network does not
|
// The administrative state of network. If false (down), the network does not
|
||||||
// forward packets.
|
// forward packets.
|
||||||
AdminStateUp bool `json:"admin_state_up"`
|
AdminStateUp bool `json:"admin_state_up"`
|
||||||
|
@ -76,6 +79,9 @@ type Network struct {
|
||||||
// Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others.
|
// Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others.
|
||||||
// Used to make network resources highly available.
|
// Used to make network resources highly available.
|
||||||
AvailabilityZoneHints []string `json:"availability_zone_hints"`
|
AvailabilityZoneHints []string `json:"availability_zone_hints"`
|
||||||
|
|
||||||
|
// Tags optionally set via extensions/attributestags
|
||||||
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkPage is the page returned by a pager when traversing over a
|
// NetworkPage is the page returned by a pager when traversing over a
|
||||||
|
|
20
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/requests.go
generated
vendored
20
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/requests.go
generated
vendored
|
@ -19,6 +19,7 @@ type ListOptsBuilder interface {
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
Status string `q:"status"`
|
Status string `q:"status"`
|
||||||
Name string `q:"name"`
|
Name string `q:"name"`
|
||||||
|
Description string `q:"description"`
|
||||||
AdminStateUp *bool `q:"admin_state_up"`
|
AdminStateUp *bool `q:"admin_state_up"`
|
||||||
NetworkID string `q:"network_id"`
|
NetworkID string `q:"network_id"`
|
||||||
TenantID string `q:"tenant_id"`
|
TenantID string `q:"tenant_id"`
|
||||||
|
@ -31,6 +32,10 @@ type ListOpts struct {
|
||||||
Marker string `q:"marker"`
|
Marker string `q:"marker"`
|
||||||
SortKey string `q:"sort_key"`
|
SortKey string `q:"sort_key"`
|
||||||
SortDir string `q:"sort_dir"`
|
SortDir string `q:"sort_dir"`
|
||||||
|
Tags string `q:"tags"`
|
||||||
|
TagsAny string `q:"tags-any"`
|
||||||
|
NotTags string `q:"not-tags"`
|
||||||
|
NotTagsAny string `q:"not-tags-any"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToPortListQuery formats a ListOpts into a query string.
|
// ToPortListQuery formats a ListOpts into a query string.
|
||||||
|
@ -76,6 +81,7 @@ type CreateOptsBuilder interface {
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
NetworkID string `json:"network_id" required:"true"`
|
NetworkID string `json:"network_id" required:"true"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
MACAddress string `json:"mac_address,omitempty"`
|
MACAddress string `json:"mac_address,omitempty"`
|
||||||
FixedIPs interface{} `json:"fixed_ips,omitempty"`
|
FixedIPs interface{} `json:"fixed_ips,omitempty"`
|
||||||
|
@ -112,11 +118,12 @@ type UpdateOptsBuilder interface {
|
||||||
|
|
||||||
// UpdateOpts represents the attributes used when updating an existing port.
|
// UpdateOpts represents the attributes used when updating an existing port.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||||
FixedIPs interface{} `json:"fixed_ips,omitempty"`
|
FixedIPs interface{} `json:"fixed_ips,omitempty"`
|
||||||
DeviceID string `json:"device_id,omitempty"`
|
DeviceID *string `json:"device_id,omitempty"`
|
||||||
DeviceOwner string `json:"device_owner,omitempty"`
|
DeviceOwner *string `json:"device_owner,omitempty"`
|
||||||
SecurityGroups *[]string `json:"security_groups,omitempty"`
|
SecurityGroups *[]string `json:"security_groups,omitempty"`
|
||||||
AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"`
|
AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -151,7 +158,12 @@ func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
pages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
6
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/results.go
generated
vendored
6
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/results.go
generated
vendored
|
@ -68,6 +68,9 @@ type Port struct {
|
||||||
// Human-readable name for the port. Might not be unique.
|
// Human-readable name for the port. Might not be unique.
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Describes the port.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
// Administrative state of port. If false (down), port does not forward
|
// Administrative state of port. If false (down), port does not forward
|
||||||
// packets.
|
// packets.
|
||||||
AdminStateUp bool `json:"admin_state_up"`
|
AdminStateUp bool `json:"admin_state_up"`
|
||||||
|
@ -101,6 +104,9 @@ type Port struct {
|
||||||
|
|
||||||
// Identifies the list of IP addresses the port will recognize/accept
|
// Identifies the list of IP addresses the port will recognize/accept
|
||||||
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"`
|
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"`
|
||||||
|
|
||||||
|
// Tags optionally set via extensions/attributestags
|
||||||
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PortPage is the page returned by a pager when traversing over a collection
|
// PortPage is the page returned by a pager when traversing over a collection
|
||||||
|
|
|
@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["choose_version.go"],
|
srcs = [
|
||||||
|
"base_endpoint.go",
|
||||||
|
"choose_version.go",
|
||||||
|
],
|
||||||
importmap = "k8s.io/kubernetes/vendor/github.com/gophercloud/gophercloud/openstack/utils",
|
importmap = "k8s.io/kubernetes/vendor/github.com/gophercloud/gophercloud/openstack/utils",
|
||||||
importpath = "github.com/gophercloud/gophercloud/openstack/utils",
|
importpath = "github.com/gophercloud/gophercloud/openstack/utils",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
|
|
28
vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go
generated
vendored
Normal file
28
vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BaseEndpoint will return a URL without the /vX.Y
|
||||||
|
// portion of the URL.
|
||||||
|
func BaseEndpoint(endpoint string) (string, error) {
|
||||||
|
u, err := url.Parse(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
u.RawQuery, u.Fragment = "", ""
|
||||||
|
|
||||||
|
path := u.Path
|
||||||
|
versionRe := regexp.MustCompile("v[0-9.]+/?")
|
||||||
|
|
||||||
|
if version := versionRe.FindString(path); version != "" {
|
||||||
|
versionIndex := strings.Index(path, version)
|
||||||
|
u.Path = path[:versionIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.String(), nil
|
||||||
|
}
|
|
@ -41,6 +41,8 @@ type Pager struct {
|
||||||
|
|
||||||
createPage func(r PageResult) Page
|
createPage func(r PageResult) Page
|
||||||
|
|
||||||
|
firstPage Page
|
||||||
|
|
||||||
Err error
|
Err error
|
||||||
|
|
||||||
// Headers supplies additional HTTP headers to populate on each paged request.
|
// Headers supplies additional HTTP headers to populate on each paged request.
|
||||||
|
@ -89,9 +91,18 @@ func (p Pager) EachPage(handler func(Page) (bool, error)) error {
|
||||||
}
|
}
|
||||||
currentURL := p.initialURL
|
currentURL := p.initialURL
|
||||||
for {
|
for {
|
||||||
currentPage, err := p.fetchNextPage(currentURL)
|
var currentPage Page
|
||||||
if err != nil {
|
|
||||||
return err
|
// if first page has already been fetched, no need to fetch it again
|
||||||
|
if p.firstPage != nil {
|
||||||
|
currentPage = p.firstPage
|
||||||
|
p.firstPage = nil
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
currentPage, err = p.fetchNextPage(currentURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
empty, err := currentPage.IsEmpty()
|
empty, err := currentPage.IsEmpty()
|
||||||
|
@ -128,23 +139,26 @@ func (p Pager) AllPages() (Page, error) {
|
||||||
// body will contain the final concatenated Page body.
|
// body will contain the final concatenated Page body.
|
||||||
var body reflect.Value
|
var body reflect.Value
|
||||||
|
|
||||||
// Grab a test page to ascertain the page body type.
|
// Grab a first page to ascertain the page body type.
|
||||||
testPage, err := p.fetchNextPage(p.initialURL)
|
firstPage, err := p.fetchNextPage(p.initialURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Store the page type so we can use reflection to create a new mega-page of
|
// Store the page type so we can use reflection to create a new mega-page of
|
||||||
// that type.
|
// that type.
|
||||||
pageType := reflect.TypeOf(testPage)
|
pageType := reflect.TypeOf(firstPage)
|
||||||
|
|
||||||
// if it's a single page, just return the testPage (first page)
|
// if it's a single page, just return the firstPage (first page)
|
||||||
if _, found := pageType.FieldByName("SinglePageBase"); found {
|
if _, found := pageType.FieldByName("SinglePageBase"); found {
|
||||||
return testPage, nil
|
return firstPage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store the first page to avoid getting it twice
|
||||||
|
p.firstPage = firstPage
|
||||||
|
|
||||||
// Switch on the page body type. Recognized types are `map[string]interface{}`,
|
// Switch on the page body type. Recognized types are `map[string]interface{}`,
|
||||||
// `[]byte`, and `[]interface{}`.
|
// `[]byte`, and `[]interface{}`.
|
||||||
switch pb := testPage.GetBody().(type) {
|
switch pb := firstPage.GetBody().(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
// key is the map key for the page body if the body type is `map[string]interface{}`.
|
// key is the map key for the page body if the body type is `map[string]interface{}`.
|
||||||
var key string
|
var key string
|
||||||
|
|
|
@ -120,6 +120,22 @@ func BuildRequestBody(opts interface{}, parent string) (map[string]interface{},
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v.Kind() == reflect.Slice || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Slice) {
|
||||||
|
sliceValue := v
|
||||||
|
if sliceValue.Kind() == reflect.Ptr {
|
||||||
|
sliceValue = sliceValue.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < sliceValue.Len(); i++ {
|
||||||
|
element := sliceValue.Index(i)
|
||||||
|
if element.Kind() == reflect.Struct || (element.Kind() == reflect.Ptr && element.Elem().Kind() == reflect.Struct) {
|
||||||
|
_, err := BuildRequestBody(element.Interface(), "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if v.Kind() == reflect.Struct || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) {
|
if v.Kind() == reflect.Struct || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) {
|
||||||
if zero {
|
if zero {
|
||||||
//fmt.Printf("value before change: %+v\n", optsValue.Field(i))
|
//fmt.Printf("value before change: %+v\n", optsValue.Field(i))
|
||||||
|
@ -363,9 +379,8 @@ func BuildQueryString(opts interface{}) (*url.URL, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, the field is not set.
|
// if the field has a 'required' tag, it can't have a zero-value
|
||||||
if len(tags) == 2 && tags[1] == "required" {
|
if requiredTag := f.Tag.Get("required"); requiredTag == "true" {
|
||||||
// And the field is required. Return an error.
|
|
||||||
return &url.URL{}, fmt.Errorf("Required query parameter [%s] not set.", f.Name)
|
return &url.URL{}, fmt.Errorf("Required query parameter [%s] not set.", f.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -439,10 +454,9 @@ func BuildHeaders(opts interface{}) (map[string]string, error) {
|
||||||
optsMap[tags[0]] = strconv.FormatBool(v.Bool())
|
optsMap[tags[0]] = strconv.FormatBool(v.Bool())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, the field is not set.
|
// if the field has a 'required' tag, it can't have a zero-value
|
||||||
if len(tags) == 2 && tags[1] == "required" {
|
if requiredTag := f.Tag.Get("required"); requiredTag == "true" {
|
||||||
// And the field is required. Return an error.
|
return optsMap, fmt.Errorf("Required header [%s] not set.", f.Name)
|
||||||
return optsMap, fmt.Errorf("Required header not set.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package gophercloud
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -71,6 +72,10 @@ type ProviderClient struct {
|
||||||
// authentication functions for different Identity service versions.
|
// authentication functions for different Identity service versions.
|
||||||
ReauthFunc func() error
|
ReauthFunc func() error
|
||||||
|
|
||||||
|
// IsThrowaway determines whether if this client is a throw-away client. It's a copy of user's provider client
|
||||||
|
// with the token and reauth func zeroed. Such client can be used to perform reauthorization.
|
||||||
|
IsThrowaway bool
|
||||||
|
|
||||||
mut *sync.RWMutex
|
mut *sync.RWMutex
|
||||||
|
|
||||||
reauthmut *reauthlock
|
reauthmut *reauthlock
|
||||||
|
@ -78,19 +83,23 @@ type ProviderClient struct {
|
||||||
|
|
||||||
type reauthlock struct {
|
type reauthlock struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
reauthing bool
|
reauthing bool
|
||||||
|
reauthingErr error
|
||||||
|
done *sync.Cond
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthenticatedHeaders returns a map of HTTP headers that are common for all
|
// AuthenticatedHeaders returns a map of HTTP headers that are common for all
|
||||||
// authenticated service requests.
|
// authenticated service requests. Blocks if Reauthenticate is in progress.
|
||||||
func (client *ProviderClient) AuthenticatedHeaders() (m map[string]string) {
|
func (client *ProviderClient) AuthenticatedHeaders() (m map[string]string) {
|
||||||
|
if client.IsThrowaway {
|
||||||
|
return
|
||||||
|
}
|
||||||
if client.reauthmut != nil {
|
if client.reauthmut != nil {
|
||||||
client.reauthmut.RLock()
|
client.reauthmut.Lock()
|
||||||
if client.reauthmut.reauthing {
|
for client.reauthmut.reauthing {
|
||||||
client.reauthmut.RUnlock()
|
client.reauthmut.done.Wait()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
client.reauthmut.RUnlock()
|
client.reauthmut.Unlock()
|
||||||
}
|
}
|
||||||
t := client.Token()
|
t := client.Token()
|
||||||
if t == "" {
|
if t == "" {
|
||||||
|
@ -126,11 +135,11 @@ func (client *ProviderClient) SetToken(t string) {
|
||||||
client.TokenID = t
|
client.TokenID = t
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reauthenticate calls client.ReauthFunc in a thread-safe way. If this is
|
// Reauthenticate calls client.ReauthFunc in a thread-safe way. If this is
|
||||||
//called because of a 401 response, the caller may pass the previous token. In
|
// called because of a 401 response, the caller may pass the previous token. In
|
||||||
//this case, the reauthentication can be skipped if another thread has already
|
// this case, the reauthentication can be skipped if another thread has already
|
||||||
//reauthenticated in the meantime. If no previous token is known, an empty
|
// reauthenticated in the meantime. If no previous token is known, an empty
|
||||||
//string should be passed instead to force unconditional reauthentication.
|
// string should be passed instead to force unconditional reauthentication.
|
||||||
func (client *ProviderClient) Reauthenticate(previousToken string) (err error) {
|
func (client *ProviderClient) Reauthenticate(previousToken string) (err error) {
|
||||||
if client.ReauthFunc == nil {
|
if client.ReauthFunc == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -139,11 +148,25 @@ func (client *ProviderClient) Reauthenticate(previousToken string) (err error) {
|
||||||
if client.mut == nil {
|
if client.mut == nil {
|
||||||
return client.ReauthFunc()
|
return client.ReauthFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client.reauthmut.Lock()
|
||||||
|
if client.reauthmut.reauthing {
|
||||||
|
for !client.reauthmut.reauthing {
|
||||||
|
client.reauthmut.done.Wait()
|
||||||
|
}
|
||||||
|
err = client.reauthmut.reauthingErr
|
||||||
|
client.reauthmut.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client.reauthmut.Unlock()
|
||||||
|
|
||||||
client.mut.Lock()
|
client.mut.Lock()
|
||||||
defer client.mut.Unlock()
|
defer client.mut.Unlock()
|
||||||
|
|
||||||
client.reauthmut.Lock()
|
client.reauthmut.Lock()
|
||||||
client.reauthmut.reauthing = true
|
client.reauthmut.reauthing = true
|
||||||
|
client.reauthmut.done = sync.NewCond(client.reauthmut)
|
||||||
|
client.reauthmut.reauthingErr = nil
|
||||||
client.reauthmut.Unlock()
|
client.reauthmut.Unlock()
|
||||||
|
|
||||||
if previousToken == "" || client.TokenID == previousToken {
|
if previousToken == "" || client.TokenID == previousToken {
|
||||||
|
@ -152,6 +175,8 @@ func (client *ProviderClient) Reauthenticate(previousToken string) (err error) {
|
||||||
|
|
||||||
client.reauthmut.Lock()
|
client.reauthmut.Lock()
|
||||||
client.reauthmut.reauthing = false
|
client.reauthmut.reauthing = false
|
||||||
|
client.reauthmut.reauthingErr = err
|
||||||
|
client.reauthmut.done.Broadcast()
|
||||||
client.reauthmut.Unlock()
|
client.reauthmut.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -192,7 +217,7 @@ func (client *ProviderClient) Request(method, url string, options *RequestOpts)
|
||||||
// io.ReadSeeker as-is. Default the content-type to application/json.
|
// io.ReadSeeker as-is. Default the content-type to application/json.
|
||||||
if options.JSONBody != nil {
|
if options.JSONBody != nil {
|
||||||
if options.RawBody != nil {
|
if options.RawBody != nil {
|
||||||
panic("Please provide only one of JSONBody or RawBody to gophercloud.Request().")
|
return nil, errors.New("please provide only one of JSONBody or RawBody to gophercloud.Request()")
|
||||||
}
|
}
|
||||||
|
|
||||||
rendered, err := json.Marshal(options.JSONBody)
|
rendered, err := json.Marshal(options.JSONBody)
|
||||||
|
@ -378,7 +403,7 @@ func defaultOkCodes(method string) []int {
|
||||||
case method == "PUT":
|
case method == "PUT":
|
||||||
return []int{201, 202}
|
return []int{201, 202}
|
||||||
case method == "PATCH":
|
case method == "PATCH":
|
||||||
return []int{200, 204}
|
return []int{200, 202, 204}
|
||||||
case method == "DELETE":
|
case method == "DELETE":
|
||||||
return []int{202, 204}
|
return []int{202, 204}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,23 +89,47 @@ func (r Result) extractIntoPtr(to interface{}, label string) error {
|
||||||
if typeOfV.Kind() == reflect.Struct {
|
if typeOfV.Kind() == reflect.Struct {
|
||||||
if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous {
|
if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous {
|
||||||
newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0)
|
newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0)
|
||||||
newType := reflect.New(typeOfV).Elem()
|
|
||||||
|
|
||||||
for _, v := range m[label].([]interface{}) {
|
if mSlice, ok := m[label].([]interface{}); ok {
|
||||||
b, err := json.Marshal(v)
|
for _, v := range mSlice {
|
||||||
if err != nil {
|
// For each iteration of the slice, we create a new struct.
|
||||||
return err
|
// This is to work around a bug where elements of a slice
|
||||||
}
|
// are reused and not overwritten when the same copy of the
|
||||||
|
// struct is used:
|
||||||
|
//
|
||||||
|
// https://github.com/golang/go/issues/21092
|
||||||
|
// https://github.com/golang/go/issues/24155
|
||||||
|
// https://play.golang.org/p/NHo3ywlPZli
|
||||||
|
newType := reflect.New(typeOfV).Elem()
|
||||||
|
|
||||||
for i := 0; i < newType.NumField(); i++ {
|
b, err := json.Marshal(v)
|
||||||
s := newType.Field(i).Addr().Interface()
|
|
||||||
err = json.NewDecoder(bytes.NewReader(b)).Decode(s)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is needed for structs with an UnmarshalJSON method.
|
||||||
|
// Technically this is just unmarshalling the response into
|
||||||
|
// a struct that is never used, but it's good enough to
|
||||||
|
// trigger the UnmarshalJSON method.
|
||||||
|
for i := 0; i < newType.NumField(); i++ {
|
||||||
|
s := newType.Field(i).Addr().Interface()
|
||||||
|
|
||||||
|
// Unmarshal is used rather than NewDecoder to also work
|
||||||
|
// around the above-mentioned bug.
|
||||||
|
err = json.Unmarshal(b, s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newSlice = reflect.Append(newSlice, newType)
|
||||||
}
|
}
|
||||||
newSlice = reflect.Append(newSlice, newType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "to" should now be properly modeled to receive the
|
||||||
|
// JSON response body and unmarshal into all the correct
|
||||||
|
// fields of the struct or composed extension struct
|
||||||
|
// at the end of this method.
|
||||||
toValue.Set(newSlice)
|
toValue.Set(newSlice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,6 +369,48 @@ func (jt *JSONRFC3339NoZ) UnmarshalJSON(data []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RFC3339ZNoT is the time format used in Zun (Containers Service).
|
||||||
|
const RFC3339ZNoT = "2006-01-02 15:04:05-07:00"
|
||||||
|
|
||||||
|
type JSONRFC3339ZNoT time.Time
|
||||||
|
|
||||||
|
func (jt *JSONRFC3339ZNoT) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(data, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if s == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
t, err := time.Parse(RFC3339ZNoT, s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*jt = JSONRFC3339ZNoT(t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RFC3339ZNoTNoZ is another time format used in Zun (Containers Service).
|
||||||
|
const RFC3339ZNoTNoZ = "2006-01-02 15:04:05"
|
||||||
|
|
||||||
|
type JSONRFC3339ZNoTNoZ time.Time
|
||||||
|
|
||||||
|
func (jt *JSONRFC3339ZNoTNoZ) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(data, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if s == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
t, err := time.Parse(RFC3339ZNoTNoZ, s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*jt = JSONRFC3339ZNoTNoZ(t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Link is an internal type to be used in packages of collection resources that are
|
Link is an internal type to be used in packages of collection resources that are
|
||||||
paginated in a certain way.
|
paginated in a certain way.
|
||||||
|
|
|
@ -28,6 +28,10 @@ type ServiceClient struct {
|
||||||
|
|
||||||
// The microversion of the service to use. Set this to use a particular microversion.
|
// The microversion of the service to use. Set this to use a particular microversion.
|
||||||
Microversion string
|
Microversion string
|
||||||
|
|
||||||
|
// MoreHeaders allows users (or Gophercloud) to set service-wide headers on requests. Put another way,
|
||||||
|
// values set in this field will be set on all the HTTP requests the service client sends.
|
||||||
|
MoreHeaders map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceBaseURL returns the base URL of any resources used by this service. It MUST end with a /.
|
// ResourceBaseURL returns the base URL of any resources used by this service. It MUST end with a /.
|
||||||
|
@ -108,6 +112,15 @@ func (client *ServiceClient) Delete(url string, opts *RequestOpts) (*http.Respon
|
||||||
return client.Request("DELETE", url, opts)
|
return client.Request("DELETE", url, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Head calls `Request` with the "HEAD" HTTP verb.
|
||||||
|
func (client *ServiceClient) Head(url string, opts *RequestOpts) (*http.Response, error) {
|
||||||
|
if opts == nil {
|
||||||
|
opts = new(RequestOpts)
|
||||||
|
}
|
||||||
|
client.initReqOpts(url, nil, nil, opts)
|
||||||
|
return client.Request("HEAD", url, opts)
|
||||||
|
}
|
||||||
|
|
||||||
func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) {
|
func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) {
|
||||||
switch client.Type {
|
switch client.Type {
|
||||||
case "compute":
|
case "compute":
|
||||||
|
@ -122,3 +135,16 @@ func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) {
|
||||||
opts.MoreHeaders["OpenStack-API-Version"] = client.Type + " " + client.Microversion
|
opts.MoreHeaders["OpenStack-API-Version"] = client.Type + " " + client.Microversion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Request carries out the HTTP operation for the service client
|
||||||
|
func (client *ServiceClient) Request(method, url string, options *RequestOpts) (*http.Response, error) {
|
||||||
|
if len(client.MoreHeaders) > 0 {
|
||||||
|
if options == nil {
|
||||||
|
options = new(RequestOpts)
|
||||||
|
}
|
||||||
|
for k, v := range client.MoreHeaders {
|
||||||
|
options.MoreHeaders[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return client.ProviderClient.Request(method, url, options)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue