diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e6e6843..606b539 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,5 +19,7 @@ jobs: uses: actions/checkout@v2 with: path: ./src/github.com/${{ github.repository }} + - name: Build + run: go build -v ./... - name: Test run: go test ./... diff --git a/go.mod b/go.mod index 3e99563..56efad0 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ module github.com/uyuni-project/hub-xmlrpc-api -go 1.14 +go 1.18 require ( github.com/gorilla/rpc v1.2.0 github.com/knadh/koanf v0.10.0 github.com/uyuni-project/xmlrpc-public-methods v0.0.0-20200805144514-2ca831c526d1 + github.com/mitchellh/mapstructure v1.2.2 ) diff --git a/hub-xmlrpc-api.changes b/hub-xmlrpc-api.changes new file mode 100644 index 0000000..96fa41b --- /dev/null +++ b/hub-xmlrpc-api.changes @@ -0,0 +1,53 @@ +- update go build version to 1.18-openssl + +------------------------------------------------------------------- +Thu Sep 29 08:47:14 UTC 2022 - Marina Latini + +- Use golang(API) = 1.18 for building on SUSE (bsc#1203599) + This source fails to build with the current go1.19 on SUSE and we + need to use go1.18 instead. + +------------------------------------------------------------------- +Fri Jan 21 20:11:30 UTC 2022 - Stefan Bluhm + +- Updated to build on Enterprise Linux 8. + +------------------------------------------------------------------- +Wed Sep 8 08:13:56 UTC 2021 - Ricardo Mateus + +- use rpm systemd macro to restart service in replace of systemctl + +------------------------------------------------------------------- +Wed Aug 19 11:34:05 UTC 2020 - Silvio Moioli + +- version 0.7 +- one configuration flag was renamed for clarity + +------------------------------------------------------------------- +Wed Jul 15 21:13:22 UTC 2020 - Abid Mehmood + +- version 0.6 +- Added USE_SSL flag to https insted of plain http +- Updated docs +- Bugfixes + +------------------------------------------------------------------- +Thu Jun 18 14:05:19 UTC 2020 - Silvio Moioli + +- version 0.5 +- Changed configuration to plain variables +- Bugfixes + +------------------------------------------------------------------- +Thu Mar 30 2020 - Abid Mehmood + +- version 0.1.4 +- Added systemd unit file for the api +- Refactoring to make code more rebust +- Better error handling in case of problems +- Unit and Integration tests have been added + +------------------------------------------------------------------- +Thu Feb 07 2020 - Abid Mehmood + +- Initial commit 0.1.3 diff --git a/hub-xmlrpc-api.spec b/hub-xmlrpc-api.spec new file mode 100644 index 0000000..9cb64c5 --- /dev/null +++ b/hub-xmlrpc-api.spec @@ -0,0 +1,153 @@ +# +# spec file for package hub-xmlrpc-api +# +# Copyright (c) 2020 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + +%if 0%{?rhel} == 8 +%global debug_package %{nil} +%endif + +%if 0%{?rhel} +# Fix ERROR: No build ID note found in +%undefine _missing_build_ids_terminate_build +%endif + +%global provider github +%global provider_tld com +%global org uyuni-project +%global project hub-xmlrpc-api +%global provider_prefix %{provider}.%{provider_tld}/%{org}/%{project} + +Name: %{project} +Version: 0.8 +Release: 0 +Summary: XMLRPC API for Hub environments +License: Apache-2.0 +Group: Applications/Internet +URL: https://%{provider_prefix} +Source0: %{name}-%{version}.tar.gz +Source1: vendor.tar.gz + +%if 0%{?suse_version} +%if 0%{?is_opensuse} +BuildRequires: golang(API) = 1.18 +%else +BuildRequires: go1.18-openssl +%endif +%else +BuildRequires: go >= 1.17 +%endif +BuildRequires: golang-packaging +BuildRequires: rsyslog +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +Requires: logrotate +Requires: rsyslog +Requires: systemd + +%description +The Hub XMLRPC API provides an API which allows access to Uyuni functionality in a Server of Serves architecture (Hub) + +%prep +%autosetup +tar -zxf %{SOURCE1} + +%build +export GOFLAGS=-mod=vendor +%goprep %{provider_prefix} +%gobuild ... + +%install +%goinstall + + +%define _release_dir %{_builddir}/%{project}-%{version}/release + +# Service file for hub xmlrpc api +install -D -m 0644 %{_release_dir}/hub-xmlrpc-api.service %{buildroot}%{_unitdir}/hub-xmlrpc-api.service + +# Add config files for hub +install -d -m 0750 %{buildroot}%{_sysconfdir}/hub +install -D -m 0644 %{_release_dir}/hub.conf %{buildroot}%{_sysconfdir}/hub +install -d -m 0750 %{buildroot}%{_var}/log/hub + +# Add syslog config to redirect logs to /var/log/hub/hub-xmlrpc-api.log +install -D -m 0644 %{_release_dir}/hub-logs.conf %{buildroot}%{_sysconfdir}/rsyslog.d/hub-logs.conf + +#logrotate config +install -D -m 0644 %{_release_dir}/logrotate.conf %{buildroot}%{_sysconfdir}/logrotate.d/hub-xmlrpc-api + +%check +# Fix OBS debug_package execution. +rm -f %{buildroot}/usr/lib/debug/%{_bindir}/%{name}-%{version}-*.debug + +%pre +%if 0%{?suse_version} +%service_add_pre %{name}.service +%endif + +%post +%if 0%{?rhel} +%systemd_post %{name}.service +%else +%service_add_post %{name}.service +%endif +if [ $1 == 1 ];then + echo "-----------------------" + echo "### The Hub XMLRPC API does NOT start on installation. You can set it up to start automatically with systemd, by executing the following commands" + echo " sudo systemctl enable hub-xmlrpc-api.service" + echo "" + echo "### You can start Hub XMLRPC API by executing the following command" + echo " sudo systemctl start hub-xmlrpc-api.service" + echo "" + echo " Make sure that '/etc/hub/hub.conf' is pointing to the correct Hub host" + echo " Logs can be viewed at /var/log/hub/hub-xmlrpc-api.log" + + %if 0%{?rhel} + %systemd_postun rsyslog.service + %else + %service_del_postun rsyslog.service + %endif +fi + +%preun +%if 0%{?rhel} +%systemd_preun %{name}.service +%else +%service_del_preun %{name}.service +%endif + +%postun +%if 0%{?rhel} +%systemd_postun %{name}.service +%else +%service_del_postun %{name}.service +%endif + +%files + +%defattr(-,root,root) +%doc README.md +%{_bindir}/hub-xmlrpc-api + +%{_unitdir}/hub-xmlrpc-api.service +%dir %{_sysconfdir}/hub +%dir %{_var}/log/hub + +%config(noreplace) %{_sysconfdir}/rsyslog.d/hub-logs.conf +%config(noreplace) %{_sysconfdir}/hub/hub.conf +%config(noreplace) %{_sysconfdir}/logrotate.d/hub-xmlrpc-api + +%changelog diff --git a/vendor/github.com/gorilla/rpc/.gitignore b/vendor/github.com/gorilla/rpc/.gitignore deleted file mode 100644 index b25c15b..0000000 --- a/vendor/github.com/gorilla/rpc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*~ diff --git a/vendor/github.com/gorilla/rpc/.travis.yml b/vendor/github.com/gorilla/rpc/.travis.yml deleted file mode 100644 index 42e9825..0000000 --- a/vendor/github.com/gorilla/rpc/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: go - -matrix: - include: - - go: 1.7.x - - go: 1.8.x - - go: 1.9.x - - go: 1.10.x - - go: 1.11.x - - go: 1.x - env: LATEST=true - - go: tip - allow_failures: - - go: tip - -install: - - # Skip - -script: - - go get -t -v ./... - - diff -u <(echo -n) <(gofmt -d .) - - if [[ "$LATEST" = true ]]; then go vet .; fi - - go test -v -race ./... diff --git a/vendor/github.com/gorilla/rpc/LICENSE b/vendor/github.com/gorilla/rpc/LICENSE deleted file mode 100644 index 0e5fb87..0000000 --- a/vendor/github.com/gorilla/rpc/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 Rodrigo Moraes. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/rpc/README.md b/vendor/github.com/gorilla/rpc/README.md deleted file mode 100644 index ee729a3..0000000 --- a/vendor/github.com/gorilla/rpc/README.md +++ /dev/null @@ -1,7 +0,0 @@ -rpc -=== -[![Build Status](https://travis-ci.org/gorilla/rpc.png?branch=master)](https://travis-ci.org/gorilla/rpc) - -gorilla/rpc is a foundation for RPC over HTTP services, providing access to the exported methods of an object through HTTP requests. - -Read the full documentation here: https://www.gorillatoolkit.org/pkg/rpc diff --git a/vendor/github.com/gorilla/rpc/doc.go b/vendor/github.com/gorilla/rpc/doc.go deleted file mode 100644 index bc65b53..0000000 --- a/vendor/github.com/gorilla/rpc/doc.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package gorilla/rpc is a foundation for RPC over HTTP services, providing -access to the exported methods of an object through HTTP requests. - -This package derives from the standard net/rpc package but uses a single HTTP -request per call instead of persistent connections. Other differences -compared to net/rpc: - - - Multiple codecs can be registered in the same server. - - A codec is chosen based on the "Content-Type" header from the request. - - Service methods also receive http.Request as parameter. - - This package can be used on Google App Engine. - -Let's setup a server and register a codec and service: - - import ( - "http" - "github.com/gorilla/rpc" - "github.com/gorilla/rpc/json" - ) - - func init() { - s := rpc.NewServer() - s.RegisterCodec(json.NewCodec(), "application/json") - s.RegisterService(new(HelloService), "") - http.Handle("/rpc", s) - } - -This server handles requests to the "/rpc" path using a JSON codec. -A codec is tied to a content type. In the example above, the JSON codec is -registered to serve requests with "application/json" as the value for the -"Content-Type" header. If the header includes a charset definition, it is -ignored; only the media-type part is taken into account. - -A service can be registered using a name. If the name is empty, like in the -example above, it will be inferred from the service type. - -That's all about the server setup. Now let's define a simple service: - - type HelloArgs struct { - Who string - } - - type HelloReply struct { - Message string - } - - type HelloService struct {} - - func (h *HelloService) Say(r *http.Request, args *HelloArgs, reply *HelloReply) error { - reply.Message = "Hello, " + args.Who + "!" - return nil - } - -The example above defines a service with a method "HelloService.Say" and -the arguments and reply related to that method. - -The service must be exported (begin with an upper case letter) or local -(defined in the package registering the service). - -When a service is registered, the server inspects the service methods -and make available the ones that follow these rules: - - - The method name is exported. - - The method has three arguments: *http.Request, *args, *reply. - - All three arguments are pointers. - - The second and third arguments are exported or local. - - The method has return type error. - -All other methods are ignored. - -Gorilla has packages with common RPC codecs. Check out their documentation: - - JSON: http://gorilla-web.appspot.com/pkg/rpc/json -*/ -package rpc diff --git a/vendor/github.com/gorilla/rpc/map.go b/vendor/github.com/gorilla/rpc/map.go deleted file mode 100644 index 433f275..0000000 --- a/vendor/github.com/gorilla/rpc/map.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package rpc - -import ( - "fmt" - "net/http" - "reflect" - "strings" - "sync" - "unicode" - "unicode/utf8" -) - -var ( - // Precompute the reflect.Type of error and http.Request - typeOfError = reflect.TypeOf((*error)(nil)).Elem() - typeOfRequest = reflect.TypeOf((*http.Request)(nil)).Elem() -) - -// ---------------------------------------------------------------------------- -// service -// ---------------------------------------------------------------------------- - -type service struct { - name string // name of service - rcvr reflect.Value // receiver of methods for the service - rcvrType reflect.Type // type of the receiver - methods map[string]*serviceMethod // registered methods - passReq bool -} - -type serviceMethod struct { - method reflect.Method // receiver method - argsType reflect.Type // type of the request argument - replyType reflect.Type // type of the response argument -} - -// ---------------------------------------------------------------------------- -// serviceMap -// ---------------------------------------------------------------------------- - -// serviceMap is a registry for services. -type serviceMap struct { - mutex sync.Mutex - services map[string]*service -} - -// register adds a new service using reflection to extract its methods. -func (m *serviceMap) register(rcvr interface{}, name string, passReq bool) error { - // Setup service. - s := &service{ - name: name, - rcvr: reflect.ValueOf(rcvr), - rcvrType: reflect.TypeOf(rcvr), - methods: make(map[string]*serviceMethod), - passReq: passReq, - } - if name == "" { - s.name = reflect.Indirect(s.rcvr).Type().Name() - if !isExported(s.name) { - return fmt.Errorf("rpc: type %q is not exported", s.name) - } - } - if s.name == "" { - return fmt.Errorf("rpc: no service name for type %q", - s.rcvrType.String()) - } - // Setup methods. - for i := 0; i < s.rcvrType.NumMethod(); i++ { - method := s.rcvrType.Method(i) - mtype := method.Type - - // offset the parameter indexes by one if the - // service methods accept an HTTP request pointer - var paramOffset int - if passReq { - paramOffset = 1 - } else { - paramOffset = 0 - } - - // Method must be exported. - if method.PkgPath != "" { - continue - } - // Method needs four ins: receiver, *http.Request, *args, *reply. - if mtype.NumIn() != 3+paramOffset { - continue - } - - // If the service methods accept an HTTP request pointer - if passReq { - // First argument must be a pointer and must be http.Request. - reqType := mtype.In(1) - if reqType.Kind() != reflect.Ptr || reqType.Elem() != typeOfRequest { - continue - } - } - // Next argument must be a pointer and must be exported. - args := mtype.In(1 + paramOffset) - if args.Kind() != reflect.Ptr || !isExportedOrBuiltin(args) { - continue - } - // Next argument must be a pointer and must be exported. - reply := mtype.In(2 + paramOffset) - if reply.Kind() != reflect.Ptr || !isExportedOrBuiltin(reply) { - continue - } - // Method needs one out: error. - if mtype.NumOut() != 1 { - continue - } - if returnType := mtype.Out(0); returnType != typeOfError { - continue - } - s.methods[method.Name] = &serviceMethod{ - method: method, - argsType: args.Elem(), - replyType: reply.Elem(), - } - } - if len(s.methods) == 0 { - return fmt.Errorf("rpc: %q has no exported methods of suitable type", - s.name) - } - // Add to the map. - m.mutex.Lock() - defer m.mutex.Unlock() - if m.services == nil { - m.services = make(map[string]*service) - } else if _, ok := m.services[s.name]; ok { - return fmt.Errorf("rpc: service already defined: %q", s.name) - } - m.services[s.name] = s - return nil -} - -// get returns a registered service given a method name. -// -// The method name uses a dotted notation as in "Service.Method". -func (m *serviceMap) get(method string) (*service, *serviceMethod, error) { - parts := strings.Split(method, ".") - if len(parts) != 2 { - err := fmt.Errorf("rpc: service/method request ill-formed: %q", method) - return nil, nil, err - } - m.mutex.Lock() - service := m.services[parts[0]] - m.mutex.Unlock() - if service == nil { - err := fmt.Errorf("rpc: can't find service %q", method) - return nil, nil, err - } - serviceMethod := service.methods[parts[1]] - if serviceMethod == nil { - err := fmt.Errorf("rpc: can't find method %q", method) - return nil, nil, err - } - return service, serviceMethod, nil -} - -// isExported returns true of a string is an exported (upper case) name. -func isExported(name string) bool { - rune, _ := utf8.DecodeRuneInString(name) - return unicode.IsUpper(rune) -} - -// isExportedOrBuiltin returns true if a type is exported or a builtin. -func isExportedOrBuiltin(t reflect.Type) bool { - for t.Kind() == reflect.Ptr { - t = t.Elem() - } - // PkgPath will be non-empty even for an exported type, - // so we need to check the type name as well. - return isExported(t.Name()) || t.PkgPath() == "" -} diff --git a/vendor/github.com/gorilla/rpc/server.go b/vendor/github.com/gorilla/rpc/server.go deleted file mode 100644 index 76a3260..0000000 --- a/vendor/github.com/gorilla/rpc/server.go +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package rpc - -import ( - "fmt" - "net/http" - "reflect" - "strings" -) - -// ---------------------------------------------------------------------------- -// Codec -// ---------------------------------------------------------------------------- - -// Codec creates a CodecRequest to process each request. -type Codec interface { - NewRequest(*http.Request) CodecRequest -} - -// CodecRequest decodes a request and encodes a response using a specific -// serialization scheme. -type CodecRequest interface { - // Reads request and returns the RPC method name. - Method() (string, error) - // Reads request filling the RPC method args. - ReadRequest(interface{}) error - // Writes response using the RPC method reply. The error parameter is - // the error returned by the method call, if any. - WriteResponse(http.ResponseWriter, interface{}, error) error -} - -// ---------------------------------------------------------------------------- -// Server -// ---------------------------------------------------------------------------- - -// NewServer returns a new RPC server. -func NewServer() *Server { - return &Server{ - codecs: make(map[string]Codec), - services: new(serviceMap), - } -} - -// RequestInfo contains all the information we pass to before/after functions -type RequestInfo struct { - Method string - Error error - Request *http.Request - StatusCode int -} - -// Server serves registered RPC services using registered codecs. -type Server struct { - codecs map[string]Codec - services *serviceMap - interceptFunc func(i *RequestInfo) *http.Request - beforeFunc func(i *RequestInfo) - afterFunc func(i *RequestInfo) -} - -// RegisterCodec adds a new codec to the server. -// -// Codecs are defined to process a given serialization scheme, e.g., JSON or -// XML. A codec is chosen based on the "Content-Type" header from the request, -// excluding the charset definition. -func (s *Server) RegisterCodec(codec Codec, contentType string) { - s.codecs[strings.ToLower(contentType)] = codec -} - -// RegisterService adds a new service to the server. -// -// The name parameter is optional: if empty it will be inferred from -// the receiver type name. -// -// Methods from the receiver will be extracted if these rules are satisfied: -// -// - The receiver is exported (begins with an upper case letter) or local -// (defined in the package registering the service). -// - The method name is exported. -// - The method has three arguments: *http.Request, *args, *reply. -// - All three arguments are pointers. -// - The second and third arguments are exported or local. -// - The method has return type error. -// -// All other methods are ignored. -func (s *Server) RegisterService(receiver interface{}, name string) error { - return s.services.register(receiver, name, true) -} - -// RegisterTCPService adds a new TCP service to the server. -// No HTTP request struct will be passed to the service methods. -// -// The name parameter is optional: if empty it will be inferred from -// the receiver type name. -// -// Methods from the receiver will be extracted if these rules are satisfied: -// -// - The receiver is exported (begins with an upper case letter) or local -// (defined in the package registering the service). -// - The method name is exported. -// - The method has two arguments: *args, *reply. -// - Both arguments are pointers. -// - Both arguments are exported or local. -// - The method has return type error. -// -// All other methods are ignored. -func (s *Server) RegisterTCPService(receiver interface{}, name string) error { - return s.services.register(receiver, name, false) -} - -// HasMethod returns true if the given method is registered. -// -// The method uses a dotted notation as in "Service.Method". -func (s *Server) HasMethod(method string) bool { - if _, _, err := s.services.get(method); err == nil { - return true - } - return false -} - -// RegisterInterceptFunc registers the specified function as the function -// that will be called before every request. The function is allowed to intercept -// the request e.g. add values to the context. -// -// Note: Only one function can be registered, subsequent calls to this -// method will overwrite all the previous functions. -func (s *Server) RegisterInterceptFunc(f func(i *RequestInfo) *http.Request) { - s.interceptFunc = f -} - -// RegisterBeforeFunc registers the specified function as the function -// that will be called before every request. -// -// Note: Only one function can be registered, subsequent calls to this -// method will overwrite all the previous functions. -func (s *Server) RegisterBeforeFunc(f func(i *RequestInfo)) { - s.beforeFunc = f -} - -// RegisterAfterFunc registers the specified function as the function -// that will be called after every request -// -// Note: Only one function can be registered, subsequent calls to this -// method will overwrite all the previous functions. -func (s *Server) RegisterAfterFunc(f func(i *RequestInfo)) { - s.afterFunc = f -} - -// ServeHTTP -func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - s.writeError(w, 405, "rpc: POST method required, received "+r.Method) - return - } - contentType := r.Header.Get("Content-Type") - idx := strings.Index(contentType, ";") - if idx != -1 { - contentType = contentType[:idx] - } - var codec Codec - if contentType == "" && len(s.codecs) == 1 { - // If Content-Type is not set and only one codec has been registered, - // then default to that codec. - for _, c := range s.codecs { - codec = c - } - } else if codec = s.codecs[strings.ToLower(contentType)]; codec == nil { - s.writeError(w, 415, "rpc: unrecognized Content-Type: "+contentType) - return - } - // Create a new codec request. - codecReq := codec.NewRequest(r) - // Get service method to be called. - method, errMethod := codecReq.Method() - if errMethod != nil { - s.writeError(w, 400, errMethod.Error()) - return - } - serviceSpec, methodSpec, errGet := s.services.get(method) - if errGet != nil { - s.writeError(w, 400, errGet.Error()) - return - } - // Decode the args. - args := reflect.New(methodSpec.argsType) - if errRead := codecReq.ReadRequest(args.Interface()); errRead != nil { - s.writeError(w, 400, errRead.Error()) - return - } - - // Call the registered Intercept Function - if s.interceptFunc != nil { - req := s.interceptFunc(&RequestInfo{ - Request: r, - Method: method, - }) - if req != nil { - r = req - } - } - // Call the registered Before Function - if s.beforeFunc != nil { - s.beforeFunc(&RequestInfo{ - Request: r, - Method: method, - }) - } - - // Call the service method. - reply := reflect.New(methodSpec.replyType) - - // omit the HTTP request if the service method doesn't accept it - var errValue []reflect.Value - if serviceSpec.passReq { - errValue = methodSpec.method.Func.Call([]reflect.Value{ - serviceSpec.rcvr, - reflect.ValueOf(r), - args, - reply, - }) - } else { - errValue = methodSpec.method.Func.Call([]reflect.Value{ - serviceSpec.rcvr, - args, - reply, - }) - } - - // Cast the result to error if needed. - var errResult error - errInter := errValue[0].Interface() - if errInter != nil { - errResult = errInter.(error) - } - - // Prevents Internet Explorer from MIME-sniffing a response away - // from the declared content-type - w.Header().Set("x-content-type-options", "nosniff") - // Encode the response. - if errWrite := codecReq.WriteResponse(w, reply.Interface(), errResult); errWrite != nil { - s.writeError(w, 400, errWrite.Error()) - } else { - // Call the registered After Function - if s.afterFunc != nil { - s.afterFunc(&RequestInfo{ - Request: r, - Method: method, - Error: errResult, - StatusCode: 200, - }) - } - } -} - -func (s *Server) writeError(w http.ResponseWriter, status int, msg string) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.WriteHeader(status) - fmt.Fprint(w, msg) - if s.afterFunc != nil { - s.afterFunc(&RequestInfo{ - Error: fmt.Errorf(msg), - StatusCode: status, - }) - } -} diff --git a/vendor/github.com/knadh/koanf/.gitignore b/vendor/github.com/knadh/koanf/.gitignore deleted file mode 100644 index 2eea525..0000000 --- a/vendor/github.com/knadh/koanf/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.env \ No newline at end of file diff --git a/vendor/github.com/knadh/koanf/.travis.yml b/vendor/github.com/knadh/koanf/.travis.yml deleted file mode 100644 index e8b36ea..0000000 --- a/vendor/github.com/knadh/koanf/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -go_import_path: github.com/knadh/koanf - -language: go - -env: - global: - - GO111MODULE="on" - -os: - - linux - -go: - - 1.11.x - - 1.12.x - -install: go get -v ./... -script: go test -v -cover ./... diff --git a/vendor/github.com/knadh/koanf/LICENSE b/vendor/github.com/knadh/koanf/LICENSE deleted file mode 100644 index c78ef52..0000000 --- a/vendor/github.com/knadh/koanf/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2019, Kailash Nadh. https://github.com/knadh - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/knadh/koanf/README.md b/vendor/github.com/knadh/koanf/README.md deleted file mode 100644 index 68f4dd3..0000000 --- a/vendor/github.com/knadh/koanf/README.md +++ /dev/null @@ -1,591 +0,0 @@ -![koanf](https://user-images.githubusercontent.com/547147/72681838-6981dd00-3aed-11ea-8f5d-310816c70c08.png) - -**koanf** (pronounced _conf_; a play on the Japanese _Koan_) is a library for reading configuration from different sources in different formats in Go applications. It is a cleaner, lighter [alternative to spf13/viper](#alternative-to-viper) with better abstractions and extensibility and fewer dependencies. - -koanf comes with built in support for reading configuration from files, command line flags, and environment variables, and can parse JSON, YAML, TOML, and Hashicorp HCL. - -[![Build Status](https://travis-ci.com/knadh/koanf.svg?branch=master)](https://travis-ci.com/knadh/koanf) [![GoDoc](https://godoc.org/github.com/knadh/koanf?status.svg)](https://godoc.org/github.com/knadh/koanf) - -### Installation - -`go get -u github.com/knadh/koanf` - -### Contents - -- [Concepts](#concepts) -- [Reading config from files](#reading-config-from-files) -- [Watching files for changes](#watching-files-for-changes) -- [Reading from command line](#reading-from-command-line) -- [Reading environment variables](#reading-environment-variables) -- [Reading raw bytes](#reading-raw-bytes) -- [Unmarshalling and marshalling](#unmarshalling-and-marshalling) -- [Unmarshalling with flat paths](#unmarshalling-with-flat-paths) -- [Setting default values](#setting-default-values) -- [Order of merge and key case senstivity](#order-of-merge-and-key-case-senstivity) -- [Custom Providers and Parsers](#custom-providers-and-parsers) -- [API](#api) - -### Concepts - -- `koanf.Provider` is a generic interface that provides configuration, for example, from files, enviornment variables, HTTP sources, or anywhere. The configuration can either be raw bytes that a parser can parse, or it can be a nested map[string]interface{} that can be directly loaded. -- `koanf.Parser` is a generic interface that takes raw bytes, parses, and returns a nested map[string]interface{} representation. For example, JSON and YAML parsers. -- Once loaded into koanf, configuration are values queried by a delimited key path syntax. eg: `app.server.port`. Any delimiter can be chosen. -- Configuration from multiple sources can be loaded and merged into a koanf instance, for example, load from a file first and override certain values with flags from the command line. - -With these two interface implementations, koanf can obtain configuration from multiple sources and parse any format and make it available to an application. - -### Reading config from files - -```go -package main - -import ( - "fmt" - "log" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/parsers/json" - "github.com/knadh/koanf/parsers/yaml" - "github.com/knadh/koanf/providers/file" -) - -// Global koanf instance. Use "." as the key path delimiter. This can be "/" or any character. -var k = koanf.New(".") - -func main() { - // Load JSON config. - if err := k.Load(file.Provider("mock/mock.json"), json.Parser()); err != nil { - log.Fatalf("error loading config: %v", err) - } - - // Load YAML config and merge into the previously loaded config (because we can). - k.Load(file.Provider("mock/mock.yaml"), yaml.Parser()) - - fmt.Println("parent's name is = ", k.String("parent1.name")) - fmt.Println("parent's ID is = ", k.Int("parent1.id")) -} - -``` - -### Watching files for changes -The `koanf.Provider` interface has a `Watch(cb)` method that asks a provider -to watch for changes and trigger the given callback that can live reload the -configuration. - -Currently, `file.Provider` supports this. - - -```go -package main - -import ( - "fmt" - "log" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/parsers/json" - "github.com/knadh/koanf/parsers/yaml" - "github.com/knadh/koanf/providers/file" -) - -// Global koanf instance. Use "." as the key path delimiter. This can be "/" or any character. -var k = koanf.New(".") - -func main() { - // Load JSON config. - f := file.Provider("mock/mock.json") - if err := k.Load(f, json.Parser()); err != nil { - log.Fatalf("error loading config: %v", err) - } - - // Load YAML config and merge into the previously loaded config (because we can). - k.Load(file.Provider("mock/mock.yaml"), yaml.Parser()) - - fmt.Println("parent's name is = ", k.String("parent1.name")) - fmt.Println("parent's ID is = ", k.Int("parent1.id")) - - // Watch the file and get a callback on change. The callback can do whatever, - // like re-load the configuration. - // File provider always returns a nil `event`. - f.Watch(func(event interface{}, err error) { - if err != nil { - log.Printf("watch error: %v", err) - return - } - - log.Println("config changed. Reloading ...") - k.Load(f, json.Parser()) - k.Print() - }) - - // Block forever (and manually make a change to mock/mock.json) to - // reload the config. - log.Println("waiting forever. Try making a change to mock/mock.json to live reload") - <-make(chan bool) -} -``` - - -### Reading from command line - -The following example shows the use of `posflag.Provider`, a wrapper over [spf13/pflag](/spf13/pflag) library, an advanced commandline lib. For Go's built in `flag` package, use `basicflag.Provider`. - -```go -package main - -import ( - "fmt" - "log" - "os" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/parsers/toml" - "github.com/knadh/koanf/providers/file" - "github.com/knadh/koanf/providers/posflag" - flag "github.com/spf13/pflag" -) - -// Global koanf instance. Use "." as the key path delimiter. This can be "/" or any character. -var k = koanf.New(".") - -func main() { - // Use the POSIX compliant pflag lib instead of Go's flag lib. - f := flag.NewFlagSet("config", flag.ContinueOnError) - f.Usage = func() { - fmt.Println(f.FlagUsages()) - os.Exit(0) - } - // Path to one or more config files to load into koanf along with some config params. - f.StringSlice("conf", []string{"mock/mock.toml"}, "path to one or more .toml config files") - f.String("time", "2020-01-01", "a time string") - f.String("type", "xxx", "type of the app") - f.Parse(os.Args[1:]) - - // Load the config files provided in the commandline. - cFiles, _ := f.GetStringSlice("conf") - for _, c := range cFiles { - if err := k.Load(file.Provider(c), toml.Parser()); err != nil { - log.Fatalf("error loading file: %v", err) - } - } - - // "time" and "type" may have been loaded from the config file, but - // they can still be overridden with the values from the command line. - // The bundled posflag.Provider takes a flagset from the spf13/pflag lib. - // Passing the Koanf instance to posflag helps it deal with default command - // line flag values that are not present in conf maps from previously loaded - // providers. - if err := k.Load(posflag.Provider(f, ".", k), nil); err != nil { - log.Fatalf("error loading config: %v", err) - } - - fmt.Println("time is = ", k.String("time")) -} -``` - -### Reading environment variables - -```go -package main - -import ( - "fmt" - "log" - "strings" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/parsers/json" - "github.com/knadh/koanf/providers/env" - "github.com/knadh/koanf/providers/file" -) - -// Global koanf instance. Use . as the key path delimiter. This can be / or anything. -var k = koanf.New(".") - -func main() { - // Load JSON config. - if err := k.Load(file.Provider("mock/mock.json"), json.Parser()); err != nil { - log.Fatalf("error loading config: %v", err) - } - - // Load environment variables and merge into the loaded config. - // "MYVAR" is the prefix to filter the env vars by. - // "." is the delimiter used to represent the key hierarchy in env vars. - // The (optional, or can be nil) function can be used to transform - // the env var names, for instance, to lowercase them. - // - // For example, env vars: MYVAR_TYPE and MYVAR_PARENT1_CHILD1_NAME - // will be merged into the "type" and the nested "parent1.child1.name" - // keys in the config file here as we lowercase the key, - // replace `_` with `.` and strip the MYVAR_ prefix so that - // only "parent1.child1.name" remains. - k.Load(env.Provider("MYVAR_", ".", func(s string) string { - return strings.Replace(strings.ToLower( - strings.TrimPrefix(s, "MYVAR_")), "_", ".", -1) - }), nil) - - fmt.Println("name is = ", k.String("parent1.child1.name")) -} -``` - -### Reading from an S3 bucket - -```go -// Load JSON config from s3. -if err := k.Load(s3.Provider(s3.Config{ - AccessKey: os.Getenv("AWS_S3_ACCESS_KEY"), - SecretKey: os.Getenv("AWS_S3_SECRET_KEY"), - Region: os.Getenv("AWS_S3_REGION"), - Bucket: os.Getenv("AWS_S3_BUCKET"), - ObjectKey: "dir/config.json", -}), json.Parser()); err != nil { - log.Fatalf("error loading config: %v", err) -} -``` - -### Reading raw bytes - -The bundled `rawbytes` Provider can be used to read arbitrary bytes from a source, like a database or an HTTP call. - -```go -package main - -import ( - "fmt" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/parsers/json" - "github.com/knadh/koanf/providers/rawbytes" -) - -// Global koanf instance. Use . as the key path delimiter. This can be / or anything. -var k = koanf.New(".") - -func main() { - b := []byte(`{"type": "rawbytes", "parent1": {"child1": {"type": "rawbytes"}}}`) - k.Load(rawbytes.Provider(b), json.Parser()) - fmt.Println("type is = ", k.String("parent1.child1.type")) -} -``` - -### Unmarshalling and marshalling -`Parser`s can be used to unmarshal and scan the values in a Koanf instance into a struct based on the field tags, and also to marshal a Koanf instance back into serialized bytes, for example, back to JSON or YAML, to write back to files. - -```go -package main - -import ( - "fmt" - "log" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/parsers/json" - "github.com/knadh/koanf/providers/file" -) - -// Global koanf instance. Use . as the key path delimiter. This can be / or anything. -var ( - k = koanf.New(".") - parser = json.Parser() -) - -func main() { - // Load JSON config. - if err := k.Load(file.Provider("mock/mock.json"), parser); err != nil { - log.Fatalf("error loading config: %v", err) - } - - // Structure to unmarshal nested conf to. - type childStruct struct { - Name string `koanf:"name"` - Type string `koanf:"type"` - Empty map[string]string `koanf:"empty"` - GrandChild struct { - Ids []int `koanf:"ids"` - On bool `koanf:"on"` - } `koanf:"grandchild1"` - } - - var out childStruct - - // Quick unmarshal. - k.Unmarshal("parent1.child1", &out) - fmt.Println(out) - - // Unmarshal with advanced config. - out = childStruct{} - k.UnmarshalWithConf("parent1.child1", &out, koanf.UnmarshalConf{Tag: "koanf"}) - fmt.Println(out) - - // Marshal the instance back to JSON. - // The paser instance can be anything, eg: json.Paser(), yaml.Parser() etc. - b, _ := k.Marshal(parser) - fmt.Println(string(b)) -} -``` - -### Unmarshalling with flat paths - -Sometimes it is necessary to unmarshal an assortment of keys from various nested structures into a flat target structure. This is possible with the `UnmarshalConf.FlatPaths` flag. - -```go -package main - -import ( - "fmt" - "log" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/parsers/json" - "github.com/knadh/koanf/providers/file" -) - -// Global koanf instance. Use . as the key path delimiter. This can be / or anything. -var k = koanf.New(".") - -func main() { - // Load JSON config. - if err := k.Load(file.Provider("mock/mock.json"), json.Parser()); err != nil { - log.Fatalf("error loading config: %v", err) - } - - type rootFlat struct { - Type string `koanf:"type"` - Empty map[string]string `koanf:"empty"` - Parent1Name string `koanf:"parent1.name"` - Parent1ID int `koanf:"parent1.id"` - Parent1Child1Name string `koanf:"parent1.child1.name"` - Parent1Child1Type string `koanf:"parent1.child1.type"` - Parent1Child1Empty map[string]string `koanf:"parent1.child1.empty"` - Parent1Child1Grandchild1IDs []int `koanf:"parent1.child1.grandchild1.ids"` - Parent1Child1Grandchild1On bool `koanf:"parent1.child1.grandchild1.on"` - } - - // Unmarshal the whole root with FlatPaths: True. - var o1 rootFlat - k.UnmarshalWithConf("", &o1, koanf.UnmarshalConf{Tag: "koanf", FlatPaths: true}) - fmt.Println(o1) - - // Unmarshal a child structure of "parent1". - type subFlat struct { - Name string `koanf:"name"` - ID int `koanf:"id"` - Child1Name string `koanf:"child1.name"` - Child1Type string `koanf:"child1.type"` - Child1Empty map[string]string `koanf:"child1.empty"` - Child1Grandchild1IDs []int `koanf:"child1.grandchild1.ids"` - Child1Grandchild1On bool `koanf:"child1.grandchild1.on"` - } - - var o2 subFlat - k.UnmarshalWithConf("parent1", &o2, koanf.UnmarshalConf{Tag: "koanf", FlatPaths: true}) - fmt.Println(o2) -} -``` - -### Marshalling and writing config -It is possible to marshal and serialize the conf map into TOML, YAML etc. - -### Setting default values. - -koanf does not provide any special functions to set default values but uses the Provider interface to enable it. - -#### From a map - -The bundled `confmap` provider takes a `map[string]interface{}` that can be loaded into a koanf instance. - -```go -package main - -import ( - "fmt" - "log" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/providers/confmap" - "github.com/knadh/koanf/providers/file" - "github.com/knadh/koanf/parsers/json" - "github.com/knadh/koanf/parsers/yaml" -) - -// Global koanf instance. Use "." as the key path delimiter. This can be "/" or any character. -var k = koanf.New(".") - -func main() { - // Load default values using the confmap provider. - // We provide a flat map with the "." delimiter. - // A nested map can be loaded by setting the delimiter to an empty string "". - k.Load(confmap.Provider(map[string]interface{}{ - "parent1.name": "Default Name", - "parent3.name": "New name here", - }, "."), nil) - - // Load JSON config on top of the default values. - if err := k.Load(file.Provider("mock/mock.json"), json.Parser()); err != nil { - log.Fatalf("error loading config: %v", err) - } - - // Load YAML config and merge into the previously loaded config (because we can). - k.Load(file.Provider("mock/mock.yaml"), yaml.Parser()) - - fmt.Println("parent's name is = ", k.String("parent1.name")) - fmt.Println("parent's ID is = ", k.Int("parent1.id")) -} -``` - -#### From a struct - -The bundled `structs` provider can be used to read data from a struct to load into a koanf instance. - -```go -package main - -import ( - "fmt" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/providers/structs" -) - -// Global koanf instance. Use "." as the key path delimiter. This can be "/" or any character. -var k = koanf.New(".") - -type parentStruct struct { - Name string `koanf:"name"` - ID int `koanf:"id"` - Child1 childStruct `koanf:"child1"` -} -type childStruct struct { - Name string `koanf:"name"` - Type string `koanf:"type"` - Empty map[string]string `koanf:"empty"` - Grandchild1 grandchildStruct `koanf:"grandchild1"` -} -type grandchildStruct struct { - Ids []int `koanf:"ids"` - On bool `koanf:"on"` -} -type sampleStruct struct { - Type string `koanf:"type"` - Empty map[string]string `koanf:"empty"` - Parent1 parentStruct `koanf:"parent1"` -} - -func main() { - // Load default values using the structs provider. - // We provide a struct along with the struct tag `koanf` to the - // provider. - k.Load(structs.Provider(sampleStruct{ - Type: "json", - Empty: make(map[string]string), - Parent1: parentStruct{ - Name: "parent1", - ID: 1234, - Child1: childStruct{ - Name: "child1", - Type: "json", - Empty: make(map[string]string), - Grandchild1: grandchildStruct{ - Ids: []int{1, 2, 3}, - On: true, - }, - }, - }, - }, "koanf"), nil) - - fmt.Printf("name is = `%s`\n", k.String("parent1.child1.name")) -} -``` - - -### Order of merge and key case senstivity - -- Config keys are case sensitive in koanf. For example, `app.server.port` and `APP.SERVER.port` are not the same. -- koanf does not impose any ordering on loading config from various providers. Every successive `Load()` or `Load()` merges new config into existing config. That means it is possible to load environment variables first, then files on top of it, and then command line variables on top of it, or any such order. - -### Custom Providers and Parsers - -A Provider can provide a nested map[string]interface{} config that can be loaded into koanf with `koanf.Load()` or raw bytes that can be parsed with a Parser (loaded using `koanf.Load()`. - -Writing Providers and Parsers are easy. See the bundled implementations in the `providers` and `parses` directory. - -## API - -### Bundled providers - -| Package | Provider | Description | -| ------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| providers/file | `file.Provider(filepath string)` | Reads a file and returns the raw bytes to be parsed. | -| providers/basicflag | `basicflag.Provider(f *flag.FlagSet, delim string)` | Takes an stdlib `flag.FlagSet` | -| providers/posflag | `posflag.Provider(f *pflag.FlagSet, delim string)` | Takes an `spft3/pflag.FlagSet` (advanced POSIX compatiable flags with multiple types) and provides a nested config map based on delim. | -| providers/env | `env.Provider(prefix, delim string, f func(s string) string)` | Takes an optional prefix to filter env variables by, an optional function that takes and returns a string to transform env variables, and returns a nested config map based on delim. | -| providers/confmap | `confmap.Provider(mp map[string]interface{}, delim string)` | Takes a premade `map[string]interface{}` conf map. If delim is provided, the keys are assumed to be flattened, thus unflattened using delim. | -| providers/structs | `structs.Provider(s interface{}, tag string)` | Takes a struct and struct tag. | -| providers/s3 | `s3.Provider(s3.S3Config{})` | Takes a s3 config struct. | -| providers/rawbytes | `rawbytes.Provider(b []byte)` | Takes a raw `[]byte` slice to be parsed with a koanf.Parser | - -### Bundled parsers - -| Package | Parser | Description | -| ------------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -| parsers/json | `json.Parser()` | Parses JSON bytes into a nested map | -| parsers/yaml | `yaml.Parser()` | Parses YAML bytes into a nested map | -| parsers/toml | `toml.Parser()` | Parses TOML bytes into a nested map | -| parsers/hcl | `hcl.Parser(flattenSlices bool)` | Parses Hashicorp HCL bytes into a nested map. `flattenSlices` is recommended to be set to true. [Read more](https://github.com/hashicorp/hcl/issues/162). | - -### Instance functions - -| Method | Description | -| ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| `Load(p Provider, pa Parser) error` | Loads config from a Provider. If a koanf.Parser is provided, the config is assumed to be raw bytes that's then parsed with the Parser. | -| `Keys() []string` | Returns the list of flattened key paths that can be used to access config values | -| `KeyMap() map[string][]string` | Returns a map of all possible key path combinations possible in the loaded nested conf map | -| `All() map[string]interface{}` | Returns a flat map of flattened key paths and their corresponding config values | -| `Raw() map[string]interface{}` | Returns a copy of the raw nested conf map | -| `Print()` | Prints a human readable copy of the flattened key paths and their values for debugging | -| `Sprint()` | Returns a human readable copy of the flattened key paths and their values for debugging | -| `Cut(path string) *Koanf` | Cuts the loaded nested conf map at the given path and returns a new Koanf instance with the children | -| `Copy() *Koanf` | Returns a copy of the Koanf instance | -| `Merge(*Koanf)` | Merges the config map of a Koanf instance into the current instance | -| `Unmarshal(path string, o interface{}) error` | Scans the given nested key path into a given struct (like json.Unmarshal) where fields are denoted by the `koanf` tag | -| `UnmarshalWithConf(path string, o interface{}, c UnmarshalConf) error` | Like Unmarshal but with customizable options | - -### Getter functions - -| | | -| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `Get(path string) interface{}` | Returns the value for the given key path, and if it doesn’t exist, returns nil | -| `Exists(path string) bool` | Returns true if the given key path exists in the conf map | -| `Int64(path string) int64` | | -| `Int64s(path string) []int64` | | -| `Int64Map(path string) map[string]int64` | | -| `Int(path string) int` | | -| `Ints(path string) []int` | | -| `IntMap(path string) map[string]int` | | -| `Float64(path string) float64` | | -| `Float64s(path string) []float64` | | -| `Float64Map(path string) map[string]float64` | | -| `Duration(path string) time.Duration` | Returns the time.Duration value of the given key path if it’s numeric (attempts a parse+convert if string) or a string representation like "3s". | -| `Time(path, layout string) time.Time` | Parses the string value of the the given key path with the given layout format and returns time.Time. If the key path is numeric, treats it as a UNIX timestamp and returns its time.Time. | -| `String(path string) string` | | -| `Strings(path string) []string` | | -| `StringMap(path string) map[string]string` | | -| `StringsMap(path string) map[string][]string` | | -| `Byte(path string) []byte` | | -| `Bool(path string) bool` | | -| `Bools(path string) []bool` | | -| `BoolMap(path string) map[string]bool` | | -| `MapKeys(path string) []string` | Returns the list of keys in any map | - -### Alternative to viper - -koanf is a light weight alternative to the popular [spf13/viper](https://github.com/spf13/viper). It does not aim to do everything viper does (such as mutating config maps and writing them back to files), but provides simpler primitives for reading and accessing configuration. It was written as a result of multiple stumbling blocks encountered with some of viper's fundamental flaws. - -- viper breaks JSON, YAML, TOML, HCL language specs by [forcibly lowercasing keys](https://github.com/spf13/viper/pull/635). -- Tightly couples config parsing with file extensions. -- Has poor semantics and abstractions. Commandline, env, file etc. and various parses are hardcoded in the core. There are no primitives that can be extended. -- Pulls a large number of [third party dependencies](https://github.com/spf13/viper/issues/707) into the core package. For instance, even if you do not use YAML or flags, the dependencies are still pulled as a result of the coupling. -- Imposes arbitrary ordering conventions (eg: flag -> env -> config etc.) -- `Get()` returns references to slices and maps. Mutations made outside change the underlying values inside the conf map. -- Does non-idiomatic things such as [throwing away O(1) on flat maps](https://github.com/spf13/viper/blob/3b4aca75714a37276c4b1883630bd98c02498b73/viper.go#L1524). -- There are a large number of [open issues](https://github.com/spf13/viper/issues). diff --git a/vendor/github.com/knadh/koanf/getters.go b/vendor/github.com/knadh/koanf/getters.go deleted file mode 100644 index ff4ffed..0000000 --- a/vendor/github.com/knadh/koanf/getters.go +++ /dev/null @@ -1,588 +0,0 @@ -package koanf - -import ( - "fmt" - "time" -) - -// Int64 returns the int64 value of a given key path or 0 if the path -// does not exist or if the value is not a valid int64. -func (ko *Koanf) Int64(path string) int64 { - if v := ko.Get(path); v != nil { - i, _ := toInt64(v) - return i - } - return 0 -} - -// MustInt64 returns the int64 value of a given key path or panics -// if the value is not set or set to default value of 0. -func (ko *Koanf) MustInt64(path string) int64 { - val := ko.Int64(path) - if val == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Int64s returns the []int64 slice value of a given key path or an -// empty []int64 slice if the path does not exist or if the value -// is not a valid int slice. -func (ko *Koanf) Int64s(path string) []int64 { - o := ko.Get(path) - if o == nil { - return []int64{} - } - - var out []int64 - switch v := o.(type) { - case []interface{}: - out = make([]int64, 0, len(v)) - for _, vi := range v { - i, err := toInt64(vi) - - // On error, return as it's not a valid - // int slice. - if err != nil { - return []int64{} - } - out = append(out, i) - } - return out - } - - return []int64{} -} - -// MustInt64s returns the []int64 slice value of a given key path or panics -// if the value is not set or its default value. -func (ko *Koanf) MustInt64s(path string) []int64 { - val := ko.Int64s(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Int64Map returns the map[string]int64 value of a given key path -// or an empty map[string]int64 if the path does not exist or if the -// value is not a valid int64 map. -func (ko *Koanf) Int64Map(path string) map[string]int64 { - var ( - out = map[string]int64{} - o = ko.Get(path) - ) - if o == nil { - return out - } - - mp, ok := o.(map[string]interface{}) - if !ok { - return out - } - - out = make(map[string]int64, len(mp)) - for k, v := range mp { - switch i := v.(type) { - case int64: - out[k] = i - default: - // Attempt a conversion. - iv, err := toInt64(i) - if err != nil { - return map[string]int64{} - } - out[k] = iv - } - } - return out -} - -// MustInt64Map returns the map[string]int64 value of a given key path -// or panics if its not set or set to default value. -func (ko *Koanf) MustInt64Map(path string) map[string]int64 { - val := ko.Int64Map(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Int returns the int value of a given key path or 0 if the path -// does not exist or if the value is not a valid int. -func (ko *Koanf) Int(path string) int { - return int(ko.Int64(path)) -} - -// MustInt returns the int value of a given key path or panics -// or panics if its not set or set to default value of 0. -func (ko *Koanf) MustInt(path string) int { - val := ko.Int(path) - if val == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Ints returns the []int slice value of a given key path or an -// empty []int slice if the path does not exist or if the value -// is not a valid int slice. -func (ko *Koanf) Ints(path string) []int { - ints := ko.Int64s(path) - if len(ints) == 0 { - return []int{} - } - - out := make([]int, len(ints)) - for i, v := range ints { - out[i] = int(v) - } - return out -} - -// MustInts returns the []int slice value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustInts(path string) []int { - val := ko.Ints(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// IntMap returns the map[string]int value of a given key path -// or an empty map[string]int if the path does not exist or if the -// value is not a valid int map. -func (ko *Koanf) IntMap(path string) map[string]int { - var ( - mp = ko.Int64Map(path) - out = make(map[string]int, len(mp)) - ) - for k, v := range mp { - out[k] = int(v) - } - return out -} - -// MustIntMap returns the map[string]int value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustIntMap(path string) map[string]int { - val := ko.IntMap(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Float64 returns the float64 value of a given key path or 0 if the path -// does not exist or if the value is not a valid float64. -func (ko *Koanf) Float64(path string) float64 { - if v := ko.Get(path); v != nil { - f, _ := toFloat64(v) - return f - } - return 0 -} - -// MustFloat64 returns the float64 value of a given key path or panics -// or panics if its not set or set to default value 0. -func (ko *Koanf) MustFloat64(path string) float64 { - val := ko.Float64(path) - if val == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Float64s returns the []float64 slice value of a given key path or an -// empty []float64 slice if the path does not exist or if the value -// is not a valid float64 slice. -func (ko *Koanf) Float64s(path string) []float64 { - o := ko.Get(path) - if o == nil { - return []float64{} - } - - var out []float64 - switch v := o.(type) { - case []interface{}: - out = make([]float64, 0, len(v)) - for _, vi := range v { - i, err := toFloat64(vi) - - // On error, return as it's not a valid - // int slice. - if err != nil { - return []float64{} - } - out = append(out, float64(i)) - } - return out - } - - return []float64{} -} - -// MustFloat64s returns the []Float64 slice value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustFloat64s(path string) []float64 { - val := ko.Float64s(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Float64Map returns the map[string]float64 value of a given key path -// or an empty map[string]float64 if the path does not exist or if the -// value is not a valid float64 map. -func (ko *Koanf) Float64Map(path string) map[string]float64 { - var ( - out = map[string]float64{} - o = ko.Get(path) - ) - if o == nil { - return out - } - - mp, ok := o.(map[string]interface{}) - if !ok { - return out - } - - out = make(map[string]float64, len(mp)) - for k, v := range mp { - switch i := v.(type) { - case float64: - out[k] = i - default: - // Attempt a conversion. - iv, err := toFloat64(i) - if err != nil { - return map[string]float64{} - } - out[k] = iv - } - } - return out -} - -// MustFloat64Map returns the map[string]float64 value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustFloat64Map(path string) map[string]float64 { - val := ko.Float64Map(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Duration returns the time.Duration value of a given key path assuming -// that the key contains a valid numeric value. -func (ko *Koanf) Duration(path string) time.Duration { - // Look for a parsable string representation first. - if v := ko.Int64(path); v > 0 { - return time.Duration(v) - } - - v, _ := time.ParseDuration(ko.String(path)) - return v -} - -// MustDuration returns the time.Duration value of a given key path or panics -// if its not set or set to default value 0. -func (ko *Koanf) MustDuration(path string) time.Duration { - val := ko.Duration(path) - if val == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Time attempts to parse the value of a given key path and return time.Time -// representation. If the value is numeric, it is treated as a UNIX timestamp -// and if it's string, a parse is attempted with the given layout. -func (ko *Koanf) Time(path, layout string) time.Time { - // Unix timestamp? - v := ko.Int64(path) - if v != 0 { - return time.Unix(v, 0) - } - - // String representation. - s := ko.String(path) - if s != "" { - t, _ := time.Parse(layout, s) - return t - } - - return time.Time{} -} - -// MustTime attempts to parse the value of a given key path and return time.Time -// representation. If the value is numeric, it is treated as a UNIX timestamp -// and if it's string, a parse is attempted with the given layout. It panics if -// the parsed time is zero. -func (ko *Koanf) MustTime(path, layout string) time.Time { - val := ko.Time(path, layout) - if val.IsZero() { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// String returns the string value of a given key path or "" if the path -// does not exist or if the value is not a valid string. -func (ko *Koanf) String(path string) string { - if v := ko.Get(path); v != nil { - if i, ok := v.(string); ok { - return i - } - return fmt.Sprintf("%v", v) - } - return "" -} - -// MustString returns the string value of a given key path -// or panics if its not set or set to default value "". -func (ko *Koanf) MustString(path string) string { - val := ko.String(path) - if val == "" { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Strings returns the []string slice value of a given key path or an -// empty []string slice if the path does not exist or if the value -// is not a valid string slice. -func (ko *Koanf) Strings(path string) []string { - o := ko.Get(path) - if o == nil { - return []string{} - } - - var out []string - switch v := o.(type) { - case []interface{}: - out = make([]string, 0, len(v)) - for _, u := range v { - if s, ok := u.(string); ok { - out = append(out, s) - } else { - out = append(out, fmt.Sprintf("%v", u)) - } - } - return out - case []string: - out := make([]string, len(v)) - copy(out[:], v[:]) - return out - } - return []string{} -} - -// MustStrings returns the []string slice value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustStrings(path string) []string { - val := ko.Strings(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// StringMap returns the map[string]string value of a given key path -// or an empty map[string]string if the path does not exist or if the -// value is not a valid string map. -func (ko *Koanf) StringMap(path string) map[string]string { - var ( - out = map[string]string{} - o = ko.Get(path) - ) - if o == nil { - return out - } - - mp, ok := o.(map[string]interface{}) - if !ok { - return out - } - out = make(map[string]string, len(mp)) - for k, v := range mp { - switch s := v.(type) { - case string: - out[k] = s - default: - // There's a non string type. Return. - return map[string]string{} - } - } - - return out -} - -// MustStringMap returns the map[string]string value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustStringMap(path string) map[string]string { - val := ko.StringMap(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// StringsMap returns the map[string][]string value of a given key path -// or an empty map[string][]string if the path does not exist or if the -// value is not a valid strings map. -func (ko *Koanf) StringsMap(path string) map[string][]string { - var ( - out = map[string][]string{} - o = ko.Get(path) - ) - if o == nil { - return out - } - - mp, ok := o.(map[string]interface{}) - if !ok { - return out - } - out = make(map[string][]string, len(mp)) - for k, v := range mp { - switch s := v.(type) { - case []interface{}: - for _, v := range s { - switch sv := v.(type) { - case string: - out[k] = append(out[k], sv) - default: - return map[string][]string{} - } - } - default: - // There's a non []interface type. Return. - return map[string][]string{} - } - } - - return out -} - -// MustStringsMap returns the map[string][]string value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustStringsMap(path string) map[string][]string { - val := ko.StringsMap(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Bytes returns the []byte value of a given key path or an empty -// []byte slice if the path does not exist or if the value is not a valid string. -func (ko *Koanf) Bytes(path string) []byte { - return []byte(ko.String(path)) -} - -// MustBytes returns the []byte value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustBytes(path string) []byte { - val := ko.Bytes(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// Bool returns the bool value of a given key path or false if the path -// does not exist or if the value is not a valid bool representation. -// Accepted string representations of bool are the ones supported by strconv.ParseBool. -func (ko *Koanf) Bool(path string) bool { - if v := ko.Get(path); v != nil { - b, _ := toBool(v) - return b - } - return false -} - -// Bools returns the []bool slice value of a given key path or an -// empty []bool slice if the path does not exist or if the value -// is not a valid bool slice. -func (ko *Koanf) Bools(path string) []bool { - o := ko.Get(path) - if o == nil { - return []bool{} - } - - var out []bool - switch v := o.(type) { - case []interface{}: - out = make([]bool, 0, len(v)) - for _, u := range v { - b, err := toBool(u) - if err != nil { - return nil - } - out = append(out, b) - } - return out - case []bool: - return out - } - return nil -} - -// MustBools returns the []bool value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustBools(path string) []bool { - val := ko.Bools(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} - -// BoolMap returns the map[string]bool value of a given key path -// or an empty map[string]bool if the path does not exist or if the -// value is not a valid bool map. -func (ko *Koanf) BoolMap(path string) map[string]bool { - var ( - out = map[string]bool{} - o = ko.Get(path) - ) - if o == nil { - return out - } - - mp, ok := o.(map[string]interface{}) - if !ok { - return out - } - out = make(map[string]bool, len(mp)) - for k, v := range mp { - switch i := v.(type) { - case bool: - out[k] = i - default: - // Attempt a conversion. - b, err := toBool(i) - if err != nil { - return map[string]bool{} - } - out[k] = b - } - } - - return out -} - -// MustBoolMap returns the map[string]bool value of a given key path or panics -// if the value is not set or set to default value. -func (ko *Koanf) MustBoolMap(path string) map[string]bool { - val := ko.BoolMap(path) - if len(val) == 0 { - panic(fmt.Sprintf("invalid value: %s=%v", path, val)) - } - return val -} diff --git a/vendor/github.com/knadh/koanf/go.mod b/vendor/github.com/knadh/koanf/go.mod deleted file mode 100644 index d1e1534..0000000 --- a/vendor/github.com/knadh/koanf/go.mod +++ /dev/null @@ -1,16 +0,0 @@ -module github.com/knadh/koanf - -go 1.12 - -require ( - github.com/fatih/structs v1.1.0 - github.com/fsnotify/fsnotify v1.4.9 - github.com/hashicorp/hcl v1.0.0 - github.com/mitchellh/mapstructure v1.2.2 - github.com/pelletier/go-toml v1.7.0 - github.com/rhnvrm/simples3 v0.5.0 - github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.3.0 - golang.org/x/sys v0.0.0-20200331124033-c3d80250170d // indirect - gopkg.in/yaml.v2 v2.2.8 -) diff --git a/vendor/github.com/knadh/koanf/go.sum b/vendor/github.com/knadh/koanf/go.sum deleted file mode 100644 index 756112a..0000000 --- a/vendor/github.com/knadh/koanf/go.sum +++ /dev/null @@ -1,32 +0,0 @@ -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4= -github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rhnvrm/simples3 v0.5.0 h1:X+WX0hqoKScdoJAw/G3GArfZ6Ygsn8q+6MdocTMKXOw= -github.com/rhnvrm/simples3 v0.5.0/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/knadh/koanf/interfaces.go b/vendor/github.com/knadh/koanf/interfaces.go deleted file mode 100644 index d6a8069..0000000 --- a/vendor/github.com/knadh/koanf/interfaces.go +++ /dev/null @@ -1,25 +0,0 @@ -package koanf - -// Provider represents a configuration provider. Providers can -// read configuration from a source (file, HTTP etc.) -type Provider interface { - // Read returns the entire configuration as raw []bytes to be parsed. - // with a Parser. - ReadBytes() ([]byte, error) - - // Read returns the prased configuration as a nested map[string]interface{}. - // It is important to note that the string keys should not be flat delimited - // keys like `parent.child.key`, but nested like `{parent: {child: {key: 1}}}`. - Read() (map[string]interface{}, error) - - // Watch watches the source for changes, for instance, changes to a file, - // and invokes a callback with an `event` interface, which a provider - // is free to substitute with its own type, including nil. - Watch(func(event interface{}, err error)) error -} - -// Parser represents a configuration format parser. -type Parser interface { - Unmarshal([]byte) (map[string]interface{}, error) - Marshal(map[string]interface{}) ([]byte, error) -} diff --git a/vendor/github.com/knadh/koanf/koanf.go b/vendor/github.com/knadh/koanf/koanf.go deleted file mode 100644 index 623aa81..0000000 --- a/vendor/github.com/knadh/koanf/koanf.go +++ /dev/null @@ -1,382 +0,0 @@ -package koanf - -import ( - "bytes" - "encoding/json" - "fmt" - "sort" - "strconv" - "strings" - - "github.com/knadh/koanf/maps" - "github.com/mitchellh/mapstructure" -) - -// Koanf is the configuration apparatus. -type Koanf struct { - confMap map[string]interface{} - confMapFlat map[string]interface{} - keyMap KeyMap - delim string -} - -// KeyMap represents a map of flattened delimited keys and the non-delimited -// parts as their slices. For nested keys, the map holds all levels of path combinations. -// For example, the nested structure `parent -> child -> key` will produce the map: -// parent.child.key => [parent, child, key] -// parent.child => [parent, child] -// parent => [parent] -type KeyMap map[string][]string - -// UnmarshalConf represents configuration options used by -// Unmarshal() to unmarshal conf maps into arbitrary structs. -type UnmarshalConf struct { - // Tag is the struct field tag to unmarshal. - // `koanf` is used if left empty. - Tag string - - // If this is set to true, instead of unmarshalling nested structures - // based on the key path, keys are taken literally to unmarshal into - // a flat struct. For example: - // ``` - // type MyStuff struct { - // Child1Name string `koanf:"parent1.child1.name"` - // Child2Name string `koanf:"parent2.child2.name"` - // Type string `koanf:"json"` - // } - // ``` - FlatPaths bool - DecoderConfig *mapstructure.DecoderConfig -} - -// New returns a new instance of Koanf. delim is the delimiter to use -// when specifying config key paths, for instance a . for `parent.child.key` -// or a / for `parent/child/key`. -func New(delim string) *Koanf { - return &Koanf{ - delim: delim, - confMap: make(map[string]interface{}), - confMapFlat: make(map[string]interface{}), - keyMap: make(KeyMap), - } -} - -// Load takes a Provider that either provides a parsed config map[string]interface{} -// in which case pa (Parser) can be nil, or raw bytes to be parsed, where a Parser -// can be provided to parse. -func (ko *Koanf) Load(p Provider, pa Parser) error { - var ( - mp map[string]interface{} - err error - ) - - // No Parser is given. Call the Provider's Read() methid to get - // the config map. - if pa == nil { - mp, err = p.Read() - if err != nil { - return err - } - } else { - // There's a Parser. Get raw bytes from the Provider to parse. - b, err := p.ReadBytes() - if err != nil { - return err - } - mp, err = pa.Unmarshal(b) - if err != nil { - return err - } - } - - ko.merge(mp) - return nil -} - -// Keys returns the slice of all flattened keys in the loaded configuration -// sorted alphabetically. -func (ko *Koanf) Keys() []string { - out := make([]string, 0, len(ko.confMapFlat)) - for k := range ko.confMapFlat { - out = append(out, k) - } - sort.Strings(out) - return out -} - -// KeyMap returns a map of flattened keys and the individual parts of the -// key as slices. eg: "parent.child.key" => ["parent", "child", "key"] -func (ko *Koanf) KeyMap() KeyMap { - out := make(KeyMap, len(ko.keyMap)) - for key, parts := range ko.keyMap { - out[key] = make([]string, len(parts)) - copy(out[key][:], parts[:]) - } - return out -} - -// All returns a map of all flattened key paths and their values. -// Note that it uses maps.Copy to create a copy that uses -// json.Marshal which changes the numeric types to float64. -func (ko *Koanf) All() map[string]interface{} { - return maps.Copy(ko.confMapFlat) -} - -// Raw returns a copy of the full raw conf map. -// Note that it uses maps.Copy to create a copy that uses -// json.Marshal which changes the numeric types to float64. -func (ko *Koanf) Raw() map[string]interface{} { - return maps.Copy(ko.confMap) -} - -// Sprint returns a key -> value string representation -// of the config map with keys sorted alphabetically. -func (ko *Koanf) Sprint() string { - b := bytes.Buffer{} - for _, k := range ko.Keys() { - b.Write([]byte(fmt.Sprintf("%s -> %v\n", k, ko.confMapFlat[k]))) - } - return b.String() -} - -// Print prints a key -> value string representation -// of the config map with keys sorted alphabetically. -func (ko *Koanf) Print() { - fmt.Print(ko.Sprint()) -} - -// Cut cuts the config map at a given key path into a sub map and -// returns a new Koanf instance with the cut config map loaded. -// For instance, if the loaded config has a path that looks like -// parent.child.sub.a.b, `Cut("parent.child")` returns a new Koanf -// instance with the config map `sub.a.b` where everything above -// `parent.child` are cut out. -func (ko *Koanf) Cut(path string) *Koanf { - out := make(map[string]interface{}) - - // Cut only makes sense if the requested key path is a map. - if v, ok := ko.Get(path).(map[string]interface{}); ok { - out = v - } - - n := New(ko.delim) - n.merge(out) - return n -} - -// Copy returns a copy of the Koanf instance. -func (ko *Koanf) Copy() *Koanf { - return ko.Cut("") -} - -// Merge merges the config map of a given Koanf instance into -// the current instance. -func (ko *Koanf) Merge(in *Koanf) { - ko.merge(in.Raw()) -} - -// Marshal takes a Parser implementation and marshals the config map into bytes, -// for example, to TOML or JSON bytes. -func (ko *Koanf) Marshal(p Parser) ([]byte, error) { - return p.Marshal(ko.All()) -} - -// Unmarshal unmarshals a given key path into the given struct using -// the mapstructure lib. If no path is specified, the whole map is unmarshalled. -// `koanf` is the struct field tag used to match field names. To customize, -// use UnmarshalWithConf(). It uses the mitchellh/mapstructure package. -func (ko *Koanf) Unmarshal(path string, o interface{}) error { - return ko.UnmarshalWithConf(path, o, UnmarshalConf{}) -} - -// UnmarshalWithConf is like Unmarshal but takes configuration params in UnmarshalConf. -// See mitchellh/mapstructure's DecoderConfig for advanced customization -// of the unmarshal behaviour. -func (ko *Koanf) UnmarshalWithConf(path string, o interface{}, c UnmarshalConf) error { - if c.DecoderConfig == nil { - c.DecoderConfig = &mapstructure.DecoderConfig{ - DecodeHook: mapstructure.ComposeDecodeHookFunc( - mapstructure.StringToTimeDurationHookFunc()), - Metadata: nil, - Result: o, - WeaklyTypedInput: true, - } - } - - if c.Tag == "" { - c.DecoderConfig.TagName = "koanf" - } else { - c.DecoderConfig.TagName = c.Tag - } - - d, err := mapstructure.NewDecoder(c.DecoderConfig) - if err != nil { - return err - } - - // Unmarshal using flat key paths. - mp := ko.Get(path) - if c.FlatPaths { - if f, ok := mp.(map[string]interface{}); ok { - fmp, _ := maps.Flatten(f, nil, ko.delim) - mp = fmp - } - } - - return d.Decode(mp) -} - -// Get returns the raw, uncast interface{} value of a given key path -// in the config map. If the key path does not exist, nil is returned. -func (ko *Koanf) Get(path string) interface{} { - // No path. Return the whole conf map. - if path == "" { - return ko.Raw() - } - - // Does the path exist? - p, ok := ko.keyMap[path] - if !ok { - return nil - } - res := maps.Search(ko.confMap, p) - - // Non-reference types are okay to return directly. - // Other types are "copied" with maps.Copy or json.Marshal - // that change the numeric types to float64. - - switch v := res.(type) { - case int, int8, int16, int32, int64, float32, float64, string, bool: - return v - case map[string]interface{}: - return maps.Copy(v) - } - - // Inefficient, but marshal and unmarshal to create a copy - // of reference types to not expose internal references to slices and maps. - var out interface{} - b, _ := json.Marshal(res) - json.Unmarshal(b, &out) - return out -} - -// Exists returns true if the given key path exists in the conf map. -func (ko *Koanf) Exists(path string) bool { - _, ok := ko.keyMap[path] - return ok -} - -// MapKeys returns a sorted string list of keys in a map addressed by the -// given path. If the path is not a map, an empty string slice is -// returned. -func (ko *Koanf) MapKeys(path string) []string { - var ( - out = []string{} - o = ko.Get(path) - ) - if o == nil { - return out - } - - mp, ok := o.(map[string]interface{}) - if !ok { - return out - } - out = make([]string, 0, len(mp)) - for k := range mp { - out = append(out, k) - } - sort.Strings(out) - return out -} - -func (ko *Koanf) merge(c map[string]interface{}) { - maps.IntfaceKeysToStrings(c) - maps.Merge(c, ko.confMap) - - // Maintain a flattened version as well. - ko.confMapFlat, ko.keyMap = maps.Flatten(ko.confMap, nil, ko.delim) - ko.keyMap = populateKeyParts(ko.keyMap, ko.delim) -} - -// toInt64 takes an interface value and if it is an integer type, -// converts and returns int64. If it's any other type, -// forces it to a string and attempts to an strconv.Atoi -// to get an integer out. -func toInt64(v interface{}) (int64, error) { - switch i := v.(type) { - case int: - return int64(i), nil - case int8: - return int64(i), nil - case int16: - return int64(i), nil - case int32: - return int64(i), nil - case int64: - return i, nil - } - - // Force it to a string and try to convert. - f, err := strconv.ParseFloat(fmt.Sprintf("%v", v), 64) - if err != nil { - return 0, err - } - - return int64(f), nil -} - -// toInt64 takes an interface v interface{}value and if it is a float type, -// converts and returns float6v interface{}4. If it's any other type, -// forces it to a string and av interface{}ttempts to an strconv.ParseFloat -// to get a float out. -func toFloat64(v interface{}) (float64, error) { - switch i := v.(type) { - case float32: - return float64(i), nil - case float64: - return i, nil - } - - // Force it to a string and try to convert. - f, err := strconv.ParseFloat(fmt.Sprintf("%v", v), 64) - if err != nil { - return f, err - } - - return f, nil -} - -// toBool takes an interface value and if it is a bool type, -// returns it. If it's any other type, forces it to a string and attempts -// to parse it as a bool using strconv.ParseBool. -func toBool(v interface{}) (bool, error) { - if b, ok := v.(bool); ok { - return b, nil - } - - // Force it to a string and try to convert. - b, err := strconv.ParseBool(fmt.Sprintf("%v", v)) - if err != nil { - return b, err - } - return b, nil -} - -// populateKeyParts iterates a key map and generates all possible -// traveral paths. For instance, `parent.child.key` generates -// `parent`, and `parent.child`. -func populateKeyParts(m KeyMap, delim string) KeyMap { - out := make(KeyMap) - for _, parts := range m { - for i := range parts { - nk := strings.Join(parts[0:i+1], delim) - if _, ok := out[nk]; ok { - continue - } - out[nk] = make([]string, i+1) - copy(out[nk][:], parts[0:i+1]) - } - } - return out -} diff --git a/vendor/github.com/knadh/koanf/maps/maps.go b/vendor/github.com/knadh/koanf/maps/maps.go deleted file mode 100644 index fa76f14..0000000 --- a/vendor/github.com/knadh/koanf/maps/maps.go +++ /dev/null @@ -1,224 +0,0 @@ -// Package maps provides reusable functions for manipulating nested -// map[string]interface{} maps are common unmarshal products from -// various serializers such as json, yaml etc. -package maps - -import ( - "encoding/json" - "fmt" - "strings" -) - -// Flatten takes a map[string]interface{} and traverses it and flattens -// nested children into keys delimited by delim. -// -// It's important to note that all nested maps should be -// map[string]interface{} and not map[interface{}]interface{}. -// Use IntfaceKeysToStrings() to convert if necessary. -// -// eg: `{ "parent": { "child": 123 }}` becomes `{ "parent.child": 123 }` -// In addition, it keeps track of and returns a map of the delimited keypaths with -// a slice of key parts, for eg: { "parent.child": ["parent", "child"] }. This -// parts list is used to remember the key path's original structure to -// unflatten later. -func Flatten(m map[string]interface{}, keys []string, delim string) (map[string]interface{}, map[string][]string) { - var ( - out = make(map[string]interface{}) - keyMap = make(map[string][]string) - ) - for key, val := range m { - // Copy the incoming key paths into a fresh list - // and append the current key in the iteration. - kp := make([]string, 0, len(keys)+1) - kp = append(kp, keys...) - kp = append(kp, key) - - switch cur := val.(type) { - case map[string]interface{}: - // Empty map. - if len(cur) == 0 { - newKey := strings.Join(kp, delim) - out[newKey] = val - keyMap[newKey] = kp - continue - } - - // It's a nested map. Flatten it recursively. - next, parts := Flatten(cur, kp, delim) - - // Copy the resultant key parts and the value maps. - for k, p := range parts { - keyMap[k] = p - } - for k, v := range next { - out[k] = v - } - default: - newKey := strings.Join(kp, delim) - out[newKey] = val - keyMap[newKey] = kp - } - } - return out, keyMap -} - -// Unflatten takes a flattened key:value map (non-nested with delimited keys) -// and returns a nested map where the keys are split into hierarchies by the given -// delimiter. For instance, `parent.child.key: 1` to `{parent: {child: {key: 1}}}` -// -// It's important to note that all nested maps should be -// map[string]interface{} and not map[interface{}]interface{}. -// Use IntfaceKeysToStrings() to convert if necessary. -func Unflatten(m map[string]interface{}, delim string) map[string]interface{} { - out := make(map[string]interface{}) - - // Iterate through the flat conf map. - for k, v := range m { - var ( - keys = strings.Split(k, delim) - next = out - ) - - // Iterate through key parts, for eg:, parent.child.key - // will be ["parent", "child", "key"] - for _, k := range keys[:len(keys)-1] { - sub, ok := next[k] - if !ok { - // If the key does not exist in the map, create it. - sub = make(map[string]interface{}) - next[k] = sub - } - if n, ok := sub.(map[string]interface{}); ok { - next = n - } - } - - // Assign the value. - next[keys[len(keys)-1]] = v - } - return out -} - -// Merge recursively merges map a into b (left to right), mutating -// and expanding map b. Note that there's no copying involved, so -// map b will retain references to map a. -// -// It's important to note that all nested maps should be -// map[string]interface{} and not map[interface{}]interface{}. -// Use IntfaceKeysToStrings() to convert if necessary. -func Merge(a, b map[string]interface{}) { - for key, val := range a { - // Does the key exist in the target map? - // If no, add it and move on. - bVal, ok := b[key] - if !ok { - b[key] = val - continue - } - - // If the incoming val is not a map, do a direct merge. - if _, ok := val.(map[string]interface{}); !ok { - b[key] = val - continue - } - - // The source key and target keys are both maps. Merge them. - switch v := bVal.(type) { - case map[string]interface{}: - Merge(val.(map[string]interface{}), v) - default: - b[key] = val - } - } -} - -// Search recursively searches a map for a given path. The path is -// the key map slice, for eg:, parent.child.key -> [parent child key]. -// -// It's important to note that all nested maps should be -// map[string]interface{} and not map[interface{}]interface{}. -// Use IntfaceKeysToStrings() to convert if necessary. -func Search(mp map[string]interface{}, path []string) interface{} { - next, ok := mp[path[0]] - if ok { - if len(path) == 1 { - return next - } - switch next.(type) { - case map[string]interface{}: - return Search(next.(map[string]interface{}), path[1:]) - default: - return nil - } // - // It's important to note that all nested maps should be - // map[string]interface{} and not map[interface{}]interface{}. - // Use IntfaceKeysToStrings() to convert if necessary. - } - return nil -} - -// Copy returns a copy of a conf map by doing a JSON marshal+unmarshal -// pass. Inefficient, but creates a true deep copy. There is a side -// effect, that is, all numeric types change to float64. -// -// It's important to note that all nested maps should be -// map[string]interface{} and not map[interface{}]interface{}. -// Use IntfaceKeysToStrings() to convert if necessary. -func Copy(mp map[string]interface{}) map[string]interface{} { - var out map[string]interface{} - b, _ := json.Marshal(mp) - json.Unmarshal(b, &out) - return out -} - -// IntfaceKeysToStrings recursively converts map[interface{}]interface{} to -// map[string]interface{}. Some parses such as YAML unmarshal return this. -func IntfaceKeysToStrings(mp map[string]interface{}) { - for key, val := range mp { - switch cur := val.(type) { - case map[interface{}]interface{}: - x := make(map[string]interface{}) - for k, v := range cur { - x[fmt.Sprintf("%v", k)] = v - } - mp[key] = x - IntfaceKeysToStrings(x) - case []interface{}: - for i, v := range cur { - switch sub := v.(type) { - case map[interface{}]interface{}: - x := make(map[string]interface{}) - for k, v := range sub { - x[fmt.Sprintf("%v", k)] = v - } - cur[i] = x - IntfaceKeysToStrings(x) - case map[string]interface{}: - IntfaceKeysToStrings(sub) - } - } - case map[string]interface{}: - IntfaceKeysToStrings(cur) - } - } -} - -// StringSliceToLookupMap takes a slice of strings and returns a lookup map -// with the slice values as keys with true values. -func StringSliceToLookupMap(s []string) map[string]bool { - mp := make(map[string]bool, len(s)) - for _, v := range s { - mp[v] = true - } - return mp -} - -// Int64SliceToLookupMap takes a slice of int64s and returns a lookup map -// with the slice values as keys with true values. -func Int64SliceToLookupMap(s []int64) map[int64]bool { - mp := make(map[int64]bool, len(s)) - for _, v := range s { - mp[v] = true - } - return mp -} diff --git a/vendor/github.com/knadh/koanf/providers/confmap/confmap.go b/vendor/github.com/knadh/koanf/providers/confmap/confmap.go deleted file mode 100644 index a151a70..0000000 --- a/vendor/github.com/knadh/koanf/providers/confmap/confmap.go +++ /dev/null @@ -1,42 +0,0 @@ -// Package confmap implements a koanf.Provider that takes nested -// and flat map[string]interface{} config maps and provides them -// to koanf. -package confmap - -import ( - "errors" - - "github.com/knadh/koanf/maps" -) - -// Confmap implements a raw map[string]interface{} provider. -type Confmap struct { - mp map[string]interface{} -} - -// Provider returns a confmap Provider that takes a flat or nested -// map[string]interface{}. If a delim is provided, it indicates that the -// keys are flat and the map needs to be unflatted by delim. -func Provider(mp map[string]interface{}, delim string) *Confmap { - cp := maps.Copy(mp) - maps.IntfaceKeysToStrings(cp) - if delim != "" { - cp = maps.Unflatten(cp, delim) - } - return &Confmap{mp: cp} -} - -// ReadBytes is not supported by the env provider. -func (e *Confmap) ReadBytes() ([]byte, error) { - return nil, errors.New("confmap provider does not support this method") -} - -// Read returns the loaded map[string]interface{}. -func (e *Confmap) Read() (map[string]interface{}, error) { - return e.mp, nil -} - -// Watch is not supported. -func (e *Confmap) Watch(cb func(event interface{}, err error)) error { - return errors.New("confmap provider does not support this method") -} diff --git a/vendor/github.com/knadh/koanf/providers/env/env.go b/vendor/github.com/knadh/koanf/providers/env/env.go deleted file mode 100644 index f26f9bb..0000000 --- a/vendor/github.com/knadh/koanf/providers/env/env.go +++ /dev/null @@ -1,77 +0,0 @@ -// Package env implements a koanf.Provider that reads environment -// variables as conf maps. -package env - -import ( - "errors" - "os" - "strings" - - "github.com/knadh/koanf/maps" -) - -// Env implements an environment variables provider. -type Env struct { - prefix string - delim string - cb func(s string) string -} - -// Provider returns an environment variables provider that returns -// a nested map[string]interface{} of environment variable where the -// nesting hierarchy of keys are defined by delim. For instance, the -// delim "." will convert the key `parent.child.key: 1` -// to `{parent: {child: {key: 1}}}`. -// -// If prefix is specified (case sensitive), only the env vars with -// the prefix are captured. cb is an optional callback that takes -// a string and returns a string (the env variable name) in case -// transformatios have to be applied, for instance, to lowercase -// everything, strip prefixes and replace _ with . etc. -func Provider(prefix, delim string, cb func(s string) string) *Env { - return &Env{ - prefix: prefix, - delim: delim, - cb: cb, - } -} - -// ReadBytes is not supported by the env provider. -func (e *Env) ReadBytes() ([]byte, error) { - return nil, errors.New("env provider does not support this method") -} - -// Read reads all available environment variables into a key:value map -// and returns it. -func (e *Env) Read() (map[string]interface{}, error) { - // Collect the environment variable keys. - var keys []string - for _, k := range os.Environ() { - if e.prefix != "" { - if strings.HasPrefix(k, e.prefix) { - keys = append(keys, k) - } - } else { - keys = append(keys, k) - } - } - - mp := make(map[string]interface{}) - for _, k := range keys { - parts := strings.SplitN(k, "=", 2) - - // If there's a string transformation callback, - // run it through every string. - if e.cb != nil { - parts[0] = e.cb(parts[0]) - } - mp[parts[0]] = parts[1] - } - - return maps.Unflatten(mp, e.delim), nil -} - -// Watch is not supported. -func (e *Env) Watch(cb func(event interface{}, err error)) error { - return errors.New("env provider does not support this method") -} diff --git a/vendor/github.com/mitchellh/mapstructure/.travis.yml b/vendor/github.com/mitchellh/mapstructure/.travis.yml deleted file mode 100644 index b122a8e..0000000 --- a/vendor/github.com/mitchellh/mapstructure/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - "1.11.x" - - tip - -script: - - go test - - go test -bench . -benchmem diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md deleted file mode 100644 index 0a21e2c..0000000 --- a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md +++ /dev/null @@ -1,40 +0,0 @@ -## 1.2.2 - -* Do not add unsettable (unexported) values to the unused metadata key - or "remain" value. [GH-150] - -## 1.2.1 - -* Go modules checksum mismatch fix - -## 1.2.0 - -* Added support to capture unused values in a field using the `",remain"` value - in the mapstructure tag. There is an example to showcase usage. -* Added `DecoderConfig` option to always squash embedded structs -* `json.Number` can decode into `uint` types -* Empty slices are preserved and not replaced with nil slices -* Fix panic that can occur in when decoding a map into a nil slice of structs -* Improved package documentation for godoc - -## 1.1.2 - -* Fix error when decode hook decodes interface implementation into interface - type. [GH-140] - -## 1.1.1 - -* Fix panic that can happen in `decodePtr` - -## 1.1.0 - -* Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133] -* Support struct to struct decoding [GH-137] -* If source map value is nil, then destination map value is nil (instead of empty) -* If source slice value is nil, then destination slice value is nil (instead of empty) -* If source pointer is nil, then destination pointer is set to nil (instead of - allocated zero value of type) - -## 1.0.0 - -* Initial tagged stable release. diff --git a/vendor/github.com/mitchellh/mapstructure/LICENSE b/vendor/github.com/mitchellh/mapstructure/LICENSE deleted file mode 100644 index f9c841a..0000000 --- a/vendor/github.com/mitchellh/mapstructure/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Mitchell Hashimoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/mitchellh/mapstructure/README.md b/vendor/github.com/mitchellh/mapstructure/README.md deleted file mode 100644 index 0018dc7..0000000 --- a/vendor/github.com/mitchellh/mapstructure/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# mapstructure [![Godoc](https://godoc.org/github.com/mitchellh/mapstructure?status.svg)](https://godoc.org/github.com/mitchellh/mapstructure) - -mapstructure is a Go library for decoding generic map values to structures -and vice versa, while providing helpful error handling. - -This library is most useful when decoding values from some data stream (JSON, -Gob, etc.) where you don't _quite_ know the structure of the underlying data -until you read a part of it. You can therefore read a `map[string]interface{}` -and use this library to decode it into the proper underlying native Go -structure. - -## Installation - -Standard `go get`: - -``` -$ go get github.com/mitchellh/mapstructure -``` - -## Usage & Example - -For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure). - -The `Decode` function has examples associated with it there. - -## But Why?! - -Go offers fantastic standard libraries for decoding formats such as JSON. -The standard method is to have a struct pre-created, and populate that struct -from the bytes of the encoded format. This is great, but the problem is if -you have configuration or an encoding that changes slightly depending on -specific fields. For example, consider this JSON: - -```json -{ - "type": "person", - "name": "Mitchell" -} -``` - -Perhaps we can't populate a specific structure without first reading -the "type" field from the JSON. We could always do two passes over the -decoding of the JSON (reading the "type" first, and the rest later). -However, it is much simpler to just decode this into a `map[string]interface{}` -structure, read the "type" key, then use something like this library -to decode it into the proper structure. diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go deleted file mode 100644 index 1f0abc6..0000000 --- a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go +++ /dev/null @@ -1,217 +0,0 @@ -package mapstructure - -import ( - "errors" - "fmt" - "net" - "reflect" - "strconv" - "strings" - "time" -) - -// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns -// it into the proper DecodeHookFunc type, such as DecodeHookFuncType. -func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { - // Create variables here so we can reference them with the reflect pkg - var f1 DecodeHookFuncType - var f2 DecodeHookFuncKind - - // Fill in the variables into this interface and the rest is done - // automatically using the reflect package. - potential := []interface{}{f1, f2} - - v := reflect.ValueOf(h) - vt := v.Type() - for _, raw := range potential { - pt := reflect.ValueOf(raw).Type() - if vt.ConvertibleTo(pt) { - return v.Convert(pt).Interface() - } - } - - return nil -} - -// DecodeHookExec executes the given decode hook. This should be used -// since it'll naturally degrade to the older backwards compatible DecodeHookFunc -// that took reflect.Kind instead of reflect.Type. -func DecodeHookExec( - raw DecodeHookFunc, - from reflect.Type, to reflect.Type, - data interface{}) (interface{}, error) { - switch f := typedDecodeHook(raw).(type) { - case DecodeHookFuncType: - return f(from, to, data) - case DecodeHookFuncKind: - return f(from.Kind(), to.Kind(), data) - default: - return nil, errors.New("invalid decode hook signature") - } -} - -// ComposeDecodeHookFunc creates a single DecodeHookFunc that -// automatically composes multiple DecodeHookFuncs. -// -// The composed funcs are called in order, with the result of the -// previous transformation. -func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}) (interface{}, error) { - var err error - for _, f1 := range fs { - data, err = DecodeHookExec(f1, f, t, data) - if err != nil { - return nil, err - } - - // Modify the from kind to be correct with the new data - f = nil - if val := reflect.ValueOf(data); val.IsValid() { - f = val.Type() - } - } - - return data, nil - } -} - -// StringToSliceHookFunc returns a DecodeHookFunc that converts -// string to []string by splitting on the given sep. -func StringToSliceHookFunc(sep string) DecodeHookFunc { - return func( - f reflect.Kind, - t reflect.Kind, - data interface{}) (interface{}, error) { - if f != reflect.String || t != reflect.Slice { - return data, nil - } - - raw := data.(string) - if raw == "" { - return []string{}, nil - } - - return strings.Split(raw, sep), nil - } -} - -// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts -// strings to time.Duration. -func StringToTimeDurationHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}) (interface{}, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(time.Duration(5)) { - return data, nil - } - - // Convert it by parsing - return time.ParseDuration(data.(string)) - } -} - -// StringToIPHookFunc returns a DecodeHookFunc that converts -// strings to net.IP -func StringToIPHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}) (interface{}, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(net.IP{}) { - return data, nil - } - - // Convert it by parsing - ip := net.ParseIP(data.(string)) - if ip == nil { - return net.IP{}, fmt.Errorf("failed parsing ip %v", data) - } - - return ip, nil - } -} - -// StringToIPNetHookFunc returns a DecodeHookFunc that converts -// strings to net.IPNet -func StringToIPNetHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}) (interface{}, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(net.IPNet{}) { - return data, nil - } - - // Convert it by parsing - _, net, err := net.ParseCIDR(data.(string)) - return net, err - } -} - -// StringToTimeHookFunc returns a DecodeHookFunc that converts -// strings to time.Time. -func StringToTimeHookFunc(layout string) DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}) (interface{}, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(time.Time{}) { - return data, nil - } - - // Convert it by parsing - return time.Parse(layout, data.(string)) - } -} - -// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to -// the decoder. -// -// Note that this is significantly different from the WeaklyTypedInput option -// of the DecoderConfig. -func WeaklyTypedHook( - f reflect.Kind, - t reflect.Kind, - data interface{}) (interface{}, error) { - dataVal := reflect.ValueOf(data) - switch t { - case reflect.String: - switch f { - case reflect.Bool: - if dataVal.Bool() { - return "1", nil - } - return "0", nil - case reflect.Float32: - return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil - case reflect.Int: - return strconv.FormatInt(dataVal.Int(), 10), nil - case reflect.Slice: - dataType := dataVal.Type() - elemKind := dataType.Elem().Kind() - if elemKind == reflect.Uint8 { - return string(dataVal.Interface().([]uint8)), nil - } - case reflect.Uint: - return strconv.FormatUint(dataVal.Uint(), 10), nil - } - } - - return data, nil -} diff --git a/vendor/github.com/mitchellh/mapstructure/error.go b/vendor/github.com/mitchellh/mapstructure/error.go deleted file mode 100644 index 47a99e5..0000000 --- a/vendor/github.com/mitchellh/mapstructure/error.go +++ /dev/null @@ -1,50 +0,0 @@ -package mapstructure - -import ( - "errors" - "fmt" - "sort" - "strings" -) - -// Error implements the error interface and can represents multiple -// errors that occur in the course of a single decode. -type Error struct { - Errors []string -} - -func (e *Error) Error() string { - points := make([]string, len(e.Errors)) - for i, err := range e.Errors { - points[i] = fmt.Sprintf("* %s", err) - } - - sort.Strings(points) - return fmt.Sprintf( - "%d error(s) decoding:\n\n%s", - len(e.Errors), strings.Join(points, "\n")) -} - -// WrappedErrors implements the errwrap.Wrapper interface to make this -// return value more useful with the errwrap and go-multierror libraries. -func (e *Error) WrappedErrors() []error { - if e == nil { - return nil - } - - result := make([]error, len(e.Errors)) - for i, e := range e.Errors { - result[i] = errors.New(e) - } - - return result -} - -func appendErrors(errors []string, err error) []string { - switch e := err.(type) { - case *Error: - return append(errors, e.Errors...) - default: - return append(errors, e.Error()) - } -} diff --git a/vendor/github.com/mitchellh/mapstructure/go.mod b/vendor/github.com/mitchellh/mapstructure/go.mod deleted file mode 100644 index a03ae97..0000000 --- a/vendor/github.com/mitchellh/mapstructure/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/mitchellh/mapstructure - -go 1.14 diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go deleted file mode 100644 index daea331..0000000 --- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go +++ /dev/null @@ -1,1309 +0,0 @@ -// Package mapstructure exposes functionality to convert one arbitrary -// Go type into another, typically to convert a map[string]interface{} -// into a native Go structure. -// -// The Go structure can be arbitrarily complex, containing slices, -// other structs, etc. and the decoder will properly decode nested -// maps and so on into the proper structures in the native Go struct. -// See the examples to see what the decoder is capable of. -// -// The simplest function to start with is Decode. -// -// Field Tags -// -// When decoding to a struct, mapstructure will use the field name by -// default to perform the mapping. For example, if a struct has a field -// "Username" then mapstructure will look for a key in the source value -// of "username" (case insensitive). -// -// type User struct { -// Username string -// } -// -// You can change the behavior of mapstructure by using struct tags. -// The default struct tag that mapstructure looks for is "mapstructure" -// but you can customize it using DecoderConfig. -// -// Renaming Fields -// -// To rename the key that mapstructure looks for, use the "mapstructure" -// tag and set a value directly. For example, to change the "username" example -// above to "user": -// -// type User struct { -// Username string `mapstructure:"user"` -// } -// -// Embedded Structs and Squashing -// -// Embedded structs are treated as if they're another field with that name. -// By default, the two structs below are equivalent when decoding with -// mapstructure: -// -// type Person struct { -// Name string -// } -// -// type Friend struct { -// Person -// } -// -// type Friend struct { -// Person Person -// } -// -// This would require an input that looks like below: -// -// map[string]interface{}{ -// "person": map[string]interface{}{"name": "alice"}, -// } -// -// If your "person" value is NOT nested, then you can append ",squash" to -// your tag value and mapstructure will treat it as if the embedded struct -// were part of the struct directly. Example: -// -// type Friend struct { -// Person `mapstructure:",squash"` -// } -// -// Now the following input would be accepted: -// -// map[string]interface{}{ -// "name": "alice", -// } -// -// DecoderConfig has a field that changes the behavior of mapstructure -// to always squash embedded structs. -// -// Remainder Values -// -// If there are any unmapped keys in the source value, mapstructure by -// default will silently ignore them. You can error by setting ErrorUnused -// in DecoderConfig. If you're using Metadata you can also maintain a slice -// of the unused keys. -// -// You can also use the ",remain" suffix on your tag to collect all unused -// values in a map. The field with this tag MUST be a map type and should -// probably be a "map[string]interface{}" or "map[interface{}]interface{}". -// See example below: -// -// type Friend struct { -// Name string -// Other map[string]interface{} `mapstructure:",remain"` -// } -// -// Given the input below, Other would be populated with the other -// values that weren't used (everything but "name"): -// -// map[string]interface{}{ -// "name": "bob", -// "address": "123 Maple St.", -// } -// -// Other Configuration -// -// mapstructure is highly configurable. See the DecoderConfig struct -// for other features and options that are supported. -package mapstructure - -import ( - "encoding/json" - "errors" - "fmt" - "reflect" - "sort" - "strconv" - "strings" -) - -// DecodeHookFunc is the callback function that can be used for -// data transformations. See "DecodeHook" in the DecoderConfig -// struct. -// -// The type should be DecodeHookFuncType or DecodeHookFuncKind. -// Either is accepted. Types are a superset of Kinds (Types can return -// Kinds) and are generally a richer thing to use, but Kinds are simpler -// if you only need those. -// -// The reason DecodeHookFunc is multi-typed is for backwards compatibility: -// we started with Kinds and then realized Types were the better solution, -// but have a promise to not break backwards compat so we now support -// both. -type DecodeHookFunc interface{} - -// DecodeHookFuncType is a DecodeHookFunc which has complete information about -// the source and target types. -type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error) - -// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the -// source and target types. -type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) - -// DecoderConfig is the configuration that is used to create a new decoder -// and allows customization of various aspects of decoding. -type DecoderConfig struct { - // DecodeHook, if set, will be called before any decoding and any - // type conversion (if WeaklyTypedInput is on). This lets you modify - // the values before they're set down onto the resulting struct. - // - // If an error is returned, the entire decode will fail with that - // error. - DecodeHook DecodeHookFunc - - // If ErrorUnused is true, then it is an error for there to exist - // keys in the original map that were unused in the decoding process - // (extra keys). - ErrorUnused bool - - // ZeroFields, if set to true, will zero fields before writing them. - // For example, a map will be emptied before decoded values are put in - // it. If this is false, a map will be merged. - ZeroFields bool - - // If WeaklyTypedInput is true, the decoder will make the following - // "weak" conversions: - // - // - bools to string (true = "1", false = "0") - // - numbers to string (base 10) - // - bools to int/uint (true = 1, false = 0) - // - strings to int/uint (base implied by prefix) - // - int to bool (true if value != 0) - // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F, - // FALSE, false, False. Anything else is an error) - // - empty array = empty map and vice versa - // - negative numbers to overflowed uint values (base 10) - // - slice of maps to a merged map - // - single values are converted to slices if required. Each - // element is weakly decoded. For example: "4" can become []int{4} - // if the target type is an int slice. - // - WeaklyTypedInput bool - - // Squash will squash embedded structs. A squash tag may also be - // added to an individual struct field using a tag. For example: - // - // type Parent struct { - // Child `mapstructure:",squash"` - // } - Squash bool - - // Metadata is the struct that will contain extra metadata about - // the decoding. If this is nil, then no metadata will be tracked. - Metadata *Metadata - - // Result is a pointer to the struct that will contain the decoded - // value. - Result interface{} - - // The tag name that mapstructure reads for field names. This - // defaults to "mapstructure" - TagName string -} - -// A Decoder takes a raw interface value and turns it into structured -// data, keeping track of rich error information along the way in case -// anything goes wrong. Unlike the basic top-level Decode method, you can -// more finely control how the Decoder behaves using the DecoderConfig -// structure. The top-level Decode method is just a convenience that sets -// up the most basic Decoder. -type Decoder struct { - config *DecoderConfig -} - -// Metadata contains information about decoding a structure that -// is tedious or difficult to get otherwise. -type Metadata struct { - // Keys are the keys of the structure which were successfully decoded - Keys []string - - // Unused is a slice of keys that were found in the raw value but - // weren't decoded since there was no matching field in the result interface - Unused []string -} - -// Decode takes an input structure and uses reflection to translate it to -// the output structure. output must be a pointer to a map or struct. -func Decode(input interface{}, output interface{}) error { - config := &DecoderConfig{ - Metadata: nil, - Result: output, - } - - decoder, err := NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -// WeakDecode is the same as Decode but is shorthand to enable -// WeaklyTypedInput. See DecoderConfig for more info. -func WeakDecode(input, output interface{}) error { - config := &DecoderConfig{ - Metadata: nil, - Result: output, - WeaklyTypedInput: true, - } - - decoder, err := NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -// DecodeMetadata is the same as Decode, but is shorthand to -// enable metadata collection. See DecoderConfig for more info. -func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error { - config := &DecoderConfig{ - Metadata: metadata, - Result: output, - } - - decoder, err := NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -// WeakDecodeMetadata is the same as Decode, but is shorthand to -// enable both WeaklyTypedInput and metadata collection. See -// DecoderConfig for more info. -func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error { - config := &DecoderConfig{ - Metadata: metadata, - Result: output, - WeaklyTypedInput: true, - } - - decoder, err := NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -// NewDecoder returns a new decoder for the given configuration. Once -// a decoder has been returned, the same configuration must not be used -// again. -func NewDecoder(config *DecoderConfig) (*Decoder, error) { - val := reflect.ValueOf(config.Result) - if val.Kind() != reflect.Ptr { - return nil, errors.New("result must be a pointer") - } - - val = val.Elem() - if !val.CanAddr() { - return nil, errors.New("result must be addressable (a pointer)") - } - - if config.Metadata != nil { - if config.Metadata.Keys == nil { - config.Metadata.Keys = make([]string, 0) - } - - if config.Metadata.Unused == nil { - config.Metadata.Unused = make([]string, 0) - } - } - - if config.TagName == "" { - config.TagName = "mapstructure" - } - - result := &Decoder{ - config: config, - } - - return result, nil -} - -// Decode decodes the given raw interface to the target pointer specified -// by the configuration. -func (d *Decoder) Decode(input interface{}) error { - return d.decode("", input, reflect.ValueOf(d.config.Result).Elem()) -} - -// Decodes an unknown data type into a specific reflection value. -func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error { - var inputVal reflect.Value - if input != nil { - inputVal = reflect.ValueOf(input) - - // We need to check here if input is a typed nil. Typed nils won't - // match the "input == nil" below so we check that here. - if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() { - input = nil - } - } - - if input == nil { - // If the data is nil, then we don't set anything, unless ZeroFields is set - // to true. - if d.config.ZeroFields { - outVal.Set(reflect.Zero(outVal.Type())) - - if d.config.Metadata != nil && name != "" { - d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) - } - } - return nil - } - - if !inputVal.IsValid() { - // If the input value is invalid, then we just set the value - // to be the zero value. - outVal.Set(reflect.Zero(outVal.Type())) - if d.config.Metadata != nil && name != "" { - d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) - } - return nil - } - - if d.config.DecodeHook != nil { - // We have a DecodeHook, so let's pre-process the input. - var err error - input, err = DecodeHookExec( - d.config.DecodeHook, - inputVal.Type(), outVal.Type(), input) - if err != nil { - return fmt.Errorf("error decoding '%s': %s", name, err) - } - } - - var err error - outputKind := getKind(outVal) - switch outputKind { - case reflect.Bool: - err = d.decodeBool(name, input, outVal) - case reflect.Interface: - err = d.decodeBasic(name, input, outVal) - case reflect.String: - err = d.decodeString(name, input, outVal) - case reflect.Int: - err = d.decodeInt(name, input, outVal) - case reflect.Uint: - err = d.decodeUint(name, input, outVal) - case reflect.Float32: - err = d.decodeFloat(name, input, outVal) - case reflect.Struct: - err = d.decodeStruct(name, input, outVal) - case reflect.Map: - err = d.decodeMap(name, input, outVal) - case reflect.Ptr: - err = d.decodePtr(name, input, outVal) - case reflect.Slice: - err = d.decodeSlice(name, input, outVal) - case reflect.Array: - err = d.decodeArray(name, input, outVal) - case reflect.Func: - err = d.decodeFunc(name, input, outVal) - default: - // If we reached this point then we weren't able to decode it - return fmt.Errorf("%s: unsupported type: %s", name, outputKind) - } - - // If we reached here, then we successfully decoded SOMETHING, so - // mark the key as used if we're tracking metainput. - if d.config.Metadata != nil && name != "" { - d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) - } - - return err -} - -// This decodes a basic type (bool, int, string, etc.) and sets the -// value to "data" of that type. -func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error { - if val.IsValid() && val.Elem().IsValid() { - return d.decode(name, data, val.Elem()) - } - - dataVal := reflect.ValueOf(data) - - // If the input data is a pointer, and the assigned type is the dereference - // of that exact pointer, then indirect it so that we can assign it. - // Example: *string to string - if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() { - dataVal = reflect.Indirect(dataVal) - } - - if !dataVal.IsValid() { - dataVal = reflect.Zero(val.Type()) - } - - dataValType := dataVal.Type() - if !dataValType.AssignableTo(val.Type()) { - return fmt.Errorf( - "'%s' expected type '%s', got '%s'", - name, val.Type(), dataValType) - } - - val.Set(dataVal) - return nil -} - -func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - - converted := true - switch { - case dataKind == reflect.String: - val.SetString(dataVal.String()) - case dataKind == reflect.Bool && d.config.WeaklyTypedInput: - if dataVal.Bool() { - val.SetString("1") - } else { - val.SetString("0") - } - case dataKind == reflect.Int && d.config.WeaklyTypedInput: - val.SetString(strconv.FormatInt(dataVal.Int(), 10)) - case dataKind == reflect.Uint && d.config.WeaklyTypedInput: - val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) - case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: - val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) - case dataKind == reflect.Slice && d.config.WeaklyTypedInput, - dataKind == reflect.Array && d.config.WeaklyTypedInput: - dataType := dataVal.Type() - elemKind := dataType.Elem().Kind() - switch elemKind { - case reflect.Uint8: - var uints []uint8 - if dataKind == reflect.Array { - uints = make([]uint8, dataVal.Len(), dataVal.Len()) - for i := range uints { - uints[i] = dataVal.Index(i).Interface().(uint8) - } - } else { - uints = dataVal.Interface().([]uint8) - } - val.SetString(string(uints)) - default: - converted = false - } - default: - converted = false - } - - if !converted { - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) - } - - return nil -} - -func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - dataType := dataVal.Type() - - switch { - case dataKind == reflect.Int: - val.SetInt(dataVal.Int()) - case dataKind == reflect.Uint: - val.SetInt(int64(dataVal.Uint())) - case dataKind == reflect.Float32: - val.SetInt(int64(dataVal.Float())) - case dataKind == reflect.Bool && d.config.WeaklyTypedInput: - if dataVal.Bool() { - val.SetInt(1) - } else { - val.SetInt(0) - } - case dataKind == reflect.String && d.config.WeaklyTypedInput: - i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits()) - if err == nil { - val.SetInt(i) - } else { - return fmt.Errorf("cannot parse '%s' as int: %s", name, err) - } - case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": - jn := data.(json.Number) - i, err := jn.Int64() - if err != nil { - return fmt.Errorf( - "error decoding json.Number into %s: %s", name, err) - } - val.SetInt(i) - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) - } - - return nil -} - -func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - dataType := dataVal.Type() - - switch { - case dataKind == reflect.Int: - i := dataVal.Int() - if i < 0 && !d.config.WeaklyTypedInput { - return fmt.Errorf("cannot parse '%s', %d overflows uint", - name, i) - } - val.SetUint(uint64(i)) - case dataKind == reflect.Uint: - val.SetUint(dataVal.Uint()) - case dataKind == reflect.Float32: - f := dataVal.Float() - if f < 0 && !d.config.WeaklyTypedInput { - return fmt.Errorf("cannot parse '%s', %f overflows uint", - name, f) - } - val.SetUint(uint64(f)) - case dataKind == reflect.Bool && d.config.WeaklyTypedInput: - if dataVal.Bool() { - val.SetUint(1) - } else { - val.SetUint(0) - } - case dataKind == reflect.String && d.config.WeaklyTypedInput: - i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits()) - if err == nil { - val.SetUint(i) - } else { - return fmt.Errorf("cannot parse '%s' as uint: %s", name, err) - } - case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": - jn := data.(json.Number) - i, err := jn.Int64() - if err != nil { - return fmt.Errorf( - "error decoding json.Number into %s: %s", name, err) - } - if i < 0 && !d.config.WeaklyTypedInput { - return fmt.Errorf("cannot parse '%s', %d overflows uint", - name, i) - } - val.SetUint(uint64(i)) - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) - } - - return nil -} - -func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - - switch { - case dataKind == reflect.Bool: - val.SetBool(dataVal.Bool()) - case dataKind == reflect.Int && d.config.WeaklyTypedInput: - val.SetBool(dataVal.Int() != 0) - case dataKind == reflect.Uint && d.config.WeaklyTypedInput: - val.SetBool(dataVal.Uint() != 0) - case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: - val.SetBool(dataVal.Float() != 0) - case dataKind == reflect.String && d.config.WeaklyTypedInput: - b, err := strconv.ParseBool(dataVal.String()) - if err == nil { - val.SetBool(b) - } else if dataVal.String() == "" { - val.SetBool(false) - } else { - return fmt.Errorf("cannot parse '%s' as bool: %s", name, err) - } - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) - } - - return nil -} - -func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - dataType := dataVal.Type() - - switch { - case dataKind == reflect.Int: - val.SetFloat(float64(dataVal.Int())) - case dataKind == reflect.Uint: - val.SetFloat(float64(dataVal.Uint())) - case dataKind == reflect.Float32: - val.SetFloat(dataVal.Float()) - case dataKind == reflect.Bool && d.config.WeaklyTypedInput: - if dataVal.Bool() { - val.SetFloat(1) - } else { - val.SetFloat(0) - } - case dataKind == reflect.String && d.config.WeaklyTypedInput: - f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits()) - if err == nil { - val.SetFloat(f) - } else { - return fmt.Errorf("cannot parse '%s' as float: %s", name, err) - } - case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": - jn := data.(json.Number) - i, err := jn.Float64() - if err != nil { - return fmt.Errorf( - "error decoding json.Number into %s: %s", name, err) - } - val.SetFloat(i) - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) - } - - return nil -} - -func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error { - valType := val.Type() - valKeyType := valType.Key() - valElemType := valType.Elem() - - // By default we overwrite keys in the current map - valMap := val - - // If the map is nil or we're purposely zeroing fields, make a new map - if valMap.IsNil() || d.config.ZeroFields { - // Make a new map to hold our result - mapType := reflect.MapOf(valKeyType, valElemType) - valMap = reflect.MakeMap(mapType) - } - - // Check input type and based on the input type jump to the proper func - dataVal := reflect.Indirect(reflect.ValueOf(data)) - switch dataVal.Kind() { - case reflect.Map: - return d.decodeMapFromMap(name, dataVal, val, valMap) - - case reflect.Struct: - return d.decodeMapFromStruct(name, dataVal, val, valMap) - - case reflect.Array, reflect.Slice: - if d.config.WeaklyTypedInput { - return d.decodeMapFromSlice(name, dataVal, val, valMap) - } - - fallthrough - - default: - return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) - } -} - -func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { - // Special case for BC reasons (covered by tests) - if dataVal.Len() == 0 { - val.Set(valMap) - return nil - } - - for i := 0; i < dataVal.Len(); i++ { - err := d.decode( - fmt.Sprintf("%s[%d]", name, i), - dataVal.Index(i).Interface(), val) - if err != nil { - return err - } - } - - return nil -} - -func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { - valType := val.Type() - valKeyType := valType.Key() - valElemType := valType.Elem() - - // Accumulate errors - errors := make([]string, 0) - - // If the input data is empty, then we just match what the input data is. - if dataVal.Len() == 0 { - if dataVal.IsNil() { - if !val.IsNil() { - val.Set(dataVal) - } - } else { - // Set to empty allocated value - val.Set(valMap) - } - - return nil - } - - for _, k := range dataVal.MapKeys() { - fieldName := fmt.Sprintf("%s[%s]", name, k) - - // First decode the key into the proper type - currentKey := reflect.Indirect(reflect.New(valKeyType)) - if err := d.decode(fieldName, k.Interface(), currentKey); err != nil { - errors = appendErrors(errors, err) - continue - } - - // Next decode the data into the proper type - v := dataVal.MapIndex(k).Interface() - currentVal := reflect.Indirect(reflect.New(valElemType)) - if err := d.decode(fieldName, v, currentVal); err != nil { - errors = appendErrors(errors, err) - continue - } - - valMap.SetMapIndex(currentKey, currentVal) - } - - // Set the built up map to the value - val.Set(valMap) - - // If we had errors, return those - if len(errors) > 0 { - return &Error{errors} - } - - return nil -} - -func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { - typ := dataVal.Type() - for i := 0; i < typ.NumField(); i++ { - // Get the StructField first since this is a cheap operation. If the - // field is unexported, then ignore it. - f := typ.Field(i) - if f.PkgPath != "" { - continue - } - - // Next get the actual value of this field and verify it is assignable - // to the map value. - v := dataVal.Field(i) - if !v.Type().AssignableTo(valMap.Type().Elem()) { - return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem()) - } - - tagValue := f.Tag.Get(d.config.TagName) - tagParts := strings.Split(tagValue, ",") - - // Determine the name of the key in the map - keyName := f.Name - if tagParts[0] != "" { - if tagParts[0] == "-" { - continue - } - keyName = tagParts[0] - } - - // If Squash is set in the config, we squash the field down. - squash := d.config.Squash && v.Kind() == reflect.Struct - // If "squash" is specified in the tag, we squash the field down. - if !squash { - for _, tag := range tagParts[1:] { - if tag == "squash" { - squash = true - break - } - } - if squash && v.Kind() != reflect.Struct { - return fmt.Errorf("cannot squash non-struct type '%s'", v.Type()) - } - } - - switch v.Kind() { - // this is an embedded struct, so handle it differently - case reflect.Struct: - x := reflect.New(v.Type()) - x.Elem().Set(v) - - vType := valMap.Type() - vKeyType := vType.Key() - vElemType := vType.Elem() - mType := reflect.MapOf(vKeyType, vElemType) - vMap := reflect.MakeMap(mType) - - err := d.decode(keyName, x.Interface(), vMap) - if err != nil { - return err - } - - if squash { - for _, k := range vMap.MapKeys() { - valMap.SetMapIndex(k, vMap.MapIndex(k)) - } - } else { - valMap.SetMapIndex(reflect.ValueOf(keyName), vMap) - } - - default: - valMap.SetMapIndex(reflect.ValueOf(keyName), v) - } - } - - if val.CanAddr() { - val.Set(valMap) - } - - return nil -} - -func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error { - // If the input data is nil, then we want to just set the output - // pointer to be nil as well. - isNil := data == nil - if !isNil { - switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() { - case reflect.Chan, - reflect.Func, - reflect.Interface, - reflect.Map, - reflect.Ptr, - reflect.Slice: - isNil = v.IsNil() - } - } - if isNil { - if !val.IsNil() && val.CanSet() { - nilValue := reflect.New(val.Type()).Elem() - val.Set(nilValue) - } - - return nil - } - - // Create an element of the concrete (non pointer) type and decode - // into that. Then set the value of the pointer to this type. - valType := val.Type() - valElemType := valType.Elem() - if val.CanSet() { - realVal := val - if realVal.IsNil() || d.config.ZeroFields { - realVal = reflect.New(valElemType) - } - - if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil { - return err - } - - val.Set(realVal) - } else { - if err := d.decode(name, data, reflect.Indirect(val)); err != nil { - return err - } - } - return nil -} - -func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error { - // Create an element of the concrete (non pointer) type and decode - // into that. Then set the value of the pointer to this type. - dataVal := reflect.Indirect(reflect.ValueOf(data)) - if val.Type() != dataVal.Type() { - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s'", - name, val.Type(), dataVal.Type()) - } - val.Set(dataVal) - return nil -} - -func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataValKind := dataVal.Kind() - valType := val.Type() - valElemType := valType.Elem() - sliceType := reflect.SliceOf(valElemType) - - // If we have a non array/slice type then we first attempt to convert. - if dataValKind != reflect.Array && dataValKind != reflect.Slice { - if d.config.WeaklyTypedInput { - switch { - // Slice and array we use the normal logic - case dataValKind == reflect.Slice, dataValKind == reflect.Array: - break - - // Empty maps turn into empty slices - case dataValKind == reflect.Map: - if dataVal.Len() == 0 { - val.Set(reflect.MakeSlice(sliceType, 0, 0)) - return nil - } - // Create slice of maps of other sizes - return d.decodeSlice(name, []interface{}{data}, val) - - case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8: - return d.decodeSlice(name, []byte(dataVal.String()), val) - - // All other types we try to convert to the slice type - // and "lift" it into it. i.e. a string becomes a string slice. - default: - // Just re-try this function with data as a slice. - return d.decodeSlice(name, []interface{}{data}, val) - } - } - - return fmt.Errorf( - "'%s': source data must be an array or slice, got %s", name, dataValKind) - } - - // If the input value is nil, then don't allocate since empty != nil - if dataVal.IsNil() { - return nil - } - - valSlice := val - if valSlice.IsNil() || d.config.ZeroFields { - // Make a new slice to hold our result, same size as the original data. - valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) - } - - // Accumulate any errors - errors := make([]string, 0) - - for i := 0; i < dataVal.Len(); i++ { - currentData := dataVal.Index(i).Interface() - for valSlice.Len() <= i { - valSlice = reflect.Append(valSlice, reflect.Zero(valElemType)) - } - currentField := valSlice.Index(i) - - fieldName := fmt.Sprintf("%s[%d]", name, i) - if err := d.decode(fieldName, currentData, currentField); err != nil { - errors = appendErrors(errors, err) - } - } - - // Finally, set the value to the slice we built up - val.Set(valSlice) - - // If there were errors, we return those - if len(errors) > 0 { - return &Error{errors} - } - - return nil -} - -func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataValKind := dataVal.Kind() - valType := val.Type() - valElemType := valType.Elem() - arrayType := reflect.ArrayOf(valType.Len(), valElemType) - - valArray := val - - if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields { - // Check input type - if dataValKind != reflect.Array && dataValKind != reflect.Slice { - if d.config.WeaklyTypedInput { - switch { - // Empty maps turn into empty arrays - case dataValKind == reflect.Map: - if dataVal.Len() == 0 { - val.Set(reflect.Zero(arrayType)) - return nil - } - - // All other types we try to convert to the array type - // and "lift" it into it. i.e. a string becomes a string array. - default: - // Just re-try this function with data as a slice. - return d.decodeArray(name, []interface{}{data}, val) - } - } - - return fmt.Errorf( - "'%s': source data must be an array or slice, got %s", name, dataValKind) - - } - if dataVal.Len() > arrayType.Len() { - return fmt.Errorf( - "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len()) - - } - - // Make a new array to hold our result, same size as the original data. - valArray = reflect.New(arrayType).Elem() - } - - // Accumulate any errors - errors := make([]string, 0) - - for i := 0; i < dataVal.Len(); i++ { - currentData := dataVal.Index(i).Interface() - currentField := valArray.Index(i) - - fieldName := fmt.Sprintf("%s[%d]", name, i) - if err := d.decode(fieldName, currentData, currentField); err != nil { - errors = appendErrors(errors, err) - } - } - - // Finally, set the value to the array we built up - val.Set(valArray) - - // If there were errors, we return those - if len(errors) > 0 { - return &Error{errors} - } - - return nil -} - -func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - - // If the type of the value to write to and the data match directly, - // then we just set it directly instead of recursing into the structure. - if dataVal.Type() == val.Type() { - val.Set(dataVal) - return nil - } - - dataValKind := dataVal.Kind() - switch dataValKind { - case reflect.Map: - return d.decodeStructFromMap(name, dataVal, val) - - case reflect.Struct: - // Not the most efficient way to do this but we can optimize later if - // we want to. To convert from struct to struct we go to map first - // as an intermediary. - m := make(map[string]interface{}) - mval := reflect.Indirect(reflect.ValueOf(&m)) - if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil { - return err - } - - result := d.decodeStructFromMap(name, mval, val) - return result - - default: - return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) - } -} - -func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error { - dataValType := dataVal.Type() - if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface { - return fmt.Errorf( - "'%s' needs a map with string keys, has '%s' keys", - name, dataValType.Key().Kind()) - } - - dataValKeys := make(map[reflect.Value]struct{}) - dataValKeysUnused := make(map[interface{}]struct{}) - for _, dataValKey := range dataVal.MapKeys() { - dataValKeys[dataValKey] = struct{}{} - dataValKeysUnused[dataValKey.Interface()] = struct{}{} - } - - errors := make([]string, 0) - - // This slice will keep track of all the structs we'll be decoding. - // There can be more than one struct if there are embedded structs - // that are squashed. - structs := make([]reflect.Value, 1, 5) - structs[0] = val - - // Compile the list of all the fields that we're going to be decoding - // from all the structs. - type field struct { - field reflect.StructField - val reflect.Value - } - - // remainField is set to a valid field set with the "remain" tag if - // we are keeping track of remaining values. - var remainField *field - - fields := []field{} - for len(structs) > 0 { - structVal := structs[0] - structs = structs[1:] - - structType := structVal.Type() - - for i := 0; i < structType.NumField(); i++ { - fieldType := structType.Field(i) - fieldKind := fieldType.Type.Kind() - - // If "squash" is specified in the tag, we squash the field down. - squash := d.config.Squash && fieldKind == reflect.Struct - remain := false - - // We always parse the tags cause we're looking for other tags too - tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",") - for _, tag := range tagParts[1:] { - if tag == "squash" { - squash = true - break - } - - if tag == "remain" { - remain = true - break - } - } - - if squash { - if fieldKind != reflect.Struct { - errors = appendErrors(errors, - fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) - } else { - structs = append(structs, structVal.FieldByName(fieldType.Name)) - } - continue - } - - // Build our field - fieldCurrent := field{fieldType, structVal.Field(i)} - if remain { - remainField = &fieldCurrent - } else { - // Normal struct field, store it away - fields = append(fields, field{fieldType, structVal.Field(i)}) - } - } - } - - // for fieldType, field := range fields { - for _, f := range fields { - field, fieldValue := f.field, f.val - fieldName := field.Name - - tagValue := field.Tag.Get(d.config.TagName) - tagValue = strings.SplitN(tagValue, ",", 2)[0] - if tagValue != "" { - fieldName = tagValue - } - - rawMapKey := reflect.ValueOf(fieldName) - rawMapVal := dataVal.MapIndex(rawMapKey) - if !rawMapVal.IsValid() { - // Do a slower search by iterating over each key and - // doing case-insensitive search. - for dataValKey := range dataValKeys { - mK, ok := dataValKey.Interface().(string) - if !ok { - // Not a string key - continue - } - - if strings.EqualFold(mK, fieldName) { - rawMapKey = dataValKey - rawMapVal = dataVal.MapIndex(dataValKey) - break - } - } - - if !rawMapVal.IsValid() { - // There was no matching key in the map for the value in - // the struct. Just ignore. - continue - } - } - - if !fieldValue.IsValid() { - // This should never happen - panic("field is not valid") - } - - // If we can't set the field, then it is unexported or something, - // and we just continue onwards. - if !fieldValue.CanSet() { - continue - } - - // Delete the key we're using from the unused map so we stop tracking - delete(dataValKeysUnused, rawMapKey.Interface()) - - // If the name is empty string, then we're at the root, and we - // don't dot-join the fields. - if name != "" { - fieldName = fmt.Sprintf("%s.%s", name, fieldName) - } - - if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil { - errors = appendErrors(errors, err) - } - } - - // If we have a "remain"-tagged field and we have unused keys then - // we put the unused keys directly into the remain field. - if remainField != nil && len(dataValKeysUnused) > 0 { - // Build a map of only the unused values - remain := map[interface{}]interface{}{} - for key := range dataValKeysUnused { - remain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface() - } - - // Decode it as-if we were just decoding this map onto our map. - if err := d.decodeMap(name, remain, remainField.val); err != nil { - errors = appendErrors(errors, err) - } - - // Set the map to nil so we have none so that the next check will - // not error (ErrorUnused) - dataValKeysUnused = nil - } - - if d.config.ErrorUnused && len(dataValKeysUnused) > 0 { - keys := make([]string, 0, len(dataValKeysUnused)) - for rawKey := range dataValKeysUnused { - keys = append(keys, rawKey.(string)) - } - sort.Strings(keys) - - err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", ")) - errors = appendErrors(errors, err) - } - - if len(errors) > 0 { - return &Error{errors} - } - - // Add the unused keys to the list of unused keys if we're tracking metadata - if d.config.Metadata != nil { - for rawKey := range dataValKeysUnused { - key := rawKey.(string) - if name != "" { - key = fmt.Sprintf("%s.%s", name, key) - } - - d.config.Metadata.Unused = append(d.config.Metadata.Unused, key) - } - } - - return nil -} - -func getKind(val reflect.Value) reflect.Kind { - kind := val.Kind() - - switch { - case kind >= reflect.Int && kind <= reflect.Int64: - return reflect.Int - case kind >= reflect.Uint && kind <= reflect.Uint64: - return reflect.Uint - case kind >= reflect.Float32 && kind <= reflect.Float64: - return reflect.Float32 - default: - return kind - } -} diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/LICENSE b/vendor/github.com/uyuni-project/xmlrpc-public-methods/LICENSE deleted file mode 100644 index 8103dd1..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2012 Dmitry Maksimov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/README.md b/vendor/github.com/uyuni-project/xmlrpc-public-methods/README.md deleted file mode 100644 index 0f0c6ae..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/README.md +++ /dev/null @@ -1,96 +0,0 @@ -[![GoDoc](https://godoc.org/github.com/kolo/xmlrpc?status.svg)](https://godoc.org/github.com/kolo/xmlrpc) - -# kolo/xmlrpc with with 'decoder' and 'marshal' made public - -This is a fork of [kolo/xmlrpc](https://github.com/kolo/xmlrpc) with the purpose of making 'decoder' and 'marshall' methods public. - -Long term plan is to move to another library such as [alexejk/go-xmlrpc](https://github.com/alexejk/go-xmlrpc) - -## Overview - -xmlrpc is an implementation of client side part of XMLRPC protocol in Go language. - -## Status - -This project is in minimal maintenance mode with no further development. Bug fixes -are accepted, but it might take some time until they will be merged. - -## Installation - -To install xmlrpc package run `go get github.com/kolo/xmlrpc`. To use -it in application add `"github.com/kolo/xmlrpc"` string to `import` -statement. - -## Usage - - client, _ := xmlrpc.NewClient("https://bugzilla.mozilla.org/xmlrpc.cgi", nil) - result := struct{ - Version string `xmlrpc:"version"` - }{} - client.Call("Bugzilla.version", nil, &result) - fmt.Printf("Version: %s\n", result.Version) // Version: 4.2.7+ - -Second argument of NewClient function is an object that implements -[http.RoundTripper](http://golang.org/pkg/net/http/#RoundTripper) -interface, it can be used to get more control over connection options. -By default it initialized by http.DefaultTransport object. - -### Arguments encoding - -xmlrpc package supports encoding of native Go data types to method -arguments. - -Data types encoding rules: - -* int, int8, int16, int32, int64 encoded to int; -* float32, float64 encoded to double; -* bool encoded to boolean; -* string encoded to string; -* time.Time encoded to datetime.iso8601; -* xmlrpc.Base64 encoded to base64; -* slice encoded to array; - -Structs encoded to struct by following rules: - -* all public field become struct members; -* field name become member name; -* if field has xmlrpc tag, its value become member name. -* for fields tagged with `",omitempty"`, empty values are omitted; - -Server method can accept few arguments, to handle this case there is -special approach to handle slice of empty interfaces (`[]interface{}`). -Each value of such slice encoded as separate argument. - -### Result decoding - -Result of remote function is decoded to native Go data type. - -Data types decoding rules: - -* int, i4 decoded to int, int8, int16, int32, int64; -* double decoded to float32, float64; -* boolean decoded to bool; -* string decoded to string; -* array decoded to slice; -* structs decoded following the rules described in previous section; -* datetime.iso8601 decoded as time.Time data type; -* base64 decoded to string. - -## Implementation details - -xmlrpc package contains clientCodec type, that implements [rpc.ClientCodec](http://golang.org/pkg/net/rpc/#ClientCodec) -interface of [net/rpc](http://golang.org/pkg/net/rpc) package. - -xmlrpc package works over HTTP protocol, but some internal functions -and data type were made public to make it easier to create another -implementation of xmlrpc that works over another protocol. To encode -request body there is EncodeMethodCall function. To decode server -response Response data type can be used. - -## Contribution - -See [project status](#status). - -## Authors - -Dmitry Maksimov (dmtmax@gmail.com) diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/client.go b/vendor/github.com/uyuni-project/xmlrpc-public-methods/client.go deleted file mode 100644 index 643dc1c..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/client.go +++ /dev/null @@ -1,161 +0,0 @@ -package xmlrpc - -import ( - "errors" - "fmt" - "io/ioutil" - "net/http" - "net/http/cookiejar" - "net/rpc" - "net/url" - "sync" -) - -type Client struct { - *rpc.Client -} - -// clientCodec is rpc.ClientCodec interface implementation. -type clientCodec struct { - // url presents url of xmlrpc service - url *url.URL - - // httpClient works with HTTP protocol - httpClient *http.Client - - // cookies stores cookies received on last request - cookies http.CookieJar - - // responses presents map of active requests. It is required to return request id, that - // rpc.Client can mark them as done. - responses map[uint64]*http.Response - mutex sync.Mutex - - response Response - - // ready presents channel, that is used to link request and it`s response. - ready chan uint64 - - // close notifies codec is closed. - close chan uint64 -} - -func (codec *clientCodec) WriteRequest(request *rpc.Request, args interface{}) (err error) { - httpRequest, err := NewRequest(codec.url.String(), request.ServiceMethod, args) - - if err != nil { - return err - } - - if codec.cookies != nil { - for _, cookie := range codec.cookies.Cookies(codec.url) { - httpRequest.AddCookie(cookie) - } - } - - var httpResponse *http.Response - httpResponse, err = codec.httpClient.Do(httpRequest) - - if err != nil { - return err - } - - if codec.cookies != nil { - codec.cookies.SetCookies(codec.url, httpResponse.Cookies()) - } - - codec.mutex.Lock() - codec.responses[request.Seq] = httpResponse - codec.mutex.Unlock() - - codec.ready <- request.Seq - - return nil -} - -func (codec *clientCodec) ReadResponseHeader(response *rpc.Response) (err error) { - var seq uint64 - select { - case seq = <-codec.ready: - case <-codec.close: - return errors.New("codec is closed") - } - response.Seq = seq - - codec.mutex.Lock() - httpResponse := codec.responses[seq] - delete(codec.responses, seq) - codec.mutex.Unlock() - - defer httpResponse.Body.Close() - - if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 { - response.Error = fmt.Sprintf("request error: bad status code - %d", httpResponse.StatusCode) - return nil - } - - body, err := ioutil.ReadAll(httpResponse.Body) - if err != nil { - response.Error = err.Error() - return nil - } - - resp := Response(body) - if err := resp.Err(); err != nil { - response.Error = err.Error() - return nil - } - - codec.response = resp - - return nil -} - -func (codec *clientCodec) ReadResponseBody(v interface{}) (err error) { - if v == nil { - return nil - } - return codec.response.Unmarshal(v) -} - -func (codec *clientCodec) Close() error { - if transport, ok := codec.httpClient.Transport.(*http.Transport); ok { - transport.CloseIdleConnections() - } - - close(codec.close) - - return nil -} - -// NewClient returns instance of rpc.Client object, that is used to send request to xmlrpc service. -func NewClient(requrl string, transport http.RoundTripper) (*Client, error) { - if transport == nil { - transport = http.DefaultTransport - } - - httpClient := &http.Client{Transport: transport} - - jar, err := cookiejar.New(nil) - - if err != nil { - return nil, err - } - - u, err := url.Parse(requrl) - - if err != nil { - return nil, err - } - - codec := clientCodec{ - url: u, - httpClient: httpClient, - close: make(chan uint64), - ready: make(chan uint64), - responses: make(map[uint64]*http.Response), - cookies: jar, - } - - return &Client{rpc.NewClientWithCodec(&codec)}, nil -} diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/decoder.go b/vendor/github.com/uyuni-project/xmlrpc-public-methods/decoder.go deleted file mode 100644 index 15022b7..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/decoder.go +++ /dev/null @@ -1,473 +0,0 @@ -package xmlrpc - -import ( - "bytes" - "encoding/xml" - "errors" - "fmt" - "io" - "reflect" - "strconv" - "strings" - "time" -) - -const ( - iso8601 = "20060102T15:04:05" - iso8601Z = "20060102T15:04:05Z07:00" - iso8601Hyphen = "2006-01-02T15:04:05" - iso8601HyphenZ = "2006-01-02T15:04:05Z07:00" -) - -var ( - // CharsetReader is a function to generate reader which converts a non UTF-8 - // charset into UTF-8. - CharsetReader func(string, io.Reader) (io.Reader, error) - - timeLayouts = []string{iso8601, iso8601Z, iso8601Hyphen, iso8601HyphenZ} - invalidXmlError = errors.New("invalid xml") -) - -type TypeMismatchError string - -func (e TypeMismatchError) Error() string { return string(e) } - -type Decoder struct { - *xml.Decoder -} - -func unmarshal(data []byte, v interface{}) (err error) { - dec := &Decoder{xml.NewDecoder(bytes.NewBuffer(data))} - - if CharsetReader != nil { - dec.CharsetReader = CharsetReader - } - - var tok xml.Token - for { - if tok, err = dec.Token(); err != nil { - return err - } - - if t, ok := tok.(xml.StartElement); ok { - if t.Name.Local == "value" { - val := reflect.ValueOf(v) - if val.Kind() != reflect.Ptr { - return errors.New("non-pointer value passed to unmarshal") - } - if err = dec.DecodeValue(val.Elem()); err != nil { - return err - } - - break - } - } - } - - // read until end of document - err = dec.Skip() - if err != nil && err != io.EOF { - return err - } - - return nil -} - -func (dec *Decoder) DecodeValue(val reflect.Value) error { - var tok xml.Token - var err error - - if val.Kind() == reflect.Ptr { - if val.IsNil() { - val.Set(reflect.New(val.Type().Elem())) - } - val = val.Elem() - } - - var typeName string - for { - if tok, err = dec.Token(); err != nil { - return err - } - - if t, ok := tok.(xml.EndElement); ok { - if t.Name.Local == "value" { - return nil - } else { - return invalidXmlError - } - } - - if t, ok := tok.(xml.StartElement); ok { - typeName = t.Name.Local - break - } - - // Treat value data without type identifier as string - if t, ok := tok.(xml.CharData); ok { - if value := strings.TrimSpace(string(t)); value != "" { - if err = checkType(val, reflect.String); err != nil { - return err - } - - val.SetString(value) - return nil - } - } - } - - switch typeName { - case "struct": - ismap := false - pmap := val - valType := val.Type() - - if err = checkType(val, reflect.Struct); err != nil { - if checkType(val, reflect.Map) == nil { - if valType.Key().Kind() != reflect.String { - return fmt.Errorf("only maps with string key type can be unmarshalled") - } - ismap = true - } else if checkType(val, reflect.Interface) == nil && val.IsNil() { - var dummy map[string]interface{} - valType = reflect.TypeOf(dummy) - pmap = reflect.New(valType).Elem() - val.Set(pmap) - ismap = true - } else { - return err - } - } - - var fields map[string]reflect.Value - - if !ismap { - fields = make(map[string]reflect.Value) - - for i := 0; i < valType.NumField(); i++ { - field := valType.Field(i) - fieldVal := val.FieldByName(field.Name) - - if fieldVal.CanSet() { - if fn := field.Tag.Get("xmlrpc"); fn != "" { - fields[fn] = fieldVal - } else { - fields[field.Name] = fieldVal - } - } - } - } else { - // Create initial empty map - pmap.Set(reflect.MakeMap(valType)) - } - - // Process struct members. - StructLoop: - for { - if tok, err = dec.Token(); err != nil { - return err - } - switch t := tok.(type) { - case xml.StartElement: - if t.Name.Local != "member" { - return invalidXmlError - } - - tagName, fieldName, err := dec.readTag() - if err != nil { - return err - } - if tagName != "name" { - return invalidXmlError - } - - var fv reflect.Value - ok := true - - if !ismap { - fv, ok = fields[string(fieldName)] - } else { - fv = reflect.New(valType.Elem()) - } - - if ok { - for { - if tok, err = dec.Token(); err != nil { - return err - } - if t, ok := tok.(xml.StartElement); ok && t.Name.Local == "value" { - if err = dec.DecodeValue(fv); err != nil { - return err - } - - // - if err = dec.Skip(); err != nil { - return err - } - - break - } - } - } - - // - if err = dec.Skip(); err != nil { - return err - } - - if ismap { - pmap.SetMapIndex(reflect.ValueOf(string(fieldName)), reflect.Indirect(fv)) - val.Set(pmap) - } - case xml.EndElement: - break StructLoop - } - } - case "array": - slice := val - if checkType(val, reflect.Interface) == nil && val.IsNil() { - slice = reflect.ValueOf([]interface{}{}) - } else if err = checkType(val, reflect.Slice); err != nil { - return err - } - - ArrayLoop: - for { - if tok, err = dec.Token(); err != nil { - return err - } - - switch t := tok.(type) { - case xml.StartElement: - var index int - if t.Name.Local != "data" { - return invalidXmlError - } - DataLoop: - for { - if tok, err = dec.Token(); err != nil { - return err - } - - switch tt := tok.(type) { - case xml.StartElement: - if tt.Name.Local != "value" { - return invalidXmlError - } - - if index < slice.Len() { - v := slice.Index(index) - if v.Kind() == reflect.Interface { - v = v.Elem() - } - if v.Kind() != reflect.Ptr { - return errors.New("error: cannot write to non-pointer array element") - } - if err = dec.DecodeValue(v); err != nil { - return err - } - } else { - v := reflect.New(slice.Type().Elem()) - if err = dec.DecodeValue(v); err != nil { - return err - } - slice = reflect.Append(slice, v.Elem()) - } - - // - if err = dec.Skip(); err != nil { - return err - } - index++ - case xml.EndElement: - val.Set(slice) - break DataLoop - } - } - case xml.EndElement: - break ArrayLoop - } - } - default: - if tok, err = dec.Token(); err != nil { - return err - } - - var data []byte - - switch t := tok.(type) { - case xml.EndElement: - return nil - case xml.CharData: - data = []byte(t.Copy()) - default: - return invalidXmlError - } - - switch typeName { - case "int", "i4", "i8": - if checkType(val, reflect.Interface) == nil && val.IsNil() { - i, err := strconv.ParseInt(string(data), 10, 64) - if err != nil { - return err - } - - pi := reflect.New(reflect.TypeOf(i)).Elem() - pi.SetInt(i) - val.Set(pi) - } else if err = checkType(val, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64); err != nil { - return err - } else { - i, err := strconv.ParseInt(string(data), 10, val.Type().Bits()) - if err != nil { - return err - } - - val.SetInt(i) - } - case "string", "base64": - str := string(data) - if checkType(val, reflect.Interface) == nil && val.IsNil() { - pstr := reflect.New(reflect.TypeOf(str)).Elem() - pstr.SetString(str) - val.Set(pstr) - } else if err = checkType(val, reflect.String); err != nil { - return err - } else { - val.SetString(str) - } - case "dateTime.iso8601": - var t time.Time - var err error - - for _, layout := range timeLayouts { - t, err = time.Parse(layout, string(data)) - if err == nil { - break - } - } - if err != nil { - return err - } - - if checkType(val, reflect.Interface) == nil && val.IsNil() { - ptime := reflect.New(reflect.TypeOf(t)).Elem() - ptime.Set(reflect.ValueOf(t)) - val.Set(ptime) - } else if _, ok := val.Interface().(time.Time); !ok { - return TypeMismatchError(fmt.Sprintf("error: type mismatch error - can't decode %v to time", val.Kind())) - } else { - val.Set(reflect.ValueOf(t)) - } - case "boolean": - v, err := strconv.ParseBool(string(data)) - if err != nil { - return err - } - - if checkType(val, reflect.Interface) == nil && val.IsNil() { - pv := reflect.New(reflect.TypeOf(v)).Elem() - pv.SetBool(v) - val.Set(pv) - } else if err = checkType(val, reflect.Bool); err != nil { - return err - } else { - val.SetBool(v) - } - case "double": - if checkType(val, reflect.Interface) == nil && val.IsNil() { - i, err := strconv.ParseFloat(string(data), 64) - if err != nil { - return err - } - - pdouble := reflect.New(reflect.TypeOf(i)).Elem() - pdouble.SetFloat(i) - val.Set(pdouble) - } else if err = checkType(val, reflect.Float32, reflect.Float64); err != nil { - return err - } else { - i, err := strconv.ParseFloat(string(data), val.Type().Bits()) - if err != nil { - return err - } - - val.SetFloat(i) - } - default: - return errors.New("unsupported type") - } - - // - if err = dec.Skip(); err != nil { - return err - } - } - - return nil -} - -func (dec *Decoder) readTag() (string, []byte, error) { - var tok xml.Token - var err error - - var name string - for { - if tok, err = dec.Token(); err != nil { - return "", nil, err - } - - if t, ok := tok.(xml.StartElement); ok { - name = t.Name.Local - break - } - } - - value, err := dec.readCharData() - if err != nil { - return "", nil, err - } - - return name, value, dec.Skip() -} - -func (dec *Decoder) readCharData() ([]byte, error) { - var tok xml.Token - var err error - - if tok, err = dec.Token(); err != nil { - return nil, err - } - - if t, ok := tok.(xml.CharData); ok { - return []byte(t.Copy()), nil - } else { - return nil, invalidXmlError - } -} - -func checkType(val reflect.Value, kinds ...reflect.Kind) error { - if len(kinds) == 0 { - return nil - } - - if val.Kind() == reflect.Ptr { - val = val.Elem() - } - - match := false - - for _, kind := range kinds { - if val.Kind() == kind { - match = true - break - } - } - - if !match { - return TypeMismatchError(fmt.Sprintf("error: type mismatch - can't unmarshal %v to %v", - val.Kind(), kinds[0])) - } - - return nil -} diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/encoder.go b/vendor/github.com/uyuni-project/xmlrpc-public-methods/encoder.go deleted file mode 100644 index ba4f2e8..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/encoder.go +++ /dev/null @@ -1,181 +0,0 @@ -package xmlrpc - -import ( - "bytes" - "encoding/xml" - "fmt" - "reflect" - "sort" - "strconv" - "strings" - "time" -) - -// Base64 represents value in base64 encoding -type Base64 string - -type encodeFunc func(reflect.Value) ([]byte, error) - -func Marshal(v interface{}) ([]byte, error) { - if v == nil { - return []byte(""), nil - } - - val := reflect.ValueOf(v) - return encodeValue(val) -} - -func encodeValue(val reflect.Value) ([]byte, error) { - var b []byte - var err error - - if val.Kind() == reflect.Ptr || val.Kind() == reflect.Interface { - if val.IsNil() { - return []byte(""), nil - } - - val = val.Elem() - } - - switch val.Kind() { - case reflect.Struct: - switch val.Interface().(type) { - case time.Time: - t := val.Interface().(time.Time) - b = []byte(fmt.Sprintf("%s", t.Format(iso8601))) - default: - b, err = encodeStruct(val) - } - case reflect.Map: - b, err = encodeMap(val) - case reflect.Slice: - b, err = encodeSlice(val) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - b = []byte(fmt.Sprintf("%s", strconv.FormatInt(val.Int(), 10))) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - b = []byte(fmt.Sprintf("%s", strconv.FormatUint(val.Uint(), 10))) - case reflect.Float32, reflect.Float64: - b = []byte(fmt.Sprintf("%s", - strconv.FormatFloat(val.Float(), 'f', -1, val.Type().Bits()))) - case reflect.Bool: - if val.Bool() { - b = []byte("1") - } else { - b = []byte("0") - } - case reflect.String: - var buf bytes.Buffer - - xml.Escape(&buf, []byte(val.String())) - - if _, ok := val.Interface().(Base64); ok { - b = []byte(fmt.Sprintf("%s", buf.String())) - } else { - b = []byte(fmt.Sprintf("%s", buf.String())) - } - default: - return nil, fmt.Errorf("xmlrpc encode error: unsupported type") - } - - if err != nil { - return nil, err - } - - return []byte(fmt.Sprintf("%s", string(b))), nil -} - -func encodeStruct(structVal reflect.Value) ([]byte, error) { - var b bytes.Buffer - - b.WriteString("") - - structType := structVal.Type() - for i := 0; i < structType.NumField(); i++ { - fieldVal := structVal.Field(i) - fieldType := structType.Field(i) - - name := fieldType.Tag.Get("xmlrpc") - // if the tag has the omitempty property, skip it - if strings.HasSuffix(name, ",omitempty") && isZero(fieldVal) { - continue - } - name = strings.TrimSuffix(name, ",omitempty") - if name == "" { - name = fieldType.Name - } - - p, err := encodeValue(fieldVal) - if err != nil { - return nil, err - } - - b.WriteString("") - b.WriteString(fmt.Sprintf("%s", name)) - b.Write(p) - b.WriteString("") - } - - b.WriteString("") - - return b.Bytes(), nil -} - -var sortMapKeys bool - -func encodeMap(val reflect.Value) ([]byte, error) { - var t = val.Type() - - if t.Key().Kind() != reflect.String { - return nil, fmt.Errorf("xmlrpc encode error: only maps with string keys are supported") - } - - var b bytes.Buffer - - b.WriteString("") - - keys := val.MapKeys() - - if sortMapKeys { - sort.Slice(keys, func(i, j int) bool { return keys[i].String() < keys[j].String() }) - } - - for i := 0; i < val.Len(); i++ { - key := keys[i] - kval := val.MapIndex(key) - - b.WriteString("") - b.WriteString(fmt.Sprintf("%s", key.String())) - - p, err := encodeValue(kval) - - if err != nil { - return nil, err - } - - b.Write(p) - b.WriteString("") - } - - b.WriteString("") - - return b.Bytes(), nil -} - -func encodeSlice(val reflect.Value) ([]byte, error) { - var b bytes.Buffer - - b.WriteString("") - - for i := 0; i < val.Len(); i++ { - p, err := encodeValue(val.Index(i)) - if err != nil { - return nil, err - } - - b.Write(p) - } - - b.WriteString("") - - return b.Bytes(), nil -} diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/is_zero.go b/vendor/github.com/uyuni-project/xmlrpc-public-methods/is_zero.go deleted file mode 100644 index 65276d0..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/is_zero.go +++ /dev/null @@ -1,44 +0,0 @@ -package xmlrpc - -import ( - "math" - . "reflect" -) - -func isZero(v Value) bool { - switch v.Kind() { - case Bool: - return !v.Bool() - case Int, Int8, Int16, Int32, Int64: - return v.Int() == 0 - case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: - return v.Uint() == 0 - case Float32, Float64: - return math.Float64bits(v.Float()) == 0 - case Complex64, Complex128: - c := v.Complex() - return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0 - case Array: - for i := 0; i < v.Len(); i++ { - if !isZero(v.Index(i)) { - return false - } - } - return true - case Chan, Func, Interface, Map, Ptr, Slice, UnsafePointer: - return v.IsNil() - case String: - return v.Len() == 0 - case Struct: - for i := 0; i < v.NumField(); i++ { - if !isZero(v.Field(i)) { - return false - } - } - return true - default: - // This should never happens, but will act as a safeguard for - // later, as a default value doesn't makes sense here. - panic(&ValueError{"reflect.Value.IsZero", v.Kind()}) - } -} diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/request.go b/vendor/github.com/uyuni-project/xmlrpc-public-methods/request.go deleted file mode 100644 index 4d6a270..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/request.go +++ /dev/null @@ -1,57 +0,0 @@ -package xmlrpc - -import ( - "bytes" - "fmt" - "net/http" -) - -func NewRequest(url string, method string, args interface{}) (*http.Request, error) { - var t []interface{} - var ok bool - if t, ok = args.([]interface{}); !ok { - if args != nil { - t = []interface{}{args} - } - } - - body, err := EncodeMethodCall(method, t...) - if err != nil { - return nil, err - } - - request, err := http.NewRequest("POST", url, bytes.NewReader(body)) - if err != nil { - return nil, err - } - - request.Header.Set("Content-Type", "text/xml") - request.Header.Set("Content-Length", fmt.Sprintf("%d", len(body))) - - return request, nil -} - -func EncodeMethodCall(method string, args ...interface{}) ([]byte, error) { - var b bytes.Buffer - b.WriteString(``) - b.WriteString(fmt.Sprintf("%s", method)) - - if args != nil { - b.WriteString("") - - for _, arg := range args { - p, err := Marshal(arg) - if err != nil { - return nil, err - } - - b.WriteString(fmt.Sprintf("%s", string(p))) - } - - b.WriteString("") - } - - b.WriteString("") - - return b.Bytes(), nil -} diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/response.go b/vendor/github.com/uyuni-project/xmlrpc-public-methods/response.go deleted file mode 100644 index 18e6d36..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/response.go +++ /dev/null @@ -1,42 +0,0 @@ -package xmlrpc - -import ( - "fmt" - "regexp" -) - -var ( - faultRx = regexp.MustCompile(`(\s|\S)+`) -) - -// FaultError is returned from the server when an invalid call is made -type FaultError struct { - Code int `xmlrpc:"faultCode"` - String string `xmlrpc:"faultString"` -} - -// Error implements the error interface -func (e FaultError) Error() string { - return fmt.Sprintf("Fault(%d): %s", e.Code, e.String) -} - -type Response []byte - -func (r Response) Err() error { - if !faultRx.Match(r) { - return nil - } - var fault FaultError - if err := unmarshal(r, &fault); err != nil { - return err - } - return fault -} - -func (r Response) Unmarshal(v interface{}) error { - if err := unmarshal(r, v); err != nil { - return err - } - - return nil -} diff --git a/vendor/github.com/uyuni-project/xmlrpc-public-methods/test_server.rb b/vendor/github.com/uyuni-project/xmlrpc-public-methods/test_server.rb deleted file mode 100644 index 1ccfc9a..0000000 --- a/vendor/github.com/uyuni-project/xmlrpc-public-methods/test_server.rb +++ /dev/null @@ -1,25 +0,0 @@ -# encoding: utf-8 - -require "xmlrpc/server" - -class Service - def time - Time.now - end - - def upcase(s) - s.upcase - end - - def sum(x, y) - x + y - end - - def error - raise XMLRPC::FaultException.new(500, "Server error") - end -end - -server = XMLRPC::Server.new 5001, 'localhost' -server.add_handler "service", Service.new -server.serve diff --git a/vendor/modules.txt b/vendor/modules.txt deleted file mode 100644 index 0ba3972..0000000 --- a/vendor/modules.txt +++ /dev/null @@ -1,14 +0,0 @@ -# github.com/gorilla/rpc v1.2.0 -## explicit -github.com/gorilla/rpc -# github.com/knadh/koanf v0.10.0 -## explicit -github.com/knadh/koanf -github.com/knadh/koanf/maps -github.com/knadh/koanf/providers/confmap -github.com/knadh/koanf/providers/env -# github.com/mitchellh/mapstructure v1.2.2 -github.com/mitchellh/mapstructure -# github.com/uyuni-project/xmlrpc-public-methods v0.0.0-20200805144514-2ca831c526d1 -## explicit -github.com/uyuni-project/xmlrpc-public-methods