diff --git a/collector.go b/collector.go index 3a41979c..be6a3c27 100644 --- a/collector.go +++ b/collector.go @@ -14,6 +14,7 @@ package main import ( + "context" "encoding/binary" "fmt" "net" @@ -82,9 +83,10 @@ func listToOid(l []int) string { return strings.Join(result, ".") } -func ScrapeTarget(target string, config *config.Module, logger log.Logger) ([]gosnmp.SnmpPDU, error) { +func ScrapeTarget(ctx context.Context, target string, config *config.Module, logger log.Logger) ([]gosnmp.SnmpPDU, error) { // Set the options. snmp := gosnmp.GoSNMP{} + snmp.Context = ctx snmp.MaxRepetitions = config.WalkParams.MaxRepetitions // User specifies timeout of each retry attempt but GoSNMP expects total timeout for all attempts. snmp.Retries = config.WalkParams.Retries @@ -195,6 +197,7 @@ func buildMetricTree(metrics []*config.Metric) *MetricNode { } type collector struct { + ctx context.Context target string module *config.Module logger log.Logger @@ -208,7 +211,7 @@ func (c collector) Describe(ch chan<- *prometheus.Desc) { // Collect implements Prometheus.Collector. func (c collector) Collect(ch chan<- prometheus.Metric) { start := time.Now() - pdus, err := ScrapeTarget(c.target, c.module, c.logger) + pdus, err := ScrapeTarget(c.ctx, c.target, c.module, c.logger) if err != nil { level.Info(c.logger).Log("msg", "Error scraping target", "err", err) ch <- prometheus.NewInvalidMetric(prometheus.NewDesc("snmp_error", "Error scraping target", nil, nil), err) diff --git a/go.mod b/go.mod index 3e97af8d..d90548c2 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,11 @@ module github.com/prometheus/snmp_exporter require ( github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect github.com/go-kit/kit v0.9.0 - github.com/golang/mock v1.3.1 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/prometheus/client_golang v1.2.1 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 github.com/prometheus/common v0.7.0 - github.com/soniah/gosnmp v1.22.0 + github.com/soniah/gosnmp v1.23.1-0.20200214014533-6d3944030084 golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 // indirect gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect diff --git a/go.sum b/go.sum index e9355430..a2a1b0bd 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,6 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= @@ -89,8 +87,8 @@ github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQl github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/soniah/gosnmp v1.22.0 h1:jVJi8+OGvR+JHIaZKMmnyNP0akJd2vEgNatybwhZvxg= -github.com/soniah/gosnmp v1.22.0/go.mod h1:DuEpAS0az51+DyVBQwITDsoq4++e3LTNckp2GoasF2I= +github.com/soniah/gosnmp v1.23.1-0.20200214014533-6d3944030084 h1:ZIBlrzG+IO20XFoyi3UlmJ6n58OEiosnALRevXkdIGM= +github.com/soniah/gosnmp v1.23.1-0.20200214014533-6d3944030084/go.mod h1:DuEpAS0az51+DyVBQwITDsoq4++e3LTNckp2GoasF2I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= @@ -102,12 +100,10 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -116,7 +112,6 @@ golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/main.go b/main.go index 35692a2d..788c0725 100644 --- a/main.go +++ b/main.go @@ -100,7 +100,7 @@ func handler(w http.ResponseWriter, r *http.Request, logger log.Logger) { start := time.Now() registry := prometheus.NewRegistry() - collector := collector{target: target, module: module, logger: logger} + collector := collector{ctx: r.Context(), target: target, module: module, logger: logger} registry.MustRegister(collector) // Delegate http serving to Prometheus client library, which will call collector.Collect. h := promhttp.HandlerFor(registry, promhttp.HandlerOpts{}) diff --git a/vendor/github.com/golang/mock/AUTHORS b/vendor/github.com/golang/mock/AUTHORS deleted file mode 100644 index 660b8ccc..00000000 --- a/vendor/github.com/golang/mock/AUTHORS +++ /dev/null @@ -1,12 +0,0 @@ -# This is the official list of GoMock authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS files. -# See the latter for an explanation. - -# Names should be added to this file as -# Name or Organization -# The email address is not required for organizations. - -# Please keep the list sorted. - -Alex Reece -Google Inc. diff --git a/vendor/github.com/golang/mock/CONTRIBUTORS b/vendor/github.com/golang/mock/CONTRIBUTORS deleted file mode 100644 index def849ca..00000000 --- a/vendor/github.com/golang/mock/CONTRIBUTORS +++ /dev/null @@ -1,37 +0,0 @@ -# This is the official list of people who can contribute (and typically -# have contributed) code to the gomock repository. -# The AUTHORS file lists the copyright holders; this file -# lists people. For example, Google employees are listed here -# but not in AUTHORS, because Google holds the copyright. -# -# The submission process automatically checks to make sure -# that people submitting code are listed in this file (by email address). -# -# Names should be added to this file only after verifying that -# the individual or the individual's organization has agreed to -# the appropriate Contributor License Agreement, found here: -# -# http://code.google.com/legal/individual-cla-v1.0.html -# http://code.google.com/legal/corporate-cla-v1.0.html -# -# The agreement for individuals can be filled out on the web. -# -# When adding J Random Contributor's name to this file, -# either J's name or J's organization's name should be -# added to the AUTHORS file, depending on whether the -# individual or corporate CLA was used. - -# Names should be added to this file like so: -# Name -# -# An entry with two email addresses specifies that the -# first address should be used in the submit logs and -# that the second address should be recognized as the -# same person when interacting with Rietveld. - -# Please keep the list sorted. - -Aaron Jacobs -Alex Reece -David Symonds -Ryan Barrett diff --git a/vendor/github.com/golang/mock/LICENSE b/vendor/github.com/golang/mock/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/github.com/golang/mock/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/golang/mock/gomock/call.go b/vendor/github.com/golang/mock/gomock/call.go deleted file mode 100644 index 3d54d9f5..00000000 --- a/vendor/github.com/golang/mock/gomock/call.go +++ /dev/null @@ -1,420 +0,0 @@ -// Copyright 2010 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gomock - -import ( - "fmt" - "reflect" - "strconv" - "strings" -) - -// Call represents an expected call to a mock. -type Call struct { - t TestHelper // for triggering test failures on invalid call setup - - receiver interface{} // the receiver of the method call - method string // the name of the method - methodType reflect.Type // the type of the method - args []Matcher // the args - origin string // file and line number of call setup - - preReqs []*Call // prerequisite calls - - // Expectations - minCalls, maxCalls int - - numCalls int // actual number made - - // actions are called when this Call is called. Each action gets the args and - // can set the return values by returning a non-nil slice. Actions run in the - // order they are created. - actions []func([]interface{}) []interface{} -} - -// newCall creates a *Call. It requires the method type in order to support -// unexported methods. -func newCall(t TestHelper, receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call { - t.Helper() - - // TODO: check arity, types. - margs := make([]Matcher, len(args)) - for i, arg := range args { - if m, ok := arg.(Matcher); ok { - margs[i] = m - } else if arg == nil { - // Handle nil specially so that passing a nil interface value - // will match the typed nils of concrete args. - margs[i] = Nil() - } else { - margs[i] = Eq(arg) - } - } - - origin := callerInfo(3) - actions := []func([]interface{}) []interface{}{func([]interface{}) []interface{} { - // Synthesize the zero value for each of the return args' types. - rets := make([]interface{}, methodType.NumOut()) - for i := 0; i < methodType.NumOut(); i++ { - rets[i] = reflect.Zero(methodType.Out(i)).Interface() - } - return rets - }} - return &Call{t: t, receiver: receiver, method: method, methodType: methodType, - args: margs, origin: origin, minCalls: 1, maxCalls: 1, actions: actions} -} - -// AnyTimes allows the expectation to be called 0 or more times -func (c *Call) AnyTimes() *Call { - c.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity - return c -} - -// MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called, MinTimes also -// sets the maximum number of calls to infinity. -func (c *Call) MinTimes(n int) *Call { - c.minCalls = n - if c.maxCalls == 1 { - c.maxCalls = 1e8 - } - return c -} - -// MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called, MaxTimes also -// sets the minimum number of calls to 0. -func (c *Call) MaxTimes(n int) *Call { - c.maxCalls = n - if c.minCalls == 1 { - c.minCalls = 0 - } - return c -} - -// DoAndReturn declares the action to run when the call is matched. -// The return values from this function are returned by the mocked function. -// It takes an interface{} argument to support n-arity functions. -func (c *Call) DoAndReturn(f interface{}) *Call { - // TODO: Check arity and types here, rather than dying badly elsewhere. - v := reflect.ValueOf(f) - - c.addAction(func(args []interface{}) []interface{} { - vargs := make([]reflect.Value, len(args)) - ft := v.Type() - for i := 0; i < len(args); i++ { - if args[i] != nil { - vargs[i] = reflect.ValueOf(args[i]) - } else { - // Use the zero value for the arg. - vargs[i] = reflect.Zero(ft.In(i)) - } - } - vrets := v.Call(vargs) - rets := make([]interface{}, len(vrets)) - for i, ret := range vrets { - rets[i] = ret.Interface() - } - return rets - }) - return c -} - -// Do declares the action to run when the call is matched. The function's -// return values are ignored to retain backward compatibility. To use the -// return values call DoAndReturn. -// It takes an interface{} argument to support n-arity functions. -func (c *Call) Do(f interface{}) *Call { - // TODO: Check arity and types here, rather than dying badly elsewhere. - v := reflect.ValueOf(f) - - c.addAction(func(args []interface{}) []interface{} { - vargs := make([]reflect.Value, len(args)) - ft := v.Type() - for i := 0; i < len(args); i++ { - if args[i] != nil { - vargs[i] = reflect.ValueOf(args[i]) - } else { - // Use the zero value for the arg. - vargs[i] = reflect.Zero(ft.In(i)) - } - } - v.Call(vargs) - return nil - }) - return c -} - -// Return declares the values to be returned by the mocked function call. -func (c *Call) Return(rets ...interface{}) *Call { - c.t.Helper() - - mt := c.methodType - if len(rets) != mt.NumOut() { - c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d [%s]", - c.receiver, c.method, len(rets), mt.NumOut(), c.origin) - } - for i, ret := range rets { - if got, want := reflect.TypeOf(ret), mt.Out(i); got == want { - // Identical types; nothing to do. - } else if got == nil { - // Nil needs special handling. - switch want.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - // ok - default: - c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable [%s]", - i, c.receiver, c.method, want, c.origin) - } - } else if got.AssignableTo(want) { - // Assignable type relation. Make the assignment now so that the generated code - // can return the values with a type assertion. - v := reflect.New(want).Elem() - v.Set(reflect.ValueOf(ret)) - rets[i] = v.Interface() - } else { - c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v [%s]", - i, c.receiver, c.method, got, want, c.origin) - } - } - - c.addAction(func([]interface{}) []interface{} { - return rets - }) - - return c -} - -// Times declares the exact number of times a function call is expected to be executed. -func (c *Call) Times(n int) *Call { - c.minCalls, c.maxCalls = n, n - return c -} - -// SetArg declares an action that will set the nth argument's value, -// indirected through a pointer. Or, in the case of a slice, SetArg -// will copy value's elements into the nth argument. -func (c *Call) SetArg(n int, value interface{}) *Call { - c.t.Helper() - - mt := c.methodType - // TODO: This will break on variadic methods. - // We will need to check those at invocation time. - if n < 0 || n >= mt.NumIn() { - c.t.Fatalf("SetArg(%d, ...) called for a method with %d args [%s]", - n, mt.NumIn(), c.origin) - } - // Permit setting argument through an interface. - // In the interface case, we don't (nay, can't) check the type here. - at := mt.In(n) - switch at.Kind() { - case reflect.Ptr: - dt := at.Elem() - if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) { - c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v [%s]", - n, vt, dt, c.origin) - } - case reflect.Interface: - // nothing to do - case reflect.Slice: - // nothing to do - default: - c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface non-slice type %v [%s]", - n, at, c.origin) - } - - c.addAction(func(args []interface{}) []interface{} { - v := reflect.ValueOf(value) - switch reflect.TypeOf(args[n]).Kind() { - case reflect.Slice: - setSlice(args[n], v) - default: - reflect.ValueOf(args[n]).Elem().Set(v) - } - return nil - }) - return c -} - -// isPreReq returns true if other is a direct or indirect prerequisite to c. -func (c *Call) isPreReq(other *Call) bool { - for _, preReq := range c.preReqs { - if other == preReq || preReq.isPreReq(other) { - return true - } - } - return false -} - -// After declares that the call may only match after preReq has been exhausted. -func (c *Call) After(preReq *Call) *Call { - c.t.Helper() - - if c == preReq { - c.t.Fatalf("A call isn't allowed to be its own prerequisite") - } - if preReq.isPreReq(c) { - c.t.Fatalf("Loop in call order: %v is a prerequisite to %v (possibly indirectly).", c, preReq) - } - - c.preReqs = append(c.preReqs, preReq) - return c -} - -// Returns true if the minimum number of calls have been made. -func (c *Call) satisfied() bool { - return c.numCalls >= c.minCalls -} - -// Returns true iff the maximum number of calls have been made. -func (c *Call) exhausted() bool { - return c.numCalls >= c.maxCalls -} - -func (c *Call) String() string { - args := make([]string, len(c.args)) - for i, arg := range c.args { - args[i] = arg.String() - } - arguments := strings.Join(args, ", ") - return fmt.Sprintf("%T.%v(%s) %s", c.receiver, c.method, arguments, c.origin) -} - -// Tests if the given call matches the expected call. -// If yes, returns nil. If no, returns error with message explaining why it does not match. -func (c *Call) matches(args []interface{}) error { - if !c.methodType.IsVariadic() { - if len(args) != len(c.args) { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d", - c.origin, len(args), len(c.args)) - } - - for i, m := range c.args { - if !m.Matches(args[i]) { - return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", - c.origin, strconv.Itoa(i), args[i], m) - } - } - } else { - if len(c.args) < c.methodType.NumIn()-1 { - return fmt.Errorf("Expected call at %s has the wrong number of matchers. Got: %d, want: %d", - c.origin, len(c.args), c.methodType.NumIn()-1) - } - if len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d", - c.origin, len(args), len(c.args)) - } - if len(args) < len(c.args)-1 { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d", - c.origin, len(args), len(c.args)-1) - } - - for i, m := range c.args { - if i < c.methodType.NumIn()-1 { - // Non-variadic args - if !m.Matches(args[i]) { - return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", - c.origin, strconv.Itoa(i), args[i], m) - } - continue - } - // The last arg has a possibility of a variadic argument, so let it branch - - // sample: Foo(a int, b int, c ...int) - if i < len(c.args) && i < len(args) { - if m.Matches(args[i]) { - // Got Foo(a, b, c) want Foo(matcherA, matcherB, gomock.Any()) - // Got Foo(a, b, c) want Foo(matcherA, matcherB, someSliceMatcher) - // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC) - // Got Foo(a, b) want Foo(matcherA, matcherB) - // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD) - continue - } - } - - // The number of actual args don't match the number of matchers, - // or the last matcher is a slice and the last arg is not. - // If this function still matches it is because the last matcher - // matches all the remaining arguments or the lack of any. - // Convert the remaining arguments, if any, into a slice of the - // expected type. - vargsType := c.methodType.In(c.methodType.NumIn() - 1) - vargs := reflect.MakeSlice(vargsType, 0, len(args)-i) - for _, arg := range args[i:] { - vargs = reflect.Append(vargs, reflect.ValueOf(arg)) - } - if m.Matches(vargs.Interface()) { - // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, gomock.Any()) - // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, someSliceMatcher) - // Got Foo(a, b) want Foo(matcherA, matcherB, gomock.Any()) - // Got Foo(a, b) want Foo(matcherA, matcherB, someEmptySliceMatcher) - break - } - // Wrong number of matchers or not match. Fail. - // Got Foo(a, b) want Foo(matcherA, matcherB, matcherC, matcherD) - // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC, matcherD) - // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD, matcherE) - // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, matcherC, matcherD) - // Got Foo(a, b, c) want Foo(matcherA, matcherB) - return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", - c.origin, strconv.Itoa(i), args[i:], c.args[i]) - - } - } - - // Check that all prerequisite calls have been satisfied. - for _, preReqCall := range c.preReqs { - if !preReqCall.satisfied() { - return fmt.Errorf("Expected call at %s doesn't have a prerequisite call satisfied:\n%v\nshould be called before:\n%v", - c.origin, preReqCall, c) - } - } - - // Check that the call is not exhausted. - if c.exhausted() { - return fmt.Errorf("Expected call at %s has already been called the max number of times.", c.origin) - } - - return nil -} - -// dropPrereqs tells the expected Call to not re-check prerequisite calls any -// longer, and to return its current set. -func (c *Call) dropPrereqs() (preReqs []*Call) { - preReqs = c.preReqs - c.preReqs = nil - return -} - -func (c *Call) call(args []interface{}) []func([]interface{}) []interface{} { - c.numCalls++ - return c.actions -} - -// InOrder declares that the given calls should occur in order. -func InOrder(calls ...*Call) { - for i := 1; i < len(calls); i++ { - calls[i].After(calls[i-1]) - } -} - -func setSlice(arg interface{}, v reflect.Value) { - va := reflect.ValueOf(arg) - for i := 0; i < v.Len(); i++ { - va.Index(i).Set(v.Index(i)) - } -} - -func (c *Call) addAction(action func([]interface{}) []interface{}) { - c.actions = append(c.actions, action) -} diff --git a/vendor/github.com/golang/mock/gomock/callset.go b/vendor/github.com/golang/mock/gomock/callset.go deleted file mode 100644 index c44a8a58..00000000 --- a/vendor/github.com/golang/mock/gomock/callset.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2011 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gomock - -import ( - "bytes" - "fmt" -) - -// callSet represents a set of expected calls, indexed by receiver and method -// name. -type callSet struct { - // Calls that are still expected. - expected map[callSetKey][]*Call - // Calls that have been exhausted. - exhausted map[callSetKey][]*Call -} - -// callSetKey is the key in the maps in callSet -type callSetKey struct { - receiver interface{} - fname string -} - -func newCallSet() *callSet { - return &callSet{make(map[callSetKey][]*Call), make(map[callSetKey][]*Call)} -} - -// Add adds a new expected call. -func (cs callSet) Add(call *Call) { - key := callSetKey{call.receiver, call.method} - m := cs.expected - if call.exhausted() { - m = cs.exhausted - } - m[key] = append(m[key], call) -} - -// Remove removes an expected call. -func (cs callSet) Remove(call *Call) { - key := callSetKey{call.receiver, call.method} - calls := cs.expected[key] - for i, c := range calls { - if c == call { - // maintain order for remaining calls - cs.expected[key] = append(calls[:i], calls[i+1:]...) - cs.exhausted[key] = append(cs.exhausted[key], call) - break - } - } -} - -// FindMatch searches for a matching call. Returns error with explanation message if no call matched. -func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) (*Call, error) { - key := callSetKey{receiver, method} - - // Search through the expected calls. - expected := cs.expected[key] - var callsErrors bytes.Buffer - for _, call := range expected { - err := call.matches(args) - if err != nil { - fmt.Fprintf(&callsErrors, "\n%v", err) - } else { - return call, nil - } - } - - // If we haven't found a match then search through the exhausted calls so we - // get useful error messages. - exhausted := cs.exhausted[key] - for _, call := range exhausted { - if err := call.matches(args); err != nil { - fmt.Fprintf(&callsErrors, "\n%v", err) - } - } - - if len(expected)+len(exhausted) == 0 { - fmt.Fprintf(&callsErrors, "there are no expected calls of the method %q for that receiver", method) - } - - return nil, fmt.Errorf(callsErrors.String()) -} - -// Failures returns the calls that are not satisfied. -func (cs callSet) Failures() []*Call { - failures := make([]*Call, 0, len(cs.expected)) - for _, calls := range cs.expected { - for _, call := range calls { - if !call.satisfied() { - failures = append(failures, call) - } - } - } - return failures -} diff --git a/vendor/github.com/golang/mock/gomock/controller.go b/vendor/github.com/golang/mock/gomock/controller.go deleted file mode 100644 index 0651c91e..00000000 --- a/vendor/github.com/golang/mock/gomock/controller.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2010 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package gomock is a mock framework for Go. -// -// Standard usage: -// (1) Define an interface that you wish to mock. -// type MyInterface interface { -// SomeMethod(x int64, y string) -// } -// (2) Use mockgen to generate a mock from the interface. -// (3) Use the mock in a test: -// func TestMyThing(t *testing.T) { -// mockCtrl := gomock.NewController(t) -// defer mockCtrl.Finish() -// -// mockObj := something.NewMockMyInterface(mockCtrl) -// mockObj.EXPECT().SomeMethod(4, "blah") -// // pass mockObj to a real object and play with it. -// } -// -// By default, expected calls are not enforced to run in any particular order. -// Call order dependency can be enforced by use of InOrder and/or Call.After. -// Call.After can create more varied call order dependencies, but InOrder is -// often more convenient. -// -// The following examples create equivalent call order dependencies. -// -// Example of using Call.After to chain expected call order: -// -// firstCall := mockObj.EXPECT().SomeMethod(1, "first") -// secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall) -// mockObj.EXPECT().SomeMethod(3, "third").After(secondCall) -// -// Example of using InOrder to declare expected call order: -// -// gomock.InOrder( -// mockObj.EXPECT().SomeMethod(1, "first"), -// mockObj.EXPECT().SomeMethod(2, "second"), -// mockObj.EXPECT().SomeMethod(3, "third"), -// ) -// -// TODO: -// - Handle different argument/return types (e.g. ..., chan, map, interface). -package gomock - -import ( - "context" - "fmt" - "reflect" - "runtime" - "sync" -) - -// A TestReporter is something that can be used to report test failures. It -// is satisfied by the standard library's *testing.T. -type TestReporter interface { - Errorf(format string, args ...interface{}) - Fatalf(format string, args ...interface{}) -} - -// TestHelper is a TestReporter that has the Helper method. It is satisfied -// by the standard library's *testing.T. -type TestHelper interface { - TestReporter - Helper() -} - -// A Controller represents the top-level control of a mock ecosystem. It -// defines the scope and lifetime of mock objects, as well as their -// expectations. It is safe to call Controller's methods from multiple -// goroutines. Each test should create a new Controller and invoke Finish via -// defer. -// -// func TestFoo(t *testing.T) { -// ctrl := gomock.NewController(st) -// defer ctrl.Finish() -// // .. -// } -// -// func TestBar(t *testing.T) { -// t.Run("Sub-Test-1", st) { -// ctrl := gomock.NewController(st) -// defer ctrl.Finish() -// // .. -// }) -// t.Run("Sub-Test-2", st) { -// ctrl := gomock.NewController(st) -// defer ctrl.Finish() -// // .. -// }) -// }) -type Controller struct { - // T should only be called within a generated mock. It is not intended to - // be used in user code and may be changed in future versions. T is the - // TestReporter passed in when creating the Controller via NewController. - // If the TestReporter does not implement a TestHelper it will be wrapped - // with a nopTestHelper. - T TestHelper - mu sync.Mutex - expectedCalls *callSet - finished bool -} - -// NewController returns a new Controller. It is the preferred way to create a -// Controller. -func NewController(t TestReporter) *Controller { - h, ok := t.(TestHelper) - if !ok { - h = nopTestHelper{t} - } - - return &Controller{ - T: h, - expectedCalls: newCallSet(), - } -} - -type cancelReporter struct { - TestHelper - cancel func() -} - -func (r *cancelReporter) Errorf(format string, args ...interface{}) { - r.TestHelper.Errorf(format, args...) -} -func (r *cancelReporter) Fatalf(format string, args ...interface{}) { - defer r.cancel() - r.TestHelper.Fatalf(format, args...) -} - -// WithContext returns a new Controller and a Context, which is cancelled on any -// fatal failure. -func WithContext(ctx context.Context, t TestReporter) (*Controller, context.Context) { - h, ok := t.(TestHelper) - if !ok { - h = nopTestHelper{t} - } - - ctx, cancel := context.WithCancel(ctx) - return NewController(&cancelReporter{h, cancel}), ctx -} - -type nopTestHelper struct { - TestReporter -} - -func (h nopTestHelper) Helper() {} - -// RecordCall is called by a mock. It should not be called by user code. -func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call { - ctrl.T.Helper() - - recv := reflect.ValueOf(receiver) - for i := 0; i < recv.Type().NumMethod(); i++ { - if recv.Type().Method(i).Name == method { - return ctrl.RecordCallWithMethodType(receiver, method, recv.Method(i).Type(), args...) - } - } - ctrl.T.Fatalf("gomock: failed finding method %s on %T", method, receiver) - panic("unreachable") -} - -// RecordCallWithMethodType is called by a mock. It should not be called by user code. -func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call { - ctrl.T.Helper() - - call := newCall(ctrl.T, receiver, method, methodType, args...) - - ctrl.mu.Lock() - defer ctrl.mu.Unlock() - ctrl.expectedCalls.Add(call) - - return call -} - -// Call is called by a mock. It should not be called by user code. -func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} { - ctrl.T.Helper() - - // Nest this code so we can use defer to make sure the lock is released. - actions := func() []func([]interface{}) []interface{} { - ctrl.T.Helper() - ctrl.mu.Lock() - defer ctrl.mu.Unlock() - - expected, err := ctrl.expectedCalls.FindMatch(receiver, method, args) - if err != nil { - origin := callerInfo(2) - ctrl.T.Fatalf("Unexpected call to %T.%v(%v) at %s because: %s", receiver, method, args, origin, err) - } - - // Two things happen here: - // * the matching call no longer needs to check prerequite calls, - // * and the prerequite calls are no longer expected, so remove them. - preReqCalls := expected.dropPrereqs() - for _, preReqCall := range preReqCalls { - ctrl.expectedCalls.Remove(preReqCall) - } - - actions := expected.call(args) - if expected.exhausted() { - ctrl.expectedCalls.Remove(expected) - } - return actions - }() - - var rets []interface{} - for _, action := range actions { - if r := action(args); r != nil { - rets = r - } - } - - return rets -} - -// Finish checks to see if all the methods that were expected to be called -// were called. It should be invoked for each Controller. It is not idempotent -// and therefore can only be invoked once. -func (ctrl *Controller) Finish() { - ctrl.T.Helper() - - ctrl.mu.Lock() - defer ctrl.mu.Unlock() - - if ctrl.finished { - ctrl.T.Fatalf("Controller.Finish was called more than once. It has to be called exactly once.") - } - ctrl.finished = true - - // If we're currently panicking, probably because this is a deferred call, - // pass through the panic. - if err := recover(); err != nil { - panic(err) - } - - // Check that all remaining expected calls are satisfied. - failures := ctrl.expectedCalls.Failures() - for _, call := range failures { - ctrl.T.Errorf("missing call(s) to %v", call) - } - if len(failures) != 0 { - ctrl.T.Fatalf("aborting test due to missing call(s)") - } -} - -func callerInfo(skip int) string { - if _, file, line, ok := runtime.Caller(skip + 1); ok { - return fmt.Sprintf("%s:%d", file, line) - } - return "unknown file" -} diff --git a/vendor/github.com/golang/mock/gomock/matchers.go b/vendor/github.com/golang/mock/gomock/matchers.go deleted file mode 100644 index fbff0606..00000000 --- a/vendor/github.com/golang/mock/gomock/matchers.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2010 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gomock - -import ( - "fmt" - "reflect" -) - -// A Matcher is a representation of a class of values. -// It is used to represent the valid or expected arguments to a mocked method. -type Matcher interface { - // Matches returns whether x is a match. - Matches(x interface{}) bool - - // String describes what the matcher matches. - String() string -} - -type anyMatcher struct{} - -func (anyMatcher) Matches(x interface{}) bool { - return true -} - -func (anyMatcher) String() string { - return "is anything" -} - -type eqMatcher struct { - x interface{} -} - -func (e eqMatcher) Matches(x interface{}) bool { - return reflect.DeepEqual(e.x, x) -} - -func (e eqMatcher) String() string { - return fmt.Sprintf("is equal to %v", e.x) -} - -type nilMatcher struct{} - -func (nilMatcher) Matches(x interface{}) bool { - if x == nil { - return true - } - - v := reflect.ValueOf(x) - switch v.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, - reflect.Ptr, reflect.Slice: - return v.IsNil() - } - - return false -} - -func (nilMatcher) String() string { - return "is nil" -} - -type notMatcher struct { - m Matcher -} - -func (n notMatcher) Matches(x interface{}) bool { - return !n.m.Matches(x) -} - -func (n notMatcher) String() string { - // TODO: Improve this if we add a NotString method to the Matcher interface. - return "not(" + n.m.String() + ")" -} - -type assignableToTypeOfMatcher struct { - targetType reflect.Type -} - -func (m assignableToTypeOfMatcher) Matches(x interface{}) bool { - return reflect.TypeOf(x).AssignableTo(m.targetType) -} - -func (m assignableToTypeOfMatcher) String() string { - return "is assignable to " + m.targetType.Name() -} - -// Constructors -// Any returns a matcher that always matches. -func Any() Matcher { return anyMatcher{} } - -// Eq returns a matcher that matches on equality. -// -// Example usage: -// Eq(5).Matches(5) // returns true -// Eq(5).Matches(4) // returns false -func Eq(x interface{}) Matcher { return eqMatcher{x} } - -// Nil returns a matcher that matches if the received value is nil. -// -// Example usage: -// var x *bytes.Buffer -// Nil().Matches(x) // returns true -// x = &bytes.Buffer{} -// Nil().Matches(x) // returns false -func Nil() Matcher { return nilMatcher{} } - -// Not reverses the results of its given child matcher. -// -// Example usage: -// Not(Eq(5)).Matches(4) // returns true -// Not(Eq(5)).Matches(5) // returns false -func Not(x interface{}) Matcher { - if m, ok := x.(Matcher); ok { - return notMatcher{m} - } - return notMatcher{Eq(x)} -} - -// AssignableToTypeOf is a Matcher that matches if the parameter to the mock -// function is assignable to the type of the parameter to this function. -// -// Example usage: -// var s fmt.Stringer = &bytes.Buffer{} -// AssignableToTypeOf(s).Matches(time.Second) // returns true -// AssignableToTypeOf(s).Matches(99) // returns false -func AssignableToTypeOf(x interface{}) Matcher { - return assignableToTypeOfMatcher{reflect.TypeOf(x)} -} diff --git a/vendor/github.com/soniah/gosnmp/CHANGELOG.md b/vendor/github.com/soniah/gosnmp/CHANGELOG.md index 2fba59d1..24494948 100644 --- a/vendor/github.com/soniah/gosnmp/CHANGELOG.md +++ b/vendor/github.com/soniah/gosnmp/CHANGELOG.md @@ -1,3 +1,12 @@ +## v1.23.0 + +* BREAKING CHANGE: The mocks have been moved to `github.com/soniah/gosnmp/mocks`. + If you use them, you will need to adjust your imports. +* bug fix: issue 170: No results when performing a walk starting on a leaf OID +* bug fix: issue 210: Set function fails if value is an Integer +* doco: loggingEnabled, MIB parser +* linting + ## v1.22.0 * travis now failing build when goimports needs running diff --git a/vendor/github.com/soniah/gosnmp/README.md b/vendor/github.com/soniah/gosnmp/README.md index 543ee546..00dd74fa 100644 --- a/vendor/github.com/soniah/gosnmp/README.md +++ b/vendor/github.com/soniah/gosnmp/README.md @@ -122,6 +122,12 @@ Running this example gives the following output (from my printer): * `examples/example3.go` demonstrates `SNMPv3` * `examples/trapserver.go` demonstrates writing an SNMP v2c trap server +MIB Parser +---------- + +I don't have any plans to write a mib parser. Others have suggested +https://github.com/sleepinggenius2/gosmi + Contributions ------------- @@ -226,7 +232,7 @@ work against any SNMP MIB-2 compliant host (e.g. a router, NAS box, printer). Mocks were generated using: -`mockgen -source=interface.go -package gosnmp > gosnmp_mock.go` +`mockgen -source=interface.go -destination=mocks/gosnmp_mock.go -package=mocks` To profile cpu usage: diff --git a/vendor/github.com/soniah/gosnmp/gosnmp.go b/vendor/github.com/soniah/gosnmp/gosnmp.go index f2abfa36..bb17abec 100644 --- a/vendor/github.com/soniah/gosnmp/gosnmp.go +++ b/vendor/github.com/soniah/gosnmp/gosnmp.go @@ -9,6 +9,7 @@ package gosnmp import ( + "context" "fmt" "io/ioutil" "log" @@ -54,10 +55,13 @@ type GoSNMP struct { // Version is an SNMP Version Version SnmpVersion - // Timeout is the timeout for the SNMP Query + // Context allows for overall deadlines and cancellation + Context context.Context + + // Timeout is the timeout for one SNMP request/response Timeout time.Duration - // Set the number of retries to attempt within timeout. + // Set the number of retries to attempt within timeout Retries int // Double timeout in each retry @@ -68,7 +72,8 @@ type GoSNMP struct { // x.Logger = log.New(os.Stdout, "", 0) Logger Logger - // loggingEnabled is set if the Logger is nil, short circuits any 'Logger' calls + // loggingEnabled is set if the Logger isn't nil, otherwise any logging calls + // are ignored via shortcircuit loggingEnabled bool // MaxOids is the maximum number of oids allowed in a Get() @@ -268,7 +273,8 @@ func (x *GoSNMP) connect(networkSuffix string) error { func (x *GoSNMP) netConnect() error { var err error addr := net.JoinHostPort(x.Target, strconv.Itoa(int(x.Port))) - x.Conn, err = net.DialTimeout(x.Transport, addr, x.Timeout) + dialer := net.Dialer{Timeout: x.Timeout} + x.Conn, err = dialer.DialContext(x.Context, x.Transport, addr) return err } @@ -302,6 +308,10 @@ func (x *GoSNMP) validateParameters() error { } } + if x.Context == nil { + x.Context = context.Background() + } + return nil } diff --git a/vendor/github.com/soniah/gosnmp/gosnmp_mock.go b/vendor/github.com/soniah/gosnmp/gosnmp_mock.go deleted file mode 100644 index b11db807..00000000 --- a/vendor/github.com/soniah/gosnmp/gosnmp_mock.go +++ /dev/null @@ -1,572 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: interface.go - -// Package gosnmp is a generated GoMock package. -package gosnmp - -import ( - reflect "reflect" - time "time" - - gomock "github.com/golang/mock/gomock" -) - -// MockHandler is a mock of Handler interface -type MockHandler struct { - ctrl *gomock.Controller - recorder *MockHandlerMockRecorder -} - -// MockHandlerMockRecorder is the mock recorder for MockHandler -type MockHandlerMockRecorder struct { - mock *MockHandler -} - -// NewMockHandler creates a new mock instance -func NewMockHandler(ctrl *gomock.Controller) *MockHandler { - mock := &MockHandler{ctrl: ctrl} - mock.recorder = &MockHandlerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockHandler) EXPECT() *MockHandlerMockRecorder { - return m.recorder -} - -// Connect mocks base method -func (m *MockHandler) Connect() error { - ret := m.ctrl.Call(m, "Connect") - ret0, _ := ret[0].(error) - return ret0 -} - -// Connect indicates an expected call of Connect -func (mr *MockHandlerMockRecorder) Connect() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockHandler)(nil).Connect)) -} - -// ConnectIPv4 mocks base method -func (m *MockHandler) ConnectIPv4() error { - ret := m.ctrl.Call(m, "ConnectIPv4") - ret0, _ := ret[0].(error) - return ret0 -} - -// ConnectIPv4 indicates an expected call of ConnectIPv4 -func (mr *MockHandlerMockRecorder) ConnectIPv4() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectIPv4", reflect.TypeOf((*MockHandler)(nil).ConnectIPv4)) -} - -// ConnectIPv6 mocks base method -func (m *MockHandler) ConnectIPv6() error { - ret := m.ctrl.Call(m, "ConnectIPv6") - ret0, _ := ret[0].(error) - return ret0 -} - -// ConnectIPv6 indicates an expected call of ConnectIPv6 -func (mr *MockHandlerMockRecorder) ConnectIPv6() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectIPv6", reflect.TypeOf((*MockHandler)(nil).ConnectIPv6)) -} - -// Get mocks base method -func (m *MockHandler) Get(oids []string) (*SnmpPacket, error) { - ret := m.ctrl.Call(m, "Get", oids) - ret0, _ := ret[0].(*SnmpPacket) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Get indicates an expected call of Get -func (mr *MockHandlerMockRecorder) Get(oids interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockHandler)(nil).Get), oids) -} - -// GetBulk mocks base method -func (m *MockHandler) GetBulk(oids []string, nonRepeaters, maxRepetitions uint8) (*SnmpPacket, error) { - ret := m.ctrl.Call(m, "GetBulk", oids, nonRepeaters, maxRepetitions) - ret0, _ := ret[0].(*SnmpPacket) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBulk indicates an expected call of GetBulk -func (mr *MockHandlerMockRecorder) GetBulk(oids, nonRepeaters, maxRepetitions interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBulk", reflect.TypeOf((*MockHandler)(nil).GetBulk), oids, nonRepeaters, maxRepetitions) -} - -// GetNext mocks base method -func (m *MockHandler) GetNext(oids []string) (*SnmpPacket, error) { - ret := m.ctrl.Call(m, "GetNext", oids) - ret0, _ := ret[0].(*SnmpPacket) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetNext indicates an expected call of GetNext -func (mr *MockHandlerMockRecorder) GetNext(oids interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNext", reflect.TypeOf((*MockHandler)(nil).GetNext), oids) -} - -// Walk mocks base method -func (m *MockHandler) Walk(rootOid string, walkFn WalkFunc) error { - ret := m.ctrl.Call(m, "Walk", rootOid, walkFn) - ret0, _ := ret[0].(error) - return ret0 -} - -// Walk indicates an expected call of Walk -func (mr *MockHandlerMockRecorder) Walk(rootOid, walkFn interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Walk", reflect.TypeOf((*MockHandler)(nil).Walk), rootOid, walkFn) -} - -// WalkAll mocks base method -func (m *MockHandler) WalkAll(rootOid string) ([]SnmpPDU, error) { - ret := m.ctrl.Call(m, "WalkAll", rootOid) - ret0, _ := ret[0].([]SnmpPDU) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// WalkAll indicates an expected call of WalkAll -func (mr *MockHandlerMockRecorder) WalkAll(rootOid interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalkAll", reflect.TypeOf((*MockHandler)(nil).WalkAll), rootOid) -} - -// BulkWalk mocks base method -func (m *MockHandler) BulkWalk(rootOid string, walkFn WalkFunc) error { - ret := m.ctrl.Call(m, "BulkWalk", rootOid, walkFn) - ret0, _ := ret[0].(error) - return ret0 -} - -// BulkWalk indicates an expected call of BulkWalk -func (mr *MockHandlerMockRecorder) BulkWalk(rootOid, walkFn interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BulkWalk", reflect.TypeOf((*MockHandler)(nil).BulkWalk), rootOid, walkFn) -} - -// BulkWalkAll mocks base method -func (m *MockHandler) BulkWalkAll(rootOid string) ([]SnmpPDU, error) { - ret := m.ctrl.Call(m, "BulkWalkAll", rootOid) - ret0, _ := ret[0].([]SnmpPDU) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// BulkWalkAll indicates an expected call of BulkWalkAll -func (mr *MockHandlerMockRecorder) BulkWalkAll(rootOid interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BulkWalkAll", reflect.TypeOf((*MockHandler)(nil).BulkWalkAll), rootOid) -} - -// SendTrap mocks base method -func (m *MockHandler) SendTrap(trap SnmpTrap) (*SnmpPacket, error) { - ret := m.ctrl.Call(m, "SendTrap", trap) - ret0, _ := ret[0].(*SnmpPacket) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SendTrap indicates an expected call of SendTrap -func (mr *MockHandlerMockRecorder) SendTrap(trap interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendTrap", reflect.TypeOf((*MockHandler)(nil).SendTrap), trap) -} - -// UnmarshalTrap mocks base method -func (m *MockHandler) UnmarshalTrap(trap []byte) *SnmpPacket { - ret := m.ctrl.Call(m, "UnmarshalTrap", trap) - ret0, _ := ret[0].(*SnmpPacket) - return ret0 -} - -// UnmarshalTrap indicates an expected call of UnmarshalTrap -func (mr *MockHandlerMockRecorder) UnmarshalTrap(trap interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnmarshalTrap", reflect.TypeOf((*MockHandler)(nil).UnmarshalTrap), trap) -} - -// Set mocks base method -func (m *MockHandler) Set(pdus []SnmpPDU) (*SnmpPacket, error) { - ret := m.ctrl.Call(m, "Set", pdus) - ret0, _ := ret[0].(*SnmpPacket) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Set indicates an expected call of Set -func (mr *MockHandlerMockRecorder) Set(pdus interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Set", reflect.TypeOf((*MockHandler)(nil).Set), pdus) -} - -// Check mocks base method -func (m *MockHandler) Check(err error) { - m.ctrl.Call(m, "Check", err) -} - -// Check indicates an expected call of Check -func (mr *MockHandlerMockRecorder) Check(err interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Check", reflect.TypeOf((*MockHandler)(nil).Check), err) -} - -// Close mocks base method -func (m *MockHandler) Close() error { - ret := m.ctrl.Call(m, "Close") - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close -func (mr *MockHandlerMockRecorder) Close() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockHandler)(nil).Close)) -} - -// Target mocks base method -func (m *MockHandler) Target() string { - ret := m.ctrl.Call(m, "Target") - ret0, _ := ret[0].(string) - return ret0 -} - -// Target indicates an expected call of Target -func (mr *MockHandlerMockRecorder) Target() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Target", reflect.TypeOf((*MockHandler)(nil).Target)) -} - -// SetTarget mocks base method -func (m *MockHandler) SetTarget(target string) { - m.ctrl.Call(m, "SetTarget", target) -} - -// SetTarget indicates an expected call of SetTarget -func (mr *MockHandlerMockRecorder) SetTarget(target interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTarget", reflect.TypeOf((*MockHandler)(nil).SetTarget), target) -} - -// Port mocks base method -func (m *MockHandler) Port() uint16 { - ret := m.ctrl.Call(m, "Port") - ret0, _ := ret[0].(uint16) - return ret0 -} - -// Port indicates an expected call of Port -func (mr *MockHandlerMockRecorder) Port() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Port", reflect.TypeOf((*MockHandler)(nil).Port)) -} - -// SetPort mocks base method -func (m *MockHandler) SetPort(port uint16) { - m.ctrl.Call(m, "SetPort", port) -} - -// SetPort indicates an expected call of SetPort -func (mr *MockHandlerMockRecorder) SetPort(port interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPort", reflect.TypeOf((*MockHandler)(nil).SetPort), port) -} - -// Community mocks base method -func (m *MockHandler) Community() string { - ret := m.ctrl.Call(m, "Community") - ret0, _ := ret[0].(string) - return ret0 -} - -// Community indicates an expected call of Community -func (mr *MockHandlerMockRecorder) Community() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Community", reflect.TypeOf((*MockHandler)(nil).Community)) -} - -// SetCommunity mocks base method -func (m *MockHandler) SetCommunity(community string) { - m.ctrl.Call(m, "SetCommunity", community) -} - -// SetCommunity indicates an expected call of SetCommunity -func (mr *MockHandlerMockRecorder) SetCommunity(community interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCommunity", reflect.TypeOf((*MockHandler)(nil).SetCommunity), community) -} - -// Version mocks base method -func (m *MockHandler) Version() SnmpVersion { - ret := m.ctrl.Call(m, "Version") - ret0, _ := ret[0].(SnmpVersion) - return ret0 -} - -// Version indicates an expected call of Version -func (mr *MockHandlerMockRecorder) Version() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockHandler)(nil).Version)) -} - -// SetVersion mocks base method -func (m *MockHandler) SetVersion(version SnmpVersion) { - m.ctrl.Call(m, "SetVersion", version) -} - -// SetVersion indicates an expected call of SetVersion -func (mr *MockHandlerMockRecorder) SetVersion(version interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetVersion", reflect.TypeOf((*MockHandler)(nil).SetVersion), version) -} - -// Timeout mocks base method -func (m *MockHandler) Timeout() time.Duration { - ret := m.ctrl.Call(m, "Timeout") - ret0, _ := ret[0].(time.Duration) - return ret0 -} - -// Timeout indicates an expected call of Timeout -func (mr *MockHandlerMockRecorder) Timeout() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Timeout", reflect.TypeOf((*MockHandler)(nil).Timeout)) -} - -// SetTimeout mocks base method -func (m *MockHandler) SetTimeout(timeout time.Duration) { - m.ctrl.Call(m, "SetTimeout", timeout) -} - -// SetTimeout indicates an expected call of SetTimeout -func (mr *MockHandlerMockRecorder) SetTimeout(timeout interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimeout", reflect.TypeOf((*MockHandler)(nil).SetTimeout), timeout) -} - -// Retries mocks base method -func (m *MockHandler) Retries() int { - ret := m.ctrl.Call(m, "Retries") - ret0, _ := ret[0].(int) - return ret0 -} - -// Retries indicates an expected call of Retries -func (mr *MockHandlerMockRecorder) Retries() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Retries", reflect.TypeOf((*MockHandler)(nil).Retries)) -} - -// SetRetries mocks base method -func (m *MockHandler) SetRetries(retries int) { - m.ctrl.Call(m, "SetRetries", retries) -} - -// SetRetries indicates an expected call of SetRetries -func (mr *MockHandlerMockRecorder) SetRetries(retries interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRetries", reflect.TypeOf((*MockHandler)(nil).SetRetries), retries) -} - -// GetExponentialTimeout mocks base method -func (m *MockHandler) GetExponentialTimeout() bool { - ret := m.ctrl.Call(m, "GetExponentialTimeout") - ret0, _ := ret[0].(bool) - return ret0 -} - -// GetExponentialTimeout indicates an expected call of GetExponentialTimeout -func (mr *MockHandlerMockRecorder) GetExponentialTimeout() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExponentialTimeout", reflect.TypeOf((*MockHandler)(nil).GetExponentialTimeout)) -} - -// SetExponentialTimeout mocks base method -func (m *MockHandler) SetExponentialTimeout(value bool) { - m.ctrl.Call(m, "SetExponentialTimeout", value) -} - -// SetExponentialTimeout indicates an expected call of SetExponentialTimeout -func (mr *MockHandlerMockRecorder) SetExponentialTimeout(value interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExponentialTimeout", reflect.TypeOf((*MockHandler)(nil).SetExponentialTimeout), value) -} - -// Logger mocks base method -func (m *MockHandler) Logger() Logger { - ret := m.ctrl.Call(m, "Logger") - ret0, _ := ret[0].(Logger) - return ret0 -} - -// Logger indicates an expected call of Logger -func (mr *MockHandlerMockRecorder) Logger() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Logger", reflect.TypeOf((*MockHandler)(nil).Logger)) -} - -// SetLogger mocks base method -func (m *MockHandler) SetLogger(logger Logger) { - m.ctrl.Call(m, "SetLogger", logger) -} - -// SetLogger indicates an expected call of SetLogger -func (mr *MockHandlerMockRecorder) SetLogger(logger interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogger", reflect.TypeOf((*MockHandler)(nil).SetLogger), logger) -} - -// MaxOids mocks base method -func (m *MockHandler) MaxOids() int { - ret := m.ctrl.Call(m, "MaxOids") - ret0, _ := ret[0].(int) - return ret0 -} - -// MaxOids indicates an expected call of MaxOids -func (mr *MockHandlerMockRecorder) MaxOids() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxOids", reflect.TypeOf((*MockHandler)(nil).MaxOids)) -} - -// SetMaxOids mocks base method -func (m *MockHandler) SetMaxOids(maxOids int) { - m.ctrl.Call(m, "SetMaxOids", maxOids) -} - -// SetMaxOids indicates an expected call of SetMaxOids -func (mr *MockHandlerMockRecorder) SetMaxOids(maxOids interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxOids", reflect.TypeOf((*MockHandler)(nil).SetMaxOids), maxOids) -} - -// MaxRepetitions mocks base method -func (m *MockHandler) MaxRepetitions() uint8 { - ret := m.ctrl.Call(m, "MaxRepetitions") - ret0, _ := ret[0].(uint8) - return ret0 -} - -// MaxRepetitions indicates an expected call of MaxRepetitions -func (mr *MockHandlerMockRecorder) MaxRepetitions() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxRepetitions", reflect.TypeOf((*MockHandler)(nil).MaxRepetitions)) -} - -// SetMaxRepetitions mocks base method -func (m *MockHandler) SetMaxRepetitions(maxRepetitions uint8) { - m.ctrl.Call(m, "SetMaxRepetitions", maxRepetitions) -} - -// SetMaxRepetitions indicates an expected call of SetMaxRepetitions -func (mr *MockHandlerMockRecorder) SetMaxRepetitions(maxRepetitions interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxRepetitions", reflect.TypeOf((*MockHandler)(nil).SetMaxRepetitions), maxRepetitions) -} - -// NonRepeaters mocks base method -func (m *MockHandler) NonRepeaters() int { - ret := m.ctrl.Call(m, "NonRepeaters") - ret0, _ := ret[0].(int) - return ret0 -} - -// NonRepeaters indicates an expected call of NonRepeaters -func (mr *MockHandlerMockRecorder) NonRepeaters() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NonRepeaters", reflect.TypeOf((*MockHandler)(nil).NonRepeaters)) -} - -// SetNonRepeaters mocks base method -func (m *MockHandler) SetNonRepeaters(nonRepeaters int) { - m.ctrl.Call(m, "SetNonRepeaters", nonRepeaters) -} - -// SetNonRepeaters indicates an expected call of SetNonRepeaters -func (mr *MockHandlerMockRecorder) SetNonRepeaters(nonRepeaters interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNonRepeaters", reflect.TypeOf((*MockHandler)(nil).SetNonRepeaters), nonRepeaters) -} - -// MsgFlags mocks base method -func (m *MockHandler) MsgFlags() SnmpV3MsgFlags { - ret := m.ctrl.Call(m, "MsgFlags") - ret0, _ := ret[0].(SnmpV3MsgFlags) - return ret0 -} - -// MsgFlags indicates an expected call of MsgFlags -func (mr *MockHandlerMockRecorder) MsgFlags() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsgFlags", reflect.TypeOf((*MockHandler)(nil).MsgFlags)) -} - -// SetMsgFlags mocks base method -func (m *MockHandler) SetMsgFlags(msgFlags SnmpV3MsgFlags) { - m.ctrl.Call(m, "SetMsgFlags", msgFlags) -} - -// SetMsgFlags indicates an expected call of SetMsgFlags -func (mr *MockHandlerMockRecorder) SetMsgFlags(msgFlags interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMsgFlags", reflect.TypeOf((*MockHandler)(nil).SetMsgFlags), msgFlags) -} - -// SecurityModel mocks base method -func (m *MockHandler) SecurityModel() SnmpV3SecurityModel { - ret := m.ctrl.Call(m, "SecurityModel") - ret0, _ := ret[0].(SnmpV3SecurityModel) - return ret0 -} - -// SecurityModel indicates an expected call of SecurityModel -func (mr *MockHandlerMockRecorder) SecurityModel() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SecurityModel", reflect.TypeOf((*MockHandler)(nil).SecurityModel)) -} - -// SetSecurityModel mocks base method -func (m *MockHandler) SetSecurityModel(securityModel SnmpV3SecurityModel) { - m.ctrl.Call(m, "SetSecurityModel", securityModel) -} - -// SetSecurityModel indicates an expected call of SetSecurityModel -func (mr *MockHandlerMockRecorder) SetSecurityModel(securityModel interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSecurityModel", reflect.TypeOf((*MockHandler)(nil).SetSecurityModel), securityModel) -} - -// SecurityParameters mocks base method -func (m *MockHandler) SecurityParameters() SnmpV3SecurityParameters { - ret := m.ctrl.Call(m, "SecurityParameters") - ret0, _ := ret[0].(SnmpV3SecurityParameters) - return ret0 -} - -// SecurityParameters indicates an expected call of SecurityParameters -func (mr *MockHandlerMockRecorder) SecurityParameters() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SecurityParameters", reflect.TypeOf((*MockHandler)(nil).SecurityParameters)) -} - -// SetSecurityParameters mocks base method -func (m *MockHandler) SetSecurityParameters(securityParameters SnmpV3SecurityParameters) { - m.ctrl.Call(m, "SetSecurityParameters", securityParameters) -} - -// SetSecurityParameters indicates an expected call of SetSecurityParameters -func (mr *MockHandlerMockRecorder) SetSecurityParameters(securityParameters interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSecurityParameters", reflect.TypeOf((*MockHandler)(nil).SetSecurityParameters), securityParameters) -} - -// ContextEngineID mocks base method -func (m *MockHandler) ContextEngineID() string { - ret := m.ctrl.Call(m, "ContextEngineID") - ret0, _ := ret[0].(string) - return ret0 -} - -// ContextEngineID indicates an expected call of ContextEngineID -func (mr *MockHandlerMockRecorder) ContextEngineID() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContextEngineID", reflect.TypeOf((*MockHandler)(nil).ContextEngineID)) -} - -// SetContextEngineID mocks base method -func (m *MockHandler) SetContextEngineID(contextEngineID string) { - m.ctrl.Call(m, "SetContextEngineID", contextEngineID) -} - -// SetContextEngineID indicates an expected call of SetContextEngineID -func (mr *MockHandlerMockRecorder) SetContextEngineID(contextEngineID interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetContextEngineID", reflect.TypeOf((*MockHandler)(nil).SetContextEngineID), contextEngineID) -} - -// ContextName mocks base method -func (m *MockHandler) ContextName() string { - ret := m.ctrl.Call(m, "ContextName") - ret0, _ := ret[0].(string) - return ret0 -} - -// ContextName indicates an expected call of ContextName -func (mr *MockHandlerMockRecorder) ContextName() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContextName", reflect.TypeOf((*MockHandler)(nil).ContextName)) -} - -// SetContextName mocks base method -func (m *MockHandler) SetContextName(contextName string) { - m.ctrl.Call(m, "SetContextName", contextName) -} - -// SetContextName indicates an expected call of SetContextName -func (mr *MockHandlerMockRecorder) SetContextName(contextName interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetContextName", reflect.TypeOf((*MockHandler)(nil).SetContextName), contextName) -} diff --git a/vendor/github.com/soniah/gosnmp/helper.go b/vendor/github.com/soniah/gosnmp/helper.go index cb3820dc..370d4803 100644 --- a/vendor/github.com/soniah/gosnmp/helper.go +++ b/vendor/github.com/soniah/gosnmp/helper.go @@ -66,8 +66,15 @@ func Check(err error) { func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err error) { retVal = new(variable) + if len(data) == 0 { + return retVal, fmt.Errorf("err: zero byte buffer") + } + // values matching this mask have the type in subsequent byte if data[0]&AsnExtensionID == AsnExtensionID { + if len(data) < 2 { + return retVal, fmt.Errorf("bytes: % x err: truncated (data %d length %d)", data, len(data), 2) + } data = data[1:] } @@ -77,6 +84,10 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x02. signed x.logPrint("decodeValue: type is Integer") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("bytes: % x err: truncated (data %d length %d)", data, len(data), length) + } + var ret int var err error if ret, err = parseInt(data[cursor:length]); err != nil { @@ -89,6 +100,10 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x04 x.logPrint("decodeValue: type is OctetString") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("bytes: % x err: truncated (data %d length %d)", data, len(data), length) + } + retVal.Type = OctetString retVal.Value = []byte(data[cursor:length]) case Null: @@ -114,6 +129,10 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x40 x.logPrint("decodeValue: type is IPAddress") retVal.Type = IPAddress + if len(data) < 2 { + return retVal, fmt.Errorf("not enough data for ipv4 address: %x", data) + } + switch data[1] { case 0: // real life, buggy devices returning bad data retVal.Value = nil @@ -137,6 +156,10 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x41. unsigned x.logPrint("decodeValue: type is Counter32") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("not enough data for Counter32 %x (data %d length %d)", data, len(data), length) + } + ret, err := parseUint(data[cursor:length]) if err != nil { x.logPrintf("decodeValue: err is %v", err) @@ -148,6 +171,10 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x42. unsigned x.logPrint("decodeValue: type is Gauge32") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("not enough data for Gauge32 %x (data %d length %d)", data, len(data), length) + } + ret, err := parseUint(data[cursor:length]) if err != nil { x.logPrintf("decodeValue: err is %v", err) @@ -159,6 +186,10 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x43 x.logPrint("decodeValue: type is TimeTicks") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("not enough data for TimeTicks %x (data %d length %d)", data, len(data), length) + } + ret, err := parseUint(data[cursor:length]) if err != nil { x.logPrintf("decodeValue: err is %v", err) @@ -170,6 +201,10 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x44 x.logPrint("decodeValue: type is Opaque") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("not enough data for Opaque %x (data %d length %d)", data, len(data), length) + } + opaqueData := data[cursor:length] // recursively decode opaque data return x.decodeValue(opaqueData, msg) @@ -177,6 +212,10 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x46 x.logPrint("decodeValue: type is Counter64") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("not enough data for Counter64 %x (data %d length %d)", data, len(data), length) + } + ret, err := parseUint64(data[cursor:length]) if err != nil { x.logPrintf("decodeValue: err is %v", err) @@ -188,12 +227,20 @@ func (x *GoSNMP) decodeValue(data []byte, msg string) (retVal *variable, err err // 0x78 x.logPrint("decodeValue: type is OpaqueFloat") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("not enough data for OpaqueFloat %x (data %d length %d)", data, len(data), length) + } + retVal.Type = OpaqueFloat retVal.Value, err = parseFloat32(data[cursor:length]) case OpaqueDouble: // 0x79 x.logPrint("decodeValue: type is OpaqueDouble") length, cursor := parseLength(data) + if length > len(data) { + return retVal, fmt.Errorf("not enough data for OpaqueDouble %x (data %d length %d)", data, len(data), length) + } + retVal.Type = OpaqueDouble retVal.Value, err = parseFloat64(data[cursor:length]) case NoSuchObject: @@ -280,13 +327,13 @@ func marshalInt32(value int) (rs []byte, err error) { rs = make([]byte, 4) if 0 <= value && value <= 2147483647 { binary.BigEndian.PutUint32(rs, uint32(value)) - if value <= 0x80 { + if value < 0x80 { return rs[3:], nil } - if value <= 0x8000 { + if value < 0x8000 { return rs[2:], nil } - if value <= 0x800000 { + if value < 0x800000 { return rs[1:], nil } return rs, nil @@ -308,13 +355,13 @@ func marshalUint32(v interface{}) ([]byte, error) { source := v.(uint32) binary.BigEndian.PutUint32(bs, source) // will panic on failure // truncate leading zeros. Cleaner technique? - if source <= 0x80 { + if source < 0x80 { return bs[3:], nil } - if source <= 0x8000 { + if source < 0x8000 { return bs[2:], nil } - if source <= 0x800000 { + if source < 0x800000 { return bs[1:], nil } return bs, nil @@ -535,9 +582,15 @@ func parseObjectIdentifier(bytes []byte) (s []int, err error) { } func parseRawField(data []byte, msg string) (interface{}, int, error) { + if len(data) == 0 { + return nil, 0, fmt.Errorf("empty data passed to parseRawField") + } switch Asn1BER(data[0]) { case Integer: length, cursor := parseLength(data) + if length > len(data) { + return nil, 0, fmt.Errorf("not enough data for Integer (%d vs %d): %x", length, len(data), data) + } i, err := parseInt(data[cursor:length]) if err != nil { return nil, 0, fmt.Errorf("Unable to parse raw INTEGER: %x err: %v", data, err) @@ -545,13 +598,23 @@ func parseRawField(data []byte, msg string) (interface{}, int, error) { return i, length, nil case OctetString: length, cursor := parseLength(data) + if length > len(data) { + return nil, 0, fmt.Errorf("not enough data for OctetString (%d vs %d): %x", length, len(data), data) + } return string(data[cursor:length]), length, nil case ObjectIdentifier: length, cursor := parseLength(data) + if length > len(data) { + return nil, 0, fmt.Errorf("not enough data for OID (%d vs %d): %x", length, len(data), data) + } oid, err := parseObjectIdentifier(data[cursor:length]) return oid, length, err case IPAddress: length, _ := parseLength(data) + if len(data) < 2 { + return nil, 0, fmt.Errorf("not enough data for ipv4 address: %x", data) + } + switch data[1] { case 0: // real life, buggy devices returning bad data return nil, length, nil @@ -565,6 +628,9 @@ func parseRawField(data []byte, msg string) (interface{}, int, error) { } case TimeTicks: length, cursor := parseLength(data) + if length > len(data) { + return nil, 0, fmt.Errorf("not enough data for TimeTicks (%d vs %d): %x", length, len(data), data) + } ret, err := parseUint(data[cursor:length]) if err != nil { return nil, 0, fmt.Errorf("Error in parseUint: %s", err) diff --git a/vendor/github.com/soniah/gosnmp/marshal.go b/vendor/github.com/soniah/gosnmp/marshal.go index 74bd8e52..09e4e48f 100644 --- a/vendor/github.com/soniah/gosnmp/marshal.go +++ b/vendor/github.com/soniah/gosnmp/marshal.go @@ -6,6 +6,7 @@ package gosnmp import ( "bytes" + "context" "encoding/asn1" "encoding/binary" "fmt" @@ -13,7 +14,6 @@ import ( "net" "strings" "sync/atomic" - "time" ) // @@ -144,8 +144,14 @@ func (x *GoSNMP) sendOneRequest(packetOut *SnmpPacket, } err = nil - reqDeadline := time.Now().Add(timeout) - err = x.Conn.SetDeadline(reqDeadline) + if x.Context.Err() != nil { + return nil, x.Context.Err() + } + + ctx, cancel := context.WithTimeout(x.Context, timeout) + defer cancel() + deadline, _ := ctx.Deadline() + err = x.Conn.SetDeadline(deadline) if err != nil { return nil, err } @@ -226,7 +232,6 @@ func (x *GoSNMP) sendOneRequest(packetOut *SnmpPacket, cursor, err = x.unmarshalHeader(resp, result) if err != nil { x.logPrintf("ERROR on unmarshall header: %s", err) - err = fmt.Errorf("Unable to decode packet: %s", err.Error()) continue } @@ -236,18 +241,16 @@ func (x *GoSNMP) sendOneRequest(packetOut *SnmpPacket, x.logPrintf("ERROR on Test Authentication on v3: %s", err) break } - resp, cursor, err = x.decryptPacket(resp, cursor, result) + resp, cursor, _ = x.decryptPacket(resp, cursor, result) } err = x.unmarshalPayload(resp, cursor, result) if err != nil { x.logPrintf("ERROR on UnmarshalPayload on v3: %s", err) - err = fmt.Errorf("Unable to decode packet: %s", err.Error()) continue } - if result == nil || len(result.Variables) < 1 { + if len(result.Variables) < 1 { x.logPrintf("ERROR on UnmarshalPayload on v3: %s", err) - err = fmt.Errorf("Unable to decode packet: nil") continue } @@ -274,7 +277,6 @@ func (x *GoSNMP) sendOneRequest(packetOut *SnmpPacket, } if !validID { x.logPrint("ERROR out of order") - err = fmt.Errorf("Out of order response") continue } @@ -755,6 +757,10 @@ func (x *GoSNMP) unmarshalHeader(packet []byte, response *SnmpPacket) (int, erro } cursor += count + if cursor > len(packet) { + return 0, fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if version, ok := rawVersion.(int); ok { response.Version = SnmpVersion(version) x.logPrintf("Parsed version %d", version) @@ -772,6 +778,10 @@ func (x *GoSNMP) unmarshalHeader(packet []byte, response *SnmpPacket) (int, erro return 0, fmt.Errorf("Error parsing community string: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return 0, fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if community, ok := rawCommunity.(string); ok { response.Community = community x.logPrintf("Parsed community %s", community) @@ -819,6 +829,10 @@ func (x *GoSNMP) unmarshalResponse(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet request ID: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if requestid, ok := rawRequestID.(int); ok { response.RequestID = uint32(requestid) x.logPrintf("requestID: %d", response.RequestID) @@ -831,6 +845,10 @@ func (x *GoSNMP) unmarshalResponse(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet non repeaters: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if nonRepeaters, ok := rawNonRepeaters.(int); ok { response.NonRepeaters = uint8(nonRepeaters) } @@ -841,6 +859,10 @@ func (x *GoSNMP) unmarshalResponse(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet max repetitions: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if maxRepetitions, ok := rawMaxRepetitions.(int); ok { response.MaxRepetitions = uint8(maxRepetitions) } @@ -851,6 +873,10 @@ func (x *GoSNMP) unmarshalResponse(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet error: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if errorStatus, ok := rawError.(int); ok { response.Error = SNMPError(errorStatus) x.logPrintf("errorStatus: %d", uint8(errorStatus)) @@ -862,6 +888,10 @@ func (x *GoSNMP) unmarshalResponse(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet error index: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if errorindex, ok := rawErrorIndex.(int); ok { response.ErrorIndex = uint8(errorindex) x.logPrintf("error-index: %d", uint8(errorindex)) @@ -886,6 +916,10 @@ func (x *GoSNMP) unmarshalTrapV1(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet error: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if Enterprise, ok := rawEnterprise.([]int); ok { response.Enterprise = oidToString(Enterprise) x.logPrintf("Enterprise: %+v", Enterprise) @@ -897,6 +931,10 @@ func (x *GoSNMP) unmarshalTrapV1(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet error: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if AgentAddress, ok := rawAgentAddress.(string); ok { response.AgentAddress = AgentAddress x.logPrintf("AgentAddress: %s", AgentAddress) @@ -908,6 +946,10 @@ func (x *GoSNMP) unmarshalTrapV1(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet error: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if GenericTrap, ok := rawGenericTrap.(int); ok { response.GenericTrap = GenericTrap x.logPrintf("GenericTrap: %d", GenericTrap) @@ -919,6 +961,10 @@ func (x *GoSNMP) unmarshalTrapV1(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet error: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if SpecificTrap, ok := rawSpecificTrap.(int); ok { response.SpecificTrap = SpecificTrap x.logPrintf("SpecificTrap: %d", SpecificTrap) @@ -930,6 +976,10 @@ func (x *GoSNMP) unmarshalTrapV1(packet []byte, response *SnmpPacket) error { return fmt.Errorf("Error parsing SNMP packet error: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return fmt.Errorf("Error parsing SNMP packet, packet length %d cursor %d", len(packet), cursor) + } + if Timestamp, ok := rawTimestamp.(uint); ok { response.Timestamp = Timestamp x.logPrintf("Timestamp: %d", Timestamp) @@ -943,11 +993,20 @@ func (x *GoSNMP) unmarshalVBL(packet []byte, response *SnmpPacket) error { var cursor, cursorInc int var vblLength int + + if len(packet) == 0 || cursor > len(packet) { + return fmt.Errorf("Truncated packet when unmarshalling a VBL, got length %d cursor %d", len(packet), cursor) + } + if packet[cursor] != 0x30 { return fmt.Errorf("Expected a sequence when unmarshalling a VBL, got %x", packet[cursor]) } vblLength, cursor = parseLength(packet) + if vblLength == 0 || vblLength > len(packet) { + return fmt.Errorf("Truncated packet when unmarshalling a VBL, packet length %d cursor %d", len(packet), cursor) + } + if len(packet) != vblLength { return fmt.Errorf("error verifying: packet length %d vbl length %d", len(packet), vblLength) } @@ -966,13 +1025,20 @@ func (x *GoSNMP) unmarshalVBL(packet []byte, response *SnmpPacket) error { _, cursorInc = parseLength(packet[cursor:]) cursor += cursorInc + if cursor > len(packet) { + return fmt.Errorf("Error parsing OID Value: packet %d cursor %d", len(packet), cursor) + } // Parse OID rawOid, oidLength, err := parseRawField(packet[cursor:], "OID") if err != nil { return fmt.Errorf("Error parsing OID Value: %s", err.Error()) } + cursor += oidLength + if cursor > len(packet) { + return fmt.Errorf("Error parsing OID Value: truncated, packet length %d cursor %d", len(packet), cursor) + } var oid []int var ok bool @@ -987,8 +1053,13 @@ func (x *GoSNMP) unmarshalVBL(packet []byte, response *SnmpPacket) error { if err != nil { return fmt.Errorf("Error decoding value: %v", err) } + valueLength, _ := parseLength(packet[cursor:]) cursor += valueLength + if cursor > len(packet) { + return fmt.Errorf("Error decoding OID Value: truncated, packet length %d cursor %d", len(packet), cursor) + } + response.Variables = append(response.Variables, SnmpPDU{oidStr, v.Type, v.Value, x.Logger}) } return nil diff --git a/vendor/github.com/soniah/gosnmp/trap.go b/vendor/github.com/soniah/gosnmp/trap.go index f5a0cf27..6409f496 100644 --- a/vendor/github.com/soniah/gosnmp/trap.go +++ b/vendor/github.com/soniah/gosnmp/trap.go @@ -8,6 +8,8 @@ import ( "fmt" "log" "net" + "os" + "strings" "sync" "sync/atomic" "time" @@ -96,7 +98,9 @@ type TrapListener struct { // These unexported fields are for letting test cases // know we are ready. - conn *net.UDPConn + conn *net.UDPConn + proto string + finish int32 // Atomic flag; set to 1 when closing connection done chan bool listening chan bool @@ -124,43 +128,26 @@ func (t *TrapListener) Listening() <-chan bool { func (t *TrapListener) Close() { // Prevent concurrent calls to Close if atomic.CompareAndSwapInt32(&t.finish, 0, 1) { - if t.conn != nil { + if t.conn.LocalAddr().Network() == "udp" { t.conn.Close() } <-t.done } } -// Listen listens on the UDP address addr and calls the OnNewTrap -// function specified in *TrapListener for every trap received. -func (t *TrapListener) Listen(addr string) error { - if t.Params == nil { - t.Params = Default - } +func (t *TrapListener) listenUDP(addr string) error { + // udp - t.Params.validateParameters() - /* - TODO returning an error causes TestSendTrapBasic() (and others) to hang - err := t.Params.validateParameters() - if err != nil { - return err - } - */ - - if t.OnNewTrap == nil { - t.OnNewTrap = debugTrapHandler - } - - udpAddr, err := net.ResolveUDPAddr("udp", addr) + udpAddr, err := net.ResolveUDPAddr(t.proto, addr) if err != nil { return err } - conn, err := net.ListenUDP("udp", udpAddr) + t.conn, err = net.ListenUDP("udp", udpAddr) if err != nil { return err } - t.conn = conn - defer conn.Close() + + defer t.conn.Close() // Mark that we are listening now. t.listening <- true @@ -173,7 +160,7 @@ func (t *TrapListener) Listen(addr string) error { default: var buf [4096]byte - rlen, remote, err := conn.ReadFromUDP(buf[:]) + rlen, remote, err := t.conn.ReadFromUDP(buf[:]) if err != nil { if atomic.LoadInt32(&t.finish) == 1 { // err most likely comes from reading from a closed connection @@ -192,6 +179,107 @@ func (t *TrapListener) Listen(addr string) error { } } +func (t *TrapListener) handleTCPRequest(conn net.Conn) { + // Make a buffer to hold incoming data. + buf := make([]byte, 4096) + // Read the incoming connection into the buffer. + reqLen, err := conn.Read(buf) + if err != nil { + t.Params.logPrintf("TrapListener: error in read %s\n", err) + return + } + + //fmt.Printf("TEST: handleTCPRequest:%s, %s", t.proto, conn.RemoteAddr()) + + msg := buf[:reqLen] + traps := t.Params.UnmarshalTrap(msg) + + if traps != nil { + // TODO: lieing for backward compatibility reason - create UDP Address ... not nice + r, _ := net.ResolveUDPAddr("", conn.RemoteAddr().String()) + t.OnNewTrap(traps, r) + } + // Close the connection when you're done with it. + conn.Close() +} + +func (t *TrapListener) listenTCP(addr string) error { + // udp + + tcpAddr, err := net.ResolveTCPAddr(t.proto, addr) + if err != nil { + return err + } + + l, err := net.ListenTCP("tcp", tcpAddr) + if err != nil { + return err + } + + defer l.Close() + + // Mark that we are listening now. + t.listening <- true + + for { + + switch { + case atomic.LoadInt32(&t.finish) == 1: + t.done <- true + return nil + default: + + // Listen for an incoming connection. + conn, err := l.Accept() + fmt.Printf("ACCEPT: %s", conn) + if err != nil { + fmt.Println("Error accepting: ", err.Error()) + os.Exit(1) + } + // Handle connections in a new goroutine. + go t.handleTCPRequest(conn) + } + } +} + +// Listen listens on the UDP address addr and calls the OnNewTrap +// function specified in *TrapListener for every trap received. +func (t *TrapListener) Listen(addr string) error { + if t.Params == nil { + t.Params = Default + } + + t.Params.validateParameters() + /* + TODO returning an error causes TestSendTrapBasic() (and others) to hang + err := t.Params.validateParameters() + if err != nil { + return err + } + */ + + if t.OnNewTrap == nil { + t.OnNewTrap = debugTrapHandler + } + + splitted := strings.SplitN(addr, "://", 2) + t.proto = "udp" + if len(splitted) > 1 { + t.proto = splitted[0] + addr = splitted[1] + } + + //fmt.Printf("TEST: Adress:%s, %s", t.proto, addr) + + if t.proto == "tcp" { + return t.listenTCP(addr) + } else if t.proto == "udp" { + return t.listenUDP(addr) + } + + return fmt.Errorf("Not implemented network protocol: %s [use: tcp/udp]", t.proto) +} + // Default trap handler func debugTrapHandler(s *SnmpPacket, u *net.UDPAddr) { log.Printf("got trapdata from %+v: %+v\n", u, s) diff --git a/vendor/github.com/soniah/gosnmp/v3.go b/vendor/github.com/soniah/gosnmp/v3.go index 134a7163..fd6ea47f 100644 --- a/vendor/github.com/soniah/gosnmp/v3.go +++ b/vendor/github.com/soniah/gosnmp/v3.go @@ -305,12 +305,19 @@ func (x *GoSNMP) unmarshalV3Header(packet []byte, _, cursorTmp := parseLength(packet[cursor:]) cursor += cursorTmp + if cursor > len(packet) { + return 0, fmt.Errorf("Error parsing SNMPV3 message ID: truncted packet") + } rawMsgID, count, err := parseRawField(packet[cursor:], "msgID") if err != nil { return 0, fmt.Errorf("Error parsing SNMPV3 message ID: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return 0, fmt.Errorf("Error parsing SNMPV3 message ID: truncted packet") + } + if MsgID, ok := rawMsgID.(int); ok { response.MsgID = uint32(MsgID) x.logPrintf("Parsed message ID %d", MsgID) @@ -321,6 +328,10 @@ func (x *GoSNMP) unmarshalV3Header(packet []byte, return 0, fmt.Errorf("Error parsing SNMPV3 msgMaxSize: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return 0, fmt.Errorf("Error parsing SNMPV3 message ID: truncted packet") + } + if MsgMaxSize, ok := rawMsgMaxSize.(int); ok { response.MsgMaxSize = uint32(MsgMaxSize) x.logPrintf("Parsed message max size %d", MsgMaxSize) @@ -331,6 +342,10 @@ func (x *GoSNMP) unmarshalV3Header(packet []byte, return 0, fmt.Errorf("Error parsing SNMPV3 msgFlags: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return 0, fmt.Errorf("Error parsing SNMPV3 message ID: truncted packet") + } + if MsgFlags, ok := rawMsgFlags.(string); ok { response.MsgFlags = SnmpV3MsgFlags(MsgFlags[0]) x.logPrintf("parsed msg flags %s", MsgFlags) @@ -341,6 +356,10 @@ func (x *GoSNMP) unmarshalV3Header(packet []byte, return 0, fmt.Errorf("Error parsing SNMPV3 msgSecModel: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return 0, fmt.Errorf("Error parsing SNMPV3 message ID: truncted packet") + } + if SecModel, ok := rawSecModel.(int); ok { response.SecurityModel = SnmpV3SecurityModel(SecModel) x.logPrintf("Parsed security model %d", SecModel) @@ -351,6 +370,9 @@ func (x *GoSNMP) unmarshalV3Header(packet []byte, } _, cursorTmp = parseLength(packet[cursor:]) cursor += cursorTmp + if cursor > len(packet) { + return 0, fmt.Errorf("Error parsing SNMPV3 message ID: truncted packet") + } if response.SecurityParameters != nil { cursor, err = response.SecurityParameters.unmarshal(response.MsgFlags, packet, cursor) @@ -366,6 +388,10 @@ func (x *GoSNMP) decryptPacket(packet []byte, cursor int, response *SnmpPacket) var err error var decrypted = false + if cursor > len(packet) { + return nil, 0, fmt.Errorf("Error parsing SNMPV3: truncated packet") + } + switch PDUType(packet[cursor]) { case PDUType(OctetString): // pdu is encrypted @@ -381,14 +407,25 @@ func (x *GoSNMP) decryptPacket(packet []byte, cursor int, response *SnmpPacket) if decrypted { // truncate padding that might have been included with // the encrypted PDU + if cursor+tlength > len(packet) { + return nil, 0, fmt.Errorf("Error parsing SNMPV3: truncated packet") + } packet = packet[:cursor+tlength] } cursor += cursorTmp + if cursor > len(packet) { + return nil, 0, fmt.Errorf("Error parsing SNMPV3: truncated packet") + } + rawContextEngineID, count, err := parseRawField(packet[cursor:], "contextEngineID") if err != nil { return nil, 0, fmt.Errorf("Error parsing SNMPV3 contextEngineID: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return nil, 0, fmt.Errorf("Error parsing SNMPV3: truncated packet") + } + if contextEngineID, ok := rawContextEngineID.(string); ok { response.ContextEngineID = contextEngineID x.logPrintf("Parsed contextEngineID %s", contextEngineID) @@ -398,6 +435,10 @@ func (x *GoSNMP) decryptPacket(packet []byte, cursor int, response *SnmpPacket) return nil, 0, fmt.Errorf("Error parsing SNMPV3 contextName: %s", err.Error()) } cursor += count + if cursor > len(packet) { + return nil, 0, fmt.Errorf("Error parsing SNMPV3: truncated packet") + } + if contextName, ok := rawContextName.(string); ok { response.ContextName = contextName x.logPrintf("Parsed contextName %s", contextName) diff --git a/vendor/github.com/soniah/gosnmp/v3_usm.go b/vendor/github.com/soniah/gosnmp/v3_usm.go index a6d3f4da..fa0622c9 100644 --- a/vendor/github.com/soniah/gosnmp/v3_usm.go +++ b/vendor/github.com/soniah/gosnmp/v3_usm.go @@ -574,6 +574,9 @@ func (sp *UsmSecurityParameters) encryptPacket(scopedPdu []byte) ([]byte, error) func (sp *UsmSecurityParameters) decryptPacket(packet []byte, cursor int) ([]byte, error) { _, cursorTmp := parseLength(packet[cursor:]) cursorTmp += cursor + if cursorTmp > len(packet) { + return nil, fmt.Errorf("error decrypting ScopedPDU: truncated packet") + } switch sp.PrivacyProtocol { case AES: @@ -681,6 +684,9 @@ func (sp *UsmSecurityParameters) unmarshal(flags SnmpV3MsgFlags, packet []byte, } _, cursorTmp := parseLength(packet[cursor:]) cursor += cursorTmp + if cursorTmp > len(packet) { + return 0, fmt.Errorf("error parsing SNMPV3 User Security Model parameters: truncated packet") + } rawMsgAuthoritativeEngineID, count, err := parseRawField(packet[cursor:], "msgAuthoritativeEngineID") if err != nil { diff --git a/vendor/github.com/soniah/gosnmp/walk.go b/vendor/github.com/soniah/gosnmp/walk.go index a62012c4..793cc1b2 100644 --- a/vendor/github.com/soniah/gosnmp/walk.go +++ b/vendor/github.com/soniah/gosnmp/walk.go @@ -81,6 +81,12 @@ RequestLoop: if requests == 1 && i == 0 { getRequestType = GetRequest continue RequestLoop + } else if pdu.Name == rootOid && pdu.Type != NoSuchInstance { + // Call walk function if the pdu instance is found + // considering that the rootOid is a leafOid + if err := walkFn(pdu); err != nil { + return err + } } break RequestLoop } diff --git a/vendor/modules.txt b/vendor/modules.txt index f1fc70d6..efa7c559 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -12,8 +12,6 @@ github.com/go-kit/kit/log github.com/go-kit/kit/log/level # github.com/go-logfmt/logfmt v0.4.0 github.com/go-logfmt/logfmt -# github.com/golang/mock v1.3.1 -github.com/golang/mock/gomock # github.com/golang/protobuf v1.3.2 github.com/golang/protobuf/proto # github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 @@ -39,7 +37,7 @@ github.com/prometheus/common/version github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util -# github.com/soniah/gosnmp v1.22.0 +# github.com/soniah/gosnmp v1.23.1-0.20200214014533-6d3944030084 github.com/soniah/gosnmp # golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 golang.org/x/sys/windows