diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index e004508adc..42c712e8bf 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -2101,123 +2101,127 @@ }, { "ImportPath": "github.com/gophercloud/gophercloud", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/common/extensions", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/images", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "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", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "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", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "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", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "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", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/networks", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/utils", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/pagination", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gorilla/websocket", diff --git a/Godeps/LICENSES b/Godeps/LICENSES index 41628249ad..5357ed5896 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -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: = diff --git a/pkg/cloudprovider/providers/openstack/openstack_volumes.go b/pkg/cloudprovider/providers/openstack/openstack_volumes.go index 68b8f92a81..fa4c4d5976 100644 --- a/pkg/cloudprovider/providers/openstack/openstack_volumes.go +++ b/pkg/cloudprovider/providers/openstack/openstack_volumes.go @@ -256,7 +256,7 @@ func (volumes *VolumesV1) deleteVolume(volumeID string) error { func (volumes *VolumesV2) deleteVolume(volumeID string) error { 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() recordOpenstackOperationMetric("delete_v2_volume", timeTaken, err) return err @@ -264,7 +264,7 @@ func (volumes *VolumesV2) deleteVolume(volumeID string) error { func (volumes *VolumesV3) deleteVolume(volumeID string) error { 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() recordOpenstackOperationMetric("delete_v3_volume", timeTaken, err) return err diff --git a/staging/src/k8s.io/client-go/Godeps/Godeps.json b/staging/src/k8s.io/client-go/Godeps/Godeps.json index 963b5084c1..4ea1f5dc05 100644 --- a/staging/src/k8s.io/client-go/Godeps/Godeps.json +++ b/staging/src/k8s.io/client-go/Godeps/Godeps.json @@ -112,31 +112,31 @@ }, { "ImportPath": "github.com/gophercloud/gophercloud", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/utils", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gophercloud/gophercloud/pagination", - "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" + "Rev": "c818fa66e4c88b30db28038fe3f18f2f4a0db9a8" }, { "ImportPath": "github.com/gregjones/httpcache", diff --git a/vendor/github.com/gophercloud/gophercloud/.gitignore b/vendor/github.com/gophercloud/gophercloud/.gitignore index df9048a010..dd91ed2055 100644 --- a/vendor/github.com/gophercloud/gophercloud/.gitignore +++ b/vendor/github.com/gophercloud/gophercloud/.gitignore @@ -1,2 +1,3 @@ **/*.swp .idea +.vscode diff --git a/vendor/github.com/gophercloud/gophercloud/.travis.yml b/vendor/github.com/gophercloud/gophercloud/.travis.yml index 59c4194952..02728f4968 100644 --- a/vendor/github.com/gophercloud/gophercloud/.travis.yml +++ b/vendor/github.com/gophercloud/gophercloud/.travis.yml @@ -7,8 +7,8 @@ install: - go get github.com/mattn/goveralls - go get golang.org/x/tools/cmd/goimports go: -- 1.8 -- tip +- "1.10" +- "tip" env: global: - secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ=" diff --git a/vendor/github.com/gophercloud/gophercloud/.zuul.yaml b/vendor/github.com/gophercloud/gophercloud/.zuul.yaml index c259d03e18..8c31ea160e 100644 --- a/vendor/github.com/gophercloud/gophercloud/.zuul.yaml +++ b/vendor/github.com/gophercloud/gophercloud/.zuul.yaml @@ -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: name: gophercloud/gophercloud check: @@ -7,6 +77,22 @@ recheck-mitaka: jobs: - gophercloud-acceptance-test-mitaka + recheck-newton: + jobs: + - gophercloud-acceptance-test-newton + recheck-ocata: + jobs: + - gophercloud-acceptance-test-ocata recheck-pike: jobs: - 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 diff --git a/vendor/github.com/gophercloud/gophercloud/FAQ.md b/vendor/github.com/gophercloud/gophercloud/FAQ.md deleted file mode 100644 index 88a366a288..0000000000 --- a/vendor/github.com/gophercloud/gophercloud/FAQ.md +++ /dev/null @@ -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 `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 -} -// ... -``` diff --git a/vendor/github.com/gophercloud/gophercloud/MIGRATING.md b/vendor/github.com/gophercloud/gophercloud/MIGRATING.md deleted file mode 100644 index aa383c9cc9..0000000000 --- a/vendor/github.com/gophercloud/gophercloud/MIGRATING.md +++ /dev/null @@ -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` diff --git a/vendor/github.com/gophercloud/gophercloud/README.md b/vendor/github.com/gophercloud/gophercloud/README.md index bb218c3fe9..ad29041d9b 100644 --- a/vendor/github.com/gophercloud/gophercloud/README.md +++ b/vendor/github.com/gophercloud/gophercloud/README.md @@ -127,7 +127,7 @@ new resource in the `server` variable (a ## 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 @@ -140,7 +140,7 @@ See the [contributing guide](./.github/CONTRIBUTING.md). ## Help and feedback 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 @@ -148,12 +148,12 @@ We'd like to extend special thanks and appreciation to the following: ### OpenLab - + OpenLab is providing a full CI environment to test each PR and merge for a variety of OpenStack releases. ### VEXXHOST - + VEXXHOST is providing their services to assist with the development and testing of Gophercloud. diff --git a/vendor/github.com/gophercloud/gophercloud/STYLEGUIDE.md b/vendor/github.com/gophercloud/gophercloud/STYLEGUIDE.md deleted file mode 100644 index 22a2900941..0000000000 --- a/vendor/github.com/gophercloud/gophercloud/STYLEGUIDE.md +++ /dev/null @@ -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 ` (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 `OptsBuilder` (eg `CreateOptsBuilder`). - This `interface` should have at the least a method named `ToMap` - (eg `ToPortCreateMap`). - -- Functions in `requests.go` that accept query strings should accept as their - last parameter an `interface` named `OptsBuilder` (eg `ListOptsBuilder`). - This `interface` should have at the least a method named `ToQuery` - (eg `ToServerListQuery`). diff --git a/vendor/github.com/gophercloud/gophercloud/auth_options.go b/vendor/github.com/gophercloud/gophercloud/auth_options.go index 4211470020..5ffa8d1e0a 100644 --- a/vendor/github.com/gophercloud/gophercloud/auth_options.go +++ b/vendor/github.com/gophercloud/gophercloud/auth_options.go @@ -81,6 +81,23 @@ type AuthOptions struct { // TokenID allows users to authenticate (possibly as another user) with an // authentication token ID. 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 @@ -131,7 +148,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s type userReq struct { ID *string `json:"id,omitempty"` Name *string `json:"name,omitempty"` - Password string `json:"password"` + Password string `json:"password,omitempty"` Domain *domainReq `json:"domain,omitempty"` } @@ -143,10 +160,18 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s 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 { - Methods []string `json:"methods"` - Password *passwordReq `json:"password,omitempty"` - Token *tokenReq `json:"token,omitempty"` + Methods []string `json:"methods"` + Password *passwordReq `json:"password,omitempty"` + Token *tokenReq `json:"token,omitempty"` + ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"` } type authReq struct { @@ -183,8 +208,68 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s req.Auth.Identity.Token = &tokenReq{ 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 { - // 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{} } } else { @@ -263,85 +348,83 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s } func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { - - var scope struct { - ProjectID string - ProjectName string - DomainID string - DomainName string - } - - if opts.TenantID != "" { - scope.ProjectID = opts.TenantID - } else { - if opts.TenantName != "" { - scope.ProjectName = opts.TenantName - scope.DomainID = opts.DomainID - scope.DomainName = opts.DomainName + // For backwards compatibility. + // If AuthOptions.Scope was not set, try to determine it. + // This works well for common scenarios. + if opts.Scope == nil { + opts.Scope = new(AuthScope) + if opts.TenantID != "" { + opts.Scope.ProjectID = opts.TenantID + } else { + if opts.TenantName != "" { + opts.Scope.ProjectName = opts.TenantName + opts.Scope.DomainID = opts.DomainID + opts.Scope.DomainName = opts.DomainName + } } } - if scope.ProjectName != "" { + if opts.Scope.ProjectName != "" { // ProjectName provided: either DomainID or DomainName must also be supplied. // ProjectID may not be supplied. - if scope.DomainID == "" && scope.DomainName == "" { + if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" { return nil, ErrScopeDomainIDOrDomainName{} } - if scope.ProjectID != "" { + if opts.Scope.ProjectID != "" { return nil, ErrScopeProjectIDOrProjectName{} } - if scope.DomainID != "" { + if opts.Scope.DomainID != "" { // ProjectName + DomainID return map[string]interface{}{ "project": map[string]interface{}{ - "name": &scope.ProjectName, - "domain": map[string]interface{}{"id": &scope.DomainID}, + "name": &opts.Scope.ProjectName, + "domain": map[string]interface{}{"id": &opts.Scope.DomainID}, }, }, nil } - if scope.DomainName != "" { + if opts.Scope.DomainName != "" { // ProjectName + DomainName return map[string]interface{}{ "project": map[string]interface{}{ - "name": &scope.ProjectName, - "domain": map[string]interface{}{"name": &scope.DomainName}, + "name": &opts.Scope.ProjectName, + "domain": map[string]interface{}{"name": &opts.Scope.DomainName}, }, }, nil } - } else if scope.ProjectID != "" { + } else if opts.Scope.ProjectID != "" { // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided. - if scope.DomainID != "" { + if opts.Scope.DomainID != "" { return nil, ErrScopeProjectIDAlone{} } - if scope.DomainName != "" { + if opts.Scope.DomainName != "" { return nil, ErrScopeProjectIDAlone{} } // ProjectID return map[string]interface{}{ "project": map[string]interface{}{ - "id": &scope.ProjectID, + "id": &opts.Scope.ProjectID, }, }, nil - } else if scope.DomainID != "" { + } else if opts.Scope.DomainID != "" { // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. - if scope.DomainName != "" { + if opts.Scope.DomainName != "" { return nil, ErrScopeDomainIDOrDomainName{} } // DomainID return map[string]interface{}{ "domain": map[string]interface{}{ - "id": &scope.DomainID, + "id": &opts.Scope.DomainID, }, }, nil - } else if scope.DomainName != "" { + } else if opts.Scope.DomainName != "" { // DomainName return map[string]interface{}{ "domain": map[string]interface{}{ - "name": &scope.DomainName, + "name": &opts.Scope.DomainName, }, }, nil } diff --git a/vendor/github.com/gophercloud/gophercloud/doc.go b/vendor/github.com/gophercloud/gophercloud/doc.go index 30067aa352..131cc8e303 100644 --- a/vendor/github.com/gophercloud/gophercloud/doc.go +++ b/vendor/github.com/gophercloud/gophercloud/doc.go @@ -41,7 +41,7 @@ pass in the parent provider, like so: opts := gophercloud.EndpointOpts{Region: "RegionOne"} - client := openstack.NewComputeV2(provider, opts) + client, err := openstack.NewComputeV2(provider, opts) Resources diff --git a/vendor/github.com/gophercloud/gophercloud/errors.go b/vendor/github.com/gophercloud/gophercloud/errors.go index 2466932efe..4bf1024684 100644 --- a/vendor/github.com/gophercloud/gophercloud/errors.go +++ b/vendor/github.com/gophercloud/gophercloud/errors.go @@ -1,6 +1,9 @@ package gophercloud -import "fmt" +import ( + "fmt" + "strings" +) // BaseError is an error type that all other error types embed. type BaseError struct { @@ -43,6 +46,33 @@ func (e ErrInvalidInput) Error() string { 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 // those listed in OkCodes is encountered. type ErrUnexpectedResponseCode struct { @@ -108,7 +138,11 @@ type ErrDefault503 struct { } 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 { return "Authentication failed" @@ -417,3 +451,10 @@ type ErrScopeEmpty struct{ BaseError } func (e ErrScopeEmpty) Error() string { 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" +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go b/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go index b5482ba8c9..0bb1f48375 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go @@ -38,6 +38,9 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) { tenantName := os.Getenv("OS_TENANT_NAME") domainID := os.Getenv("OS_DOMAIN_ID") 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 v := os.Getenv("OS_PROJECT_ID"); v != "" { @@ -50,29 +53,61 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) { } if authURL == "" { - err := gophercloud.ErrMissingInput{Argument: "authURL"} + err := gophercloud.ErrMissingEnvironmentVariable{ + EnvironmentVariable: "OS_AUTH_URL", + } return nilOptions, err } - if username == "" && userID == "" { - err := gophercloud.ErrMissingInput{Argument: "username"} + if userID == "" && 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 } - if password == "" { - err := gophercloud.ErrMissingInput{Argument: "password"} + if (applicationCredentialID != "" || applicationCredentialName != "") && applicationCredentialSecret == "" { + err := gophercloud.ErrMissingEnvironmentVariable{ + EnvironmentVariable: "OS_APPLICATION_CREDENTIAL_SECRET", + } 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{ - IdentityEndpoint: authURL, - UserID: userID, - Username: username, - Password: password, - TenantID: tenantID, - TenantName: tenantName, - DomainID: domainID, - DomainName: domainName, + IdentityEndpoint: authURL, + UserID: userID, + Username: username, + Password: password, + TenantID: tenantID, + TenantName: tenantName, + DomainID: domainID, + DomainName: domainName, + ApplicationCredentialID: applicationCredentialID, + ApplicationCredentialName: applicationCredentialName, + ApplicationCredentialSecret: applicationCredentialSecret, } return ao, nil diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go index 566def5181..1da94238b9 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go @@ -110,8 +110,8 @@ type UpdateOptsBuilder interface { // to the volumes.Update function. For more information about the parameters, see // the Volume object. type UpdateOpts struct { - Name string `json:"display_name,omitempty"` - Description string `json:"display_description,omitempty"` + Name *string `json:"display_name,omitempty"` + Description *string `json:"display_description,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) { count := 0 id := "" - pages, err := List(client, nil).AllPages() + + listOpts := ListOpts{ + Name: name, + } + + pages, err := List(client, listOpts).AllPages() if err != nil { return "", err } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go index 2ec10ad55e..c27ddbf67c 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go @@ -61,9 +61,37 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create 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. -func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) +func Delete(client *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) { + 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 } @@ -98,6 +126,19 @@ type ListOpts struct { // TenantID will filter by a specific tenant/project ID. // Setting AllTenants is required for this. TenantID string `q:"project_id"` + + // Comma-separated list of sort keys and optional sort directions in the + // form of [:]. + 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. @@ -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 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 // the Volume object. type UpdateOpts struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,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) { count := 0 id := "" - pages, err := List(client, nil).AllPages() + + listOpts := ListOpts{ + Name: name, + } + + pages, err := List(client, listOpts).AllPages() if err != nil { return "", err } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go index 674ec34686..96572b01b4 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go @@ -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. type VolumePage struct { - pagination.SinglePageBase + pagination.LinkedPageBase } // IsEmpty returns true if a ListResult contains no Volumes. @@ -107,6 +107,19 @@ func (r VolumePage) IsEmpty() (bool, error) { 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. func ExtractVolumes(r pagination.Page) ([]Volume, error) { var s []Volume diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go index 43727409dd..25f70b27c1 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go @@ -38,6 +38,8 @@ type CreateOpts struct { ImageID string `json:"imageRef,omitempty"` // The associated volume type 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 @@ -61,9 +63,37 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create 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. -func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) +func Delete(client *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) { + 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 } @@ -145,8 +175,8 @@ type UpdateOptsBuilder interface { // to the volumes.Update function. For more information about the parameters, see // the Volume object. type UpdateOpts struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,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) { count := 0 id := "" - pages, err := List(client, nil).AllPages() + + listOpts := ListOpts{ + Name: name, + } + + pages, err := List(client, listOpts).AllPages() if err != nil { return "", err } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/client.go b/vendor/github.com/gophercloud/gophercloud/openstack/client.go index 85705d2126..7a7a1803f1 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/client.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/client.go @@ -2,10 +2,7 @@ package openstack import ( "fmt" - "net/url" "reflect" - "regexp" - "strings" "github.com/gophercloud/gophercloud" 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{}) */ func NewClient(endpoint string) (*gophercloud.ProviderClient, error) { - u, err := url.Parse(endpoint) + base, err := utils.BaseEndpoint(endpoint) if err != nil { 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) 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`, // this should retry authentication only once tac := *client + tac.IsThrowaway = true tac.ReauthFunc = nil tac.TokenID = "" 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`, // this should retry authentication only once tac := *client + tac.IsThrowaway = true tac.ReauthFunc = nil tac.TokenID = "" var tao tokens3.AuthOptionsBuilder @@ -287,11 +276,17 @@ func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOp // Ensure endpoint still has a suffix of v3. // This is because EndpointLocator might have found a versionless - // endpoint and requests will fail unless targeted at /v3. - if !strings.HasSuffix(endpoint, "v3/") { - endpoint = endpoint + "v3/" + // endpoint or the published endpoint is still /v2.0. In both + // cases, we need to fix the endpoint to point to /v3. + base, err := utils.BaseEndpoint(endpoint) + if err != nil { + return nil, err } + base = gophercloud.NormalizeURL(base) + + endpoint = base + "v3/" + return &gophercloud.ServiceClient{ ProviderClient: client, 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) { 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") +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go index 18dade837c..874f7a61ec 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go @@ -28,7 +28,6 @@ type CreateOptsBuilder interface { // CreateOpts specifies parameters of a new interface attachment. type CreateOpts struct { - // PortID is the ID of the port for which you want to create an interface. // The NetworkID and PortID parameters are mutually exclusive. // 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 // 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"` } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go index a16fa14f75..7d15e1ecb4 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go @@ -37,8 +37,10 @@ type DeleteResult struct { } // 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 { - SubnetID string `json:"subnet_id"` + SubnetID string `json:"subnet_id,omitempty"` IPAddress string `json:"ip_address"` } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go index 4b406df957..539019e90d 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go @@ -52,6 +52,14 @@ type ListOpts struct { MinDisk int `q:"minDisk"` 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 instructs List where to start listing from. Marker string `q:"marker"` diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go index 525cddaea2..92fe1b1809 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go @@ -59,7 +59,7 @@ type Flavor struct { RxTxFactor float64 `json:"rxtx_factor"` // 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 int `json:"vcpus"` diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go index 626eb63e91..a6530f8d65 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go @@ -383,7 +383,7 @@ type RebootOpts struct { } // 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") } @@ -545,39 +545,6 @@ func RevertResize(client *gophercloud.ServiceClient, id string) (r ActionResult) 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 // the Reset request. 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) { count := 0 id := "" - allPages, err := List(client, nil).AllPages() + + listOpts := ListOpts{ + Name: name, + } + + allPages, err := List(client, listOpts).AllPages() if err != nil { 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) 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 +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go index c6c1ff43f7..f973d1ea0e 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go @@ -68,18 +68,27 @@ type ActionResult struct { 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 // ExtractImageID method to retrieve the ID of the newly created image. type CreateImageResult struct { 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. // Call its ExtractPassword method to retrieve the password. type GetPasswordResult struct { @@ -134,15 +143,6 @@ func (r CreateImageResult) ExtractImageID() (string, error) { 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. type Server struct { // ID uniquely identifies this server amongst all other servers, diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go index 60f58c8ce3..f21a58f10c 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go @@ -85,7 +85,7 @@ type UpdateOpts struct { Name string `json:"name,omitempty"` // 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 *bool `json:"enabled,omitempty"` diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go index ca35851e4a..2d20fa6f4b 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go @@ -52,19 +52,28 @@ type AuthOptions struct { // authentication token ID. 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:"-"` } // ToTokenV3CreateMap builds a request body from AuthOptions. func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) { gophercloudAuthOpts := gophercloud.AuthOptions{ - Username: opts.Username, - UserID: opts.UserID, - Password: opts.Password, - DomainID: opts.DomainID, - DomainName: opts.DomainName, - AllowReauth: opts.AllowReauth, - TokenID: opts.TokenID, + Username: opts.Username, + UserID: opts.UserID, + Password: opts.Password, + DomainID: opts.DomainID, + DomainName: opts.DomainName, + AllowReauth: opts.AllowReauth, + TokenID: opts.TokenID, + ApplicationCredentialID: opts.ApplicationCredentialID, + ApplicationCredentialName: opts.ApplicationCredentialName, + ApplicationCredentialSecret: opts.ApplicationCredentialSecret, } 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. func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { - if opts.Scope.ProjectName != "" { - // 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{} - } + scope := gophercloud.AuthScope(opts.Scope) - if opts.Scope.DomainID != "" { - // ProjectName + DomainID - return map[string]interface{}{ - "project": map[string]interface{}{ - "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 + gophercloudAuthOpts := gophercloud.AuthOptions{ + Scope: &scope, + DomainID: opts.DomainID, + DomainName: opts.DomainName, } - return nil, nil + return gophercloudAuthOpts.ToTokenV3ScopeMap() } 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. 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), OkCodes: []int{200, 204, 404}, }) diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/BUILD b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/BUILD index e0a9439818..fbdc351b89 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/BUILD +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/BUILD @@ -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/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/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/loadbalancers:all-srcs", "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors:all-srcs", diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/BUILD b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/BUILD index 1987a7b5d6..3f9a188103 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/BUILD +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/BUILD @@ -10,7 +10,10 @@ go_library( importmap = "k8s.io/kubernetes/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external", importpath = "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external", 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( diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/doc.go index b8261684e7..eda010cb0c 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/doc.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/doc.go @@ -4,6 +4,13 @@ extension for the OpenStack Networking service. Example to List Networks with External Information + iTrue := true + networkListOpts := networks.ListOpts{} + listOpts := external.ListOptsExt{ + ListOptsBuilder: networkListOpts, + External: &iTrue, + } + type NetworkWithExternalExt struct { networks.Network external.NetworkExternalExt @@ -11,7 +18,7 @@ Example to List Networks with External Information var allNetworks []NetworkWithExternalExt - allPages, err := networks.List(networkClient, nil).AllPages() + allPages, err := networks.List(networkClient, listOpts).AllPages() if err != nil { panic(err) } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/requests.go index f28e574612..ced5efed8d 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/requests.go @@ -1,9 +1,37 @@ package external import ( + "net/url" + "strconv" + + "github.com/gophercloud/gophercloud" "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 // resources. It embeds networks.CreateOpts and so inherits all of its required // and optional fields, with the addition of the External field. diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/doc.go index bf5ec6807c..a71a3ec88a 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/doc.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/doc.go @@ -52,7 +52,7 @@ Example to Disassociate a Floating IP with a Port fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7" updateOpts := floatingips.UpdateOpts{ - PortID: nil, + PortID: new(string), } fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract() diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go index d82a1bc8e2..77efef6869 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go @@ -12,6 +12,7 @@ import ( // either `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { ID string `q:"id"` + Description string `q:"description"` FloatingNetworkID string `q:"floating_network_id"` PortID string `q:"port_id"` FixedIP string `q:"fixed_ip_address"` @@ -24,6 +25,10 @@ type ListOpts struct { SortDir string `q:"sort_dir"` RouterID string `q:"router_id"` 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 @@ -50,6 +55,7 @@ type CreateOptsBuilder interface { // resource. The only required fields are FloatingNetworkID and PortID which // refer to the external network and internal port respectively. type CreateOpts struct { + Description string `json:"description,omitempty"` FloatingNetworkID string `json:"floating_network_id" required:"true"` FloatingIP string `json:"floating_ip_address,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 // ID. To disassociate the floating IP from all ports, provide an empty string. 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 // interface 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go index 8b1a517645..b0b25a9d66 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go @@ -15,6 +15,9 @@ type FloatingIP struct { // ID is the unique identifier for the floating IP instance. 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 // IP is to be created. 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 string `json:"router_id"` + + // Tags optionally set via extensions/attributestags + Tags []string `json:"tags"` } type commonResult struct { diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go index 8b2bde530e..cf499f9873 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go @@ -13,6 +13,7 @@ import ( type ListOpts struct { ID string `q:"id"` Name string `q:"name"` + Description string `q:"description"` AdminStateUp *bool `q:"admin_state_up"` Distributed *bool `q:"distributed"` Status string `q:"status"` @@ -22,6 +23,10 @@ type ListOpts struct { Marker string `q:"marker"` 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 @@ -51,6 +56,7 @@ type CreateOptsBuilder interface { // no required values. type CreateOpts struct { Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` AdminStateUp *bool `json:"admin_state_up,omitempty"` Distributed *bool `json:"distributed,omitempty"` TenantID string `json:"tenant_id,omitempty"` @@ -97,6 +103,7 @@ type UpdateOptsBuilder interface { // UpdateOpts contains the values used when updating a router. type UpdateOpts struct { Name string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` AdminStateUp *bool `json:"admin_state_up,omitempty"` Distributed *bool `json:"distributed,omitempty"` GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"` diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go index dffdce8f48..a6fa4a35ea 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go @@ -16,7 +16,7 @@ type GatewayInfo struct { // ExternalFixedIP is the IP address and subnet ID of the external gateway of a // router. type ExternalFixedIP struct { - IPAddress string `json:"ip_address"` + IPAddress string `json:"ip_address,omitempty"` SubnetID string `json:"subnet_id"` } @@ -51,6 +51,9 @@ type Router struct { // unique. Name string `json:"name"` + // Description for the router. + Description string `json:"description"` + // ID is the unique identifier for the router. 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. // Used to make network resources highly available. 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/BUILD b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/BUILD new file mode 100644 index 0000000000..6f361a9121 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/BUILD @@ -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"], +) diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/doc.go new file mode 100644 index 0000000000..813579905c --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/doc.go @@ -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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/requests.go new file mode 100644 index 0000000000..9d2b3a0d35 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/requests.go @@ -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 +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/results.go new file mode 100644 index 0000000000..5153b1b90c --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/results.go @@ -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 +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/urls.go new file mode 100644 index 0000000000..ecb607a8e8 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies/urls.go @@ -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) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/BUILD b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/BUILD index 0226887f10..9ba1b22a93 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/BUILD +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/BUILD @@ -13,6 +13,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//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/pagination:go_default_library", ], diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/requests.go index dd190f606f..f2966b6c44 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/requests.go @@ -10,9 +10,10 @@ type Protocol string // Supported attributes for create/update operations. const ( - ProtocolTCP Protocol = "TCP" - ProtocolHTTP Protocol = "HTTP" - ProtocolHTTPS Protocol = "HTTPS" + ProtocolTCP Protocol = "TCP" + ProtocolHTTP Protocol = "HTTP" + ProtocolHTTPS Protocol = "HTTPS" + ProtocolTerminatedHTTPS Protocol = "TERMINATED_HTTPS" ) // ListOptsBuilder allows extensions to add additional parameters to the @@ -154,10 +155,13 @@ type UpdateOptsBuilder interface { // UpdateOpts represents options for updating a Listener. type UpdateOpts struct { // 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. - Description string `json:"description,omitempty"` + Description *string `json:"description,omitempty"` // The maximum number of connections allowed for the Listener. ConnLimit *int `json:"connection_limit,omitempty"` @@ -175,7 +179,16 @@ type UpdateOpts struct { // ToListenerUpdateMap builds a request body from UpdateOpts. 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/results.go index e0c134ed51..ae10579322 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/results.go @@ -2,6 +2,7 @@ package listeners import ( "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/pagination" ) @@ -54,6 +55,15 @@ type Listener struct { // Pools are the pools which are part of this listener. 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/BUILD b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/BUILD index 501891a21b..407685f313 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/BUILD +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/BUILD @@ -14,6 +14,7 @@ go_library( deps = [ "//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/pools:go_default_library", "//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library", ], ) diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/doc.go index eea43391a8..c6d53a7b05 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/doc.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/doc.go @@ -67,5 +67,13 @@ Example to Get the Status of a Load Balancer if err != nil { 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/requests.go index 1ed23c3c82..f5b1413482 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/requests.go @@ -141,10 +141,10 @@ type UpdateOptsBuilder interface { // operation. type UpdateOpts struct { // 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. - Description string `json:"description,omitempty"` + Description *string `json:"description,omitempty"` // The administrative state of the Loadbalancer. A valid value is true (UP) // 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) 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 +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/results.go index 42fff57131..7f423c933d 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/results.go @@ -3,6 +3,7 @@ package loadbalancers import ( "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/pools" "github.com/gophercloud/gophercloud/pagination" ) @@ -51,6 +52,9 @@ type LoadBalancer struct { // Listeners are the listeners related to this Loadbalancer. 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. @@ -58,6 +62,23 @@ type StatusTree struct { 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 // collection of load balancers. type LoadBalancerPage struct { @@ -124,6 +145,22 @@ func (r GetStatusesResult) Extract() (*StatusTree, error) { 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 // method to interpret it as a LoadBalancer. type CreateResult struct { diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/urls.go index 73cf5dc126..2d2a99b779 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/urls.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/urls.go @@ -3,9 +3,10 @@ package loadbalancers import "github.com/gophercloud/gophercloud" const ( - rootPath = "lbaas" - resourcePath = "loadbalancers" - statusPath = "statuses" + rootPath = "lbaas" + resourcePath = "loadbalancers" + statusPath = "statuses" + statisticsPath = "stats" ) 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 { return c.ServiceURL(rootPath, resourcePath, id, statusPath) } + +func statisticsRootURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(rootPath, resourcePath, id, statisticsPath) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/requests.go index c173e1c64e..f728f5a823 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/requests.go @@ -223,7 +223,7 @@ type UpdateOpts struct { ExpectedCodes string `json:"expected_codes,omitempty"` // 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) // or false (DOWN). diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/results.go index ea832cc5d0..a78f7aeb0f 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/results.go @@ -70,6 +70,10 @@ type Monitor struct { // List of pools that are associated with the health monitor. 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/doc.go index 2d57ed4393..0697148680 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/doc.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/doc.go @@ -13,7 +13,7 @@ Example to List Pools panic(err) } - allPools, err := pools.ExtractMonitors(allPages) + allPools, err := pools.ExtractPools(allPages) if err != nil { panic(err) } @@ -83,12 +83,13 @@ Example to Create a Member poolID := "d67d56a6-4a86-4688-a282-f46444705c64" + weight := 10 createOpts := pools.CreateMemberOpts{ Name: "db", SubnetID: "1981f108-3c48-48d2-b908-30f7d28532c9", Address: "10.0.2.11", ProtocolPort: 80, - Weight: 10, + Weight: &weight, } member, err := pools.CreateMember(networkClient, poolID, createOpts).Extract() @@ -101,9 +102,10 @@ Example to Update a Member poolID := "d67d56a6-4a86-4688-a282-f46444705c64" memberID := "64dba99f-8af8-4200-8882-e32a0660f23e" + weight := 4 updateOpts := pools.UpdateMemberOpts{ Name: "new-name", - Weight: 4, + Weight: &weight, } member, err := pools.UpdateMember(networkClient, poolID, memberID, updateOpts).Extract() diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/requests.go index 11564be83f..f427ae7bf5 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/requests.go @@ -154,10 +154,10 @@ type UpdateOptsBuilder interface { // operation. type UpdateOpts struct { // Name of the pool. - Name string `json:"name,omitempty"` + Name *string `json:"name,omitempty"` // 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 // 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 // a weight of 10 receives five times as much traffic as a member with a // 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 // for the subnet UUID. @@ -317,13 +317,13 @@ type UpdateMemberOptsBuilder interface { // operation. type UpdateMemberOpts struct { // 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 // 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 // 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) // or false (DOWN). diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/results.go index 56790fff99..fba0d3a878 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/results.go @@ -92,6 +92,15 @@ type Pool struct { // The Monitor associated with this Pool. 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 @@ -196,6 +205,15 @@ type Member struct { // The unique ID for the Member. 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go index ebacc6ee34..a22cd306e8 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go @@ -11,14 +11,19 @@ import ( // sort by a particular network attribute. SortDir sets the direction, and is // either `asc' or `desc'. Marker and Limit are used for pagination. type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` + ID string `q:"id"` + Name string `q:"name"` + Description string `q:"description"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + Limit int `q:"limit"` + Marker string `q:"marker"` + 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 @@ -88,7 +93,7 @@ type UpdateOpts struct { Name string `json:"name,omitempty"` // Describes the security group. - Description string `json:"description,omitempty"` + Description *string `json:"description,omitempty"` } // 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) { count := 0 id := "" - pages, err := List(client, ListOpts{}).AllPages() + + listOpts := ListOpts{ + Name: name, + } + + pages, err := List(client, listOpts).AllPages() if err != nil { return "", err } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/results.go index 66915e6e55..468952b3e4 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/results.go @@ -27,6 +27,9 @@ type SecGroup struct { // ProjectID is the project owner of the security group. 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go index 96cce2817d..c7741ffcd2 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go @@ -14,6 +14,7 @@ type ListOpts struct { Direction string `q:"direction"` EtherType string `q:"ethertype"` ID string `q:"id"` + Description string `q:"description"` PortRangeMax int `q:"port_range_max"` PortRangeMin int `q:"port_range_min"` Protocol string `q:"protocol"` @@ -88,6 +89,9 @@ type CreateOpts struct { // group rule is applied. 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 // ingress or egress rules. EtherType RuleEtherType `json:"ethertype" required:"true"` diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/results.go index 377e753140..3bf5501d92 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/results.go @@ -17,6 +17,9 @@ type SecGroupRule struct { // instance. An egress rule is applied to traffic leaving the instance. Direction string + // Descripton of the rule + Description string `json:"description"` + // Must be IPv4 or IPv6, and addresses represented in CIDR must match the // ingress or egress rules. EtherType string `json:"ethertype"` diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go index bc4460a065..d52d099a67 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go @@ -19,6 +19,7 @@ type ListOptsBuilder interface { type ListOpts struct { Status string `q:"status"` Name string `q:"name"` + Description string `q:"description"` AdminStateUp *bool `q:"admin_state_up"` TenantID string `q:"tenant_id"` ProjectID string `q:"project_id"` @@ -28,6 +29,10 @@ type ListOpts struct { Limit int `q:"limit"` 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"` } // ToNetworkListQuery formats a ListOpts into a query string. @@ -69,6 +74,7 @@ type CreateOptsBuilder interface { type CreateOpts struct { AdminStateUp *bool `json:"admin_state_up,omitempty"` Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` Shared *bool `json:"shared,omitempty"` TenantID string `json:"tenant_id,omitempty"` ProjectID string `json:"project_id,omitempty"` @@ -105,9 +111,10 @@ type UpdateOptsBuilder interface { // UpdateOpts represents options used to update a network. type UpdateOpts struct { - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Name string `json:"name,omitempty"` - Shared *bool `json:"shared,omitempty"` + AdminStateUp *bool `json:"admin_state_up,omitempty"` + Name string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + Shared *bool `json:"shared,omitempty"` } // 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) { count := 0 id := "" - pages, err := List(client, nil).AllPages() + + listOpts := ListOpts{ + Name: name, + } + + pages, err := List(client, listOpts).AllPages() if err != nil { return "", err } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go index 62f4b3c3a5..f03067415f 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go @@ -52,6 +52,9 @@ type Network struct { // Human-readable name for the network. Might not be unique. Name string `json:"name"` + // Description for the network + Description string `json:"description"` + // The administrative state of network. If false (down), the network does not // forward packets. 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. // Used to make network resources highly available. 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/requests.go index 90416faa19..f5f7d761ce 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/requests.go @@ -19,6 +19,7 @@ type ListOptsBuilder interface { type ListOpts struct { Status string `q:"status"` Name string `q:"name"` + Description string `q:"description"` AdminStateUp *bool `q:"admin_state_up"` NetworkID string `q:"network_id"` TenantID string `q:"tenant_id"` @@ -31,6 +32,10 @@ type ListOpts struct { Marker string `q:"marker"` 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"` } // ToPortListQuery formats a ListOpts into a query string. @@ -76,6 +81,7 @@ type CreateOptsBuilder interface { type CreateOpts struct { NetworkID string `json:"network_id" required:"true"` Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` AdminStateUp *bool `json:"admin_state_up,omitempty"` MACAddress string `json:"mac_address,omitempty"` FixedIPs interface{} `json:"fixed_ips,omitempty"` @@ -112,11 +118,12 @@ type UpdateOptsBuilder interface { // UpdateOpts represents the attributes used when updating an existing port. 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"` FixedIPs interface{} `json:"fixed_ips,omitempty"` - DeviceID string `json:"device_id,omitempty"` - DeviceOwner string `json:"device_owner,omitempty"` + DeviceID *string `json:"device_id,omitempty"` + DeviceOwner *string `json:"device_owner,omitempty"` SecurityGroups *[]string `json:"security_groups,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) { count := 0 id := "" - pages, err := List(client, nil).AllPages() + + listOpts := ListOpts{ + Name: name, + } + + pages, err := List(client, listOpts).AllPages() if err != nil { return "", err } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/results.go index 66937fd989..3941b62300 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/results.go @@ -68,6 +68,9 @@ type Port struct { // Human-readable name for the port. Might not be unique. Name string `json:"name"` + // Describes the port. + Description string `json:"description"` + // Administrative state of port. If false (down), port does not forward // packets. AdminStateUp bool `json:"admin_state_up"` @@ -101,6 +104,9 @@ type Port struct { // Identifies the list of IP addresses the port will recognize/accept 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 diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/utils/BUILD b/vendor/github.com/gophercloud/gophercloud/openstack/utils/BUILD index 66d31aaabf..e8866231e2 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/utils/BUILD +++ b/vendor/github.com/gophercloud/gophercloud/openstack/utils/BUILD @@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_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", importpath = "github.com/gophercloud/gophercloud/openstack/utils", visibility = ["//visibility:public"], diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go b/vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go new file mode 100644 index 0000000000..40080f7af2 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go @@ -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 +} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/pager.go b/vendor/github.com/gophercloud/gophercloud/pagination/pager.go index 7c65926b72..42c0b2dbe5 100644 --- a/vendor/github.com/gophercloud/gophercloud/pagination/pager.go +++ b/vendor/github.com/gophercloud/gophercloud/pagination/pager.go @@ -41,6 +41,8 @@ type Pager struct { createPage func(r PageResult) Page + firstPage Page + Err error // 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 for { - currentPage, err := p.fetchNextPage(currentURL) - if err != nil { - return err + var currentPage Page + + // 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() @@ -128,23 +139,26 @@ func (p Pager) AllPages() (Page, error) { // body will contain the final concatenated Page body. var body reflect.Value - // Grab a test page to ascertain the page body type. - testPage, err := p.fetchNextPage(p.initialURL) + // Grab a first page to ascertain the page body type. + firstPage, err := p.fetchNextPage(p.initialURL) if err != nil { return nil, err } // Store the page type so we can use reflection to create a new mega-page of // 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 { - 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{}`, // `[]byte`, and `[]interface{}`. - switch pb := testPage.GetBody().(type) { + switch pb := firstPage.GetBody().(type) { case map[string]interface{}: // key is the map key for the page body if the body type is `map[string]interface{}`. var key string diff --git a/vendor/github.com/gophercloud/gophercloud/params.go b/vendor/github.com/gophercloud/gophercloud/params.go index 28ad906856..b9986660cb 100644 --- a/vendor/github.com/gophercloud/gophercloud/params.go +++ b/vendor/github.com/gophercloud/gophercloud/params.go @@ -120,6 +120,22 @@ func BuildRequestBody(opts interface{}, parent string) (map[string]interface{}, 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 zero { //fmt.Printf("value before change: %+v\n", optsValue.Field(i)) @@ -363,9 +379,8 @@ func BuildQueryString(opts interface{}) (*url.URL, error) { } } } else { - // Otherwise, the field is not set. - if len(tags) == 2 && tags[1] == "required" { - // And the field is required. Return an error. + // if the field has a 'required' tag, it can't have a zero-value + if requiredTag := f.Tag.Get("required"); requiredTag == "true" { 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()) } } else { - // Otherwise, the field is not set. - if len(tags) == 2 && tags[1] == "required" { - // And the field is required. Return an error. - return optsMap, fmt.Errorf("Required header not set.") + // if the field has a 'required' tag, it can't have a zero-value + if requiredTag := f.Tag.Get("required"); requiredTag == "true" { + return optsMap, fmt.Errorf("Required header [%s] not set.", f.Name) } } } diff --git a/vendor/github.com/gophercloud/gophercloud/provider_client.go b/vendor/github.com/gophercloud/gophercloud/provider_client.go index 17e4512743..f2aae976cf 100644 --- a/vendor/github.com/gophercloud/gophercloud/provider_client.go +++ b/vendor/github.com/gophercloud/gophercloud/provider_client.go @@ -3,6 +3,7 @@ package gophercloud import ( "bytes" "encoding/json" + "errors" "io" "io/ioutil" "net/http" @@ -71,6 +72,10 @@ type ProviderClient struct { // authentication functions for different Identity service versions. 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 reauthmut *reauthlock @@ -78,19 +83,23 @@ type ProviderClient struct { type reauthlock struct { sync.RWMutex - reauthing bool + reauthing bool + reauthingErr error + done *sync.Cond } // 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) { + if client.IsThrowaway { + return + } if client.reauthmut != nil { - client.reauthmut.RLock() - if client.reauthmut.reauthing { - client.reauthmut.RUnlock() - return + client.reauthmut.Lock() + for client.reauthmut.reauthing { + client.reauthmut.done.Wait() } - client.reauthmut.RUnlock() + client.reauthmut.Unlock() } t := client.Token() if t == "" { @@ -126,11 +135,11 @@ func (client *ProviderClient) SetToken(t string) { client.TokenID = t } -//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 -//this case, the reauthentication can be skipped if another thread has already -//reauthenticated in the meantime. If no previous token is known, an empty -//string should be passed instead to force unconditional reauthentication. +// 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 +// this case, the reauthentication can be skipped if another thread has already +// reauthenticated in the meantime. If no previous token is known, an empty +// string should be passed instead to force unconditional reauthentication. func (client *ProviderClient) Reauthenticate(previousToken string) (err error) { if client.ReauthFunc == nil { return nil @@ -139,11 +148,25 @@ func (client *ProviderClient) Reauthenticate(previousToken string) (err error) { if client.mut == nil { 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() defer client.mut.Unlock() client.reauthmut.Lock() client.reauthmut.reauthing = true + client.reauthmut.done = sync.NewCond(client.reauthmut) + client.reauthmut.reauthingErr = nil client.reauthmut.Unlock() if previousToken == "" || client.TokenID == previousToken { @@ -152,6 +175,8 @@ func (client *ProviderClient) Reauthenticate(previousToken string) (err error) { client.reauthmut.Lock() client.reauthmut.reauthing = false + client.reauthmut.reauthingErr = err + client.reauthmut.done.Broadcast() client.reauthmut.Unlock() 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. if options.JSONBody != 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) @@ -378,7 +403,7 @@ func defaultOkCodes(method string) []int { case method == "PUT": return []int{201, 202} case method == "PATCH": - return []int{200, 204} + return []int{200, 202, 204} case method == "DELETE": return []int{202, 204} } diff --git a/vendor/github.com/gophercloud/gophercloud/results.go b/vendor/github.com/gophercloud/gophercloud/results.go index e64feee19e..94a16bff0b 100644 --- a/vendor/github.com/gophercloud/gophercloud/results.go +++ b/vendor/github.com/gophercloud/gophercloud/results.go @@ -89,23 +89,47 @@ func (r Result) extractIntoPtr(to interface{}, label string) error { if typeOfV.Kind() == reflect.Struct { if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0) - newType := reflect.New(typeOfV).Elem() - for _, v := range m[label].([]interface{}) { - b, err := json.Marshal(v) - if err != nil { - return err - } + if mSlice, ok := m[label].([]interface{}); ok { + for _, v := range mSlice { + // For each iteration of the slice, we create a new struct. + // 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++ { - s := newType.Field(i).Addr().Interface() - err = json.NewDecoder(bytes.NewReader(b)).Decode(s) + b, err := json.Marshal(v) if err != nil { 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) } } @@ -345,6 +369,48 @@ func (jt *JSONRFC3339NoZ) UnmarshalJSON(data []byte) error { 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 paginated in a certain way. diff --git a/vendor/github.com/gophercloud/gophercloud/service_client.go b/vendor/github.com/gophercloud/gophercloud/service_client.go index d1a48fea35..2734510e1b 100644 --- a/vendor/github.com/gophercloud/gophercloud/service_client.go +++ b/vendor/github.com/gophercloud/gophercloud/service_client.go @@ -28,6 +28,10 @@ type ServiceClient struct { // The microversion of the service to use. Set this to use a particular microversion. 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 /. @@ -108,6 +112,15 @@ func (client *ServiceClient) Delete(url string, opts *RequestOpts) (*http.Respon 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) { switch client.Type { case "compute": @@ -122,3 +135,16 @@ func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { 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) +}