mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
Release 3.0.0 Candidate (#699)
Final changes before V3.0.0 release * Remove old Gandi. Fixes #575 * Many cleanups * go mod tidy && go mod vendor * integration_test.go: Output subtest name * Cleanups * integration_test.go: Description should include sub-test name * Add a whitespace test to js/parse_tests/017-txt.js * Cloudflare strips whitespace from end of TXT * Fixes https://github.com/StackExchange/dnscontrol/issues/700 * Whitespace at end of TXT records Name.com strips the whitespace from the end of a TXT record. There's nothing we can do other than file a bug. * Fixes https://github.com/StackExchange/dnscontrol/issues/701
This commit is contained in:
9
vendor/github.com/google/uuid/.travis.yml
generated
vendored
9
vendor/github.com/google/uuid/.travis.yml
generated
vendored
@ -1,9 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.4.3
|
||||
- 1.5.3
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v ./...
|
10
vendor/github.com/google/uuid/CONTRIBUTING.md
generated
vendored
10
vendor/github.com/google/uuid/CONTRIBUTING.md
generated
vendored
@ -1,10 +0,0 @@
|
||||
# How to contribute
|
||||
|
||||
We definitely welcome patches and contribution to this project!
|
||||
|
||||
### Legal requirements
|
||||
|
||||
In order to protect both you and ourselves, you will need to sign the
|
||||
[Contributor License Agreement](https://cla.developers.google.com/clas).
|
||||
|
||||
You may have already signed it for other Google projects.
|
9
vendor/github.com/google/uuid/CONTRIBUTORS
generated
vendored
9
vendor/github.com/google/uuid/CONTRIBUTORS
generated
vendored
@ -1,9 +0,0 @@
|
||||
Paul Borman <borman@google.com>
|
||||
bmatsuo
|
||||
shawnps
|
||||
theory
|
||||
jboverfelt
|
||||
dsymonds
|
||||
cd1
|
||||
wallclockbuilder
|
||||
dansouza
|
27
vendor/github.com/google/uuid/LICENSE
generated
vendored
27
vendor/github.com/google/uuid/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2009,2014 Google Inc. 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.
|
19
vendor/github.com/google/uuid/README.md
generated
vendored
19
vendor/github.com/google/uuid/README.md
generated
vendored
@ -1,19 +0,0 @@
|
||||
# uuid 
|
||||
The uuid package generates and inspects UUIDs based on
|
||||
[RFC 4122](http://tools.ietf.org/html/rfc4122)
|
||||
and DCE 1.1: Authentication and Security Services.
|
||||
|
||||
This package is based on the github.com/pborman/uuid package (previously named
|
||||
code.google.com/p/go-uuid). It differs from these earlier packages in that
|
||||
a UUID is a 16 byte array rather than a byte slice. One loss due to this
|
||||
change is the ability to represent an invalid UUID (vs a NIL UUID).
|
||||
|
||||
###### Install
|
||||
`go get github.com/google/uuid`
|
||||
|
||||
###### Documentation
|
||||
[](http://godoc.org/github.com/google/uuid)
|
||||
|
||||
Full `go doc` style documentation for the package can be viewed online without
|
||||
installing this package by using the GoDoc site here:
|
||||
http://godoc.org/github.com/google/uuid
|
80
vendor/github.com/google/uuid/dce.go
generated
vendored
80
vendor/github.com/google/uuid/dce.go
generated
vendored
@ -1,80 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// A Domain represents a Version 2 domain
|
||||
type Domain byte
|
||||
|
||||
// Domain constants for DCE Security (Version 2) UUIDs.
|
||||
const (
|
||||
Person = Domain(0)
|
||||
Group = Domain(1)
|
||||
Org = Domain(2)
|
||||
)
|
||||
|
||||
// NewDCESecurity returns a DCE Security (Version 2) UUID.
|
||||
//
|
||||
// The domain should be one of Person, Group or Org.
|
||||
// On a POSIX system the id should be the users UID for the Person
|
||||
// domain and the users GID for the Group. The meaning of id for
|
||||
// the domain Org or on non-POSIX systems is site defined.
|
||||
//
|
||||
// For a given domain/id pair the same token may be returned for up to
|
||||
// 7 minutes and 10 seconds.
|
||||
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
|
||||
uuid, err := NewUUID()
|
||||
if err == nil {
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
|
||||
uuid[9] = byte(domain)
|
||||
binary.BigEndian.PutUint32(uuid[0:], id)
|
||||
}
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
|
||||
// domain with the id returned by os.Getuid.
|
||||
//
|
||||
// NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
func NewDCEPerson() (UUID, error) {
|
||||
return NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
}
|
||||
|
||||
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
|
||||
// domain with the id returned by os.Getgid.
|
||||
//
|
||||
// NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
func NewDCEGroup() (UUID, error) {
|
||||
return NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
}
|
||||
|
||||
// Domain returns the domain for a Version 2 UUID. Domains are only defined
|
||||
// for Version 2 UUIDs.
|
||||
func (uuid UUID) Domain() Domain {
|
||||
return Domain(uuid[9])
|
||||
}
|
||||
|
||||
// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
|
||||
// UUIDs.
|
||||
func (uuid UUID) ID() uint32 {
|
||||
return binary.BigEndian.Uint32(uuid[0:4])
|
||||
}
|
||||
|
||||
func (d Domain) String() string {
|
||||
switch d {
|
||||
case Person:
|
||||
return "Person"
|
||||
case Group:
|
||||
return "Group"
|
||||
case Org:
|
||||
return "Org"
|
||||
}
|
||||
return fmt.Sprintf("Domain%d", int(d))
|
||||
}
|
12
vendor/github.com/google/uuid/doc.go
generated
vendored
12
vendor/github.com/google/uuid/doc.go
generated
vendored
@ -1,12 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package uuid generates and inspects UUIDs.
|
||||
//
|
||||
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security
|
||||
// Services.
|
||||
//
|
||||
// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to
|
||||
// maps or compared directly.
|
||||
package uuid
|
1
vendor/github.com/google/uuid/go.mod
generated
vendored
1
vendor/github.com/google/uuid/go.mod
generated
vendored
@ -1 +0,0 @@
|
||||
module github.com/google/uuid
|
53
vendor/github.com/google/uuid/hash.go
generated
vendored
53
vendor/github.com/google/uuid/hash.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// Well known namespace IDs and UUIDs
|
||||
var (
|
||||
NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
|
||||
Nil UUID // empty UUID, all zeros
|
||||
)
|
||||
|
||||
// NewHash returns a new UUID derived from the hash of space concatenated with
|
||||
// data generated by h. The hash should be at least 16 byte in length. The
|
||||
// first 16 bytes of the hash are used to form the UUID. The version of the
|
||||
// UUID will be the lower 4 bits of version. NewHash is used to implement
|
||||
// NewMD5 and NewSHA1.
|
||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||
h.Reset()
|
||||
h.Write(space[:])
|
||||
h.Write(data)
|
||||
s := h.Sum(nil)
|
||||
var uuid UUID
|
||||
copy(uuid[:], s)
|
||||
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
|
||||
return uuid
|
||||
}
|
||||
|
||||
// NewMD5 returns a new MD5 (Version 3) UUID based on the
|
||||
// supplied name space and data. It is the same as calling:
|
||||
//
|
||||
// NewHash(md5.New(), space, data, 3)
|
||||
func NewMD5(space UUID, data []byte) UUID {
|
||||
return NewHash(md5.New(), space, data, 3)
|
||||
}
|
||||
|
||||
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
|
||||
// supplied name space and data. It is the same as calling:
|
||||
//
|
||||
// NewHash(sha1.New(), space, data, 5)
|
||||
func NewSHA1(space UUID, data []byte) UUID {
|
||||
return NewHash(sha1.New(), space, data, 5)
|
||||
}
|
37
vendor/github.com/google/uuid/marshal.go
generated
vendored
37
vendor/github.com/google/uuid/marshal.go
generated
vendored
@ -1,37 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import "fmt"
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (uuid UUID) MarshalText() ([]byte, error) {
|
||||
var js [36]byte
|
||||
encodeHex(js[:], uuid)
|
||||
return js[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (uuid *UUID) UnmarshalText(data []byte) error {
|
||||
id, err := ParseBytes(data)
|
||||
if err == nil {
|
||||
*uuid = id
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler.
|
||||
func (uuid UUID) MarshalBinary() ([]byte, error) {
|
||||
return uuid[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
||||
func (uuid *UUID) UnmarshalBinary(data []byte) error {
|
||||
if len(data) != 16 {
|
||||
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
|
||||
}
|
||||
copy(uuid[:], data)
|
||||
return nil
|
||||
}
|
90
vendor/github.com/google/uuid/node.go
generated
vendored
90
vendor/github.com/google/uuid/node.go
generated
vendored
@ -1,90 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
nodeMu sync.Mutex
|
||||
ifname string // name of interface being used
|
||||
nodeID [6]byte // hardware for version 1 UUIDs
|
||||
zeroID [6]byte // nodeID with only 0's
|
||||
)
|
||||
|
||||
// NodeInterface returns the name of the interface from which the NodeID was
|
||||
// derived. The interface "user" is returned if the NodeID was set by
|
||||
// SetNodeID.
|
||||
func NodeInterface() string {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
return ifname
|
||||
}
|
||||
|
||||
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
|
||||
// If name is "" then the first usable interface found will be used or a random
|
||||
// Node ID will be generated. If a named interface cannot be found then false
|
||||
// is returned.
|
||||
//
|
||||
// SetNodeInterface never fails when name is "".
|
||||
func SetNodeInterface(name string) bool {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
return setNodeInterface(name)
|
||||
}
|
||||
|
||||
func setNodeInterface(name string) bool {
|
||||
iname, addr := getHardwareInterface(name) // null implementation for js
|
||||
if iname != "" && addr != nil {
|
||||
ifname = iname
|
||||
copy(nodeID[:], addr)
|
||||
return true
|
||||
}
|
||||
|
||||
// We found no interfaces with a valid hardware address. If name
|
||||
// does not specify a specific interface generate a random Node ID
|
||||
// (section 4.1.6)
|
||||
if name == "" {
|
||||
ifname = "random"
|
||||
randomBits(nodeID[:])
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
|
||||
// if not already set.
|
||||
func NodeID() []byte {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
if nodeID == zeroID {
|
||||
setNodeInterface("")
|
||||
}
|
||||
nid := nodeID
|
||||
return nid[:]
|
||||
}
|
||||
|
||||
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
|
||||
// of id are used. If id is less than 6 bytes then false is returned and the
|
||||
// Node ID is not set.
|
||||
func SetNodeID(id []byte) bool {
|
||||
if len(id) < 6 {
|
||||
return false
|
||||
}
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
copy(nodeID[:], id)
|
||||
ifname = "user"
|
||||
return true
|
||||
}
|
||||
|
||||
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
|
||||
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) NodeID() []byte {
|
||||
var node [6]byte
|
||||
copy(node[:], uuid[10:])
|
||||
return node[:]
|
||||
}
|
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
@ -1,12 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build js
|
||||
|
||||
package uuid
|
||||
|
||||
// getHardwareInterface returns nil values for the JS version of the code.
|
||||
// This remvoves the "net" dependency, because it is not used in the browser.
|
||||
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
|
||||
func getHardwareInterface(name string) (string, []byte) { return "", nil }
|
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !js
|
||||
|
||||
package uuid
|
||||
|
||||
import "net"
|
||||
|
||||
var interfaces []net.Interface // cached list of interfaces
|
||||
|
||||
// getHardwareInterface returns the name and hardware address of interface name.
|
||||
// If name is "" then the name and hardware address of one of the system's
|
||||
// interfaces is returned. If no interfaces are found (name does not exist or
|
||||
// there are no interfaces) then "", nil is returned.
|
||||
//
|
||||
// Only addresses of at least 6 bytes are returned.
|
||||
func getHardwareInterface(name string) (string, []byte) {
|
||||
if interfaces == nil {
|
||||
var err error
|
||||
interfaces, err = net.Interfaces()
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
for _, ifs := range interfaces {
|
||||
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
|
||||
return ifs.Name, ifs.HardwareAddr
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
59
vendor/github.com/google/uuid/sql.go
generated
vendored
59
vendor/github.com/google/uuid/sql.go
generated
vendored
@ -1,59 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
|
||||
// Currently, database types that map to string and []byte are supported. Please
|
||||
// consult database-specific driver documentation for matching types.
|
||||
func (uuid *UUID) Scan(src interface{}) error {
|
||||
switch src := src.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
|
||||
case string:
|
||||
// if an empty UUID comes from a table, we return a null UUID
|
||||
if src == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// see Parse for required string format
|
||||
u, err := Parse(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Scan: %v", err)
|
||||
}
|
||||
|
||||
*uuid = u
|
||||
|
||||
case []byte:
|
||||
// if an empty UUID comes from a table, we return a null UUID
|
||||
if len(src) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// assumes a simple slice of bytes if 16 bytes
|
||||
// otherwise attempts to parse
|
||||
if len(src) != 16 {
|
||||
return uuid.Scan(string(src))
|
||||
}
|
||||
copy((*uuid)[:], src)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements sql.Valuer so that UUIDs can be written to databases
|
||||
// transparently. Currently, UUIDs map to strings. Please consult
|
||||
// database-specific driver documentation for matching types.
|
||||
func (uuid UUID) Value() (driver.Value, error) {
|
||||
return uuid.String(), nil
|
||||
}
|
123
vendor/github.com/google/uuid/time.go
generated
vendored
123
vendor/github.com/google/uuid/time.go
generated
vendored
@ -1,123 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
|
||||
// 1582.
|
||||
type Time int64
|
||||
|
||||
const (
|
||||
lillian = 2299160 // Julian day of 15 Oct 1582
|
||||
unix = 2440587 // Julian day of 1 Jan 1970
|
||||
epoch = unix - lillian // Days between epochs
|
||||
g1582 = epoch * 86400 // seconds between epochs
|
||||
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
|
||||
)
|
||||
|
||||
var (
|
||||
timeMu sync.Mutex
|
||||
lasttime uint64 // last time we returned
|
||||
clockSeq uint16 // clock sequence for this run
|
||||
|
||||
timeNow = time.Now // for testing
|
||||
)
|
||||
|
||||
// UnixTime converts t the number of seconds and nanoseconds using the Unix
|
||||
// epoch of 1 Jan 1970.
|
||||
func (t Time) UnixTime() (sec, nsec int64) {
|
||||
sec = int64(t - g1582ns100)
|
||||
nsec = (sec % 10000000) * 100
|
||||
sec /= 10000000
|
||||
return sec, nsec
|
||||
}
|
||||
|
||||
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
|
||||
// clock sequence as well as adjusting the clock sequence as needed. An error
|
||||
// is returned if the current time cannot be determined.
|
||||
func GetTime() (Time, uint16, error) {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
return getTime()
|
||||
}
|
||||
|
||||
func getTime() (Time, uint16, error) {
|
||||
t := timeNow()
|
||||
|
||||
// If we don't have a clock sequence already, set one.
|
||||
if clockSeq == 0 {
|
||||
setClockSequence(-1)
|
||||
}
|
||||
now := uint64(t.UnixNano()/100) + g1582ns100
|
||||
|
||||
// If time has gone backwards with this clock sequence then we
|
||||
// increment the clock sequence
|
||||
if now <= lasttime {
|
||||
clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000
|
||||
}
|
||||
lasttime = now
|
||||
return Time(now), clockSeq, nil
|
||||
}
|
||||
|
||||
// ClockSequence returns the current clock sequence, generating one if not
|
||||
// already set. The clock sequence is only used for Version 1 UUIDs.
|
||||
//
|
||||
// The uuid package does not use global static storage for the clock sequence or
|
||||
// the last time a UUID was generated. Unless SetClockSequence is used, a new
|
||||
// random clock sequence is generated the first time a clock sequence is
|
||||
// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1)
|
||||
func ClockSequence() int {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
return clockSequence()
|
||||
}
|
||||
|
||||
func clockSequence() int {
|
||||
if clockSeq == 0 {
|
||||
setClockSequence(-1)
|
||||
}
|
||||
return int(clockSeq & 0x3fff)
|
||||
}
|
||||
|
||||
// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to
|
||||
// -1 causes a new sequence to be generated.
|
||||
func SetClockSequence(seq int) {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
setClockSequence(seq)
|
||||
}
|
||||
|
||||
func setClockSequence(seq int) {
|
||||
if seq == -1 {
|
||||
var b [2]byte
|
||||
randomBits(b[:]) // clock sequence
|
||||
seq = int(b[0])<<8 | int(b[1])
|
||||
}
|
||||
oldSeq := clockSeq
|
||||
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
|
||||
if oldSeq != clockSeq {
|
||||
lasttime = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
|
||||
// uuid. The time is only defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) Time() Time {
|
||||
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
|
||||
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
|
||||
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
|
||||
return Time(time)
|
||||
}
|
||||
|
||||
// ClockSequence returns the clock sequence encoded in uuid.
|
||||
// The clock sequence is only well defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) ClockSequence() int {
|
||||
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff
|
||||
}
|
43
vendor/github.com/google/uuid/util.go
generated
vendored
43
vendor/github.com/google/uuid/util.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// randomBits completely fills slice b with random data.
|
||||
func randomBits(b []byte) {
|
||||
if _, err := io.ReadFull(rander, b); err != nil {
|
||||
panic(err.Error()) // rand should never fail
|
||||
}
|
||||
}
|
||||
|
||||
// xvalues returns the value of a byte as a hexadecimal digit or 255.
|
||||
var xvalues = [256]byte{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
|
||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
}
|
||||
|
||||
// xtob converts hex characters x1 and x2 into a byte.
|
||||
func xtob(x1, x2 byte) (byte, bool) {
|
||||
b1 := xvalues[x1]
|
||||
b2 := xvalues[x2]
|
||||
return (b1 << 4) | b2, b1 != 255 && b2 != 255
|
||||
}
|
245
vendor/github.com/google/uuid/uuid.go
generated
vendored
245
vendor/github.com/google/uuid/uuid.go
generated
vendored
@ -1,245 +0,0 @@
|
||||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
|
||||
// 4122.
|
||||
type UUID [16]byte
|
||||
|
||||
// A Version represents a UUID's version.
|
||||
type Version byte
|
||||
|
||||
// A Variant represents a UUID's variant.
|
||||
type Variant byte
|
||||
|
||||
// Constants returned by Variant.
|
||||
const (
|
||||
Invalid = Variant(iota) // Invalid UUID
|
||||
RFC4122 // The variant specified in RFC4122
|
||||
Reserved // Reserved, NCS backward compatibility.
|
||||
Microsoft // Reserved, Microsoft Corporation backward compatibility.
|
||||
Future // Reserved for future definition.
|
||||
)
|
||||
|
||||
var rander = rand.Reader // random function
|
||||
|
||||
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
||||
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
|
||||
// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex
|
||||
// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
|
||||
func Parse(s string) (UUID, error) {
|
||||
var uuid UUID
|
||||
switch len(s) {
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36:
|
||||
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9:
|
||||
if strings.ToLower(s[:9]) != "urn:uuid:" {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
|
||||
}
|
||||
s = s[9:]
|
||||
|
||||
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
case 36 + 2:
|
||||
s = s[1:]
|
||||
|
||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
case 32:
|
||||
var ok bool
|
||||
for i := range uuid {
|
||||
uuid[i], ok = xtob(s[i*2], s[i*2+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
for i, x := range [16]int{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34} {
|
||||
v, ok := xtob(s[x], s[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
uuid[i] = v
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// ParseBytes is like Parse, except it parses a byte slice instead of a string.
|
||||
func ParseBytes(b []byte) (UUID, error) {
|
||||
var uuid UUID
|
||||
switch len(b) {
|
||||
case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
|
||||
}
|
||||
b = b[9:]
|
||||
case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
b = b[1:]
|
||||
case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
var ok bool
|
||||
for i := 0; i < 32; i += 2 {
|
||||
uuid[i/2], ok = xtob(b[i], b[i+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
for i, x := range [16]int{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34} {
|
||||
v, ok := xtob(b[x], b[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
uuid[i] = v
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// MustParse is like Parse but panics if the string cannot be parsed.
|
||||
// It simplifies safe initialization of global variables holding compiled UUIDs.
|
||||
func MustParse(s string) UUID {
|
||||
uuid, err := Parse(s)
|
||||
if err != nil {
|
||||
panic(`uuid: Parse(` + s + `): ` + err.Error())
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
|
||||
// does not have a length of 16. The bytes are copied from the slice.
|
||||
func FromBytes(b []byte) (uuid UUID, err error) {
|
||||
err = uuid.UnmarshalBinary(b)
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
// Must returns uuid if err is nil and panics otherwise.
|
||||
func Must(uuid UUID, err error) UUID {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
// , or "" if uuid is invalid.
|
||||
func (uuid UUID) String() string {
|
||||
var buf [36]byte
|
||||
encodeHex(buf[:], uuid)
|
||||
return string(buf[:])
|
||||
}
|
||||
|
||||
// URN returns the RFC 2141 URN form of uuid,
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
|
||||
func (uuid UUID) URN() string {
|
||||
var buf [36 + 9]byte
|
||||
copy(buf[:], "urn:uuid:")
|
||||
encodeHex(buf[9:], uuid)
|
||||
return string(buf[:])
|
||||
}
|
||||
|
||||
func encodeHex(dst []byte, uuid UUID) {
|
||||
hex.Encode(dst, uuid[:4])
|
||||
dst[8] = '-'
|
||||
hex.Encode(dst[9:13], uuid[4:6])
|
||||
dst[13] = '-'
|
||||
hex.Encode(dst[14:18], uuid[6:8])
|
||||
dst[18] = '-'
|
||||
hex.Encode(dst[19:23], uuid[8:10])
|
||||
dst[23] = '-'
|
||||
hex.Encode(dst[24:], uuid[10:])
|
||||
}
|
||||
|
||||
// Variant returns the variant encoded in uuid.
|
||||
func (uuid UUID) Variant() Variant {
|
||||
switch {
|
||||
case (uuid[8] & 0xc0) == 0x80:
|
||||
return RFC4122
|
||||
case (uuid[8] & 0xe0) == 0xc0:
|
||||
return Microsoft
|
||||
case (uuid[8] & 0xe0) == 0xe0:
|
||||
return Future
|
||||
default:
|
||||
return Reserved
|
||||
}
|
||||
}
|
||||
|
||||
// Version returns the version of uuid.
|
||||
func (uuid UUID) Version() Version {
|
||||
return Version(uuid[6] >> 4)
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
if v > 15 {
|
||||
return fmt.Sprintf("BAD_VERSION_%d", v)
|
||||
}
|
||||
return fmt.Sprintf("VERSION_%d", v)
|
||||
}
|
||||
|
||||
func (v Variant) String() string {
|
||||
switch v {
|
||||
case RFC4122:
|
||||
return "RFC4122"
|
||||
case Reserved:
|
||||
return "Reserved"
|
||||
case Microsoft:
|
||||
return "Microsoft"
|
||||
case Future:
|
||||
return "Future"
|
||||
case Invalid:
|
||||
return "Invalid"
|
||||
}
|
||||
return fmt.Sprintf("BadVariant%d", int(v))
|
||||
}
|
||||
|
||||
// SetRand sets the random number generator to r, which implements io.Reader.
|
||||
// If r.Read returns an error when the package requests random data then
|
||||
// a panic will be issued.
|
||||
//
|
||||
// Calling SetRand with nil sets the random number generator to the default
|
||||
// generator.
|
||||
func SetRand(r io.Reader) {
|
||||
if r == nil {
|
||||
rander = rand.Reader
|
||||
return
|
||||
}
|
||||
rander = r
|
||||
}
|
44
vendor/github.com/google/uuid/version1.go
generated
vendored
44
vendor/github.com/google/uuid/version1.go
generated
vendored
@ -1,44 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
|
||||
// sequence, and the current time. If the NodeID has not been set by SetNodeID
|
||||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
|
||||
// be set NewUUID returns nil. If clock sequence has not been set by
|
||||
// SetClockSequence then it will be set automatically. If GetTime fails to
|
||||
// return the current NewUUID returns nil and an error.
|
||||
//
|
||||
// In most cases, New should be used.
|
||||
func NewUUID() (UUID, error) {
|
||||
nodeMu.Lock()
|
||||
if nodeID == zeroID {
|
||||
setNodeInterface("")
|
||||
}
|
||||
nodeMu.Unlock()
|
||||
|
||||
var uuid UUID
|
||||
now, seq, err := GetTime()
|
||||
if err != nil {
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
timeLow := uint32(now & 0xffffffff)
|
||||
timeMid := uint16((now >> 32) & 0xffff)
|
||||
timeHi := uint16((now >> 48) & 0x0fff)
|
||||
timeHi |= 0x1000 // Version 1
|
||||
|
||||
binary.BigEndian.PutUint32(uuid[0:], timeLow)
|
||||
binary.BigEndian.PutUint16(uuid[4:], timeMid)
|
||||
binary.BigEndian.PutUint16(uuid[6:], timeHi)
|
||||
binary.BigEndian.PutUint16(uuid[8:], seq)
|
||||
copy(uuid[10:], nodeID[:])
|
||||
|
||||
return uuid, nil
|
||||
}
|
43
vendor/github.com/google/uuid/version4.go
generated
vendored
43
vendor/github.com/google/uuid/version4.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import "io"
|
||||
|
||||
// New creates a new random UUID or panics. New is equivalent to
|
||||
// the expression
|
||||
//
|
||||
// uuid.Must(uuid.NewRandom())
|
||||
func New() UUID {
|
||||
return Must(NewRandom())
|
||||
}
|
||||
|
||||
// NewRandom returns a Random (Version 4) UUID.
|
||||
//
|
||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||
// package.
|
||||
//
|
||||
// A note about uniqueness derived from the UUID Wikipedia entry:
|
||||
//
|
||||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
||||
// hit by a meteorite is estimated to be one chance in 17 billion, that
|
||||
// means the probability is about 0.00000000006 (6 × 10−11),
|
||||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
|
||||
// year and having one duplicate.
|
||||
func NewRandom() (UUID, error) {
|
||||
return NewRandomFromReader(rander)
|
||||
}
|
||||
|
||||
func NewRandomFromReader(r io.Reader) (UUID, error) {
|
||||
var uuid UUID
|
||||
_, err := io.ReadFull(r, uuid[:])
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
||||
return uuid, nil
|
||||
}
|
||||
|
19
vendor/github.com/kolo/xmlrpc/LICENSE
generated
vendored
19
vendor/github.com/kolo/xmlrpc/LICENSE
generated
vendored
@ -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.
|
79
vendor/github.com/kolo/xmlrpc/README.md
generated
vendored
79
vendor/github.com/kolo/xmlrpc/README.md
generated
vendored
@ -1,79 +0,0 @@
|
||||
## Overview
|
||||
|
||||
xmlrpc is an implementation of client side part of XMLRPC protocol in Go language.
|
||||
|
||||
## 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 decoded to array;
|
||||
|
||||
Structs decoded 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.
|
||||
|
||||
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
|
||||
|
||||
Feel free to fork the project, submit pull requests, ask questions.
|
||||
|
||||
## Authors
|
||||
|
||||
Dmitry Maksimov (dmtmax@gmail.com)
|
144
vendor/github.com/kolo/xmlrpc/client.go
generated
vendored
144
vendor/github.com/kolo/xmlrpc/client.go
generated
vendored
@ -1,144 +0,0 @@
|
||||
package xmlrpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/rpc"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
response *Response
|
||||
|
||||
// ready presents channel, that is used to link request and it`s response.
|
||||
ready chan uint64
|
||||
}
|
||||
|
||||
func (codec *clientCodec) WriteRequest(request *rpc.Request, args interface{}) (err error) {
|
||||
httpRequest, err := NewRequest(codec.url.String(), request.ServiceMethod, args)
|
||||
|
||||
if codec.cookies != nil {
|
||||
for _, cookie := range codec.cookies.Cookies(codec.url) {
|
||||
httpRequest.AddCookie(cookie)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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.responses[request.Seq] = httpResponse
|
||||
codec.ready <- request.Seq
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (codec *clientCodec) ReadResponseHeader(response *rpc.Response) (err error) {
|
||||
seq := <-codec.ready
|
||||
httpResponse := codec.responses[seq]
|
||||
|
||||
if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 {
|
||||
return fmt.Errorf("request error: bad status code - %d", httpResponse.StatusCode)
|
||||
}
|
||||
|
||||
respData, err := ioutil.ReadAll(httpResponse.Body)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
httpResponse.Body.Close()
|
||||
|
||||
resp := NewResponse(respData)
|
||||
|
||||
if resp.Failed() {
|
||||
response.Error = fmt.Sprintf("%v", resp.Err())
|
||||
}
|
||||
|
||||
codec.response = resp
|
||||
|
||||
response.Seq = seq
|
||||
delete(codec.responses, seq)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (codec *clientCodec) ReadResponseBody(v interface{}) (err error) {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = codec.response.Unmarshal(v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (codec *clientCodec) Close() error {
|
||||
transport := codec.httpClient.Transport.(*http.Transport)
|
||||
transport.CloseIdleConnections()
|
||||
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,
|
||||
ready: make(chan uint64),
|
||||
responses: make(map[uint64]*http.Response),
|
||||
cookies: jar,
|
||||
}
|
||||
|
||||
return &Client{rpc.NewClientWithCodec(&codec)}, nil
|
||||
}
|
449
vendor/github.com/kolo/xmlrpc/decoder.go
generated
vendored
449
vendor/github.com/kolo/xmlrpc/decoder.go
generated
vendored
@ -1,449 +0,0 @@
|
||||
package xmlrpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const iso8601 = "20060102T15:04:05"
|
||||
|
||||
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)
|
||||
|
||||
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{}
|
||||
pmap = reflect.New(reflect.TypeOf(dummy)).Elem()
|
||||
valType = pmap.Type()
|
||||
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
|
||||
}
|
||||
|
||||
// </value>
|
||||
if err = dec.Skip(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// </member>
|
||||
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":
|
||||
pslice := val
|
||||
if checkType(val, reflect.Interface) == nil && val.IsNil() {
|
||||
var dummy []interface{}
|
||||
pslice = reflect.New(reflect.TypeOf(dummy)).Elem()
|
||||
} 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:
|
||||
if t.Name.Local != "data" {
|
||||
return invalidXmlError
|
||||
}
|
||||
|
||||
slice := reflect.MakeSlice(pslice.Type(), 0, 0)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
v := reflect.New(pslice.Type().Elem())
|
||||
if err = dec.decodeValue(v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
slice = reflect.Append(slice, v.Elem())
|
||||
|
||||
// </value>
|
||||
if err = dec.Skip(); err != nil {
|
||||
return err
|
||||
}
|
||||
case xml.EndElement:
|
||||
pslice.Set(slice)
|
||||
val.Set(pslice)
|
||||
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":
|
||||
t, err := time.Parse(iso8601, string(data))
|
||||
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")
|
||||
}
|
||||
|
||||
// </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
|
||||
}
|
164
vendor/github.com/kolo/xmlrpc/encoder.go
generated
vendored
164
vendor/github.com/kolo/xmlrpc/encoder.go
generated
vendored
@ -1,164 +0,0 @@
|
||||
package xmlrpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
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("<value/>"), 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("<dateTime.iso8601>%s</dateTime.iso8601>", 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("<int>%s</int>", strconv.FormatInt(val.Int(), 10)))
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
b = []byte(fmt.Sprintf("<i4>%s</i4>", strconv.FormatUint(val.Uint(), 10)))
|
||||
case reflect.Float32, reflect.Float64:
|
||||
b = []byte(fmt.Sprintf("<double>%s</double>",
|
||||
strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits())))
|
||||
case reflect.Bool:
|
||||
if val.Bool() {
|
||||
b = []byte("<boolean>1</boolean>")
|
||||
} else {
|
||||
b = []byte("<boolean>0</boolean>")
|
||||
}
|
||||
case reflect.String:
|
||||
var buf bytes.Buffer
|
||||
|
||||
xml.Escape(&buf, []byte(val.String()))
|
||||
|
||||
if _, ok := val.Interface().(Base64); ok {
|
||||
b = []byte(fmt.Sprintf("<base64>%s</base64>", buf.String()))
|
||||
} else {
|
||||
b = []byte(fmt.Sprintf("<string>%s</string>", buf.String()))
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("xmlrpc encode error: unsupported type")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []byte(fmt.Sprintf("<value>%s</value>", string(b))), nil
|
||||
}
|
||||
|
||||
func encodeStruct(val reflect.Value) ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
|
||||
b.WriteString("<struct>")
|
||||
|
||||
t := val.Type()
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
b.WriteString("<member>")
|
||||
f := t.Field(i)
|
||||
|
||||
name := f.Tag.Get("xmlrpc")
|
||||
if name == "" {
|
||||
name = f.Name
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("<name>%s</name>", name))
|
||||
|
||||
p, err := encodeValue(val.FieldByName(f.Name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.Write(p)
|
||||
|
||||
b.WriteString("</member>")
|
||||
}
|
||||
|
||||
b.WriteString("</struct>")
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
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("<struct>")
|
||||
|
||||
keys := val.MapKeys()
|
||||
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
key := keys[i]
|
||||
kval := val.MapIndex(key)
|
||||
|
||||
b.WriteString("<member>")
|
||||
b.WriteString(fmt.Sprintf("<name>%s</name>", key.String()))
|
||||
|
||||
p, err := encodeValue(kval)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.Write(p)
|
||||
b.WriteString("</member>")
|
||||
}
|
||||
|
||||
b.WriteString("</struct>")
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func encodeSlice(val reflect.Value) ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
|
||||
b.WriteString("<array><data>")
|
||||
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
p, err := encodeValue(val.Index(i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.Write(p)
|
||||
}
|
||||
|
||||
b.WriteString("</data></array>")
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
57
vendor/github.com/kolo/xmlrpc/request.go
generated
vendored
57
vendor/github.com/kolo/xmlrpc/request.go
generated
vendored
@ -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(`<?xml version="1.0" encoding="UTF-8"?>`)
|
||||
b.WriteString(fmt.Sprintf("<methodCall><methodName>%s</methodName>", method))
|
||||
|
||||
if args != nil {
|
||||
b.WriteString("<params>")
|
||||
|
||||
for _, arg := range args {
|
||||
p, err := marshal(arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.WriteString(fmt.Sprintf("<param>%s</param>", string(p)))
|
||||
}
|
||||
|
||||
b.WriteString("</params>")
|
||||
}
|
||||
|
||||
b.WriteString("</methodCall>")
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
52
vendor/github.com/kolo/xmlrpc/response.go
generated
vendored
52
vendor/github.com/kolo/xmlrpc/response.go
generated
vendored
@ -1,52 +0,0 @@
|
||||
package xmlrpc
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var (
|
||||
faultRx = regexp.MustCompile(`<fault>(\s|\S)+</fault>`)
|
||||
)
|
||||
|
||||
type failedResponse struct {
|
||||
Code int `xmlrpc:"faultCode"`
|
||||
Error string `xmlrpc:"faultString"`
|
||||
}
|
||||
|
||||
func (r *failedResponse) err() error {
|
||||
return &xmlrpcError{
|
||||
code: r.Code,
|
||||
err: r.Error,
|
||||
}
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
func NewResponse(data []byte) *Response {
|
||||
return &Response{
|
||||
data: data,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Response) Failed() bool {
|
||||
return faultRx.Match(r.data)
|
||||
}
|
||||
|
||||
func (r *Response) Err() error {
|
||||
failedResp := new(failedResponse)
|
||||
if err := unmarshal(r.data, failedResp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return failedResp.err()
|
||||
}
|
||||
|
||||
func (r *Response) Unmarshal(v interface{}) error {
|
||||
if err := unmarshal(r.data, v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
25
vendor/github.com/kolo/xmlrpc/test_server.rb
generated
vendored
25
vendor/github.com/kolo/xmlrpc/test_server.rb
generated
vendored
@ -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
|
19
vendor/github.com/kolo/xmlrpc/xmlrpc.go
generated
vendored
19
vendor/github.com/kolo/xmlrpc/xmlrpc.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
package xmlrpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// xmlrpcError represents errors returned on xmlrpc request.
|
||||
type xmlrpcError struct {
|
||||
code int
|
||||
err string
|
||||
}
|
||||
|
||||
// Error() method implements Error interface
|
||||
func (e *xmlrpcError) Error() string {
|
||||
return fmt.Sprintf("error: \"%s\" code: %d", e.err, e.code)
|
||||
}
|
||||
|
||||
// Base64 represents value in base64 encoding
|
||||
type Base64 string
|
22
vendor/github.com/prasmussen/gandi-api/LICENSE
generated
vendored
22
vendor/github.com/prasmussen/gandi-api/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2013 Petter Rasmussen
|
||||
|
||||
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.
|
||||
|
208
vendor/github.com/prasmussen/gandi-api/client/client.go
generated
vendored
208
vendor/github.com/prasmussen/gandi-api/client/client.go
generated
vendored
@ -1,208 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/kolo/xmlrpc"
|
||||
)
|
||||
|
||||
const (
|
||||
// Production is the SystemType to provide to New to use the production XML API
|
||||
Production SystemType = iota
|
||||
// Testing is the SystemType to provide to New to use the test XML API
|
||||
Testing
|
||||
// LiveDNS is the SystemType to provide to New to use the Live DNS REST API
|
||||
// Full documentation of the API is available here: http://doc.livedns.gandi.net/
|
||||
LiveDNS
|
||||
)
|
||||
|
||||
// Enable/disable debug output:
|
||||
const debug = false
|
||||
|
||||
// SystemType is the type used to resolve gandi API address
|
||||
type SystemType int
|
||||
|
||||
// Url returns the actual gandi API base URL
|
||||
func (s SystemType) Url() string {
|
||||
if s == Production {
|
||||
return "https://rpc.gandi.net/xmlrpc/"
|
||||
}
|
||||
if s == LiveDNS {
|
||||
return "https://dns.api.gandi.net/api/v5/"
|
||||
}
|
||||
return "https://rpc.ote.gandi.net/xmlrpc/"
|
||||
}
|
||||
|
||||
// Client holds the configuration of a gandi client
|
||||
type Client struct {
|
||||
// Key is the API key to provide to gandi
|
||||
Key string
|
||||
// Url is the base URL of the gandi API
|
||||
Url string
|
||||
}
|
||||
|
||||
// New creates a new gandi client for the given system
|
||||
func New(apiKey string, system SystemType) *Client {
|
||||
return &Client{
|
||||
Key: apiKey,
|
||||
Url: system.Url(),
|
||||
}
|
||||
}
|
||||
|
||||
// Call performs an acual XML RPC call to the gandi API
|
||||
func (c *Client) Call(serviceMethod string, args []interface{}, reply interface{}) error {
|
||||
rpc, err := xmlrpc.NewClient(c.Url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return rpc.Call(serviceMethod, args, reply)
|
||||
}
|
||||
|
||||
// DoRest performs a request to gandi LiveDNS api and optionnally decodes the reply
|
||||
func (c *Client) DoRest(req *http.Request, decoded interface{}) (*http.Response, error) {
|
||||
if decoded != nil {
|
||||
req.Header.Set("Accept", "application/json")
|
||||
}
|
||||
client := http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode == http.StatusUnauthorized {
|
||||
return nil, fmt.Errorf("the server returned unauthorized code. Your API key might be invalid or have expired")
|
||||
}
|
||||
//
|
||||
defer func() { err = resp.Body.Close() }()
|
||||
if decoded != nil {
|
||||
b, e := ioutil.ReadAll(resp.Body)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
if len(b) > 0 {
|
||||
e = json.Unmarshal(b, decoded)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
if resp.StatusCode == http.StatusBadRequest {
|
||||
return nil, fmt.Errorf("the server returned 400 bad request (%v)", string(b))
|
||||
}
|
||||
}
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// NewJSONRequest creates a new authenticated to gandi live DNS REST API.
|
||||
// If data is not null, it will be encoded as json and prodived in the request body
|
||||
func (c *Client) NewJSONRequest(method string, url string, data interface{}) (*http.Request, error) {
|
||||
var reader io.Reader
|
||||
if data != nil {
|
||||
b, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reader = bytes.NewReader(b)
|
||||
}
|
||||
req, err := http.NewRequest(method, fmt.Sprintf("%s/%s", strings.TrimRight(c.Url, "/"), strings.TrimLeft(url, "/")), reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if data != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("X-Api-Key", c.Key)
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Get performs a Get request to gandi Live DNS api and decodes the returned data if a not null decoded pointer is provided
|
||||
func (c *Client) Get(URI string, decoded interface{}) (*http.Response, error) {
|
||||
req, err := c.NewJSONRequest("GET", URI, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.DoRest(req, decoded)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("Unexpected http code %d on URL %v. expecting %d", resp.StatusCode, resp.Request.URL, http.StatusOK)
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Delete performs a Delete request to gandi Live DNS api and decodes the returned data if a not null decoded pointer is provided
|
||||
func (c *Client) Delete(URI string, decoded interface{}) (*http.Response, error) {
|
||||
req, err := c.NewJSONRequest("DELETE", URI, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.DoRest(req, decoded)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusNoContent {
|
||||
return nil, fmt.Errorf("Unexpected http code %d on URL %v. expecting %d", resp.StatusCode, resp.Request.URL, http.StatusNoContent)
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Post performs a Post request request to gandi Live DNS api
|
||||
// - with data encoded as JSON if a not null data pointer is provided
|
||||
// - decodes the returned data if a not null decoded pointer is provided
|
||||
// - ensures the status code is an HTTP accepted
|
||||
func (c *Client) Post(URI string, data interface{}, decoded interface{}) (*http.Response, error) {
|
||||
if debug {
|
||||
fmt.Printf("DEBUG: POST URI=%s\n", URI)
|
||||
}
|
||||
req, err := c.NewJSONRequest("POST", URI, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if debug {
|
||||
fmt.Printf("DEBUG: POST req=%v decoded=%v\n", req, decoded)
|
||||
}
|
||||
resp, err := c.DoRest(req, decoded)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
return nil, fmt.Errorf("Unexpected http code %d on URL %v. expecting %d", resp.StatusCode, resp.Request.URL, http.StatusCreated)
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Put performs a Put request to gandi Live DNS api
|
||||
// - with data encoded as JSON if a not null data pointer is provided
|
||||
// - decodes the returned data if a not null decoded pointer is provided
|
||||
func (c *Client) Put(URI string, data interface{}, decoded interface{}) (*http.Response, error) {
|
||||
req, err := c.NewJSONRequest("PUT", URI, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.DoRest(req, decoded)
|
||||
}
|
||||
|
||||
// Patch performs a Patch request to gandi Live DNS api
|
||||
// - with data encoded as JSON if a not null data pointer is provided
|
||||
// - decodes the returned data if a not null decoded pointer is provided
|
||||
// - ensures the status code is an HTTP accepted
|
||||
func (c *Client) Patch(URI string, data interface{}, decoded interface{}) (*http.Response, error) {
|
||||
req, err := c.NewJSONRequest("PATCH", URI, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.DoRest(req, decoded)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusAccepted {
|
||||
return nil, fmt.Errorf("Unexpected http code %d on URL %v. expecting %d", resp.StatusCode, resp.Request.URL, http.StatusAccepted)
|
||||
}
|
||||
return resp, err
|
||||
}
|
87
vendor/github.com/prasmussen/gandi-api/domain/domain.go
generated
vendored
87
vendor/github.com/prasmussen/gandi-api/domain/domain.go
generated
vendored
@ -1,87 +0,0 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/client"
|
||||
"github.com/prasmussen/gandi-api/operation"
|
||||
)
|
||||
|
||||
type Domain struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
func New(c *client.Client) *Domain {
|
||||
return &Domain{c}
|
||||
}
|
||||
|
||||
// Check the availability of some domain
|
||||
func (self *Domain) Available(name string) (string, error) {
|
||||
var result map[string]interface{}
|
||||
domain := []string{name}
|
||||
params := []interface{}{self.Key, domain}
|
||||
if err := self.Call("domain.available", params, &result); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return result[name].(string), nil
|
||||
}
|
||||
|
||||
// Get domain information
|
||||
func (self *Domain) Info(name string) (*DomainInfo, error) {
|
||||
var res map[string]interface{}
|
||||
params := []interface{}{self.Key, name}
|
||||
if err := self.Call("domain.info", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ToDomainInfo(res), nil
|
||||
}
|
||||
|
||||
// List domains associated to the contact represented by apikey
|
||||
func (self *Domain) List() ([]*DomainInfoBase, error) {
|
||||
opts := &struct {
|
||||
Page int `xmlrpc:"page"`
|
||||
}{0}
|
||||
const perPage = 100
|
||||
params := []interface{}{self.Key, opts}
|
||||
domains := make([]*DomainInfoBase, 0)
|
||||
for {
|
||||
var res []interface{}
|
||||
if err := self.Call("domain.list", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, r := range res {
|
||||
domain := ToDomainInfoBase(r.(map[string]interface{}))
|
||||
domains = append(domains, domain)
|
||||
}
|
||||
if len(res) < perPage {
|
||||
break
|
||||
}
|
||||
opts.Page++
|
||||
}
|
||||
return domains, nil
|
||||
}
|
||||
|
||||
// Count domains associated to the contact represented by apikey
|
||||
func (self *Domain) Count() (int64, error) {
|
||||
var result int64
|
||||
params := []interface{}{self.Key}
|
||||
if err := self.Call("domain.count", params, &result); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Create a domain
|
||||
func (self *Domain) Create(name, contactHandle string, years int64) (*operation.OperationInfo, error) {
|
||||
var res map[string]interface{}
|
||||
createArgs := map[string]interface{}{
|
||||
"admin": contactHandle,
|
||||
"bill": contactHandle,
|
||||
"owner": contactHandle,
|
||||
"tech": contactHandle,
|
||||
"duration": years,
|
||||
}
|
||||
params := []interface{}{self.Key, name, createArgs}
|
||||
if err := self.Call("domain.create", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return operation.ToOperationInfo(res), nil
|
||||
}
|
24
vendor/github.com/prasmussen/gandi-api/domain/nameservers/nameservers.go
generated
vendored
24
vendor/github.com/prasmussen/gandi-api/domain/nameservers/nameservers.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package zone
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/client"
|
||||
"github.com/prasmussen/gandi-api/operation"
|
||||
)
|
||||
|
||||
type Nameservers struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
func New(c *client.Client) *Nameservers {
|
||||
return &Nameservers{c}
|
||||
}
|
||||
|
||||
// Set the current zone of a domain
|
||||
func (self *Nameservers) Set(domainName string, nameservers []string) (*operation.OperationInfo, error) {
|
||||
var res map[string]interface{}
|
||||
params := []interface{}{self.Key, domainName, nameservers}
|
||||
if err := self.Call("domain.nameservers.set", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return operation.ToOperationInfo(res), nil
|
||||
}
|
57
vendor/github.com/prasmussen/gandi-api/domain/structs.go
generated
vendored
57
vendor/github.com/prasmussen/gandi-api/domain/structs.go
generated
vendored
@ -1,57 +0,0 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type DomainInfoBase struct {
|
||||
AuthInfo string
|
||||
DateCreated time.Time
|
||||
DateRegistryCreation time.Time
|
||||
DateRegistryEnd time.Time
|
||||
DateUpdated time.Time
|
||||
Fqdn string
|
||||
Id int64
|
||||
Status []string
|
||||
Tld string
|
||||
}
|
||||
|
||||
type DomainInfoExtra struct {
|
||||
DateDelete time.Time
|
||||
DateHoldBegin time.Time
|
||||
DateHoldEnd time.Time
|
||||
DatePendingDeleteEnd time.Time
|
||||
DateRenewBegin time.Time
|
||||
DateRestoreEnd time.Time
|
||||
Nameservers []string
|
||||
Services []string
|
||||
ZoneId int64
|
||||
Autorenew *AutorenewInfo
|
||||
Contacts *ContactInfo
|
||||
}
|
||||
|
||||
type DomainInfo struct {
|
||||
*DomainInfoBase
|
||||
*DomainInfoExtra
|
||||
}
|
||||
|
||||
type AutorenewInfo struct {
|
||||
Active bool
|
||||
Contact string
|
||||
Id int64
|
||||
ProductId int64
|
||||
ProductTypeId int64
|
||||
}
|
||||
|
||||
type ContactInfo struct {
|
||||
Admin *ContactDetails
|
||||
Bill *ContactDetails
|
||||
Owner *ContactDetails
|
||||
Reseller *ContactDetails
|
||||
Tech *ContactDetails
|
||||
}
|
||||
|
||||
type ContactDetails struct {
|
||||
Handle string
|
||||
Id int64
|
||||
}
|
69
vendor/github.com/prasmussen/gandi-api/domain/util.go
generated
vendored
69
vendor/github.com/prasmussen/gandi-api/domain/util.go
generated
vendored
@ -1,69 +0,0 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/util"
|
||||
)
|
||||
|
||||
func ToDomainInfoBase(res map[string]interface{}) *DomainInfoBase {
|
||||
return &DomainInfoBase{
|
||||
AuthInfo: util.ToString(res["authinfo"]),
|
||||
DateCreated: util.ToTime(res["date_created"]),
|
||||
DateRegistryCreation: util.ToTime(res["date_registry_creation"]),
|
||||
DateRegistryEnd: util.ToTime(res["date_registry_end"]),
|
||||
DateUpdated: util.ToTime(res["date_updated"]),
|
||||
Fqdn: util.ToString(res["fqdn"]),
|
||||
Id: util.ToInt64(res["id"]),
|
||||
Status: util.ToStringSlice(util.ToInterfaceSlice(res["status"])),
|
||||
Tld: util.ToString(res["tld"]),
|
||||
}
|
||||
}
|
||||
|
||||
func ToDomainInfoExtra(res map[string]interface{}) *DomainInfoExtra {
|
||||
return &DomainInfoExtra{
|
||||
DateDelete: util.ToTime(res["date_delete"]),
|
||||
DateHoldBegin: util.ToTime(res["date_hold_begin"]),
|
||||
DateHoldEnd: util.ToTime(res["date_hold_end"]),
|
||||
DatePendingDeleteEnd: util.ToTime(res["date_pending_delete_end"]),
|
||||
DateRenewBegin: util.ToTime(res["date_renew_begin"]),
|
||||
DateRestoreEnd: util.ToTime(res["date_restore_end"]),
|
||||
Nameservers: util.ToStringSlice(util.ToInterfaceSlice(res["nameservers"])),
|
||||
Services: util.ToStringSlice(util.ToInterfaceSlice(res["services"])),
|
||||
ZoneId: util.ToInt64(res["zone_id"]),
|
||||
Autorenew: toAutorenewInfo(util.ToXmlrpcStruct(res["autorenew"])),
|
||||
Contacts: toContactInfo(util.ToXmlrpcStruct(res["contacts"])),
|
||||
}
|
||||
}
|
||||
|
||||
func ToDomainInfo(res map[string]interface{}) *DomainInfo {
|
||||
return &DomainInfo{
|
||||
ToDomainInfoBase(res),
|
||||
ToDomainInfoExtra(res),
|
||||
}
|
||||
}
|
||||
|
||||
func toAutorenewInfo(res map[string]interface{}) *AutorenewInfo {
|
||||
return &AutorenewInfo{
|
||||
Active: util.ToBool(res["active"]),
|
||||
Contact: util.ToString(res["contact"]),
|
||||
Id: util.ToInt64(res["id"]),
|
||||
ProductId: util.ToInt64(res["product_id"]),
|
||||
ProductTypeId: util.ToInt64(res["product_type_id"]),
|
||||
}
|
||||
}
|
||||
|
||||
func toContactInfo(res map[string]interface{}) *ContactInfo {
|
||||
return &ContactInfo{
|
||||
Admin: toContactDetails(util.ToXmlrpcStruct(res["admin"])),
|
||||
Bill: toContactDetails(util.ToXmlrpcStruct(res["bill"])),
|
||||
Owner: toContactDetails(util.ToXmlrpcStruct(res["owner"])),
|
||||
Reseller: toContactDetails(util.ToXmlrpcStruct(res["reseller"])),
|
||||
Tech: toContactDetails(util.ToXmlrpcStruct(res["tech"])),
|
||||
}
|
||||
}
|
||||
|
||||
func toContactDetails(res map[string]interface{}) *ContactDetails {
|
||||
return &ContactDetails{
|
||||
Handle: util.ToString(res["handle"]),
|
||||
Id: util.ToInt64(res["id"]),
|
||||
}
|
||||
}
|
129
vendor/github.com/prasmussen/gandi-api/domain/zone/record/record.go
generated
vendored
129
vendor/github.com/prasmussen/gandi-api/domain/zone/record/record.go
generated
vendored
@ -1,129 +0,0 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/client"
|
||||
)
|
||||
|
||||
type Record struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
func New(c *client.Client) *Record {
|
||||
return &Record{c}
|
||||
}
|
||||
|
||||
// Count number of records for a given zone/version
|
||||
func (self *Record) Count(zoneId, version int64) (int64, error) {
|
||||
var result int64
|
||||
params := []interface{}{self.Key, zoneId, version}
|
||||
if err := self.Call("domain.zone.record.count", params, &result); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List records of a version of a DNS zone
|
||||
func (self *Record) List(zoneId, version int64) ([]*RecordInfo, error) {
|
||||
opts := &struct {
|
||||
Page int `xmlrpc:"page"`
|
||||
}{0}
|
||||
const perPage = 100
|
||||
params := []interface{}{self.Key, zoneId, version, opts}
|
||||
records := make([]*RecordInfo, 0)
|
||||
for {
|
||||
var res []interface{}
|
||||
if err := self.Call("domain.zone.record.list", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, r := range res {
|
||||
record := ToRecordInfo(r.(map[string]interface{}))
|
||||
records = append(records, record)
|
||||
}
|
||||
if len(res) < perPage {
|
||||
break
|
||||
}
|
||||
opts.Page++
|
||||
}
|
||||
return records, nil
|
||||
}
|
||||
|
||||
// Add a new record to zone
|
||||
func (self *Record) Add(args RecordAdd) (*RecordInfo, error) {
|
||||
var res map[string]interface{}
|
||||
createArgs := map[string]interface{}{
|
||||
"name": args.Name,
|
||||
"type": args.Type,
|
||||
"value": args.Value,
|
||||
"ttl": args.Ttl,
|
||||
}
|
||||
|
||||
params := []interface{}{self.Key, args.Zone, args.Version, createArgs}
|
||||
if err := self.Call("domain.zone.record.add", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ToRecordInfo(res), nil
|
||||
}
|
||||
|
||||
// Remove a record from a zone/version
|
||||
func (self *Record) Delete(zoneId, version int64, recordId string) (bool, error) {
|
||||
var res int64
|
||||
deleteArgs := map[string]interface{}{"id": recordId}
|
||||
params := []interface{}{self.Key, zoneId, version, deleteArgs}
|
||||
if err := self.Call("domain.zone.record.delete", params, &res); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return (res == 1), nil
|
||||
}
|
||||
|
||||
// Update a record from zone/version
|
||||
func (self *Record) Update(args RecordUpdate) ([]*RecordInfo, error) {
|
||||
var res []interface{}
|
||||
updateArgs := map[string]interface{}{
|
||||
"name": args.Name,
|
||||
"type": args.Type,
|
||||
"value": args.Value,
|
||||
"ttl": args.Ttl,
|
||||
}
|
||||
updateOpts := map[string]string{
|
||||
"id": args.Id,
|
||||
}
|
||||
|
||||
params := []interface{}{self.Key, args.Zone, args.Version, updateOpts, updateArgs}
|
||||
if err := self.Call("domain.zone.record.update", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
records := make([]*RecordInfo, 0)
|
||||
for _, r := range res {
|
||||
record := ToRecordInfo(r.(map[string]interface{}))
|
||||
records = append(records, record)
|
||||
}
|
||||
return records, nil
|
||||
}
|
||||
|
||||
// SetRecords replaces the entire zone with new records.
|
||||
func (self *Record) SetRecords(zone_id, version_id int64, args []RecordSet) ([]*RecordInfo, error) {
|
||||
var res []interface{}
|
||||
|
||||
params := []interface{}{self.Key, zone_id, version_id, args}
|
||||
if err := self.Call("domain.zone.record.set", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
records := make([]*RecordInfo, 0)
|
||||
for _, r := range res {
|
||||
record := ToRecordInfo(r.(map[string]interface{}))
|
||||
records = append(records, record)
|
||||
}
|
||||
return records, nil
|
||||
}
|
||||
|
||||
//// Set the current zone of a domain
|
||||
//func (self *Record) Set(domainName string, id int64) (*domain.DomainInfo, error) {
|
||||
// var res map[string]interface{}
|
||||
// params := []interface{}{self.Key, domainName, id}
|
||||
// if err := self.zone.set", params, &res); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return domain.ToDomainInfo(res), nil
|
||||
//}
|
30
vendor/github.com/prasmussen/gandi-api/domain/zone/record/structs.go
generated
vendored
30
vendor/github.com/prasmussen/gandi-api/domain/zone/record/structs.go
generated
vendored
@ -1,30 +0,0 @@
|
||||
package record
|
||||
|
||||
type RecordInfo struct {
|
||||
Id string
|
||||
Name string
|
||||
Ttl int64
|
||||
Type string
|
||||
Value string
|
||||
}
|
||||
|
||||
type RecordAdd struct {
|
||||
Zone int64 `goptions:"-z, --zone, obligatory, description='Zone id'"`
|
||||
Version int64 `goptions:"-v, --version, obligatory, description='Zone version'"`
|
||||
Name string `goptions:"-n, --name, obligatory, description='Record name. Relative name, may contain leading wildcard. @ for empty name'"`
|
||||
Type string `goptions:"-t, --type, obligatory, description='Record type'"`
|
||||
Value string `goptions:"-V, --value, obligatory, description='Value for record. Semantics depends on the record type.'"`
|
||||
Ttl int64 `goptions:"-T, --ttl, description='Time to live, in seconds, between 5 minutes and 30 days'"`
|
||||
}
|
||||
|
||||
type RecordUpdate struct {
|
||||
Zone int64 `goptions:"-z, --zone, obligatory, description='Zone id'"`
|
||||
Version int64 `goptions:"-v, --version, obligatory, description='Zone version'"`
|
||||
Name string `goptions:"-n, --name, obligatory, description='Record name. Relative name, may contain leading wildcard. @ for empty name'"`
|
||||
Type string `goptions:"-t, --type, obligatory, description='Record type'"`
|
||||
Value string `goptions:"-V, --value, obligatory, description='Value for record. Semantics depends on the record type.'"`
|
||||
Ttl int64 `goptions:"-T, --ttl, description='Time to live, in seconds, between 5 minutes and 30 days'"`
|
||||
Id string `goptions:"-r, --record, obligatory, description='Record id'"`
|
||||
}
|
||||
|
||||
type RecordSet map[string]interface{}
|
15
vendor/github.com/prasmussen/gandi-api/domain/zone/record/util.go
generated
vendored
15
vendor/github.com/prasmussen/gandi-api/domain/zone/record/util.go
generated
vendored
@ -1,15 +0,0 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/util"
|
||||
)
|
||||
|
||||
func ToRecordInfo(res map[string]interface{}) *RecordInfo {
|
||||
return &RecordInfo{
|
||||
Id: util.ToString(res["id"]),
|
||||
Name: util.ToString(res["name"]),
|
||||
Ttl: util.ToInt64(res["ttl"]),
|
||||
Type: util.ToString(res["type"]),
|
||||
Value: util.ToString(res["value"]),
|
||||
}
|
||||
}
|
24
vendor/github.com/prasmussen/gandi-api/domain/zone/structs.go
generated
vendored
24
vendor/github.com/prasmussen/gandi-api/domain/zone/structs.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package zone
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type ZoneInfoBase struct {
|
||||
DateUpdated time.Time
|
||||
Id int64
|
||||
Name string
|
||||
Public bool
|
||||
Version int64
|
||||
}
|
||||
|
||||
type ZoneInfoExtra struct {
|
||||
Domains int64
|
||||
Owner string
|
||||
Versions []int64
|
||||
}
|
||||
|
||||
type ZoneInfo struct {
|
||||
*ZoneInfoBase
|
||||
*ZoneInfoExtra
|
||||
}
|
30
vendor/github.com/prasmussen/gandi-api/domain/zone/util.go
generated
vendored
30
vendor/github.com/prasmussen/gandi-api/domain/zone/util.go
generated
vendored
@ -1,30 +0,0 @@
|
||||
package zone
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/util"
|
||||
)
|
||||
|
||||
func ToZoneInfoBase(res map[string]interface{}) *ZoneInfoBase {
|
||||
return &ZoneInfoBase{
|
||||
DateUpdated: util.ToTime(res["date_updated"]),
|
||||
Id: util.ToInt64(res["id"]),
|
||||
Name: util.ToString(res["name"]),
|
||||
Public: util.ToBool(res["public"]),
|
||||
Version: util.ToInt64(res["version"]),
|
||||
}
|
||||
}
|
||||
|
||||
func ToZoneInfoExtra(res map[string]interface{}) *ZoneInfoExtra {
|
||||
return &ZoneInfoExtra{
|
||||
Domains: util.ToInt64(res["domains"]),
|
||||
Owner: util.ToString(res["owner"]),
|
||||
Versions: util.ToIntSlice(util.ToInterfaceSlice(res["versions"])),
|
||||
}
|
||||
}
|
||||
|
||||
func ToZoneInfo(res map[string]interface{}) *ZoneInfo {
|
||||
return &ZoneInfo{
|
||||
ToZoneInfoBase(res),
|
||||
ToZoneInfoExtra(res),
|
||||
}
|
||||
}
|
10
vendor/github.com/prasmussen/gandi-api/domain/zone/version/structs.go
generated
vendored
10
vendor/github.com/prasmussen/gandi-api/domain/zone/version/structs.go
generated
vendored
@ -1,10 +0,0 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type VersionInfo struct {
|
||||
Id int64
|
||||
DateCreated time.Time
|
||||
}
|
13
vendor/github.com/prasmussen/gandi-api/domain/zone/version/util.go
generated
vendored
13
vendor/github.com/prasmussen/gandi-api/domain/zone/version/util.go
generated
vendored
@ -1,13 +0,0 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/util"
|
||||
)
|
||||
|
||||
|
||||
func ToVersionInfo(res map[string]interface{}) *VersionInfo {
|
||||
return &VersionInfo{
|
||||
Id: util.ToInt64(res["id"]),
|
||||
DateCreated: util.ToTime(res["date_created"]),
|
||||
}
|
||||
}
|
68
vendor/github.com/prasmussen/gandi-api/domain/zone/version/version.go
generated
vendored
68
vendor/github.com/prasmussen/gandi-api/domain/zone/version/version.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
package version
|
||||
|
||||
import "github.com/prasmussen/gandi-api/client"
|
||||
|
||||
type Version struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
func New(c *client.Client) *Version {
|
||||
return &Version{c}
|
||||
}
|
||||
|
||||
// Count this zone versions
|
||||
func (self *Version) Count(zoneId int64) (int64, error) {
|
||||
var result int64
|
||||
params := []interface{}{self.Key, zoneId}
|
||||
if err := self.Call("domain.zone.version.count", params, &result); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List this zone versions, with their creation date
|
||||
func (self *Version) List(zoneId int64) ([]*VersionInfo, error) {
|
||||
var res []interface{}
|
||||
params := []interface{}{self.Key, zoneId}
|
||||
if err := self.Call("domain.zone.version.list", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
versions := make([]*VersionInfo, 0)
|
||||
for _, r := range res {
|
||||
version := ToVersionInfo(r.(map[string]interface{}))
|
||||
versions = append(versions, version)
|
||||
}
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
// Create a new version from another version. This will duplicate the version’s records
|
||||
func (self *Version) New(zoneId, version int64) (int64, error) {
|
||||
var res int64
|
||||
|
||||
params := []interface{}{self.Key, zoneId, version}
|
||||
if err := self.Call("domain.zone.version.new", params, &res); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Delete a specific version
|
||||
func (self *Version) Delete(zoneId, version int64) (bool, error) {
|
||||
var res bool
|
||||
params := []interface{}{self.Key, zoneId, version}
|
||||
if err := self.Call("domain.zone.version.delete", params, &res); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Set the active version of a zone
|
||||
func (self *Version) Set(zoneId, version int64) (bool, error) {
|
||||
var res bool
|
||||
params := []interface{}{self.Key, zoneId, version}
|
||||
if err := self.Call("domain.zone.version.set", params, &res); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
81
vendor/github.com/prasmussen/gandi-api/domain/zone/zone.go
generated
vendored
81
vendor/github.com/prasmussen/gandi-api/domain/zone/zone.go
generated
vendored
@ -1,81 +0,0 @@
|
||||
package zone
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/client"
|
||||
"github.com/prasmussen/gandi-api/domain"
|
||||
)
|
||||
|
||||
type Zone struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
func New(c *client.Client) *Zone {
|
||||
return &Zone{c}
|
||||
}
|
||||
|
||||
// Counts accessible zones
|
||||
func (self *Zone) Count() (int64, error) {
|
||||
var result int64
|
||||
params := []interface{}{self.Key}
|
||||
if err := self.Call("domain.zone.count", params, &result); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Get zone information
|
||||
func (self *Zone) Info(id int64) (*ZoneInfo, error) {
|
||||
var res map[string]interface{}
|
||||
params := []interface{}{self.Key, id}
|
||||
if err := self.Call("domain.zone.info", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ToZoneInfo(res), nil
|
||||
}
|
||||
|
||||
// List accessible DNS zones.
|
||||
func (self *Zone) List() ([]*ZoneInfoBase, error) {
|
||||
var res []interface{}
|
||||
params := []interface{}{self.Key}
|
||||
if err := self.Call("domain.zone.list", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
zones := make([]*ZoneInfoBase, 0)
|
||||
for _, r := range res {
|
||||
zone := ToZoneInfoBase(r.(map[string]interface{}))
|
||||
zones = append(zones, zone)
|
||||
}
|
||||
return zones, nil
|
||||
}
|
||||
|
||||
// Create a zone
|
||||
func (self *Zone) Create(name string) (*ZoneInfo, error) {
|
||||
var res map[string]interface{}
|
||||
createArgs := map[string]interface{}{"name": name}
|
||||
params := []interface{}{self.Key, createArgs}
|
||||
if err := self.Call("domain.zone.create", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ToZoneInfo(res), nil
|
||||
}
|
||||
|
||||
// Delete a zone
|
||||
func (self *Zone) Delete(id int64) (bool, error) {
|
||||
var res bool
|
||||
params := []interface{}{self.Key, id}
|
||||
if err := self.Call("domain.zone.delete", params, &res); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Set the current zone of a domain
|
||||
func (self *Zone) Set(domainName string, id int64) (*domain.DomainInfo, error) {
|
||||
var res map[string]interface{}
|
||||
params := []interface{}{self.Key, domainName, id}
|
||||
if err := self.Call("domain.zone.set", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return domain.ToDomainInfo(res), nil
|
||||
}
|
35
vendor/github.com/prasmussen/gandi-api/live_dns/domain/domain.go
generated
vendored
35
vendor/github.com/prasmussen/gandi-api/live_dns/domain/domain.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prasmussen/gandi-api/client"
|
||||
"github.com/prasmussen/gandi-api/live_dns/record"
|
||||
)
|
||||
|
||||
// Domain holds the domain client stucture
|
||||
type Domain struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New instanciates a new Domain client
|
||||
func New(c *client.Client) *Domain {
|
||||
return &Domain{c}
|
||||
}
|
||||
|
||||
// List domains associated to the contact represented by apikey
|
||||
func (d *Domain) List() (domains []*InfoBase, err error) {
|
||||
_, err = d.Get("/domains", &domains)
|
||||
return
|
||||
}
|
||||
|
||||
// Info Gets domain information
|
||||
func (d *Domain) Info(name string) (infos *Info, err error) {
|
||||
_, err = d.Get(fmt.Sprintf("/domains/%s", name), &infos)
|
||||
return
|
||||
}
|
||||
|
||||
// Records gets a record client for the current domain
|
||||
func (d *Domain) Records(name string) record.Manager {
|
||||
return record.New(d.Client, fmt.Sprintf("/domains/%s", name))
|
||||
}
|
32
vendor/github.com/prasmussen/gandi-api/live_dns/domain/structs.go
generated
vendored
32
vendor/github.com/prasmussen/gandi-api/live_dns/domain/structs.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
package domain
|
||||
|
||||
import "github.com/google/uuid"
|
||||
|
||||
// InfoBase holds the basic domain informations returned by the domain listing
|
||||
type InfoBase struct {
|
||||
// Fqdn stands for Fully Qualified Domain Name. It is the domain name managed by gandi (<domain>.<tld>)
|
||||
Fqdn string `json:"fqdn,omitempty"`
|
||||
// DomainRecordsHref contains the API URL to retrieve all records registered for the domain
|
||||
DomainRecordsHref string `json:"domain_records_href,omitempty"`
|
||||
// DomainHref contains the API URL to retrieve full DomainInfo for this domain
|
||||
DomainHref string `json:"domain_href,omitempty"`
|
||||
}
|
||||
|
||||
// InfoExtra holds the extra domain informations returned by domain details
|
||||
type InfoExtra struct {
|
||||
// ZomeUUID is the id of the zone currently configured on this domain
|
||||
ZoneUUID *uuid.UUID `json:"zone_uuid,omitempty"`
|
||||
// DomainKeysHref contains the API URL to list DNSSEC keys for this domain
|
||||
// note: DNSSEC is currently not supported by this library.
|
||||
DomainKeysHref string `json:"domain_keys_href,omitempty"`
|
||||
// ZoneHref contains the API URL to retrieve informations about the zone
|
||||
ZoneHref string `json:"zone_href,omitempty"`
|
||||
// ZoneRecordsHref contains the API URL to retrieve all records registered for the zone linked to this domain
|
||||
ZoneRecordsHref string `json:"zone_records_href,omitempty"`
|
||||
}
|
||||
|
||||
// Info holds all domain information
|
||||
type Info struct {
|
||||
*InfoBase
|
||||
*InfoExtra
|
||||
}
|
185
vendor/github.com/prasmussen/gandi-api/live_dns/record/record.go
generated
vendored
185
vendor/github.com/prasmussen/gandi-api/live_dns/record/record.go
generated
vendored
@ -1,185 +0,0 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/prasmussen/gandi-api/client"
|
||||
)
|
||||
|
||||
// Record holds the zone client structure
|
||||
type Record struct {
|
||||
*client.Client
|
||||
Prefix string
|
||||
}
|
||||
|
||||
// Creator is an interface to create new record entries
|
||||
type Creator interface {
|
||||
// Create creates a new record entry
|
||||
// possible calls are:
|
||||
// Create(recordInfo)
|
||||
// Create(recordInfo, "entry")
|
||||
// Create(recordInfo, "entry", "type")
|
||||
// where "entry" matches entry.example.com
|
||||
// and "type" is the record type (A, CNAME, ...)
|
||||
Create(recordInfo Info, args ...string) (status *Status, err error)
|
||||
}
|
||||
|
||||
// Updater is an interface to update existing record entries
|
||||
type Updater interface {
|
||||
// Update creates a new record entry
|
||||
// possible calls are:
|
||||
// Update(recordInfo)
|
||||
// Update(recordInfo, "entry")
|
||||
// Update(recordInfo, "entry", "type")
|
||||
// where "entry" matches entry.example.com
|
||||
// and "type" is the record type (A, CNAME, ...)
|
||||
Update(recordInfo Info, args ...string) (status *Status, err error)
|
||||
}
|
||||
|
||||
// Lister is an interface to list existing record entries
|
||||
type Lister interface {
|
||||
// List creates a new record entry
|
||||
// possible calls are:
|
||||
// List(recordInfo)
|
||||
// List(recordInfo, "entry")
|
||||
// List(recordInfo, "entry", "type")
|
||||
// where "entry" matches entry.example.com
|
||||
// and "type" is the record type (A, CNAME, ...)
|
||||
List(args ...string) (list []*Info, err error)
|
||||
}
|
||||
|
||||
// Deleter is an interface to delete existing record entries
|
||||
type Deleter interface {
|
||||
// Delete creates a new record entry
|
||||
// possible calls are:
|
||||
// Delete(recordInfo)
|
||||
// Delete(recordInfo, "entry")
|
||||
// Delete(recordInfo, "entry", "type")
|
||||
// where "entry" matches entry.example.com
|
||||
// and "type" is the record type (A, CNAME, ...)
|
||||
Delete(args ...string) (err error)
|
||||
}
|
||||
|
||||
// Manager is an interface to manage records (for a zone or domain)
|
||||
type Manager interface {
|
||||
Creator
|
||||
Updater
|
||||
Lister
|
||||
Deleter
|
||||
}
|
||||
|
||||
// New instanciates a new instance of a Zone client
|
||||
func New(c *client.Client, prefix string) *Record {
|
||||
return &Record{c, prefix}
|
||||
}
|
||||
|
||||
func (r *Record) uri(pattern string, paths ...string) string {
|
||||
args := make([]interface{}, len(paths))
|
||||
for i, v := range paths {
|
||||
args[i] = v
|
||||
}
|
||||
return fmt.Sprintf("%s/%s",
|
||||
strings.TrimRight(r.Prefix, "/"),
|
||||
strings.TrimLeft(fmt.Sprintf(pattern, args...), "/"))
|
||||
}
|
||||
|
||||
func (r *Record) formatCallError(function string, args ...string) error {
|
||||
format := "unexpected arguments for function %s." +
|
||||
" supported calls are: %s(), %s(<Name>), %s(<Name>, <Type>)" +
|
||||
" %s called with"
|
||||
a := []interface{}{
|
||||
function,
|
||||
function, function, function,
|
||||
function,
|
||||
}
|
||||
for _, v := range args {
|
||||
format = format + " %s"
|
||||
a = append(a, v)
|
||||
}
|
||||
return fmt.Errorf(format, a...)
|
||||
}
|
||||
|
||||
// Create creates a new record entry
|
||||
// possible calls are:
|
||||
// Create(recordInfo)
|
||||
// Create(recordInfo, "entry")
|
||||
// Create(recordInfo, "entry", "type")
|
||||
// where "entry" matches entry.example.com
|
||||
// and "type" is the record type (A, CNAME, ...)
|
||||
func (r *Record) Create(recordInfo Info, args ...string) (status *Status, err error) {
|
||||
switch len(args) {
|
||||
case 0:
|
||||
_, err = r.Post(r.uri("/records"), recordInfo, &status)
|
||||
case 1:
|
||||
_, err = r.Post(r.uri("/records/%s", args...), recordInfo, &status)
|
||||
case 2:
|
||||
_, err = r.Post(r.uri("/records/%s/%s", args...), recordInfo, &status)
|
||||
default:
|
||||
err = r.formatCallError("Create", args...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Update creates a new record entry
|
||||
// possible calls are:
|
||||
// Update(recordInfo)
|
||||
// Update(recordInfo, "entry")
|
||||
// Update(recordInfo, "entry", "type")
|
||||
// where "entry" matches entry.example.com
|
||||
// and "type" is the record type (A, CNAME, ...)
|
||||
func (r *Record) Update(recordInfo Info, args ...string) (status *Status, err error) {
|
||||
switch len(args) {
|
||||
case 0:
|
||||
_, err = r.Put(r.uri("/records"), recordInfo, &status)
|
||||
case 1:
|
||||
_, err = r.Put(r.uri("/records/%s", args...), recordInfo, &status)
|
||||
case 2:
|
||||
_, err = r.Put(r.uri("/records/%s/%s", args...), recordInfo, &status)
|
||||
default:
|
||||
err = r.formatCallError("Update", args...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// List creates a new record entry
|
||||
// possible calls are:
|
||||
// List(recordInfo)
|
||||
// List(recordInfo, "entry")
|
||||
// List(recordInfo, "entry", "type")
|
||||
// where "entry" matches entry.example.com
|
||||
// and "type" is the record type (A, CNAME, ...)
|
||||
func (r *Record) List(args ...string) (list []*Info, err error) {
|
||||
switch len(args) {
|
||||
case 0:
|
||||
_, err = r.Get(r.uri("/records"), &list)
|
||||
case 1:
|
||||
_, err = r.Get(r.uri("/records/%s", args...), &list)
|
||||
case 2:
|
||||
_, err = r.Get(r.uri("/records/%s/%s", args...), &list)
|
||||
default:
|
||||
err = r.formatCallError("List", args...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete creates a new record entry
|
||||
// possible calls are:
|
||||
// Delete(recordInfo)
|
||||
// Delete(recordInfo, "entry")
|
||||
// Delete(recordInfo, "entry", "type")
|
||||
// where "entry" matches entry.example.com
|
||||
// and "type" is the record type (A, CNAME, ...)
|
||||
func (r *Record) Delete(args ...string) (err error) {
|
||||
switch len(args) {
|
||||
case 0:
|
||||
_, err = r.Client.Delete(r.uri("/records"), nil)
|
||||
case 1:
|
||||
_, err = r.Client.Delete(r.uri("/records/%s", args...), nil)
|
||||
case 2:
|
||||
_, err = r.Client.Delete(r.uri("/records/%s/%s", args...), nil)
|
||||
default:
|
||||
err = r.formatCallError("Delete", args...)
|
||||
}
|
||||
return
|
||||
}
|
68
vendor/github.com/prasmussen/gandi-api/live_dns/record/structs.go
generated
vendored
68
vendor/github.com/prasmussen/gandi-api/live_dns/record/structs.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
package record
|
||||
|
||||
const (
|
||||
// A is the type of record that hold a 32-bit IPv4 address, most commonly used to map hostnames to an IP address of the host
|
||||
A = "A"
|
||||
// AAAA is the type of record that hold a Returns a 128-bit IPv6 address, most commonly used to map hostnames to an IP address of the host
|
||||
AAAA = "AAAA"
|
||||
// CAA is the type of record that hold the DNS Certification Authority Authorization, constraining acceptable CAs for a host/domain
|
||||
CAA = "CAA"
|
||||
// CDS is the type of record that hold the child copy of DS record, for transfer to parent
|
||||
CDS = "CDS"
|
||||
// CNAME is the type of record that hold the alias of one name to another: the DNS lookup will continue by retrying the lookup with the new name
|
||||
CNAME = "CNAME"
|
||||
// DNAME is the type of record that hold the alias for a name and all its subnames, unlike CNAME, which is an alias for only the exact name.
|
||||
// Like a CNAME record, the DNS lookup will continue by retrying the lookup with the new name
|
||||
DNAME = "DNAME"
|
||||
// DS is the type of record that hold the record used to identify the DNSSEC signing key of a delegated zone
|
||||
DS = "DS"
|
||||
// LOC is the type of record that specifies a geographical location associated with a domain name
|
||||
LOC = "LOC"
|
||||
// MX is the type of record that maps a domain name to a list of message transfer agents for that domain
|
||||
MX = "MX"
|
||||
// NS is the type of record that delegates a DNS zone to use the given authoritative name servers
|
||||
NS = "NS"
|
||||
// PTR is the type of record that hold a pointer to a canonical name. Unlike a CNAME, DNS processing stops and just the name is returned.
|
||||
// The most common use is for implementing reverse DNS lookups, but other uses include such things as DNS-SD.
|
||||
PTR = "PTR"
|
||||
// SPF (99) (from RFC 4408) was specified as part of the Sender Policy Framework protocol as an alternative to storing SPF data in TXT records,
|
||||
// using the same format. It was later found that the majority of SPF deployments lack proper support for this record type, and support for it was discontinued in RFC 7208
|
||||
SPF = "SPF"
|
||||
// SRV is the type of record that hold the generalized service location record, used for newer protocols instead of creating protocol-specific records such as MX.
|
||||
SRV = "SRV"
|
||||
// SSHFP is the type of record that hold resource record for publishing SSH public host key fingerprints in the DNS System,
|
||||
// in order to aid in verifying the authenticity of the host. RFC 6594 defines ECC SSH keys and SHA-256 hashes
|
||||
SSHFP = "SSHFP"
|
||||
// TLSA is the type of record that hold a record for DANE.
|
||||
// record for DANE. RFC 6698 defines "The TLSA DNS resource record is used to associate a TLS server
|
||||
// certificate or public key with the domain name where the record is found, thus forming a 'TLSA certificate association'".
|
||||
TLSA = "TLSA"
|
||||
// TXT is the type of record that hold human readable text.
|
||||
// Since the early 1990s, however, this record more often carries machine-readable data,
|
||||
// such as specified by RFC 1464, opportunistic encryption, Sender Policy Framework, DKIM, DMARC, DNS-SD, etc.
|
||||
TXT = "TXT"
|
||||
// WKS is the type of record that describe well-known services supported by a host. Not used in practice.
|
||||
// The current recommendation and practice is to determine whether a service is supported on an IP address by trying to connect to it.
|
||||
// SMTP is even prohibited from using WKS records in MX processing
|
||||
WKS = "WKS"
|
||||
)
|
||||
|
||||
// Info holds the record informations for a single record entry
|
||||
type Info struct {
|
||||
// Href contains the API URL to get the record informations
|
||||
Href string `json:"rrset_href,omitempty"`
|
||||
// Name contains name of the subdomain for this record
|
||||
Name string `json:"rrset_name,omitempty"`
|
||||
// TTL contains the life time of the record.
|
||||
TTL int64 `json:"rrset_ttl,omitempty"`
|
||||
// Type contains the DNS record type
|
||||
Type string `json:"rrset_type,omitempty"`
|
||||
// Values contains the DNS values resolved by the record
|
||||
Values []string `json:"rrset_values,omitempty"`
|
||||
}
|
||||
|
||||
// Status holds the data returned by the API in case of record creation or update
|
||||
type Status struct {
|
||||
// Message is the status message returned by the gandi api
|
||||
Message string `json:"message"`
|
||||
}
|
56
vendor/github.com/prasmussen/gandi-api/live_dns/zone/structs.go
generated
vendored
56
vendor/github.com/prasmussen/gandi-api/live_dns/zone/structs.go
generated
vendored
@ -1,56 +0,0 @@
|
||||
package zone
|
||||
|
||||
import "github.com/google/uuid"
|
||||
|
||||
// Source: http://knowledgelayer.softlayer.com/faq/what-does-serial-refresh-retry-expire-minimum-and-ttl-mean
|
||||
|
||||
// Info holds the DNS zone informations
|
||||
type Info struct {
|
||||
// Retry is the amount of time in seconds that a domain's primary name server (or servers)
|
||||
// should wait if an attempt to refresh by a secondary name server failed before
|
||||
// attempting to refresh a domain's zone with that secondary name server again.
|
||||
Retry int `json:"retry,omitempty"`
|
||||
// UUID is the zone id
|
||||
UUID *uuid.UUID `json:"uuid,omitempty"`
|
||||
// Minimum is the amount of time in seconds that a domain's resource records are valid.
|
||||
// This is also known as a minimum TTL, and can be overridden by an individual resource record's TTL
|
||||
Minimum int `json:"minimum,omitempty"`
|
||||
// Refresh is the amount of time in seconds that a secondary name server should wait to check for
|
||||
// a new copy of a DNS zone from the domain's primary name server. If a zone file has changed then
|
||||
// the secondary DNS server will update it's copy of the zone to match the primary DNS server's zone
|
||||
Refresh int `json:"refresh,omitempty"`
|
||||
// Expire is the amount of time in seconds that a secondary name server (or servers) will
|
||||
// hold a zone before it is no longer considered authoritative
|
||||
Expire int64 `json:"expire,omitempty"`
|
||||
// SharingID is currently undocumented in http://doc.livedns.gandi.net/
|
||||
// But seems to be the ID used to https://admin.gandi.net/domain/<...>
|
||||
SharingID *uuid.UUID `json:"sharing_id,omitempty"`
|
||||
// Serial is the revision number of this zone file. Increment this number each time the zone
|
||||
// file is changed so that the changes will be distributed to any secondary DNS servers
|
||||
Serial int `json:"serial,omitempty"`
|
||||
// Email is listed but undocumented in http://doc.livedns.gandi.net/
|
||||
Email string `json:"email,omitempty"`
|
||||
// PrimaryNS is the name of the nameserver to be used for this zone
|
||||
PrimaryNS string `json:"primary_ns,omitempty"`
|
||||
// Name is the name of the zone
|
||||
Name string `json:"name,omitempty"`
|
||||
// DomainsHref contains the API URL to retrieve all domains using this zone
|
||||
DomainsHref string `json:"domains_href,omitempty"`
|
||||
// ZoneHref contains the API URL to retrieve full DomainInfo for this domain
|
||||
ZoneHref string `json:"zone_href,omitempty"`
|
||||
// ZoneRecordsHref contains the API URL to retrieve all records registered for the zone linked to this zone
|
||||
ZoneRecordsHref string `json:"zone_records_href,omitempty"`
|
||||
}
|
||||
|
||||
// Status holds the data returned by the API in case of zone update or association to a domain
|
||||
type Status struct {
|
||||
// Message is the status message returned by the gandi api
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// CreateStatus holds the data for returned by the API zone creation
|
||||
type CreateStatus struct {
|
||||
*Status
|
||||
// UUID is the created zone ID
|
||||
UUID *uuid.UUID `json:"uuid"`
|
||||
}
|
100
vendor/github.com/prasmussen/gandi-api/live_dns/zone/zone.go
generated
vendored
100
vendor/github.com/prasmussen/gandi-api/live_dns/zone/zone.go
generated
vendored
@ -1,100 +0,0 @@
|
||||
package zone
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/prasmussen/gandi-api/client"
|
||||
"github.com/prasmussen/gandi-api/live_dns/domain"
|
||||
"github.com/prasmussen/gandi-api/live_dns/record"
|
||||
)
|
||||
|
||||
// Enable/disable debug output:
|
||||
const debug = false
|
||||
|
||||
// Zone holds the zone client structure
|
||||
type Zone struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New instanciates a new instance of a Zone client
|
||||
func New(c *client.Client) *Zone {
|
||||
return &Zone{c}
|
||||
}
|
||||
|
||||
// List accessible DNS zones.
|
||||
func (z *Zone) List() (zones []*Info, err error) {
|
||||
_, err = z.Get("/zones", &zones)
|
||||
return
|
||||
}
|
||||
|
||||
// InfoByUUID Gets zone information from its UUID
|
||||
func (z *Zone) InfoByUUID(uuid uuid.UUID) (info *Info, err error) {
|
||||
_, err = z.Get(fmt.Sprintf("/zones/%s", uuid), &info)
|
||||
if debug {
|
||||
fmt.Printf("DEBUG: InfoByUUID returned SharingID=%v domain=%v\n", info.SharingID, info.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Info Gets zone information
|
||||
func (z *Zone) Info(zoneInfo Info) (info *Info, err error) {
|
||||
if zoneInfo.UUID == nil {
|
||||
return nil, fmt.Errorf("can not get zone info %s without an id", zoneInfo.Name)
|
||||
}
|
||||
return z.InfoByUUID(*zoneInfo.UUID)
|
||||
}
|
||||
|
||||
// Create creates a new zone
|
||||
func (z *Zone) Create(zoneInfo Info) (status *CreateStatus, err error) {
|
||||
if debug {
|
||||
fmt.Printf("DEBUG: Create WILL SET SharingID=%v domain=%v\n", zoneInfo.SharingID, zoneInfo.Name)
|
||||
}
|
||||
_, err = z.Post(fmt.Sprintf("/zones?sharing_id=%s", zoneInfo.SharingID), zoneInfo, &status)
|
||||
return
|
||||
}
|
||||
|
||||
// Update updates an existing zone
|
||||
func (z *Zone) Update(zoneInfo Info) (status *Status, err error) {
|
||||
if zoneInfo.UUID == nil {
|
||||
return nil, fmt.Errorf("can not update zone %s without an id", zoneInfo.Name)
|
||||
}
|
||||
_, err = z.Patch(fmt.Sprintf("/zones/%s", zoneInfo.UUID), zoneInfo, &status)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete Deletes an existing zone
|
||||
func (z *Zone) Delete(zoneInfo Info) (err error) {
|
||||
if zoneInfo.UUID == nil {
|
||||
return fmt.Errorf("can not update zone %s without an id", zoneInfo.Name)
|
||||
}
|
||||
_, err = z.Client.Delete(fmt.Sprintf("/zones/%s", zoneInfo.UUID), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Domains lists all domains using a zone
|
||||
func (z *Zone) Domains(zoneInfo Info) (domains []*domain.InfoBase, err error) {
|
||||
if zoneInfo.UUID == nil {
|
||||
return nil, fmt.Errorf("can not get domains on a zone %s without an id", zoneInfo.Name)
|
||||
}
|
||||
_, err = z.Get(fmt.Sprintf("/zones/%s/domains", zoneInfo.UUID), &domains)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// Set the current zone of a domain
|
||||
func (z *Zone) Set(domainName string, zoneInfo Info) (status *Status, err error) {
|
||||
if zoneInfo.UUID == nil {
|
||||
return nil, fmt.Errorf("can not attach a domain %s to a zone %s without an id", domainName, zoneInfo.Name)
|
||||
}
|
||||
if debug {
|
||||
fmt.Printf("DEBUG: Set WILL SET SharingID=%v domain=%s dn=%v\n", zoneInfo.SharingID, domainName, zoneInfo.Name)
|
||||
}
|
||||
_, err = z.Post(fmt.Sprintf("/zones/%s/domains/%s", zoneInfo.UUID, domainName), nil, &status)
|
||||
return
|
||||
}
|
||||
|
||||
// Records gets a record client for the current zone
|
||||
func (z *Zone) Records(zoneInfo Info) record.Manager {
|
||||
return record.New(z.Client, fmt.Sprintf("/zones/%s", zoneInfo.UUID))
|
||||
}
|
60
vendor/github.com/prasmussen/gandi-api/operation/operation.go
generated
vendored
60
vendor/github.com/prasmussen/gandi-api/operation/operation.go
generated
vendored
@ -1,60 +0,0 @@
|
||||
package operation
|
||||
|
||||
import "github.com/prasmussen/gandi-api/client"
|
||||
|
||||
type Operation struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
func New(c *client.Client) *Operation {
|
||||
return &Operation{c}
|
||||
}
|
||||
|
||||
// Count operations created by this contact
|
||||
func (self *Operation) Count() (int64, error) {
|
||||
var result int64
|
||||
// params := Params{Params: []interface{}{self.Key}}
|
||||
params := []interface{}{self.Key}
|
||||
if err := self.Call("operation.count", params, &result); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Get operation information
|
||||
func (self *Operation) Info(id int64) (*OperationInfo, error) {
|
||||
var res map[string]interface{}
|
||||
// params := Params{Params: []interface{}{self.Key, id}}
|
||||
params := []interface{}{self.Key, id}
|
||||
if err := self.Call("operation.info", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ToOperationInfo(res), nil
|
||||
}
|
||||
|
||||
// Cancel an operation
|
||||
func (self *Operation) Cancel(id int64) (bool, error) {
|
||||
var res bool
|
||||
// params := Params{Params: []interface{}{self.Key, id}}
|
||||
params := []interface{}{self.Key, id}
|
||||
if err := self.Call("operation.cancel", params, &res); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// List operations created by this contact
|
||||
func (self *Operation) List() ([]*OperationInfo, error) {
|
||||
var res []interface{}
|
||||
// params := Params{Params: []interface{}{self.Key}}
|
||||
params := []interface{}{self.Key}
|
||||
if err := self.Call("operation.list", params, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
operations := make([]*OperationInfo, len(res), len(res))
|
||||
for i, r := range res {
|
||||
operations[i] = ToOperationInfo(r.(map[string]interface{}))
|
||||
}
|
||||
return operations, nil
|
||||
}
|
29
vendor/github.com/prasmussen/gandi-api/operation/structs.go
generated
vendored
29
vendor/github.com/prasmussen/gandi-api/operation/structs.go
generated
vendored
@ -1,29 +0,0 @@
|
||||
package operation
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type OperationInfo struct {
|
||||
DateCreated time.Time
|
||||
DateStart time.Time
|
||||
DateUpdated time.Time
|
||||
Eta string
|
||||
Id int64
|
||||
LastError string
|
||||
SessionId int64
|
||||
Source string
|
||||
Step string
|
||||
Type string
|
||||
Params map[string]interface{}
|
||||
OperationDetails *OperationDetails
|
||||
}
|
||||
|
||||
type OperationDetails struct {
|
||||
Id string
|
||||
Label string
|
||||
ProductAction string
|
||||
ProductName string
|
||||
ProductType string
|
||||
Quantity int64
|
||||
}
|
33
vendor/github.com/prasmussen/gandi-api/operation/util.go
generated
vendored
33
vendor/github.com/prasmussen/gandi-api/operation/util.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
package operation
|
||||
|
||||
import (
|
||||
"github.com/prasmussen/gandi-api/util"
|
||||
)
|
||||
|
||||
func ToOperationInfo(res map[string]interface{}) *OperationInfo {
|
||||
return &OperationInfo{
|
||||
DateCreated: util.ToTime(res["date_created"]),
|
||||
DateStart: util.ToTime(res["date_start"]),
|
||||
DateUpdated: util.ToTime(res["date_updated"]),
|
||||
Eta: util.ToString(res["eta"]),
|
||||
Id: util.ToInt64(res["id"]),
|
||||
LastError: util.ToString(res["last_error"]),
|
||||
SessionId: util.ToInt64(res["session_id"]),
|
||||
Source: util.ToString(res["source"]),
|
||||
Step: util.ToString(res["step"]),
|
||||
Type: util.ToString(res["type"]),
|
||||
OperationDetails: ToOperationDetails(util.ToXmlrpcStruct(res["infos"])),
|
||||
Params: util.ToXmlrpcStruct(res["params"]),
|
||||
}
|
||||
}
|
||||
|
||||
func ToOperationDetails(res map[string]interface{}) *OperationDetails {
|
||||
return &OperationDetails{
|
||||
Id: util.ToString(res["id"]),
|
||||
Label: util.ToString(res["label"]),
|
||||
ProductAction: util.ToString(res["product_action"]),
|
||||
ProductName: util.ToString(res["product_name"]),
|
||||
ProductType: util.ToString(res["product_type"]),
|
||||
Quantity: util.ToInt64(res["quantity"]),
|
||||
}
|
||||
}
|
76
vendor/github.com/prasmussen/gandi-api/util/util.go
generated
vendored
76
vendor/github.com/prasmussen/gandi-api/util/util.go
generated
vendored
@ -1,76 +0,0 @@
|
||||
package util
|
||||
|
||||
import "time"
|
||||
|
||||
func ToStringSlice(is []interface{}) []string {
|
||||
ss := make([]string, len(is), len(is))
|
||||
|
||||
for i, _ := range is {
|
||||
ss[i] = is[i].(string)
|
||||
}
|
||||
return ss
|
||||
}
|
||||
|
||||
func ToString(i interface{}) string {
|
||||
if v, ok := i.(string); ok {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func ToTime(i interface{}) time.Time {
|
||||
if v, ok := i.(time.Time); ok {
|
||||
return v
|
||||
}
|
||||
var t time.Time
|
||||
return t
|
||||
}
|
||||
|
||||
func ToInterfaceSlice(i interface{}) []interface{} {
|
||||
if v, ok := i.([]interface{}); ok {
|
||||
return v
|
||||
}
|
||||
var s []interface{}
|
||||
return s
|
||||
}
|
||||
|
||||
func ToInt64(i interface{}) int64 {
|
||||
if v, ok := i.(int64); ok {
|
||||
return v
|
||||
}
|
||||
var n int64
|
||||
return n
|
||||
}
|
||||
|
||||
func ToFloat64(i interface{}) float64 {
|
||||
if v, ok := i.(float64); ok {
|
||||
return v
|
||||
}
|
||||
var n float64
|
||||
return n
|
||||
}
|
||||
|
||||
func ToXmlrpcStruct(i interface{}) map[string]interface{} {
|
||||
if v, ok := i.(map[string]interface{}); ok {
|
||||
return v
|
||||
}
|
||||
var s map[string]interface{}
|
||||
return s
|
||||
}
|
||||
|
||||
func ToBool(i interface{}) bool {
|
||||
if v, ok := i.(bool); ok {
|
||||
return v
|
||||
}
|
||||
var b bool
|
||||
return b
|
||||
}
|
||||
|
||||
func ToIntSlice(is []interface{}) []int64 {
|
||||
numbers := make([]int64, len(is), len(is))
|
||||
|
||||
for i, _ := range is {
|
||||
numbers[i] = ToInt64(is[i])
|
||||
}
|
||||
return numbers
|
||||
}
|
Reference in New Issue
Block a user