From 92fa290eadff8578afbf7aedc227bbc1808d8a42 Mon Sep 17 00:00:00 2001 From: Humble Chirammal Date: Fri, 9 Nov 2018 21:08:56 +0530 Subject: [PATCH] Update heketi dependencies to sha@558b29266ce0a873991ecfb3edc41a668a998514. Fixes # https://github.com/kubernetes/kubernetes/issues/70802 Signed-off-by: Humble Chirammal --- Godeps/Godeps.json | 27 +- Godeps/LICENSES | 258 ++------- vendor/BUILD | 2 +- .../ozzo-validation}/.gitignore | 2 + .../go-ozzo/ozzo-validation/.travis.yml | 16 + .../github.com/go-ozzo/ozzo-validation/BUILD | 41 ++ .../go-ozzo/ozzo-validation/LICENSE | 17 + .../go-ozzo/ozzo-validation/README.md | 534 ++++++++++++++++++ .../go-ozzo/ozzo-validation/UPGRADE.md | 46 ++ .../go-ozzo/ozzo-validation/date.go | 84 +++ .../go-ozzo/ozzo-validation/error.go | 89 +++ .../github.com/go-ozzo/ozzo-validation/in.go | 43 ++ .../ozzo-validation/is}/BUILD | 10 +- .../go-ozzo/ozzo-validation/is/rules.go | 171 ++++++ .../go-ozzo/ozzo-validation/length.go | 81 +++ .../go-ozzo/ozzo-validation/match.go | 47 ++ .../go-ozzo/ozzo-validation/minmax.go | 177 ++++++ .../go-ozzo/ozzo-validation/multipleof.go | 55 ++ .../go-ozzo/ozzo-validation/not_in.go | 45 ++ .../go-ozzo/ozzo-validation/not_nil.go | 32 ++ .../go-ozzo/ozzo-validation/required.go | 42 ++ .../go-ozzo/ozzo-validation/string.go | 48 ++ .../go-ozzo/ozzo-validation/struct.go | 154 +++++ .../go-ozzo/ozzo-validation/util.go | 163 ++++++ .../go-ozzo/ozzo-validation/validation.go | 133 +++++ .../heketi/heketi/client/api/go-client/BUILD | 5 + .../heketi/client/api/go-client/admin.go | 78 +++ .../heketi/client/api/go-client/backup.go | 2 +- .../client/api/go-client/block_volume.go | 160 ++++++ .../heketi/client/api/go-client/client.go | 173 +++++- .../heketi/client/api/go-client/cluster.go | 51 +- .../heketi/heketi/client/api/go-client/db.go | 52 ++ .../heketi/client/api/go-client/device.go | 90 ++- .../heketi/client/api/go-client/logging.go | 78 +++ .../heketi/client/api/go-client/node.go | 38 +- .../heketi/client/api/go-client/operations.go | 46 ++ .../heketi/client/api/go-client/topology.go | 4 + .../heketi/client/api/go-client/volume.go | 111 +++- .../heketi/heketi/pkg/glusterfs/api/BUILD | 4 + .../heketi/heketi/pkg/glusterfs/api/types.go | 405 ++++++++++++- .../github.com/heketi/heketi/pkg/utils/BUILD | 6 - .../heketi/heketi/pkg/utils/bodystring.go | 17 +- .../heketi/heketi/pkg/utils/jsonutils.go | 7 +- .../github.com/heketi/heketi/pkg/utils/log.go | 155 ----- .../heketi/heketi/pkg/utils/sortedstrings.go | 33 -- .../heketi/heketi/pkg/utils/statusgroup.go | 7 +- .../heketi/heketi/pkg/utils/stringset.go | 44 -- .../heketi/heketi/pkg/utils/stringstack.go | 33 -- .../heketi/heketi/pkg/utils/uuid.go | 27 - vendor/github.com/lpabon/godbc/.travis.yml | 13 - vendor/github.com/lpabon/godbc/AUTHORS | 1 - vendor/github.com/lpabon/godbc/LICENSE | 201 ------- vendor/github.com/lpabon/godbc/README.md | 21 - vendor/github.com/lpabon/godbc/godbc.go | 146 ----- vendor/github.com/lpabon/godbc/godbc_prod.go | 42 -- 55 files changed, 3392 insertions(+), 975 deletions(-) rename vendor/github.com/{lpabon/godbc => go-ozzo/ozzo-validation}/.gitignore (93%) create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/.travis.yml create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/BUILD create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/LICENSE create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/README.md create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/UPGRADE.md create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/date.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/error.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/in.go rename vendor/github.com/{lpabon/godbc => go-ozzo/ozzo-validation/is}/BUILD (55%) create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/is/rules.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/length.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/match.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/minmax.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/multipleof.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/not_in.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/not_nil.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/required.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/string.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/struct.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/util.go create mode 100644 vendor/github.com/go-ozzo/ozzo-validation/validation.go create mode 100644 vendor/github.com/heketi/heketi/client/api/go-client/admin.go create mode 100644 vendor/github.com/heketi/heketi/client/api/go-client/block_volume.go create mode 100644 vendor/github.com/heketi/heketi/client/api/go-client/db.go create mode 100644 vendor/github.com/heketi/heketi/client/api/go-client/logging.go create mode 100644 vendor/github.com/heketi/heketi/client/api/go-client/operations.go delete mode 100644 vendor/github.com/heketi/heketi/pkg/utils/log.go delete mode 100644 vendor/github.com/heketi/heketi/pkg/utils/sortedstrings.go delete mode 100644 vendor/github.com/heketi/heketi/pkg/utils/stringset.go delete mode 100644 vendor/github.com/heketi/heketi/pkg/utils/stringstack.go delete mode 100644 vendor/github.com/heketi/heketi/pkg/utils/uuid.go delete mode 100644 vendor/github.com/lpabon/godbc/.travis.yml delete mode 100644 vendor/github.com/lpabon/godbc/AUTHORS delete mode 100644 vendor/github.com/lpabon/godbc/LICENSE delete mode 100644 vendor/github.com/lpabon/godbc/README.md delete mode 100644 vendor/github.com/lpabon/godbc/godbc.go delete mode 100644 vendor/github.com/lpabon/godbc/godbc_prod.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index a5f34bd44c23..521454e9c774 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1639,6 +1639,16 @@ "Comment": "v0.17.2", "Rev": "d2eab7d93009e9215fc85b2faa2c2f2a98c2af48" }, + { + "ImportPath": "github.com/go-ozzo/ozzo-validation", + "Comment": "v3.5.0", + "Rev": "106681dbb37bfa3e7683c4c8129cb7f5925ea3e9" + }, + { + "ImportPath": "github.com/go-ozzo/ozzo-validation/is", + "Comment": "v3.5.0", + "Rev": "106681dbb37bfa3e7683c4c8129cb7f5925ea3e9" + }, { "ImportPath": "github.com/go-sql-driver/mysql", "Comment": "v1.3.0", @@ -2285,18 +2295,18 @@ }, { "ImportPath": "github.com/heketi/heketi/client/api/go-client", - "Comment": "v4.0.0-95-gaaf40619d85fda", - "Rev": "aaf40619d85fda757e7a1c1ea1b5118cea65594b" + "Comment": "v8.0.0-49-g558b29266ce0a8", + "Rev": "558b29266ce0a873991ecfb3edc41a668a998514" }, { "ImportPath": "github.com/heketi/heketi/pkg/glusterfs/api", - "Comment": "v4.0.0-95-gaaf40619d85fda", - "Rev": "aaf40619d85fda757e7a1c1ea1b5118cea65594b" + "Comment": "v8.0.0-49-g558b29266ce0a8", + "Rev": "558b29266ce0a873991ecfb3edc41a668a998514" }, { "ImportPath": "github.com/heketi/heketi/pkg/utils", - "Comment": "v4.0.0-95-gaaf40619d85fda", - "Rev": "aaf40619d85fda757e7a1c1ea1b5118cea65594b" + "Comment": "v8.0.0-49-g558b29266ce0a8", + "Rev": "558b29266ce0a873991ecfb3edc41a668a998514" }, { "ImportPath": "github.com/imdario/mergo", @@ -2408,11 +2418,6 @@ "ImportPath": "github.com/libopenstorage/openstorage/volume", "Rev": "093a0c3888753c2056e7373183693d670c6bba01" }, - { - "ImportPath": "github.com/lpabon/godbc", - "Comment": "v1.0-1-g9577782540c139", - "Rev": "9577782540c1398b710ddae1b86268ba03a19b0c" - }, { "ImportPath": "github.com/magiconair/properties", "Comment": "v1.7.0-4-g61b492c03cf472", diff --git a/Godeps/LICENSES b/Godeps/LICENSES index 8721b49ea49b..0f07f0ddeffe 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -48780,6 +48780,56 @@ third-party archives. ================================================================================ +================================================================================ += vendor/github.com/go-ozzo/ozzo-validation licensed under: = + +The MIT License (MIT) +Copyright (c) 2016, Qiang Xue + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + += vendor/github.com/go-ozzo/ozzo-validation/LICENSE da12d993f2ce14947ad6eec35520b081 +================================================================================ + + +================================================================================ += vendor/github.com/go-ozzo/ozzo-validation/is licensed under: = + +The MIT License (MIT) +Copyright (c) 2016, Qiang Xue + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + += vendor/github.com/go-ozzo/ozzo-validation/LICENSE da12d993f2ce14947ad6eec35520b081 +================================================================================ + + ================================================================================ = vendor/github.com/go-sql-driver/mysql licensed under: = @@ -74190,214 +74240,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ================================================================================ -================================================================================ -= vendor/github.com/lpabon/godbc licensed under: = - -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -= vendor/github.com/lpabon/godbc/LICENSE 6c4db32a2fa8717faffa1d4f10136f47 -================================================================================ - - ================================================================================ = vendor/github.com/magiconair/properties licensed under: = diff --git a/vendor/BUILD b/vendor/BUILD index e9b8a36fc764..cf21ccec5b86 100644 --- a/vendor/BUILD +++ b/vendor/BUILD @@ -207,6 +207,7 @@ filegroup( "//vendor/github.com/go-openapi/strfmt:all-srcs", "//vendor/github.com/go-openapi/swag:all-srcs", "//vendor/github.com/go-openapi/validate:all-srcs", + "//vendor/github.com/go-ozzo/ozzo-validation:all-srcs", "//vendor/github.com/go-sql-driver/mysql:all-srcs", "//vendor/github.com/godbus/dbus:all-srcs", "//vendor/github.com/gogo/protobuf/gogoproto:all-srcs", @@ -296,7 +297,6 @@ filegroup( "//vendor/github.com/libopenstorage/openstorage/pkg/parser:all-srcs", "//vendor/github.com/libopenstorage/openstorage/pkg/units:all-srcs", "//vendor/github.com/libopenstorage/openstorage/volume:all-srcs", - "//vendor/github.com/lpabon/godbc:all-srcs", "//vendor/github.com/magiconair/properties:all-srcs", "//vendor/github.com/mailru/easyjson/buffer:all-srcs", "//vendor/github.com/mailru/easyjson/jlexer:all-srcs", diff --git a/vendor/github.com/lpabon/godbc/.gitignore b/vendor/github.com/go-ozzo/ozzo-validation/.gitignore similarity index 93% rename from vendor/github.com/lpabon/godbc/.gitignore rename to vendor/github.com/go-ozzo/ozzo-validation/.gitignore index 836562412fe8..5a3865c74f70 100644 --- a/vendor/github.com/lpabon/godbc/.gitignore +++ b/vendor/github.com/go-ozzo/ozzo-validation/.gitignore @@ -21,3 +21,5 @@ _testmain.go *.exe *.test +*.prof +.DS_Store diff --git a/vendor/github.com/go-ozzo/ozzo-validation/.travis.yml b/vendor/github.com/go-ozzo/ozzo-validation/.travis.yml new file mode 100644 index 000000000000..fc2af5986180 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/.travis.yml @@ -0,0 +1,16 @@ +language: go + +go: + - 1.8 + - 1.9 + - tip + +install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v + - go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v + +script: + - go test -v -covermode=count -coverprofile=coverage.out + - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci diff --git a/vendor/github.com/go-ozzo/ozzo-validation/BUILD b/vendor/github.com/go-ozzo/ozzo-validation/BUILD new file mode 100644 index 000000000000..96ca75ad1839 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/BUILD @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "date.go", + "error.go", + "in.go", + "length.go", + "match.go", + "minmax.go", + "multipleof.go", + "not_in.go", + "not_nil.go", + "required.go", + "string.go", + "struct.go", + "util.go", + "validation.go", + ], + importmap = "k8s.io/kubernetes/vendor/github.com/go-ozzo/ozzo-validation", + importpath = "github.com/go-ozzo/ozzo-validation", + visibility = ["//visibility:public"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [ + ":package-srcs", + "//vendor/github.com/go-ozzo/ozzo-validation/is:all-srcs", + ], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/go-ozzo/ozzo-validation/LICENSE b/vendor/github.com/go-ozzo/ozzo-validation/LICENSE new file mode 100644 index 000000000000..d235be9cc6df --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/LICENSE @@ -0,0 +1,17 @@ +The MIT License (MIT) +Copyright (c) 2016, Qiang Xue + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/go-ozzo/ozzo-validation/README.md b/vendor/github.com/go-ozzo/ozzo-validation/README.md new file mode 100644 index 000000000000..ca9445d2cf82 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/README.md @@ -0,0 +1,534 @@ +# ozzo-validation + +[![GoDoc](https://godoc.org/github.com/go-ozzo/ozzo-validation?status.png)](http://godoc.org/github.com/go-ozzo/ozzo-validation) +[![Build Status](https://travis-ci.org/go-ozzo/ozzo-validation.svg?branch=master)](https://travis-ci.org/go-ozzo/ozzo-validation) +[![Coverage Status](https://coveralls.io/repos/github/go-ozzo/ozzo-validation/badge.svg?branch=master)](https://coveralls.io/github/go-ozzo/ozzo-validation?branch=master) +[![Go Report](https://goreportcard.com/badge/github.com/go-ozzo/ozzo-validation)](https://goreportcard.com/report/github.com/go-ozzo/ozzo-validation) + +## Description + +ozzo-validation is a Go package that provides configurable and extensible data validation capabilities. +It has the following features: + +* use normal programming constructs rather than error-prone struct tags to specify how data should be validated. +* can validate data of different types, e.g., structs, strings, byte slices, slices, maps, arrays. +* can validate custom data types as long as they implement the `Validatable` interface. +* can validate data types that implement the `sql.Valuer` interface (e.g. `sql.NullString`). +* customizable and well-formatted validation errors. +* provide a rich set of validation rules right out of box. +* extremely easy to create and use custom validation rules. + + +## Requirements + +Go 1.8 or above. + + +## Getting Started + +The ozzo-validation package mainly includes a set of validation rules and two validation methods. You use +validation rules to describe how a value should be considered valid, and you call either `validation.Validate()` +or `validation.ValidateStruct()` to validate the value. + + +### Installation + +Run the following command to install the package: + +``` +go get github.com/go-ozzo/ozzo-validation +go get github.com/go-ozzo/ozzo-validation/is +``` + +### Validating a Simple Value + +For a simple value, such as a string or an integer, you may use `validation.Validate()` to validate it. For example, + +```go +package main + +import ( + "fmt" + + "github.com/go-ozzo/ozzo-validation" + "github.com/go-ozzo/ozzo-validation/is" +) + +func main() { + data := "example" + err := validation.Validate(data, + validation.Required, // not empty + validation.Length(5, 100), // length between 5 and 100 + is.URL, // is a valid URL + ) + fmt.Println(err) + // Output: + // must be a valid URL +} +``` + +The method `validation.Validate()` will run through the rules in the order that they are listed. If a rule fails +the validation, the method will return the corresponding error and skip the rest of the rules. The method will +return nil if the value passes all validation rules. + + +### Validating a Struct + +For a struct value, you usually want to check if its fields are valid. For example, in a RESTful application, you +may unmarshal the request payload into a struct and then validate the struct fields. If one or multiple fields +are invalid, you may want to get an error describing which fields are invalid. You can use `validation.ValidateStruct()` +to achieve this purpose. A single struct can have rules for multiple fields, and a field can be associated with multiple +rules. For example, + +```go +package main + +import ( + "fmt" + "regexp" + + "github.com/go-ozzo/ozzo-validation" + "github.com/go-ozzo/ozzo-validation/is" +) + +type Address struct { + Street string + City string + State string + Zip string +} + +func (a Address) Validate() error { + return validation.ValidateStruct(&a, + // Street cannot be empty, and the length must between 5 and 50 + validation.Field(&a.Street, validation.Required, validation.Length(5, 50)), + // City cannot be empty, and the length must between 5 and 50 + validation.Field(&a.City, validation.Required, validation.Length(5, 50)), + // State cannot be empty, and must be a string consisting of two letters in upper case + validation.Field(&a.State, validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))), + // State cannot be empty, and must be a string consisting of five digits + validation.Field(&a.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), + ) +} + +func main() { + a := Address{ + Street: "123", + City: "Unknown", + State: "Virginia", + Zip: "12345", + } + + err := a.Validate() + fmt.Println(err) + // Output: + // Street: the length must be between 5 and 50; State: must be in a valid format. +} +``` + +Note that when calling `validation.ValidateStruct` to validate a struct, you should pass to the method a pointer +to the struct instead of the struct itself. Similarly, when calling `validation.Field` to specify the rules +for a struct field, you should use a pointer to the struct field. + +When the struct validation is performed, the fields are validated in the order they are specified in `ValidateStruct`. +And when each field is validated, its rules are also evaluated in the order they are associated with the field. +If a rule fails, an error is recorded for that field, and the validation will continue with the next field. + + +### Validation Errors + +The `validation.ValidateStruct` method returns validation errors found in struct fields in terms of `validation.Errors` +which is a map of fields and their corresponding errors. Nil is returned if validation passes. + +By default, `validation.Errors` uses the struct tags named `json` to determine what names should be used to +represent the invalid fields. The type also implements the `json.Marshaler` interface so that it can be marshaled +into a proper JSON object. For example, + +```go +type Address struct { + Street string `json:"street"` + City string `json:"city"` + State string `json:"state"` + Zip string `json:"zip"` +} + +// ...perform validation here... + +err := a.Validate() +b, _ := json.Marshal(err) +fmt.Println(string(b)) +// Output: +// {"street":"the length must be between 5 and 50","state":"must be in a valid format"} +``` + +You may modify `validation.ErrorTag` to use a different struct tag name. + +If you do not like the magic that `ValidateStruct` determines error keys based on struct field names or corresponding +tag values, you may use the following alternative approach: + +```go +c := Customer{ + Name: "Qiang Xue", + Email: "q", + Address: Address{ + State: "Virginia", + }, +} + +err := validation.Errors{ + "name": validation.Validate(c.Name, validation.Required, validation.Length(5, 20)), + "email": validation.Validate(c.Name, validation.Required, is.Email), + "zip": validation.Validate(c.Address.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), +}.Filter() +fmt.Println(err) +// Output: +// email: must be a valid email address; zip: cannot be blank. +``` + +In the above example, we build a `validation.Errors` by a list of names and the corresponding validation results. +At the end we call `Errors.Filter()` to remove from `Errors` all nils which correspond to those successful validation +results. The method will return nil if `Errors` is empty. + +The above approach is very flexible as it allows you to freely build up your validation error structure. You can use +it to validate both struct and non-struct values. Compared to using `ValidateStruct` to validate a struct, +it has the drawback that you have to redundantly specify the error keys while `ValidateStruct` can automatically +find them out. + + +### Internal Errors + +Internal errors are different from validation errors in that internal errors are caused by malfunctioning code (e.g. +a validator making a remote call to validate some data when the remote service is down) rather +than the data being validated. When an internal error happens during data validation, you may allow the user to resubmit +the same data to perform validation again, hoping the program resumes functioning. On the other hand, if data validation +fails due to data error, the user should generally not resubmit the same data again. + +To differentiate internal errors from validation errors, when an internal error occurs in a validator, wrap it +into `validation.InternalError` by calling `validation.NewInternalError()`. The user of the validator can then check +if a returned error is an internal error or not. For example, + +```go +if err := a.Validate(); err != nil { + if e, ok := err.(validation.InternalError); ok { + // an internal error happened + fmt.Println(e.InternalError()) + } +} +``` + + +## Validatable Types + +A type is validatable if it implements the `validation.Validatable` interface. + +When `validation.Validate` is used to validate a validatable value, if it does not find any error with the +given validation rules, it will further call the value's `Validate()` method. + +Similarly, when `validation.ValidateStruct` is validating a struct field whose type is validatable, it will call +the field's `Validate` method after it passes the listed rules. + +In the following example, the `Address` field of `Customer` is validatable because `Address` implements +`validation.Validatable`. Therefore, when validating a `Customer` struct with `validation.ValidateStruct`, +validation will "dive" into the `Address` field. + +```go +type Customer struct { + Name string + Gender string + Email string + Address Address +} + +func (c Customer) Validate() error { + return validation.ValidateStruct(&c, + // Name cannot be empty, and the length must be between 5 and 20. + validation.Field(&c.Name, validation.Required, validation.Length(5, 20)), + // Gender is optional, and should be either "Female" or "Male". + validation.Field(&c.Gender, validation.In("Female", "Male")), + // Email cannot be empty and should be in a valid email format. + validation.Field(&c.Email, validation.Required, is.Email), + // Validate Address using its own validation rules + validation.Field(&c.Address), + ) +} + +c := Customer{ + Name: "Qiang Xue", + Email: "q", + Address: Address{ + Street: "123 Main Street", + City: "Unknown", + State: "Virginia", + Zip: "12345", + }, +} + +err := c.Validate() +fmt.Println(err) +// Output: +// Address: (State: must be in a valid format.); Email: must be a valid email address. +``` + +Sometimes, you may want to skip the invocation of a type's `Validate` method. To do so, simply associate +a `validation.Skip` rule with the value being validated. + + +### Maps/Slices/Arrays of Validatables + +When validating a map, slice, or array, whose element type implements the `validation.Validatable` interface, +the `validation.Validate` method will call the `Validate` method of every non-nil element. +The validation errors of the elements will be returned as `validation.Errors` which maps the keys of the +invalid elements to their corresponding validation errors. For example, + +```go +addresses := []Address{ + Address{State: "MD", Zip: "12345"}, + Address{Street: "123 Main St", City: "Vienna", State: "VA", Zip: "12345"}, + Address{City: "Unknown", State: "NC", Zip: "123"}, +} +err := validation.Validate(addresses) +fmt.Println(err) +// Output: +// 0: (City: cannot be blank; Street: cannot be blank.); 2: (Street: cannot be blank; Zip: must be in a valid format.). +``` + +When using `validation.ValidateStruct` to validate a struct, the above validation procedure also applies to those struct +fields which are map/slices/arrays of validatables. + + +### Pointers + +When a value being validated is a pointer, most validation rules will validate the actual value pointed to by the pointer. +If the pointer is nil, these rules will skip the validation. + +An exception is the `validation.Required` and `validation.NotNil` rules. When a pointer is nil, they +will report a validation error. + + +### Types Implementing `sql.Valuer` + +If a data type implements the `sql.Valuer` interface (e.g. `sql.NullString`), the built-in validation rules will handle +it properly. In particular, when a rule is validating such data, it will call the `Value()` method and validate +the returned value instead. + + +### Required vs. Not Nil + +When validating input values, there are two different scenarios about checking if input values are provided or not. + +In the first scenario, an input value is considered missing if it is not entered or it is entered as a zero value +(e.g. an empty string, a zero integer). You can use the `validation.Required` rule in this case. + +In the second scenario, an input value is considered missing only if it is not entered. A pointer field is usually +used in this case so that you can detect if a value is entered or not by checking if the pointer is nil or not. +You can use the `validation.NotNil` rule to ensure a value is entered (even if it is a zero value). + + +### Embedded Structs + +The `validation.ValidateStruct` method will properly validate a struct that contains embedded structs. In particular, +the fields of an embedded struct are treated as if they belong directly to the containing struct. For example, + +```go +type Employee struct { + Name string +} + +func () + +type Manager struct { + Employee + Level int +} + +m := Manager{} +err := validation.ValidateStruct(&m, + validation.Field(&m.Name, validation.Required), + validation.Field(&m.Level, validation.Required), +) +fmt.Println(err) +// Output: +// Level: cannot be blank; Name: cannot be blank. +``` + +In the above code, we use `&m.Name` to specify the validation of the `Name` field of the embedded struct `Employee`. +And the validation error uses `Name` as the key for the error associated with the `Name` field as if `Name` a field +directly belonging to `Manager`. + +If `Employee` implements the `validation.Validatable` interface, we can also use the following code to validate +`Manager`, which generates the same validation result: + +```go +func (e Employee) Validate() error { + return validation.ValidateStruct(&e, + validation.Field(&e.Name, validation.Required), + ) +} + +err := validation.ValidateStruct(&m, + validation.Field(&m.Employee), + validation.Field(&m.Level, validation.Required), +) +fmt.Println(err) +// Output: +// Level: cannot be blank; Name: cannot be blank. +``` + + +## Built-in Validation Rules + +The following rules are provided in the `validation` package: + +* `In(...interface{})`: checks if a value can be found in the given list of values. +* `Length(min, max int)`: checks if the length of a value is within the specified range. + This rule should only be used for validating strings, slices, maps, and arrays. +* `RuneLength(min, max int)`: checks if the length of a string is within the specified range. + This rule is similar as `Length` except that when the value being validated is a string, it checks + its rune length instead of byte length. +* `Min(min interface{})` and `Max(max interface{})`: checks if a value is within the specified range. + These two rules should only be used for validating int, uint, float and time.Time types. +* `Match(*regexp.Regexp)`: checks if a value matches the specified regular expression. + This rule should only be used for strings and byte slices. +* `Date(layout string)`: checks if a string value is a date whose format is specified by the layout. + By calling `Min()` and/or `Max()`, you can check additionally if the date is within the specified range. +* `Required`: checks if a value is not empty (neither nil nor zero). +* `NotNil`: checks if a pointer value is not nil. Non-pointer values are considered valid. +* `NilOrNotEmpty`: checks if a value is a nil pointer or a non-empty value. This differs from `Required` in that it treats a nil pointer as valid. +* `Skip`: this is a special rule used to indicate that all rules following it should be skipped (including the nested ones). +* `MultipleOf`: checks if the value is a multiple of the specified range. + +The `is` sub-package provides a list of commonly used string validation rules that can be used to check if the format +of a value satisfies certain requirements. Note that these rules only handle strings and byte slices and if a string + or byte slice is empty, it is considered valid. You may use a `Required` rule to ensure a value is not empty. +Below is the whole list of the rules provided by the `is` package: + +* `Email`: validates if a string is an email or not +* `URL`: validates if a string is a valid URL +* `RequestURL`: validates if a string is a valid request URL +* `RequestURI`: validates if a string is a valid request URI +* `Alpha`: validates if a string contains English letters only (a-zA-Z) +* `Digit`: validates if a string contains digits only (0-9) +* `Alphanumeric`: validates if a string contains English letters and digits only (a-zA-Z0-9) +* `UTFLetter`: validates if a string contains unicode letters only +* `UTFDigit`: validates if a string contains unicode decimal digits only +* `UTFLetterNumeric`: validates if a string contains unicode letters and numbers only +* `UTFNumeric`: validates if a string contains unicode number characters (category N) only +* `LowerCase`: validates if a string contains lower case unicode letters only +* `UpperCase`: validates if a string contains upper case unicode letters only +* `Hexadecimal`: validates if a string is a valid hexadecimal number +* `HexColor`: validates if a string is a valid hexadecimal color code +* `RGBColor`: validates if a string is a valid RGB color in the form of rgb(R, G, B) +* `Int`: validates if a string is a valid integer number +* `Float`: validates if a string is a floating point number +* `UUIDv3`: validates if a string is a valid version 3 UUID +* `UUIDv4`: validates if a string is a valid version 4 UUID +* `UUIDv5`: validates if a string is a valid version 5 UUID +* `UUID`: validates if a string is a valid UUID +* `CreditCard`: validates if a string is a valid credit card number +* `ISBN10`: validates if a string is an ISBN version 10 +* `ISBN13`: validates if a string is an ISBN version 13 +* `ISBN`: validates if a string is an ISBN (either version 10 or 13) +* `JSON`: validates if a string is in valid JSON format +* `ASCII`: validates if a string contains ASCII characters only +* `PrintableASCII`: validates if a string contains printable ASCII characters only +* `Multibyte`: validates if a string contains multibyte characters +* `FullWidth`: validates if a string contains full-width characters +* `HalfWidth`: validates if a string contains half-width characters +* `VariableWidth`: validates if a string contains both full-width and half-width characters +* `Base64`: validates if a string is encoded in Base64 +* `DataURI`: validates if a string is a valid base64-encoded data URI +* `E164`: validates if a string is a valid E164 phone number (+19251232233) +* `CountryCode2`: validates if a string is a valid ISO3166 Alpha 2 country code +* `CountryCode3`: validates if a string is a valid ISO3166 Alpha 3 country code +* `DialString`: validates if a string is a valid dial string that can be passed to Dial() +* `MAC`: validates if a string is a MAC address +* `IP`: validates if a string is a valid IP address (either version 4 or 6) +* `IPv4`: validates if a string is a valid version 4 IP address +* `IPv6`: validates if a string is a valid version 6 IP address +* `Subdomain`: validates if a string is valid subdomain +* `Domain`: validates if a string is valid domain +* `DNSName`: validates if a string is valid DNS name +* `Host`: validates if a string is a valid IP (both v4 and v6) or a valid DNS name +* `Port`: validates if a string is a valid port number +* `MongoID`: validates if a string is a valid Mongo ID +* `Latitude`: validates if a string is a valid latitude +* `Longitude`: validates if a string is a valid longitude +* `SSN`: validates if a string is a social security number (SSN) +* `Semver`: validates if a string is a valid semantic version + +### Customizing Error Messages + +All built-in validation rules allow you to customize error messages. To do so, simply call the `Error()` method +of the rules. For example, + +```go +data := "2123" +err := validation.Validate(data, + validation.Required.Error("is required"), + validation.Match(regexp.MustCompile("^[0-9]{5}$")).Error("must be a string with five digits"), +) +fmt.Println(err) +// Output: +// must be a string with five digits +``` + + +## Creating Custom Rules + +Creating a custom rule is as simple as implementing the `validation.Rule` interface. The interface contains a single +method as shown below, which should validate the value and return the validation error, if any: + +```go +// Validate validates a value and returns an error if validation fails. +Validate(value interface{}) error +``` + +If you already have a function with the same signature as shown above, you can call `validation.By()` to turn +it into a validation rule. For example, + +```go +func checkAbc(value interface{}) error { + s, _ := value.(string) + if s != "abc" { + return errors.New("must be abc") + } + return nil +} + +err := validation.Validate("xyz", validation.By(checkAbc)) +fmt.Println(err) +// Output: must be abc +``` + + +### Rule Groups + +When a combination of several rules are used in multiple places, you may use the following trick to create a +rule group so that your code is more maintainable. + +```go +var NameRule = []validation.Rule{ + validation.Required, + validation.Length(5, 20), +} + +type User struct { + FirstName string + LastName string +} + +func (u User) Validate() error { + return validation.ValidateStruct(&u, + validation.Field(&u.FirstName, NameRule...), + validation.Field(&u.LastName, NameRule...), + ) +} +``` + +In the above example, we create a rule group `NameRule` which consists of two validation rules. We then use this rule +group to validate both `FirstName` and `LastName`. + + +## Credits + +The `is` sub-package wraps the excellent validators provided by the [govalidator](https://github.com/asaskevich/govalidator) package. diff --git a/vendor/github.com/go-ozzo/ozzo-validation/UPGRADE.md b/vendor/github.com/go-ozzo/ozzo-validation/UPGRADE.md new file mode 100644 index 000000000000..8f11d03eaa95 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/UPGRADE.md @@ -0,0 +1,46 @@ +# Upgrade Instructions + +## Upgrade from 2.x to 3.x + +* Instead of using `StructRules` to define struct validation rules, use `ValidateStruct()` to declare and perform + struct validation. The following code snippet shows how to modify your code: +```go +// 2.x usage +err := validation.StructRules{}. + Add("Street", validation.Required, validation.Length(5, 50)). + Add("City", validation.Required, validation.Length(5, 50)). + Add("State", validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))). + Add("Zip", validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))). + Validate(a) + +// 3.x usage +err := validation.ValidateStruct(&a, + validation.Field(&a.Street, validation.Required, validation.Length(5, 50)), + validation.Field(&a.City, validation.Required, validation.Length(5, 50)), + validation.Field(&a.State, validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))), + validation.Field(&a.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), +) +``` + +* Instead of using `Rules` to declare a rule list and use it to validate a value, call `Validate()` with the rules directly. +```go +data := "example" + +// 2.x usage +rules := validation.Rules{ + validation.Required, + validation.Length(5, 100), + is.URL, +} +err := rules.Validate(data) + +// 3.x usage +err := validation.Validate(data, + validation.Required, + validation.Length(5, 100), + is.URL, +) +``` + +* The default struct tags used for determining error keys is changed from `validation` to `json`. You may modify + `validation.ErrorTag` to change it back. \ No newline at end of file diff --git a/vendor/github.com/go-ozzo/ozzo-validation/date.go b/vendor/github.com/go-ozzo/ozzo-validation/date.go new file mode 100644 index 000000000000..432e035155e9 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/date.go @@ -0,0 +1,84 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "errors" + "time" +) + +type DateRule struct { + layout string + min, max time.Time + message string + rangeMessage string +} + +// Date returns a validation rule that checks if a string value is in a format that can be parsed into a date. +// The format of the date should be specified as the layout parameter which accepts the same value as that for time.Parse. +// For example, +// validation.Date(time.ANSIC) +// validation.Date("02 Jan 06 15:04 MST") +// validation.Date("2006-01-02") +// +// By calling Min() and/or Max(), you can let the Date rule to check if a parsed date value is within +// the specified date range. +// +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func Date(layout string) *DateRule { + return &DateRule{ + layout: layout, + message: "must be a valid date", + rangeMessage: "the data is out of range", + } +} + +// Error sets the error message that is used when the value being validated is not a valid date. +func (r *DateRule) Error(message string) *DateRule { + r.message = message + return r +} + +// RangeError sets the error message that is used when the value being validated is out of the specified Min/Max date range. +func (r *DateRule) RangeError(message string) *DateRule { + r.rangeMessage = message + return r +} + +// Min sets the minimum date range. A zero value means skipping the minimum range validation. +func (r *DateRule) Min(min time.Time) *DateRule { + r.min = min + return r +} + +// Max sets the maximum date range. A zero value means skipping the maximum range validation. +func (r *DateRule) Max(max time.Time) *DateRule { + r.max = max + return r +} + +// Validate checks if the given value is a valid date. +func (r *DateRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + str, err := EnsureString(value) + if err != nil { + return err + } + + date, err := time.Parse(r.layout, str) + if err != nil { + return errors.New(r.message) + } + + if !r.min.IsZero() && r.min.After(date) || !r.max.IsZero() && date.After(r.max) { + return errors.New(r.rangeMessage) + } + + return nil +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/error.go b/vendor/github.com/go-ozzo/ozzo-validation/error.go new file mode 100644 index 000000000000..d89d62857379 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/error.go @@ -0,0 +1,89 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "encoding/json" + "fmt" + "sort" +) + +type ( + // Errors represents the validation errors that are indexed by struct field names, map or slice keys. + Errors map[string]error + + // InternalError represents an error that should NOT be treated as a validation error. + InternalError interface { + error + InternalError() error + } + + internalError struct { + error + } +) + +// NewInternalError wraps a given error into an InternalError. +func NewInternalError(err error) InternalError { + return &internalError{error: err} +} + +// InternalError returns the actual error that it wraps around. +func (e *internalError) InternalError() error { + return e.error +} + +// Error returns the error string of Errors. +func (es Errors) Error() string { + if len(es) == 0 { + return "" + } + + keys := []string{} + for key := range es { + keys = append(keys, key) + } + sort.Strings(keys) + + s := "" + for i, key := range keys { + if i > 0 { + s += "; " + } + if errs, ok := es[key].(Errors); ok { + s += fmt.Sprintf("%v: (%v)", key, errs) + } else { + s += fmt.Sprintf("%v: %v", key, es[key].Error()) + } + } + return s + "." +} + +// MarshalJSON converts the Errors into a valid JSON. +func (es Errors) MarshalJSON() ([]byte, error) { + errs := map[string]interface{}{} + for key, err := range es { + if ms, ok := err.(json.Marshaler); ok { + errs[key] = ms + } else { + errs[key] = err.Error() + } + } + return json.Marshal(errs) +} + +// Filter removes all nils from Errors and returns back the updated Errors as an error. +// If the length of Errors becomes 0, it will return nil. +func (es Errors) Filter() error { + for key, value := range es { + if value == nil { + delete(es, key) + } + } + if len(es) == 0 { + return nil + } + return es +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/in.go b/vendor/github.com/go-ozzo/ozzo-validation/in.go new file mode 100644 index 000000000000..33ee5e534422 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/in.go @@ -0,0 +1,43 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import "errors" + +// In returns a validation rule that checks if a value can be found in the given list of values. +// Note that the value being checked and the possible range of values must be of the same type. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func In(values ...interface{}) *InRule { + return &InRule{ + elements: values, + message: "must be a valid value", + } +} + +type InRule struct { + elements []interface{} + message string +} + +// Validate checks if the given value is valid or not. +func (r *InRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + for _, e := range r.elements { + if e == value { + return nil + } + } + return errors.New(r.message) +} + +// Error sets the error message for the rule. +func (r *InRule) Error(message string) *InRule { + r.message = message + return r +} diff --git a/vendor/github.com/lpabon/godbc/BUILD b/vendor/github.com/go-ozzo/ozzo-validation/is/BUILD similarity index 55% rename from vendor/github.com/lpabon/godbc/BUILD rename to vendor/github.com/go-ozzo/ozzo-validation/is/BUILD index 31c0af8f19f3..95b6767cce57 100644 --- a/vendor/github.com/lpabon/godbc/BUILD +++ b/vendor/github.com/go-ozzo/ozzo-validation/is/BUILD @@ -2,10 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", - srcs = ["godbc.go"], - importmap = "k8s.io/kubernetes/vendor/github.com/lpabon/godbc", - importpath = "github.com/lpabon/godbc", + srcs = ["rules.go"], + importmap = "k8s.io/kubernetes/vendor/github.com/go-ozzo/ozzo-validation/is", + importpath = "github.com/go-ozzo/ozzo-validation/is", visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/asaskevich/govalidator:go_default_library", + "//vendor/github.com/go-ozzo/ozzo-validation:go_default_library", + ], ) filegroup( diff --git a/vendor/github.com/go-ozzo/ozzo-validation/is/rules.go b/vendor/github.com/go-ozzo/ozzo-validation/is/rules.go new file mode 100644 index 000000000000..73cfb7e4de72 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/is/rules.go @@ -0,0 +1,171 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +// Package is provides a list of commonly used string validation rules. +package is + +import ( + "regexp" + "unicode" + + "github.com/asaskevich/govalidator" + "github.com/go-ozzo/ozzo-validation" +) + +var ( + // Email validates if a string is an email or not. + Email = validation.NewStringRule(govalidator.IsEmail, "must be a valid email address") + // URL validates if a string is a valid URL + URL = validation.NewStringRule(govalidator.IsURL, "must be a valid URL") + // RequestURL validates if a string is a valid request URL + RequestURL = validation.NewStringRule(govalidator.IsRequestURL, "must be a valid request URL") + // RequestURI validates if a string is a valid request URI + RequestURI = validation.NewStringRule(govalidator.IsRequestURI, "must be a valid request URI") + // Alpha validates if a string contains English letters only (a-zA-Z) + Alpha = validation.NewStringRule(govalidator.IsAlpha, "must contain English letters only") + // Digit validates if a string contains digits only (0-9) + Digit = validation.NewStringRule(isDigit, "must contain digits only") + // Alphanumeric validates if a string contains English letters and digits only (a-zA-Z0-9) + Alphanumeric = validation.NewStringRule(govalidator.IsAlphanumeric, "must contain English letters and digits only") + // UTFLetter validates if a string contains unicode letters only + UTFLetter = validation.NewStringRule(govalidator.IsUTFLetter, "must contain unicode letter characters only") + // UTFDigit validates if a string contains unicode decimal digits only + UTFDigit = validation.NewStringRule(govalidator.IsUTFDigit, "must contain unicode decimal digits only") + // UTFLetterNumeric validates if a string contains unicode letters and numbers only + UTFLetterNumeric = validation.NewStringRule(govalidator.IsUTFLetterNumeric, "must contain unicode letters and numbers only") + // UTFNumeric validates if a string contains unicode number characters (category N) only + UTFNumeric = validation.NewStringRule(isUTFNumeric, "must contain unicode number characters only") + // LowerCase validates if a string contains lower case unicode letters only + LowerCase = validation.NewStringRule(govalidator.IsLowerCase, "must be in lower case") + // UpperCase validates if a string contains upper case unicode letters only + UpperCase = validation.NewStringRule(govalidator.IsUpperCase, "must be in upper case") + // Hexadecimal validates if a string is a valid hexadecimal number + Hexadecimal = validation.NewStringRule(govalidator.IsHexadecimal, "must be a valid hexadecimal number") + // HexColor validates if a string is a valid hexadecimal color code + HexColor = validation.NewStringRule(govalidator.IsHexcolor, "must be a valid hexadecimal color code") + // RGBColor validates if a string is a valid RGB color in the form of rgb(R, G, B) + RGBColor = validation.NewStringRule(govalidator.IsRGBcolor, "must be a valid RGB color code") + // Int validates if a string is a valid integer number + Int = validation.NewStringRule(govalidator.IsInt, "must be an integer number") + // Float validates if a string is a floating point number + Float = validation.NewStringRule(govalidator.IsFloat, "must be a floating point number") + // UUIDv3 validates if a string is a valid version 3 UUID + UUIDv3 = validation.NewStringRule(govalidator.IsUUIDv3, "must be a valid UUID v3") + // UUIDv4 validates if a string is a valid version 4 UUID + UUIDv4 = validation.NewStringRule(govalidator.IsUUIDv4, "must be a valid UUID v4") + // UUIDv5 validates if a string is a valid version 5 UUID + UUIDv5 = validation.NewStringRule(govalidator.IsUUIDv5, "must be a valid UUID v5") + // UUID validates if a string is a valid UUID + UUID = validation.NewStringRule(govalidator.IsUUID, "must be a valid UUID") + // CreditCard validates if a string is a valid credit card number + CreditCard = validation.NewStringRule(govalidator.IsCreditCard, "must be a valid credit card number") + // ISBN10 validates if a string is an ISBN version 10 + ISBN10 = validation.NewStringRule(govalidator.IsISBN10, "must be a valid ISBN-10") + // ISBN13 validates if a string is an ISBN version 13 + ISBN13 = validation.NewStringRule(govalidator.IsISBN13, "must be a valid ISBN-13") + // ISBN validates if a string is an ISBN (either version 10 or 13) + ISBN = validation.NewStringRule(isISBN, "must be a valid ISBN") + // JSON validates if a string is in valid JSON format + JSON = validation.NewStringRule(govalidator.IsJSON, "must be in valid JSON format") + // ASCII validates if a string contains ASCII characters only + ASCII = validation.NewStringRule(govalidator.IsASCII, "must contain ASCII characters only") + // PrintableASCII validates if a string contains printable ASCII characters only + PrintableASCII = validation.NewStringRule(govalidator.IsPrintableASCII, "must contain printable ASCII characters only") + // Multibyte validates if a string contains multibyte characters + Multibyte = validation.NewStringRule(govalidator.IsMultibyte, "must contain multibyte characters") + // FullWidth validates if a string contains full-width characters + FullWidth = validation.NewStringRule(govalidator.IsFullWidth, "must contain full-width characters") + // HalfWidth validates if a string contains half-width characters + HalfWidth = validation.NewStringRule(govalidator.IsHalfWidth, "must contain half-width characters") + // VariableWidth validates if a string contains both full-width and half-width characters + VariableWidth = validation.NewStringRule(govalidator.IsVariableWidth, "must contain both full-width and half-width characters") + // Base64 validates if a string is encoded in Base64 + Base64 = validation.NewStringRule(govalidator.IsBase64, "must be encoded in Base64") + // DataURI validates if a string is a valid base64-encoded data URI + DataURI = validation.NewStringRule(govalidator.IsDataURI, "must be a Base64-encoded data URI") + // E164 validates if a string is a valid ISO3166 Alpha 2 country code + E164 = validation.NewStringRule(isE164Number, "must be a valid E164 number") + // CountryCode2 validates if a string is a valid ISO3166 Alpha 2 country code + CountryCode2 = validation.NewStringRule(govalidator.IsISO3166Alpha2, "must be a valid two-letter country code") + // CountryCode3 validates if a string is a valid ISO3166 Alpha 3 country code + CountryCode3 = validation.NewStringRule(govalidator.IsISO3166Alpha3, "must be a valid three-letter country code") + // DialString validates if a string is a valid dial string that can be passed to Dial() + DialString = validation.NewStringRule(govalidator.IsDialString, "must be a valid dial string") + // MAC validates if a string is a MAC address + MAC = validation.NewStringRule(govalidator.IsMAC, "must be a valid MAC address") + // IP validates if a string is a valid IP address (either version 4 or 6) + IP = validation.NewStringRule(govalidator.IsIP, "must be a valid IP address") + // IPv4 validates if a string is a valid version 4 IP address + IPv4 = validation.NewStringRule(govalidator.IsIPv4, "must be a valid IPv4 address") + // IPv6 validates if a string is a valid version 6 IP address + IPv6 = validation.NewStringRule(govalidator.IsIPv6, "must be a valid IPv6 address") + // Subdomain validates if a string is valid subdomain + Subdomain = validation.NewStringRule(isSubdomain, "must be a valid subdomain") + // Domain validates if a string is valid domain + Domain = validation.NewStringRule(isDomain, "must be a valid domain") + // DNSName validates if a string is valid DNS name + DNSName = validation.NewStringRule(govalidator.IsDNSName, "must be a valid DNS name") + // Host validates if a string is a valid IP (both v4 and v6) or a valid DNS name + Host = validation.NewStringRule(govalidator.IsHost, "must be a valid IP address or DNS name") + // Port validates if a string is a valid port number + Port = validation.NewStringRule(govalidator.IsPort, "must be a valid port number") + // MongoID validates if a string is a valid Mongo ID + MongoID = validation.NewStringRule(govalidator.IsMongoID, "must be a valid hex-encoded MongoDB ObjectId") + // Latitude validates if a string is a valid latitude + Latitude = validation.NewStringRule(govalidator.IsLatitude, "must be a valid latitude") + // Longitude validates if a string is a valid longitude + Longitude = validation.NewStringRule(govalidator.IsLongitude, "must be a valid longitude") + // SSN validates if a string is a social security number (SSN) + SSN = validation.NewStringRule(govalidator.IsSSN, "must be a valid social security number") + // Semver validates if a string is a valid semantic version + Semver = validation.NewStringRule(govalidator.IsSemver, "must be a valid semantic version") +) + +var ( + reDigit = regexp.MustCompile("^[0-9]+$") + // Subdomain regex source: https://stackoverflow.com/a/7933253 + reSubdomain = regexp.MustCompile(`^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`) +) + +func isISBN(value string) bool { + return govalidator.IsISBN(value, 10) || govalidator.IsISBN(value, 13) +} + +func isDigit(value string) bool { + return reDigit.MatchString(value) +} + +func isE164Number(value string) bool { + // E164 regex source: https://stackoverflow.com/a/23299989 + reE164 := regexp.MustCompile(`^\+?[1-9]\d{1,14}$`) + return reE164.MatchString(value) +} + +func isSubdomain(value string) bool { + // Subdomain regex source: https://stackoverflow.com/a/7933253 + reSubdomain := regexp.MustCompile(`^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`) + return reSubdomain.MatchString(value) +} + +func isDomain(value string) bool { + if len(value) > 255 { + return false + } + + // Domain regex source: https://stackoverflow.com/a/7933253 + // Slightly modified: Removed 255 max length validation since Go regex does not + // support lookarounds. More info: https://stackoverflow.com/a/38935027 + reDomain := regexp.MustCompile(`^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+(?:[a-z]{1,63}| xn--[a-z0-9]{1,59})$`) + + return reDomain.MatchString(value) +} + +func isUTFNumeric(value string) bool { + for _, c := range value { + if unicode.IsNumber(c) == false { + return false + } + } + return true +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/length.go b/vendor/github.com/go-ozzo/ozzo-validation/length.go new file mode 100644 index 000000000000..d5effdf0f72b --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/length.go @@ -0,0 +1,81 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "errors" + "fmt" + "unicode/utf8" +) + +// Length returns a validation rule that checks if a value's length is within the specified range. +// If max is 0, it means there is no upper bound for the length. +// This rule should only be used for validating strings, slices, maps, and arrays. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func Length(min, max int) *LengthRule { + message := "the value must be empty" + if min == 0 && max > 0 { + message = fmt.Sprintf("the length must be no more than %v", max) + } else if min > 0 && max == 0 { + message = fmt.Sprintf("the length must be no less than %v", min) + } else if min > 0 && max > 0 { + if min == max { + message = fmt.Sprintf("the length must be exactly %v", min) + } else { + message = fmt.Sprintf("the length must be between %v and %v", min, max) + } + } + return &LengthRule{ + min: min, + max: max, + message: message, + } +} + +// RuneLength returns a validation rule that checks if a string's rune length is within the specified range. +// If max is 0, it means there is no upper bound for the length. +// This rule should only be used for validating strings, slices, maps, and arrays. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +// If the value being validated is not a string, the rule works the same as Length. +func RuneLength(min, max int) *LengthRule { + r := Length(min, max) + r.rune = true + return r +} + +type LengthRule struct { + min, max int + message string + rune bool +} + +// Validate checks if the given value is valid or not. +func (v *LengthRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + var ( + l int + err error + ) + if s, ok := value.(string); ok && v.rune { + l = utf8.RuneCountInString(s) + } else if l, err = LengthOfValue(value); err != nil { + return err + } + + if v.min > 0 && l < v.min || v.max > 0 && l > v.max { + return errors.New(v.message) + } + return nil +} + +// Error sets the error message for the rule. +func (v *LengthRule) Error(message string) *LengthRule { + v.message = message + return v +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/match.go b/vendor/github.com/go-ozzo/ozzo-validation/match.go new file mode 100644 index 000000000000..4a842bedecb5 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/match.go @@ -0,0 +1,47 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "errors" + "regexp" +) + +// Match returns a validation rule that checks if a value matches the specified regular expression. +// This rule should only be used for validating strings and byte slices, or a validation error will be reported. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func Match(re *regexp.Regexp) *MatchRule { + return &MatchRule{ + re: re, + message: "must be in a valid format", + } +} + +type MatchRule struct { + re *regexp.Regexp + message string +} + +// Validate checks if the given value is valid or not. +func (v *MatchRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil { + return nil + } + + isString, str, isBytes, bs := StringOrBytes(value) + if isString && (str == "" || v.re.MatchString(str)) { + return nil + } else if isBytes && (len(bs) == 0 || v.re.Match(bs)) { + return nil + } + return errors.New(v.message) +} + +// Error sets the error message for the rule. +func (v *MatchRule) Error(message string) *MatchRule { + v.message = message + return v +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/minmax.go b/vendor/github.com/go-ozzo/ozzo-validation/minmax.go new file mode 100644 index 000000000000..5eded0a54b6f --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/minmax.go @@ -0,0 +1,177 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "errors" + "fmt" + "reflect" + "time" +) + +type ThresholdRule struct { + threshold interface{} + operator int + message string +} + +const ( + greaterThan = iota + greaterEqualThan + lessThan + lessEqualThan +) + +// Min is a validation rule that checks if a value is greater or equal than the specified value. +// By calling Exclusive, the rule will check if the value is strictly greater than the specified value. +// Note that the value being checked and the threshold value must be of the same type. +// Only int, uint, float and time.Time types are supported. +// An empty value is considered valid. Please use the Required rule to make sure a value is not empty. +func Min(min interface{}) *ThresholdRule { + return &ThresholdRule{ + threshold: min, + operator: greaterEqualThan, + message: fmt.Sprintf("must be no less than %v", min), + } +} + +// Max is a validation rule that checks if a value is less or equal than the specified value. +// By calling Exclusive, the rule will check if the value is strictly less than the specified value. +// Note that the value being checked and the threshold value must be of the same type. +// Only int, uint, float and time.Time types are supported. +// An empty value is considered valid. Please use the Required rule to make sure a value is not empty. +func Max(max interface{}) *ThresholdRule { + return &ThresholdRule{ + threshold: max, + operator: lessEqualThan, + message: fmt.Sprintf("must be no greater than %v", max), + } +} + +// Exclusive sets the comparison to exclude the boundary value. +func (r *ThresholdRule) Exclusive() *ThresholdRule { + if r.operator == greaterEqualThan { + r.operator = greaterThan + r.message = fmt.Sprintf("must be greater than %v", r.threshold) + } else if r.operator == lessEqualThan { + r.operator = lessThan + r.message = fmt.Sprintf("must be less than %v", r.threshold) + } + return r +} + +// Validate checks if the given value is valid or not. +func (r *ThresholdRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + rv := reflect.ValueOf(r.threshold) + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v, err := ToInt(value) + if err != nil { + return err + } + if r.compareInt(rv.Int(), v) { + return nil + } + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + v, err := ToUint(value) + if err != nil { + return err + } + if r.compareUint(rv.Uint(), v) { + return nil + } + + case reflect.Float32, reflect.Float64: + v, err := ToFloat(value) + if err != nil { + return err + } + if r.compareFloat(rv.Float(), v) { + return nil + } + + case reflect.Struct: + t, ok := r.threshold.(time.Time) + if !ok { + return fmt.Errorf("type not supported: %v", rv.Type()) + } + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("cannot convert %v to time.Time", reflect.TypeOf(value)) + } + if v.IsZero() || r.compareTime(t, v) { + return nil + } + + default: + return fmt.Errorf("type not supported: %v", rv.Type()) + } + + return errors.New(r.message) +} + +// Error sets the error message for the rule. +func (r *ThresholdRule) Error(message string) *ThresholdRule { + r.message = message + return r +} + +func (r *ThresholdRule) compareInt(threshold, value int64) bool { + switch r.operator { + case greaterThan: + return value > threshold + case greaterEqualThan: + return value >= threshold + case lessThan: + return value < threshold + default: + return value <= threshold + } +} + +func (r *ThresholdRule) compareUint(threshold, value uint64) bool { + switch r.operator { + case greaterThan: + return value > threshold + case greaterEqualThan: + return value >= threshold + case lessThan: + return value < threshold + default: + return value <= threshold + } +} + +func (r *ThresholdRule) compareFloat(threshold, value float64) bool { + switch r.operator { + case greaterThan: + return value > threshold + case greaterEqualThan: + return value >= threshold + case lessThan: + return value < threshold + default: + return value <= threshold + } +} + +func (r *ThresholdRule) compareTime(threshold, value time.Time) bool { + switch r.operator { + case greaterThan: + return value.After(threshold) + case greaterEqualThan: + return value.After(threshold) || value.Equal(threshold) + case lessThan: + return value.Before(threshold) + default: + return value.Before(threshold) || value.Equal(threshold) + } +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/multipleof.go b/vendor/github.com/go-ozzo/ozzo-validation/multipleof.go new file mode 100644 index 000000000000..c40fcfa72c8f --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/multipleof.go @@ -0,0 +1,55 @@ +package validation + +import ( + "errors" + "fmt" + "reflect" +) + +func MultipleOf(threshold interface{}) *multipleOfRule { + return &multipleOfRule{ + threshold, + fmt.Sprintf("must be multiple of %v", threshold), + } +} + +type multipleOfRule struct { + threshold interface{} + message string +} + +// Error sets the error message for the rule. +func (r *multipleOfRule) Error(message string) *multipleOfRule { + r.message = message + return r +} + + +func (r *multipleOfRule) Validate(value interface{}) error { + + rv := reflect.ValueOf(r.threshold) + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v, err := ToInt(value) + if err != nil { + return err + } + if v%rv.Int() == 0 { + return nil + } + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + v, err := ToUint(value) + if err != nil { + return err + } + + if v%rv.Uint() == 0 { + return nil + } + default: + return fmt.Errorf("type not supported: %v", rv.Type()) + } + + return errors.New(r.message) +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/not_in.go b/vendor/github.com/go-ozzo/ozzo-validation/not_in.go new file mode 100644 index 000000000000..18cf4a0ffc4c --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/not_in.go @@ -0,0 +1,45 @@ +// Copyright 2018 Qiang Xue, Google LLC. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "errors" +) + +// NotIn returns a validation rule that checks if a value os absent from, the given list of values. +// Note that the value being checked and the possible range of values must be of the same type. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func NotIn(values ...interface{}) *NotInRule { + return &NotInRule{ + elements: values, + message: "must not be in list", + } +} + +type NotInRule struct { + elements []interface{} + message string +} + +// Validate checks if the given value is valid or not. +func (r *NotInRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + for _, e := range r.elements { + if e == value { + return errors.New(r.message) + } + } + return nil +} + +// Error sets the error message for the rule. +func (r *NotInRule) Error(message string) *NotInRule { + r.message = message + return r +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/not_nil.go b/vendor/github.com/go-ozzo/ozzo-validation/not_nil.go new file mode 100644 index 000000000000..6cfca1204af7 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/not_nil.go @@ -0,0 +1,32 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import "errors" + +// NotNil is a validation rule that checks if a value is not nil. +// NotNil only handles types including interface, pointer, slice, and map. +// All other types are considered valid. +var NotNil = ¬NilRule{message: "is required"} + +type notNilRule struct { + message string +} + +// Validate checks if the given value is valid or not. +func (r *notNilRule) Validate(value interface{}) error { + _, isNil := Indirect(value) + if isNil { + return errors.New(r.message) + } + return nil +} + +// Error sets the error message for the rule. +func (r *notNilRule) Error(message string) *notNilRule { + return ¬NilRule{ + message: message, + } +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/required.go b/vendor/github.com/go-ozzo/ozzo-validation/required.go new file mode 100644 index 000000000000..ef9558e02546 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/required.go @@ -0,0 +1,42 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import "errors" + +// Required is a validation rule that checks if a value is not empty. +// A value is considered not empty if +// - integer, float: not zero +// - bool: true +// - string, array, slice, map: len() > 0 +// - interface, pointer: not nil and the referenced value is not empty +// - any other types +var Required = &requiredRule{message: "cannot be blank", skipNil: false} + +// NilOrNotEmpty checks if a value is a nil pointer or a value that is not empty. +// NilOrNotEmpty differs from Required in that it treats a nil pointer as valid. +var NilOrNotEmpty = &requiredRule{message: "cannot be blank", skipNil: true} + +type requiredRule struct { + message string + skipNil bool +} + +// Validate checks if the given value is valid or not. +func (v *requiredRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if v.skipNil && !isNil && IsEmpty(value) || !v.skipNil && (isNil || IsEmpty(value)) { + return errors.New(v.message) + } + return nil +} + +// Error sets the error message for the rule. +func (v *requiredRule) Error(message string) *requiredRule { + return &requiredRule{ + message: message, + skipNil: v.skipNil, + } +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/string.go b/vendor/github.com/go-ozzo/ozzo-validation/string.go new file mode 100644 index 000000000000..e8f2a5e749af --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/string.go @@ -0,0 +1,48 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import "errors" + +type stringValidator func(string) bool + +// StringRule is a rule that checks a string variable using a specified stringValidator. +type StringRule struct { + validate stringValidator + message string +} + +// NewStringRule creates a new validation rule using a function that takes a string value and returns a bool. +// The rule returned will use the function to check if a given string or byte slice is valid or not. +// An empty value is considered to be valid. Please use the Required rule to make sure a value is not empty. +func NewStringRule(validator stringValidator, message string) *StringRule { + return &StringRule{ + validate: validator, + message: message, + } +} + +// Error sets the error message for the rule. +func (v *StringRule) Error(message string) *StringRule { + return NewStringRule(v.validate, message) +} + +// Validate checks if the given value is valid or not. +func (v *StringRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + str, err := EnsureString(value) + if err != nil { + return err + } + + if v.validate(str) { + return nil + } + return errors.New(v.message) +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/struct.go b/vendor/github.com/go-ozzo/ozzo-validation/struct.go new file mode 100644 index 000000000000..2ff852ad5dc8 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/struct.go @@ -0,0 +1,154 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "errors" + "fmt" + "reflect" + "strings" +) + +var ( + // ErrStructPointer is the error that a struct being validated is not specified as a pointer. + ErrStructPointer = errors.New("only a pointer to a struct can be validated") +) + +type ( + // ErrFieldPointer is the error that a field is not specified as a pointer. + ErrFieldPointer int + + // ErrFieldNotFound is the error that a field cannot be found in the struct. + ErrFieldNotFound int + + // FieldRules represents a rule set associated with a struct field. + FieldRules struct { + fieldPtr interface{} + rules []Rule + } +) + +// Error returns the error string of ErrFieldPointer. +func (e ErrFieldPointer) Error() string { + return fmt.Sprintf("field #%v must be specified as a pointer", int(e)) +} + +// Error returns the error string of ErrFieldNotFound. +func (e ErrFieldNotFound) Error() string { + return fmt.Sprintf("field #%v cannot be found in the struct", int(e)) +} + +// ValidateStruct validates a struct by checking the specified struct fields against the corresponding validation rules. +// Note that the struct being validated must be specified as a pointer to it. If the pointer is nil, it is considered valid. +// Use Field() to specify struct fields that need to be validated. Each Field() call specifies a single field which +// should be specified as a pointer to the field. A field can be associated with multiple rules. +// For example, +// +// value := struct { +// Name string +// Value string +// }{"name", "demo"} +// err := validation.ValidateStruct(&value, +// validation.Field(&a.Name, validation.Required), +// validation.Field(&a.Value, validation.Required, validation.Length(5, 10)), +// ) +// fmt.Println(err) +// // Value: the length must be between 5 and 10. +// +// An error will be returned if validation fails. +func ValidateStruct(structPtr interface{}, fields ...*FieldRules) error { + value := reflect.ValueOf(structPtr) + if value.Kind() != reflect.Ptr || !value.IsNil() && value.Elem().Kind() != reflect.Struct { + // must be a pointer to a struct + return NewInternalError(ErrStructPointer) + } + if value.IsNil() { + // treat a nil struct pointer as valid + return nil + } + value = value.Elem() + + errs := Errors{} + + for i, fr := range fields { + fv := reflect.ValueOf(fr.fieldPtr) + if fv.Kind() != reflect.Ptr { + return NewInternalError(ErrFieldPointer(i)) + } + ft := findStructField(value, fv) + if ft == nil { + return NewInternalError(ErrFieldNotFound(i)) + } + if err := Validate(fv.Elem().Interface(), fr.rules...); err != nil { + if ie, ok := err.(InternalError); ok && ie.InternalError() != nil { + return err + } + if ft.Anonymous { + // merge errors from anonymous struct field + if es, ok := err.(Errors); ok { + for name, value := range es { + errs[name] = value + } + continue + } + } + errs[getErrorFieldName(ft)] = err + } + } + + if len(errs) > 0 { + return errs + } + return nil +} + +// Field specifies a struct field and the corresponding validation rules. +// The struct field must be specified as a pointer to it. +func Field(fieldPtr interface{}, rules ...Rule) *FieldRules { + return &FieldRules{ + fieldPtr: fieldPtr, + rules: rules, + } +} + +// findStructField looks for a field in the given struct. +// The field being looked for should be a pointer to the actual struct field. +// If found, the field info will be returned. Otherwise, nil will be returned. +func findStructField(structValue reflect.Value, fieldValue reflect.Value) *reflect.StructField { + ptr := fieldValue.Pointer() + for i := structValue.NumField() - 1; i >= 0; i-- { + sf := structValue.Type().Field(i) + if ptr == structValue.Field(i).UnsafeAddr() { + // do additional type comparison because it's possible that the address of + // an embedded struct is the same as the first field of the embedded struct + if sf.Type == fieldValue.Elem().Type() { + return &sf + } + } + if sf.Anonymous { + // delve into anonymous struct to look for the field + fi := structValue.Field(i) + if sf.Type.Kind() == reflect.Ptr { + fi = fi.Elem() + } + if fi.Kind() == reflect.Struct { + if f := findStructField(fi, fieldValue); f != nil { + return f + } + } + } + } + return nil +} + +// getErrorFieldName returns the name that should be used to represent the validation error of a struct field. +func getErrorFieldName(f *reflect.StructField) string { + if tag := f.Tag.Get(ErrorTag); tag != "" { + if cps := strings.SplitN(tag, ",", 2); cps[0] != "" { + return cps[0] + } + } + return f.Name +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/util.go b/vendor/github.com/go-ozzo/ozzo-validation/util.go new file mode 100644 index 000000000000..b15fd9a2979c --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/util.go @@ -0,0 +1,163 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "database/sql/driver" + "errors" + "fmt" + "reflect" + "time" +) + +var ( + bytesType = reflect.TypeOf([]byte(nil)) + valuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() +) + +// EnsureString ensures the given value is a string. +// If the value is a byte slice, it will be typecast into a string. +// An error is returned otherwise. +func EnsureString(value interface{}) (string, error) { + v := reflect.ValueOf(value) + if v.Kind() == reflect.String { + return v.String(), nil + } + if v.Type() == bytesType { + return string(v.Interface().([]byte)), nil + } + return "", errors.New("must be either a string or byte slice") +} + +// StringOrBytes typecasts a value into a string or byte slice. +// Boolean flags are returned to indicate if the typecasting succeeds or not. +func StringOrBytes(value interface{}) (isString bool, str string, isBytes bool, bs []byte) { + v := reflect.ValueOf(value) + if v.Kind() == reflect.String { + str = v.String() + isString = true + } else if v.Kind() == reflect.Slice && v.Type() == bytesType { + bs = v.Interface().([]byte) + isBytes = true + } + return +} + +// LengthOfValue returns the length of a value that is a string, slice, map, or array. +// An error is returned for all other types. +func LengthOfValue(value interface{}) (int, error) { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.String, reflect.Slice, reflect.Map, reflect.Array: + return v.Len(), nil + } + return 0, fmt.Errorf("cannot get the length of %v", v.Kind()) +} + +// ToInt converts the given value to an int64. +// An error is returned for all incompatible types. +func ToInt(value interface{}) (int64, error) { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int(), nil + } + return 0, fmt.Errorf("cannot convert %v to int64", v.Kind()) +} + +// ToUint converts the given value to an uint64. +// An error is returned for all incompatible types. +func ToUint(value interface{}) (uint64, error) { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint(), nil + } + return 0, fmt.Errorf("cannot convert %v to uint64", v.Kind()) +} + +// ToFloat converts the given value to a float64. +// An error is returned for all incompatible types. +func ToFloat(value interface{}) (float64, error) { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Float32, reflect.Float64: + return v.Float(), nil + } + return 0, fmt.Errorf("cannot convert %v to float64", v.Kind()) +} + +// IsEmpty checks if a value is empty or not. +// A value is considered empty if +// - integer, float: zero +// - bool: false +// - string, array: len() == 0 +// - slice, map: nil or len() == 0 +// - interface, pointer: nil or the referenced value is empty +func IsEmpty(value interface{}) bool { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.String, reflect.Array, reflect.Map, reflect.Slice: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Invalid: + return true + case reflect.Interface, reflect.Ptr: + if v.IsNil() { + return true + } + return IsEmpty(v.Elem().Interface()) + case reflect.Struct: + v, ok := value.(time.Time) + if ok && v.IsZero() { + return true + } + } + + return false +} + +// Indirect returns the value that the given interface or pointer references to. +// If the value implements driver.Valuer, it will deal with the value returned by +// the Value() method instead. A boolean value is also returned to indicate if +// the value is nil or not (only applicable to interface, pointer, map, and slice). +// If the value is neither an interface nor a pointer, it will be returned back. +func Indirect(value interface{}) (interface{}, bool) { + rv := reflect.ValueOf(value) + kind := rv.Kind() + switch kind { + case reflect.Invalid: + return nil, true + case reflect.Ptr, reflect.Interface: + if rv.IsNil() { + return nil, true + } + return Indirect(rv.Elem().Interface()) + case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan: + if rv.IsNil() { + return nil, true + } + } + + if rv.Type().Implements(valuerType) { + return indirectValuer(value.(driver.Valuer)) + } + + return value, false +} + +func indirectValuer(valuer driver.Valuer) (interface{}, bool) { + if value, err := valuer.Value(); value != nil && err == nil { + return Indirect(value) + } + return nil, true +} diff --git a/vendor/github.com/go-ozzo/ozzo-validation/validation.go b/vendor/github.com/go-ozzo/ozzo-validation/validation.go new file mode 100644 index 000000000000..1633258178d5 --- /dev/null +++ b/vendor/github.com/go-ozzo/ozzo-validation/validation.go @@ -0,0 +1,133 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +// Package validation provides configurable and extensible rules for validating data of various types. +package validation + +import ( + "fmt" + "reflect" + "strconv" +) + +type ( + // Validatable is the interface indicating the type implementing it supports data validation. + Validatable interface { + // Validate validates the data and returns an error if validation fails. + Validate() error + } + + // Rule represents a validation rule. + Rule interface { + // Validate validates a value and returns a value if validation fails. + Validate(value interface{}) error + } + + // RuleFunc represents a validator function. + // You may wrap it as a Rule by calling By(). + RuleFunc func(value interface{}) error +) + +var ( + // ErrorTag is the struct tag name used to customize the error field name for a struct field. + ErrorTag = "json" + + // Skip is a special validation rule that indicates all rules following it should be skipped. + Skip = &skipRule{} + + validatableType = reflect.TypeOf((*Validatable)(nil)).Elem() +) + +// Validate validates the given value and returns the validation error, if any. +// +// Validate performs validation using the following steps: +// - validate the value against the rules passed in as parameters +// - if the value is a map and the map values implement `Validatable`, call `Validate` of every map value +// - if the value is a slice or array whose values implement `Validatable`, call `Validate` of every element +func Validate(value interface{}, rules ...Rule) error { + for _, rule := range rules { + if _, ok := rule.(*skipRule); ok { + return nil + } + if err := rule.Validate(value); err != nil { + return err + } + } + + rv := reflect.ValueOf(value) + if (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface) && rv.IsNil() { + return nil + } + + if v, ok := value.(Validatable); ok { + return v.Validate() + } + + switch rv.Kind() { + case reflect.Map: + if rv.Type().Elem().Implements(validatableType) { + return validateMap(rv) + } + case reflect.Slice, reflect.Array: + if rv.Type().Elem().Implements(validatableType) { + return validateSlice(rv) + } + case reflect.Ptr, reflect.Interface: + return Validate(rv.Elem().Interface()) + } + + return nil +} + +// validateMap validates a map of validatable elements +func validateMap(rv reflect.Value) error { + errs := Errors{} + for _, key := range rv.MapKeys() { + if mv := rv.MapIndex(key).Interface(); mv != nil { + if err := mv.(Validatable).Validate(); err != nil { + errs[fmt.Sprintf("%v", key.Interface())] = err + } + } + } + if len(errs) > 0 { + return errs + } + return nil +} + +// validateMap validates a slice/array of validatable elements +func validateSlice(rv reflect.Value) error { + errs := Errors{} + l := rv.Len() + for i := 0; i < l; i++ { + if ev := rv.Index(i).Interface(); ev != nil { + if err := ev.(Validatable).Validate(); err != nil { + errs[strconv.Itoa(i)] = err + } + } + } + if len(errs) > 0 { + return errs + } + return nil +} + +type skipRule struct{} + +func (r *skipRule) Validate(interface{}) error { + return nil +} + +type inlineRule struct { + f RuleFunc +} + +func (r *inlineRule) Validate(value interface{}) error { + return r.f(value) +} + +// By wraps a RuleFunc into a Rule. +func By(f RuleFunc) Rule { + return &inlineRule{f} +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/BUILD b/vendor/github.com/heketi/heketi/client/api/go-client/BUILD index f83f7de7253f..4cc7cec05c85 100644 --- a/vendor/github.com/heketi/heketi/client/api/go-client/BUILD +++ b/vendor/github.com/heketi/heketi/client/api/go-client/BUILD @@ -3,11 +3,16 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", srcs = [ + "admin.go", "backup.go", + "block_volume.go", "client.go", "cluster.go", + "db.go", "device.go", + "logging.go", "node.go", + "operations.go", "topology.go", "volume.go", ], diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/admin.go b/vendor/github.com/heketi/heketi/client/api/go-client/admin.go new file mode 100644 index 000000000000..f47cf2361097 --- /dev/null +++ b/vendor/github.com/heketi/heketi/client/api/go-client/admin.go @@ -0,0 +1,78 @@ +// +// Copyright (c) 2018 The heketi Authors +// +// This file is licensed to you under your choice of the GNU Lesser +// General Public License, version 3 or any later version (LGPLv3 or +// later), as published by the Free Software Foundation, +// or under the Apache License, Version 2.0 . +// +// You may not use this file except in compliance with those terms. +// + +package client + +import ( + "bytes" + "encoding/json" + "net/http" + + "github.com/heketi/heketi/pkg/glusterfs/api" + "github.com/heketi/heketi/pkg/utils" +) + +func (c *Client) AdminStatusGet() (*api.AdminStatus, error) { + req, err := http.NewRequest("GET", c.host+"/admin", nil) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return nil, err + } + + // Send request + r, err := c.do(req) + if err != nil { + return nil, err + } + var as api.AdminStatus + err = utils.GetJsonFromResponse(r, &as) + if err != nil { + return nil, err + } + return &as, nil +} + +func (c *Client) AdminStatusSet(request *api.AdminStatus) error { + // Marshal request to JSON + buffer, err := json.Marshal(request) + if err != nil { + return err + } + + req, err := http.NewRequest("POST", c.host+"/admin", bytes.NewBuffer(buffer)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return err + } + + // Send request + r, err := c.do(req) + if err != nil { + return err + } + if r.StatusCode == http.StatusOK || r.StatusCode == http.StatusNoContent { + return nil + } + return utils.GetErrorFromResponse(r) +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/backup.go b/vendor/github.com/heketi/heketi/client/api/go-client/backup.go index 4b04d12de6d2..0690b3f41737 100644 --- a/vendor/github.com/heketi/heketi/client/api/go-client/backup.go +++ b/vendor/github.com/heketi/heketi/client/api/go-client/backup.go @@ -37,12 +37,12 @@ func (c *Client) BackupDb(w io.Writer) error { if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return utils.GetErrorFromResponse(r) } // Read data from response - defer r.Body.Close() _, err = io.Copy(w, r.Body) return err diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/block_volume.go b/vendor/github.com/heketi/heketi/client/api/go-client/block_volume.go new file mode 100644 index 000000000000..c84187f533ee --- /dev/null +++ b/vendor/github.com/heketi/heketi/client/api/go-client/block_volume.go @@ -0,0 +1,160 @@ +// +// Copyright (c) 2015 The heketi Authors +// +// This file is licensed to you under your choice of the GNU Lesser +// General Public License, version 3 or any later version (LGPLv3 or +// later), as published by the Free Software Foundation, +// or under the Apache License, Version 2.0 . +// +// You may not use this file except in compliance with those terms. +// + +package client + +import ( + "bytes" + "encoding/json" + "net/http" + "time" + + "github.com/heketi/heketi/pkg/glusterfs/api" + "github.com/heketi/heketi/pkg/utils" +) + +func (c *Client) BlockVolumeCreate(request *api.BlockVolumeCreateRequest) ( + *api.BlockVolumeInfoResponse, error) { + + buffer, err := json.Marshal(request) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", + c.host+"/blockvolumes", + bytes.NewBuffer(buffer)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + err = c.setToken(req) + if err != nil { + return nil, err + } + + r, err := c.do(req) + if err != nil { + return nil, err + } + defer r.Body.Close() + if r.StatusCode != http.StatusAccepted { + return nil, utils.GetErrorFromResponse(r) + } + + r, err = c.waitForResponseWithTimer(r, time.Second) + if err != nil { + return nil, err + } + if r.StatusCode != http.StatusOK { + return nil, utils.GetErrorFromResponse(r) + } + + var blockvolume api.BlockVolumeInfoResponse + err = utils.GetJsonFromResponse(r, &blockvolume) + if err != nil { + return nil, err + } + + return &blockvolume, nil + +} + +func (c *Client) BlockVolumeList() (*api.BlockVolumeListResponse, error) { + req, err := http.NewRequest("GET", c.host+"/blockvolumes", nil) + if err != nil { + return nil, err + } + + err = c.setToken(req) + if err != nil { + return nil, err + } + + r, err := c.do(req) + if err != nil { + return nil, err + } + defer r.Body.Close() + if r.StatusCode != http.StatusOK { + return nil, utils.GetErrorFromResponse(r) + } + + var blockvolumes api.BlockVolumeListResponse + err = utils.GetJsonFromResponse(r, &blockvolumes) + if err != nil { + return nil, err + } + + return &blockvolumes, nil +} + +func (c *Client) BlockVolumeInfo(id string) (*api.BlockVolumeInfoResponse, error) { + req, err := http.NewRequest("GET", c.host+"/blockvolumes/"+id, nil) + if err != nil { + return nil, err + } + + err = c.setToken(req) + if err != nil { + return nil, err + } + + r, err := c.do(req) + if err != nil { + return nil, err + } + defer r.Body.Close() + if r.StatusCode != http.StatusOK { + return nil, utils.GetErrorFromResponse(r) + } + + var blockvolume api.BlockVolumeInfoResponse + err = utils.GetJsonFromResponse(r, &blockvolume) + if err != nil { + return nil, err + } + + return &blockvolume, nil +} + +func (c *Client) BlockVolumeDelete(id string) error { + req, err := http.NewRequest("DELETE", c.host+"/blockvolumes/"+id, nil) + if err != nil { + return err + } + + err = c.setToken(req) + if err != nil { + return err + } + + r, err := c.do(req) + if err != nil { + return err + } + defer r.Body.Close() + if r.StatusCode != http.StatusAccepted { + return utils.GetErrorFromResponse(r) + } + + r, err = c.waitForResponseWithTimer(r, time.Second) + if err != nil { + return err + } + if r.StatusCode != http.StatusNoContent { + return utils.GetErrorFromResponse(r) + } + + return nil +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/client.go b/vendor/github.com/heketi/heketi/client/api/go-client/client.go index e29abfbfb889..74d6fe2739c2 100644 --- a/vendor/github.com/heketi/heketi/client/api/go-client/client.go +++ b/vendor/github.com/heketi/heketi/client/api/go-client/client.go @@ -13,9 +13,16 @@ package client import ( + "bytes" "crypto/sha256" + "crypto/tls" + "crypto/x509" "encoding/hex" + "fmt" + "io/ioutil" + "math/rand" "net/http" + "strconv" "time" jwt "github.com/dgrijalva/jwt-go" @@ -24,35 +31,118 @@ import ( const ( MAX_CONCURRENT_REQUESTS = 32 + RETRY_COUNT = 6 + + // default delay values + MIN_DELAY = 10 + MAX_DELAY = 30 ) +type ClientTLSOptions struct { + // directly borrow the field names from crypto/tls + InsecureSkipVerify bool + // one or more cert file paths (best for self-signed certs) + VerifyCerts []string +} + +// Client configuration options +type ClientOptions struct { + RetryEnabled bool + RetryCount int + // control waits between retries + RetryMinDelay, RetryMaxDelay int +} + // Client object type Client struct { host string key string user string throttle chan bool + + // configuration for TLS support + tlsClientConfig *tls.Config + + // general behavioral options + opts ClientOptions + + // allow plugging in custom do wrappers + do func(*http.Request) (*http.Response, error) +} + +var defaultClientOptions = ClientOptions{ + RetryEnabled: true, + RetryCount: RETRY_COUNT, + RetryMinDelay: MIN_DELAY, + RetryMaxDelay: MAX_DELAY, } -// Creates a new client to access a Heketi server +// NewClient creates a new client to access a Heketi server func NewClient(host, user, key string) *Client { + return NewClientWithOptions(host, user, key, defaultClientOptions) +} + +// NewClientWithOptions creates a new client to access a Heketi server +// with a user specified suite of options. +func NewClientWithOptions(host, user, key string, opts ClientOptions) *Client { c := &Client{} c.key = key c.host = host c.user = user - + c.opts = opts // Maximum concurrent requests c.throttle = make(chan bool, MAX_CONCURRENT_REQUESTS) + if opts.RetryEnabled { + c.do = c.retryOperationDo + } else { + c.do = c.doBasic + } return c } +func NewClientTLS(host, user, key string, tlsOpts *ClientTLSOptions) (*Client, error) { + c := NewClient(host, user, key) + if err := c.SetTLSOptions(tlsOpts); err != nil { + return nil, err + } + return c, nil +} + // Create a client to access a Heketi server without authentication enabled func NewClientNoAuth(host string) *Client { return NewClient(host, "", "") } +// SetTLSOptions configures an existing heketi client for +// TLS support based on the ClientTLSOptions. +func (c *Client) SetTLSOptions(o *ClientTLSOptions) error { + if o == nil { + c.tlsClientConfig = nil + return nil + } + + tlsConfig := &tls.Config{} + tlsConfig.InsecureSkipVerify = o.InsecureSkipVerify + if len(o.VerifyCerts) > 0 { + tlsConfig.RootCAs = x509.NewCertPool() + for _, path := range o.VerifyCerts { + pem, err := ioutil.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read cert file %v: %v", + path, err) + } + if ok := tlsConfig.RootCAs.AppendCertsFromPEM(pem); !ok { + return fmt.Errorf("failed to load PEM encoded cert from %s", + path) + } + } + } + c.tlsClientConfig = tlsConfig + return nil +} + // Simple Hello test to check if the server is up func (c *Client) Hello() error { // Create request @@ -72,6 +162,7 @@ func (c *Client) Hello() error { if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return utils.GetErrorFromResponse(r) } @@ -79,14 +170,20 @@ func (c *Client) Hello() error { return nil } +// doBasic performs the core http transaction. // Make sure we do not run out of fds by throttling the requests -func (c *Client) do(req *http.Request) (*http.Response, error) { +func (c *Client) doBasic(req *http.Request) (*http.Response, error) { c.throttle <- true defer func() { <-c.throttle }() httpClient := &http.Client{} + if c.tlsClientConfig != nil { + httpClient.Transport = &http.Transport{ + TLSClientConfig: c.tlsClientConfig, + } + } httpClient.CheckRedirect = c.checkRedirect return httpClient.Do(req) } @@ -122,7 +219,7 @@ func (c *Client) waitForResponseWithTimer(r *http.Response, } // Wait for response - r, err = c.do(req) + r, err = c.doBasic(req) if err != nil { return nil, err } @@ -132,6 +229,11 @@ func (c *Client) waitForResponseWithTimer(r *http.Response, if r.StatusCode != http.StatusOK { return nil, utils.GetErrorFromResponse(r) } + if r != nil { + //Read Response Body + ioutil.ReadAll(r.Body) + r.Body.Close() + } time.Sleep(waitTime) } else { return r, nil @@ -174,3 +276,66 @@ func (c *Client) setToken(r *http.Request) error { return nil } + +// retryOperationDo performs the http request and internally +// handles http 429 codes up to the number of retries specified +// by the Client. +func (c *Client) retryOperationDo(req *http.Request) (*http.Response, error) { + var ( + requestBody []byte + err error + ) + if req.Body != nil { + requestBody, err = ioutil.ReadAll(req.Body) + if err != nil { + return nil, err + } + } + + // Send request + var r *http.Response + for i := 0; i <= c.opts.RetryCount; i++ { + req.Body = ioutil.NopCloser(bytes.NewReader(requestBody)) + r, err = c.doBasic(req) + if err != nil { + return nil, err + } + switch r.StatusCode { + case http.StatusTooManyRequests: + if r != nil { + //Read Response Body + // I don't like discarding error here, but I cant + // think of something better atm + b, _ := ioutil.ReadAll(r.Body) + r.Body.Close() + r.Body = ioutil.NopCloser(bytes.NewReader(b)) + } + //sleep before continue + time.Sleep(c.opts.retryDelay(r)) + continue + + default: + return r, err + + } + } + return r, err +} + +// retryDelay returns a duration for which a retry should wait +// (after failure) before continuing. +func (c *ClientOptions) retryDelay(r *http.Response) time.Duration { + var ( + min = c.RetryMinDelay + max = c.RetryMaxDelay + ) + if ra := r.Header.Get("Retry-After"); ra != "" { + // TODO: support http date + if i, err := strconv.Atoi(ra); err == nil { + s := rand.Intn(min) + i + return time.Second * time.Duration(s) + } + } + s := rand.Intn(max-min) + min + return time.Second * time.Duration(s) +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/cluster.go b/vendor/github.com/heketi/heketi/client/api/go-client/cluster.go index ddab70dac545..b68a9e437292 100644 --- a/vendor/github.com/heketi/heketi/client/api/go-client/cluster.go +++ b/vendor/github.com/heketi/heketi/client/api/go-client/cluster.go @@ -14,16 +14,23 @@ package client import ( "bytes" + "encoding/json" "net/http" "github.com/heketi/heketi/pkg/glusterfs/api" "github.com/heketi/heketi/pkg/utils" ) -func (c *Client) ClusterCreate() (*api.ClusterInfoResponse, error) { +func (c *Client) ClusterCreate(request *api.ClusterCreateRequest) (*api.ClusterInfoResponse, error) { + + buffer, err := json.Marshal(request) + if err != nil { + return nil, err + } // Create a request - req, err := http.NewRequest("POST", c.host+"/clusters", bytes.NewBuffer([]byte(`{}`))) + req, err := http.NewRequest("POST", c.host+"/clusters", + bytes.NewBuffer(buffer)) if err != nil { return nil, err } @@ -40,6 +47,7 @@ func (c *Client) ClusterCreate() (*api.ClusterInfoResponse, error) { if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusCreated { return nil, utils.GetErrorFromResponse(r) } @@ -47,7 +55,6 @@ func (c *Client) ClusterCreate() (*api.ClusterInfoResponse, error) { // Read JSON response var cluster api.ClusterInfoResponse err = utils.GetJsonFromResponse(r, &cluster) - r.Body.Close() if err != nil { return nil, err } @@ -55,6 +62,40 @@ func (c *Client) ClusterCreate() (*api.ClusterInfoResponse, error) { return &cluster, nil } +func (c *Client) ClusterSetFlags(id string, request *api.ClusterSetFlagsRequest) error { + + buffer, err := json.Marshal(request) + if err != nil { + return err + } + + // Create a request + req, err := http.NewRequest("POST", c.host+"/clusters/"+id+"/flags", + bytes.NewBuffer(buffer)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return err + } + + // Send request + r, err := c.do(req) + if err != nil { + return err + } + defer r.Body.Close() + if r.StatusCode != http.StatusOK { + return utils.GetErrorFromResponse(r) + } + + return nil +} + func (c *Client) ClusterInfo(id string) (*api.ClusterInfoResponse, error) { // Create request @@ -74,6 +115,7 @@ func (c *Client) ClusterInfo(id string) (*api.ClusterInfoResponse, error) { if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return nil, utils.GetErrorFromResponse(r) } @@ -81,7 +123,6 @@ func (c *Client) ClusterInfo(id string) (*api.ClusterInfoResponse, error) { // Read JSON response var cluster api.ClusterInfoResponse err = utils.GetJsonFromResponse(r, &cluster) - r.Body.Close() if err != nil { return nil, err } @@ -108,6 +149,7 @@ func (c *Client) ClusterList() (*api.ClusterListResponse, error) { if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return nil, utils.GetErrorFromResponse(r) } @@ -141,6 +183,7 @@ func (c *Client) ClusterDelete(id string) error { if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return utils.GetErrorFromResponse(r) } diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/db.go b/vendor/github.com/heketi/heketi/client/api/go-client/db.go new file mode 100644 index 000000000000..72ed129b0021 --- /dev/null +++ b/vendor/github.com/heketi/heketi/client/api/go-client/db.go @@ -0,0 +1,52 @@ +// +// Copyright (c) 2018 The heketi Authors +// +// This file is licensed to you under your choice of the GNU Lesser +// General Public License, version 3 or any later version (LGPLv3 or +// later), as published by the Free Software Foundation, +// or under the Apache License, Version 2.0 . +// +// You may not use this file except in compliance with those terms. +// + +package client + +import ( + "io/ioutil" + "net/http" + + "github.com/heketi/heketi/pkg/utils" +) + +// DbDump provides a JSON representation of current state of DB +func (c *Client) DbDump() (string, error) { + req, err := http.NewRequest("GET", c.host+"/db/dump", nil) + if err != nil { + return "", err + } + + // Set token + err = c.setToken(req) + if err != nil { + return "", err + } + + // Send request + r, err := c.do(req) + if err != nil { + return "", err + } + defer r.Body.Close() + if r.StatusCode != http.StatusOK { + return "", utils.GetErrorFromResponse(r) + } + + respBytes, err := ioutil.ReadAll(r.Body) + if err != nil { + return "", err + } + + respJSON := string(respBytes) + return respJSON, nil +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/device.go b/vendor/github.com/heketi/heketi/client/api/go-client/device.go index 50412521a56c..fd856d8b4765 100644 --- a/vendor/github.com/heketi/heketi/client/api/go-client/device.go +++ b/vendor/github.com/heketi/heketi/client/api/go-client/device.go @@ -15,6 +15,7 @@ package client import ( "bytes" "encoding/json" + "io" "net/http" "time" @@ -47,6 +48,7 @@ func (c *Client) DeviceAdd(request *api.DeviceAddRequest) error { if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return utils.GetErrorFromResponse(r) } @@ -82,6 +84,7 @@ func (c *Client) DeviceInfo(id string) (*api.DeviceInfoResponse, error) { if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return nil, utils.GetErrorFromResponse(r) } @@ -89,7 +92,6 @@ func (c *Client) DeviceInfo(id string) (*api.DeviceInfoResponse, error) { // Read JSON response var device api.DeviceInfoResponse err = utils.GetJsonFromResponse(r, &device) - r.Body.Close() if err != nil { return nil, err } @@ -98,9 +100,23 @@ func (c *Client) DeviceInfo(id string) (*api.DeviceInfoResponse, error) { } func (c *Client) DeviceDelete(id string) error { + return c.DeviceDeleteWithOptions(id, nil) +} + +func (c *Client) DeviceDeleteWithOptions( + id string, request *api.DeviceDeleteOptions) error { + + var buf io.Reader + if request != nil { + b, err := json.Marshal(request) + if err != nil { + return err + } + buf = bytes.NewBuffer(b) + } // Create a request - req, err := http.NewRequest("DELETE", c.host+"/devices/"+id, nil) + req, err := http.NewRequest("DELETE", c.host+"/devices/"+id, buf) if err != nil { return err } @@ -116,6 +132,7 @@ func (c *Client) DeviceDelete(id string) error { if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return utils.GetErrorFromResponse(r) } @@ -161,6 +178,7 @@ func (c *Client) DeviceState(id string, if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return utils.GetErrorFromResponse(r) } @@ -176,3 +194,71 @@ func (c *Client) DeviceState(id string, return nil } + +func (c *Client) DeviceResync(id string) error { + + // Create a request + req, err := http.NewRequest("GET", c.host+"/devices/"+id+"/resync", nil) + if err != nil { + return err + } + + // Set token + err = c.setToken(req) + if err != nil { + return err + } + + // Send request + r, err := c.do(req) + if err != nil { + return err + } + defer r.Body.Close() + if r.StatusCode != http.StatusAccepted { + return utils.GetErrorFromResponse(r) + } + + // Wait for response + r, err = c.waitForResponseWithTimer(r, time.Millisecond*250) + if err != nil { + return err + } + if r.StatusCode != http.StatusNoContent { + return utils.GetErrorFromResponse(r) + } + + return nil +} + +func (c *Client) DeviceSetTags(id string, request *api.TagsChangeRequest) error { + buffer, err := json.Marshal(request) + if err != nil { + return err + } + + req, err := http.NewRequest("POST", + c.host+"/devices/"+id+"/tags", + bytes.NewBuffer(buffer)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return err + } + + // Get info + r, err := c.do(req) + if err != nil { + return err + } + defer r.Body.Close() + if r.StatusCode != http.StatusOK { + return utils.GetErrorFromResponse(r) + } + return nil +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/logging.go b/vendor/github.com/heketi/heketi/client/api/go-client/logging.go new file mode 100644 index 000000000000..96a29d2ec751 --- /dev/null +++ b/vendor/github.com/heketi/heketi/client/api/go-client/logging.go @@ -0,0 +1,78 @@ +// +// Copyright (c) 2018 The heketi Authors +// +// This file is licensed to you under your choice of the GNU Lesser +// General Public License, version 3 or any later version (LGPLv3 or +// later), as published by the Free Software Foundation, +// or under the Apache License, Version 2.0 . +// +// You may not use this file except in compliance with those terms. +// + +package client + +import ( + "bytes" + "encoding/json" + "net/http" + + "github.com/heketi/heketi/pkg/glusterfs/api" + "github.com/heketi/heketi/pkg/utils" +) + +func (c *Client) LogLevelGet() (*api.LogLevelInfo, error) { + req, err := http.NewRequest("GET", c.host+"/internal/logging", nil) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return nil, err + } + + // Send request + r, err := c.do(req) + if err != nil { + return nil, err + } + var lli api.LogLevelInfo + err = utils.GetJsonFromResponse(r, &lli) + if err != nil { + return nil, err + } + return &lli, nil +} + +func (c *Client) LogLevelSet(request *api.LogLevelInfo) error { + // Marshal request to JSON + buffer, err := json.Marshal(request) + if err != nil { + return err + } + + req, err := http.NewRequest("POST", c.host+"/internal/logging", bytes.NewBuffer(buffer)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return err + } + + // Send request + r, err := c.do(req) + if err != nil { + return err + } + if r.StatusCode != http.StatusOK { + return utils.GetErrorFromResponse(r) + } + return nil +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/node.go b/vendor/github.com/heketi/heketi/client/api/go-client/node.go index 20039c1ef436..da31379d1996 100644 --- a/vendor/github.com/heketi/heketi/client/api/go-client/node.go +++ b/vendor/github.com/heketi/heketi/client/api/go-client/node.go @@ -48,6 +48,7 @@ func (c *Client) NodeAdd(request *api.NodeAddRequest) (*api.NodeInfoResponse, er if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return nil, utils.GetErrorFromResponse(r) } @@ -64,7 +65,6 @@ func (c *Client) NodeAdd(request *api.NodeAddRequest) (*api.NodeInfoResponse, er // Read JSON response var node api.NodeInfoResponse err = utils.GetJsonFromResponse(r, &node) - r.Body.Close() if err != nil { return nil, err } @@ -91,6 +91,7 @@ func (c *Client) NodeInfo(id string) (*api.NodeInfoResponse, error) { if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return nil, utils.GetErrorFromResponse(r) } @@ -98,7 +99,6 @@ func (c *Client) NodeInfo(id string) (*api.NodeInfoResponse, error) { // Read JSON response var node api.NodeInfoResponse err = utils.GetJsonFromResponse(r, &node) - r.Body.Close() if err != nil { return nil, err } @@ -125,6 +125,7 @@ func (c *Client) NodeDelete(id string) error { if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return utils.GetErrorFromResponse(r) } @@ -168,6 +169,7 @@ func (c *Client) NodeState(id string, request *api.StateRequest) error { if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return utils.GetErrorFromResponse(r) } @@ -183,3 +185,35 @@ func (c *Client) NodeState(id string, request *api.StateRequest) error { return nil } + +func (c *Client) NodeSetTags(id string, request *api.TagsChangeRequest) error { + buffer, err := json.Marshal(request) + if err != nil { + return err + } + + req, err := http.NewRequest("POST", + c.host+"/nodes/"+id+"/tags", + bytes.NewBuffer(buffer)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return err + } + + // Get info + r, err := c.do(req) + if err != nil { + return err + } + defer r.Body.Close() + if r.StatusCode != http.StatusOK { + return utils.GetErrorFromResponse(r) + } + return nil +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/operations.go b/vendor/github.com/heketi/heketi/client/api/go-client/operations.go new file mode 100644 index 000000000000..d641aea50076 --- /dev/null +++ b/vendor/github.com/heketi/heketi/client/api/go-client/operations.go @@ -0,0 +1,46 @@ +// +// Copyright (c) 2018 The heketi Authors +// +// This file is licensed to you under your choice of the GNU Lesser +// General Public License, version 3 or any later version (LGPLv3 or +// later), as published by the Free Software Foundation, +// or under the Apache License, Version 2.0 . +// +// You may not use this file except in compliance with those terms. +// + +package client + +import ( + "net/http" + + "github.com/heketi/heketi/pkg/glusterfs/api" + "github.com/heketi/heketi/pkg/utils" +) + +func (c *Client) OperationsInfo() (*api.OperationsInfo, error) { + req, err := http.NewRequest("GET", c.host+"/operations", nil) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return nil, err + } + + // Send request + r, err := c.do(req) + if err != nil { + return nil, err + } + var oi api.OperationsInfo + err = utils.GetJsonFromResponse(r, &oi) + if err != nil { + return nil, err + } + return &oi, nil +} diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/topology.go b/vendor/github.com/heketi/heketi/client/api/go-client/topology.go index 6c9ffe28c882..549aa7c75c4e 100644 --- a/vendor/github.com/heketi/heketi/client/api/go-client/topology.go +++ b/vendor/github.com/heketi/heketi/client/api/go-client/topology.go @@ -33,6 +33,10 @@ func (c *Client) TopologyInfo() (*api.TopologyInfoResponse, error) { Id: clusteri.Id, Volumes: make([]api.VolumeInfoResponse, 0), Nodes: make([]api.NodeInfoResponse, 0), + ClusterFlags: api.ClusterFlags{ + Block: clusteri.Block, + File: clusteri.File, + }, } cluster.Id = clusteri.Id diff --git a/vendor/github.com/heketi/heketi/client/api/go-client/volume.go b/vendor/github.com/heketi/heketi/client/api/go-client/volume.go index 821cfa80837b..5b5d919ac5f2 100644 --- a/vendor/github.com/heketi/heketi/client/api/go-client/volume.go +++ b/vendor/github.com/heketi/heketi/client/api/go-client/volume.go @@ -51,6 +51,61 @@ func (c *Client) VolumeCreate(request *api.VolumeCreateRequest) ( if err != nil { return nil, err } + defer r.Body.Close() + if r.StatusCode != http.StatusAccepted { + return nil, utils.GetErrorFromResponse(r) + } + + // Wait for response + r, err = c.waitForResponseWithTimer(r, time.Second) + if err != nil { + return nil, err + } + if r.StatusCode != http.StatusOK { + return nil, utils.GetErrorFromResponse(r) + } + + // Read JSON response + var volume api.VolumeInfoResponse + err = utils.GetJsonFromResponse(r, &volume) + if err != nil { + return nil, err + } + + return &volume, nil + +} + +func (c *Client) VolumeSetBlockRestriction(id string, request *api.VolumeBlockRestrictionRequest) ( + *api.VolumeInfoResponse, error) { + + // Marshal request to JSON + buffer, err := json.Marshal(request) + if err != nil { + return nil, err + } + + // Create a request + req, err := http.NewRequest("POST", + c.host+"/volumes/"+id+"/block-restriction", + bytes.NewBuffer(buffer)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return nil, err + } + + // Send request + r, err := c.do(req) + if err != nil { + return nil, err + } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return nil, utils.GetErrorFromResponse(r) } @@ -67,7 +122,6 @@ func (c *Client) VolumeCreate(request *api.VolumeCreateRequest) ( // Read JSON response var volume api.VolumeInfoResponse err = utils.GetJsonFromResponse(r, &volume) - r.Body.Close() if err != nil { return nil, err } @@ -105,6 +159,7 @@ func (c *Client) VolumeExpand(id string, request *api.VolumeExpandRequest) ( if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return nil, utils.GetErrorFromResponse(r) } @@ -121,7 +176,6 @@ func (c *Client) VolumeExpand(id string, request *api.VolumeExpandRequest) ( // Read JSON response var volume api.VolumeInfoResponse err = utils.GetJsonFromResponse(r, &volume) - r.Body.Close() if err != nil { return nil, err } @@ -149,6 +203,7 @@ func (c *Client) VolumeList() (*api.VolumeListResponse, error) { if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return nil, utils.GetErrorFromResponse(r) } @@ -182,6 +237,7 @@ func (c *Client) VolumeInfo(id string) (*api.VolumeInfoResponse, error) { if err != nil { return nil, err } + defer r.Body.Close() if r.StatusCode != http.StatusOK { return nil, utils.GetErrorFromResponse(r) } @@ -189,7 +245,6 @@ func (c *Client) VolumeInfo(id string) (*api.VolumeInfoResponse, error) { // Read JSON response var volume api.VolumeInfoResponse err = utils.GetJsonFromResponse(r, &volume) - r.Body.Close() if err != nil { return nil, err } @@ -216,6 +271,7 @@ func (c *Client) VolumeDelete(id string) error { if err != nil { return err } + defer r.Body.Close() if r.StatusCode != http.StatusAccepted { return utils.GetErrorFromResponse(r) } @@ -231,3 +287,52 @@ func (c *Client) VolumeDelete(id string) error { return nil } + +func (c *Client) VolumeClone(id string, request *api.VolumeCloneRequest) (*api.VolumeInfoResponse, error) { + // Marshal request to JSON + buffer, err := json.Marshal(request) + if err != nil { + return nil, err + } + + // Create a request + req, err := http.NewRequest("POST", c.host+"/volumes/"+id+"/clone", bytes.NewBuffer(buffer)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + // Set token + err = c.setToken(req) + if err != nil { + return nil, err + } + + // Send request + r, err := c.do(req) + if err != nil { + return nil, err + } + defer r.Body.Close() + if r.StatusCode != http.StatusAccepted { + return nil, utils.GetErrorFromResponse(r) + } + + // Wait for response + r, err = c.waitForResponseWithTimer(r, time.Second) + if err != nil { + return nil, err + } + if r.StatusCode != http.StatusOK { + return nil, utils.GetErrorFromResponse(r) + } + + // Read JSON response + var volume api.VolumeInfoResponse + err = utils.GetJsonFromResponse(r, &volume) + if err != nil { + return nil, err + } + + return &volume, nil +} diff --git a/vendor/github.com/heketi/heketi/pkg/glusterfs/api/BUILD b/vendor/github.com/heketi/heketi/pkg/glusterfs/api/BUILD index 4adc57ab9690..53936fa0ad9e 100644 --- a/vendor/github.com/heketi/heketi/pkg/glusterfs/api/BUILD +++ b/vendor/github.com/heketi/heketi/pkg/glusterfs/api/BUILD @@ -6,6 +6,10 @@ go_library( importmap = "k8s.io/kubernetes/vendor/github.com/heketi/heketi/pkg/glusterfs/api", importpath = "github.com/heketi/heketi/pkg/glusterfs/api", visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/go-ozzo/ozzo-validation:go_default_library", + "//vendor/github.com/go-ozzo/ozzo-validation/is:go_default_library", + ], ) filegroup( diff --git a/vendor/github.com/heketi/heketi/pkg/glusterfs/api/types.go b/vendor/github.com/heketi/heketi/pkg/glusterfs/api/types.go index c244f5af9b92..759fb9bda3a2 100644 --- a/vendor/github.com/heketi/heketi/pkg/glusterfs/api/types.go +++ b/vendor/github.com/heketi/heketi/pkg/glusterfs/api/types.go @@ -18,9 +18,38 @@ package api import ( "fmt" + "regexp" "sort" + + "github.com/go-ozzo/ozzo-validation" + "github.com/go-ozzo/ozzo-validation/is" ) +var ( + // Restricting the deviceName to much smaller subset of Unix Path + // as unix path takes almost everything except NULL + deviceNameRe = regexp.MustCompile("^/[a-zA-Z0-9_.:/-]+$") + + // Volume name constraints decided by looking at + // "cli_validate_volname" function in cli-cmd-parser.c of gluster code + volumeNameRe = regexp.MustCompile("^[a-zA-Z0-9_-]+$") + + blockVolNameRe = regexp.MustCompile("^[a-zA-Z0-9_-]+$") + + tagNameRe = regexp.MustCompile("^[a-zA-Z0-9_.-]+$") +) + +// ValidateUUID is written this way because heketi UUID does not +// conform to neither UUID v4 nor v5. +func ValidateUUID(value interface{}) error { + s, _ := value.(string) + err := validation.Validate(s, validation.RuneLength(32, 32), is.Hexadecimal) + if err != nil { + return fmt.Errorf("%v is not a valid UUID", s) + } + return nil +} + // State type EntryState string @@ -31,6 +60,15 @@ const ( EntryStateFailed EntryState = "failed" ) +func ValidateEntryState(value interface{}) error { + s, _ := value.(EntryState) + err := validation.Validate(s, validation.Required, validation.In(EntryStateOnline, EntryStateOffline, EntryStateFailed)) + if err != nil { + return fmt.Errorf("%v is not valid state", s) + } + return nil +} + type DurabilityType string const ( @@ -39,11 +77,26 @@ const ( DurabilityEC DurabilityType = "disperse" ) +func ValidateDurabilityType(value interface{}) error { + s, _ := value.(DurabilityType) + err := validation.Validate(s, validation.Required, validation.In(DurabilityReplicate, DurabilityDistributeOnly, DurabilityEC)) + if err != nil { + return fmt.Errorf("%v is not a valid durability type", s) + } + return nil +} + // Common type StateRequest struct { State EntryState `json:"state"` } +func (statereq StateRequest) Validate() error { + return validation.ValidateStruct(&statereq, + validation.Field(&statereq.State, validation.Required, validation.By(ValidateEntryState)), + ) +} + // Storage values in KB type StorageSize struct { Total uint64 `json:"total"` @@ -56,6 +109,35 @@ type HostAddresses struct { Storage sort.StringSlice `json:"storage"` } +func ValidateManagementHostname(value interface{}) error { + s, _ := value.(sort.StringSlice) + for _, fqdn := range s { + err := validation.Validate(fqdn, validation.Required, is.Host) + if err != nil { + return fmt.Errorf("%v is not a valid manage hostname", s) + } + } + return nil +} + +func ValidateStorageHostname(value interface{}) error { + s, _ := value.(sort.StringSlice) + for _, ip := range s { + err := validation.Validate(ip, validation.Required, is.Host) + if err != nil { + return fmt.Errorf("%v is not a valid storage hostname", s) + } + } + return nil +} + +func (hostadd HostAddresses) Validate() error { + return validation.ValidateStruct(&hostadd, + validation.Field(&hostadd.Manage, validation.Required, validation.By(ValidateManagementHostname)), + validation.Field(&hostadd.Storage, validation.Required, validation.By(ValidateStorageHostname)), + ) +} + // Brick type BrickInfo struct { Id string `json:"id"` @@ -70,12 +152,29 @@ type BrickInfo struct { // Device type Device struct { - Name string `json:"name"` + Name string `json:"name"` + Tags map[string]string `json:"tags,omitempty"` +} + +func (dev Device) Validate() error { + return validation.ValidateStruct(&dev, + validation.Field(&dev.Name, validation.Required, validation.Match(deviceNameRe)), + validation.Field(&dev.Tags, validation.By(ValidateTags)), + ) } type DeviceAddRequest struct { Device - NodeId string `json:"node"` + NodeId string `json:"node"` + DestroyData bool `json:"destroydata,omitempty"` +} + +func (devAddReq DeviceAddRequest) Validate() error { + return validation.ValidateStruct(&devAddReq, + validation.Field(&devAddReq.Device, validation.Required), + validation.Field(&devAddReq.NodeId, validation.Required, validation.By(ValidateUUID)), + validation.Field(&devAddReq.DestroyData, validation.In(true, false)), + ) } type DeviceInfo struct { @@ -92,9 +191,19 @@ type DeviceInfoResponse struct { // Node type NodeAddRequest struct { - Zone int `json:"zone"` - Hostnames HostAddresses `json:"hostnames"` - ClusterId string `json:"cluster"` + Zone int `json:"zone"` + Hostnames HostAddresses `json:"hostnames"` + ClusterId string `json:"cluster"` + Tags map[string]string `json:"tags,omitempty"` +} + +func (req NodeAddRequest) Validate() error { + return validation.ValidateStruct(&req, + validation.Field(&req.Zone, validation.Required, validation.Min(1)), + validation.Field(&req.Hostnames, validation.Required), + validation.Field(&req.ClusterId, validation.Required, validation.By(ValidateUUID)), + validation.Field(&req.Tags, validation.By(ValidateTags)), + ) } type NodeInfo struct { @@ -109,20 +218,37 @@ type NodeInfoResponse struct { } // Cluster + +type ClusterFlags struct { + Block bool `json:"block"` + File bool `json:"file"` +} + type Cluster struct { Volumes []VolumeInfoResponse `json:"volumes"` Nodes []NodeInfoResponse `json:"nodes"` Id string `json:"id"` + ClusterFlags } type TopologyInfoResponse struct { ClusterList []Cluster `json:"clusters"` } +type ClusterCreateRequest struct { + ClusterFlags +} + +type ClusterSetFlagsRequest struct { + ClusterFlags +} + type ClusterInfoResponse struct { Id string `json:"id"` Nodes sort.StringSlice `json:"nodes"` Volumes sort.StringSlice `json:"volumes"` + ClusterFlags + BlockVolumes sort.StringSlice `json:"blockvolumes"` } type ClusterListResponse struct { @@ -147,19 +273,57 @@ type VolumeDurabilityInfo struct { } type VolumeCreateRequest struct { - // Size in GB + // Size in GiB Size int `json:"size"` Clusters []string `json:"clusters,omitempty"` Name string `json:"name"` Durability VolumeDurabilityInfo `json:"durability,omitempty"` Gid int64 `json:"gid,omitempty"` GlusterVolumeOptions []string `json:"glustervolumeoptions,omitempty"` + Block bool `json:"block,omitempty"` Snapshot struct { Enable bool `json:"enable"` Factor float32 `json:"factor"` } `json:"snapshot"` } +func (volCreateRequest VolumeCreateRequest) Validate() error { + return validation.ValidateStruct(&volCreateRequest, + validation.Field(&volCreateRequest.Size, validation.Required, validation.Min(1)), + validation.Field(&volCreateRequest.Clusters, validation.By(ValidateUUID)), + validation.Field(&volCreateRequest.Name, validation.Match(volumeNameRe)), + validation.Field(&volCreateRequest.Durability, validation.Skip), + validation.Field(&volCreateRequest.Gid, validation.Skip), + validation.Field(&volCreateRequest.GlusterVolumeOptions, validation.Skip), + validation.Field(&volCreateRequest.Block, validation.In(true, false)), + // This is possibly a bug in validation lib, ignore next two lines for now + // validation.Field(&volCreateRequest.Snapshot.Enable, validation.In(true, false)), + // validation.Field(&volCreateRequest.Snapshot.Factor, validation.Min(1.0)), + ) +} + +type BlockRestriction string + +const ( + Unrestricted BlockRestriction = "" + Locked BlockRestriction = "locked" + LockedByUpdate BlockRestriction = "locked-by-update" +) + +func (br BlockRestriction) String() string { + switch br { + case Unrestricted: + return "(none)" + case Locked: + return "locked" + case LockedByUpdate: + return "locked-by-update" + default: + return "unknown" + + } +} + type VolumeInfo struct { VolumeCreateRequest Id string `json:"id"` @@ -171,6 +335,12 @@ type VolumeInfo struct { Options map[string]string `json:"options"` } `json:"glusterfs"` } `json:"mount"` + BlockInfo struct { + FreeSize int `json:"freesize,omitempty"` + ReservedSize int `json:"reservedsize,omitempty"` + BlockVolumes sort.StringSlice `json:"blockvolume,omitempty"` + Restriction BlockRestriction `json:"restriction,omitempty"` + } `json:"blockinfo,omitempty"` } type VolumeInfoResponse struct { @@ -186,6 +356,132 @@ type VolumeExpandRequest struct { Size int `json:"expand_size"` } +func (volExpandReq VolumeExpandRequest) Validate() error { + return validation.ValidateStruct(&volExpandReq, + validation.Field(&volExpandReq.Size, validation.Required, validation.Min(1)), + ) +} + +type VolumeCloneRequest struct { + Name string `json:"name,omitempty"` +} + +func (vcr VolumeCloneRequest) Validate() error { + return validation.ValidateStruct(&vcr, + validation.Field(&vcr.Name, validation.Match(volumeNameRe)), + ) +} + +type VolumeBlockRestrictionRequest struct { + Restriction BlockRestriction `json:"restriction"` +} + +func (vbrr VolumeBlockRestrictionRequest) Validate() error { + return validation.ValidateStruct(&vbrr, + validation.Field(&vbrr.Restriction, + validation.In(Unrestricted, Locked))) +} + +// BlockVolume + +type BlockVolumeCreateRequest struct { + // Size in GiB + Size int `json:"size"` + Clusters []string `json:"clusters,omitempty"` + Name string `json:"name"` + Hacount int `json:"hacount,omitempty"` + Auth bool `json:"auth,omitempty"` +} + +func (blockVolCreateReq BlockVolumeCreateRequest) Validate() error { + return validation.ValidateStruct(&blockVolCreateReq, + validation.Field(&blockVolCreateReq.Size, validation.Required, validation.Min(1)), + validation.Field(&blockVolCreateReq.Clusters, validation.By(ValidateUUID)), + validation.Field(&blockVolCreateReq.Name, validation.Match(blockVolNameRe)), + validation.Field(&blockVolCreateReq.Hacount, validation.Min(1)), + validation.Field(&blockVolCreateReq.Auth, validation.Skip), + ) +} + +type BlockVolumeInfo struct { + BlockVolumeCreateRequest + Id string `json:"id"` + BlockVolume struct { + Hosts []string `json:"hosts"` + Iqn string `json:"iqn"` + Lun int `json:"lun"` + Username string `json:"username"` + Password string `json:"password"` + /* + Options map[string]string `json:"options"` // needed?... + */ + } `json:"blockvolume"` + Cluster string `json:"cluster,omitempty"` + BlockHostingVolume string `json:"blockhostingvolume,omitempty"` +} + +type BlockVolumeInfoResponse struct { + BlockVolumeInfo +} + +type BlockVolumeListResponse struct { + BlockVolumes []string `json:"blockvolumes"` +} + +type LogLevelInfo struct { + // should contain one or more logger to log-level-name mapping + LogLevel map[string]string `json:"loglevel"` +} + +type TagsChangeType string + +const ( + UnknownTagsChangeType TagsChangeType = "" + SetTags TagsChangeType = "set" + UpdateTags TagsChangeType = "update" + DeleteTags TagsChangeType = "delete" +) + +// Common tag post body +type TagsChangeRequest struct { + Tags map[string]string `json:"tags"` + Change TagsChangeType `json:"change_type"` +} + +func (tcr TagsChangeRequest) Validate() error { + return validation.ValidateStruct(&tcr, + validation.Field(&tcr.Tags, validation.By(ValidateTags)), + validation.Field(&tcr.Change, + validation.Required, + validation.In(SetTags, UpdateTags, DeleteTags))) +} + +func ValidateTags(v interface{}) error { + t, ok := v.(map[string]string) + if !ok { + return fmt.Errorf("tags must be a map of strings to strings") + } + if len(t) > 32 { + return fmt.Errorf("too many tags specified (%v), up to %v supported", + len(t), 32) + } + for k, v := range t { + if len(k) == 0 { + return fmt.Errorf("tag names may not be empty") + } + if err := validation.Validate(k, validation.RuneLength(1, 32)); err != nil { + return fmt.Errorf("tag name %v: %v", k, err) + } + if err := validation.Validate(v, validation.RuneLength(0, 64)); err != nil { + return fmt.Errorf("value of tag %v: %v", k, err) + } + if !tagNameRe.MatchString(k) { + return fmt.Errorf("invalid characters in tag name %+v", k) + } + } + return nil +} + // Constructors func NewVolumeInfoResponse() *VolumeInfoResponse { @@ -205,6 +501,11 @@ func (v *VolumeInfoResponse) String() string { "Cluster Id: %v\n"+ "Mount: %v\n"+ "Mount Options: backup-volfile-servers=%v\n"+ + "Block: %v\n"+ + "Free Size: %v\n"+ + "Reserved Size: %v\n"+ + "Block Hosting Restriction: %v\n"+ + "Block Volumes: %v\n"+ "Durability Type: %v\n", v.Name, v.Size, @@ -212,6 +513,11 @@ func (v *VolumeInfoResponse) String() string { v.Cluster, v.Mount.GlusterFS.MountPoint, v.Mount.GlusterFS.Options["backup-volfile-servers"], + v.Block, + v.BlockInfo.FreeSize, + v.BlockInfo.ReservedSize, + v.BlockInfo.Restriction, + v.BlockInfo.BlockVolumes, v.Durability.Type) switch v.Durability.Type { @@ -248,3 +554,90 @@ func (v *VolumeInfoResponse) String() string { return s } + +func NewBlockVolumeInfoResponse() *BlockVolumeInfoResponse { + + info := &BlockVolumeInfoResponse{} + // Nothing to Construct now maybe for future + + return info +} + +// String functions +func (v *BlockVolumeInfoResponse) String() string { + s := fmt.Sprintf("Name: %v\n"+ + "Size: %v\n"+ + "Volume Id: %v\n"+ + "Cluster Id: %v\n"+ + "Hosts: %v\n"+ + "IQN: %v\n"+ + "LUN: %v\n"+ + "Hacount: %v\n"+ + "Username: %v\n"+ + "Password: %v\n"+ + "Block Hosting Volume: %v\n", + v.Name, + v.Size, + v.Id, + v.Cluster, + v.BlockVolume.Hosts, + v.BlockVolume.Iqn, + v.BlockVolume.Lun, + v.Hacount, + v.BlockVolume.Username, + v.BlockVolume.Password, + v.BlockHostingVolume) + + /* + s += "\nBricks:\n" + for _, b := range v.Bricks { + s += fmt.Sprintf("Id: %v\n"+ + "Path: %v\n"+ + "Size (GiB): %v\n"+ + "Node: %v\n"+ + "Device: %v\n\n", + b.Id, + b.Path, + b.Size/(1024*1024), + b.NodeId, + b.DeviceId) + } + */ + + return s +} + +type OperationsInfo struct { + Total uint64 `json:"total"` + InFlight uint64 `json:"in_flight"` + // state based counts: + Stale uint64 `json:"stale"` + New uint64 `json:"new"` +} + +type AdminState string + +const ( + AdminStateNormal AdminState = "normal" + AdminStateReadOnly AdminState = "read-only" + AdminStateLocal AdminState = "local-client" +) + +type AdminStatus struct { + State AdminState `json:"state"` +} + +func (as AdminStatus) Validate() error { + return validation.ValidateStruct(&as, + validation.Field(&as.State, + validation.Required, + validation.In(AdminStateNormal, AdminStateReadOnly, AdminStateLocal))) +} + +// DeviceDeleteOptions is used to specify additional behavior for device +// deletes. +type DeviceDeleteOptions struct { + // force heketi to forget about a device, possibly + // orphaning metadata on the node + ForceForget bool `json:"forceforget"` +} diff --git a/vendor/github.com/heketi/heketi/pkg/utils/BUILD b/vendor/github.com/heketi/heketi/pkg/utils/BUILD index e7cbd9129833..bb83291af8a6 100644 --- a/vendor/github.com/heketi/heketi/pkg/utils/BUILD +++ b/vendor/github.com/heketi/heketi/pkg/utils/BUILD @@ -5,17 +5,11 @@ go_library( srcs = [ "bodystring.go", "jsonutils.go", - "log.go", - "sortedstrings.go", "statusgroup.go", - "stringset.go", - "stringstack.go", - "uuid.go", ], importmap = "k8s.io/kubernetes/vendor/github.com/heketi/heketi/pkg/utils", importpath = "github.com/heketi/heketi/pkg/utils", visibility = ["//visibility:public"], - deps = ["//vendor/github.com/lpabon/godbc:go_default_library"], ) filegroup( diff --git a/vendor/github.com/heketi/heketi/pkg/utils/bodystring.go b/vendor/github.com/heketi/heketi/pkg/utils/bodystring.go index 468db04e4541..8a7b4aca1bc1 100644 --- a/vendor/github.com/heketi/heketi/pkg/utils/bodystring.go +++ b/vendor/github.com/heketi/heketi/pkg/utils/bodystring.go @@ -3,14 +3,18 @@ // // This file is licensed to you under your choice of the GNU Lesser // General Public License, version 3 or any later version (LGPLv3 or -// later), or the GNU General Public License, version 2 (GPLv2), in all -// cases as published by the Free Software Foundation. +// later), as published by the Free Software Foundation, +// or under the Apache License, Version 2.0 . +// +// You may not use this file except in compliance with those terms. // package utils import ( "errors" + "fmt" "io" "io/ioutil" "net/http" @@ -20,10 +24,10 @@ import ( // Return the body from a response as a string func GetStringFromResponse(r *http.Response) (string, error) { body, err := ioutil.ReadAll(io.LimitReader(r.Body, r.ContentLength)) + defer r.Body.Close() if err != nil { return "", err } - r.Body.Close() return string(body), nil } @@ -33,5 +37,10 @@ func GetErrorFromResponse(r *http.Response) error { if err != nil { return err } - return errors.New(strings.TrimSpace(s)) + + s = strings.TrimSpace(s) + if len(s) == 0 { + return fmt.Errorf("server did not provide a message (status %v: %v)", r.StatusCode, http.StatusText(r.StatusCode)) + } + return errors.New(s) } diff --git a/vendor/github.com/heketi/heketi/pkg/utils/jsonutils.go b/vendor/github.com/heketi/heketi/pkg/utils/jsonutils.go index 77781d9c938b..6fb958d8ff47 100644 --- a/vendor/github.com/heketi/heketi/pkg/utils/jsonutils.go +++ b/vendor/github.com/heketi/heketi/pkg/utils/jsonutils.go @@ -3,8 +3,11 @@ // // This file is licensed to you under your choice of the GNU Lesser // General Public License, version 3 or any later version (LGPLv3 or -// later), or the GNU General Public License, version 2 (GPLv2), in all -// cases as published by the Free Software Foundation. +// later), as published by the Free Software Foundation, +// or under the Apache License, Version 2.0 . +// +// You may not use this file except in compliance with those terms. // package utils diff --git a/vendor/github.com/heketi/heketi/pkg/utils/log.go b/vendor/github.com/heketi/heketi/pkg/utils/log.go deleted file mode 100644 index a9451ed7e575..000000000000 --- a/vendor/github.com/heketi/heketi/pkg/utils/log.go +++ /dev/null @@ -1,155 +0,0 @@ -// -// Copyright (c) 2015 The heketi Authors -// -// This file is licensed to you under your choice of the GNU Lesser -// General Public License, version 3 or any later version (LGPLv3 or -// later), or the GNU General Public License, version 2 (GPLv2), in all -// cases as published by the Free Software Foundation. -// - -package utils - -import ( - "fmt" - "io" - "log" - "os" - "runtime" - "strings" - - "github.com/lpabon/godbc" -) - -type LogLevel int - -// Log levels -const ( - LEVEL_NOLOG LogLevel = iota - LEVEL_CRITICAL - LEVEL_ERROR - LEVEL_WARNING - LEVEL_INFO - LEVEL_DEBUG -) - -var ( - stderr io.Writer = os.Stderr - stdout io.Writer = os.Stdout -) - -type Logger struct { - critlog, errorlog, infolog *log.Logger - debuglog, warninglog *log.Logger - - level LogLevel -} - -func logWithLongFile(l *log.Logger, format string, v ...interface{}) { - _, file, line, _ := runtime.Caller(2) - - // Shorten the path. - // From - // /builddir/build/BUILD/heketi-3f4a5b1b6edff87232e8b24533c53b4151ebd9c7/src/github.com/heketi/heketi/apps/glusterfs/volume_entry.go - // to - // src/github.com/heketi/heketi/apps/glusterfs/volume_entry.go - i := strings.Index(file, "/src/") - if i == -1 { - i = 0 - } - - l.Print(fmt.Sprintf("%v:%v: ", file[i:], line) + - fmt.Sprintf(format, v...)) -} - -// Create a new logger -func NewLogger(prefix string, level LogLevel) *Logger { - godbc.Require(level >= 0, level) - godbc.Require(level <= LEVEL_DEBUG, level) - - l := &Logger{} - - if level == LEVEL_NOLOG { - l.level = LEVEL_DEBUG - } else { - l.level = level - } - - l.critlog = log.New(stderr, prefix+" CRITICAL ", log.LstdFlags) - l.errorlog = log.New(stderr, prefix+" ERROR ", log.LstdFlags) - l.warninglog = log.New(stdout, prefix+" WARNING ", log.LstdFlags) - l.infolog = log.New(stdout, prefix+" INFO ", log.LstdFlags) - l.debuglog = log.New(stdout, prefix+" DEBUG ", log.LstdFlags) - - godbc.Ensure(l.critlog != nil) - godbc.Ensure(l.errorlog != nil) - godbc.Ensure(l.warninglog != nil) - godbc.Ensure(l.infolog != nil) - godbc.Ensure(l.debuglog != nil) - - return l -} - -// Return current level -func (l *Logger) Level() LogLevel { - return l.level -} - -// Set level -func (l *Logger) SetLevel(level LogLevel) { - l.level = level -} - -// Log critical information -func (l *Logger) Critical(format string, v ...interface{}) { - if l.level >= LEVEL_CRITICAL { - logWithLongFile(l.critlog, format, v...) - } -} - -// Log error string -func (l *Logger) LogError(format string, v ...interface{}) error { - if l.level >= LEVEL_ERROR { - logWithLongFile(l.errorlog, format, v...) - } - - return fmt.Errorf(format, v...) -} - -// Log error variable -func (l *Logger) Err(err error) error { - if l.level >= LEVEL_ERROR { - logWithLongFile(l.errorlog, "%v", err) - } - - return err -} - -// Log warning information -func (l *Logger) Warning(format string, v ...interface{}) { - if l.level >= LEVEL_WARNING { - l.warninglog.Printf(format, v...) - } -} - -// Log error variable as a warning -func (l *Logger) WarnErr(err error) error { - if l.level >= LEVEL_WARNING { - logWithLongFile(l.warninglog, "%v", err) - } - - return err -} - -// Log string -func (l *Logger) Info(format string, v ...interface{}) { - if l.level >= LEVEL_INFO { - l.infolog.Printf(format, v...) - } -} - -// Log string as debug -func (l *Logger) Debug(format string, v ...interface{}) { - if l.level >= LEVEL_DEBUG { - logWithLongFile(l.debuglog, format, v...) - } -} diff --git a/vendor/github.com/heketi/heketi/pkg/utils/sortedstrings.go b/vendor/github.com/heketi/heketi/pkg/utils/sortedstrings.go deleted file mode 100644 index 985230d9f329..000000000000 --- a/vendor/github.com/heketi/heketi/pkg/utils/sortedstrings.go +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2015 The heketi Authors -// -// This file is licensed to you under your choice of the GNU Lesser -// General Public License, version 3 or any later version (LGPLv3 or -// later), or the GNU General Public License, version 2 (GPLv2), in all -// cases as published by the Free Software Foundation. -// - -package utils - -import ( - "sort" -) - -// Check if a sorted string list has a string -func SortedStringHas(s sort.StringSlice, x string) bool { - index := s.Search(x) - if index == len(s) { - return false - } - return s[s.Search(x)] == x -} - -// Delete a string from a sorted string list -func SortedStringsDelete(s sort.StringSlice, x string) sort.StringSlice { - index := s.Search(x) - if len(s) != index && s[index] == x { - s = append(s[:index], s[index+1:]...) - } - - return s -} diff --git a/vendor/github.com/heketi/heketi/pkg/utils/statusgroup.go b/vendor/github.com/heketi/heketi/pkg/utils/statusgroup.go index 7c678a5031bf..c0354c964c4e 100644 --- a/vendor/github.com/heketi/heketi/pkg/utils/statusgroup.go +++ b/vendor/github.com/heketi/heketi/pkg/utils/statusgroup.go @@ -3,8 +3,11 @@ // // This file is licensed to you under your choice of the GNU Lesser // General Public License, version 3 or any later version (LGPLv3 or -// later), or the GNU General Public License, version 2 (GPLv2), in all -// cases as published by the Free Software Foundation. +// later), as published by the Free Software Foundation, +// or under the Apache License, Version 2.0 . +// +// You may not use this file except in compliance with those terms. // package utils diff --git a/vendor/github.com/heketi/heketi/pkg/utils/stringset.go b/vendor/github.com/heketi/heketi/pkg/utils/stringset.go deleted file mode 100644 index 8d7f3ca780d9..000000000000 --- a/vendor/github.com/heketi/heketi/pkg/utils/stringset.go +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) 2015 The heketi Authors -// -// This file is licensed to you under your choice of the GNU Lesser -// General Public License, version 3 or any later version (LGPLv3 or -// later), or the GNU General Public License, version 2 (GPLv2), in all -// cases as published by the Free Software Foundation. -// - -package utils - -import ( - "sort" -) - -type StringSet struct { - Set sort.StringSlice -} - -// Create a string set. -// -// A string set is a list where each element appears only once -func NewStringSet() *StringSet { - return &StringSet{ - Set: make(sort.StringSlice, 0), - } -} - -// Add a string to the string set -func (s *StringSet) Add(v string) { - if !SortedStringHas(s.Set, v) { - s.Set = append(s.Set, v) - s.Set.Sort() - } -} - -// Return string list -func (s *StringSet) Strings() []string { - return s.Set -} - -func (s *StringSet) Len() int { - return len(s.Set) -} diff --git a/vendor/github.com/heketi/heketi/pkg/utils/stringstack.go b/vendor/github.com/heketi/heketi/pkg/utils/stringstack.go deleted file mode 100644 index c1b48e219aa0..000000000000 --- a/vendor/github.com/heketi/heketi/pkg/utils/stringstack.go +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2015 The heketi Authors -// -// This file is licensed to you under your choice of the GNU Lesser -// General Public License, version 3 or any later version (LGPLv3 or -// later), or the GNU General Public License, version 2 (GPLv2), in all -// cases as published by the Free Software Foundation. -// - -package utils - -type StringStack struct { - list []string -} - -func NewStringStack() *StringStack { - a := &StringStack{} - a.list = make([]string, 0) - return a -} - -func (a *StringStack) IsEmpty() bool { - return len(a.list) == 0 -} - -func (a *StringStack) Pop() (x string) { - x, a.list = a.list[0], a.list[1:len(a.list)] - return -} - -func (a *StringStack) Push(x string) { - a.list = append(a.list, x) -} diff --git a/vendor/github.com/heketi/heketi/pkg/utils/uuid.go b/vendor/github.com/heketi/heketi/pkg/utils/uuid.go deleted file mode 100644 index 39e743d4dad6..000000000000 --- a/vendor/github.com/heketi/heketi/pkg/utils/uuid.go +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright (c) 2015 The heketi Authors -// -// This file is licensed to you under your choice of the GNU Lesser -// General Public License, version 3 or any later version (LGPLv3 or -// later), or the GNU General Public License, version 2 (GPLv2), in all -// cases as published by the Free Software Foundation. - -package utils - -// From http://www.ashishbanerjee.com/home/go/go-generate-uuid - -import ( - "crypto/rand" - "encoding/hex" - "github.com/lpabon/godbc" -) - -// Return a 16-byte uuid -func GenUUID() string { - uuid := make([]byte, 16) - n, err := rand.Read(uuid) - godbc.Check(n == len(uuid), n, len(uuid)) - godbc.Check(err == nil, err) - - return hex.EncodeToString(uuid) -} diff --git a/vendor/github.com/lpabon/godbc/.travis.yml b/vendor/github.com/lpabon/godbc/.travis.yml deleted file mode 100644 index 43b7cb86537c..000000000000 --- a/vendor/github.com/lpabon/godbc/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go - -go: - - 1.1 - - 1.2 - - tip - -install: - - go get github.com/stretchr/testify - -script: - - go test - - go test -tags 'prod' diff --git a/vendor/github.com/lpabon/godbc/AUTHORS b/vendor/github.com/lpabon/godbc/AUTHORS deleted file mode 100644 index d4ddde5dd014..000000000000 --- a/vendor/github.com/lpabon/godbc/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -lpabon@redhat.com \ No newline at end of file diff --git a/vendor/github.com/lpabon/godbc/LICENSE b/vendor/github.com/lpabon/godbc/LICENSE deleted file mode 100644 index ad410e113021..000000000000 --- a/vendor/github.com/lpabon/godbc/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/vendor/github.com/lpabon/godbc/README.md b/vendor/github.com/lpabon/godbc/README.md deleted file mode 100644 index 2df53d423730..000000000000 --- a/vendor/github.com/lpabon/godbc/README.md +++ /dev/null @@ -1,21 +0,0 @@ -[![Build Status](https://travis-ci.org/lpabon/godbc.svg?branch=master)](https://travis-ci.org/lpabon/godbc) - -# godbc - -Design by contract for Go - -# Installation - -To install godbc, use `go get`: - - go get github.com/lpabon/godbc - -Import the `godbc` package into your code using this template: - - import ( - "github.com/lpabon/godbc" - ) - -# Documentation - -Documentation is available at https://godoc.org/github.com/lpabon/godbc diff --git a/vendor/github.com/lpabon/godbc/godbc.go b/vendor/github.com/lpabon/godbc/godbc.go deleted file mode 100644 index 7c44a9154eac..000000000000 --- a/vendor/github.com/lpabon/godbc/godbc.go +++ /dev/null @@ -1,146 +0,0 @@ -//+build !prod - -// -// Copyright (c) 2014 The godbc Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Design-by-Contract for Go -// -// Design by Contract is a programming methodology -// which binds the caller and the function called to a -// contract. The contract is represented using Hoare Triple: -// {P} C {Q} -// where {P} is the precondition before executing command C, -// and {Q} is the postcondition. -// -// See Also -// -// * http://en.wikipedia.org/wiki/Design_by_contract -// * http://en.wikipedia.org/wiki/Hoare_logic -// * http://dlang.org/dbc.html -// -// Usage -// -// Godbc is enabled by default, but can be disabled for production -// builds by using the tag 'prod' in builds and tests as follows: -// go build -tags 'prod' -// or -// go test -tags 'prod' -// -package godbc - -import ( - "errors" - "fmt" - "runtime" -) - -// InvariantSimpleTester is an interface which provides a receiver to -// test the object -type InvariantSimpleTester interface { - Invariant() bool -} - -// InvariantTester is an interface which provides not only an Invariant(), -// but also a receiver to print the structure -type InvariantTester interface { - InvariantSimpleTester - String() string -} - -// dbc_panic prints to the screen information of the failure followed -// by a call to panic() -func dbc_panic(dbc_func_name string, b bool, message ...interface{}) { - if !b { - - // Get caller information which is the caller - // of the caller of this function - pc, file, line, _ := runtime.Caller(2) - caller_func_info := runtime.FuncForPC(pc) - - error_string := fmt.Sprintf("%s:\n\r\tfunc (%s) 0x%x\n\r\tFile %s:%d", - dbc_func_name, - caller_func_info.Name(), - pc, - file, - line) - - if len(message) > 0 { - error_string += fmt.Sprintf("\n\r\tInfo: %+v", message) - } - err := errors.New(error_string) - - // Finally panic - panic(err) - } -} - -// Require checks that the preconditions are satisfied before -// executing the function -// -// Example Code -// -// func Divide(a, b int) int { -// godbc.Require(b != 0) -// return a/b -// } -// -func Require(b bool, message ...interface{}) { - dbc_panic("REQUIRE", b, message...) -} - -// Ensure checks the postconditions are satisfied before returning -// to the caller. -// -// Example Code -// -// type Data struct { -// a int -// } -// -// func (*d Data) Set(a int) { -// d.a = a -// godbc.Ensure(d.a == a) -// } -// -func Ensure(b bool, message ...interface{}) { - dbc_panic("ENSURE", b, message...) -} - -// Check provides a simple assert -func Check(b bool, message ...interface{}) { - dbc_panic("CHECK", b, message...) -} - -// InvariantSimple calls the objects Invariant() receiver to test -// the object for correctness. -// -// The caller object must provide an object that supports the -// interface InvariantSimpleTester and does not need to provide -// a String() receiver -func InvariantSimple(obj InvariantSimpleTester, message ...interface{}) { - dbc_panic("INVARIANT", obj.Invariant(), message...) -} - -// Invariant calls the objects Invariant() receiver to test -// the object for correctness. -// -// The caller object must provide an object that supports the -// interface InvariantTester -// -// To see an example, please take a look at the godbc_test.go -func Invariant(obj InvariantTester, message ...interface{}) { - m := append(message, obj) - dbc_panic("INVARIANT", obj.Invariant(), m) -} diff --git a/vendor/github.com/lpabon/godbc/godbc_prod.go b/vendor/github.com/lpabon/godbc/godbc_prod.go deleted file mode 100644 index 1cb2fffb8073..000000000000 --- a/vendor/github.com/lpabon/godbc/godbc_prod.go +++ /dev/null @@ -1,42 +0,0 @@ -//+build prod - -// -// Copyright (c) 2014 The godbc Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package godbc - -type InvariantSimpleTester interface { - Invariant() bool -} - -type InvariantTester interface { - InvariantSimpleTester - String() string -} - -func Require(b bool, message ...interface{}) { -} - -func Ensure(b bool, message ...interface{}) { -} - -func Check(b bool, message ...interface{}) { -} - -func InvariantSimple(obj InvariantSimpleTester, message ...interface{}) { -} - -func Invariant(obj InvariantTester, message ...interface{}) { -}