diff --git a/go.mod b/go.mod index 10f34093fae..6b7c76e97fd 100644 --- a/go.mod +++ b/go.mod @@ -246,6 +246,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect + github.com/openshift/assisted-service v1.0.10-0.20230830164851-6573b5d7021d // indirect github.com/openshift/custom-resource-status v1.1.2 // indirect github.com/openshift/machine-api-operator v0.2.1-0.20240722145313-3a817c78946a // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect @@ -261,6 +262,7 @@ require ( github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace // indirect github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect + github.com/thoas/go-funk v0.9.3 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect github.com/zclconf/go-cty v1.11.0 // indirect @@ -313,11 +315,11 @@ replace ( replace sigs.k8s.io/cluster-api-provider-ibmcloud => sigs.k8s.io/cluster-api-provider-ibmcloud v0.9.0-alpha.0.0.20240913094112-c6bcd313bce0 -replace github.com/openshift/assisted-service/api => github.com/openshift/assisted-service/api v0.0.0-20230831114549-1922eda29cf8 +replace github.com/openshift/assisted-service/api => github.com/openshift/assisted-service/api v0.0.0-20231215152050-d41f53691d6e -replace github.com/openshift/assisted-service/client => github.com/openshift/assisted-service/client v0.0.0-20230831114549-1922eda29cf8 +replace github.com/openshift/assisted-service/client => github.com/openshift/assisted-service/client v0.0.0-20231215152050-d41f53691d6e -replace github.com/openshift/assisted-service/models => github.com/openshift/assisted-service/models v0.0.0-20230831114549-1922eda29cf8 +replace github.com/openshift/assisted-service/models => github.com/openshift/assisted-service/models v0.0.0-20231215152050-d41f53691d6e // https://issues.redhat.com/browse/OCPBUGS-8119 // https://issues.redhat.com/browse/OCPBUGS-27507 diff --git a/go.sum b/go.sum index 1582d3d9fc2..8226f84a4f4 100644 --- a/go.sum +++ b/go.sum @@ -768,12 +768,14 @@ github.com/openshift/api v0.0.0-20240809035623-d6942fb7294e h1:gEw+Gxu4r3g9WAYOI github.com/openshift/api v0.0.0-20240809035623-d6942fb7294e/go.mod h1:OOh6Qopf21pSzqNVCB5gomomBXb8o5sGKZxG2KNpaXM= github.com/openshift/assisted-image-service v0.0.0-20240607085136-02df2e56dde6 h1:U6ve+dnHlHhAELoxX+rdFOHVhoaYl0l9qtxwYtsO6C0= github.com/openshift/assisted-image-service v0.0.0-20240607085136-02df2e56dde6/go.mod h1:o2H5VwQhUD8P6XsK6dRmKpCCJqVvv12KJQZBXmcCXCU= -github.com/openshift/assisted-service/api v0.0.0-20230831114549-1922eda29cf8 h1:+fZLKbycDo4JeLwPGVSAgf2XPaJGLM341l9ZfrrlxG0= -github.com/openshift/assisted-service/api v0.0.0-20230831114549-1922eda29cf8/go.mod h1:PmMnbVno5ocinfELDdKOaatvT5ucJLrau+fjHQNeCiY= -github.com/openshift/assisted-service/client v0.0.0-20230831114549-1922eda29cf8 h1:9NpCGby6O44BlWqWCbd8wcN4QwBebR8McQGrjTwhlzQ= -github.com/openshift/assisted-service/client v0.0.0-20230831114549-1922eda29cf8/go.mod h1:k0S4WqxFuMBJYyinCgHjtWoEnE6/R2OyakW60MUHPYQ= -github.com/openshift/assisted-service/models v0.0.0-20230831114549-1922eda29cf8 h1:lQO/vwmLX4kSmZitusnqdq9KbuW402DWkcmR0CJfgBI= -github.com/openshift/assisted-service/models v0.0.0-20230831114549-1922eda29cf8/go.mod h1:ImkG1jQgM72erhLaZtWqEn0g0Y8AYUOxLR/HgvlPi2Y= +github.com/openshift/assisted-service v1.0.10-0.20230830164851-6573b5d7021d h1:CKw2Y4EdaFsMoqAdr2Tq0nlYTaaXmCRdP0gOu7pN64U= +github.com/openshift/assisted-service v1.0.10-0.20230830164851-6573b5d7021d/go.mod h1:1J9kimemAdpLZVb3yLDEGmzwK0DXZ4/x6POeEog8A+4= +github.com/openshift/assisted-service/api v0.0.0-20231215152050-d41f53691d6e h1:YpFedWNg2Y5gkqw3M2FN45iyGUiIzg8yvPjteEnL8gU= +github.com/openshift/assisted-service/api v0.0.0-20231215152050-d41f53691d6e/go.mod h1:beaoSFvU8GCXwVb11vgQEGdPGSko+CQCSIYHc04if5Y= +github.com/openshift/assisted-service/client v0.0.0-20231215152050-d41f53691d6e h1:4e9xSfRoM0msjSjzx7kbLJ9xNQ24/YdZrni3798zthE= +github.com/openshift/assisted-service/client v0.0.0-20231215152050-d41f53691d6e/go.mod h1:L0Q77cX4nqrxpFjvkcMSFNSm4vNvKrIXgZc8vxxDHuE= +github.com/openshift/assisted-service/models v0.0.0-20231215152050-d41f53691d6e h1:UDlcixue45RaW9dOsPFDwffMQu9kGm2EdBvLXCm1584= +github.com/openshift/assisted-service/models v0.0.0-20231215152050-d41f53691d6e/go.mod h1:k18+EZ03irOyyZ+bYrnWVOr0mLgCNw8rkHY4c+GuIK4= github.com/openshift/baremetal-operator/apis v0.0.0-20231128154154-6736c9b9c6c8 h1:f5nZJ4mB9Rf1epInmKoqDJGdoHyqZwHCiaE/OH4Yx84= github.com/openshift/baremetal-operator/apis v0.0.0-20231128154154-6736c9b9c6c8/go.mod h1:CvKrrnAcvvtrZIc9y9WaqWmJhK0AJ9sWnh+VP4d7jcM= github.com/openshift/baremetal-operator/pkg/hardwareutils v0.0.0-20231128154154-6736c9b9c6c8 h1:38vY9w7dXqB7tI9g1GCUnpahNDyBbp9Yylq+BQ154YE= @@ -900,6 +902,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtse github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/thedevsaddam/retry v0.0.0-20200324223450-9769a859cc6d h1:U8ZUZKRBI+Xgo3QWD/alCQ2vIysyl0Efx8yCJWPdaGQ= github.com/thedevsaddam/retry v0.0.0-20200324223450-9769a859cc6d/go.mod h1:2rz2mY+1qEXG47loLDkV+ZJHGFwmhax5rOTpP+5aR80= +github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw= +github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= diff --git a/pkg/asset/agent/image/agentartifacts.go b/pkg/asset/agent/image/agentartifacts.go index c7707c843c6..bba1134120c 100644 --- a/pkg/asset/agent/image/agentartifacts.go +++ b/pkg/asset/agent/image/agentartifacts.go @@ -9,11 +9,11 @@ import ( "strings" "github.com/openshift/assisted-image-service/pkg/isoeditor" - "github.com/openshift/assisted-service/models" "github.com/openshift/installer/pkg/asset" config "github.com/openshift/installer/pkg/asset/agent/agentconfig" "github.com/openshift/installer/pkg/asset/agent/manifests" "github.com/openshift/installer/pkg/asset/agent/mirror" + external "github.com/openshift/installer/pkg/types/external" ) const ( @@ -76,7 +76,7 @@ func (a *AgentArtifacts) Generate(_ context.Context, dependencies asset.Parents) } var agentTuiFiles []string - if agentClusterInstall.GetExternalPlatformName() != string(models.PlatformTypeOci) { + if agentClusterInstall.GetExternalPlatformName() != external.ExternalPlatformNameOci { agentTuiFiles, err = a.fetchAgentTuiFiles(agentManifests.ClusterImageSet.Spec.ReleaseImage, agentManifests.GetPullSecretData(), registriesConf.MirrorConfig) if err != nil { return err diff --git a/pkg/asset/agent/image/kargs.go b/pkg/asset/agent/image/kargs.go index 67fdc80c852..5bda94c7ad0 100644 --- a/pkg/asset/agent/image/kargs.go +++ b/pkg/asset/agent/image/kargs.go @@ -7,11 +7,11 @@ import ( "github.com/sirupsen/logrus" hiveext "github.com/openshift/assisted-service/api/hiveextension/v1beta1" - "github.com/openshift/assisted-service/models" "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/agent/joiner" "github.com/openshift/installer/pkg/asset/agent/manifests" "github.com/openshift/installer/pkg/asset/agent/workflow" + external "github.com/openshift/installer/pkg/types/external" ) // Kargs is an Asset that generates the additional kernel args. @@ -40,8 +40,8 @@ func (a *Kargs) Generate(_ context.Context, dependencies asset.Parents) error { case workflow.AgentWorkflowTypeInstall: a.fips = agentClusterInstall.FIPSEnabled() // Add kernel args for external oci platform - if agentClusterInstall.GetExternalPlatformName() == string(models.PlatformTypeOci) { - logrus.Debugf("Added kernel args to enable serial console for %s %s platform", hiveext.ExternalPlatformType, string(models.PlatformTypeOci)) + if agentClusterInstall.GetExternalPlatformName() == external.ExternalPlatformNameOci { + logrus.Debugf("Added kernel args to enable serial console for %s %s platform", hiveext.ExternalPlatformType, external.ExternalPlatformNameOci) a.consoleArgs = " console=ttyS0" } diff --git a/pkg/asset/agent/installconfig.go b/pkg/asset/agent/installconfig.go index e25fd07002e..e6c115d4074 100644 --- a/pkg/asset/agent/installconfig.go +++ b/pkg/asset/agent/installconfig.go @@ -10,7 +10,6 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" configv1 "github.com/openshift/api/config/v1" - "github.com/openshift/assisted-service/models" "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/asset/releaseimage" @@ -133,10 +132,10 @@ func (a *OptionalInstallConfig) validatePlatformsByName(installConfig *types.Ins var allErrs field.ErrorList if installConfig.Platform.Name() == external.Name { - if installConfig.Platform.External.PlatformName == string(models.PlatformTypeOci) && + if installConfig.Platform.External.PlatformName == external.ExternalPlatformNameOci && installConfig.Platform.External.CloudControllerManager != external.CloudControllerManagerTypeExternal { fieldPath := field.NewPath("Platform", "External", "CloudControllerManager") - allErrs = append(allErrs, field.Invalid(fieldPath, installConfig.Platform.External.CloudControllerManager, fmt.Sprintf("When using external %s platform, %s must be set to %s", string(models.PlatformTypeOci), fieldPath, external.CloudControllerManagerTypeExternal))) + allErrs = append(allErrs, field.Invalid(fieldPath, installConfig.Platform.External.CloudControllerManager, fmt.Sprintf("When using external %s platform, %s must be set to %s", external.ExternalPlatformNameOci, fieldPath, external.CloudControllerManagerTypeExternal))) } } diff --git a/pkg/asset/agent/manifests/agentclusterinstall_test.go b/pkg/asset/agent/manifests/agentclusterinstall_test.go index 0ee91dcacb6..31f22b6e757 100644 --- a/pkg/asset/agent/manifests/agentclusterinstall_test.go +++ b/pkg/asset/agent/manifests/agentclusterinstall_test.go @@ -14,7 +14,6 @@ import ( configv1 "github.com/openshift/api/config/v1" hiveext "github.com/openshift/assisted-service/api/hiveextension/v1beta1" - "github.com/openshift/assisted-service/models" hivev1 "github.com/openshift/hive/apis/hive/v1" "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/agent" @@ -104,7 +103,7 @@ func TestAgentClusterInstall_Generate(t *testing.T) { installConfigWExternalOCIPlatform := getValidOptionalInstallConfig() installConfigWExternalOCIPlatform.Config.Platform = types.Platform{ External: &externaltype.Platform{ - PlatformName: string(models.PlatformTypeOci), + PlatformName: externaltype.ExternalPlatformNameOci, CloudControllerManager: externaltype.CloudControllerManagerTypeExternal, }, } @@ -118,7 +117,7 @@ func TestAgentClusterInstall_Generate(t *testing.T) { goodExternalOCIPlatformACI.Spec.Networking.UserManagedNetworking = &val goodExternalOCIPlatformACI.Spec.PlatformType = hiveext.ExternalPlatformType goodExternalOCIPlatformACI.Spec.ExternalPlatformSpec = &hiveext.ExternalPlatformSpec{ - PlatformName: string(models.PlatformTypeOci), + PlatformName: externaltype.ExternalPlatformNameOci, } goodExternalOCIPlatformACI.SetAnnotations(map[string]string{ installConfigOverrides: `{"platform":{"external":{"platformName":"oci","cloudControllerManager":"External"}}}`, @@ -405,7 +404,7 @@ spec: IngressVIP: "192.168.111.4", PlatformType: hiveext.ExternalPlatformType, ExternalPlatformSpec: &hiveext.ExternalPlatformSpec{ - PlatformName: string(models.PlatformTypeOci), + PlatformName: externaltype.ExternalPlatformNameOci, }, ClusterDeploymentRef: corev1.LocalObjectReference{ Name: "ostest", diff --git a/pkg/types/external/platform.go b/pkg/types/external/platform.go index a636d86313e..04b898e6cb4 100644 --- a/pkg/types/external/platform.go +++ b/pkg/types/external/platform.go @@ -9,6 +9,9 @@ const ( // CloudControllerManagerTypeNone specifies that no cloud provider is to be configured. CloudControllerManagerTypeNone = "" + + // ExternalPlatformNameOci specifies oci platform. + ExternalPlatformNameOci = "oci" ) // Platform stores configuration related to external cloud providers. diff --git a/vendor/github.com/openshift/assisted-service/LICENSE b/vendor/github.com/openshift/assisted-service/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/LICENSE @@ -0,0 +1,201 @@ + 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. diff --git a/vendor/github.com/openshift/assisted-service/api/hiveextension/v1beta1/agentclusterinstall_types.go b/vendor/github.com/openshift/assisted-service/api/hiveextension/v1beta1/agentclusterinstall_types.go index e1ab7c82b02..ed63f0b874c 100644 --- a/vendor/github.com/openshift/assisted-service/api/hiveextension/v1beta1/agentclusterinstall_types.go +++ b/vendor/github.com/openshift/assisted-service/api/hiveextension/v1beta1/agentclusterinstall_types.go @@ -79,6 +79,11 @@ const ( ClusterBackendErrorMsg string = "The Spec could not be synced due to backend error:" ClusterInputErrorReason string = "InputError" ClusterInputErrorMsg string = "The Spec could not be synced due to an input error:" + + ClusterLastInstallationPreparationFailedOKReason string = "There is no failing prior preparation attempt" + ClusterLastInstallationPreparationFailedErrorReason string = "The last installation preparation failed" + ClusterLastInstallationPreparationPending string = "Cluster preparation has never been performed for this cluster" + ClusterLastInstallationPreparationFailedCondition string = "LastInstallationPreparationFailed" ) // +genclient @@ -380,6 +385,18 @@ const ( // +kubebuilder:validation:Enum="";BareMetal;None;VSphere;Nutanix;External type PlatformType string +// CloudControllerManager describes the type of cloud controller manager to be enabled. +// +kubebuilder:validation:Enum="";BareMetal;None;VSphere;Nutanix;External +type CloudControllerManager string + +const ( + // CloudControllerManagerTypeExternal specifies that an external cloud provider is to be configured. + CloudControllerManagerTypeExternal = "External" + + // CloudControllerManagerTypeNone specifies that no cloud provider is to be configured. + CloudControllerManagerTypeNone = "" +) + // ExternalPlatformSpec holds the desired state for the generic External infrastructure provider. type ExternalPlatformSpec struct { // PlatformName holds the arbitrary string representing the infrastructure provider name, expected to be set at the installation time. @@ -389,6 +406,13 @@ type ExternalPlatformSpec struct { // +kubebuilder:validation:XValidation:rule="oldSelf == 'Unknown' || self == oldSelf",message="platform name cannot be changed once set" // +optional PlatformName string `json:"platformName,omitempty"` + + // CloudControllerManager when set to external, this property will enable an external cloud provider. + // +kubebuilder:default:="" + // +default="" + // +kubebuilder:validation:Enum="";External + // +optional + CloudControllerManager CloudControllerManager `json:"cloudControllerManager,omitempty"` } const ( diff --git a/vendor/github.com/openshift/assisted-service/api/v1beta1/infraenv_types.go b/vendor/github.com/openshift/assisted-service/api/v1beta1/infraenv_types.go index f2996718120..aeb28a5d82f 100644 --- a/vendor/github.com/openshift/assisted-service/api/v1beta1/infraenv_types.go +++ b/vendor/github.com/openshift/assisted-service/api/v1beta1/infraenv_types.go @@ -172,6 +172,8 @@ type InfraEnvDebugInfo struct { // EventsURL specifies an HTTP/S URL that contains InfraEnv events // +optional EventsURL string `json:"eventsURL"` + // StaticNetworkDownloadURL specifies an HTTP/S URL that contains the static network config + StaticNetworkDownloadURL string `json:"staticNetworkDownloadURL,omitempty"` } type BootArtifacts struct { diff --git a/vendor/github.com/openshift/assisted-service/client/events/events_client.go b/vendor/github.com/openshift/assisted-service/client/events/events_client.go index c8b34b78462..bb7480741fb 100644 --- a/vendor/github.com/openshift/assisted-service/client/events/events_client.go +++ b/vendor/github.com/openshift/assisted-service/client/events/events_client.go @@ -20,6 +20,9 @@ type API interface { /* V2ListEvents Lists events for a cluster.*/ V2ListEvents(ctx context.Context, params *V2ListEventsParams) (*V2ListEventsOK, error) + /* + V2TriggerEvent Add new assisted installer event.*/ + V2TriggerEvent(ctx context.Context, params *V2TriggerEventParams) (*V2TriggerEventCreated, error) } // New creates a new events API client. @@ -64,3 +67,28 @@ func (a *Client) V2ListEvents(ctx context.Context, params *V2ListEventsParams) ( return result.(*V2ListEventsOK), nil } + +/* +V2TriggerEvent Add new assisted installer event. +*/ +func (a *Client) V2TriggerEvent(ctx context.Context, params *V2TriggerEventParams) (*V2TriggerEventCreated, error) { + + result, err := a.transport.Submit(&runtime.ClientOperation{ + ID: "v2TriggerEvent", + Method: "POST", + PathPattern: "/v2/events", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &V2TriggerEventReader{formats: a.formats}, + AuthInfo: a.authInfo, + Context: ctx, + Client: params.HTTPClient, + }) + if err != nil { + return nil, err + } + return result.(*V2TriggerEventCreated), nil + +} diff --git a/vendor/github.com/openshift/assisted-service/client/events/v2_trigger_event_parameters.go b/vendor/github.com/openshift/assisted-service/client/events/v2_trigger_event_parameters.go new file mode 100644 index 00000000000..f9db05a6e1d --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/client/events/v2_trigger_event_parameters.go @@ -0,0 +1,153 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package events + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/openshift/assisted-service/models" +) + +// NewV2TriggerEventParams creates a new V2TriggerEventParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewV2TriggerEventParams() *V2TriggerEventParams { + return &V2TriggerEventParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewV2TriggerEventParamsWithTimeout creates a new V2TriggerEventParams object +// with the ability to set a timeout on a request. +func NewV2TriggerEventParamsWithTimeout(timeout time.Duration) *V2TriggerEventParams { + return &V2TriggerEventParams{ + timeout: timeout, + } +} + +// NewV2TriggerEventParamsWithContext creates a new V2TriggerEventParams object +// with the ability to set a context for a request. +func NewV2TriggerEventParamsWithContext(ctx context.Context) *V2TriggerEventParams { + return &V2TriggerEventParams{ + Context: ctx, + } +} + +// NewV2TriggerEventParamsWithHTTPClient creates a new V2TriggerEventParams object +// with the ability to set a custom HTTPClient for a request. +func NewV2TriggerEventParamsWithHTTPClient(client *http.Client) *V2TriggerEventParams { + return &V2TriggerEventParams{ + HTTPClient: client, + } +} + +/* +V2TriggerEventParams contains all the parameters to send to the API endpoint + + for the v2 trigger event operation. + + Typically these are written to a http.Request. +*/ +type V2TriggerEventParams struct { + + /* TriggerEventParams. + + The event to be created. + */ + TriggerEventParams *models.Event + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the v2 trigger event params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *V2TriggerEventParams) WithDefaults() *V2TriggerEventParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the v2 trigger event params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *V2TriggerEventParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the v2 trigger event params +func (o *V2TriggerEventParams) WithTimeout(timeout time.Duration) *V2TriggerEventParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the v2 trigger event params +func (o *V2TriggerEventParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the v2 trigger event params +func (o *V2TriggerEventParams) WithContext(ctx context.Context) *V2TriggerEventParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the v2 trigger event params +func (o *V2TriggerEventParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the v2 trigger event params +func (o *V2TriggerEventParams) WithHTTPClient(client *http.Client) *V2TriggerEventParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the v2 trigger event params +func (o *V2TriggerEventParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithTriggerEventParams adds the triggerEventParams to the v2 trigger event params +func (o *V2TriggerEventParams) WithTriggerEventParams(triggerEventParams *models.Event) *V2TriggerEventParams { + o.SetTriggerEventParams(triggerEventParams) + return o +} + +// SetTriggerEventParams adds the triggerEventParams to the v2 trigger event params +func (o *V2TriggerEventParams) SetTriggerEventParams(triggerEventParams *models.Event) { + o.TriggerEventParams = triggerEventParams +} + +// WriteToRequest writes these params to a swagger request +func (o *V2TriggerEventParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.TriggerEventParams != nil { + if err := r.SetBodyParam(o.TriggerEventParams); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/client/events/v2_trigger_event_responses.go b/vendor/github.com/openshift/assisted-service/client/events/v2_trigger_event_responses.go new file mode 100644 index 00000000000..5f99aeff662 --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/client/events/v2_trigger_event_responses.go @@ -0,0 +1,707 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package events + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/openshift/assisted-service/models" +) + +// V2TriggerEventReader is a Reader for the V2TriggerEvent structure. +type V2TriggerEventReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *V2TriggerEventReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 201: + result := NewV2TriggerEventCreated() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 400: + result := NewV2TriggerEventBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 401: + result := NewV2TriggerEventUnauthorized() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 403: + result := NewV2TriggerEventForbidden() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 404: + result := NewV2TriggerEventNotFound() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 405: + result := NewV2TriggerEventMethodNotAllowed() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 409: + result := NewV2TriggerEventConflict() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 500: + result := NewV2TriggerEventInternalServerError() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 501: + result := NewV2TriggerEventNotImplemented() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 503: + result := NewV2TriggerEventServiceUnavailable() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + default: + return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code()) + } +} + +// NewV2TriggerEventCreated creates a V2TriggerEventCreated with default headers values +func NewV2TriggerEventCreated() *V2TriggerEventCreated { + return &V2TriggerEventCreated{} +} + +/* +V2TriggerEventCreated describes a response with status code 201, with default header values. + +Success. +*/ +type V2TriggerEventCreated struct { +} + +// IsSuccess returns true when this v2 trigger event created response has a 2xx status code +func (o *V2TriggerEventCreated) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this v2 trigger event created response has a 3xx status code +func (o *V2TriggerEventCreated) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event created response has a 4xx status code +func (o *V2TriggerEventCreated) IsClientError() bool { + return false +} + +// IsServerError returns true when this v2 trigger event created response has a 5xx status code +func (o *V2TriggerEventCreated) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 trigger event created response a status code equal to that given +func (o *V2TriggerEventCreated) IsCode(code int) bool { + return code == 201 +} + +func (o *V2TriggerEventCreated) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventCreated ", 201) +} + +func (o *V2TriggerEventCreated) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventCreated ", 201) +} + +func (o *V2TriggerEventCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewV2TriggerEventBadRequest creates a V2TriggerEventBadRequest with default headers values +func NewV2TriggerEventBadRequest() *V2TriggerEventBadRequest { + return &V2TriggerEventBadRequest{} +} + +/* +V2TriggerEventBadRequest describes a response with status code 400, with default header values. + +Error. +*/ +type V2TriggerEventBadRequest struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 trigger event bad request response has a 2xx status code +func (o *V2TriggerEventBadRequest) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event bad request response has a 3xx status code +func (o *V2TriggerEventBadRequest) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event bad request response has a 4xx status code +func (o *V2TriggerEventBadRequest) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 trigger event bad request response has a 5xx status code +func (o *V2TriggerEventBadRequest) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 trigger event bad request response a status code equal to that given +func (o *V2TriggerEventBadRequest) IsCode(code int) bool { + return code == 400 +} + +func (o *V2TriggerEventBadRequest) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventBadRequest %+v", 400, o.Payload) +} + +func (o *V2TriggerEventBadRequest) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventBadRequest %+v", 400, o.Payload) +} + +func (o *V2TriggerEventBadRequest) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2TriggerEventBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2TriggerEventUnauthorized creates a V2TriggerEventUnauthorized with default headers values +func NewV2TriggerEventUnauthorized() *V2TriggerEventUnauthorized { + return &V2TriggerEventUnauthorized{} +} + +/* +V2TriggerEventUnauthorized describes a response with status code 401, with default header values. + +Unauthorized. +*/ +type V2TriggerEventUnauthorized struct { + Payload *models.InfraError +} + +// IsSuccess returns true when this v2 trigger event unauthorized response has a 2xx status code +func (o *V2TriggerEventUnauthorized) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event unauthorized response has a 3xx status code +func (o *V2TriggerEventUnauthorized) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event unauthorized response has a 4xx status code +func (o *V2TriggerEventUnauthorized) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 trigger event unauthorized response has a 5xx status code +func (o *V2TriggerEventUnauthorized) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 trigger event unauthorized response a status code equal to that given +func (o *V2TriggerEventUnauthorized) IsCode(code int) bool { + return code == 401 +} + +func (o *V2TriggerEventUnauthorized) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventUnauthorized %+v", 401, o.Payload) +} + +func (o *V2TriggerEventUnauthorized) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventUnauthorized %+v", 401, o.Payload) +} + +func (o *V2TriggerEventUnauthorized) GetPayload() *models.InfraError { + return o.Payload +} + +func (o *V2TriggerEventUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.InfraError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2TriggerEventForbidden creates a V2TriggerEventForbidden with default headers values +func NewV2TriggerEventForbidden() *V2TriggerEventForbidden { + return &V2TriggerEventForbidden{} +} + +/* +V2TriggerEventForbidden describes a response with status code 403, with default header values. + +Forbidden. +*/ +type V2TriggerEventForbidden struct { + Payload *models.InfraError +} + +// IsSuccess returns true when this v2 trigger event forbidden response has a 2xx status code +func (o *V2TriggerEventForbidden) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event forbidden response has a 3xx status code +func (o *V2TriggerEventForbidden) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event forbidden response has a 4xx status code +func (o *V2TriggerEventForbidden) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 trigger event forbidden response has a 5xx status code +func (o *V2TriggerEventForbidden) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 trigger event forbidden response a status code equal to that given +func (o *V2TriggerEventForbidden) IsCode(code int) bool { + return code == 403 +} + +func (o *V2TriggerEventForbidden) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventForbidden %+v", 403, o.Payload) +} + +func (o *V2TriggerEventForbidden) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventForbidden %+v", 403, o.Payload) +} + +func (o *V2TriggerEventForbidden) GetPayload() *models.InfraError { + return o.Payload +} + +func (o *V2TriggerEventForbidden) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.InfraError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2TriggerEventNotFound creates a V2TriggerEventNotFound with default headers values +func NewV2TriggerEventNotFound() *V2TriggerEventNotFound { + return &V2TriggerEventNotFound{} +} + +/* +V2TriggerEventNotFound describes a response with status code 404, with default header values. + +Error. +*/ +type V2TriggerEventNotFound struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 trigger event not found response has a 2xx status code +func (o *V2TriggerEventNotFound) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event not found response has a 3xx status code +func (o *V2TriggerEventNotFound) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event not found response has a 4xx status code +func (o *V2TriggerEventNotFound) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 trigger event not found response has a 5xx status code +func (o *V2TriggerEventNotFound) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 trigger event not found response a status code equal to that given +func (o *V2TriggerEventNotFound) IsCode(code int) bool { + return code == 404 +} + +func (o *V2TriggerEventNotFound) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventNotFound %+v", 404, o.Payload) +} + +func (o *V2TriggerEventNotFound) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventNotFound %+v", 404, o.Payload) +} + +func (o *V2TriggerEventNotFound) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2TriggerEventNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2TriggerEventMethodNotAllowed creates a V2TriggerEventMethodNotAllowed with default headers values +func NewV2TriggerEventMethodNotAllowed() *V2TriggerEventMethodNotAllowed { + return &V2TriggerEventMethodNotAllowed{} +} + +/* +V2TriggerEventMethodNotAllowed describes a response with status code 405, with default header values. + +Method Not Allowed. +*/ +type V2TriggerEventMethodNotAllowed struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 trigger event method not allowed response has a 2xx status code +func (o *V2TriggerEventMethodNotAllowed) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event method not allowed response has a 3xx status code +func (o *V2TriggerEventMethodNotAllowed) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event method not allowed response has a 4xx status code +func (o *V2TriggerEventMethodNotAllowed) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 trigger event method not allowed response has a 5xx status code +func (o *V2TriggerEventMethodNotAllowed) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 trigger event method not allowed response a status code equal to that given +func (o *V2TriggerEventMethodNotAllowed) IsCode(code int) bool { + return code == 405 +} + +func (o *V2TriggerEventMethodNotAllowed) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventMethodNotAllowed %+v", 405, o.Payload) +} + +func (o *V2TriggerEventMethodNotAllowed) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventMethodNotAllowed %+v", 405, o.Payload) +} + +func (o *V2TriggerEventMethodNotAllowed) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2TriggerEventMethodNotAllowed) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2TriggerEventConflict creates a V2TriggerEventConflict with default headers values +func NewV2TriggerEventConflict() *V2TriggerEventConflict { + return &V2TriggerEventConflict{} +} + +/* +V2TriggerEventConflict describes a response with status code 409, with default header values. + +Cluster cannot accept new agents due to its current state. +*/ +type V2TriggerEventConflict struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 trigger event conflict response has a 2xx status code +func (o *V2TriggerEventConflict) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event conflict response has a 3xx status code +func (o *V2TriggerEventConflict) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event conflict response has a 4xx status code +func (o *V2TriggerEventConflict) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 trigger event conflict response has a 5xx status code +func (o *V2TriggerEventConflict) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 trigger event conflict response a status code equal to that given +func (o *V2TriggerEventConflict) IsCode(code int) bool { + return code == 409 +} + +func (o *V2TriggerEventConflict) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventConflict %+v", 409, o.Payload) +} + +func (o *V2TriggerEventConflict) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventConflict %+v", 409, o.Payload) +} + +func (o *V2TriggerEventConflict) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2TriggerEventConflict) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2TriggerEventInternalServerError creates a V2TriggerEventInternalServerError with default headers values +func NewV2TriggerEventInternalServerError() *V2TriggerEventInternalServerError { + return &V2TriggerEventInternalServerError{} +} + +/* +V2TriggerEventInternalServerError describes a response with status code 500, with default header values. + +Error. +*/ +type V2TriggerEventInternalServerError struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 trigger event internal server error response has a 2xx status code +func (o *V2TriggerEventInternalServerError) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event internal server error response has a 3xx status code +func (o *V2TriggerEventInternalServerError) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event internal server error response has a 4xx status code +func (o *V2TriggerEventInternalServerError) IsClientError() bool { + return false +} + +// IsServerError returns true when this v2 trigger event internal server error response has a 5xx status code +func (o *V2TriggerEventInternalServerError) IsServerError() bool { + return true +} + +// IsCode returns true when this v2 trigger event internal server error response a status code equal to that given +func (o *V2TriggerEventInternalServerError) IsCode(code int) bool { + return code == 500 +} + +func (o *V2TriggerEventInternalServerError) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventInternalServerError %+v", 500, o.Payload) +} + +func (o *V2TriggerEventInternalServerError) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventInternalServerError %+v", 500, o.Payload) +} + +func (o *V2TriggerEventInternalServerError) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2TriggerEventInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2TriggerEventNotImplemented creates a V2TriggerEventNotImplemented with default headers values +func NewV2TriggerEventNotImplemented() *V2TriggerEventNotImplemented { + return &V2TriggerEventNotImplemented{} +} + +/* +V2TriggerEventNotImplemented describes a response with status code 501, with default header values. + +Not implemented. +*/ +type V2TriggerEventNotImplemented struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 trigger event not implemented response has a 2xx status code +func (o *V2TriggerEventNotImplemented) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event not implemented response has a 3xx status code +func (o *V2TriggerEventNotImplemented) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event not implemented response has a 4xx status code +func (o *V2TriggerEventNotImplemented) IsClientError() bool { + return false +} + +// IsServerError returns true when this v2 trigger event not implemented response has a 5xx status code +func (o *V2TriggerEventNotImplemented) IsServerError() bool { + return true +} + +// IsCode returns true when this v2 trigger event not implemented response a status code equal to that given +func (o *V2TriggerEventNotImplemented) IsCode(code int) bool { + return code == 501 +} + +func (o *V2TriggerEventNotImplemented) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventNotImplemented %+v", 501, o.Payload) +} + +func (o *V2TriggerEventNotImplemented) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventNotImplemented %+v", 501, o.Payload) +} + +func (o *V2TriggerEventNotImplemented) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2TriggerEventNotImplemented) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2TriggerEventServiceUnavailable creates a V2TriggerEventServiceUnavailable with default headers values +func NewV2TriggerEventServiceUnavailable() *V2TriggerEventServiceUnavailable { + return &V2TriggerEventServiceUnavailable{} +} + +/* +V2TriggerEventServiceUnavailable describes a response with status code 503, with default header values. + +Unavailable. +*/ +type V2TriggerEventServiceUnavailable struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 trigger event service unavailable response has a 2xx status code +func (o *V2TriggerEventServiceUnavailable) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 trigger event service unavailable response has a 3xx status code +func (o *V2TriggerEventServiceUnavailable) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 trigger event service unavailable response has a 4xx status code +func (o *V2TriggerEventServiceUnavailable) IsClientError() bool { + return false +} + +// IsServerError returns true when this v2 trigger event service unavailable response has a 5xx status code +func (o *V2TriggerEventServiceUnavailable) IsServerError() bool { + return true +} + +// IsCode returns true when this v2 trigger event service unavailable response a status code equal to that given +func (o *V2TriggerEventServiceUnavailable) IsCode(code int) bool { + return code == 503 +} + +func (o *V2TriggerEventServiceUnavailable) Error() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventServiceUnavailable %+v", 503, o.Payload) +} + +func (o *V2TriggerEventServiceUnavailable) String() string { + return fmt.Sprintf("[POST /v2/events][%d] v2TriggerEventServiceUnavailable %+v", 503, o.Payload) +} + +func (o *V2TriggerEventServiceUnavailable) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2TriggerEventServiceUnavailable) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/client/installer/get_supported_features_parameters.go b/vendor/github.com/openshift/assisted-service/client/installer/get_supported_features_parameters.go index d48f60ce4ae..3e511a49aee 100644 --- a/vendor/github.com/openshift/assisted-service/client/installer/get_supported_features_parameters.go +++ b/vendor/github.com/openshift/assisted-service/client/installer/get_supported_features_parameters.go @@ -69,6 +69,12 @@ type GetSupportedFeaturesParams struct { */ CPUArchitecture *string + /* ExternalPlatformName. + + External platform name when platform type is set to external. The value of this parameter will be ignored if platform_type is not external. + */ + ExternalPlatformName *string + /* OpenshiftVersion. Version of the OpenShift cluster. @@ -156,6 +162,17 @@ func (o *GetSupportedFeaturesParams) SetCPUArchitecture(cPUArchitecture *string) o.CPUArchitecture = cPUArchitecture } +// WithExternalPlatformName adds the externalPlatformName to the get supported features params +func (o *GetSupportedFeaturesParams) WithExternalPlatformName(externalPlatformName *string) *GetSupportedFeaturesParams { + o.SetExternalPlatformName(externalPlatformName) + return o +} + +// SetExternalPlatformName adds the externalPlatformName to the get supported features params +func (o *GetSupportedFeaturesParams) SetExternalPlatformName(externalPlatformName *string) { + o.ExternalPlatformName = externalPlatformName +} + // WithOpenshiftVersion adds the openshiftVersion to the get supported features params func (o *GetSupportedFeaturesParams) WithOpenshiftVersion(openshiftVersion string) *GetSupportedFeaturesParams { o.SetOpenshiftVersion(openshiftVersion) @@ -203,6 +220,23 @@ func (o *GetSupportedFeaturesParams) WriteToRequest(r runtime.ClientRequest, reg } } + if o.ExternalPlatformName != nil { + + // query param external_platform_name + var qrExternalPlatformName string + + if o.ExternalPlatformName != nil { + qrExternalPlatformName = *o.ExternalPlatformName + } + qExternalPlatformName := qrExternalPlatformName + if qExternalPlatformName != "" { + + if err := r.SetQueryParam("external_platform_name", qExternalPlatformName); err != nil { + return err + } + } + } + // query param openshift_version qrOpenshiftVersion := o.OpenshiftVersion qOpenshiftVersion := qrOpenshiftVersion diff --git a/vendor/github.com/openshift/assisted-service/client/installer/installer_client.go b/vendor/github.com/openshift/assisted-service/client/installer/installer_client.go index f5ffdb1f456..ebde8f2af08 100644 --- a/vendor/github.com/openshift/assisted-service/client/installer/installer_client.go +++ b/vendor/github.com/openshift/assisted-service/client/installer/installer_client.go @@ -180,6 +180,9 @@ type API interface { /* V2SetIgnoredValidations Register the validations which are to be ignored for this cluster.*/ V2SetIgnoredValidations(ctx context.Context, params *V2SetIgnoredValidationsParams) (*V2SetIgnoredValidationsCreated, error) + /* + V2UpdateClusterFinalizingProgress Update installation finalizing progress.*/ + V2UpdateClusterFinalizingProgress(ctx context.Context, params *V2UpdateClusterFinalizingProgressParams) (*V2UpdateClusterFinalizingProgressOK, error) /* V2UpdateClusterInstallConfig Override values in the install config.*/ V2UpdateClusterInstallConfig(ctx context.Context, params *V2UpdateClusterInstallConfigParams) (*V2UpdateClusterInstallConfigCreated, error) @@ -1557,6 +1560,31 @@ func (a *Client) V2SetIgnoredValidations(ctx context.Context, params *V2SetIgnor } +/* +V2UpdateClusterFinalizingProgress Update installation finalizing progress. +*/ +func (a *Client) V2UpdateClusterFinalizingProgress(ctx context.Context, params *V2UpdateClusterFinalizingProgressParams) (*V2UpdateClusterFinalizingProgressOK, error) { + + result, err := a.transport.Submit(&runtime.ClientOperation{ + ID: "v2UpdateClusterFinalizingProgress", + Method: "PUT", + PathPattern: "/v2/clusters/{cluster_id}/progress", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &V2UpdateClusterFinalizingProgressReader{formats: a.formats}, + AuthInfo: a.authInfo, + Context: ctx, + Client: params.HTTPClient, + }) + if err != nil { + return nil, err + } + return result.(*V2UpdateClusterFinalizingProgressOK), nil + +} + /* V2UpdateClusterInstallConfig Override values in the install config. */ diff --git a/vendor/github.com/openshift/assisted-service/client/installer/v2_update_cluster_finalizing_progress_parameters.go b/vendor/github.com/openshift/assisted-service/client/installer/v2_update_cluster_finalizing_progress_parameters.go new file mode 100644 index 00000000000..4ee918d2390 --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/client/installer/v2_update_cluster_finalizing_progress_parameters.go @@ -0,0 +1,177 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package installer + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/openshift/assisted-service/models" +) + +// NewV2UpdateClusterFinalizingProgressParams creates a new V2UpdateClusterFinalizingProgressParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewV2UpdateClusterFinalizingProgressParams() *V2UpdateClusterFinalizingProgressParams { + return &V2UpdateClusterFinalizingProgressParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewV2UpdateClusterFinalizingProgressParamsWithTimeout creates a new V2UpdateClusterFinalizingProgressParams object +// with the ability to set a timeout on a request. +func NewV2UpdateClusterFinalizingProgressParamsWithTimeout(timeout time.Duration) *V2UpdateClusterFinalizingProgressParams { + return &V2UpdateClusterFinalizingProgressParams{ + timeout: timeout, + } +} + +// NewV2UpdateClusterFinalizingProgressParamsWithContext creates a new V2UpdateClusterFinalizingProgressParams object +// with the ability to set a context for a request. +func NewV2UpdateClusterFinalizingProgressParamsWithContext(ctx context.Context) *V2UpdateClusterFinalizingProgressParams { + return &V2UpdateClusterFinalizingProgressParams{ + Context: ctx, + } +} + +// NewV2UpdateClusterFinalizingProgressParamsWithHTTPClient creates a new V2UpdateClusterFinalizingProgressParams object +// with the ability to set a custom HTTPClient for a request. +func NewV2UpdateClusterFinalizingProgressParamsWithHTTPClient(client *http.Client) *V2UpdateClusterFinalizingProgressParams { + return &V2UpdateClusterFinalizingProgressParams{ + HTTPClient: client, + } +} + +/* +V2UpdateClusterFinalizingProgressParams contains all the parameters to send to the API endpoint + + for the v2 update cluster finalizing progress operation. + + Typically these are written to a http.Request. +*/ +type V2UpdateClusterFinalizingProgressParams struct { + + /* ClusterID. + + The cluster being updated. + + Format: uuid + */ + ClusterID strfmt.UUID + + /* FinalizingProgress. + + New progress value. + */ + FinalizingProgress *models.ClusterFinalizingProgress + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the v2 update cluster finalizing progress params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *V2UpdateClusterFinalizingProgressParams) WithDefaults() *V2UpdateClusterFinalizingProgressParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the v2 update cluster finalizing progress params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *V2UpdateClusterFinalizingProgressParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) WithTimeout(timeout time.Duration) *V2UpdateClusterFinalizingProgressParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) WithContext(ctx context.Context) *V2UpdateClusterFinalizingProgressParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) WithHTTPClient(client *http.Client) *V2UpdateClusterFinalizingProgressParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithClusterID adds the clusterID to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) WithClusterID(clusterID strfmt.UUID) *V2UpdateClusterFinalizingProgressParams { + o.SetClusterID(clusterID) + return o +} + +// SetClusterID adds the clusterId to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) SetClusterID(clusterID strfmt.UUID) { + o.ClusterID = clusterID +} + +// WithFinalizingProgress adds the finalizingProgress to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) WithFinalizingProgress(finalizingProgress *models.ClusterFinalizingProgress) *V2UpdateClusterFinalizingProgressParams { + o.SetFinalizingProgress(finalizingProgress) + return o +} + +// SetFinalizingProgress adds the finalizingProgress to the v2 update cluster finalizing progress params +func (o *V2UpdateClusterFinalizingProgressParams) SetFinalizingProgress(finalizingProgress *models.ClusterFinalizingProgress) { + o.FinalizingProgress = finalizingProgress +} + +// WriteToRequest writes these params to a swagger request +func (o *V2UpdateClusterFinalizingProgressParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + // path param cluster_id + if err := r.SetPathParam("cluster_id", o.ClusterID.String()); err != nil { + return err + } + if o.FinalizingProgress != nil { + if err := r.SetBodyParam(o.FinalizingProgress); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/client/installer/v2_update_cluster_finalizing_progress_responses.go b/vendor/github.com/openshift/assisted-service/client/installer/v2_update_cluster_finalizing_progress_responses.go new file mode 100644 index 00000000000..9fa9146a8b2 --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/client/installer/v2_update_cluster_finalizing_progress_responses.go @@ -0,0 +1,500 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package installer + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/openshift/assisted-service/models" +) + +// V2UpdateClusterFinalizingProgressReader is a Reader for the V2UpdateClusterFinalizingProgress structure. +type V2UpdateClusterFinalizingProgressReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *V2UpdateClusterFinalizingProgressReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewV2UpdateClusterFinalizingProgressOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 401: + result := NewV2UpdateClusterFinalizingProgressUnauthorized() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 403: + result := NewV2UpdateClusterFinalizingProgressForbidden() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 404: + result := NewV2UpdateClusterFinalizingProgressNotFound() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 405: + result := NewV2UpdateClusterFinalizingProgressMethodNotAllowed() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 500: + result := NewV2UpdateClusterFinalizingProgressInternalServerError() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 503: + result := NewV2UpdateClusterFinalizingProgressServiceUnavailable() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + default: + return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code()) + } +} + +// NewV2UpdateClusterFinalizingProgressOK creates a V2UpdateClusterFinalizingProgressOK with default headers values +func NewV2UpdateClusterFinalizingProgressOK() *V2UpdateClusterFinalizingProgressOK { + return &V2UpdateClusterFinalizingProgressOK{} +} + +/* +V2UpdateClusterFinalizingProgressOK describes a response with status code 200, with default header values. + +Update install progress. +*/ +type V2UpdateClusterFinalizingProgressOK struct { +} + +// IsSuccess returns true when this v2 update cluster finalizing progress o k response has a 2xx status code +func (o *V2UpdateClusterFinalizingProgressOK) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this v2 update cluster finalizing progress o k response has a 3xx status code +func (o *V2UpdateClusterFinalizingProgressOK) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 update cluster finalizing progress o k response has a 4xx status code +func (o *V2UpdateClusterFinalizingProgressOK) IsClientError() bool { + return false +} + +// IsServerError returns true when this v2 update cluster finalizing progress o k response has a 5xx status code +func (o *V2UpdateClusterFinalizingProgressOK) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 update cluster finalizing progress o k response a status code equal to that given +func (o *V2UpdateClusterFinalizingProgressOK) IsCode(code int) bool { + return code == 200 +} + +func (o *V2UpdateClusterFinalizingProgressOK) Error() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressOK ", 200) +} + +func (o *V2UpdateClusterFinalizingProgressOK) String() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressOK ", 200) +} + +func (o *V2UpdateClusterFinalizingProgressOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewV2UpdateClusterFinalizingProgressUnauthorized creates a V2UpdateClusterFinalizingProgressUnauthorized with default headers values +func NewV2UpdateClusterFinalizingProgressUnauthorized() *V2UpdateClusterFinalizingProgressUnauthorized { + return &V2UpdateClusterFinalizingProgressUnauthorized{} +} + +/* +V2UpdateClusterFinalizingProgressUnauthorized describes a response with status code 401, with default header values. + +Unauthorized. +*/ +type V2UpdateClusterFinalizingProgressUnauthorized struct { + Payload *models.InfraError +} + +// IsSuccess returns true when this v2 update cluster finalizing progress unauthorized response has a 2xx status code +func (o *V2UpdateClusterFinalizingProgressUnauthorized) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 update cluster finalizing progress unauthorized response has a 3xx status code +func (o *V2UpdateClusterFinalizingProgressUnauthorized) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 update cluster finalizing progress unauthorized response has a 4xx status code +func (o *V2UpdateClusterFinalizingProgressUnauthorized) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 update cluster finalizing progress unauthorized response has a 5xx status code +func (o *V2UpdateClusterFinalizingProgressUnauthorized) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 update cluster finalizing progress unauthorized response a status code equal to that given +func (o *V2UpdateClusterFinalizingProgressUnauthorized) IsCode(code int) bool { + return code == 401 +} + +func (o *V2UpdateClusterFinalizingProgressUnauthorized) Error() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressUnauthorized %+v", 401, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressUnauthorized) String() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressUnauthorized %+v", 401, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressUnauthorized) GetPayload() *models.InfraError { + return o.Payload +} + +func (o *V2UpdateClusterFinalizingProgressUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.InfraError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2UpdateClusterFinalizingProgressForbidden creates a V2UpdateClusterFinalizingProgressForbidden with default headers values +func NewV2UpdateClusterFinalizingProgressForbidden() *V2UpdateClusterFinalizingProgressForbidden { + return &V2UpdateClusterFinalizingProgressForbidden{} +} + +/* +V2UpdateClusterFinalizingProgressForbidden describes a response with status code 403, with default header values. + +Forbidden. +*/ +type V2UpdateClusterFinalizingProgressForbidden struct { + Payload *models.InfraError +} + +// IsSuccess returns true when this v2 update cluster finalizing progress forbidden response has a 2xx status code +func (o *V2UpdateClusterFinalizingProgressForbidden) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 update cluster finalizing progress forbidden response has a 3xx status code +func (o *V2UpdateClusterFinalizingProgressForbidden) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 update cluster finalizing progress forbidden response has a 4xx status code +func (o *V2UpdateClusterFinalizingProgressForbidden) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 update cluster finalizing progress forbidden response has a 5xx status code +func (o *V2UpdateClusterFinalizingProgressForbidden) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 update cluster finalizing progress forbidden response a status code equal to that given +func (o *V2UpdateClusterFinalizingProgressForbidden) IsCode(code int) bool { + return code == 403 +} + +func (o *V2UpdateClusterFinalizingProgressForbidden) Error() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressForbidden %+v", 403, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressForbidden) String() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressForbidden %+v", 403, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressForbidden) GetPayload() *models.InfraError { + return o.Payload +} + +func (o *V2UpdateClusterFinalizingProgressForbidden) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.InfraError) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2UpdateClusterFinalizingProgressNotFound creates a V2UpdateClusterFinalizingProgressNotFound with default headers values +func NewV2UpdateClusterFinalizingProgressNotFound() *V2UpdateClusterFinalizingProgressNotFound { + return &V2UpdateClusterFinalizingProgressNotFound{} +} + +/* +V2UpdateClusterFinalizingProgressNotFound describes a response with status code 404, with default header values. + +Error. +*/ +type V2UpdateClusterFinalizingProgressNotFound struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 update cluster finalizing progress not found response has a 2xx status code +func (o *V2UpdateClusterFinalizingProgressNotFound) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 update cluster finalizing progress not found response has a 3xx status code +func (o *V2UpdateClusterFinalizingProgressNotFound) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 update cluster finalizing progress not found response has a 4xx status code +func (o *V2UpdateClusterFinalizingProgressNotFound) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 update cluster finalizing progress not found response has a 5xx status code +func (o *V2UpdateClusterFinalizingProgressNotFound) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 update cluster finalizing progress not found response a status code equal to that given +func (o *V2UpdateClusterFinalizingProgressNotFound) IsCode(code int) bool { + return code == 404 +} + +func (o *V2UpdateClusterFinalizingProgressNotFound) Error() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressNotFound %+v", 404, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressNotFound) String() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressNotFound %+v", 404, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressNotFound) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2UpdateClusterFinalizingProgressNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2UpdateClusterFinalizingProgressMethodNotAllowed creates a V2UpdateClusterFinalizingProgressMethodNotAllowed with default headers values +func NewV2UpdateClusterFinalizingProgressMethodNotAllowed() *V2UpdateClusterFinalizingProgressMethodNotAllowed { + return &V2UpdateClusterFinalizingProgressMethodNotAllowed{} +} + +/* +V2UpdateClusterFinalizingProgressMethodNotAllowed describes a response with status code 405, with default header values. + +Method Not Allowed. +*/ +type V2UpdateClusterFinalizingProgressMethodNotAllowed struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 update cluster finalizing progress method not allowed response has a 2xx status code +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 update cluster finalizing progress method not allowed response has a 3xx status code +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 update cluster finalizing progress method not allowed response has a 4xx status code +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) IsClientError() bool { + return true +} + +// IsServerError returns true when this v2 update cluster finalizing progress method not allowed response has a 5xx status code +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) IsServerError() bool { + return false +} + +// IsCode returns true when this v2 update cluster finalizing progress method not allowed response a status code equal to that given +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) IsCode(code int) bool { + return code == 405 +} + +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) Error() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressMethodNotAllowed %+v", 405, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) String() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressMethodNotAllowed %+v", 405, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2UpdateClusterFinalizingProgressMethodNotAllowed) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2UpdateClusterFinalizingProgressInternalServerError creates a V2UpdateClusterFinalizingProgressInternalServerError with default headers values +func NewV2UpdateClusterFinalizingProgressInternalServerError() *V2UpdateClusterFinalizingProgressInternalServerError { + return &V2UpdateClusterFinalizingProgressInternalServerError{} +} + +/* +V2UpdateClusterFinalizingProgressInternalServerError describes a response with status code 500, with default header values. + +Error. +*/ +type V2UpdateClusterFinalizingProgressInternalServerError struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 update cluster finalizing progress internal server error response has a 2xx status code +func (o *V2UpdateClusterFinalizingProgressInternalServerError) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 update cluster finalizing progress internal server error response has a 3xx status code +func (o *V2UpdateClusterFinalizingProgressInternalServerError) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 update cluster finalizing progress internal server error response has a 4xx status code +func (o *V2UpdateClusterFinalizingProgressInternalServerError) IsClientError() bool { + return false +} + +// IsServerError returns true when this v2 update cluster finalizing progress internal server error response has a 5xx status code +func (o *V2UpdateClusterFinalizingProgressInternalServerError) IsServerError() bool { + return true +} + +// IsCode returns true when this v2 update cluster finalizing progress internal server error response a status code equal to that given +func (o *V2UpdateClusterFinalizingProgressInternalServerError) IsCode(code int) bool { + return code == 500 +} + +func (o *V2UpdateClusterFinalizingProgressInternalServerError) Error() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressInternalServerError %+v", 500, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressInternalServerError) String() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressInternalServerError %+v", 500, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressInternalServerError) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2UpdateClusterFinalizingProgressInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewV2UpdateClusterFinalizingProgressServiceUnavailable creates a V2UpdateClusterFinalizingProgressServiceUnavailable with default headers values +func NewV2UpdateClusterFinalizingProgressServiceUnavailable() *V2UpdateClusterFinalizingProgressServiceUnavailable { + return &V2UpdateClusterFinalizingProgressServiceUnavailable{} +} + +/* +V2UpdateClusterFinalizingProgressServiceUnavailable describes a response with status code 503, with default header values. + +Unavailable. +*/ +type V2UpdateClusterFinalizingProgressServiceUnavailable struct { + Payload *models.Error +} + +// IsSuccess returns true when this v2 update cluster finalizing progress service unavailable response has a 2xx status code +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this v2 update cluster finalizing progress service unavailable response has a 3xx status code +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) IsRedirect() bool { + return false +} + +// IsClientError returns true when this v2 update cluster finalizing progress service unavailable response has a 4xx status code +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) IsClientError() bool { + return false +} + +// IsServerError returns true when this v2 update cluster finalizing progress service unavailable response has a 5xx status code +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) IsServerError() bool { + return true +} + +// IsCode returns true when this v2 update cluster finalizing progress service unavailable response a status code equal to that given +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) IsCode(code int) bool { + return code == 503 +} + +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) Error() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressServiceUnavailable %+v", 503, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) String() string { + return fmt.Sprintf("[PUT /v2/clusters/{cluster_id}/progress][%d] v2UpdateClusterFinalizingProgressServiceUnavailable %+v", 503, o.Payload) +} + +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) GetPayload() *models.Error { + return o.Payload +} + +func (o *V2UpdateClusterFinalizingProgressServiceUnavailable) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/client/manifests/v2_list_cluster_manifests_parameters.go b/vendor/github.com/openshift/assisted-service/client/manifests/v2_list_cluster_manifests_parameters.go index 51445875b73..1d40fa9f783 100644 --- a/vendor/github.com/openshift/assisted-service/client/manifests/v2_list_cluster_manifests_parameters.go +++ b/vendor/github.com/openshift/assisted-service/client/manifests/v2_list_cluster_manifests_parameters.go @@ -14,6 +14,7 @@ import ( "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" ) // NewV2ListClusterManifestsParams creates a new V2ListClusterManifestsParams object, @@ -69,6 +70,12 @@ type V2ListClusterManifestsParams struct { */ ClusterID strfmt.UUID + /* IncludeSystemGenerated. + + Include system generated manifests in results? Default is false. + */ + IncludeSystemGenerated *bool + timeout time.Duration Context context.Context HTTPClient *http.Client @@ -86,7 +93,18 @@ func (o *V2ListClusterManifestsParams) WithDefaults() *V2ListClusterManifestsPar // // All values with no default are reset to their zero value. func (o *V2ListClusterManifestsParams) SetDefaults() { - // no default values defined for this parameter + var ( + includeSystemGeneratedDefault = bool(false) + ) + + val := V2ListClusterManifestsParams{ + IncludeSystemGenerated: &includeSystemGeneratedDefault, + } + + val.timeout = o.timeout + val.Context = o.Context + val.HTTPClient = o.HTTPClient + *o = val } // WithTimeout adds the timeout to the v2 list cluster manifests params @@ -133,6 +151,17 @@ func (o *V2ListClusterManifestsParams) SetClusterID(clusterID strfmt.UUID) { o.ClusterID = clusterID } +// WithIncludeSystemGenerated adds the includeSystemGenerated to the v2 list cluster manifests params +func (o *V2ListClusterManifestsParams) WithIncludeSystemGenerated(includeSystemGenerated *bool) *V2ListClusterManifestsParams { + o.SetIncludeSystemGenerated(includeSystemGenerated) + return o +} + +// SetIncludeSystemGenerated adds the includeSystemGenerated to the v2 list cluster manifests params +func (o *V2ListClusterManifestsParams) SetIncludeSystemGenerated(includeSystemGenerated *bool) { + o.IncludeSystemGenerated = includeSystemGenerated +} + // WriteToRequest writes these params to a swagger request func (o *V2ListClusterManifestsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { @@ -146,6 +175,23 @@ func (o *V2ListClusterManifestsParams) WriteToRequest(r runtime.ClientRequest, r return err } + if o.IncludeSystemGenerated != nil { + + // query param include_system_generated + var qrIncludeSystemGenerated bool + + if o.IncludeSystemGenerated != nil { + qrIncludeSystemGenerated = *o.IncludeSystemGenerated + } + qIncludeSystemGenerated := swag.FormatBool(qrIncludeSystemGenerated) + if qIncludeSystemGenerated != "" { + + if err := r.SetQueryParam("include_system_generated", qIncludeSystemGenerated); err != nil { + return err + } + } + } + if len(res) > 0 { return errors.CompositeValidationError(res...) } diff --git a/vendor/github.com/openshift/assisted-service/models/boot.go b/vendor/github.com/openshift/assisted-service/models/boot.go index 361ebd0a9c1..8b7defc9531 100644 --- a/vendor/github.com/openshift/assisted-service/models/boot.go +++ b/vendor/github.com/openshift/assisted-service/models/boot.go @@ -17,6 +17,9 @@ import ( // swagger:model boot type Boot struct { + // command line + CommandLine string `json:"command_line,omitempty"` + // current boot mode CurrentBootMode string `json:"current_boot_mode,omitempty"` diff --git a/vendor/github.com/openshift/assisted-service/models/cluster.go b/vendor/github.com/openshift/assisted-service/models/cluster.go index ae27513916a..ed4f66367bc 100644 --- a/vendor/github.com/openshift/assisted-service/models/cluster.go +++ b/vendor/github.com/openshift/assisted-service/models/cluster.go @@ -30,10 +30,6 @@ type Cluster struct { // Format: uuid AmsSubscriptionID strfmt.UUID `json:"ams_subscription_id,omitempty"` - // (DEPRECATED) The virtual IP used to reach the OpenShift cluster's API. - // Pattern: ^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))$ - APIVip string `json:"api_vip,omitempty"` - // The domain name used to reach the OpenShift cluster API. APIVipDNSName *string `json:"api_vip_dns_name,omitempty"` @@ -147,10 +143,6 @@ type Cluster struct { // reflect the actual cluster they represent Imported *bool `json:"imported,omitempty"` - // (DEPRECATED) The virtual IP used for cluster ingress traffic. - // Pattern: ^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))$ - IngressVip string `json:"ingress_vip,omitempty"` - // The virtual IPs used for cluster ingress traffic. Enter one IP address for single-stack clusters, or up to two for dual-stack clusters (at most one IP address per IP stack used). The order of stacks should be the same as order of subnets in Cluster Networks, Service Networks, and Machine Networks. IngressVips []*IngressVip `json:"ingress_vips" gorm:"foreignkey:ClusterID;references:ID"` @@ -176,6 +168,9 @@ type Cluster struct { // Enum: [Cluster AddHostsCluster] Kind *string `json:"kind"` + // last installation preparation + LastInstallationPreparation LastInstallationPreparation `json:"last-installation-preparation,omitempty" gorm:"embedded;embeddedPrefix:last_installation_preparation_"` + // The progress of log collection or empty if logs are not applicable LogsInfo LogsState `json:"logs_info,omitempty" gorm:"type:varchar(2048)"` @@ -286,10 +281,6 @@ func (m *Cluster) Validate(formats strfmt.Registry) error { res = append(res, err) } - if err := m.validateAPIVip(formats); err != nil { - res = append(res, err) - } - if err := m.validateAPIVips(formats); err != nil { res = append(res, err) } @@ -358,10 +349,6 @@ func (m *Cluster) Validate(formats strfmt.Registry) error { res = append(res, err) } - if err := m.validateIngressVip(formats); err != nil { - res = append(res, err) - } - if err := m.validateIngressVips(formats); err != nil { res = append(res, err) } @@ -378,6 +365,10 @@ func (m *Cluster) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateLastInstallationPreparation(formats); err != nil { + res = append(res, err) + } + if err := m.validateLogsInfo(formats); err != nil { res = append(res, err) } @@ -452,18 +443,6 @@ func (m *Cluster) validateAmsSubscriptionID(formats strfmt.Registry) error { return nil } -func (m *Cluster) validateAPIVip(formats strfmt.Registry) error { - if swag.IsZero(m.APIVip) { // not required - return nil - } - - if err := validate.Pattern("api_vip", "body", m.APIVip, `^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))$`); err != nil { - return err - } - - return nil -} - func (m *Cluster) validateAPIVips(formats strfmt.Registry) error { if swag.IsZero(m.APIVips) { // not required return nil @@ -856,18 +835,6 @@ func (m *Cluster) validateImageInfo(formats strfmt.Registry) error { return nil } -func (m *Cluster) validateIngressVip(formats strfmt.Registry) error { - if swag.IsZero(m.IngressVip) { // not required - return nil - } - - if err := validate.Pattern("ingress_vip", "body", m.IngressVip, `^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))$`); err != nil { - return err - } - - return nil -} - func (m *Cluster) validateIngressVips(formats strfmt.Registry) error { if swag.IsZero(m.IngressVips) { // not required return nil @@ -961,6 +928,23 @@ func (m *Cluster) validateKind(formats strfmt.Registry) error { return nil } +func (m *Cluster) validateLastInstallationPreparation(formats strfmt.Registry) error { + if swag.IsZero(m.LastInstallationPreparation) { // not required + return nil + } + + if err := m.LastInstallationPreparation.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("last-installation-preparation") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("last-installation-preparation") + } + return err + } + + return nil +} + func (m *Cluster) validateLogsInfo(formats strfmt.Registry) error { if swag.IsZero(m.LogsInfo) { // not required return nil @@ -1311,6 +1295,10 @@ func (m *Cluster) ContextValidate(ctx context.Context, formats strfmt.Registry) res = append(res, err) } + if err := m.contextValidateLastInstallationPreparation(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateLogsInfo(ctx, formats); err != nil { res = append(res, err) } @@ -1489,6 +1477,20 @@ func (m *Cluster) contextValidateIngressVips(ctx context.Context, formats strfmt return nil } +func (m *Cluster) contextValidateLastInstallationPreparation(ctx context.Context, formats strfmt.Registry) error { + + if err := m.LastInstallationPreparation.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("last-installation-preparation") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("last-installation-preparation") + } + return err + } + + return nil +} + func (m *Cluster) contextValidateLogsInfo(ctx context.Context, formats strfmt.Registry) error { if err := m.LogsInfo.ContextValidate(ctx, formats); err != nil { diff --git a/vendor/github.com/openshift/assisted-service/models/cluster_create_params.go b/vendor/github.com/openshift/assisted-service/models/cluster_create_params.go index 432ab0ed9a2..3eeade9fcdc 100644 --- a/vendor/github.com/openshift/assisted-service/models/cluster_create_params.go +++ b/vendor/github.com/openshift/assisted-service/models/cluster_create_params.go @@ -24,10 +24,6 @@ type ClusterCreateParams struct { // A comma-separated list of NTP sources (name or IP) going to be added to all the hosts. AdditionalNtpSource *string `json:"additional_ntp_source,omitempty"` - // (DEPRECATED) The virtual IP used to reach the OpenShift cluster's API. - // Pattern: ^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))?$ - APIVip string `json:"api_vip,omitempty"` - // The virtual IPs used to reach the OpenShift cluster's API. Enter one IP address for single-stack clusters, or up to two for dual-stack clusters (at most one IP address per IP stack used). The order of stacks should be the same as order of subnets in Cluster Networks, Service Networks, and Machine Networks. APIVips []*APIVip `json:"api_vips"` @@ -76,10 +72,6 @@ type ClusterCreateParams struct { // Explicit ignition endpoint overrides the default ignition endpoint. IgnitionEndpoint *IgnitionEndpoint `json:"ignition_endpoint,omitempty" gorm:"embedded;embeddedPrefix:ignition_endpoint_"` - // (DEPRECATED) The virtual IP used for cluster ingress traffic. - // Pattern: ^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))$ - IngressVip string `json:"ingress_vip,omitempty"` - // The virtual IPs used for cluster ingress traffic. Enter one IP address for single-stack clusters, or up to two for dual-stack clusters (at most one IP address per IP stack used). The order of stacks should be the same as order of subnets in Cluster Networks, Service Networks, and Machine Networks. IngressVips []*IngressVip `json:"ingress_vips"` @@ -143,10 +135,6 @@ type ClusterCreateParams struct { func (m *ClusterCreateParams) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateAPIVip(formats); err != nil { - res = append(res, err) - } - if err := m.validateAPIVips(formats); err != nil { res = append(res, err) } @@ -183,10 +171,6 @@ func (m *ClusterCreateParams) Validate(formats strfmt.Registry) error { res = append(res, err) } - if err := m.validateIngressVip(formats); err != nil { - res = append(res, err) - } - if err := m.validateIngressVips(formats); err != nil { res = append(res, err) } @@ -233,18 +217,6 @@ func (m *ClusterCreateParams) Validate(formats strfmt.Registry) error { return nil } -func (m *ClusterCreateParams) validateAPIVip(formats strfmt.Registry) error { - if swag.IsZero(m.APIVip) { // not required - return nil - } - - if err := validate.Pattern("api_vip", "body", m.APIVip, `^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))?$`); err != nil { - return err - } - - return nil -} - func (m *ClusterCreateParams) validateAPIVips(formats strfmt.Registry) error { if swag.IsZero(m.APIVips) { // not required return nil @@ -507,18 +479,6 @@ func (m *ClusterCreateParams) validateIgnitionEndpoint(formats strfmt.Registry) return nil } -func (m *ClusterCreateParams) validateIngressVip(formats strfmt.Registry) error { - if swag.IsZero(m.IngressVip) { // not required - return nil - } - - if err := validate.Pattern("ingress_vip", "body", m.IngressVip, `^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))$`); err != nil { - return err - } - - return nil -} - func (m *ClusterCreateParams) validateIngressVips(formats strfmt.Registry) error { if swag.IsZero(m.IngressVips) { // not required return nil diff --git a/vendor/github.com/openshift/assisted-service/models/cluster_finalizing_progress.go b/vendor/github.com/openshift/assisted-service/models/cluster_finalizing_progress.go new file mode 100644 index 00000000000..50e324845e2 --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/models/cluster_finalizing_progress.go @@ -0,0 +1,100 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// ClusterFinalizingProgress cluster finalizing progress +// +// swagger:model cluster-finalizing-progress +type ClusterFinalizingProgress struct { + + // finalizing stage + FinalizingStage FinalizingStage `json:"finalizing_stage,omitempty"` +} + +// Validate validates this cluster finalizing progress +func (m *ClusterFinalizingProgress) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateFinalizingStage(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ClusterFinalizingProgress) validateFinalizingStage(formats strfmt.Registry) error { + if swag.IsZero(m.FinalizingStage) { // not required + return nil + } + + if err := m.FinalizingStage.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("finalizing_stage") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("finalizing_stage") + } + return err + } + + return nil +} + +// ContextValidate validate this cluster finalizing progress based on the context it is used +func (m *ClusterFinalizingProgress) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateFinalizingStage(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ClusterFinalizingProgress) contextValidateFinalizingStage(ctx context.Context, formats strfmt.Registry) error { + + if err := m.FinalizingStage.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("finalizing_stage") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("finalizing_stage") + } + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *ClusterFinalizingProgress) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *ClusterFinalizingProgress) UnmarshalBinary(b []byte) error { + var res ClusterFinalizingProgress + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/models/cluster_progress_info.go b/vendor/github.com/openshift/assisted-service/models/cluster_progress_info.go index 5a2f49283b6..5a1b5ecdced 100644 --- a/vendor/github.com/openshift/assisted-service/models/cluster_progress_info.go +++ b/vendor/github.com/openshift/assisted-service/models/cluster_progress_info.go @@ -8,8 +8,10 @@ package models import ( "context" + "github.com/go-openapi/errors" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" + "github.com/go-openapi/validate" ) // ClusterProgressInfo cluster progress info @@ -17,12 +19,27 @@ import ( // swagger:model cluster-progress-info type ClusterProgressInfo struct { + // finalizing stage + FinalizingStage FinalizingStage `json:"finalizing_stage,omitempty"` + // finalizing stage percentage FinalizingStagePercentage int64 `json:"finalizing_stage_percentage,omitempty"` + // finalizing stage started at + // Format: date-time + FinalizingStageStartedAt strfmt.DateTime `json:"finalizing_stage_started_at,omitempty" gorm:"type:timestamp with time zone"` + // installing stage percentage InstallingStagePercentage int64 `json:"installing_stage_percentage,omitempty"` + // node updater finished at + // Format: date-time + NodeUpdaterFinishedAt strfmt.DateTime `json:"node_updater_finished_at,omitempty" gorm:"type:timestamp with time zone"` + + // node updater started at + // Format: date-time + NodeUpdaterStartedAt strfmt.DateTime `json:"node_updater_started_at,omitempty" gorm:"type:timestamp with time zone"` + // preparing for installation stage percentage PreparingForInstallationStagePercentage int64 `json:"preparing_for_installation_stage_percentage,omitempty"` @@ -32,11 +49,108 @@ type ClusterProgressInfo struct { // Validate validates this cluster progress info func (m *ClusterProgressInfo) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateFinalizingStage(formats); err != nil { + res = append(res, err) + } + + if err := m.validateFinalizingStageStartedAt(formats); err != nil { + res = append(res, err) + } + + if err := m.validateNodeUpdaterFinishedAt(formats); err != nil { + res = append(res, err) + } + + if err := m.validateNodeUpdaterStartedAt(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } return nil } -// ContextValidate validates this cluster progress info based on context it is used +func (m *ClusterProgressInfo) validateFinalizingStage(formats strfmt.Registry) error { + if swag.IsZero(m.FinalizingStage) { // not required + return nil + } + + if err := m.FinalizingStage.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("finalizing_stage") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("finalizing_stage") + } + return err + } + + return nil +} + +func (m *ClusterProgressInfo) validateFinalizingStageStartedAt(formats strfmt.Registry) error { + if swag.IsZero(m.FinalizingStageStartedAt) { // not required + return nil + } + + if err := validate.FormatOf("finalizing_stage_started_at", "body", "date-time", m.FinalizingStageStartedAt.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *ClusterProgressInfo) validateNodeUpdaterFinishedAt(formats strfmt.Registry) error { + if swag.IsZero(m.NodeUpdaterFinishedAt) { // not required + return nil + } + + if err := validate.FormatOf("node_updater_finished_at", "body", "date-time", m.NodeUpdaterFinishedAt.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *ClusterProgressInfo) validateNodeUpdaterStartedAt(formats strfmt.Registry) error { + if swag.IsZero(m.NodeUpdaterStartedAt) { // not required + return nil + } + + if err := validate.FormatOf("node_updater_started_at", "body", "date-time", m.NodeUpdaterStartedAt.String(), formats); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this cluster progress info based on the context it is used func (m *ClusterProgressInfo) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateFinalizingStage(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ClusterProgressInfo) contextValidateFinalizingStage(ctx context.Context, formats strfmt.Registry) error { + + if err := m.FinalizingStage.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("finalizing_stage") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("finalizing_stage") + } + return err + } + return nil } diff --git a/vendor/github.com/openshift/assisted-service/models/custom.go b/vendor/github.com/openshift/assisted-service/models/custom.go new file mode 100644 index 00000000000..a1ad42b71ef --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/models/custom.go @@ -0,0 +1,71 @@ +// custom.go file has custom models for assisted-service that are not +// auto-generated via the swagger.yaml file due to the need for custom +// validation or fields +package models + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" + "github.com/openshift/assisted-service/pkg/validations" +) + +// DomainResolutionRequestDomain is a struct to hold the domain resolution request domain +type DomainResolutionRequestDomain struct { + + // The domain name that should be resolved + // Required: true + DomainName *string `json:"domain_name"` +} + +// Validate is a function required for interfaces derived from swagger models and it +// validates this domain resolution request domain +func (m *DomainResolutionRequestDomain) Validate(formats strfmt.Registry) error { + if err := m.validateDomainName(formats); err != nil { + return err + } + + return nil +} + +// validateDomainName ensures that the required DomainName field exists and that the +// DomainName is valid +func (m *DomainResolutionRequestDomain) validateDomainName(formats strfmt.Registry) error { + if err := validate.Required("domain_name", "body", m.DomainName); err != nil { + return err + } + + if _, err := validations.ValidateDomainNameFormat(*m.DomainName); err != nil { + return err + } + + return nil +} + +// The following functions (ContextValidate, MarshalBinary, UnmarshalBinary) are required for +// interfaces derived from swagger models + +// ContextValidate validates this domain resolution request domain based on context it is used +func (m *DomainResolutionRequestDomain) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *DomainResolutionRequestDomain) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *DomainResolutionRequestDomain) UnmarshalBinary(b []byte) error { + var res DomainResolutionRequestDomain + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/models/domain_resolution_request.go b/vendor/github.com/openshift/assisted-service/models/domain_resolution_request.go index 030a4365401..13c3290d9c4 100644 --- a/vendor/github.com/openshift/assisted-service/models/domain_resolution_request.go +++ b/vendor/github.com/openshift/assisted-service/models/domain_resolution_request.go @@ -22,7 +22,7 @@ type DomainResolutionRequest struct { // domains // Required: true - Domains []*DomainResolutionRequestDomain `json:"domains"` + Domains []DomainResolutionRequestDomain `json:"domains"` } // Validate validates this domain resolution request @@ -46,19 +46,14 @@ func (m *DomainResolutionRequest) validateDomains(formats strfmt.Registry) error } for i := 0; i < len(m.Domains); i++ { - if swag.IsZero(m.Domains[i]) { // not required - continue - } - if m.Domains[i] != nil { - if err := m.Domains[i].Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("domains" + "." + strconv.Itoa(i)) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("domains" + "." + strconv.Itoa(i)) - } - return err + if err := m.Domains[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("domains" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("domains" + "." + strconv.Itoa(i)) } + return err } } @@ -66,37 +61,8 @@ func (m *DomainResolutionRequest) validateDomains(formats strfmt.Registry) error return nil } -// ContextValidate validate this domain resolution request based on the context it is used +// ContextValidate validates this domain resolution request based on context it is used func (m *DomainResolutionRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - var res []error - - if err := m.contextValidateDomains(ctx, formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *DomainResolutionRequest) contextValidateDomains(ctx context.Context, formats strfmt.Registry) error { - - for i := 0; i < len(m.Domains); i++ { - - if m.Domains[i] != nil { - if err := m.Domains[i].ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("domains" + "." + strconv.Itoa(i)) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("domains" + "." + strconv.Itoa(i)) - } - return err - } - } - - } - return nil } @@ -117,64 +83,3 @@ func (m *DomainResolutionRequest) UnmarshalBinary(b []byte) error { *m = res return nil } - -// DomainResolutionRequestDomain domain resolution request domain -// -// swagger:model DomainResolutionRequestDomain -type DomainResolutionRequestDomain struct { - - // The domain name that should be resolved - // Required: true - // Pattern: ^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*[.])+[a-zA-Z]{2,}[.]?$ - DomainName *string `json:"domain_name"` -} - -// Validate validates this domain resolution request domain -func (m *DomainResolutionRequestDomain) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateDomainName(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *DomainResolutionRequestDomain) validateDomainName(formats strfmt.Registry) error { - - if err := validate.Required("domain_name", "body", m.DomainName); err != nil { - return err - } - - if err := validate.Pattern("domain_name", "body", *m.DomainName, `^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*[.])+[a-zA-Z]{2,}[.]?$`); err != nil { - return err - } - - return nil -} - -// ContextValidate validates this domain resolution request domain based on context it is used -func (m *DomainResolutionRequestDomain) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (m *DomainResolutionRequestDomain) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *DomainResolutionRequestDomain) UnmarshalBinary(b []byte) error { - var res DomainResolutionRequestDomain - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/vendor/github.com/openshift/assisted-service/models/feature_support_level_id.go b/vendor/github.com/openshift/assisted-service/models/feature_support_level_id.go index 36f7fc3c8ac..892cdc9ef16 100644 --- a/vendor/github.com/openshift/assisted-service/models/feature_support_level_id.go +++ b/vendor/github.com/openshift/assisted-service/models/feature_support_level_id.go @@ -92,6 +92,12 @@ const ( // FeatureSupportLevelIDPLATFORMMANAGEDNETWORKING captures enum value "PLATFORM_MANAGED_NETWORKING" FeatureSupportLevelIDPLATFORMMANAGEDNETWORKING FeatureSupportLevelID = "PLATFORM_MANAGED_NETWORKING" + + // FeatureSupportLevelIDSKIPMCOREBOOT captures enum value "SKIP_MCO_REBOOT" + FeatureSupportLevelIDSKIPMCOREBOOT FeatureSupportLevelID = "SKIP_MCO_REBOOT" + + // FeatureSupportLevelIDEXTERNALPLATFORM captures enum value "EXTERNAL_PLATFORM" + FeatureSupportLevelIDEXTERNALPLATFORM FeatureSupportLevelID = "EXTERNAL_PLATFORM" ) // for schema @@ -99,7 +105,7 @@ var featureSupportLevelIdEnum []interface{} func init() { var res []FeatureSupportLevelID - if err := json.Unmarshal([]byte(`["SNO","VIP_AUTO_ALLOC","CUSTOM_MANIFEST","SINGLE_NODE_EXPANSION","LVM","ODF","LSO","CNV","MCE","NUTANIX_INTEGRATION","BAREMETAL_PLATFORM","NONE_PLATFORM","VSPHERE_INTEGRATION","DUAL_STACK_VIPS","CLUSTER_MANAGED_NETWORKING","USER_MANAGED_NETWORKING","MINIMAL_ISO","FULL_ISO","EXTERNAL_PLATFORM_OCI","DUAL_STACK","PLATFORM_MANAGED_NETWORKING"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["SNO","VIP_AUTO_ALLOC","CUSTOM_MANIFEST","SINGLE_NODE_EXPANSION","LVM","ODF","LSO","CNV","MCE","NUTANIX_INTEGRATION","BAREMETAL_PLATFORM","NONE_PLATFORM","VSPHERE_INTEGRATION","DUAL_STACK_VIPS","CLUSTER_MANAGED_NETWORKING","USER_MANAGED_NETWORKING","MINIMAL_ISO","FULL_ISO","EXTERNAL_PLATFORM_OCI","DUAL_STACK","PLATFORM_MANAGED_NETWORKING","SKIP_MCO_REBOOT","EXTERNAL_PLATFORM"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/vendor/github.com/openshift/assisted-service/models/finalizing_stage.go b/vendor/github.com/openshift/assisted-service/models/finalizing_stage.go new file mode 100644 index 00000000000..a45e95e7aa1 --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/models/finalizing_stage.go @@ -0,0 +1,93 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/validate" +) + +// FinalizingStage Cluster finalizing stage managed by controller +// +// swagger:model finalizing-stage +type FinalizingStage string + +func NewFinalizingStage(value FinalizingStage) *FinalizingStage { + return &value +} + +// Pointer returns a pointer to a freshly-allocated FinalizingStage. +func (m FinalizingStage) Pointer() *FinalizingStage { + return &m +} + +const ( + + // FinalizingStageWaitingForFinalizing captures enum value "Waiting for finalizing" + FinalizingStageWaitingForFinalizing FinalizingStage = "Waiting for finalizing" + + // FinalizingStageWaitingForClusterOperators captures enum value "Waiting for cluster operators" + FinalizingStageWaitingForClusterOperators FinalizingStage = "Waiting for cluster operators" + + // FinalizingStageAddingRouterCa captures enum value "Adding router ca" + FinalizingStageAddingRouterCa FinalizingStage = "Adding router ca" + + // FinalizingStageWaitingForOlmOperators captures enum value "Waiting for olm operators" + FinalizingStageWaitingForOlmOperators FinalizingStage = "Waiting for olm operators" + + // FinalizingStageApplyingManifests captures enum value "Applying manifests" + FinalizingStageApplyingManifests FinalizingStage = "Applying manifests" + + // FinalizingStageWaitingForOlmOperatorsCsv captures enum value "Waiting for olm operators csv" + FinalizingStageWaitingForOlmOperatorsCsv FinalizingStage = "Waiting for olm operators csv" + + // FinalizingStageDone captures enum value "Done" + FinalizingStageDone FinalizingStage = "Done" +) + +// for schema +var finalizingStageEnum []interface{} + +func init() { + var res []FinalizingStage + if err := json.Unmarshal([]byte(`["Waiting for finalizing","Waiting for cluster operators","Adding router ca","Waiting for olm operators","Applying manifests","Waiting for olm operators csv","Done"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + finalizingStageEnum = append(finalizingStageEnum, v) + } +} + +func (m FinalizingStage) validateFinalizingStageEnum(path, location string, value FinalizingStage) error { + if err := validate.EnumCase(path, location, value, finalizingStageEnum, true); err != nil { + return err + } + return nil +} + +// Validate validates this finalizing stage +func (m FinalizingStage) Validate(formats strfmt.Registry) error { + var res []error + + // value enum + if err := m.validateFinalizingStageEnum("", "body", m); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// ContextValidate validates this finalizing stage based on context it is used +func (m FinalizingStage) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/models/install_cmd_request.go b/vendor/github.com/openshift/assisted-service/models/install_cmd_request.go index ea633209df2..917cfc813f2 100644 --- a/vendor/github.com/openshift/assisted-service/models/install_cmd_request.go +++ b/vendor/github.com/openshift/assisted-service/models/install_cmd_request.go @@ -41,6 +41,9 @@ type InstallCmdRequest struct { // List of disks to format DisksToFormat []string `json:"disks_to_format"` + // If true, assisted service will attempt to skip MCO reboot + EnableSkipMcoReboot bool `json:"enable_skip_mco_reboot,omitempty"` + // Guaranteed availability of the installed cluster. 'Full' installs a Highly-Available cluster // over multiple master nodes whereas 'None' installs a full cluster over one node. // diff --git a/vendor/github.com/openshift/assisted-service/models/last_installation_preparation.go b/vendor/github.com/openshift/assisted-service/models/last_installation_preparation.go new file mode 100644 index 00000000000..465934b6c55 --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/models/last_installation_preparation.go @@ -0,0 +1,111 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// LastInstallationPreparation Gives the status of the last installation preparation (if any) +// +// swagger:model last-installation-preparation +type LastInstallationPreparation struct { + + // The reason for the preparation status if applicable + Reason string `json:"reason,omitempty"` + + // The last installation preparation status + // Enum: [preparation_never_performed failed success] + Status string `json:"status,omitempty"` +} + +// Validate validates this last installation preparation +func (m *LastInstallationPreparation) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var lastInstallationPreparationTypeStatusPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["preparation_never_performed","failed","success"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + lastInstallationPreparationTypeStatusPropEnum = append(lastInstallationPreparationTypeStatusPropEnum, v) + } +} + +const ( + + // LastInstallationPreparationStatusPreparationNeverPerformed captures enum value "preparation_never_performed" + LastInstallationPreparationStatusPreparationNeverPerformed string = "preparation_never_performed" + + // LastInstallationPreparationStatusFailed captures enum value "failed" + LastInstallationPreparationStatusFailed string = "failed" + + // LastInstallationPreparationStatusSuccess captures enum value "success" + LastInstallationPreparationStatusSuccess string = "success" +) + +// prop value enum +func (m *LastInstallationPreparation) validateStatusEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, lastInstallationPreparationTypeStatusPropEnum, true); err != nil { + return err + } + return nil +} + +func (m *LastInstallationPreparation) validateStatus(formats strfmt.Registry) error { + if swag.IsZero(m.Status) { // not required + return nil + } + + // value enum + if err := m.validateStatusEnum("status", "body", m.Status); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this last installation preparation based on context it is used +func (m *LastInstallationPreparation) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *LastInstallationPreparation) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *LastInstallationPreparation) UnmarshalBinary(b []byte) error { + var res LastInstallationPreparation + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/models/platform.go b/vendor/github.com/openshift/assisted-service/models/platform.go index b12e113d831..d4772a7d596 100644 --- a/vendor/github.com/openshift/assisted-service/models/platform.go +++ b/vendor/github.com/openshift/assisted-service/models/platform.go @@ -19,10 +19,8 @@ import ( // swagger:model platform type Platform struct { - // Used by the service to indicate that the platform-specific components are not included in - // OpenShift and must be provided as manifests separately. - // Read Only: true - IsExternal *bool `json:"is_external,omitempty"` + // external + External *PlatformExternal `json:"external,omitempty" gorm:"embedded;embeddedPrefix:external_"` // type // Required: true @@ -33,6 +31,10 @@ type Platform struct { func (m *Platform) Validate(formats strfmt.Registry) error { var res []error + if err := m.validateExternal(formats); err != nil { + res = append(res, err) + } + if err := m.validateType(formats); err != nil { res = append(res, err) } @@ -43,6 +45,25 @@ func (m *Platform) Validate(formats strfmt.Registry) error { return nil } +func (m *Platform) validateExternal(formats strfmt.Registry) error { + if swag.IsZero(m.External) { // not required + return nil + } + + if m.External != nil { + if err := m.External.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("external") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("external") + } + return err + } + } + + return nil +} + func (m *Platform) validateType(formats strfmt.Registry) error { if err := validate.Required("type", "body", m.Type); err != nil { @@ -71,7 +92,7 @@ func (m *Platform) validateType(formats strfmt.Registry) error { func (m *Platform) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := m.contextValidateIsExternal(ctx, formats); err != nil { + if err := m.contextValidateExternal(ctx, formats); err != nil { res = append(res, err) } @@ -85,10 +106,17 @@ func (m *Platform) ContextValidate(ctx context.Context, formats strfmt.Registry) return nil } -func (m *Platform) contextValidateIsExternal(ctx context.Context, formats strfmt.Registry) error { +func (m *Platform) contextValidateExternal(ctx context.Context, formats strfmt.Registry) error { - if err := validate.ReadOnly(ctx, "is_external", "body", m.IsExternal); err != nil { - return err + if m.External != nil { + if err := m.External.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("external") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("external") + } + return err + } } return nil diff --git a/vendor/github.com/openshift/assisted-service/models/platform_external.go b/vendor/github.com/openshift/assisted-service/models/platform_external.go new file mode 100644 index 00000000000..3816691273b --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/models/platform_external.go @@ -0,0 +1,125 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// PlatformExternal Configuration used when installing with an external platform type. +// +// swagger:model platform_external +type PlatformExternal struct { + + // When set to external, this property will enable an external cloud provider. + // Enum: [ External] + CloudControllerManager *string `json:"cloud_controller_manager,omitempty"` + + // Holds the arbitrary string representing the infrastructure provider name. + // Min Length: 1 + PlatformName *string `json:"platform_name,omitempty"` +} + +// Validate validates this platform external +func (m *PlatformExternal) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCloudControllerManager(formats); err != nil { + res = append(res, err) + } + + if err := m.validatePlatformName(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var platformExternalTypeCloudControllerManagerPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["","External"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + platformExternalTypeCloudControllerManagerPropEnum = append(platformExternalTypeCloudControllerManagerPropEnum, v) + } +} + +const ( + + // PlatformExternalCloudControllerManagerEmpty captures enum value "" + PlatformExternalCloudControllerManagerEmpty string = "" + + // PlatformExternalCloudControllerManagerExternal captures enum value "External" + PlatformExternalCloudControllerManagerExternal string = "External" +) + +// prop value enum +func (m *PlatformExternal) validateCloudControllerManagerEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, platformExternalTypeCloudControllerManagerPropEnum, true); err != nil { + return err + } + return nil +} + +func (m *PlatformExternal) validateCloudControllerManager(formats strfmt.Registry) error { + if swag.IsZero(m.CloudControllerManager) { // not required + return nil + } + + // value enum + if err := m.validateCloudControllerManagerEnum("cloud_controller_manager", "body", *m.CloudControllerManager); err != nil { + return err + } + + return nil +} + +func (m *PlatformExternal) validatePlatformName(formats strfmt.Registry) error { + if swag.IsZero(m.PlatformName) { // not required + return nil + } + + if err := validate.MinLength("platform_name", "body", *m.PlatformName, 1); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this platform external based on context it is used +func (m *PlatformExternal) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *PlatformExternal) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *PlatformExternal) UnmarshalBinary(b []byte) error { + var res PlatformExternal + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/vendor/github.com/openshift/assisted-service/models/platform_type.go b/vendor/github.com/openshift/assisted-service/models/platform_type.go index b110d6ecafc..24c9d816731 100644 --- a/vendor/github.com/openshift/assisted-service/models/platform_type.go +++ b/vendor/github.com/openshift/assisted-service/models/platform_type.go @@ -42,8 +42,8 @@ const ( // PlatformTypeNone captures enum value "none" PlatformTypeNone PlatformType = "none" - // PlatformTypeOci captures enum value "oci" - PlatformTypeOci PlatformType = "oci" + // PlatformTypeExternal captures enum value "external" + PlatformTypeExternal PlatformType = "external" ) // for schema @@ -51,7 +51,7 @@ var platformTypeEnum []interface{} func init() { var res []PlatformType - if err := json.Unmarshal([]byte(`["baremetal","nutanix","vsphere","none","oci"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["baremetal","nutanix","vsphere","none","external"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/vendor/github.com/openshift/assisted-service/models/v2_cluster_update_params.go b/vendor/github.com/openshift/assisted-service/models/v2_cluster_update_params.go index 27bc0598506..cf3edc1efcf 100644 --- a/vendor/github.com/openshift/assisted-service/models/v2_cluster_update_params.go +++ b/vendor/github.com/openshift/assisted-service/models/v2_cluster_update_params.go @@ -24,10 +24,6 @@ type V2ClusterUpdateParams struct { // A comma-separated list of NTP sources (name or IP) going to be added to all the hosts. AdditionalNtpSource *string `json:"additional_ntp_source,omitempty"` - // (DEPRECATED) The virtual IP used to reach the OpenShift cluster's API. - // Pattern: ^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))?$ - APIVip *string `json:"api_vip,omitempty"` - // The domain name used to reach the OpenShift cluster API. APIVipDNSName *string `json:"api_vip_dns_name,omitempty"` @@ -69,10 +65,6 @@ type V2ClusterUpdateParams struct { // Explicit ignition endpoint overrides the default ignition endpoint. IgnitionEndpoint *IgnitionEndpoint `json:"ignition_endpoint,omitempty" gorm:"embedded;embeddedPrefix:ignition_endpoint_"` - // (DEPRECATED) The virtual IP used for cluster ingress traffic. - // Pattern: ^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))?$ - IngressVip *string `json:"ingress_vip,omitempty"` - // The virtual IPs used for cluster ingress traffic. Enter one IP address for single-stack clusters, or up to two for dual-stack clusters (at most one IP address per IP stack used). The order of stacks should be the same as order of subnets in Cluster Networks, Service Networks, and Machine Networks. IngressVips []*IngressVip `json:"ingress_vips"` @@ -131,10 +123,6 @@ type V2ClusterUpdateParams struct { func (m *V2ClusterUpdateParams) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateAPIVip(formats); err != nil { - res = append(res, err) - } - if err := m.validateAPIVips(formats); err != nil { res = append(res, err) } @@ -163,10 +151,6 @@ func (m *V2ClusterUpdateParams) Validate(formats strfmt.Registry) error { res = append(res, err) } - if err := m.validateIngressVip(formats); err != nil { - res = append(res, err) - } - if err := m.validateIngressVips(formats); err != nil { res = append(res, err) } @@ -209,18 +193,6 @@ func (m *V2ClusterUpdateParams) Validate(formats strfmt.Registry) error { return nil } -func (m *V2ClusterUpdateParams) validateAPIVip(formats strfmt.Registry) error { - if swag.IsZero(m.APIVip) { // not required - return nil - } - - if err := validate.Pattern("api_vip", "body", *m.APIVip, `^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))?$`); err != nil { - return err - } - - return nil -} - func (m *V2ClusterUpdateParams) validateAPIVips(formats strfmt.Registry) error { if swag.IsZero(m.APIVips) { // not required return nil @@ -387,18 +359,6 @@ func (m *V2ClusterUpdateParams) validateIgnitionEndpoint(formats strfmt.Registry return nil } -func (m *V2ClusterUpdateParams) validateIngressVip(formats strfmt.Registry) error { - if swag.IsZero(m.IngressVip) { // not required - return nil - } - - if err := validate.Pattern("ingress_vip", "body", *m.IngressVip, `^(?:(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:(?:[0-9a-fA-F]*:[0-9a-fA-F]*){2,}))?$`); err != nil { - return err - } - - return nil -} - func (m *V2ClusterUpdateParams) validateIngressVips(formats strfmt.Registry) error { if swag.IsZero(m.IngressVips) { // not required return nil diff --git a/vendor/github.com/openshift/assisted-service/pkg/validations/validations.go b/vendor/github.com/openshift/assisted-service/pkg/validations/validations.go new file mode 100644 index 00000000000..5b5612352fd --- /dev/null +++ b/vendor/github.com/openshift/assisted-service/pkg/validations/validations.go @@ -0,0 +1,192 @@ +package validations + +import ( + "crypto/x509" + "encoding/base64" + "fmt" + "net" + "net/http" + "net/url" + "regexp" + "strings" + + "github.com/asaskevich/govalidator" + "github.com/pkg/errors" + "github.com/thoas/go-funk" +) + +const ( + baseDomainRegex = `^[a-z\d][\-]*[a-z\d]+$` + dnsNameRegex = `^([a-z\d]([\-]*[a-z\d]+)*\.)+[a-z\d]+[\-]*[a-z\d]+$` + hostnameRegex = `^[a-z0-9][a-z0-9\-\.]{0,61}[a-z0-9]$` + installerArgsValuesRegex = `^[A-Za-z0-9@!#$%*()_+-=//.,";':{}\[\]]+$` +) + +var allowedFlags = []string{"--append-karg", "--delete-karg", "-n", "--copy-network", "--network-dir", "--save-partlabel", "--save-partindex", "--image-url", "--image-file"} + +func ValidateInstallerArgs(args []string) error { + argsRe := regexp.MustCompile("^-+.*") + valuesRe := regexp.MustCompile(installerArgsValuesRegex) + + for _, arg := range args { + if argsRe.MatchString(arg) { + if !funk.ContainsString(allowedFlags, arg) { + return fmt.Errorf("found unexpected flag %s for installer - allowed flags are %v", arg, allowedFlags) + } + continue + } + + if !valuesRe.MatchString(arg) { + return fmt.Errorf("found unexpected chars in value %s for installer", arg) + } + } + + return nil +} + +func ValidateDomainNameFormat(dnsDomainName string) (int32, error) { + matched, err := regexp.MatchString(baseDomainRegex, dnsDomainName) + if err != nil { + return http.StatusInternalServerError, errors.Wrapf(err, "Single DNS base domain validation for %s", dnsDomainName) + } + if matched && len(dnsDomainName) > 1 { + return 0, nil + } + matched, err = regexp.MatchString(dnsNameRegex, dnsDomainName) + if err != nil { + return http.StatusInternalServerError, errors.Wrapf(err, "DNS name validation for %s", dnsDomainName) + } + if !matched { + return http.StatusBadRequest, errors.Errorf("DNS format mismatch: %s domain name is not valid", dnsDomainName) + } + return 0, nil +} + +func ValidateHostname(name string) error { + matched, err := regexp.MatchString(hostnameRegex, name) + if err != nil { + return errors.Wrapf(err, "Hostname validation for %s", name) + } + if !matched { + return errors.Errorf(`Hostname format mismatch: %s name is not valid. + Hostname must have a maximum length of 64 characters, + start and end with a lowercase alphanumerical character, + and can only contain lowercase alphanumerical characters, dashes, and periods.`, name) + } + return nil +} + +func AllStrings(vs []string, f func(string) bool) bool { + for _, v := range vs { + if !f(v) { + return false + } + } + return true +} + +func ValidateAdditionalNTPSource(commaSeparatedNTPSources string) bool { + return AllStrings(strings.Split(commaSeparatedNTPSources, ","), ValidateNTPSource) +} + +func ValidateNTPSource(ntpSource string) bool { + if addr := net.ParseIP(ntpSource); addr != nil { + return true + } + + if err := ValidateHostname(ntpSource); err == nil { + return true + } + + return false +} + +// ValidateHTTPFormat validates the HTTP and HTTPS format +func ValidateHTTPFormat(theurl string) error { + u, err := url.Parse(theurl) + if err != nil { + return fmt.Errorf("URL '%s' format is not valid: %w", theurl, err) + } + if !(u.Scheme == "http" || u.Scheme == "https") { + return errors.Errorf("The URL scheme must be http(s) and specified in the URL: '%s'", theurl) + } + return nil +} + +// ValidateHTTPProxyFormat validates the HTTP Proxy and HTTPS Proxy format +func ValidateHTTPProxyFormat(proxyURL string) error { + if !govalidator.IsURL(proxyURL) { + return errors.Errorf("Proxy URL format is not valid: '%s'", proxyURL) + } + u, err := url.Parse(proxyURL) + if err != nil { + return errors.Errorf("Proxy URL format is not valid: '%s'", proxyURL) + } + if u.Scheme == "https" { + return errors.Errorf("The URL scheme must be http; https is currently not supported: '%s'", proxyURL) + } + if u.Scheme != "http" { + return errors.Errorf("The URL scheme must be http and specified in the URL: '%s'", proxyURL) + } + return nil +} + +// ValidateNoProxyFormat validates the no-proxy format which should be a comma-separated list +// of destination domain names, domains, IP addresses or other network CIDRs. A domain can be +// prefaced with '.' to include all subdomains of that domain. +func ValidateNoProxyFormat(noProxy string) error { + if noProxy == "*" { + return nil + } + domains := strings.Split(noProxy, ",") + for _, s := range domains { + s = strings.TrimPrefix(s, ".") + if govalidator.IsIP(s) { + continue + } + + if govalidator.IsCIDR(s) { + continue + } + + if govalidator.IsDNSName(s) { + continue + } + return errors.Errorf("NO Proxy format is not valid: '%s'. "+ + "NO Proxy is a comma-separated list of destination domain names, domains, IP addresses or other network CIDRs. "+ + "A domain can be prefaced with '.' to include all subdomains of that domain. Use '*' to bypass proxy for all destinations with OpenShift 4.8 or later.", noProxy) + } + return nil +} + +func ValidateTags(tags string) error { + if tags == "" { + return nil + } + if !AllStrings(strings.Split(tags, ","), IsValidTag) { + errMsg := "Invalid format for Tags: %s. Tags should be a comma-separated list (e.g. tag1,tag2,tag3). " + + "Each tag can consist of the following characters: Alphanumeric (aA-zZ, 0-9), underscore (_) and white-spaces." + return errors.Errorf(errMsg, tags) + } + return nil +} + +func IsValidTag(tag string) bool { + tagRegex := `^\w+( \w+)*$` // word characters and whitespace + return regexp.MustCompile(tagRegex).MatchString(tag) +} + +// ValidateCaCertificate ensures the specified base64 CA certificate +// is valid by trying to decode and parse it. +func ValidateCaCertificate(certificate string) error { + decodedCaCert, err := base64.StdEncoding.DecodeString(certificate) + if err != nil { + return errors.Wrap(err, "failed to decode certificate") + } + caCertPool := x509.NewCertPool() + if ok := caCertPool.AppendCertsFromPEM(decodedCaCert); !ok { + return errors.Errorf("unable to parse certificate") + } + + return nil +} diff --git a/vendor/github.com/thoas/go-funk/.gitignore b/vendor/github.com/thoas/go-funk/.gitignore new file mode 100644 index 00000000000..7b4c598b0b9 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/.gitignore @@ -0,0 +1,27 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +#GoLand +.idea \ No newline at end of file diff --git a/vendor/github.com/thoas/go-funk/.travis.yml b/vendor/github.com/thoas/go-funk/.travis.yml new file mode 100644 index 00000000000..f8aa08ad61e --- /dev/null +++ b/vendor/github.com/thoas/go-funk/.travis.yml @@ -0,0 +1,7 @@ +language: go +before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/stretchr/testify +go: + - "1.16" +script: make test diff --git a/vendor/github.com/thoas/go-funk/CHANGELOG.md b/vendor/github.com/thoas/go-funk/CHANGELOG.md new file mode 100644 index 00000000000..000a371bf42 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/CHANGELOG.md @@ -0,0 +1,29 @@ +go-funk changelog +================= + +0.1 (2017-01-18) +---------------- + +Changes can be seen [here](https://github.com/thoas/go-funk/compare/73b8ae1f6443c9d4acbdc612bbb2ca804bb39b1d...master) + +* Better test suite +* Better documentation +* Add typesafe implementations: + + * ``Contains`` + * ``Sum`` + * ``Reverse`` + * ``IndexOf`` + * ``Uniq`` + * ``Shuffle`` +* Add benchmarks + + * ``Contains`` + * ``Uniq`` + * ``Sum`` +* Fix ``redirectValue`` when using a circular reference +* Add ``Sum`` generic implementation which computes the sum of values in an array +* Add ``Tail`` generic implementation to retrieve all but the first element of array +* Add ``Initial`` generic implementation to retrieve all but the last element of array +* Add ``Last`` generic implementation to retrieve the last element of an array +* Add ``Head`` generic implementation to retrieve the first element of an array diff --git a/vendor/github.com/thoas/go-funk/LICENSE b/vendor/github.com/thoas/go-funk/LICENSE new file mode 100644 index 00000000000..2430978a067 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Florent Messa + +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/thoas/go-funk/Makefile b/vendor/github.com/thoas/go-funk/Makefile new file mode 100644 index 00000000000..59ae860ebc3 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/Makefile @@ -0,0 +1,11 @@ +build: + go build -v ./... + +test: + go test -v ./... + +lint: + golangci-lint run + +bench: + go test -benchmem -bench . diff --git a/vendor/github.com/thoas/go-funk/README.rst b/vendor/github.com/thoas/go-funk/README.rst new file mode 100644 index 00000000000..d1a9f856581 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/README.rst @@ -0,0 +1,895 @@ +go-funk +======= + +.. image:: https://secure.travis-ci.org/thoas/go-funk.svg?branch=master + :alt: Build Status + :target: http://travis-ci.org/thoas/go-funk + +.. image:: https://godoc.org/github.com/thoas/go-funk?status.svg + :alt: GoDoc + :target: https://pkg.go.dev/github.com/thoas/go-funk + +.. image:: https://goreportcard.com/badge/github.com/thoas/go-funk + :alt: Go report + :target: https://goreportcard.com/report/github.com/thoas/go-funk + +``go-funk`` is a modern Go library based on reflect_. + +Generic helpers rely on reflect_, be careful this code runs exclusively on runtime so you must have a good test suite. + +These helpers have started as an experiment to learn reflect_. It may look like lodash_ in some aspects but +it will have its own roadmap. lodash_ is an awesome library with a lot of work behind it, all features included in +``go-funk`` come from internal use cases. + +You can also find typesafe implementation in the godoc_. + +Why this name? +-------------- + +Long story, short answer because ``func`` is a reserved word in Go, I wanted something similar. + +Initially this project was named ``fn`` I don't need to explain why that was a bad idea for french speakers :) + +Let's ``funk``! + +.. image:: https://media.giphy.com/media/3oEjHQKtDXpeGN9rW0/giphy.gif + +<3 + +Installation +------------ + +.. code-block:: bash + + go get github.com/thoas/go-funk + +Usage +----- + +.. code-block:: go + + import "github.com/thoas/go-funk" + +These examples will be based on the following data model: + +.. code-block:: go + + type Foo struct { + ID int + FirstName string `tag_name:"tag 1"` + LastName string `tag_name:"tag 2"` + Age int `tag_name:"tag 3"` + } + + func (f Foo) TableName() string { + return "foo" + } + +With fixtures: + +.. code-block:: go + + f := &Foo{ + ID: 1, + FirstName: "Foo", + LastName: "Bar", + Age: 30, + } + +You can import ``go-funk`` using a basic statement: + +.. code-block:: go + + import "github.com/thoas/go-funk" + +funk.Contains +............. + +Returns true if an element is present in a iteratee (slice, map, string). + +One frustrating thing in Go is to implement ``contains`` methods for each type, for example: + +.. code-block:: go + + func ContainsInt(s []int, e int) bool { + for _, a := range s { + if a == e { + return true + } + } + return false + } + +this can be replaced by ``funk.Contains``: + +.. code-block:: go + + // slice of string + funk.Contains([]string{"foo", "bar"}, "bar") // true + + // slice of Foo ptr + funk.Contains([]*Foo{f}, f) // true + funk.Contains([]*Foo{f}, func (foo *Foo) bool { + return foo.ID == f.ID + }) // true + funk.Contains([]*Foo{f}, nil) // false + + b := &Foo{ + ID: 2, + FirstName: "Florent", + LastName: "Messa", + Age: 28, + } + + funk.Contains([]*Foo{f}, b) // false + + // string + funk.Contains("florent", "rent") // true + funk.Contains("florent", "foo") // false + + // even map + funk.Contains(map[int]string{1: "Florent"}, 1) // true + funk.Contains(map[int]string{1: "Florent"}, func(key int, name string) bool { + return key == 1 // or `name == "Florent"` for the value type + }) // true + +see also, typesafe implementations: ContainsInt_, ContainsInt64_, ContainsFloat32_, ContainsFloat64_, ContainsString_ + +.. _ContainsFloat32: https://godoc.org/github.com/thoas/go-funk#ContainsFloat32 +.. _ContainsFloat64: https://godoc.org/github.com/thoas/go-funk#ContainsFloat64 +.. _ContainsInt: https://godoc.org/github.com/thoas/go-funk#ContainsInt +.. _ContainsInt64: https://godoc.org/github.com/thoas/go-funk#ContainsInt64 +.. _ContainsString: https://godoc.org/github.com/thoas/go-funk#ContainsString + +funk.Intersect +.............. + +Returns the intersection between two collections. + +.. code-block:: go + + funk.Intersect([]int{1, 2, 3, 4}, []int{2, 4, 6}) // []int{2, 4} + funk.Intersect([]string{"foo", "bar", "hello", "bar"}, []string{"foo", "bar"}) // []string{"foo", "bar"} + +see also, typesafe implementations: IntersectString + +.. IntersectString: https://godoc.org/github.com/thoas/go-funk#IntersectString + + +funk.Difference +.............. + +Returns the difference between two collections. + +.. code-block:: go + + funk.Difference([]int{1, 2, 3, 4}, []int{2, 4, 6}) // []int{1, 3}, []int{6} + funk.Difference([]string{"foo", "bar", "hello", "bar"}, []string{"foo", "bar"}) // []string{"hello"}, []string{} + +see also, typesafe implementations: DifferenceString + +.. DifferenceString: https://godoc.org/github.com/thoas/go-funk#DifferenceString + + +funk.IndexOf +............ + +Gets the index at which the first occurrence of a value is found in an array or return -1 +if the value cannot be found. + +.. code-block:: go + + // slice of string + funk.IndexOf([]string{"foo", "bar"}, "bar") // 1 + funk.IndexOf([]string{"foo", "bar"}, func(value string) bool { + return value == "bar" + }) // 1 + funk.IndexOf([]string{"foo", "bar"}, "gilles") // -1 + +see also, typesafe implementations: IndexOfInt_, IndexOfInt64_, IndexOfFloat32_, IndexOfFloat64_, IndexOfString_ + +.. _IndexOfFloat32: https://godoc.org/github.com/thoas/go-funk#IndexOfFloat32 +.. _IndexOfFloat64: https://godoc.org/github.com/thoas/go-funk#IndexOfFloat64 +.. _IndexOfInt: https://godoc.org/github.com/thoas/go-funk#IndexOfInt +.. _IndexOfInt64: https://godoc.org/github.com/thoas/go-funk#IndexOfInt64 +.. _IndexOfString: https://godoc.org/github.com/thoas/go-funk#IndexOfString + +funk.LastIndexOf +................ + +Gets the index at which the last occurrence of a value is found in an array or return -1 +if the value cannot be found. + +.. code-block:: go + + // slice of string + funk.LastIndexOf([]string{"foo", "bar", "bar"}, "bar") // 2 + funk.LastIndexOf([]string{"foo", "bar"}, func(value string) bool { + return value == "bar" + }) // 2 + funk.LastIndexOf([]string{"foo", "bar"}, "gilles") // -1 + +see also, typesafe implementations: LastIndexOfInt_, LastIndexOfInt64_, LastIndexOfFloat32_, LastIndexOfFloat64_, LastIndexOfString_ + +.. _LastIndexOfFloat32: https://godoc.org/github.com/thoas/go-funk#LastIndexOfFloat32 +.. _LastIndexOfFloat64: https://godoc.org/github.com/thoas/go-funk#LastIndexOfFloat64 +.. _LastIndexOfInt: https://godoc.org/github.com/thoas/go-funk#LastIndexOfInt +.. _LastIndexOfInt64: https://godoc.org/github.com/thoas/go-funk#LastIndexOfInt64 +.. _LastIndexOfString: https://godoc.org/github.com/thoas/go-funk#LastIndexOfString + +funk.ToMap +.......... + +Transforms a slice or an array of structs to a map based on a ``pivot`` field. + +.. code-block:: go + + f := &Foo{ + ID: 1, + FirstName: "Gilles", + LastName: "Fabio", + Age: 70, + } + + b := &Foo{ + ID: 2, + FirstName: "Florent", + LastName: "Messa", + Age: 80, + } + + results := []*Foo{f, b} + + mapping := funk.ToMap(results, "ID") // map[int]*Foo{1: f, 2: b} + +funk.ToSet +.......... + +Transforms an array or a slice to a set (a map with zero-size values). + +.. code-block:: go + + f := Foo{ + ID: 1, + FirstName: "Gilles", + LastName: "Fabio", + Age: 70, + } + + b := Foo{ + ID: 2, + FirstName: "Florent", + LastName: "Messa", + Age: 80, + } + + mapping := funk.ToSet([]Foo{f, b}) // map[Foo]stuct{}{f: struct{}{}, b: struct{}{}} + + mapping := funk.ToSet([4]int{1, 1, 2, 2}) // map[int]struct{}{1: struct{}{}, 2: struct{}{}} + + + +funk.Filter +........... + +Filters a slice based on a predicate. + +.. code-block:: go + + r := funk.Filter([]int{1, 2, 3, 4}, func(x int) bool { + return x%2 == 0 + }) // []int{2, 4} + +see also, typesafe implementations: FilterInt_, FilterInt64_, FilterFloat32_, FilterFloat64_, FilterString_ + +.. _FilterFloat32: https://godoc.org/github.com/thoas/go-funk#FilterFloat32 +.. _FilterFloat64: https://godoc.org/github.com/thoas/go-funk#FilterFloat64 +.. _FilterInt: https://godoc.org/github.com/thoas/go-funk#FilterInt +.. _FilterInt64: https://godoc.org/github.com/thoas/go-funk#FilterInt64 +.. _FilterString: https://godoc.org/github.com/thoas/go-funk#FilterString + +funk.Reduce +........... + +Reduces an iteratee based on an accumulator function or operation rune for numbers. + +.. code-block:: go + + // Using operation runes. '+' and '*' only supported. + r := funk.Reduce([]int{1, 2, 3, 4}, '+', float64(0)) // 10 + r := funk.Reduce([]int{1, 2, 3, 4}, '*', 1) // 24 + + // Using accumulator function + r := funk.Reduce([]int{1, 2, 3, 4}, func(acc float64, num int) float64 { + return acc + float64(num) + }, float64(0)) // 10 + + r := funk.Reduce([]int{1, 2, 3, 4}, func(acc string, num int) string { + return acc + fmt.Sprint(num) + }, "") // "1234" + +funk.Find +......... + +Finds an element in a slice based on a predicate. + +.. code-block:: go + + r := funk.Find([]int{1, 2, 3, 4}, func(x int) bool { + return x%2 == 0 + }) // 2 + +see also, typesafe implementations: FindInt_, FindInt64_, FindFloat32_, FindFloat64_, FindString_ + +.. _FindFloat32: https://godoc.org/github.com/thoas/go-funk#FindFloat32 +.. _FindFloat64: https://godoc.org/github.com/thoas/go-funk#FindFloat64 +.. _FindInt: https://godoc.org/github.com/thoas/go-funk#FindInt +.. _FindInt64: https://godoc.org/github.com/thoas/go-funk#FindInt64 +.. _FindString: https://godoc.org/github.com/thoas/go-funk#FindString + +funk.Map +........ + +Manipulates an iteratee (map, slice) and transforms it to another type: + +* map -> slice +* map -> map +* slice -> map +* slice -> slice + +.. code-block:: go + + r := funk.Map([]int{1, 2, 3, 4}, func(x int) int { + return x * 2 + }) // []int{2, 4, 6, 8} + + r := funk.Map([]int{1, 2, 3, 4}, func(x int) string { + return "Hello" + }) // []string{"Hello", "Hello", "Hello", "Hello"} + + r = funk.Map([]int{1, 2, 3, 4}, func(x int) (int, int) { + return x, x + }) // map[int]int{1: 1, 2: 2, 3: 3, 4: 4} + + mapping := map[int]string{ + 1: "Florent", + 2: "Gilles", + } + + r = funk.Map(mapping, func(k int, v string) int { + return k + }) // []int{1, 2} + + r = funk.Map(mapping, func(k int, v string) (string, string) { + return fmt.Sprintf("%d", k), v + }) // map[string]string{"1": "Florent", "2": "Gilles"} + +funk.FlatMap +............ + +Manipulates an iteratee (map, slice) and transforms it to to a flattened collection of another type: + +* map -> slice +* slice -> slice + +.. code-block:: go + + r := funk.FlatMap([][]int{{1, 2}, {3, 4}}, func(x []int) []int { + return append(x, 0) + }) // []int{1, 2, 0, 3, 4, 0} + + mapping := map[string][]int{ + "Florent": {1, 2}, + "Gilles": {3, 4}, + } + + r = funk.FlatMap(mapping, func(k string, v []int) []int { + return v + }) // []int{1, 2, 3, 4} + +funk.Get +........ + +Retrieves the value at path of struct(s) or map(s). + +.. code-block:: go + + var bar *Bar = &Bar{ + Name: "Test", + Bars: []*Bar{ + &Bar{ + Name: "Level1-1", + Bar: &Bar{ + Name: "Level2-1", + }, + }, + &Bar{ + Name: "Level1-2", + Bar: &Bar{ + Name: "Level2-2", + }, + }, + }, + } + + var foo *Foo = &Foo{ + ID: 1, + FirstName: "Dark", + LastName: "Vador", + Age: 30, + Bar: bar, + Bars: []*Bar{ + bar, + bar, + }, + } + + funk.Get([]*Foo{foo}, "Bar.Bars.Bar.Name") // []string{"Level2-1", "Level2-2"} + funk.Get(foo, "Bar.Bars.Bar.Name") // []string{"Level2-1", "Level2-2"} + funk.Get(foo, "Bar.Name") // Test + +``funk.Get`` also support ``map`` values: + +.. code-block:: go + + bar := map[string]interface{}{ + "Name": "Test", + } + + foo1 := map[string]interface{}{ + "ID": 1, + "FirstName": "Dark", + "LastName": "Vador", + "Age": 30, + "Bar": bar, + } + + foo2 := &map[string]interface{}{ + "ID": 1, + "FirstName": "Dark", + "LastName": "Vador", + "Age": 30, + "Labels": map[string]interface{} { + "example.com/hello": "world", + }, + } // foo2.Bar is nil + + funk.Get(bar, "Name") // "Test" + funk.Get([]map[string]interface{}{foo1, foo2}, "Bar.Name") // []string{"Test"} + funk.Get(foo2, "Bar.Name") // nil + funk.Get(foo2, `Labels."example.com/hello"`) // world + + +``funk.Get`` also handles ``nil`` values: + +.. code-block:: go + + bar := &Bar{ + Name: "Test", + } + + foo1 := &Foo{ + ID: 1, + FirstName: "Dark", + LastName: "Vador", + Age: 30, + Bar: bar, + } + + foo2 := &Foo{ + ID: 1, + FirstName: "Dark", + LastName: "Vador", + Age: 30, + } // foo2.Bar is nil + + funk.Get([]*Foo{foo1, foo2}, "Bar.Name") // []string{"Test"} + funk.Get(foo2, "Bar.Name") // nil + + + +funk.GetOrElse +.............. + +Retrieves the value of the pointer or default. + +.. code-block:: go + + str := "hello world" + GetOrElse(&str, "foobar") // string{"hello world"} + GetOrElse(str, "foobar") // string{"hello world"} + GetOrElse(nil, "foobar") // string{"foobar"} + +funk.Set +........ +Set value at a path of a struct + +.. code-block:: go + + var bar Bar = Bar{ + Name: "level-0", + Bar: &Bar{ + Name: "level-1", + Bars: []*Bar{ + {Name: "level2-1"}, + {Name: "level2-2"}, + }, + }, + } + + _ = Set(&bar, "level-0-new", "Name") + fmt.Println(bar.Name) // "level-0-new" + + MustSet(&bar, "level-1-new", "Bar.Name") + fmt.Println(bar.Bar.Name) // "level-1-new" + + Set(&bar, "level-2-new", "Bar.Bars.Name") + fmt.Println(bar.Bar.Bars[0].Name) // "level-2-new" + fmt.Println(bar.Bar.Bars[1].Name) // "level-2-new" + +funk.MustSet +............ +Short hand for funk.Set if struct does not contain interface{} field type to discard errors. + +funk.Prune +.......... +Copy a struct with only selected fields. Slice is handled by pruning all elements. + +.. code-block:: go + + bar := &Bar{ + Name: "Test", + } + + foo1 := &Foo{ + ID: 1, + FirstName: "Dark", + LastName: "Vador", + Bar: bar, + } + + pruned, _ := Prune(foo1, []string{"FirstName", "Bar.Name"}) + // *Foo{ + // ID: 0, + // FirstName: "Dark", + // LastName: "", + // Bar: &Bar{Name: "Test}, + // } + +funk.PruneByTag +.......... +Same functionality as funk.Prune, but uses struct tags instead of struct field names. + +funk.Keys +......... + +Creates an array of the own enumerable map keys or struct field names. + +.. code-block:: go + + funk.Keys(map[string]int{"one": 1, "two": 2}) // []string{"one", "two"} (iteration order is not guaranteed) + + foo := &Foo{ + ID: 1, + FirstName: "Dark", + LastName: "Vador", + Age: 30, + } + + funk.Keys(foo) // []string{"ID", "FirstName", "LastName", "Age"} (iteration order is not guaranteed) + +funk.Values +........... + +Creates an array of the own enumerable map values or struct field values. + +.. code-block:: go + + funk.Values(map[string]int{"one": 1, "two": 2}) // []int{1, 2} (iteration order is not guaranteed) + + foo := &Foo{ + ID: 1, + FirstName: "Dark", + LastName: "Vador", + Age: 30, + } + + funk.Values(foo) // []interface{}{1, "Dark", "Vador", 30} (iteration order is not guaranteed) + +funk.ForEach +............ + +Range over an iteratee (map, slice). + +Or update element in slice(Not map, reflect#Value#MapIndex#CanSet is false). + +.. code-block:: go + + funk.ForEach([]int{1, 2, 3, 4}, func(x int) { + fmt.Println(x) + }) + + foo := []int{1,2,3} + funk.ForEach(foo, func(x *int){ *x = *x * 2}) + fmt.Println(foo) // []int{2, 4, 6} + +funk.ForEachRight +............ + +Range over an iteratee (map, slice) from the right. + +.. code-block:: go + + results := []int{} + + funk.ForEachRight([]int{1, 2, 3, 4}, func(x int) { + results = append(results, x) + }) + + fmt.Println(results) // []int{4, 3, 2, 1} + +funk.Chunk +.......... + +Creates an array of elements split into groups with the length of the size. +If array can't be split evenly, the final chunk will be the remaining element. + +.. code-block:: go + + funk.Chunk([]int{1, 2, 3, 4, 5}, 2) // [][]int{[]int{1, 2}, []int{3, 4}, []int{5}} + +funk.FlattenDeep +................ + +Recursively flattens an array. + +.. code-block:: go + + funk.FlattenDeep([][]int{[]int{1, 2}, []int{3, 4}}) // []int{1, 2, 3, 4} + +funk.Uniq +......... + +Creates an array with unique values. + +.. code-block:: go + + funk.Uniq([]int{0, 1, 1, 2, 3, 0, 0, 12}) // []int{0, 1, 2, 3, 12} + +see also, typesafe implementations: UniqInt_, UniqInt64_, UniqFloat32_, UniqFloat64_, UniqString_ + +.. _UniqFloat32: https://godoc.org/github.com/thoas/go-funk#UniqFloat32 +.. _UniqFloat64: https://godoc.org/github.com/thoas/go-funk#UniqFloat64 +.. _UniqInt: https://godoc.org/github.com/thoas/go-funk#UniqInt +.. _UniqInt64: https://godoc.org/github.com/thoas/go-funk#UniqInt64 +.. _UniqString: https://godoc.org/github.com/thoas/go-funk#UniqString + +funk.UniqBy +......... + +Creates an array with unique values returned by a callback. + +.. code-block:: go + + funk.UniqBy([]int{0, 1, 1, 2, 3, 0, 0, 12}, func(nbr int) int { + return nbr % 3 + }) // []int{0, 1, 2} + + foo1 := Foo{ + ID: 42, + FirstName: "Bob", + } + foo2 := Foo{ + ID: 42, + FirstName: "Bob", + } + funk.UniqBy([]Foo{foo1, foo2}, func(f Foo) int { + return f.ID + }) // []Foo{ Foo{ID: 42, Firstname: "Bob"} } + +funk.Drop +......... + +Creates an array/slice with `n` elements dropped from the beginning. + +.. code-block:: go + + funk.Drop([]int{0, 0, 0, 0}, 3) // []int{0} + +see also, typesafe implementations: DropInt_, DropInt32_, DropInt64_, DropFloat32_, DropFloat64_, DropString_ + +.. _DropInt: https://godoc.org/github.com/thoas/go-funk#DropInt +.. _DropInt32: https://godoc.org/github.com/thoas/go-funk#DropInt64 +.. _DropInt64: https://godoc.org/github.com/thoas/go-funk#DropInt64 +.. _DropFloat32: https://godoc.org/github.com/thoas/go-funk#DropFloat32 +.. _DropFloat64: https://godoc.org/github.com/thoas/go-funk#DropFloat64 +.. _DropString: https://godoc.org/github.com/thoas/go-funk#DropString + +funk.Initial +............ + +Gets all but the last element of array. + +.. code-block:: go + + funk.Initial([]int{0, 1, 2, 3, 4}) // []int{0, 1, 2, 3} + +funk.Tail +......... + +Gets all but the first element of array. + +.. code-block:: go + + funk.Tail([]int{0, 1, 2, 3, 4}) // []int{1, 2, 3, 4} + +funk.Shuffle +............ + +Creates an array of shuffled values. + +.. code-block:: go + + funk.Shuffle([]int{0, 1, 2, 3, 4}) // []int{2, 1, 3, 4, 0} + + +see also, typesafe implementations: ShuffleInt_, ShuffleInt64_, ShuffleFloat32_, ShuffleFloat64_, ShuffleString_ + +.. _ShuffleFloat32: https://godoc.org/github.com/thoas/go-funk#ShuffleFloat32 +.. _ShuffleFloat64: https://godoc.org/github.com/thoas/go-funk#ShuffleFloat64 +.. _ShuffleInt: https://godoc.org/github.com/thoas/go-funk#ShuffleInt +.. _ShuffleInt64: https://godoc.org/github.com/thoas/go-funk#ShuffleInt64 +.. _ShuffleString: https://godoc.org/github.com/thoas/go-funk#ShuffleString + +funk.Subtract +............. + +Returns the subtraction between two collections. It preserve order. + +.. code-block:: go + + funk.Subtract([]int{0, 1, 2, 3, 4}, []int{0, 4}) // []int{1, 2, 3} + funk.Subtract([]int{0, 3, 2, 3, 4}, []int{0, 4}) // []int{3, 2, 3} + + +see also, typesafe implementations: SubtractString_ + +.. SubtractString: https://godoc.org/github.com/thoas/go-funk#SubtractString + +funk.Sum +........ + +Computes the sum of the values in an array. + +.. code-block:: go + + funk.Sum([]int{0, 1, 2, 3, 4}) // 10.0 + funk.Sum([]interface{}{0.5, 1, 2, 3, 4}) // 10.5 + +see also, typesafe implementations: SumInt_, SumInt64_, SumFloat32_, SumFloat64_ + +.. _SumFloat32: https://godoc.org/github.com/thoas/go-funk#SumFloat32 +.. _SumFloat64: https://godoc.org/github.com/thoas/go-funk#SumFloat64 +.. _SumInt: https://godoc.org/github.com/thoas/go-funk#SumInt +.. _SumInt64: https://godoc.org/github.com/thoas/go-funk#SumInt64 + +funk.Reverse +............ + +Transforms an array such that the first element will become the last, the second element +will become the second to last, etc. + +.. code-block:: go + + funk.Reverse([]int{0, 1, 2, 3, 4}) // []int{4, 3, 2, 1, 0} + +see also, typesafe implementations: ReverseInt_, ReverseInt64_, ReverseFloat32_, ReverseFloat64_, ReverseString_, ReverseStrings_ + +.. _ReverseFloat32: https://godoc.org/github.com/thoas/go-funk#ReverseFloat32 +.. _ReverseFloat64: https://godoc.org/github.com/thoas/go-funk#ReverseFloat64 +.. _ReverseInt: https://godoc.org/github.com/thoas/go-funk#ReverseInt +.. _ReverseInt64: https://godoc.org/github.com/thoas/go-funk#ReverseInt64 +.. _ReverseString: https://godoc.org/github.com/thoas/go-funk#ReverseString +.. _ReverseStrings: https://godoc.org/github.com/thoas/go-funk#ReverseStrings + +funk.SliceOf +............ + +Returns a slice based on an element. + +.. code-block:: go + + funk.SliceOf(f) // will return a []*Foo{f} + +funk.RandomInt +.............. + +Generates a random int, based on a min and max values. + +.. code-block:: go + + funk.RandomInt(0, 100) // will be between 0 and 100 + +funk.RandomString +................. + +Generates a random string with a fixed length. + +.. code-block:: go + + funk.RandomString(4) // will be a string of 4 random characters + +funk.Shard +.......... + +Generates a sharded string with a fixed length and depth. + +.. code-block:: go + + funk.Shard("e89d66bdfdd4dd26b682cc77e23a86eb", 1, 2, false) // []string{"e", "8", "e89d66bdfdd4dd26b682cc77e23a86eb"} + + funk.Shard("e89d66bdfdd4dd26b682cc77e23a86eb", 2, 2, false) // []string{"e8", "9d", "e89d66bdfdd4dd26b682cc77e23a86eb"} + + funk.Shard("e89d66bdfdd4dd26b682cc77e23a86eb", 2, 3, true) // []string{"e8", "9d", "66", "bdfdd4dd26b682cc77e23a86eb"} + +funk.Subset +............. + +Returns true if a collection is a subset of another + +.. code-block:: go + + funk.Subset([]int{1, 2, 4}, []int{1, 2, 3, 4, 5}) // true + funk.Subset([]string{"foo", "bar"},[]string{"foo", "bar", "hello", "bar", "hi"}) //true + + +Performance +----------- + +``go-funk`` currently has an open issue about performance_, don't hesitate to participate in the discussion +to enhance the generic helpers implementations. + +Let's stop beating around the bush, a typesafe implementation in pure Go of ``funk.Contains``, let's say for example: + +.. code-block:: go + + func ContainsInt(s []int, e int) bool { + for _, a := range s { + if a == e { + return true + } + } + return false + } + +will always outperform an implementation based on reflect_ in terms of speed and allocs because of +how it's implemented in the language. + +If you want a similarity, gorm_ will always be slower than sqlx_ (which is very low level btw) and will use more allocs. + +You must not think generic helpers of ``go-funk`` as a replacement when you are dealing with performance in your codebase, +you should use typesafe implementations instead. + +Contributing +------------ + +* Ping me on twitter `@thoas `_ (DMs, mentions, whatever :)) +* Fork the `project `_ +* Fix `open issues `_ or request new features + +Don't hesitate ;) + +Authors +------- + +* Florent Messa +* Gilles Fabio +* Alexey Pokhozhaev +* Alexandre Nicolaie + +.. _reflect: https://golang.org/pkg/reflect/ +.. _lodash: https://lodash.com/ +.. _performance: https://github.com/thoas/go-funk/issues/19 +.. _gorm: https://github.com/jinzhu/gorm +.. _sqlx: https://github.com/jmoiron/sqlx +.. _godoc: https://godoc.org/github.com/thoas/go-funk diff --git a/vendor/github.com/thoas/go-funk/assign.go b/vendor/github.com/thoas/go-funk/assign.go new file mode 100644 index 00000000000..a0da834e81e --- /dev/null +++ b/vendor/github.com/thoas/go-funk/assign.go @@ -0,0 +1,129 @@ +package funk + +import ( + "errors" + "fmt" + "reflect" + "strings" +) + +// Set assigns in at path with value val. i.e. in.path = val +// in accepts types of ptr to struct, ptr to variable, slice and ptr to slice. +// Along the path, interface{} is supported and nil ptr is initialized to ptr to zero value +// of the type until the variable to be set is obtained. +// It returns errors when encountering along the path unknown types, uninitialized +// interface{} or interface{} containing struct directly (not ptr to struct). +// +// Slice is resolved the same way in funk.Get(), by traversing each element of the slice, +// so that each element of the slice's corresponding field are going to be set to the same provided val. +// If Set is called on slice with empty path "", it behaves the same as funk.Fill() +// +// If in is well formed, i.e. do not expect above descripted errors to happen, funk.MustSet() +// is a short hand wrapper to discard error return +func Set(in interface{}, val interface{}, path string) error { + if in == nil { + return errors.New("Cannot Set nil") + } + parts := []string{} + if path != "" { + parts = strings.Split(path, ".") + } + return setByParts(in, val, parts) +} + +// we need this layer to handle interface{} type +func setByParts(in interface{}, val interface{}, parts []string) error { + + if in == nil { + // nil interface can happen during traversing the path + return errors.New("Cannot traverse nil/uninitialized interface{}") + } + + inValue := reflect.ValueOf(in) + inKind := inValue.Type().Kind() + + // Note: if interface contains a struct (not ptr to struct) then the content of the struct cannot be set. + // I.e. it is not CanAddr() or CanSet() + // So we require in interface{} to be a ptr, slice or array + if inKind == reflect.Ptr { + inValue = inValue.Elem() // if it is ptr we set its content not ptr its self + } else if inKind != reflect.Array && inKind != reflect.Slice { + return fmt.Errorf("Type %s not supported by Set", inValue.Type().String()) + } + + return set(inValue, reflect.ValueOf(val), parts) +} + +// traverse inValue using path in parts and set the dst to be setValue +func set(inValue reflect.Value, setValue reflect.Value, parts []string) error { + + // traverse the path to get the inValue we need to set + i := 0 + for i < len(parts) { + + kind := inValue.Kind() + + switch kind { + case reflect.Invalid: + // do not expect this case to happen + return errors.New("nil pointer found along the path") + case reflect.Struct: + fValue := inValue.FieldByName(parts[i]) + if !fValue.IsValid() { + return fmt.Errorf("field name %v is not found in struct %v", parts[i], inValue.Type().String()) + } + if !fValue.CanSet() { + return fmt.Errorf("field name %v is not exported in struct %v", parts[i], inValue.Type().String()) + } + inValue = fValue + i++ + case reflect.Slice, reflect.Array: + // set all its elements + length := inValue.Len() + for j := 0; j < length; j++ { + err := set(inValue.Index(j), setValue, parts[i:]) + if err != nil { + return err + } + } + return nil + case reflect.Ptr: + // only traverse down one level + if inValue.IsNil() { + // we initialize nil ptr to ptr to zero value of the type + // and continue traversing + inValue.Set(reflect.New(inValue.Type().Elem())) + } + // traverse the ptr until it is not pointer any more or is nil again + inValue = redirectValue(inValue) + case reflect.Interface: + // Note: if interface contains a struct (not ptr to struct) then the content of the struct cannot be set. + // I.e. it is not CanAddr() or CanSet(). This is why setByParts has a nil ptr check. + // we treat this as a new call to setByParts, and it will do proper check of the types + return setByParts(inValue.Interface(), setValue.Interface(), parts[i:]) + default: + return fmt.Errorf("kind %v in path %v is not supported", kind, parts[i]) + } + + } + // here inValue holds the value we need to set + + // interface{} can be set to any val + // other types we ensure the type matches + if inValue.Kind() != setValue.Kind() && inValue.Kind() != reflect.Interface { + return fmt.Errorf("cannot set target of type %v with type %v", inValue.Kind(), setValue.Kind()) + } + inValue.Set(setValue) + + return nil +} + +// MustSet is functionally the same as Set. +// It panics instead of returning error. +// It is safe to use if the in value is well formed. +func MustSet(in interface{}, val interface{}, path string) { + err := Set(in, val, path) + if err != nil { + panic(err) + } +} diff --git a/vendor/github.com/thoas/go-funk/builder.go b/vendor/github.com/thoas/go-funk/builder.go new file mode 100644 index 00000000000..6dfc814d732 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/builder.go @@ -0,0 +1,110 @@ +package funk + +import ( + "fmt" + "reflect" +) + +// Builder contains all tools which can be chained. +type Builder interface { + Chunk(size int) Builder + Compact() Builder + Drop(n int) Builder + Filter(predicate interface{}) Builder + Flatten() Builder + FlattenDeep() Builder + Initial() Builder + Intersect(y interface{}) Builder + Join(rarr interface{}, fnc JoinFnc) Builder + Map(mapFunc interface{}) Builder + FlatMap(mapFunc interface{}) Builder + Reverse() Builder + Shuffle() Builder + Tail() Builder + Uniq() Builder + Without(values ...interface{}) Builder + + All() bool + Any() bool + Contains(elem interface{}) bool + Every(elements ...interface{}) bool + Find(predicate interface{}) interface{} + ForEach(predicate interface{}) + ForEachRight(predicate interface{}) + Head() interface{} + Keys() interface{} + IndexOf(elem interface{}) int + IsEmpty() bool + Last() interface{} + LastIndexOf(elem interface{}) int + NotEmpty() bool + Product() float64 + Reduce(reduceFunc, acc interface{}) interface{} + Sum() float64 + Type() reflect.Type + Value() interface{} + Values() interface{} +} + +// Chain creates a simple new go-funk.Builder from a collection. Each method +// call generate a new builder containing the previous result. +func Chain(v interface{}) Builder { + isNotNil(v, "Chain") + + valueType := reflect.TypeOf(v) + if isValidBuilderEntry(valueType) || + (valueType.Kind() == reflect.Ptr && isValidBuilderEntry(valueType.Elem())) { + return &chainBuilder{v} + } + + panic(fmt.Sprintf("Type %s is not supported by Chain", valueType.String())) +} + +// LazyChain creates a lazy go-funk.Builder from a collection. Each method call +// generate a new builder containing a method generating the previous value. +// With that, all data are only generated when we call a tailling method like All or Find. +func LazyChain(v interface{}) Builder { + isNotNil(v, "LazyChain") + + valueType := reflect.TypeOf(v) + if isValidBuilderEntry(valueType) || + (valueType.Kind() == reflect.Ptr && isValidBuilderEntry(valueType.Elem())) { + return &lazyBuilder{func() interface{} { return v }} + } + + panic(fmt.Sprintf("Type %s is not supported by LazyChain", valueType.String())) + +} + +// LazyChainWith creates a lazy go-funk.Builder from a generator. Like LazyChain, each +// method call generate a new builder containing a method generating the previous value. +// But, instead of using a collection, it takes a generator which can generate values. +// With LazyChainWith, to can create a generic pipeline of collection transformation and, +// throw the generator, sending different collection. +func LazyChainWith(generator func() interface{}) Builder { + isNotNil(generator, "LazyChainWith") + return &lazyBuilder{func() interface{} { + isNotNil(generator, "LazyChainWith") + + v := generator() + valueType := reflect.TypeOf(v) + if isValidBuilderEntry(valueType) || + (valueType.Kind() == reflect.Ptr && isValidBuilderEntry(valueType.Elem())) { + return v + } + + panic(fmt.Sprintf("Type %s is not supported by LazyChainWith generator", valueType.String())) + }} +} + +func isNotNil(v interface{}, from string) { + if v == nil { + panic(fmt.Sprintf("nil value is not supported by %s", from)) + } +} + +func isValidBuilderEntry(valueType reflect.Type) bool { + return valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Array || + valueType.Kind() == reflect.Map || + valueType.Kind() == reflect.String +} diff --git a/vendor/github.com/thoas/go-funk/chain_builder.go b/vendor/github.com/thoas/go-funk/chain_builder.go new file mode 100644 index 00000000000..18226ab573c --- /dev/null +++ b/vendor/github.com/thoas/go-funk/chain_builder.go @@ -0,0 +1,142 @@ +package funk + +import ( + "fmt" + "reflect" +) + +type chainBuilder struct { + collection interface{} +} + +func (b *chainBuilder) Chunk(size int) Builder { + return &chainBuilder{Chunk(b.collection, size)} +} +func (b *chainBuilder) Compact() Builder { + return &chainBuilder{Compact(b.collection)} +} +func (b *chainBuilder) Drop(n int) Builder { + return &chainBuilder{Drop(b.collection, n)} +} +func (b *chainBuilder) Filter(predicate interface{}) Builder { + return &chainBuilder{Filter(b.collection, predicate)} +} +func (b *chainBuilder) Flatten() Builder { + return &chainBuilder{Flatten(b.collection)} +} +func (b *chainBuilder) FlattenDeep() Builder { + return &chainBuilder{FlattenDeep(b.collection)} +} +func (b *chainBuilder) Initial() Builder { + return &chainBuilder{Initial(b.collection)} +} +func (b *chainBuilder) Intersect(y interface{}) Builder { + return &chainBuilder{Intersect(b.collection, y)} +} +func (b *chainBuilder) Join(rarr interface{}, fnc JoinFnc) Builder { + return &chainBuilder{Join(b.collection, rarr, fnc)} +} +func (b *chainBuilder) Map(mapFunc interface{}) Builder { + return &chainBuilder{Map(b.collection, mapFunc)} +} +func (b *chainBuilder) FlatMap(mapFunc interface{}) Builder { + return &chainBuilder{FlatMap(b.collection, mapFunc)} +} +func (b *chainBuilder) Reverse() Builder { + return &chainBuilder{Reverse(b.collection)} +} +func (b *chainBuilder) Shuffle() Builder { + return &chainBuilder{Shuffle(b.collection)} +} +func (b *chainBuilder) Tail() Builder { + return &chainBuilder{Tail(b.collection)} +} +func (b *chainBuilder) Uniq() Builder { + return &chainBuilder{Uniq(b.collection)} +} +func (b *chainBuilder) Without(values ...interface{}) Builder { + return &chainBuilder{Without(b.collection, values...)} +} + +func (b *chainBuilder) All() bool { + v := reflect.ValueOf(b.collection) + t := v.Type() + + if t.Kind() != reflect.Array && t.Kind() != reflect.Slice { + panic(fmt.Sprintf("Type %s is not supported by Chain.All", t.String())) + } + + c := make([]interface{}, v.Len()) + for i := 0; i < v.Len(); i++ { + c[i] = v.Index(i).Interface() + } + return All(c...) +} +func (b *chainBuilder) Any() bool { + v := reflect.ValueOf(b.collection) + t := v.Type() + + if t.Kind() != reflect.Array && t.Kind() != reflect.Slice { + panic(fmt.Sprintf("Type %s is not supported by Chain.Any", t.String())) + } + + c := make([]interface{}, v.Len()) + for i := 0; i < v.Len(); i++ { + c[i] = v.Index(i).Interface() + } + return Any(c...) +} +func (b *chainBuilder) Contains(elem interface{}) bool { + return Contains(b.collection, elem) +} +func (b *chainBuilder) Every(elements ...interface{}) bool { + return Every(b.collection, elements...) +} +func (b *chainBuilder) Find(predicate interface{}) interface{} { + return Find(b.collection, predicate) +} +func (b *chainBuilder) ForEach(predicate interface{}) { + ForEach(b.collection, predicate) +} +func (b *chainBuilder) ForEachRight(predicate interface{}) { + ForEachRight(b.collection, predicate) +} +func (b *chainBuilder) Head() interface{} { + return Head(b.collection) +} +func (b *chainBuilder) Keys() interface{} { + return Keys(b.collection) +} +func (b *chainBuilder) IndexOf(elem interface{}) int { + return IndexOf(b.collection, elem) +} +func (b *chainBuilder) IsEmpty() bool { + return IsEmpty(b.collection) +} +func (b *chainBuilder) Last() interface{} { + return Last(b.collection) +} +func (b *chainBuilder) LastIndexOf(elem interface{}) int { + return LastIndexOf(b.collection, elem) +} +func (b *chainBuilder) NotEmpty() bool { + return NotEmpty(b.collection) +} +func (b *chainBuilder) Product() float64 { + return Product(b.collection) +} +func (b *chainBuilder) Reduce(reduceFunc, acc interface{}) interface{} { + return Reduce(b.collection, reduceFunc, acc) +} +func (b *chainBuilder) Sum() float64 { + return Sum(b.collection) +} +func (b *chainBuilder) Type() reflect.Type { + return reflect.TypeOf(b.collection) +} +func (b *chainBuilder) Value() interface{} { + return b.collection +} +func (b *chainBuilder) Values() interface{} { + return Values(b.collection) +} diff --git a/vendor/github.com/thoas/go-funk/compact.go b/vendor/github.com/thoas/go-funk/compact.go new file mode 100644 index 00000000000..ba151aa9c25 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/compact.go @@ -0,0 +1,50 @@ +package funk + +import ( + "reflect" +) + +// Compact creates a slice with all empty/zero values removed. +func Compact(value interface{}) interface{} { + arr := redirectValue(reflect.ValueOf(value)) + + if arr.Kind() != reflect.Slice && arr.Kind() != reflect.Array { + panic("First parameter must be array or slice") + } + + sliceElemType := sliceElem(arr.Type()) + resultSliceType := reflect.SliceOf(sliceElemType) + result := reflect.MakeSlice(resultSliceType, 0, 0) + + for i := 0; i < arr.Len(); i++ { + elemVal := arr.Index(i) + + if elemVal.Kind() == reflect.Interface { + elemVal = elemVal.Elem() + } + + redirectedElemVal := redirectValue(elemVal) + + switch redirectedElemVal.Kind() { + case reflect.Invalid: + continue + case reflect.Func: + if redirectedElemVal.IsNil() { + continue + } + case reflect.Map, reflect.Slice, reflect.Chan: + if redirectedElemVal.Len() == 0 { + continue + } + default: + defaultValue := reflect.Zero(redirectedElemVal.Type()).Interface() + if redirectedElemVal.Interface() == defaultValue { + continue + } + } + + result = reflect.Append(result, elemVal) + } + + return result.Interface() +} diff --git a/vendor/github.com/thoas/go-funk/fill.go b/vendor/github.com/thoas/go-funk/fill.go new file mode 100644 index 00000000000..6af5cfa77fc --- /dev/null +++ b/vendor/github.com/thoas/go-funk/fill.go @@ -0,0 +1,34 @@ +package funk + +import ( + "errors" + "fmt" + "reflect" +) + +// Fill fills elements of array with value +func Fill(in interface{}, fillValue interface{}) (interface{}, error) { + inValue := reflect.ValueOf(in) + inKind := inValue.Type().Kind() + if inKind != reflect.Slice && inKind != reflect.Array { + return nil, errors.New("Can only fill slices and arrays") + } + + inType := reflect.TypeOf(in).Elem() + value := reflect.ValueOf(fillValue) + if inType != value.Type() { + return nil, fmt.Errorf( + "Cannot fill '%s' with '%s'", reflect.TypeOf(in), value.Type(), + ) + } + + length := inValue.Len() + newSlice := reflect.SliceOf(reflect.TypeOf(fillValue)) + in = reflect.MakeSlice(newSlice, length, length).Interface() + inValue = reflect.ValueOf(in) + + for i := 0; i < length; i++ { + inValue.Index(i).Set(value) + } + return in, nil +} diff --git a/vendor/github.com/thoas/go-funk/helpers.go b/vendor/github.com/thoas/go-funk/helpers.go new file mode 100644 index 00000000000..da3f032a5d4 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/helpers.go @@ -0,0 +1,317 @@ +package funk + +import ( + "bytes" + "math/rand" + "reflect" +) + +var numericZeros = []interface{}{ + int(0), + int8(0), + int16(0), + int32(0), + int64(0), + uint(0), + uint8(0), + uint16(0), + uint32(0), + uint64(0), + float32(0), + float64(0), +} + +// ToFloat64 converts any numeric value to float64. +func ToFloat64(x interface{}) (float64, bool) { + var xf float64 + xok := true + + switch xn := x.(type) { + case uint8: + xf = float64(xn) + case uint16: + xf = float64(xn) + case uint32: + xf = float64(xn) + case uint64: + xf = float64(xn) + case int: + xf = float64(xn) + case int8: + xf = float64(xn) + case int16: + xf = float64(xn) + case int32: + xf = float64(xn) + case int64: + xf = float64(xn) + case float32: + xf = float64(xn) + case float64: + xf = float64(xn) + default: + xok = false + } + + return xf, xok +} + +// PtrOf makes a copy of the given interface and returns a pointer. +func PtrOf(itf interface{}) interface{} { + t := reflect.TypeOf(itf) + + cp := reflect.New(t) + cp.Elem().Set(reflect.ValueOf(itf)) + + // Avoid double pointers if itf is a pointer + if t.Kind() == reflect.Ptr { + return cp.Elem().Interface() + } + + return cp.Interface() +} + +// IsFunction returns if the argument is a function. +func IsFunction(in interface{}, num ...int) bool { + funcType := reflect.TypeOf(in) + + result := funcType != nil && funcType.Kind() == reflect.Func + + if len(num) >= 1 { + result = result && funcType.NumIn() == num[0] + } + + if len(num) == 2 { + result = result && funcType.NumOut() == num[1] + } + + return result +} + +// IsPredicate returns if the argument is a predicate function. +func IsPredicate(in interface{}, inTypes ...reflect.Type) bool { + if len(inTypes) == 0 { + inTypes = append(inTypes, nil) + } + + funcType := reflect.TypeOf(in) + + result := funcType != nil && funcType.Kind() == reflect.Func + + result = result && funcType.NumOut() == 1 && funcType.Out(0).Kind() == reflect.Bool + result = result && funcType.NumIn() == len(inTypes) + + for i := 0; result && i < len(inTypes); i++ { + inType := inTypes[i] + result = inType == nil || inType.ConvertibleTo(funcType.In(i)) + } + + return result +} + +// IsEqual returns if the two objects are equal +func IsEqual(expected interface{}, actual interface{}) bool { + if expected == nil || actual == nil { + return expected == actual + } + + if exp, ok := expected.([]byte); ok { + act, ok := actual.([]byte) + if !ok { + return false + } + + if exp == nil || act == nil { + return true + } + + return bytes.Equal(exp, act) + } + + return reflect.DeepEqual(expected, actual) + +} + +// IsType returns if the two objects are in the same type +func IsType(expected interface{}, actual interface{}) bool { + return IsEqual(reflect.TypeOf(expected), reflect.TypeOf(actual)) +} + +// Equal returns if the two objects are equal +func Equal(expected interface{}, actual interface{}) bool { + return IsEqual(expected, actual) +} + +// NotEqual returns if the two objects are not equal +func NotEqual(expected interface{}, actual interface{}) bool { + return !IsEqual(expected, actual) +} + +// IsIteratee returns if the argument is an iteratee. +func IsIteratee(in interface{}) bool { + if in == nil { + return false + } + arrType := reflect.TypeOf(in) + + kind := arrType.Kind() + + return kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map +} + +// IsCollection returns if the argument is a collection. +func IsCollection(in interface{}) bool { + arrType := reflect.TypeOf(in) + + kind := arrType.Kind() + + return kind == reflect.Array || kind == reflect.Slice +} + +// SliceOf returns a slice which contains the element. +func SliceOf(in interface{}) interface{} { + value := reflect.ValueOf(in) + + sliceType := reflect.SliceOf(reflect.TypeOf(in)) + slice := reflect.New(sliceType) + sliceValue := reflect.MakeSlice(sliceType, 0, 0) + sliceValue = reflect.Append(sliceValue, value) + slice.Elem().Set(sliceValue) + + return slice.Elem().Interface() +} + +// Any returns true if any element of the iterable is not empty. If the iterable is empty, return False. +func Any(objs ...interface{}) bool { + if len(objs) == 0 { + return false + } + + for _, obj := range objs { + if !IsEmpty(obj) { + return true + } + } + + return false +} + +// All returns true if all elements of the iterable are not empty (or if the iterable is empty) +func All(objs ...interface{}) bool { + if len(objs) == 0 { + return true + } + + for _, obj := range objs { + if IsEmpty(obj) { + return false + } + } + + return true +} + +// IsEmpty returns if the object is considered as empty or not. +func IsEmpty(obj interface{}) bool { + if obj == nil || obj == "" || obj == false { + return true + } + + for _, v := range numericZeros { + if obj == v { + return true + } + } + + objValue := reflect.ValueOf(obj) + + switch objValue.Kind() { + case reflect.Map: + fallthrough + case reflect.Slice, reflect.Chan: + return objValue.Len() == 0 + case reflect.Struct: + return reflect.DeepEqual(obj, ZeroOf(obj)) + case reflect.Ptr: + if objValue.IsNil() { + return true + } + + obj = redirectValue(objValue).Interface() + + return reflect.DeepEqual(obj, ZeroOf(obj)) + } + + return false +} + +// IsZero returns if the object is considered as zero value +func IsZero(obj interface{}) bool { + if obj == nil || obj == "" || obj == false { + return true + } + + for _, v := range numericZeros { + if obj == v { + return true + } + } + + return reflect.DeepEqual(obj, ZeroOf(obj)) +} + +// NotEmpty returns if the object is considered as non-empty or not. +func NotEmpty(obj interface{}) bool { + return !IsEmpty(obj) +} + +// ZeroOf returns a zero value of an element. +func ZeroOf(in interface{}) interface{} { + if in == nil { + return nil + } + + return reflect.Zero(reflect.TypeOf(in)).Interface() +} + +// RandomInt generates a random int, based on a min and max values +func RandomInt(min, max int) int { + return min + rand.Intn(max-min) +} + +// Shard will shard a string name +func Shard(str string, width int, depth int, restOnly bool) []string { + var results []string + + for i := 0; i < depth; i++ { + results = append(results, str[(width*i):(width*(i+1))]) + } + + if restOnly { + results = append(results, str[(width*depth):]) + } else { + results = append(results, str) + } + + return results +} + +var defaultLetters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + +// RandomString returns a random string with a fixed length +func RandomString(n int, allowedChars ...[]rune) string { + var letters []rune + + if len(allowedChars) == 0 { + letters = defaultLetters + } else { + letters = allowedChars[0] + } + + b := make([]rune, n) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + + return string(b) +} diff --git a/vendor/github.com/thoas/go-funk/intersection.go b/vendor/github.com/thoas/go-funk/intersection.go new file mode 100644 index 00000000000..6670ad2b697 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/intersection.go @@ -0,0 +1,282 @@ +package funk + +import ( + "reflect" +) + +// Intersect returns the intersection between two collections. +// +// Deprecated: use Join(x, y, InnerJoin) instead of Intersect, InnerJoin +// implements deduplication mechanism, so verify your code behaviour +// before using it +func Intersect(x interface{}, y interface{}) interface{} { + if !IsCollection(x) { + panic("First parameter must be a collection") + } + if !IsCollection(y) { + panic("Second parameter must be a collection") + } + + hash := map[interface{}]struct{}{} + + xValue := reflect.ValueOf(x) + xType := xValue.Type() + + yValue := reflect.ValueOf(y) + yType := yValue.Type() + + if NotEqual(xType, yType) { + panic("Parameters must have the same type") + } + + zType := reflect.SliceOf(xType.Elem()) + zSlice := reflect.MakeSlice(zType, 0, 0) + + for i := 0; i < xValue.Len(); i++ { + v := xValue.Index(i).Interface() + hash[v] = struct{}{} + } + + for i := 0; i < yValue.Len(); i++ { + v := yValue.Index(i).Interface() + _, ok := hash[v] + if ok { + zSlice = reflect.Append(zSlice, yValue.Index(i)) + } + } + + return zSlice.Interface() +} + +// IntersectString returns the intersection between two collections of string. +func IntersectString(x []string, y []string) []string { + if len(x) == 0 || len(y) == 0 { + return []string{} + } + + set := []string{} + hash := map[string]struct{}{} + + for _, v := range x { + hash[v] = struct{}{} + } + + for _, v := range y { + _, ok := hash[v] + if ok { + set = append(set, v) + } + } + + return set +} + +// Difference returns the difference between two collections. +func Difference(x interface{}, y interface{}) (interface{}, interface{}) { + if !IsIteratee(x) { + panic("First parameter must be an iteratee") + } + if !IsIteratee(y) { + panic("Second parameter must be an iteratee") + } + + xValue := reflect.ValueOf(x) + xType := xValue.Type() + + yValue := reflect.ValueOf(y) + yType := yValue.Type() + + if NotEqual(xType, yType) { + panic("Parameters must have the same type") + } + + if xType.Kind() == reflect.Map { + leftType := reflect.MapOf(xType.Key(), xType.Elem()) + rightType := reflect.MapOf(xType.Key(), xType.Elem()) + leftMap := reflect.MakeMap(leftType) + rightMap := reflect.MakeMap(rightType) + + xIter := xValue.MapRange() + for xIter.Next() { + k := xIter.Key() + xv := xIter.Value() + yv := yValue.MapIndex(k) + equalTo := equal(xv.Interface(), true) + if !yv.IsValid() || !equalTo(yv, yv) { + leftMap.SetMapIndex(k, xv) + } + } + + yIter := yValue.MapRange() + for yIter.Next() { + k := yIter.Key() + yv := yIter.Value() + xv := xValue.MapIndex(k) + equalTo := equal(yv.Interface(), true) + if !xv.IsValid() || !equalTo(xv, xv) { + rightMap.SetMapIndex(k, yv) + } + } + return leftMap.Interface(), rightMap.Interface() + } else { + leftType := reflect.SliceOf(xType.Elem()) + rightType := reflect.SliceOf(yType.Elem()) + leftSlice := reflect.MakeSlice(leftType, 0, 0) + rightSlice := reflect.MakeSlice(rightType, 0, 0) + + for i := 0; i < xValue.Len(); i++ { + v := xValue.Index(i).Interface() + if !Contains(y, v) { + leftSlice = reflect.Append(leftSlice, xValue.Index(i)) + } + } + + for i := 0; i < yValue.Len(); i++ { + v := yValue.Index(i).Interface() + if !Contains(x, v) { + rightSlice = reflect.Append(rightSlice, yValue.Index(i)) + } + } + return leftSlice.Interface(), rightSlice.Interface() + } +} + +// DifferenceString returns the difference between two collections of strings. +func DifferenceString(x []string, y []string) ([]string, []string) { + leftSlice := []string{} + rightSlice := []string{} + + for _, v := range x { + if !ContainsString(y, v) { + leftSlice = append(leftSlice, v) + } + } + + for _, v := range y { + if !ContainsString(x, v) { + rightSlice = append(rightSlice, v) + } + } + + return leftSlice, rightSlice +} + +// DifferenceInt64 returns the difference between two collections of int64s. +func DifferenceInt64(x []int64, y []int64) ([]int64, []int64) { + leftSlice := []int64{} + rightSlice := []int64{} + + for _, v := range x { + if !ContainsInt64(y, v) { + leftSlice = append(leftSlice, v) + } + } + + for _, v := range y { + if !ContainsInt64(x, v) { + rightSlice = append(rightSlice, v) + } + } + + return leftSlice, rightSlice +} + +// DifferenceInt32 returns the difference between two collections of ints32. +func DifferenceInt32(x []int32, y []int32) ([]int32, []int32) { + leftSlice := []int32{} + rightSlice := []int32{} + + for _, v := range x { + if !ContainsInt32(y, v) { + leftSlice = append(leftSlice, v) + } + } + + for _, v := range y { + if !ContainsInt32(x, v) { + rightSlice = append(rightSlice, v) + } + } + + return leftSlice, rightSlice +} + +// DifferenceInt returns the difference between two collections of ints. +func DifferenceInt(x []int, y []int) ([]int, []int) { + leftSlice := []int{} + rightSlice := []int{} + + for _, v := range x { + if !ContainsInt(y, v) { + leftSlice = append(leftSlice, v) + } + } + + for _, v := range y { + if !ContainsInt(x, v) { + rightSlice = append(rightSlice, v) + } + } + + return leftSlice, rightSlice +} + +// DifferenceUInt returns the difference between two collections of uints. +func DifferenceUInt(x []uint, y []uint) ([]uint, []uint) { + leftSlice := []uint{} + rightSlice := []uint{} + + for _, v := range x { + if !ContainsUInt(y, v) { + leftSlice = append(leftSlice, v) + } + } + + for _, v := range y { + if !ContainsUInt(x, v) { + rightSlice = append(rightSlice, v) + } + } + + return leftSlice, rightSlice +} + +// DifferenceUInt32 returns the difference between two collections of uints32. +func DifferenceUInt32(x []uint32, y []uint32) ([]uint32, []uint32) { + leftSlice := []uint32{} + rightSlice := []uint32{} + + for _, v := range x { + if !ContainsUInt32(y, v) { + leftSlice = append(leftSlice, v) + } + } + + for _, v := range y { + if !ContainsUInt32(x, v) { + rightSlice = append(rightSlice, v) + } + } + + return leftSlice, rightSlice +} + +// DifferenceUInt64 returns the difference between two collections of uints64. +func DifferenceUInt64(x []uint64, y []uint64) ([]uint64, []uint64) { + leftSlice := []uint64{} + rightSlice := []uint64{} + + for _, v := range x { + if !ContainsUInt64(y, v) { + leftSlice = append(leftSlice, v) + } + } + + for _, v := range y { + if !ContainsUInt64(x, v) { + rightSlice = append(rightSlice, v) + } + } + + return leftSlice, rightSlice +} diff --git a/vendor/github.com/thoas/go-funk/join.go b/vendor/github.com/thoas/go-funk/join.go new file mode 100644 index 00000000000..f5de606571c --- /dev/null +++ b/vendor/github.com/thoas/go-funk/join.go @@ -0,0 +1,111 @@ +package funk + +import ( + "reflect" + "strings" +) + +type JoinFnc func(lx, rx reflect.Value) reflect.Value + +// Join combines two collections using the given join method. +func Join(larr, rarr interface{}, fnc JoinFnc) interface{} { + if !IsCollection(larr) { + panic("First parameter must be a collection") + } + if !IsCollection(rarr) { + panic("Second parameter must be a collection") + } + + lvalue := reflect.ValueOf(larr) + rvalue := reflect.ValueOf(rarr) + if NotEqual(lvalue.Type(), rvalue.Type()) { + panic("Parameters must have the same type") + } + + return fnc(lvalue, rvalue).Interface() +} + +// InnerJoin finds and returns matching data from two collections. +func InnerJoin(lx, rx reflect.Value) reflect.Value { + result := reflect.MakeSlice(reflect.SliceOf(lx.Type().Elem()), 0, lx.Len()+rx.Len()) + rhash := hashSlice(rx) + lhash := make(map[interface{}]struct{}, lx.Len()) + + for i := 0; i < lx.Len(); i++ { + v := lx.Index(i) + _, ok := rhash[v.Interface()] + _, alreadyExists := lhash[v.Interface()] + if ok && !alreadyExists { + lhash[v.Interface()] = struct{}{} + result = reflect.Append(result, v) + } + } + return result +} + +// OuterJoin finds and returns dissimilar data from two collections. +func OuterJoin(lx, rx reflect.Value) reflect.Value { + ljoin := LeftJoin(lx, rx) + rjoin := RightJoin(lx, rx) + + result := reflect.MakeSlice(reflect.SliceOf(lx.Type().Elem()), ljoin.Len()+rjoin.Len(), ljoin.Len()+rjoin.Len()) + for i := 0; i < ljoin.Len(); i++ { + result.Index(i).Set(ljoin.Index(i)) + } + for i := 0; i < rjoin.Len(); i++ { + result.Index(ljoin.Len() + i).Set(rjoin.Index(i)) + } + + return result +} + +// LeftJoin finds and returns dissimilar data from the first collection (left). +func LeftJoin(lx, rx reflect.Value) reflect.Value { + result := reflect.MakeSlice(reflect.SliceOf(lx.Type().Elem()), 0, lx.Len()) + rhash := hashSlice(rx) + + for i := 0; i < lx.Len(); i++ { + v := lx.Index(i) + _, ok := rhash[v.Interface()] + if !ok { + result = reflect.Append(result, v) + } + } + return result +} + +// LeftJoin finds and returns dissimilar data from the second collection (right). +func RightJoin(lx, rx reflect.Value) reflect.Value { return LeftJoin(rx, lx) } + +func hashSlice(arr reflect.Value) map[interface{}]struct{} { + hash := map[interface{}]struct{}{} + for i := 0; i < arr.Len(); i++ { + v := arr.Index(i).Interface() + hash[v] = struct{}{} + } + return hash +} + +// StringerJoin joins an array of elements which implement the `String() string` function. +// Direct copy of strings.Join() with a few tweaks. +func StringerJoin(elems []interface{ String() string }, sep string) string { + switch len(elems) { + case 0: + return "" + case 1: + return elems[0].String() + } + n := len(sep) * (len(elems) - 1) + for i := 0; i < len(elems); i++ { + n += len(elems[i].String()) + } + + var b strings.Builder + b.Grow(n) + b.WriteString(elems[0].String()) + for _, s := range elems[1:] { + b.WriteString(sep) + b.WriteString(s.String()) + } + return b.String() +} diff --git a/vendor/github.com/thoas/go-funk/join_primitives.go b/vendor/github.com/thoas/go-funk/join_primitives.go new file mode 100644 index 00000000000..eefcac12d58 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/join_primitives.go @@ -0,0 +1,373 @@ +package funk + +type JoinIntFnc func(lx, rx []int) []int + +// JoinInt combines two int collections using the given join method. +func JoinInt(larr, rarr []int, fnc JoinIntFnc) []int { + return fnc(larr, rarr) +} + +// InnerJoinInt finds and returns matching data from two int collections. +func InnerJoinInt(lx, rx []int) []int { + result := make([]int, 0, len(lx)+len(rx)) + rhash := hashSliceInt(rx) + lhash := make(map[int]struct{}, len(lx)) + + for _, v := range lx { + _, ok := rhash[v] + _, alreadyExists := lhash[v] + if ok && !alreadyExists { + lhash[v] = struct{}{} + result = append(result, v) + } + } + return result +} + +// OuterJoinInt finds and returns dissimilar data from two int collections. +func OuterJoinInt(lx, rx []int) []int { + ljoin := LeftJoinInt(lx, rx) + rjoin := RightJoinInt(lx, rx) + + result := make([]int, len(ljoin)+len(rjoin)) + copy(result, ljoin) + for i, v := range rjoin { + result[len(ljoin)+i] = v + } + return result +} + +// LeftJoinInt finds and returns dissimilar data from the first int collection (left). +func LeftJoinInt(lx, rx []int) []int { + result := make([]int, 0, len(lx)) + rhash := hashSliceInt(rx) + + for _, v := range lx { + _, ok := rhash[v] + if !ok { + result = append(result, v) + } + } + return result +} + +// LeftJoinInt finds and returns dissimilar data from the second int collection (right). +func RightJoinInt(lx, rx []int) []int { return LeftJoinInt(rx, lx) } + +func hashSliceInt(arr []int) map[int]struct{} { + hash := make(map[int]struct{}, len(arr)) + for _, i := range arr { + hash[i] = struct{}{} + } + return hash +} + +type JoinInt32Fnc func(lx, rx []int32) []int32 + +// JoinInt32 combines two int32 collections using the given join method. +func JoinInt32(larr, rarr []int32, fnc JoinInt32Fnc) []int32 { + return fnc(larr, rarr) +} + +// InnerJoinInt32 finds and returns matching data from two int32 collections. +func InnerJoinInt32(lx, rx []int32) []int32 { + result := make([]int32, 0, len(lx)+len(rx)) + rhash := hashSliceInt32(rx) + lhash := make(map[int32]struct{}, len(lx)) + + for _, v := range lx { + _, ok := rhash[v] + _, alreadyExists := lhash[v] + if ok && !alreadyExists { + lhash[v] = struct{}{} + result = append(result, v) + } + } + return result +} + +// OuterJoinInt32 finds and returns dissimilar data from two int32 collections. +func OuterJoinInt32(lx, rx []int32) []int32 { + ljoin := LeftJoinInt32(lx, rx) + rjoin := RightJoinInt32(lx, rx) + + result := make([]int32, len(ljoin)+len(rjoin)) + copy(result, ljoin) + for i, v := range rjoin { + result[len(ljoin)+i] = v + } + return result +} + +// LeftJoinInt32 finds and returns dissimilar data from the first int32 collection (left). +func LeftJoinInt32(lx, rx []int32) []int32 { + result := make([]int32, 0, len(lx)) + rhash := hashSliceInt32(rx) + + for _, v := range lx { + _, ok := rhash[v] + if !ok { + result = append(result, v) + } + } + return result +} + +// LeftJoinInt32 finds and returns dissimilar data from the second int32 collection (right). +func RightJoinInt32(lx, rx []int32) []int32 { return LeftJoinInt32(rx, lx) } + +func hashSliceInt32(arr []int32) map[int32]struct{} { + hash := make(map[int32]struct{}, len(arr)) + for _, i := range arr { + hash[i] = struct{}{} + } + return hash +} + +type JoinInt64Fnc func(lx, rx []int64) []int64 + +// JoinInt64 combines two int64 collections using the given join method. +func JoinInt64(larr, rarr []int64, fnc JoinInt64Fnc) []int64 { + return fnc(larr, rarr) +} + +// InnerJoinInt64 finds and returns matching data from two int64 collections. +func InnerJoinInt64(lx, rx []int64) []int64 { + result := make([]int64, 0, len(lx)+len(rx)) + rhash := hashSliceInt64(rx) + lhash := make(map[int64]struct{}, len(lx)) + + for _, v := range lx { + _, ok := rhash[v] + _, alreadyExists := lhash[v] + if ok && !alreadyExists { + lhash[v] = struct{}{} + result = append(result, v) + } + } + return result +} + +// OuterJoinInt64 finds and returns dissimilar data from two int64 collections. +func OuterJoinInt64(lx, rx []int64) []int64 { + ljoin := LeftJoinInt64(lx, rx) + rjoin := RightJoinInt64(lx, rx) + + result := make([]int64, len(ljoin)+len(rjoin)) + copy(result, ljoin) + for i, v := range rjoin { + result[len(ljoin)+i] = v + } + return result +} + +// LeftJoinInt64 finds and returns dissimilar data from the first int64 collection (left). +func LeftJoinInt64(lx, rx []int64) []int64 { + result := make([]int64, 0, len(lx)) + rhash := hashSliceInt64(rx) + + for _, v := range lx { + _, ok := rhash[v] + if !ok { + result = append(result, v) + } + } + return result +} + +// LeftJoinInt64 finds and returns dissimilar data from the second int64 collection (right). +func RightJoinInt64(lx, rx []int64) []int64 { return LeftJoinInt64(rx, lx) } + +func hashSliceInt64(arr []int64) map[int64]struct{} { + hash := make(map[int64]struct{}, len(arr)) + for _, i := range arr { + hash[i] = struct{}{} + } + return hash +} + +type JoinStringFnc func(lx, rx []string) []string + +// JoinString combines two string collections using the given join method. +func JoinString(larr, rarr []string, fnc JoinStringFnc) []string { + return fnc(larr, rarr) +} + +// InnerJoinString finds and returns matching data from two string collections. +func InnerJoinString(lx, rx []string) []string { + result := make([]string, 0, len(lx)+len(rx)) + rhash := hashSliceString(rx) + lhash := make(map[string]struct{}, len(lx)) + + for _, v := range lx { + _, ok := rhash[v] + _, alreadyExists := lhash[v] + if ok && !alreadyExists { + lhash[v] = struct{}{} + result = append(result, v) + } + } + return result +} + +// OuterJoinString finds and returns dissimilar data from two string collections. +func OuterJoinString(lx, rx []string) []string { + ljoin := LeftJoinString(lx, rx) + rjoin := RightJoinString(lx, rx) + + result := make([]string, len(ljoin)+len(rjoin)) + copy(result, ljoin) + for i, v := range rjoin { + result[len(ljoin)+i] = v + } + return result +} + +// LeftJoinString finds and returns dissimilar data from the first string collection (left). +func LeftJoinString(lx, rx []string) []string { + result := make([]string, 0, len(lx)) + rhash := hashSliceString(rx) + + for _, v := range lx { + _, ok := rhash[v] + if !ok { + result = append(result, v) + } + } + return result +} + +// LeftJoinString finds and returns dissimilar data from the second string collection (right). +func RightJoinString(lx, rx []string) []string { return LeftJoinString(rx, lx) } + +func hashSliceString(arr []string) map[string]struct{} { + hash := make(map[string]struct{}, len(arr)) + for _, i := range arr { + hash[i] = struct{}{} + } + return hash +} + +type JoinFloat32Fnc func(lx, rx []float32) []float32 + +// JoinFloat32 combines two float32 collections using the given join method. +func JoinFloat32(larr, rarr []float32, fnc JoinFloat32Fnc) []float32 { + return fnc(larr, rarr) +} + +// InnerJoinFloat32 finds and returns matching data from two float32 collections. +func InnerJoinFloat32(lx, rx []float32) []float32 { + result := make([]float32, 0, len(lx)+len(rx)) + rhash := hashSliceFloat32(rx) + lhash := make(map[float32]struct{}, len(lx)) + + for _, v := range lx { + _, ok := rhash[v] + _, alreadyExists := lhash[v] + if ok && !alreadyExists { + lhash[v] = struct{}{} + result = append(result, v) + } + } + return result +} + +// OuterJoinFloat32 finds and returns dissimilar data from two float32 collections. +func OuterJoinFloat32(lx, rx []float32) []float32 { + ljoin := LeftJoinFloat32(lx, rx) + rjoin := RightJoinFloat32(lx, rx) + + result := make([]float32, len(ljoin)+len(rjoin)) + copy(result, ljoin) + for i, v := range rjoin { + result[len(ljoin)+i] = v + } + return result +} + +// LeftJoinFloat32 finds and returns dissimilar data from the first float32 collection (left). +func LeftJoinFloat32(lx, rx []float32) []float32 { + result := make([]float32, 0, len(lx)) + rhash := hashSliceFloat32(rx) + + for _, v := range lx { + _, ok := rhash[v] + if !ok { + result = append(result, v) + } + } + return result +} + +// LeftJoinFloat32 finds and returns dissimilar data from the second float32 collection (right). +func RightJoinFloat32(lx, rx []float32) []float32 { return LeftJoinFloat32(rx, lx) } + +func hashSliceFloat32(arr []float32) map[float32]struct{} { + hash := make(map[float32]struct{}, len(arr)) + for _, i := range arr { + hash[i] = struct{}{} + } + return hash +} + +type JoinFloat64Fnc func(lx, rx []float64) []float64 + +// JoinFloat64 combines two float64 collections using the given join method. +func JoinFloat64(larr, rarr []float64, fnc JoinFloat64Fnc) []float64 { + return fnc(larr, rarr) +} + +// InnerJoinFloat64 finds and returns matching data from two float64 collections. +func InnerJoinFloat64(lx, rx []float64) []float64 { + result := make([]float64, 0, len(lx)+len(rx)) + rhash := hashSliceFloat64(rx) + lhash := make(map[float64]struct{}, len(lx)) + + for _, v := range lx { + _, ok := rhash[v] + _, alreadyExists := lhash[v] + if ok && !alreadyExists { + lhash[v] = struct{}{} + result = append(result, v) + } + } + return result +} + +// OuterJoinFloat64 finds and returns dissimilar data from two float64 collections. +func OuterJoinFloat64(lx, rx []float64) []float64 { + ljoin := LeftJoinFloat64(lx, rx) + rjoin := RightJoinFloat64(lx, rx) + + result := make([]float64, len(ljoin)+len(rjoin)) + copy(result, ljoin) + for i, v := range rjoin { + result[len(ljoin)+i] = v + } + return result +} + +// LeftJoinFloat64 finds and returns dissimilar data from the first float64 collection (left). +func LeftJoinFloat64(lx, rx []float64) []float64 { + result := make([]float64, 0, len(lx)) + rhash := hashSliceFloat64(rx) + + for _, v := range lx { + _, ok := rhash[v] + if !ok { + result = append(result, v) + } + } + return result +} + +// LeftJoinFloat64 finds and returns dissimilar data from the second float64 collection (right). +func RightJoinFloat64(lx, rx []float64) []float64 { return LeftJoinFloat64(rx, lx) } + +func hashSliceFloat64(arr []float64) map[float64]struct{} { + hash := make(map[float64]struct{}, len(arr)) + for _, i := range arr { + hash[i] = struct{}{} + } + return hash +} diff --git a/vendor/github.com/thoas/go-funk/lazy_builder.go b/vendor/github.com/thoas/go-funk/lazy_builder.go new file mode 100644 index 00000000000..9ba1907ea10 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/lazy_builder.go @@ -0,0 +1,117 @@ +package funk + +import "reflect" + +type lazyBuilder struct { + exec func() interface{} +} + +func (b *lazyBuilder) Chunk(size int) Builder { + return &lazyBuilder{func() interface{} { return Chunk(b.exec(), size) }} +} +func (b *lazyBuilder) Compact() Builder { + return &lazyBuilder{func() interface{} { return Compact(b.exec()) }} +} +func (b *lazyBuilder) Drop(n int) Builder { + return &lazyBuilder{func() interface{} { return Drop(b.exec(), n) }} +} +func (b *lazyBuilder) Filter(predicate interface{}) Builder { + return &lazyBuilder{func() interface{} { return Filter(b.exec(), predicate) }} +} +func (b *lazyBuilder) Flatten() Builder { + return &lazyBuilder{func() interface{} { return Flatten(b.exec()) }} +} +func (b *lazyBuilder) FlattenDeep() Builder { + return &lazyBuilder{func() interface{} { return FlattenDeep(b.exec()) }} +} +func (b *lazyBuilder) Initial() Builder { + return &lazyBuilder{func() interface{} { return Initial(b.exec()) }} +} +func (b *lazyBuilder) Intersect(y interface{}) Builder { + return &lazyBuilder{func() interface{} { return Intersect(b.exec(), y) }} +} +func (b *lazyBuilder) Join(rarr interface{}, fnc JoinFnc) Builder { + return &lazyBuilder{func() interface{} { return Join(b.exec(), rarr, fnc) }} +} +func (b *lazyBuilder) Map(mapFunc interface{}) Builder { + return &lazyBuilder{func() interface{} { return Map(b.exec(), mapFunc) }} +} +func (b *lazyBuilder) FlatMap(mapFunc interface{}) Builder { + return &lazyBuilder{func() interface{} { return FlatMap(b.exec(), mapFunc) }} +} +func (b *lazyBuilder) Reverse() Builder { + return &lazyBuilder{func() interface{} { return Reverse(b.exec()) }} +} +func (b *lazyBuilder) Shuffle() Builder { + return &lazyBuilder{func() interface{} { return Shuffle(b.exec()) }} +} +func (b *lazyBuilder) Tail() Builder { + return &lazyBuilder{func() interface{} { return Tail(b.exec()) }} +} +func (b *lazyBuilder) Uniq() Builder { + return &lazyBuilder{func() interface{} { return Uniq(b.exec()) }} +} +func (b *lazyBuilder) Without(values ...interface{}) Builder { + return &lazyBuilder{func() interface{} { return Without(b.exec(), values...) }} +} + +func (b *lazyBuilder) All() bool { + return (&chainBuilder{b.exec()}).All() +} +func (b *lazyBuilder) Any() bool { + return (&chainBuilder{b.exec()}).Any() +} +func (b *lazyBuilder) Contains(elem interface{}) bool { + return Contains(b.exec(), elem) +} +func (b *lazyBuilder) Every(elements ...interface{}) bool { + return Every(b.exec(), elements...) +} +func (b *lazyBuilder) Find(predicate interface{}) interface{} { + return Find(b.exec(), predicate) +} +func (b *lazyBuilder) ForEach(predicate interface{}) { + ForEach(b.exec(), predicate) +} +func (b *lazyBuilder) ForEachRight(predicate interface{}) { + ForEachRight(b.exec(), predicate) +} +func (b *lazyBuilder) Head() interface{} { + return Head(b.exec()) +} +func (b *lazyBuilder) Keys() interface{} { + return Keys(b.exec()) +} +func (b *lazyBuilder) IndexOf(elem interface{}) int { + return IndexOf(b.exec(), elem) +} +func (b *lazyBuilder) IsEmpty() bool { + return IsEmpty(b.exec()) +} +func (b *lazyBuilder) Last() interface{} { + return Last(b.exec()) +} +func (b *lazyBuilder) LastIndexOf(elem interface{}) int { + return LastIndexOf(b.exec(), elem) +} +func (b *lazyBuilder) NotEmpty() bool { + return NotEmpty(b.exec()) +} +func (b *lazyBuilder) Product() float64 { + return Product(b.exec()) +} +func (b *lazyBuilder) Reduce(reduceFunc, acc interface{}) interface{} { + return Reduce(b.exec(), reduceFunc, acc) +} +func (b *lazyBuilder) Sum() float64 { + return Sum(b.exec()) +} +func (b *lazyBuilder) Type() reflect.Type { + return reflect.TypeOf(b.exec()) +} +func (b *lazyBuilder) Value() interface{} { + return b.exec() +} +func (b *lazyBuilder) Values() interface{} { + return Values(b.exec()) +} diff --git a/vendor/github.com/thoas/go-funk/map.go b/vendor/github.com/thoas/go-funk/map.go new file mode 100644 index 00000000000..4dfb4f90478 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/map.go @@ -0,0 +1,74 @@ +package funk + +import ( + "fmt" + "reflect" +) + +// Keys creates an array of the own enumerable map keys or struct field names. +func Keys(out interface{}) interface{} { + value := redirectValue(reflect.ValueOf(out)) + valueType := value.Type() + + if value.Kind() == reflect.Map { + keys := value.MapKeys() + + length := len(keys) + + resultSlice := reflect.MakeSlice(reflect.SliceOf(valueType.Key()), length, length) + + for i, key := range keys { + resultSlice.Index(i).Set(key) + } + + return resultSlice.Interface() + } + + if value.Kind() == reflect.Struct { + length := value.NumField() + + resultSlice := make([]string, length) + + for i := 0; i < length; i++ { + resultSlice[i] = valueType.Field(i).Name + } + + return resultSlice + } + + panic(fmt.Sprintf("Type %s is not supported by Keys", valueType.String())) +} + +// Values creates an array of the own enumerable map values or struct field values. +func Values(out interface{}) interface{} { + value := redirectValue(reflect.ValueOf(out)) + valueType := value.Type() + + if value.Kind() == reflect.Map { + keys := value.MapKeys() + + length := len(keys) + + resultSlice := reflect.MakeSlice(reflect.SliceOf(valueType.Elem()), length, length) + + for i, key := range keys { + resultSlice.Index(i).Set(value.MapIndex(key)) + } + + return resultSlice.Interface() + } + + if value.Kind() == reflect.Struct { + length := value.NumField() + + resultSlice := make([]interface{}, length) + + for i := 0; i < length; i++ { + resultSlice[i] = value.Field(i).Interface() + } + + return resultSlice + } + + panic(fmt.Sprintf("Type %s is not supported by Keys", valueType.String())) +} diff --git a/vendor/github.com/thoas/go-funk/max.go b/vendor/github.com/thoas/go-funk/max.go new file mode 100644 index 00000000000..0d63dc6e781 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/max.go @@ -0,0 +1,178 @@ +package funk + +import "strings" + +// MaxInt validates the input, compares the elements and returns the maximum element in an array/slice. +// It accepts []int +// It returns int +func MaxInt(i []int) int { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var max int + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + max = item + continue + } + if item > max { + max = item + } + } + return max +} + +// MaxInt8 validates the input, compares the elements and returns the maximum element in an array/slice. +// It accepts []int8 +// It returns int8 +func MaxInt8(i []int8) int8 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var max int8 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + max = item + continue + } + if item > max { + max = item + } + } + return max +} + +// MaxInt16 validates the input, compares the elements and returns the maximum element in an array/slice. +// It accepts []int16 +// It returns int16 +func MaxInt16(i []int16) int16 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var max int16 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + max = item + continue + } + if item > max { + max = item + } + } + return max +} + +// MaxInt32 validates the input, compares the elements and returns the maximum element in an array/slice. +// It accepts []int32 +// It returns int32 +func MaxInt32(i []int32) int32 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var max int32 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + max = item + continue + } + if item > max { + max = item + } + } + return max +} + +// MaxInt64 validates the input, compares the elements and returns the maximum element in an array/slice. +// It accepts []int64 +// It returns int64 +func MaxInt64(i []int64) int64 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var max int64 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + max = item + continue + } + if item > max { + max = item + } + } + return max +} + +// MaxFloat32 validates the input, compares the elements and returns the maximum element in an array/slice. +// It accepts []float32 +// It returns float32 +func MaxFloat32(i []float32) float32 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var max float32 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + max = item + continue + } + if item > max { + max = item + } + } + return max +} + +// MaxFloat64 validates the input, compares the elements and returns the maximum element in an array/slice. +// It accepts []float64 +// It returns float64 +func MaxFloat64(i []float64) float64 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var max float64 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + max = item + continue + } + if item > max { + max = item + } + } + return max +} + +// MaxString validates the input, compares the elements and returns the maximum element in an array/slice. +// It accepts []string +// It returns string +func MaxString(i []string) string { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var max string + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + max = item + continue + } + max = compareStringsMax(max, item) + } + return max +} + +// compareStrings uses the strings.Compare method to compare two strings, and returns the greater one. +func compareStringsMax(max, current string) string { + r := strings.Compare(strings.ToLower(max), strings.ToLower(current)) + if r > 0 { + return max + } + return current +} diff --git a/vendor/github.com/thoas/go-funk/min.go b/vendor/github.com/thoas/go-funk/min.go new file mode 100644 index 00000000000..81ffa77bd47 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/min.go @@ -0,0 +1,177 @@ +package funk + +import "strings" + +// MinInt validates the input, compares the elements and returns the minimum element in an array/slice. +// It accepts []int +// It returns int +func MinInt(i []int) int { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var min int + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + min = item + continue + } + if item < min { + min = item + } + } + return min +} + +// MinInt8 validates the input, compares the elements and returns the minimum element in an array/slice. +// It accepts []int8 +// It returns int8 +func MinInt8(i []int8) int8 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var min int8 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + min = item + continue + } + if item < min { + min = item + } + } + return min +} + +// MinInt16 validates the input, compares the elements and returns the minimum element in an array/slice. +// It accepts []int16 +// It returns int16 +func MinInt16(i []int16) int16 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var min int16 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + min = item + continue + } + if item < min { + min = item + } + } + return min +} + +// MinInt32 validates the input, compares the elements and returns the minimum element in an array/slice. +// It accepts []int32 +// It returns int32 +func MinInt32(i []int32) int32 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var min int32 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + min = item + continue + } + if item < min { + min = item + } + } + return min +} + +// MinInt64 validates the input, compares the elements and returns the minimum element in an array/slice. +// It accepts []int64 +// It returns int64 +func MinInt64(i []int64) int64 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var min int64 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + min = item + continue + } + if item < min { + min = item + } + } + return min +} + +// MinFloat32 validates the input, compares the elements and returns the minimum element in an array/slice. +// It accepts []float32 +// It returns float32 +func MinFloat32(i []float32) float32 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var min float32 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + min = item + continue + } + if item < min { + min = item + } + } + return min +} + +// MinFloat64 validates the input, compares the elements and returns the minimum element in an array/slice. +// It accepts []float64 +// It returns float64 +func MinFloat64(i []float64) float64 { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var min float64 + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + min = item + continue + } + if item < min { + min = item + } + } + return min +} + +// MinString validates the input, compares the elements and returns the minimum element in an array/slice. +// It accepts []string +// It returns string +func MinString(i []string) string { + if len(i) == 0 { + panic("arg is an empty array/slice") + } + var min string + for idx := 0; idx < len(i); idx++ { + item := i[idx] + if idx == 0 { + min = item + continue + } + min = compareStringsMin(min, item) + } + return min +} + +func compareStringsMin(min, current string) string { + r := strings.Compare(strings.ToLower(min), strings.ToLower(current)) + if r < 0 { + return min + } + return current +} diff --git a/vendor/github.com/thoas/go-funk/operation.go b/vendor/github.com/thoas/go-funk/operation.go new file mode 100644 index 00000000000..170948b4a6c --- /dev/null +++ b/vendor/github.com/thoas/go-funk/operation.go @@ -0,0 +1,69 @@ +package funk + +import ( + "fmt" + "reflect" +) + +func calculate(arr interface{}, name string, operation rune) float64 { + value := redirectValue(reflect.ValueOf(arr)) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.Array || kind == reflect.Slice { + length := value.Len() + + if length == 0 { + return 0 + } + + result := map[rune]float64{ + '+': 0.0, + '*': 1, + }[operation] + + for i := 0; i < length; i++ { + elem := redirectValue(value.Index(i)).Interface() + + var value float64 + switch e := elem.(type) { + case int: + value = float64(e) + case int8: + value = float64(e) + case int16: + value = float64(e) + case int32: + value = float64(e) + case int64: + value = float64(e) + case float32: + value = float64(e) + case float64: + value = e + } + + switch operation { + case '+': + result += value + case '*': + result *= value + } + } + + return result + } + + panic(fmt.Sprintf("Type %s is not supported by %s", valueType.String(), name)) +} + +// Sum computes the sum of the values in array. +func Sum(arr interface{}) float64 { + return calculate(arr, "Sum", '+') +} + +// Product computes the product of the values in array. +func Product(arr interface{}) float64 { + return calculate(arr, "Product", '*') +} diff --git a/vendor/github.com/thoas/go-funk/options.go b/vendor/github.com/thoas/go-funk/options.go new file mode 100644 index 00000000000..5d08c24efce --- /dev/null +++ b/vendor/github.com/thoas/go-funk/options.go @@ -0,0 +1,24 @@ +package funk + +type options struct { + allowZero bool +} + +type option func(*options) + +func newOptions(values ...option) *options { + opts := &options{ + allowZero: false, + } + for _, o := range values { + o(opts) + } + return opts +} + +// WithAllowZero allows zero values. +func WithAllowZero() func(*options) { + return func(opts *options) { + opts.allowZero = true + } +} diff --git a/vendor/github.com/thoas/go-funk/permutation.go b/vendor/github.com/thoas/go-funk/permutation.go new file mode 100644 index 00000000000..0b109930625 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/permutation.go @@ -0,0 +1,29 @@ +package funk + +import "errors" + +// NextPermutation Implement next permutation, +// which rearranges numbers into the lexicographically next greater permutation of numbers. +func NextPermutation(nums []int) error { + n := len(nums) + if n == 0 { + return errors.New("nums is empty") + } + + i := n - 2 + + for i >= 0 && nums[i] >= nums[i+1] { + i-- + } + + if i >= 0 { + j := n - 1 + for j >= 0 && nums[i] >= nums[j] { + j-- + } + nums[i], nums[j] = nums[j], nums[i] + } + + ReverseInt(nums[i+1:]) + return nil +} diff --git a/vendor/github.com/thoas/go-funk/predicate.go b/vendor/github.com/thoas/go-funk/predicate.go new file mode 100644 index 00000000000..e6b4131de2e --- /dev/null +++ b/vendor/github.com/thoas/go-funk/predicate.go @@ -0,0 +1,47 @@ +package funk + +import ( + "reflect" +) + +// predicatesImpl contains the common implementation of AnyPredicates and AllPredicates. +func predicatesImpl(value interface{}, wantedAnswer bool, predicates interface{}) bool { + if !IsCollection(predicates) { + panic("Predicates parameter must be an iteratee") + } + + predicatesValue := reflect.ValueOf(predicates) + inputValue := reflect.ValueOf(value) + + for i := 0; i < predicatesValue.Len(); i++ { + funcValue := predicatesValue.Index(i) + if !IsFunction(funcValue.Interface()) { + panic("Got non function as predicate") + } + + funcType := funcValue.Type() + if !IsPredicate(funcValue.Interface()) { + panic("Predicate function must have 1 parameter and must return boolean") + } + + if !inputValue.Type().ConvertibleTo(funcType.In(0)) { + panic("Given value is not compatible with type of parameter for the predicate.") + } + if result := funcValue.Call([]reflect.Value{inputValue}); wantedAnswer == result[0].Bool() { + return wantedAnswer + } + } + + return !wantedAnswer +} + +// AnyPredicates gets a value and a series of predicates, and return true if at least one of the predicates +// is true. +func AnyPredicates(value interface{}, predicates interface{}) bool { + return predicatesImpl(value, true, predicates) +} + +// AllPredicates gets a value and a series of predicates, and return true if all of the predicates are true. +func AllPredicates(value interface{}, predicates interface{}) bool { + return predicatesImpl(value, false, predicates) +} diff --git a/vendor/github.com/thoas/go-funk/presence.go b/vendor/github.com/thoas/go-funk/presence.go new file mode 100644 index 00000000000..9ab0f0f4270 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/presence.go @@ -0,0 +1,207 @@ +package funk + +import ( + "fmt" + "reflect" + "strings" +) + +// Filter iterates over elements of collection, returning an array of +// all elements predicate returns truthy for. +func Filter(arr interface{}, predicate interface{}) interface{} { + if !IsIteratee(arr) { + panic("First parameter must be an iteratee") + } + + if !IsFunction(predicate, 1, 1) { + panic("Second argument must be function") + } + + funcValue := reflect.ValueOf(predicate) + + funcType := funcValue.Type() + + if funcType.Out(0).Kind() != reflect.Bool { + panic("Return argument should be a boolean") + } + + arrValue := reflect.ValueOf(arr) + + arrType := arrValue.Type() + + // Get slice type corresponding to array type + resultSliceType := reflect.SliceOf(arrType.Elem()) + + // MakeSlice takes a slice kind type, and makes a slice. + resultSlice := reflect.MakeSlice(resultSliceType, 0, 0) + + for i := 0; i < arrValue.Len(); i++ { + elem := arrValue.Index(i) + + result := funcValue.Call([]reflect.Value{elem})[0].Interface().(bool) + + if result { + resultSlice = reflect.Append(resultSlice, elem) + } + } + + return resultSlice.Interface() +} + +// Find iterates over elements of collection, returning the first +// element predicate returns truthy for. +func Find(arr interface{}, predicate interface{}) interface{} { + _, val := FindKey(arr, predicate) + return val +} + +// Find iterates over elements of collection, returning the first +// element of an array and random of a map which predicate returns truthy for. +func FindKey(arr interface{}, predicate interface{}) (matchKey, matchEle interface{}) { + if !IsIteratee(arr) { + panic("First parameter must be an iteratee") + } + + if !IsFunction(predicate, 1, 1) { + panic("Second argument must be function") + } + + funcValue := reflect.ValueOf(predicate) + + funcType := funcValue.Type() + + if funcType.Out(0).Kind() != reflect.Bool { + panic("Return argument should be a boolean") + } + + arrValue := reflect.ValueOf(arr) + var keyArrs []reflect.Value + + isMap := arrValue.Kind() == reflect.Map + if isMap { + keyArrs = arrValue.MapKeys() + } + for i := 0; i < arrValue.Len(); i++ { + var ( + elem reflect.Value + key reflect.Value + ) + if isMap { + key = keyArrs[i] + elem = arrValue.MapIndex(key) + } else { + key = reflect.ValueOf(i) + elem = arrValue.Index(i) + } + + result := funcValue.Call([]reflect.Value{elem})[0].Interface().(bool) + + if result { + return key.Interface(), elem.Interface() + } + } + + return nil, nil +} + +// IndexOf gets the index at which the first occurrence of value is found in array or return -1 +// if the value cannot be found +func IndexOf(in interface{}, elem interface{}) int { + inValue := reflect.ValueOf(in) + + elemValue := reflect.ValueOf(elem) + + inType := inValue.Type() + + if inType.Kind() == reflect.String { + return strings.Index(inValue.String(), elemValue.String()) + } + + if inType.Kind() == reflect.Slice { + equalTo := equal(elem) + for i := 0; i < inValue.Len(); i++ { + if equalTo(reflect.Value{}, inValue.Index(i)) { + return i + } + } + } + + return -1 +} + +// LastIndexOf gets the index at which the last occurrence of value is found in array or return -1 +// if the value cannot be found +func LastIndexOf(in interface{}, elem interface{}) int { + inValue := reflect.ValueOf(in) + + elemValue := reflect.ValueOf(elem) + + inType := inValue.Type() + + if inType.Kind() == reflect.String { + return strings.LastIndex(inValue.String(), elemValue.String()) + } + + if inType.Kind() == reflect.Slice { + length := inValue.Len() + + equalTo := equal(elem) + for i := length - 1; i >= 0; i-- { + if equalTo(reflect.Value{}, inValue.Index(i)) { + return i + } + } + } + + return -1 +} + +// Contains returns true if an element is present in a iteratee. +func Contains(in interface{}, elem interface{}) bool { + inValue := reflect.ValueOf(in) + elemValue := reflect.ValueOf(elem) + inType := inValue.Type() + + switch inType.Kind() { + case reflect.String: + return strings.Contains(inValue.String(), elemValue.String()) + case reflect.Map: + equalTo := equal(elem, true) + for _, key := range inValue.MapKeys() { + if equalTo(key, inValue.MapIndex(key)) { + return true + } + } + case reflect.Slice, reflect.Array: + equalTo := equal(elem) + for i := 0; i < inValue.Len(); i++ { + if equalTo(reflect.Value{}, inValue.Index(i)) { + return true + } + } + default: + panic(fmt.Sprintf("Type %s is not supported by Contains, supported types are String, Map, Slice, Array", inType.String())) + } + + return false +} + +// Every returns true if every element is present in a iteratee. +func Every(in interface{}, elements ...interface{}) bool { + for _, elem := range elements { + if !Contains(in, elem) { + return false + } + } + return true +} + +// Some returns true if atleast one element is present in an iteratee. +func Some(in interface{}, elements ...interface{}) bool { + for _, elem := range elements { + if Contains(in, elem) { + return true + } + } + return false +} diff --git a/vendor/github.com/thoas/go-funk/reduce.go b/vendor/github.com/thoas/go-funk/reduce.go new file mode 100644 index 00000000000..579b82254d7 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/reduce.go @@ -0,0 +1,87 @@ +package funk + +import ( + "reflect" +) + +// Reduce takes a collection and reduces it to a single value using a reduction +// function (or a valid symbol) and an accumulator value. +func Reduce(arr, reduceFunc, acc interface{}) interface{} { + arrValue := redirectValue(reflect.ValueOf(arr)) + + if !IsIteratee(arrValue.Interface()) { + panic("First parameter must be an iteratee") + } + + returnType := reflect.TypeOf(Reduce).Out(0) + + isFunc := IsFunction(reduceFunc, 2, 1) + isRune := reflect.TypeOf(reduceFunc).Kind() == reflect.Int32 + + if !(isFunc || isRune) { + panic("Second argument must be a valid function or rune") + } + + accValue := reflect.ValueOf(acc) + sliceElemType := sliceElem(arrValue.Type()) + + if isRune { + if arrValue.Kind() == reflect.Slice && sliceElemType.Kind() == reflect.Interface { + accValue = accValue.Convert(returnType) + } else { + accValue = accValue.Convert(sliceElemType) + } + } else { + accValue = accValue.Convert(reflect.TypeOf(reduceFunc).In(0)) + } + + accType := accValue.Type() + + // Generate reduce function if was passed as rune + if isRune { + reduceSign := reduceFunc.(int32) + + if ok := map[rune]bool{'+': true, '*': true}[reduceSign]; !ok { + panic("Invalid reduce sign, allowed: '+' and '*'") + } + + in := []reflect.Type{accType, sliceElemType} + out := []reflect.Type{accType} + funcType := reflect.FuncOf(in, out, false) + + reduceFunc = reflect.MakeFunc(funcType, func(args []reflect.Value) []reflect.Value { + acc := args[0].Interface() + elem := args[1].Interface() + + var result float64 + params := []interface{}{acc, elem} + switch reduceSign { + case '+': + result = Sum(params) + case '*': + result = Product(params) + } + + return []reflect.Value{reflect.ValueOf(result).Convert(accType)} + }).Interface() + } + + funcValue := reflect.ValueOf(reduceFunc) + funcType := funcValue.Type() + + for i := 0; i < arrValue.Len(); i++ { + if accType.ConvertibleTo(funcType.In(0)) { + accValue = accValue.Convert(funcType.In(0)) + } + + arrElementValue := arrValue.Index(i) + if sliceElemType.ConvertibleTo(funcType.In(1)) { + arrElementValue = arrElementValue.Convert(funcType.In(1)) + } + + result := funcValue.Call([]reflect.Value{accValue, arrElementValue}) + accValue = result[0] + } + + return accValue.Convert(returnType).Interface() +} diff --git a/vendor/github.com/thoas/go-funk/retrieve.go b/vendor/github.com/thoas/go-funk/retrieve.go new file mode 100644 index 00000000000..da89e1d4711 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/retrieve.go @@ -0,0 +1,146 @@ +package funk + +import ( + "reflect" + "strings" +) + +// Get retrieves the value from given path, retriever can be modified with available RetrieverOptions +func Get(out interface{}, path string, opts ...option) interface{} { + options := newOptions(opts...) + + result := get(reflect.ValueOf(out), path, opts...) + // valid kind and we can return a result.Interface() without panic + if result.Kind() != reflect.Invalid && result.CanInterface() { + // if we don't allow zero and the result is a zero value return nil + if !options.allowZero && result.IsZero() { + return nil + } + // if the result kind is a pointer and its nil return nil + if result.Kind() == reflect.Ptr && result.IsNil() { + return nil + } + // return the result interface (i.e the zero value of it) + return result.Interface() + } + + return nil +} + +// GetOrElse retrieves the value of the pointer or default. +func GetOrElse(v interface{}, def interface{}) interface{} { + val := reflect.ValueOf(v) + if v == nil || (val.Kind() == reflect.Ptr && val.IsNil()) { + return def + } else if val.Kind() != reflect.Ptr { + return v + } + return val.Elem().Interface() +} + +func get(value reflect.Value, path string, opts ...option) reflect.Value { + options := newOptions(opts...) + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Array { + var resultSlice reflect.Value + + length := value.Len() + + if length == 0 { + zeroElement := reflect.Zero(value.Type().Elem()) + pathValue := get(zeroElement, path) + value = reflect.MakeSlice(reflect.SliceOf(pathValue.Type()), 0, 0) + + return value + } + + for i := 0; i < length; i++ { + item := value.Index(i) + + resultValue := get(item, path) + + if resultValue.Kind() == reflect.Invalid || (resultValue.IsZero() && !options.allowZero) { + continue + } + + resultType := resultValue.Type() + + if resultSlice.Kind() == reflect.Invalid { + resultType := reflect.SliceOf(resultType) + + resultSlice = reflect.MakeSlice(resultType, 0, 0) + } + + resultSlice = reflect.Append(resultSlice, resultValue) + } + + // if the result is a slice of a slice, we need to flatten it + if resultSlice.Kind() != reflect.Invalid && resultSlice.Type().Elem().Kind() == reflect.Slice { + return flattenDeep(resultSlice) + } + + return resultSlice + } + + quoted := false + parts := strings.FieldsFunc(path, func(r rune) bool { + if r == '"' { + quoted = !quoted + } + return !quoted && r == '.' + }) + + for i, part := range parts { + parts[i] = strings.Trim(part, "\"") + } + + for _, part := range parts { + value = redirectValue(value) + kind := value.Kind() + + switch kind { + case reflect.Invalid: + continue + case reflect.Struct: + if isNilIndirection(value, part) { + return reflect.ValueOf(nil) + } + value = value.FieldByName(part) + case reflect.Map: + value = value.MapIndex(reflect.ValueOf(part)) + case reflect.Slice, reflect.Array: + value = get(value, part) + default: + return reflect.ValueOf(nil) + } + } + + return value +} + +func isNilIndirection(v reflect.Value, name string) bool { + vType := v.Type() + for i := 0; i < vType.NumField(); i++ { + field := vType.Field(i) + if !isEmbeddedStructPointerField(field) { + return false + } + + fieldType := field.Type.Elem() + + _, found := fieldType.FieldByName(name) + if found { + return v.Field(i).IsNil() + } + } + + return false +} + +func isEmbeddedStructPointerField(field reflect.StructField) bool { + if !field.Anonymous { + return false + } + + return field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct +} diff --git a/vendor/github.com/thoas/go-funk/scan.go b/vendor/github.com/thoas/go-funk/scan.go new file mode 100644 index 00000000000..197330fb646 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/scan.go @@ -0,0 +1,205 @@ +package funk + +import ( + "fmt" + "reflect" +) + +// ForEach iterates over elements of collection and invokes iteratee +// for each element. +func ForEach(arr interface{}, predicate interface{}) { + if !IsIteratee(arr) { + panic("First parameter must be an iteratee") + } + + var ( + funcValue = reflect.ValueOf(predicate) + arrValue = reflect.ValueOf(arr) + arrType = arrValue.Type() + funcType = funcValue.Type() + ) + + if arrType.Kind() == reflect.Slice || arrType.Kind() == reflect.Array { + if !IsFunction(predicate, 1, 0) { + panic("Second argument must be a function with one parameter") + } + + arrElemType := arrValue.Type().Elem() + arrElemPointerType := reflect.New(arrElemType).Type() + usePointer := arrElemPointerType.ConvertibleTo(funcType.In(0)) + + // Checking whether element type is convertible to function's first argument's type. + if !arrElemType.ConvertibleTo(funcType.In(0)) && !usePointer { + panic("Map function's argument is not compatible with type of array.") + } + + for i := 0; i < arrValue.Len(); i++ { + if usePointer { + funcValue.Call([]reflect.Value{arrValue.Index(i).Addr()}) + } else { + funcValue.Call([]reflect.Value{arrValue.Index(i)}) + } + } + } + + if arrType.Kind() == reflect.Map { + if !IsFunction(predicate, 2, 0) { + panic("Second argument must be a function with two parameters") + } + + // Type checking for Map = (key, value) + keyType := arrType.Key() + valueType := arrType.Elem() + + if !keyType.ConvertibleTo(funcType.In(0)) { + panic(fmt.Sprintf("function first argument is not compatible with %s", keyType.String())) + } + + if !valueType.ConvertibleTo(funcType.In(1)) { + panic(fmt.Sprintf("function second argument is not compatible with %s", valueType.String())) + } + + for _, key := range arrValue.MapKeys() { + funcValue.Call([]reflect.Value{key, arrValue.MapIndex(key)}) + } + } +} + +// ForEachRight iterates over elements of collection from the right and invokes iteratee +// for each element. +func ForEachRight(arr interface{}, predicate interface{}) { + if !IsIteratee(arr) { + panic("First parameter must be an iteratee") + } + + var ( + funcValue = reflect.ValueOf(predicate) + arrValue = reflect.ValueOf(arr) + arrType = arrValue.Type() + funcType = funcValue.Type() + ) + + if arrType.Kind() == reflect.Slice || arrType.Kind() == reflect.Array { + if !IsFunction(predicate, 1, 0) { + panic("Second argument must be a function with one parameter") + } + + arrElemType := arrValue.Type().Elem() + arrElemPointerType := reflect.New(arrElemType).Type() + usePointer := arrElemPointerType.ConvertibleTo(funcType.In(0)) + + // Checking whether element type is convertible to function's first argument's type. + if !arrElemType.ConvertibleTo(funcType.In(0)) && !usePointer { + panic("Map function's argument is not compatible with type of array.") + } + + for i := arrValue.Len() - 1; i >= 0; i-- { + if usePointer { + funcValue.Call([]reflect.Value{arrValue.Index(i).Addr()}) + } else { + funcValue.Call([]reflect.Value{arrValue.Index(i)}) + } + + } + } + + if arrType.Kind() == reflect.Map { + if !IsFunction(predicate, 2, 0) { + panic("Second argument must be a function with two parameters") + } + + // Type checking for Map = (key, value) + keyType := arrType.Key() + valueType := arrType.Elem() + + if !keyType.ConvertibleTo(funcType.In(0)) { + panic(fmt.Sprintf("function first argument is not compatible with %s", keyType.String())) + } + + if !valueType.ConvertibleTo(funcType.In(1)) { + panic(fmt.Sprintf("function second argument is not compatible with %s", valueType.String())) + } + + keys := Reverse(arrValue.MapKeys()).([]reflect.Value) + + for _, key := range keys { + funcValue.Call([]reflect.Value{key, arrValue.MapIndex(key)}) + } + } +} + +// Head gets the first element of array. +func Head(arr interface{}) interface{} { + value := redirectValue(reflect.ValueOf(arr)) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.Array || kind == reflect.Slice { + if value.Len() == 0 { + return nil + } + + return value.Index(0).Interface() + } + + panic(fmt.Sprintf("Type %s is not supported by Head", valueType.String())) +} + +// Last gets the last element of array. +func Last(arr interface{}) interface{} { + value := redirectValue(reflect.ValueOf(arr)) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.Array || kind == reflect.Slice { + if value.Len() == 0 { + return nil + } + + return value.Index(value.Len() - 1).Interface() + } + + panic(fmt.Sprintf("Type %s is not supported by Last", valueType.String())) +} + +// Initial gets all but the last element of array. +func Initial(arr interface{}) interface{} { + value := redirectValue(reflect.ValueOf(arr)) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.Array || kind == reflect.Slice { + length := value.Len() + + if length <= 1 { + return arr + } + + return value.Slice(0, length-1).Interface() + } + + panic(fmt.Sprintf("Type %s is not supported by Initial", valueType.String())) +} + +// Tail gets all but the first element of array. +func Tail(arr interface{}) interface{} { + value := redirectValue(reflect.ValueOf(arr)) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.Array || kind == reflect.Slice { + length := value.Len() + + if length <= 1 { + return arr + } + + return value.Slice(1, length).Interface() + } + + panic(fmt.Sprintf("Type %s is not supported by Initial", valueType.String())) +} diff --git a/vendor/github.com/thoas/go-funk/short_if.go b/vendor/github.com/thoas/go-funk/short_if.go new file mode 100644 index 00000000000..537ff56f0a7 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/short_if.go @@ -0,0 +1,8 @@ +package funk + +func ShortIf(condition bool, a interface{}, b interface{}) interface{} { + if condition { + return a + } + return b +} diff --git a/vendor/github.com/thoas/go-funk/subset.go b/vendor/github.com/thoas/go-funk/subset.go new file mode 100644 index 00000000000..de47be15176 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/subset.go @@ -0,0 +1,41 @@ +package funk + +import ( + "reflect" +) + +// Subset returns true if collection x is a subset of y. +func Subset(x interface{}, y interface{}) bool { + if !IsCollection(x) { + panic("First parameter must be a collection") + } + if !IsCollection(y) { + panic("Second parameter must be a collection") + } + + xValue := reflect.ValueOf(x) + xType := xValue.Type() + + yValue := reflect.ValueOf(y) + yType := yValue.Type() + + if NotEqual(xType, yType) { + panic("Parameters must have the same type") + } + + if xValue.Len() == 0 { + return true + } + + if yValue.Len() == 0 || yValue.Len() < xValue.Len() { + return false + } + + for i := 0; i < xValue.Len(); i++ { + if !Contains(yValue.Interface(), xValue.Index(i).Interface()) { + return false + } + } + + return true +} diff --git a/vendor/github.com/thoas/go-funk/subtraction.go b/vendor/github.com/thoas/go-funk/subtraction.go new file mode 100644 index 00000000000..10a0a982021 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/subtraction.go @@ -0,0 +1,87 @@ +package funk + +import ( + "reflect" +) + +// Subtract returns the subtraction between two collections. +func Subtract(x interface{}, y interface{}) interface{} { + if !IsCollection(x) { + panic("First parameter must be a collection") + } + if !IsCollection(y) { + panic("Second parameter must be a collection") + } + + hash := map[interface{}]struct{}{} + + xValue := reflect.ValueOf(x) + xType := xValue.Type() + + yValue := reflect.ValueOf(y) + yType := yValue.Type() + + if NotEqual(xType, yType) { + panic("Parameters must have the same type") + } + + zType := reflect.SliceOf(xType.Elem()) + zSlice := reflect.MakeSlice(zType, 0, 0) + + for i := 0; i < xValue.Len(); i++ { + v := xValue.Index(i).Interface() + hash[v] = struct{}{} + } + + for i := 0; i < yValue.Len(); i++ { + v := yValue.Index(i).Interface() + _, ok := hash[v] + if ok { + delete(hash, v) + } + } + + for i := 0; i < xValue.Len(); i++ { + v := xValue.Index(i).Interface() + _, ok := hash[v] + if ok { + zSlice = reflect.Append(zSlice, xValue.Index(i)) + } + } + + return zSlice.Interface() +} + +// SubtractString returns the subtraction between two collections of string +func SubtractString(x []string, y []string) []string { + if len(x) == 0 { + return []string{} + } + + if len(y) == 0 { + return x + } + + slice := []string{} + hash := map[string]struct{}{} + + for _, v := range x { + hash[v] = struct{}{} + } + + for _, v := range y { + _, ok := hash[v] + if ok { + delete(hash, v) + } + } + + for _, v := range x { + _, ok := hash[v] + if ok { + slice = append(slice, v) + } + } + + return slice +} diff --git a/vendor/github.com/thoas/go-funk/transform.go b/vendor/github.com/thoas/go-funk/transform.go new file mode 100644 index 00000000000..73ae76ac0a3 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/transform.go @@ -0,0 +1,618 @@ +package funk + +import ( + "fmt" + "math/rand" + "reflect" + "strings" +) + +// Chunk creates an array of elements split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func Chunk(arr interface{}, size int) interface{} { + if !IsIteratee(arr) { + panic("First parameter must be neither array nor slice") + } + + if size == 0 { + return arr + } + + arrValue := reflect.ValueOf(arr) + + arrType := arrValue.Type() + + resultSliceType := reflect.SliceOf(arrType) + + // Initialize final result slice which will contains slice + resultSlice := reflect.MakeSlice(resultSliceType, 0, 0) + + itemType := arrType.Elem() + + var itemSlice reflect.Value + + itemSliceType := reflect.SliceOf(itemType) + + length := arrValue.Len() + + for i := 0; i < length; i++ { + if i%size == 0 || i == 0 { + if itemSlice.Kind() != reflect.Invalid { + resultSlice = reflect.Append(resultSlice, itemSlice) + } + + itemSlice = reflect.MakeSlice(itemSliceType, 0, 0) + } + + itemSlice = reflect.Append(itemSlice, arrValue.Index(i)) + + if i == length-1 { + resultSlice = reflect.Append(resultSlice, itemSlice) + } + } + + return resultSlice.Interface() +} + +// ToMap transforms a collection of instances to a Map. +// []T => map[type of T.]T +func ToMap(in interface{}, pivot string) interface{} { + // input value must be a collection + if !IsCollection(in) { + panic(fmt.Sprintf("%v must be a slict or an array", in)) + } + + value := reflect.ValueOf(in) + + inType := value.Type() + structType := inType.Elem() + + // retrieve the struct in the slice to deduce key type + if structType.Kind() == reflect.Ptr { + structType = structType.Elem() + } + + field, ok := structType.FieldByName(pivot) + if !ok { + panic(fmt.Sprintf("`%s` must be a field of the struct %s", pivot, structType.Name())) + } + + // value of the map will be the input type + collectionType := reflect.MapOf(field.Type, inType.Elem()) + + // create a map from scratch + collection := reflect.MakeMap(collectionType) + + for i := 0; i < value.Len(); i++ { + instance := value.Index(i) + var field reflect.Value + + if instance.Kind() == reflect.Ptr { + field = instance.Elem().FieldByName(pivot) + } else { + field = instance.FieldByName(pivot) + } + + collection.SetMapIndex(field, instance) + } + + return collection.Interface() +} + +// ToSet transforms a collection of instances to a Set. +// []T => map[T]struct{} +func ToSet(in interface{}) interface{} { + // input value must be a collection + if !IsCollection(in) { + panic(fmt.Sprintf("%v must be a slice or an array", in)) + } + + var ( + empty = struct{}{} + emptyType = reflect.TypeOf(empty) + emptyValue = reflect.ValueOf(empty) + ) + + value := reflect.ValueOf(in) + elemType := value.Type().Elem() + + // key of the set will be the input type + collection := reflect.MakeMap(reflect.MapOf(elemType, emptyType)) + + for i := 0; i < value.Len(); i++ { + collection.SetMapIndex(value.Index(i), emptyValue) + } + + return collection.Interface() +} + +func mapSlice(arrValue reflect.Value, funcValue reflect.Value) reflect.Value { + funcType := funcValue.Type() + + if funcType.NumIn() != 1 || funcType.NumOut() == 0 || funcType.NumOut() > 2 { + panic("Map function with an array must have one parameter and must return one or two parameters") + } + + arrElemType := arrValue.Type().Elem() + + // Checking whether element type is convertible to function's first argument's type. + if !arrElemType.ConvertibleTo(funcType.In(0)) { + panic("Map function's argument is not compatible with type of array.") + } + + if funcType.NumOut() == 1 { + // Get slice type corresponding to function's return value's type. + resultSliceType := reflect.SliceOf(funcType.Out(0)) + + // MakeSlice takes a slice kind type, and makes a slice. + resultSlice := reflect.MakeSlice(resultSliceType, 0, 0) + + for i := 0; i < arrValue.Len(); i++ { + result := funcValue.Call([]reflect.Value{arrValue.Index(i)})[0] + + resultSlice = reflect.Append(resultSlice, result) + } + + return resultSlice + } + + if funcType.NumOut() == 2 { + // value of the map will be the input type + collectionType := reflect.MapOf(funcType.Out(0), funcType.Out(1)) + + // create a map from scratch + collection := reflect.MakeMap(collectionType) + + for i := 0; i < arrValue.Len(); i++ { + results := funcValue.Call([]reflect.Value{arrValue.Index(i)}) + + collection.SetMapIndex(results[0], results[1]) + } + + return collection + } + + return reflect.Value{} +} + +func mapMap(arrValue reflect.Value, funcValue reflect.Value) reflect.Value { + funcType := funcValue.Type() + + if funcType.NumIn() != 2 || funcType.NumOut() == 0 || funcType.NumOut() > 2 { + panic("Map function with a map must have two parameters and must return one or two parameters") + } + + // Only one returned parameter, should be a slice + if funcType.NumOut() == 1 { + // Get slice type corresponding to function's return value's type. + resultSliceType := reflect.SliceOf(funcType.Out(0)) + + // MakeSlice takes a slice kind type, and makes a slice. + resultSlice := reflect.MakeSlice(resultSliceType, 0, 0) + + for _, key := range arrValue.MapKeys() { + results := funcValue.Call([]reflect.Value{key, arrValue.MapIndex(key)}) + + result := results[0] + + resultSlice = reflect.Append(resultSlice, result) + } + + return resultSlice + } + + // two parameters, should be a map + if funcType.NumOut() == 2 { + // value of the map will be the input type + collectionType := reflect.MapOf(funcType.Out(0), funcType.Out(1)) + + // create a map from scratch + collection := reflect.MakeMap(collectionType) + + for _, key := range arrValue.MapKeys() { + results := funcValue.Call([]reflect.Value{key, arrValue.MapIndex(key)}) + + collection.SetMapIndex(results[0], results[1]) + + } + + return collection + } + + return reflect.Value{} +} + +// Map manipulates an iteratee and transforms it to another type. +func Map(arr interface{}, mapFunc interface{}) interface{} { + result := mapFn(arr, mapFunc, "Map") + + if result.IsValid() { + return result.Interface() + } + + return nil +} + +func mapFn(arr interface{}, mapFunc interface{}, funcName string) reflect.Value { + if !IsIteratee(arr) { + panic("First parameter must be an iteratee") + } + + if !IsFunction(mapFunc) { + panic("Second argument must be function") + } + + var ( + funcValue = reflect.ValueOf(mapFunc) + arrValue = reflect.ValueOf(arr) + arrType = arrValue.Type() + ) + + kind := arrType.Kind() + + if kind == reflect.Slice || kind == reflect.Array { + return mapSlice(arrValue, funcValue) + } else if kind == reflect.Map { + return mapMap(arrValue, funcValue) + } + + panic(fmt.Sprintf("Type %s is not supported by "+funcName, arrType.String())) +} + +// FlatMap manipulates an iteratee and transforms it to a flattened collection of another type. +func FlatMap(arr interface{}, mapFunc interface{}) interface{} { + result := mapFn(arr, mapFunc, "FlatMap") + + if result.IsValid() { + return flatten(result).Interface() + } + + return nil +} + +// Flatten flattens a two-dimensional array. +func Flatten(out interface{}) interface{} { + return flatten(reflect.ValueOf(out)).Interface() +} + +func flatten(value reflect.Value) reflect.Value { + sliceType := value.Type() + + if (value.Kind() != reflect.Slice && value.Kind() != reflect.Array) || + (sliceType.Elem().Kind() != reflect.Slice && sliceType.Elem().Kind() != reflect.Array) { + panic("Argument must be an array or slice of at least two dimensions") + } + + resultSliceType := sliceType.Elem().Elem() + + resultSlice := reflect.MakeSlice(reflect.SliceOf(resultSliceType), 0, 0) + + length := value.Len() + + for i := 0; i < length; i++ { + item := value.Index(i) + + resultSlice = reflect.AppendSlice(resultSlice, item) + } + + return resultSlice +} + +// FlattenDeep recursively flattens array. +func FlattenDeep(out interface{}) interface{} { + return flattenDeep(reflect.ValueOf(out)).Interface() +} + +func flattenDeep(value reflect.Value) reflect.Value { + sliceType := sliceElem(value.Type()) + + resultSlice := reflect.MakeSlice(reflect.SliceOf(sliceType), 0, 0) + + return flattenRecursive(value, resultSlice) +} + +func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value { + length := value.Len() + + for i := 0; i < length; i++ { + item := value.Index(i) + kind := item.Kind() + + if kind == reflect.Slice || kind == reflect.Array { + result = flattenRecursive(item, result) + } else { + result = reflect.Append(result, item) + } + } + + return result +} + +// Shuffle creates an array of shuffled values +func Shuffle(in interface{}) interface{} { + value := reflect.ValueOf(in) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.Array || kind == reflect.Slice { + length := value.Len() + + resultSlice := makeSlice(value, length) + + for i, v := range rand.Perm(length) { + resultSlice.Index(i).Set(value.Index(v)) + } + + return resultSlice.Interface() + } + + panic(fmt.Sprintf("Type %s is not supported by Shuffle", valueType.String())) +} + +// Reverse transforms an array the first element will become the last, +// the second element will become the second to last, etc. +func Reverse(in interface{}) interface{} { + value := reflect.ValueOf(in) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.String { + return ReverseString(in.(string)) + } + + if kind == reflect.Array || kind == reflect.Slice { + length := value.Len() + + resultSlice := makeSlice(value, length) + + j := 0 + for i := length - 1; i >= 0; i-- { + resultSlice.Index(j).Set(value.Index(i)) + j++ + } + + return resultSlice.Interface() + } + + panic(fmt.Sprintf("Type %s is not supported by Reverse", valueType.String())) +} + +// Uniq creates an array with unique values. +func Uniq(in interface{}) interface{} { + value := reflect.ValueOf(in) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.Array || kind == reflect.Slice { + length := value.Len() + + result := makeSlice(value, 0) + + seen := make(map[interface{}]bool, length) + + for i := 0; i < length; i++ { + val := value.Index(i) + v := val.Interface() + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = true + result = reflect.Append(result, val) + } + + return result.Interface() + } + + panic(fmt.Sprintf("Type %s is not supported by Uniq", valueType.String())) +} + +// Uniq creates an array with unique values. +func UniqBy(in interface{}, mapFunc interface{}) interface{} { + if !IsFunction(mapFunc) { + panic("Second argument must be function") + } + + value := reflect.ValueOf(in) + valueType := value.Type() + + kind := value.Kind() + + funcValue := reflect.ValueOf(mapFunc) + + if kind == reflect.Array || kind == reflect.Slice { + length := value.Len() + + result := makeSlice(value, 0) + + seen := make(map[interface{}]bool, length) + + for i := 0; i < length; i++ { + val := value.Index(i) + v := funcValue.Call([]reflect.Value{val})[0].Interface() + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = true + result = reflect.Append(result, val) + } + + return result.Interface() + } + + panic(fmt.Sprintf("Type %s is not supported by Uniq", valueType.String())) +} + +// ConvertSlice converts a slice type to another, +// a perfect example would be to convert a slice of struct to a slice of interface. +func ConvertSlice(in interface{}, out interface{}) { + srcValue := reflect.ValueOf(in) + + dstValue := reflect.ValueOf(out) + + if dstValue.Kind() != reflect.Ptr { + panic("Second argument must be a pointer") + } + + dstValue = dstValue.Elem() + + if srcValue.Kind() != reflect.Slice && srcValue.Kind() != reflect.Array { + panic("First argument must be an array or slice") + } + + if dstValue.Kind() != reflect.Slice && dstValue.Kind() != reflect.Array { + panic("Second argument must be an array or slice") + } + + // returns value that points to dstValue + direct := reflect.Indirect(dstValue) + + length := srcValue.Len() + + for i := 0; i < length; i++ { + dstValue = reflect.Append(dstValue, srcValue.Index(i)) + } + + direct.Set(dstValue) +} + +// Drop creates an array/slice with `n` elements dropped from the beginning. +func Drop(in interface{}, n int) interface{} { + value := reflect.ValueOf(in) + valueType := value.Type() + + kind := value.Kind() + + if kind == reflect.Array || kind == reflect.Slice { + length := value.Len() + + resultSlice := makeSlice(value, length-n) + + j := 0 + for i := n; i < length; i++ { + resultSlice.Index(j).Set(value.Index(i)) + j++ + } + + return resultSlice.Interface() + + } + + panic(fmt.Sprintf("Type %s is not supported by Drop", valueType.String())) +} + +// Prune returns a copy of "in" that only contains fields in "paths" +// which are looked up using struct field name. +// For lookup paths by field tag instead, use funk.PruneByTag() +func Prune(in interface{}, paths []string) (interface{}, error) { + return pruneByTag(in, paths, nil /*tag*/) +} + +// pruneByTag returns a copy of "in" that only contains fields in "paths" +// which are looked up using struct field Tag "tag". +func PruneByTag(in interface{}, paths []string, tag string) (interface{}, error) { + return pruneByTag(in, paths, &tag) +} + +// pruneByTag returns a copy of "in" that only contains fields in "paths" +// which are looked up using struct field Tag "tag". If tag is nil, +// traverse paths using struct field name +func pruneByTag(in interface{}, paths []string, tag *string) (interface{}, error) { + inValue := reflect.ValueOf(in) + + ret := reflect.New(inValue.Type()).Elem() + + for _, path := range paths { + parts := strings.Split(path, ".") + if err := prune(inValue, ret, parts, tag); err != nil { + return nil, err + } + } + return ret.Interface(), nil +} + +func prune(inValue reflect.Value, ret reflect.Value, parts []string, tag *string) error { + if len(parts) == 0 { + // we reached the location that ret needs to hold inValue + // Note: The value at the end of the path is not copied, maybe we need to change. + // ret and the original data holds the same reference to this value + ret.Set(inValue) + return nil + } + + inKind := inValue.Kind() + + switch inKind { + case reflect.Ptr: + if inValue.IsNil() { + // TODO validate + return nil + } + if ret.IsNil() { + // init ret and go to next level + ret.Set(reflect.New(inValue.Type().Elem())) + } + return prune(inValue.Elem(), ret.Elem(), parts, tag) + case reflect.Struct: + part := parts[0] + var fValue reflect.Value + var fRet reflect.Value + if tag == nil { + // use field name + fValue = inValue.FieldByName(part) + if !fValue.IsValid() { + return fmt.Errorf("field name %v is not found in struct %v", part, inValue.Type().String()) + } + fRet = ret.FieldByName(part) + } else { + // search tag that has key equal to part + found := false + for i := 0; i < inValue.NumField(); i++ { + f := inValue.Type().Field(i) + if key, ok := f.Tag.Lookup(*tag); ok { + if key == part { + fValue = inValue.Field(i) + fRet = ret.Field(i) + found = true + break + } + } + } + if !found { + return fmt.Errorf("struct tag %v is not found with key %v", *tag, part) + } + } + // init Ret is zero and go down one more level + if fRet.IsZero() { + fRet.Set(reflect.New(fValue.Type()).Elem()) + } + return prune(fValue, fRet, parts[1:], tag) + case reflect.Array, reflect.Slice: + // set all its elements + length := inValue.Len() + // init ret + if ret.IsZero() { + if inKind == reflect.Slice { + ret.Set(reflect.MakeSlice(inValue.Type(), length /*len*/, length /*cap*/)) + } else { // array + ret.Set(reflect.New(inValue.Type()).Elem()) + } + } + for j := 0; j < length; j++ { + if err := prune(inValue.Index(j), ret.Index(j), parts, tag); err != nil { + return err + } + } + default: + return fmt.Errorf("path %v cannot be looked up on kind of %v", strings.Join(parts, "."), inValue.Kind()) + } + + return nil +} diff --git a/vendor/github.com/thoas/go-funk/typesafe.go b/vendor/github.com/thoas/go-funk/typesafe.go new file mode 100644 index 00000000000..2b240e5baff --- /dev/null +++ b/vendor/github.com/thoas/go-funk/typesafe.go @@ -0,0 +1,1200 @@ +package funk + +import ( + "math/rand" +) + +// InBools is an alias of ContainsBool, returns true if a bool is present in a iteratee. +func InBools(s []bool, v bool) bool { + return ContainsBool(s, v) +} + +// InInts is an alias of ContainsInt, returns true if an int is present in a iteratee. +func InInts(s []int, v int) bool { + return ContainsInt(s, v) +} + +// InInt32s is an alias of ContainsInt32, returns true if an int32 is present in a iteratee. +func InInt32s(s []int32, v int32) bool { + return ContainsInt32(s, v) +} + +// InInt64s is an alias of ContainsInt64, returns true if an int64 is present in a iteratee. +func InInt64s(s []int64, v int64) bool { + return ContainsInt64(s, v) +} + +// InUInts is an alias of ContainsUInt, returns true if an uint is present in a iteratee. +func InUInts(s []uint, v uint) bool { + return ContainsUInt(s, v) +} + +// InUInt32s is an alias of ContainsUInt32, returns true if an uint32 is present in a iteratee. +func InUInt32s(s []uint32, v uint32) bool { + return ContainsUInt32(s, v) +} + +// InUInt64s is an alias of ContainsUInt64, returns true if an uint64 is present in a iteratee. +func InUInt64s(s []uint64, v uint64) bool { + return ContainsUInt64(s, v) +} + +// InStrings is an alias of ContainsString, returns true if a string is present in a iteratee. +func InStrings(s []string, v string) bool { + return ContainsString(s, v) +} + +// InFloat32s is an alias of ContainsFloat32, returns true if a float32 is present in a iteratee. +func InFloat32s(s []float32, v float32) bool { + return ContainsFloat32(s, v) +} + +// InFloat64s is an alias of ContainsFloat64, returns true if a float64 is present in a iteratee. +func InFloat64s(s []float64, v float64) bool { + return ContainsFloat64(s, v) +} + +// FindFloat64 iterates over a collection of float64, returning an array of +// all float64 elements predicate returns truthy for. +func FindFloat64(s []float64, cb func(s float64) bool) (float64, bool) { + for _, i := range s { + result := cb(i) + + if result { + return i, true + } + } + + return 0.0, false +} + +// FindFloat32 iterates over a collection of float32, returning the first +// float32 element predicate returns truthy for. +func FindFloat32(s []float32, cb func(s float32) bool) (float32, bool) { + for _, i := range s { + result := cb(i) + + if result { + return i, true + } + } + + return 0.0, false +} + +// FindInt iterates over a collection of int, returning the first +// int element predicate returns truthy for. +func FindInt(s []int, cb func(s int) bool) (int, bool) { + for _, i := range s { + result := cb(i) + + if result { + return i, true + } + } + + return 0, false +} + +// FindInt32 iterates over a collection of int32, returning the first +// int32 element predicate returns truthy for. +func FindInt32(s []int32, cb func(s int32) bool) (int32, bool) { + for _, i := range s { + result := cb(i) + + if result { + return i, true + } + } + + return 0, false +} + +// FindInt64 iterates over a collection of int64, returning the first +// int64 element predicate returns truthy for. +func FindInt64(s []int64, cb func(s int64) bool) (int64, bool) { + for _, i := range s { + result := cb(i) + + if result { + return i, true + } + } + + return 0, false +} + +// FindString iterates over a collection of string, returning the first +// string element predicate returns truthy for. +func FindString(s []string, cb func(s string) bool) (string, bool) { + for _, i := range s { + result := cb(i) + + if result { + return i, true + } + } + + return "", false +} + +// FilterBool iterates over a collection of bool, returning an array of +// all bool elements predicate returns truthy for. +func FilterBool(s []bool, cb func(s bool) bool) []bool { + results := []bool{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterFloat64 iterates over a collection of float64, returning an array of +// all float64 elements predicate returns truthy for. +func FilterFloat64(s []float64, cb func(s float64) bool) []float64 { + results := []float64{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterFloat32 iterates over a collection of float32, returning an array of +// all float32 elements predicate returns truthy for. +func FilterFloat32(s []float32, cb func(s float32) bool) []float32 { + results := []float32{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterInt iterates over a collection of int, returning an array of +// all int elements predicate returns truthy for. +func FilterInt(s []int, cb func(s int) bool) []int { + results := []int{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterInt32 iterates over a collection of int32, returning an array of +// all int32 elements predicate returns truthy for. +func FilterInt32(s []int32, cb func(s int32) bool) []int32 { + results := []int32{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterInt64 iterates over a collection of int64, returning an array of +// all int64 elements predicate returns truthy for. +func FilterInt64(s []int64, cb func(s int64) bool) []int64 { + results := []int64{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterUInt iterates over a collection of uint, returning an array of +// all uint elements predicate returns truthy for. +func FilterUInt(s []uint, cb func(s uint) bool) []uint { + results := []uint{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterUInt32 iterates over a collection of uint32, returning an array of +// all uint32 elements predicate returns truthy for. +func FilterUInt32(s []uint32, cb func(s uint32) bool) []uint32 { + results := []uint32{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterUInt64 iterates over a collection of uint64, returning an array of +// all uint64 elements predicate returns truthy for. +func FilterUInt64(s []uint64, cb func(s uint64) bool) []uint64 { + results := []uint64{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// FilterString iterates over a collection of string, returning an array of +// all string elements predicate returns truthy for. +func FilterString(s []string, cb func(s string) bool) []string { + results := []string{} + + for _, i := range s { + result := cb(i) + + if result { + results = append(results, i) + } + } + + return results +} + +// ContainsBool returns true if a boolean is present in a iteratee. +func ContainsBool(s []bool, v bool) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsInt returns true if an int is present in a iteratee. +func ContainsInt(s []int, v int) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsInt32 returns true if an int32 is present in a iteratee. +func ContainsInt32(s []int32, v int32) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsInt64 returns true if an int64 is present in a iteratee. +func ContainsInt64(s []int64, v int64) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsUInt returns true if an uint is present in a iteratee. +func ContainsUInt(s []uint, v uint) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsUInt32 returns true if an uint32 is present in a iteratee. +func ContainsUInt32(s []uint32, v uint32) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsUInt64 returns true if an uint64 is present in a iteratee. +func ContainsUInt64(s []uint64, v uint64) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsString returns true if a string is present in a iteratee. +func ContainsString(s []string, v string) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsFloat32 returns true if a float32 is present in a iteratee. +func ContainsFloat32(s []float32, v float32) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// ContainsFloat64 returns true if a float64 is present in a iteratee. +func ContainsFloat64(s []float64, v float64) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} + +// SumInt32 sums a int32 iteratee and returns the sum of all elements +func SumInt32(s []int32) (sum int32) { + for _, v := range s { + sum += v + } + return +} + +// SumInt64 sums a int64 iteratee and returns the sum of all elements +func SumInt64(s []int64) (sum int64) { + for _, v := range s { + sum += v + } + return +} + +// SumInt sums a int iteratee and returns the sum of all elements +func SumInt(s []int) (sum int) { + for _, v := range s { + sum += v + } + return +} + +// SumUInt32 sums a uint32 iteratee and returns the sum of all elements +func SumUInt32(s []uint32) (sum uint32) { + for _, v := range s { + sum += v + } + return +} + +// SumUInt64 sums a uint64 iteratee and returns the sum of all elements +func SumUInt64(s []uint64) (sum uint64) { + for _, v := range s { + sum += v + } + return +} + +// SumUInt sums a uint iteratee and returns the sum of all elements +func SumUInt(s []uint) (sum uint) { + for _, v := range s { + sum += v + } + return +} + +// SumFloat64 sums a float64 iteratee and returns the sum of all elements +func SumFloat64(s []float64) (sum float64) { + for _, v := range s { + sum += v + } + return +} + +// SumFloat32 sums a float32 iteratee and returns the sum of all elements +func SumFloat32(s []float32) (sum float32) { + for _, v := range s { + sum += v + } + return +} + +// ReverseBools reverses an array of bool +func ReverseBools(s []bool) []bool { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseStrings reverses an array of string +func ReverseStrings(s []string) []string { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseInt reverses an array of int +func ReverseInt(s []int) []int { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseInt32 reverses an array of int32 +func ReverseInt32(s []int32) []int32 { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseInt64 reverses an array of int64 +func ReverseInt64(s []int64) []int64 { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseUInt reverses an array of int +func ReverseUInt(s []uint) []uint { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseUInt32 reverses an array of uint32 +func ReverseUInt32(s []uint32) []uint32 { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseUInt64 reverses an array of uint64 +func ReverseUInt64(s []uint64) []uint64 { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseFloat64 reverses an array of float64 +func ReverseFloat64(s []float64) []float64 { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseFloat32 reverses an array of float32 +func ReverseFloat32(s []float32) []float32 { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// ReverseString reverses a string +func ReverseString(s string) string { + r := []rune(s) + for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { + r[i], r[j] = r[j], r[i] + } + return string(r) +} + +func indexOf(n int, f func(int) bool) int { + for i := 0; i < n; i++ { + if f(i) { + return i + } + } + return -1 +} + +// IndexOfBool gets the index at which the first occurrence of a bool value is found in array or return -1 +// if the value cannot be found +func IndexOfBool(a []bool, x bool) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// IndexOfInt gets the index at which the first occurrence of an int value is found in array or return -1 +// if the value cannot be found +func IndexOfInt(a []int, x int) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// IndexOfInt32 gets the index at which the first occurrence of an int32 value is found in array or return -1 +// if the value cannot be found +func IndexOfInt32(a []int32, x int32) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// IndexOfInt64 gets the index at which the first occurrence of an int64 value is found in array or return -1 +// if the value cannot be found +func IndexOfInt64(a []int64, x int64) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// IndexOfUInt gets the index at which the first occurrence of an uint value is found in array or return -1 +// if the value cannot be found +func IndexOfUInt(a []uint, x uint) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// IndexOfUInt32 gets the index at which the first occurrence of an uint32 value is found in array or return -1 +// if the value cannot be found +func IndexOfUInt32(a []uint32, x uint32) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// IndexOfUInt64 gets the index at which the first occurrence of an uint64 value is found in array or return -1 +// if the value cannot be found +func IndexOfUInt64(a []uint64, x uint64) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// IndexOfFloat64 gets the index at which the first occurrence of an float64 value is found in array or return -1 +// if the value cannot be found +func IndexOfFloat64(a []float64, x float64) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// IndexOfString gets the index at which the first occurrence of a string value is found in array or return -1 +// if the value cannot be found +func IndexOfString(a []string, x string) int { + return indexOf(len(a), func(i int) bool { return a[i] == x }) +} + +func lastIndexOf(n int, f func(int) bool) int { + for i := n - 1; i >= 0; i-- { + if f(i) { + return i + } + } + return -1 +} + +// LastIndexOfBool gets the index at which the first occurrence of a bool value is found in array or return -1 +// if the value cannot be found +func LastIndexOfBool(a []bool, x bool) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfInt gets the index at which the first occurrence of an int value is found in array or return -1 +// if the value cannot be found +func LastIndexOfInt(a []int, x int) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfInt32 gets the index at which the first occurrence of an int32 value is found in array or return -1 +// if the value cannot be found +func LastIndexOfInt32(a []int32, x int32) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfInt64 gets the index at which the first occurrence of an int64 value is found in array or return -1 +// if the value cannot be found +func LastIndexOfInt64(a []int64, x int64) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfUInt gets the index at which the first occurrence of an uint value is found in array or return -1 +// if the value cannot be found +func LastIndexOfUInt(a []uint, x uint) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfUInt32 gets the index at which the first occurrence of an uint32 value is found in array or return -1 +// if the value cannot be found +func LastIndexOfUInt32(a []uint32, x uint32) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfUInt64 gets the index at which the first occurrence of an uint64 value is found in array or return -1 +// if the value cannot be found +func LastIndexOfUInt64(a []uint64, x uint64) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfFloat64 gets the index at which the first occurrence of an float64 value is found in array or return -1 +// if the value cannot be found +func LastIndexOfFloat64(a []float64, x float64) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfFloat32 gets the index at which the first occurrence of an float32 value is found in array or return -1 +// if the value cannot be found +func LastIndexOfFloat32(a []float32, x float32) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// LastIndexOfString gets the index at which the first occurrence of a string value is found in array or return -1 +// if the value cannot be found +func LastIndexOfString(a []string, x string) int { + return lastIndexOf(len(a), func(i int) bool { return a[i] == x }) +} + +// UniqBool creates an array of bool with unique values. +func UniqBool(a []bool) []bool { + results := []bool{} + for _, value := range a { + // If results is not empty, there is at most 1 value in it + if len(results) == 0 || results[0] != value { + results = append(results, value) + } + // At most 2 unique values + if len(results) == 2 { + break + } + } + return results +} + +// UniqInt32 creates an array of int32 with unique values. +func UniqInt32(a []int32) []int32 { + var ( + length = len(a) + seen = make(map[int32]struct{}, length) + results = make([]int32, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// UniqInt64 creates an array of int64 with unique values. +func UniqInt64(a []int64) []int64 { + var ( + length = len(a) + seen = make(map[int64]struct{}, length) + results = make([]int64, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// UniqInt creates an array of int with unique values. +func UniqInt(a []int) []int { + var ( + length = len(a) + seen = make(map[int]struct{}, length) + results = make([]int, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// UniqUInt32 creates an array of uint32 with unique values. +func UniqUInt32(a []uint32) []uint32 { + var ( + length = len(a) + seen = make(map[uint32]struct{}, length) + results = make([]uint32, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// UniqUInt64 creates an array of uint64 with unique values. +func UniqUInt64(a []uint64) []uint64 { + var ( + length = len(a) + seen = make(map[uint64]struct{}, length) + results = make([]uint64, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// UniqUInt creates an array of uint with unique values. +func UniqUInt(a []uint) []uint { + var ( + length = len(a) + seen = make(map[uint]struct{}, length) + results = make([]uint, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// UniqString creates an array of string with unique values. +func UniqString(a []string) []string { + var ( + length = len(a) + seen = make(map[string]struct{}, length) + results = make([]string, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// UniqFloat64 creates an array of float64 with unique values. +func UniqFloat64(a []float64) []float64 { + var ( + length = len(a) + seen = make(map[float64]struct{}, length) + results = make([]float64, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// UniqFloat32 creates an array of float32 with unique values. +func UniqFloat32(a []float32) []float32 { + var ( + length = len(a) + seen = make(map[float32]struct{}, length) + results = make([]float32, 0) + ) + + for i := 0; i < length; i++ { + v := a[i] + + if _, ok := seen[v]; ok { + continue + } + + seen[v] = struct{}{} + results = append(results, v) + } + + return results +} + +// ShuffleBool creates an array of bool shuffled values using Fisher–Yates algorithm +func ShuffleBool(a []bool) []bool { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleInt creates an array of int shuffled values using Fisher–Yates algorithm +func ShuffleInt(a []int) []int { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleInt32 creates an array of int32 shuffled values using Fisher–Yates algorithm +func ShuffleInt32(a []int32) []int32 { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleInt64 creates an array of int64 shuffled values using Fisher–Yates algorithm +func ShuffleInt64(a []int64) []int64 { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleUInt creates an array of int shuffled values using Fisher–Yates algorithm +func ShuffleUInt(a []uint) []uint { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleUInt32 creates an array of uint32 shuffled values using Fisher–Yates algorithm +func ShuffleUInt32(a []uint32) []uint32 { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleUInt64 creates an array of uint64 shuffled values using Fisher–Yates algorithm +func ShuffleUInt64(a []uint64) []uint64 { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleString creates an array of string shuffled values using Fisher–Yates algorithm +func ShuffleString(a []string) []string { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleFloat32 creates an array of float32 shuffled values using Fisher–Yates algorithm +func ShuffleFloat32(a []float32) []float32 { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// ShuffleFloat64 creates an array of float64 shuffled values using Fisher–Yates algorithm +func ShuffleFloat64(a []float64) []float64 { + for i := range a { + j := rand.Intn(i + 1) + a[i], a[j] = a[j], a[i] + } + + return a +} + +// DropBool creates a slice with `n` bools dropped from the beginning. +func DropBool(s []bool, n int) []bool { + return s[n:] +} + +// DropString creates a slice with `n` strings dropped from the beginning. +func DropString(s []string, n int) []string { + return s[n:] +} + +// DropInt creates a slice with `n` ints dropped from the beginning. +func DropInt(s []int, n int) []int { + return s[n:] +} + +// DropInt32 creates a slice with `n` int32s dropped from the beginning. +func DropInt32(s []int32, n int) []int32 { + return s[n:] +} + +// DropInt64 creates a slice with `n` int64s dropped from the beginning. +func DropInt64(s []int64, n int) []int64 { + return s[n:] +} + +// DropUInt creates a slice with `n` ints dropped from the beginning. +func DropUInt(s []uint, n uint) []uint { + return s[n:] +} + +// DropUInt32 creates a slice with `n` int32s dropped from the beginning. +func DropUInt32(s []uint32, n int) []uint32 { + return s[n:] +} + +// DropUInt64 creates a slice with `n` int64s dropped from the beginning. +func DropUInt64(s []uint64, n int) []uint64 { + return s[n:] +} + +// DropFloat32 creates a slice with `n` float32s dropped from the beginning. +func DropFloat32(s []float32, n int) []float32 { + return s[n:] +} + +// DropFloat64 creates a slice with `n` float64s dropped from the beginning. +func DropFloat64(s []float64, n int) []float64 { + return s[n:] +} + +// ChunkStrings creates an array of strings split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func ChunkStrings(arr []string, size int) [][]string { + var results [][]string + + for i := 0; i < len(arr); i += size { + end := i + size + + if end > len(arr) { + end = len(arr) + } + + results = append(results, arr[i:end]) + } + + return results +} + +// ChunkInts creates an array of ints split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func ChunkInts(arr []int, size int) [][]int { + var results [][]int + + for i := 0; i < len(arr); i += size { + end := i + size + + if end > len(arr) { + end = len(arr) + } + + results = append(results, arr[i:end]) + } + + return results +} + +// ChunkInt32s creates an array of int32s split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func ChunkInt32s(arr []int32, size int) [][]int32 { + var results [][]int32 + + for i := 0; i < len(arr); i += size { + end := i + size + + if end > len(arr) { + end = len(arr) + } + + results = append(results, arr[i:end]) + } + + return results +} + +// ChunkInt64s creates an array of int64s split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func ChunkInt64s(arr []int64, size int) [][]int64 { + var results [][]int64 + + for i := 0; i < len(arr); i += size { + end := i + size + + if end > len(arr) { + end = len(arr) + } + + results = append(results, arr[i:end]) + } + + return results +} + +// ChunkUInts creates an array of uints split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func ChunkUInts(arr []uint, size int) [][]uint { + var results [][]uint + + for i := 0; i < len(arr); i += size { + end := i + size + + if end > len(arr) { + end = len(arr) + } + + results = append(results, arr[i:end]) + } + + return results +} + +// ChunkUInt32s creates an array of uint32s split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func ChunkUInt32s(arr []uint32, size int) [][]uint32 { + var results [][]uint32 + + for i := 0; i < len(arr); i += size { + end := i + size + + if end > len(arr) { + end = len(arr) + } + + results = append(results, arr[i:end]) + } + + return results +} + +// ChunkUInt64s creates an array of uint64s split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func ChunkUInt64s(arr []uint64, size int) [][]uint64 { + var results [][]uint64 + + for i := 0; i < len(arr); i += size { + end := i + size + + if end > len(arr) { + end = len(arr) + } + + results = append(results, arr[i:end]) + } + + return results +} + +// ChunkFloat64s creates an array of float64s split into groups with the length of size. +// If array can't be split evenly, the final chunk will be +// the remaining element. +func ChunkFloat64s(arr []float64, size int) [][]float64 { + var results [][]float64 + + for i := 0; i < len(arr); i += size { + end := i + size + + if end > len(arr) { + end = len(arr) + } + + results = append(results, arr[i:end]) + } + + return results +} diff --git a/vendor/github.com/thoas/go-funk/union.go b/vendor/github.com/thoas/go-funk/union.go new file mode 100644 index 00000000000..559cdd543af --- /dev/null +++ b/vendor/github.com/thoas/go-funk/union.go @@ -0,0 +1,67 @@ +package funk + +import ( + "reflect" +) + +// Union returns the union between two collections. +func Union(collections ...interface{}) interface{} { + // shortcut zero/single argument + if len(collections) == 0 { + return nil + } else if len(collections) == 1 { + return collections[0] + } + + if !IsIteratee(collections[0]) { + panic("Parameter must be a collection") + } + + cType := reflect.TypeOf(collections[0]) + zLen := 0 + + for i, x := range collections { + xValue := reflect.ValueOf(x) + xType := xValue.Type() + if i > 0 && NotEqual(cType, xType) { + panic("Parameters must have the same type") + } + + zLen += xValue.Len() + } + + if cType.Kind() == reflect.Map { + zType := reflect.MapOf(cType.Key(), cType.Elem()) + zMap := reflect.MakeMap(zType) + + for _, x := range collections { + xIter := reflect.ValueOf(x).MapRange() + for xIter.Next() { + zMap.SetMapIndex(xIter.Key(), xIter.Value()) + } + } + + return zMap.Interface() + } else { + zType := reflect.SliceOf(cType.Elem()) + zSlice := reflect.MakeSlice(zType, 0, 0) + + for _, x := range collections { + xValue := reflect.ValueOf(x) + zSlice = reflect.AppendSlice(zSlice, xValue) + } + + return zSlice.Interface() + } +} + +// UnionStringMap returns the union between multiple string maps +func UnionStringMap(x ...map[string]string) map[string]string { + zMap := map[string]string{} + for _, xMap := range x { + for k, v := range xMap { + zMap[k] = v + } + } + return zMap +} diff --git a/vendor/github.com/thoas/go-funk/utils.go b/vendor/github.com/thoas/go-funk/utils.go new file mode 100644 index 00000000000..43d9a2be73a --- /dev/null +++ b/vendor/github.com/thoas/go-funk/utils.go @@ -0,0 +1,103 @@ +package funk + +import ( + "fmt" + "reflect" +) + +func equal(expectedOrPredicate interface{}, optionalIsMap ...bool) func(keyValueIfMap, actualValue reflect.Value) bool { + isMap := append(optionalIsMap, false)[0] + + if IsFunction(expectedOrPredicate) { + inTypes := []reflect.Type{nil}; if isMap { + inTypes = append(inTypes, nil) + } + + if !IsPredicate(expectedOrPredicate, inTypes...) { + panic(fmt.Sprintf("Predicate function must have %d parameter and must return boolean", len(inTypes))) + } + + predicateValue := reflect.ValueOf(expectedOrPredicate) + + return func(keyValueIfMap, actualValue reflect.Value) bool { + + if isMap && !keyValueIfMap.Type().ConvertibleTo(predicateValue.Type().In(0)) { + panic("Given key is not compatible with type of parameter for the predicate.") + } + + if (isMap && !actualValue.Type().ConvertibleTo(predicateValue.Type().In(1))) || + (!isMap && !actualValue.Type().ConvertibleTo(predicateValue.Type().In(0))) { + panic("Given value is not compatible with type of parameter for the predicate.") + } + + args := []reflect.Value{actualValue} + if isMap { + args = append([]reflect.Value{keyValueIfMap}, args...) + } + + return predicateValue.Call(args)[0].Bool() + } + } + + expected := expectedOrPredicate + + return func(keyValueIfMap, actualValue reflect.Value) bool { + if isMap { + actualValue = keyValueIfMap + } + + if expected == nil || actualValue.IsZero() { + return actualValue.Interface() == expected + } + + return reflect.DeepEqual(actualValue.Interface(), expected) + } +} + +func sliceElem(rtype reflect.Type) reflect.Type { + for { + if rtype.Kind() != reflect.Slice && rtype.Kind() != reflect.Array { + return rtype + } + + rtype = rtype.Elem() + } +} + +func redirectValue(value reflect.Value) reflect.Value { + for { + if !value.IsValid() || (value.Kind() != reflect.Ptr && value.Kind() != reflect.Interface) { + return value + } + + res := value.Elem() + + // Test for a circular type. + if res.Kind() == reflect.Ptr && value.Kind() == reflect.Ptr && value.Pointer() == res.Pointer() { + return value + } + + if !res.IsValid() && value.Kind() == reflect.Ptr { + return reflect.Zero(value.Type().Elem()) + } + + value = res + } +} + +func makeSlice(value reflect.Value, values ...int) reflect.Value { + sliceType := sliceElem(value.Type()) + + size := value.Len() + cap := size + + if len(values) > 0 { + size = values[0] + } + + if len(values) > 1 { + cap = values[1] + } + + return reflect.MakeSlice(reflect.SliceOf(sliceType), size, cap) +} diff --git a/vendor/github.com/thoas/go-funk/without.go b/vendor/github.com/thoas/go-funk/without.go new file mode 100644 index 00000000000..6e35e986993 --- /dev/null +++ b/vendor/github.com/thoas/go-funk/without.go @@ -0,0 +1,19 @@ +package funk + +import "reflect" + +// Without creates an array excluding all given values. +func Without(in interface{}, values ...interface{}) interface{} { + if !IsCollection(in) { + panic("First parameter must be a collection") + } + + inValue := reflect.ValueOf(in) + for _, value := range values { + if NotEqual(inValue.Type().Elem(), reflect.TypeOf(value)) { + panic("Values must have the same type") + } + } + + return LeftJoin(inValue, reflect.ValueOf(values)).Interface() +} diff --git a/vendor/github.com/thoas/go-funk/zip.go b/vendor/github.com/thoas/go-funk/zip.go new file mode 100644 index 00000000000..dcd38287faf --- /dev/null +++ b/vendor/github.com/thoas/go-funk/zip.go @@ -0,0 +1,44 @@ +package funk + +import ( + "reflect" +) + +// Tuple is the return type of Zip +type Tuple struct { + Element1 interface{} + Element2 interface{} +} + +// Zip returns a list of tuples, where the i-th tuple contains the i-th element +// from each of the input iterables. The returned list is truncated in length +// to the length of the shortest input iterable. +func Zip(slice1 interface{}, slice2 interface{}) []Tuple { + if !IsCollection(slice1) || !IsCollection(slice2) { + panic("First parameter must be a collection") + } + + var ( + minLength int + inValue1 = reflect.ValueOf(slice1) + inValue2 = reflect.ValueOf(slice2) + result = []Tuple{} + length1 = inValue1.Len() + length2 = inValue2.Len() + ) + + if length1 <= length2 { + minLength = length1 + } else { + minLength = length2 + } + + for i := 0; i < minLength; i++ { + newTuple := Tuple{ + Element1: inValue1.Index(i).Interface(), + Element2: inValue2.Index(i).Interface(), + } + result = append(result, newTuple) + } + return result +} diff --git a/vendor/modules.txt b/vendor/modules.txt index d0ea1ccc98f..d57f033479a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1054,12 +1054,15 @@ github.com/openshift/api/route/v1 ## explicit; go 1.21 github.com/openshift/assisted-image-service/pkg/isoeditor github.com/openshift/assisted-image-service/pkg/overlay -# github.com/openshift/assisted-service/api v0.0.0 => github.com/openshift/assisted-service/api v0.0.0-20230831114549-1922eda29cf8 +# github.com/openshift/assisted-service v1.0.10-0.20230830164851-6573b5d7021d +## explicit; go 1.18 +github.com/openshift/assisted-service/pkg/validations +# github.com/openshift/assisted-service/api v0.0.0 => github.com/openshift/assisted-service/api v0.0.0-20231215152050-d41f53691d6e ## explicit; go 1.18 github.com/openshift/assisted-service/api/common github.com/openshift/assisted-service/api/hiveextension/v1beta1 github.com/openshift/assisted-service/api/v1beta1 -# github.com/openshift/assisted-service/client v0.0.0 => github.com/openshift/assisted-service/client v0.0.0-20230831114549-1922eda29cf8 +# github.com/openshift/assisted-service/client v0.0.0 => github.com/openshift/assisted-service/client v0.0.0-20231215152050-d41f53691d6e ## explicit; go 1.18 github.com/openshift/assisted-service/client github.com/openshift/assisted-service/client/events @@ -1068,7 +1071,7 @@ github.com/openshift/assisted-service/client/managed_domains github.com/openshift/assisted-service/client/manifests github.com/openshift/assisted-service/client/operators github.com/openshift/assisted-service/client/versions -# github.com/openshift/assisted-service/models v0.0.0 => github.com/openshift/assisted-service/models v0.0.0-20230831114549-1922eda29cf8 +# github.com/openshift/assisted-service/models v0.0.0 => github.com/openshift/assisted-service/models v0.0.0-20231215152050-d41f53691d6e ## explicit; go 1.18 github.com/openshift/assisted-service/models # github.com/openshift/client-go v0.0.0-20240528061634-b054aa794d87 @@ -1267,6 +1270,9 @@ github.com/syndtr/gocapability/capability # github.com/thedevsaddam/retry v0.0.0-20200324223450-9769a859cc6d ## explicit; go 1.13 github.com/thedevsaddam/retry +# github.com/thoas/go-funk v0.9.3 +## explicit; go 1.13 +github.com/thoas/go-funk # github.com/ulikunitz/xz v0.5.12 ## explicit; go 1.12 github.com/ulikunitz/xz @@ -2374,7 +2380,7 @@ sigs.k8s.io/yaml/goyaml.v3 # github.com/metal3-io/baremetal-operator/pkg/hardwareutils => github.com/openshift/baremetal-operator/pkg/hardwareutils v0.0.0-20231128154154-6736c9b9c6c8 # k8s.io/cloud-provider-vsphere => github.com/openshift/cloud-provider-vsphere v1.19.1-0.20211222185833-7829863d0558 # sigs.k8s.io/cluster-api-provider-ibmcloud => sigs.k8s.io/cluster-api-provider-ibmcloud v0.9.0-alpha.0.0.20240913094112-c6bcd313bce0 -# github.com/openshift/assisted-service/api => github.com/openshift/assisted-service/api v0.0.0-20230831114549-1922eda29cf8 -# github.com/openshift/assisted-service/client => github.com/openshift/assisted-service/client v0.0.0-20230831114549-1922eda29cf8 -# github.com/openshift/assisted-service/models => github.com/openshift/assisted-service/models v0.0.0-20230831114549-1922eda29cf8 +# github.com/openshift/assisted-service/api => github.com/openshift/assisted-service/api v0.0.0-20231215152050-d41f53691d6e +# github.com/openshift/assisted-service/client => github.com/openshift/assisted-service/client v0.0.0-20231215152050-d41f53691d6e +# github.com/openshift/assisted-service/models => github.com/openshift/assisted-service/models v0.0.0-20231215152050-d41f53691d6e # github.com/containerd/containerd => github.com/containerd/containerd v1.6.26