mirror of
https://github.com/vxcontrol/rancher-letsencrypt.git
synced 2026-07-01 22:24:01 -04:00
Switch to vendor folder / Update third-party libraries
This commit is contained in:
Generated
+109
-90
@@ -1,141 +1,160 @@
|
||||
{
|
||||
"ImportPath": "github.com/janeczku/rancher-letsencrypt",
|
||||
"GoVersion": "go1.5",
|
||||
"GoVersion": "go1.6",
|
||||
"GodepVersion": "v74",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/JamesClonk/vultr/lib",
|
||||
"Comment": "v1.8",
|
||||
"Rev": "f4daffde4646155fa142e64e114f771aa259c7f5"
|
||||
"Comment": "1.12.0-11-g9ec0427",
|
||||
"Rev": "9ec0427d51411407c0402b093a1771cb75af9679"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Sirupsen/logrus",
|
||||
"Comment": "v0.8.7-55-gf7f79f7",
|
||||
"Rev": "f7f79f729e0fbe2fcc061db48a9ba0263f588252"
|
||||
"Comment": "v0.11.0-35-g61e43dc",
|
||||
"Rev": "61e43dc76f7ee59a82bdf3d71033dc12bea4c77d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds",
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/stscreds",
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/request",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/session",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/signer/v4",
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/endpoints",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/restxml",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/signer/v4",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/waiter",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/route53",
|
||||
"Comment": "v1.1.25",
|
||||
"Rev": "02ee239c4ddbc6750fd0c3b5b5728b2b33aa92b4"
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/sts",
|
||||
"Comment": "v1.4.22",
|
||||
"Rev": "6c577e9e7b08a6d10bad1c9703227cd0403a8dd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-ini/ini",
|
||||
"Comment": "v1.11.0",
|
||||
"Rev": "12f418cc7edc5a618a51407b7ac1f1f512139df3"
|
||||
"Comment": "v1.24.0",
|
||||
"Rev": "e3c2d47c61e5333f9aa2974695dd94396eb69c75"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/websocket",
|
||||
"Rev": "c45a635370221f34fea2d5163fd156fcb4e38e8a"
|
||||
"Comment": "v1.1.0-19-gc36f2fe",
|
||||
"Rev": "c36f2fe5c330f0ac404b616b96c438b8616b1aaf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jmespath/go-jmespath",
|
||||
"Comment": "0.2.2-12-g0b12d6b",
|
||||
"Rev": "0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74"
|
||||
"Comment": "0.2.2-14-gbd40a43",
|
||||
"Rev": "bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/juju/ratelimit",
|
||||
@@ -143,16 +162,16 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/miekg/dns",
|
||||
"Rev": "48ab6605c66ac797e07f615101c3e9e10e932b66"
|
||||
"Rev": "2be0b50f7f04c7223e2b82601ac9ca1e199a9c21"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ovh/go-ovh/ovh",
|
||||
"Rev": "d2b2eae2511fa5fcd0bdef9f1790ea3979fa35d4"
|
||||
"Rev": "d2207178e10e4527e8f222fd8707982df8c3af17"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rancher/go-rancher/client",
|
||||
"Comment": "v0.1.0-151-gc21ad77",
|
||||
"Rev": "c21ad7797bc727e5fe65ae85d1be714845ce415c"
|
||||
"Comment": "v0.1.0-173-g37c17e4",
|
||||
"Rev": "37c17e456a2d6dce279f54ee2f957797d30a20dc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/weppos/dnsimple-go/dnsimple",
|
||||
@@ -160,80 +179,80 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/acme",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/providers/dns/cloudflare",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/providers/dns/digitalocean",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/providers/dns/dnsimple",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/providers/dns/dyn",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/providers/dns/gandi",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/providers/dns/ovh",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/providers/dns/route53",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xenolf/lego/providers/dns/vultr",
|
||||
"Comment": "v0.3.1-44-gb12ce5e",
|
||||
"Rev": "b12ce5e73146e74520c426895394b92dffeb3a25"
|
||||
"Comment": "v0.3.1-102-gf5d538c",
|
||||
"Rev": "f5d538caab6dc0c167d4e32990c79bbf9eff578c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/ocsp",
|
||||
"Rev": "5dc8cb4b8a8eb076cbb5a06bc3b8682c15bdbbd3"
|
||||
"Rev": "854ae91cdcbf914b499b1d7641d07859f3653481"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/publicsuffix",
|
||||
"Rev": "3e5cd1ed149001198e582f9d3f5bfd564cde2896"
|
||||
"Rev": "f2499483f923065a842d38eb4c7f1927e6fc6e6d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/sys/unix",
|
||||
"Rev": "eb2c74142fd19a79b3f237334c7384d5167b1b46"
|
||||
"Rev": "d75a52659825e75fff6158388dddc6a5b04f9ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/ini.v1",
|
||||
"Comment": "v1.18.0",
|
||||
"Rev": "cf53f9204df4fbdd7ec4164b57fa6184ba168292"
|
||||
"Comment": "v1.24.0",
|
||||
"Rev": "e3c2d47c61e5333f9aa2974695dd94396eb69c75"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/square/go-jose.v1",
|
||||
"Comment": "v1.0.1",
|
||||
"Rev": "40d457b439244b546f023d056628e5184136899b"
|
||||
"Comment": "v1.1.0",
|
||||
"Rev": "aa2e30fdd1fe9dd3394119af66451ae790d50e0d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/square/go-jose.v1/cipher",
|
||||
"Comment": "v1.0.1",
|
||||
"Rev": "40d457b439244b546f023d056628e5184136899b"
|
||||
"Comment": "v1.1.0",
|
||||
"Rev": "aa2e30fdd1fe9dd3394119af66451ae790d50e0d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/square/go-jose.v1/json",
|
||||
"Comment": "v1.0.1",
|
||||
"Rev": "40d457b439244b546f023d056628e5184136899b"
|
||||
"Comment": "v1.1.0",
|
||||
"Rev": "aa2e30fdd1fe9dd3394119af66451ae790d50e0d"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Generated
-2
@@ -1,2 +0,0 @@
|
||||
/pkg
|
||||
/bin
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package lib
|
||||
|
||||
// Region on Vultr
|
||||
type Region struct {
|
||||
ID int `json:"DCID,string"`
|
||||
Name string `json:"name"`
|
||||
Country string `json:"country"`
|
||||
Continent string `json:"continent"`
|
||||
State string `json:"state"`
|
||||
Ddos bool `json:"ddos_protection"`
|
||||
}
|
||||
|
||||
func (c *Client) GetRegions() ([]Region, error) {
|
||||
var regionMap map[string]Region
|
||||
if err := c.get(`regions/list`, ®ionMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var regionList []Region
|
||||
for _, os := range regionMap {
|
||||
regionList = append(regionList, os)
|
||||
}
|
||||
return regionList, nil
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.3
|
||||
- 1.4
|
||||
- tip
|
||||
install:
|
||||
- go get -t ./...
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type JSONFormatter struct {
|
||||
// TimestampFormat sets the format used for marshaling timestamps.
|
||||
TimestampFormat string
|
||||
}
|
||||
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data := make(Fields, len(entry.Data)+3)
|
||||
for k, v := range entry.Data {
|
||||
switch v := v.(type) {
|
||||
case error:
|
||||
// Otherwise errors are ignored by `encoding/json`
|
||||
// https://github.com/Sirupsen/logrus/issues/137
|
||||
data[k] = v.Error()
|
||||
default:
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
prefixFieldClashes(data)
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
|
||||
data["time"] = entry.Time.Format(timestampFormat)
|
||||
data["msg"] = entry.Message
|
||||
data["level"] = entry.Level.String()
|
||||
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func (logger *Logger) Writer() *io.PipeWriter {
|
||||
reader, writer := io.Pipe()
|
||||
|
||||
go logger.writerScanner(reader)
|
||||
runtime.SetFinalizer(writer, writerFinalizer)
|
||||
|
||||
return writer
|
||||
}
|
||||
|
||||
func (logger *Logger) writerScanner(reader *io.PipeReader) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
logger.Print(scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
logger.Errorf("Error while reading from Writer: %s", err)
|
||||
}
|
||||
reader.Close()
|
||||
}
|
||||
|
||||
func writerFinalizer(writer *io.PipeWriter) {
|
||||
writer.Close()
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
// +build go1.5
|
||||
|
||||
package request
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
|
||||
return &http.Request{
|
||||
URL: r.URL,
|
||||
Header: r.Header,
|
||||
Close: r.Close,
|
||||
Form: r.Form,
|
||||
PostForm: r.PostForm,
|
||||
Body: body,
|
||||
MultipartForm: r.MultipartForm,
|
||||
Host: r.Host,
|
||||
Method: r.Method,
|
||||
Proto: r.Proto,
|
||||
ContentLength: r.ContentLength,
|
||||
// Cancel will be deprecated in 1.7 and will be replaced with Context
|
||||
Cancel: r.Cancel,
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
// +build !go1.5
|
||||
|
||||
package request
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
|
||||
return &http.Request{
|
||||
URL: r.URL,
|
||||
Header: r.Header,
|
||||
Close: r.Close,
|
||||
Form: r.Form,
|
||||
PostForm: r.PostForm,
|
||||
Body: body,
|
||||
MultipartForm: r.MultipartForm,
|
||||
Host: r.Host,
|
||||
Method: r.Method,
|
||||
Proto: r.Proto,
|
||||
ContentLength: r.ContentLength,
|
||||
}
|
||||
}
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
// Package session provides a way to create service clients with shared configuration
|
||||
// and handlers.
|
||||
//
|
||||
// Generally this package should be used instead of the `defaults` package.
|
||||
//
|
||||
// A session should be used to share configurations and request handlers between multiple
|
||||
// service clients. When service clients need specific configuration aws.Config can be
|
||||
// used to provide additional configuration directly to the service client.
|
||||
package session
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/endpoints"
|
||||
)
|
||||
|
||||
// A Session provides a central location to create service clients from and
|
||||
// store configurations and request handlers for those services.
|
||||
//
|
||||
// Sessions are safe to create service clients concurrently, but it is not safe
|
||||
// to mutate the session concurrently.
|
||||
type Session struct {
|
||||
Config *aws.Config
|
||||
Handlers request.Handlers
|
||||
}
|
||||
|
||||
// New creates a new instance of the handlers merging in the provided Configs
|
||||
// on top of the SDK's default configurations. Once the session is created it
|
||||
// can be mutated to modify Configs or Handlers. The session is safe to be read
|
||||
// concurrently, but it should not be written to concurrently.
|
||||
//
|
||||
// Example:
|
||||
// // Create a session with the default config and request handlers.
|
||||
// sess := session.New()
|
||||
//
|
||||
// // Create a session with a custom region
|
||||
// sess := session.New(&aws.Config{Region: aws.String("us-east-1")})
|
||||
//
|
||||
// // Create a session, and add additional handlers for all service
|
||||
// // clients created with the session to inherit. Adds logging handler.
|
||||
// sess := session.New()
|
||||
// sess.Handlers.Send.PushFront(func(r *request.Request) {
|
||||
// // Log every request made and its payload
|
||||
// logger.Println("Request: %s/%s, Payload: %s", r.ClientInfo.ServiceName, r.Operation, r.Params)
|
||||
// })
|
||||
//
|
||||
// // Create a S3 client instance from a session
|
||||
// sess := session.New()
|
||||
// svc := s3.New(sess)
|
||||
func New(cfgs ...*aws.Config) *Session {
|
||||
cfg := defaults.Config()
|
||||
handlers := defaults.Handlers()
|
||||
|
||||
// Apply the passed in configs so the configuration can be applied to the
|
||||
// default credential chain
|
||||
cfg.MergeIn(cfgs...)
|
||||
cfg.Credentials = defaults.CredChain(cfg, handlers)
|
||||
|
||||
// Reapply any passed in configs to override credentials if set
|
||||
cfg.MergeIn(cfgs...)
|
||||
|
||||
s := &Session{
|
||||
Config: cfg,
|
||||
Handlers: handlers,
|
||||
}
|
||||
|
||||
initHandlers(s)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func initHandlers(s *Session) {
|
||||
// Add the Validate parameter handler if it is not disabled.
|
||||
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
|
||||
if !aws.BoolValue(s.Config.DisableParamValidation) {
|
||||
s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// Copy creates and returns a copy of the current session, coping the config
|
||||
// and handlers. If any additional configs are provided they will be merged
|
||||
// on top of the session's copied config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a copy of the current session, configured for the us-west-2 region.
|
||||
// sess.Copy(&aws.Config{Region: aws.String("us-west-2")})
|
||||
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
||||
newSession := &Session{
|
||||
Config: s.Config.Copy(cfgs...),
|
||||
Handlers: s.Handlers.Copy(),
|
||||
}
|
||||
|
||||
initHandlers(newSession)
|
||||
|
||||
return newSession
|
||||
}
|
||||
|
||||
// ClientConfig satisfies the client.ConfigProvider interface and is used to
|
||||
// configure the service client instances. Passing the Session to the service
|
||||
// client's constructor (New) will use this method to configure the client.
|
||||
//
|
||||
// Example:
|
||||
// sess := session.New()
|
||||
// s3.New(sess)
|
||||
func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
|
||||
s = s.Copy(cfgs...)
|
||||
endpoint, signingRegion := endpoints.NormalizeEndpoint(
|
||||
aws.StringValue(s.Config.Endpoint), serviceName,
|
||||
aws.StringValue(s.Config.Region), aws.BoolValue(s.Config.DisableSSL))
|
||||
|
||||
return client.Config{
|
||||
Config: s.Config,
|
||||
Handlers: s.Handlers,
|
||||
Endpoint: endpoint,
|
||||
SigningRegion: signingRegion,
|
||||
}
|
||||
}
|
||||
-465
@@ -1,465 +0,0 @@
|
||||
// Package v4 implements signing for AWS V4 signer
|
||||
package v4
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/rest"
|
||||
)
|
||||
|
||||
const (
|
||||
authHeaderPrefix = "AWS4-HMAC-SHA256"
|
||||
timeFormat = "20060102T150405Z"
|
||||
shortTimeFormat = "20060102"
|
||||
)
|
||||
|
||||
var ignoredHeaders = rules{
|
||||
blacklist{
|
||||
mapRule{
|
||||
"Authorization": struct{}{},
|
||||
"User-Agent": struct{}{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// requiredSignedHeaders is a whitelist for build canonical headers.
|
||||
var requiredSignedHeaders = rules{
|
||||
whitelist{
|
||||
mapRule{
|
||||
"Cache-Control": struct{}{},
|
||||
"Content-Disposition": struct{}{},
|
||||
"Content-Encoding": struct{}{},
|
||||
"Content-Language": struct{}{},
|
||||
"Content-Md5": struct{}{},
|
||||
"Content-Type": struct{}{},
|
||||
"Expires": struct{}{},
|
||||
"If-Match": struct{}{},
|
||||
"If-Modified-Since": struct{}{},
|
||||
"If-None-Match": struct{}{},
|
||||
"If-Unmodified-Since": struct{}{},
|
||||
"Range": struct{}{},
|
||||
"X-Amz-Acl": struct{}{},
|
||||
"X-Amz-Copy-Source": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Match": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Modified-Since": struct{}{},
|
||||
"X-Amz-Copy-Source-If-None-Match": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Unmodified-Since": struct{}{},
|
||||
"X-Amz-Copy-Source-Range": struct{}{},
|
||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{},
|
||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
||||
"X-Amz-Grant-Full-control": struct{}{},
|
||||
"X-Amz-Grant-Read": struct{}{},
|
||||
"X-Amz-Grant-Read-Acp": struct{}{},
|
||||
"X-Amz-Grant-Write": struct{}{},
|
||||
"X-Amz-Grant-Write-Acp": struct{}{},
|
||||
"X-Amz-Metadata-Directive": struct{}{},
|
||||
"X-Amz-Mfa": struct{}{},
|
||||
"X-Amz-Request-Payer": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
||||
"X-Amz-Storage-Class": struct{}{},
|
||||
"X-Amz-Website-Redirect-Location": struct{}{},
|
||||
},
|
||||
},
|
||||
patterns{"X-Amz-Meta-"},
|
||||
}
|
||||
|
||||
// allowedHoisting is a whitelist for build query headers. The boolean value
|
||||
// represents whether or not it is a pattern.
|
||||
var allowedQueryHoisting = inclusiveRules{
|
||||
blacklist{requiredSignedHeaders},
|
||||
patterns{"X-Amz-"},
|
||||
}
|
||||
|
||||
type signer struct {
|
||||
Request *http.Request
|
||||
Time time.Time
|
||||
ExpireTime time.Duration
|
||||
ServiceName string
|
||||
Region string
|
||||
CredValues credentials.Value
|
||||
Credentials *credentials.Credentials
|
||||
Query url.Values
|
||||
Body io.ReadSeeker
|
||||
Debug aws.LogLevelType
|
||||
Logger aws.Logger
|
||||
|
||||
isPresign bool
|
||||
formattedTime string
|
||||
formattedShortTime string
|
||||
|
||||
signedHeaders string
|
||||
canonicalHeaders string
|
||||
canonicalString string
|
||||
credentialString string
|
||||
stringToSign string
|
||||
signature string
|
||||
authorization string
|
||||
notHoist bool
|
||||
signedHeaderVals http.Header
|
||||
}
|
||||
|
||||
// Sign requests with signature version 4.
|
||||
//
|
||||
// Will sign the requests with the service config's Credentials object
|
||||
// Signing is skipped if the credentials is the credentials.AnonymousCredentials
|
||||
// object.
|
||||
func Sign(req *request.Request) {
|
||||
// If the request does not need to be signed ignore the signing of the
|
||||
// request if the AnonymousCredentials object is used.
|
||||
if req.Config.Credentials == credentials.AnonymousCredentials {
|
||||
return
|
||||
}
|
||||
|
||||
region := req.ClientInfo.SigningRegion
|
||||
if region == "" {
|
||||
region = aws.StringValue(req.Config.Region)
|
||||
}
|
||||
|
||||
name := req.ClientInfo.SigningName
|
||||
if name == "" {
|
||||
name = req.ClientInfo.ServiceName
|
||||
}
|
||||
|
||||
s := signer{
|
||||
Request: req.HTTPRequest,
|
||||
Time: req.Time,
|
||||
ExpireTime: req.ExpireTime,
|
||||
Query: req.HTTPRequest.URL.Query(),
|
||||
Body: req.Body,
|
||||
ServiceName: name,
|
||||
Region: region,
|
||||
Credentials: req.Config.Credentials,
|
||||
Debug: req.Config.LogLevel.Value(),
|
||||
Logger: req.Config.Logger,
|
||||
notHoist: req.NotHoist,
|
||||
}
|
||||
|
||||
req.Error = s.sign()
|
||||
req.Time = s.Time
|
||||
req.SignedHeaderVals = s.signedHeaderVals
|
||||
}
|
||||
|
||||
func (v4 *signer) sign() error {
|
||||
if v4.ExpireTime != 0 {
|
||||
v4.isPresign = true
|
||||
}
|
||||
|
||||
if v4.isRequestSigned() {
|
||||
if !v4.Credentials.IsExpired() && time.Now().Before(v4.Time.Add(10*time.Minute)) {
|
||||
// If the request is already signed, and the credentials have not
|
||||
// expired, and the request is not too old ignore the signing request.
|
||||
return nil
|
||||
}
|
||||
v4.Time = time.Now()
|
||||
|
||||
// The credentials have expired for this request. The current signing
|
||||
// is invalid, and needs to be request because the request will fail.
|
||||
if v4.isPresign {
|
||||
v4.removePresign()
|
||||
// Update the request's query string to ensure the values stays in
|
||||
// sync in the case retrieving the new credentials fails.
|
||||
v4.Request.URL.RawQuery = v4.Query.Encode()
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
v4.CredValues, err = v4.Credentials.Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v4.isPresign {
|
||||
v4.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
|
||||
if v4.CredValues.SessionToken != "" {
|
||||
v4.Query.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
|
||||
} else {
|
||||
v4.Query.Del("X-Amz-Security-Token")
|
||||
}
|
||||
} else if v4.CredValues.SessionToken != "" {
|
||||
v4.Request.Header.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
|
||||
}
|
||||
|
||||
v4.build()
|
||||
|
||||
if v4.Debug.Matches(aws.LogDebugWithSigning) {
|
||||
v4.logSigningInfo()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const logSignInfoMsg = `DEBUG: Request Signiture:
|
||||
---[ CANONICAL STRING ]-----------------------------
|
||||
%s
|
||||
---[ STRING TO SIGN ]--------------------------------
|
||||
%s%s
|
||||
-----------------------------------------------------`
|
||||
const logSignedURLMsg = `
|
||||
---[ SIGNED URL ]------------------------------------
|
||||
%s`
|
||||
|
||||
func (v4 *signer) logSigningInfo() {
|
||||
signedURLMsg := ""
|
||||
if v4.isPresign {
|
||||
signedURLMsg = fmt.Sprintf(logSignedURLMsg, v4.Request.URL.String())
|
||||
}
|
||||
msg := fmt.Sprintf(logSignInfoMsg, v4.canonicalString, v4.stringToSign, signedURLMsg)
|
||||
v4.Logger.Log(msg)
|
||||
}
|
||||
|
||||
func (v4 *signer) build() {
|
||||
|
||||
v4.buildTime() // no depends
|
||||
v4.buildCredentialString() // no depends
|
||||
|
||||
unsignedHeaders := v4.Request.Header
|
||||
if v4.isPresign {
|
||||
if !v4.notHoist {
|
||||
urlValues := url.Values{}
|
||||
urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends
|
||||
for k := range urlValues {
|
||||
v4.Query[k] = urlValues[k]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v4.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
|
||||
v4.buildCanonicalString() // depends on canon headers / signed headers
|
||||
v4.buildStringToSign() // depends on canon string
|
||||
v4.buildSignature() // depends on string to sign
|
||||
|
||||
if v4.isPresign {
|
||||
v4.Request.URL.RawQuery += "&X-Amz-Signature=" + v4.signature
|
||||
} else {
|
||||
parts := []string{
|
||||
authHeaderPrefix + " Credential=" + v4.CredValues.AccessKeyID + "/" + v4.credentialString,
|
||||
"SignedHeaders=" + v4.signedHeaders,
|
||||
"Signature=" + v4.signature,
|
||||
}
|
||||
v4.Request.Header.Set("Authorization", strings.Join(parts, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
func (v4 *signer) buildTime() {
|
||||
v4.formattedTime = v4.Time.UTC().Format(timeFormat)
|
||||
v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat)
|
||||
|
||||
if v4.isPresign {
|
||||
duration := int64(v4.ExpireTime / time.Second)
|
||||
v4.Query.Set("X-Amz-Date", v4.formattedTime)
|
||||
v4.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
|
||||
} else {
|
||||
v4.Request.Header.Set("X-Amz-Date", v4.formattedTime)
|
||||
}
|
||||
}
|
||||
|
||||
func (v4 *signer) buildCredentialString() {
|
||||
v4.credentialString = strings.Join([]string{
|
||||
v4.formattedShortTime,
|
||||
v4.Region,
|
||||
v4.ServiceName,
|
||||
"aws4_request",
|
||||
}, "/")
|
||||
|
||||
if v4.isPresign {
|
||||
v4.Query.Set("X-Amz-Credential", v4.CredValues.AccessKeyID+"/"+v4.credentialString)
|
||||
}
|
||||
}
|
||||
|
||||
func buildQuery(r rule, header http.Header) (url.Values, http.Header) {
|
||||
query := url.Values{}
|
||||
unsignedHeaders := http.Header{}
|
||||
for k, h := range header {
|
||||
if r.IsValid(k) {
|
||||
query[k] = h
|
||||
} else {
|
||||
unsignedHeaders[k] = h
|
||||
}
|
||||
}
|
||||
|
||||
return query, unsignedHeaders
|
||||
}
|
||||
func (v4 *signer) buildCanonicalHeaders(r rule, header http.Header) {
|
||||
var headers []string
|
||||
headers = append(headers, "host")
|
||||
for k, v := range header {
|
||||
canonicalKey := http.CanonicalHeaderKey(k)
|
||||
if !r.IsValid(canonicalKey) {
|
||||
continue // ignored header
|
||||
}
|
||||
if v4.signedHeaderVals == nil {
|
||||
v4.signedHeaderVals = make(http.Header)
|
||||
}
|
||||
|
||||
lowerCaseKey := strings.ToLower(k)
|
||||
if _, ok := v4.signedHeaderVals[lowerCaseKey]; ok {
|
||||
// include additional values
|
||||
v4.signedHeaderVals[lowerCaseKey] = append(v4.signedHeaderVals[lowerCaseKey], v...)
|
||||
continue
|
||||
}
|
||||
|
||||
headers = append(headers, lowerCaseKey)
|
||||
v4.signedHeaderVals[lowerCaseKey] = v
|
||||
}
|
||||
sort.Strings(headers)
|
||||
|
||||
v4.signedHeaders = strings.Join(headers, ";")
|
||||
|
||||
if v4.isPresign {
|
||||
v4.Query.Set("X-Amz-SignedHeaders", v4.signedHeaders)
|
||||
}
|
||||
|
||||
headerValues := make([]string, len(headers))
|
||||
for i, k := range headers {
|
||||
if k == "host" {
|
||||
headerValues[i] = "host:" + v4.Request.URL.Host
|
||||
} else {
|
||||
headerValues[i] = k + ":" +
|
||||
strings.Join(v4.signedHeaderVals[k], ",")
|
||||
}
|
||||
}
|
||||
|
||||
v4.canonicalHeaders = strings.Join(stripExcessSpaces(headerValues), "\n")
|
||||
}
|
||||
|
||||
func (v4 *signer) buildCanonicalString() {
|
||||
v4.Request.URL.RawQuery = strings.Replace(v4.Query.Encode(), "+", "%20", -1)
|
||||
uri := v4.Request.URL.Opaque
|
||||
if uri != "" {
|
||||
uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/")
|
||||
} else {
|
||||
uri = v4.Request.URL.Path
|
||||
}
|
||||
if uri == "" {
|
||||
uri = "/"
|
||||
}
|
||||
|
||||
if v4.ServiceName != "s3" {
|
||||
uri = rest.EscapePath(uri, false)
|
||||
}
|
||||
|
||||
v4.canonicalString = strings.Join([]string{
|
||||
v4.Request.Method,
|
||||
uri,
|
||||
v4.Request.URL.RawQuery,
|
||||
v4.canonicalHeaders + "\n",
|
||||
v4.signedHeaders,
|
||||
v4.bodyDigest(),
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
func (v4 *signer) buildStringToSign() {
|
||||
v4.stringToSign = strings.Join([]string{
|
||||
authHeaderPrefix,
|
||||
v4.formattedTime,
|
||||
v4.credentialString,
|
||||
hex.EncodeToString(makeSha256([]byte(v4.canonicalString))),
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
func (v4 *signer) buildSignature() {
|
||||
secret := v4.CredValues.SecretAccessKey
|
||||
date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
|
||||
region := makeHmac(date, []byte(v4.Region))
|
||||
service := makeHmac(region, []byte(v4.ServiceName))
|
||||
credentials := makeHmac(service, []byte("aws4_request"))
|
||||
signature := makeHmac(credentials, []byte(v4.stringToSign))
|
||||
v4.signature = hex.EncodeToString(signature)
|
||||
}
|
||||
|
||||
func (v4 *signer) bodyDigest() string {
|
||||
hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
|
||||
if hash == "" {
|
||||
if v4.isPresign && v4.ServiceName == "s3" {
|
||||
hash = "UNSIGNED-PAYLOAD"
|
||||
} else if v4.Body == nil {
|
||||
hash = hex.EncodeToString(makeSha256([]byte{}))
|
||||
} else {
|
||||
hash = hex.EncodeToString(makeSha256Reader(v4.Body))
|
||||
}
|
||||
v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
// isRequestSigned returns if the request is currently signed or presigned
|
||||
func (v4 *signer) isRequestSigned() bool {
|
||||
if v4.isPresign && v4.Query.Get("X-Amz-Signature") != "" {
|
||||
return true
|
||||
}
|
||||
if v4.Request.Header.Get("Authorization") != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// unsign removes signing flags for both signed and presigned requests.
|
||||
func (v4 *signer) removePresign() {
|
||||
v4.Query.Del("X-Amz-Algorithm")
|
||||
v4.Query.Del("X-Amz-Signature")
|
||||
v4.Query.Del("X-Amz-Security-Token")
|
||||
v4.Query.Del("X-Amz-Date")
|
||||
v4.Query.Del("X-Amz-Expires")
|
||||
v4.Query.Del("X-Amz-Credential")
|
||||
v4.Query.Del("X-Amz-SignedHeaders")
|
||||
}
|
||||
|
||||
func makeHmac(key []byte, data []byte) []byte {
|
||||
hash := hmac.New(sha256.New, key)
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func makeSha256(data []byte) []byte {
|
||||
hash := sha256.New()
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func makeSha256Reader(reader io.ReadSeeker) []byte {
|
||||
hash := sha256.New()
|
||||
start, _ := reader.Seek(0, 1)
|
||||
defer reader.Seek(start, 0)
|
||||
|
||||
io.Copy(hash, reader)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func stripExcessSpaces(headerVals []string) []string {
|
||||
vals := make([]string, len(headerVals))
|
||||
for i, str := range headerVals {
|
||||
stripped := ""
|
||||
found := false
|
||||
str = strings.TrimSpace(str)
|
||||
for _, c := range str {
|
||||
if !found && c == ' ' {
|
||||
stripped += string(c)
|
||||
found = true
|
||||
} else if c != ' ' {
|
||||
stripped += string(c)
|
||||
found = false
|
||||
}
|
||||
}
|
||||
vals[i] = stripped
|
||||
}
|
||||
return vals
|
||||
}
|
||||
-6785
File diff suppressed because it is too large
Load Diff
-44
@@ -1,44 +0,0 @@
|
||||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// tokenListContainsValue returns true if the 1#token header with the given
|
||||
// name contains token.
|
||||
func tokenListContainsValue(header http.Header, name string, value string) bool {
|
||||
for _, v := range header[name] {
|
||||
for _, s := range strings.Split(v, ",") {
|
||||
if strings.EqualFold(value, strings.TrimSpace(s)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
|
||||
|
||||
func computeAcceptKey(challengeKey string) string {
|
||||
h := sha1.New()
|
||||
h.Write([]byte(challengeKey))
|
||||
h.Write(keyGUID)
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func generateChallengeKey() (string, error) {
|
||||
p := make([]byte, 16)
|
||||
if _, err := io.ReadFull(rand.Reader, p); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(p), nil
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
script:
|
||||
- go test -race -v -bench=.
|
||||
-1957
File diff suppressed because it is too large
Load Diff
-95
@@ -1,95 +0,0 @@
|
||||
package dns
|
||||
|
||||
// These raw* functions do not use reflection, they directly set the values
|
||||
// in the buffer. There are faster than their reflection counterparts.
|
||||
|
||||
// RawSetId sets the message id in buf.
|
||||
func rawSetId(msg []byte, i uint16) bool {
|
||||
if len(msg) < 2 {
|
||||
return false
|
||||
}
|
||||
msg[0], msg[1] = packUint16(i)
|
||||
return true
|
||||
}
|
||||
|
||||
// rawSetQuestionLen sets the length of the question section.
|
||||
func rawSetQuestionLen(msg []byte, i uint16) bool {
|
||||
if len(msg) < 6 {
|
||||
return false
|
||||
}
|
||||
msg[4], msg[5] = packUint16(i)
|
||||
return true
|
||||
}
|
||||
|
||||
// rawSetAnswerLen sets the length of the answer section.
|
||||
func rawSetAnswerLen(msg []byte, i uint16) bool {
|
||||
if len(msg) < 8 {
|
||||
return false
|
||||
}
|
||||
msg[6], msg[7] = packUint16(i)
|
||||
return true
|
||||
}
|
||||
|
||||
// rawSetsNsLen sets the length of the authority section.
|
||||
func rawSetNsLen(msg []byte, i uint16) bool {
|
||||
if len(msg) < 10 {
|
||||
return false
|
||||
}
|
||||
msg[8], msg[9] = packUint16(i)
|
||||
return true
|
||||
}
|
||||
|
||||
// rawSetExtraLen sets the length of the additional section.
|
||||
func rawSetExtraLen(msg []byte, i uint16) bool {
|
||||
if len(msg) < 12 {
|
||||
return false
|
||||
}
|
||||
msg[10], msg[11] = packUint16(i)
|
||||
return true
|
||||
}
|
||||
|
||||
// rawSetRdlength sets the rdlength in the header of
|
||||
// the RR. The offset 'off' must be positioned at the
|
||||
// start of the header of the RR, 'end' must be the
|
||||
// end of the RR.
|
||||
func rawSetRdlength(msg []byte, off, end int) bool {
|
||||
l := len(msg)
|
||||
Loop:
|
||||
for {
|
||||
if off+1 > l {
|
||||
return false
|
||||
}
|
||||
c := int(msg[off])
|
||||
off++
|
||||
switch c & 0xC0 {
|
||||
case 0x00:
|
||||
if c == 0x00 {
|
||||
// End of the domainname
|
||||
break Loop
|
||||
}
|
||||
if off+c > l {
|
||||
return false
|
||||
}
|
||||
off += c
|
||||
|
||||
case 0xC0:
|
||||
// pointer, next byte included, ends domainname
|
||||
off++
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
// The domainname has been seen, we at the start of the fixed part in the header.
|
||||
// Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length.
|
||||
off += 2 + 2 + 4
|
||||
if off+2 > l {
|
||||
return false
|
||||
}
|
||||
//off+1 is the end of the header, 'end' is the end of the rr
|
||||
//so 'end' - 'off+2' is the length of the rdata
|
||||
rdatalen := end - (off + 2)
|
||||
if rdatalen > 0xFFFF {
|
||||
return false
|
||||
}
|
||||
msg[off], msg[off+1] = packUint16(uint16(rdatalen))
|
||||
return true
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// CertificateToDANE converts a certificate to a hex string as used in the TLSA record.
|
||||
func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) {
|
||||
switch matchingType {
|
||||
case 0:
|
||||
switch selector {
|
||||
case 0:
|
||||
return hex.EncodeToString(cert.Raw), nil
|
||||
case 1:
|
||||
return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil
|
||||
}
|
||||
case 1:
|
||||
h := sha256.New()
|
||||
switch selector {
|
||||
case 0:
|
||||
io.WriteString(h, string(cert.Raw))
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
case 1:
|
||||
io.WriteString(h, string(cert.RawSubjectPublicKeyInfo))
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
}
|
||||
case 2:
|
||||
h := sha512.New()
|
||||
switch selector {
|
||||
case 0:
|
||||
io.WriteString(h, string(cert.Raw))
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
case 1:
|
||||
io.WriteString(h, string(cert.RawSubjectPublicKeyInfo))
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("dns: bad TLSA MatchingType or TLSA Selector")
|
||||
}
|
||||
|
||||
// Sign creates a TLSA record from an SSL certificate.
|
||||
func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
|
||||
r.Hdr.Rrtype = TypeTLSA
|
||||
r.Usage = uint8(usage)
|
||||
r.Selector = uint8(selector)
|
||||
r.MatchingType = uint8(matchingType)
|
||||
|
||||
r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify verifies a TLSA record against an SSL certificate. If it is OK
|
||||
// a nil error is returned.
|
||||
func (r *TLSA) Verify(cert *x509.Certificate) error {
|
||||
c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
|
||||
if err != nil {
|
||||
return err // Not also ErrSig?
|
||||
}
|
||||
if r.Certificate == c {
|
||||
return nil
|
||||
}
|
||||
return ErrSig // ErrSig, really?
|
||||
}
|
||||
|
||||
// TLSAName returns the ownername of a TLSA resource record as per the
|
||||
// rules specified in RFC 6698, Section 3.
|
||||
func TLSAName(name, service, network string) (string, error) {
|
||||
if !IsFqdn(name) {
|
||||
return "", ErrFqdn
|
||||
}
|
||||
p, e := net.LookupPort(network, service)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil
|
||||
}
|
||||
-185
@@ -1,185 +0,0 @@
|
||||
This software is licensed under the LGPLv3, included below.
|
||||
|
||||
As a special exception to the GNU Lesser General Public License version 3
|
||||
("LGPL3"), the copyright holders of this Library give you permission to
|
||||
convey to a third party a Combined Work that links statically or dynamically
|
||||
to this Library without providing any Minimal Corresponding Source or
|
||||
Minimal Application Code as set out in 4d or providing the installation
|
||||
information set out in section 4e, provided that you comply with the other
|
||||
provisions of LGPL3 and provided that you meet, for the Application the
|
||||
terms and conditions of the license(s) which apply to the Application.
|
||||
|
||||
Except as stated in this special exception, the provisions of LGPL3 will
|
||||
continue to comply in full to this Library. If you modify this Library, you
|
||||
may apply this exception to your version of this Library, but you are not
|
||||
obliged to do so. If you do not wish to do so, delete this exception
|
||||
statement from your version. This exception does not (and cannot) modify any
|
||||
license terms which apply to the Application, with which you must still
|
||||
comply.
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
-8786
File diff suppressed because it is too large
Load Diff
-63
@@ -1,63 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build 386,dragonfly
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
|
||||
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||
ts.Sec = int32(nsec / 1e9)
|
||||
ts.Nsec = int32(nsec % 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
||||
|
||||
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint32(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
||||
func (iov *Iovec) SetLen(length int) {
|
||||
iov.Len = uint32(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) {
|
||||
msghdr.Controllen = uint32(length)
|
||||
}
|
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||
var writtenOut uint64 = 0
|
||||
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)
|
||||
|
||||
written = int(writtenOut)
|
||||
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
-1530
File diff suppressed because it is too large
Load Diff
-304
@@ -1,304 +0,0 @@
|
||||
// mksysnum_dragonfly.pl
|
||||
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
||||
|
||||
// +build 386,dragonfly
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
// SYS_NOSYS = 0; // { int nosys(void); } syscall nosys_args int
|
||||
SYS_EXIT = 1 // { void exit(int rval); }
|
||||
SYS_FORK = 2 // { int fork(void); }
|
||||
SYS_READ = 3 // { ssize_t read(int fd, void *buf, size_t nbyte); }
|
||||
SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, size_t nbyte); }
|
||||
SYS_OPEN = 5 // { int open(char *path, int flags, int mode); }
|
||||
SYS_CLOSE = 6 // { int close(int fd); }
|
||||
SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, \
|
||||
SYS_LINK = 9 // { int link(char *path, char *link); }
|
||||
SYS_UNLINK = 10 // { int unlink(char *path); }
|
||||
SYS_CHDIR = 12 // { int chdir(char *path); }
|
||||
SYS_FCHDIR = 13 // { int fchdir(int fd); }
|
||||
SYS_MKNOD = 14 // { int mknod(char *path, int mode, int dev); }
|
||||
SYS_CHMOD = 15 // { int chmod(char *path, int mode); }
|
||||
SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); }
|
||||
SYS_OBREAK = 17 // { int obreak(char *nsize); } break obreak_args int
|
||||
SYS_GETFSSTAT = 18 // { int getfsstat(struct statfs *buf, long bufsize, \
|
||||
SYS_GETPID = 20 // { pid_t getpid(void); }
|
||||
SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, \
|
||||
SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); }
|
||||
SYS_SETUID = 23 // { int setuid(uid_t uid); }
|
||||
SYS_GETUID = 24 // { uid_t getuid(void); }
|
||||
SYS_GETEUID = 25 // { uid_t geteuid(void); }
|
||||
SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, \
|
||||
SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, int flags); }
|
||||
SYS_SENDMSG = 28 // { int sendmsg(int s, caddr_t msg, int flags); }
|
||||
SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, \
|
||||
SYS_ACCEPT = 30 // { int accept(int s, caddr_t name, int *anamelen); }
|
||||
SYS_GETPEERNAME = 31 // { int getpeername(int fdes, caddr_t asa, int *alen); }
|
||||
SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, caddr_t asa, int *alen); }
|
||||
SYS_ACCESS = 33 // { int access(char *path, int flags); }
|
||||
SYS_CHFLAGS = 34 // { int chflags(char *path, int flags); }
|
||||
SYS_FCHFLAGS = 35 // { int fchflags(int fd, int flags); }
|
||||
SYS_SYNC = 36 // { int sync(void); }
|
||||
SYS_KILL = 37 // { int kill(int pid, int signum); }
|
||||
SYS_GETPPID = 39 // { pid_t getppid(void); }
|
||||
SYS_DUP = 41 // { int dup(u_int fd); }
|
||||
SYS_PIPE = 42 // { int pipe(void); }
|
||||
SYS_GETEGID = 43 // { gid_t getegid(void); }
|
||||
SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, \
|
||||
SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, \
|
||||
SYS_GETGID = 47 // { gid_t getgid(void); }
|
||||
SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int namelen); }
|
||||
SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); }
|
||||
SYS_ACCT = 51 // { int acct(char *path); }
|
||||
SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, stack_t *oss); }
|
||||
SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, caddr_t data); }
|
||||
SYS_REBOOT = 55 // { int reboot(int opt); }
|
||||
SYS_REVOKE = 56 // { int revoke(char *path); }
|
||||
SYS_SYMLINK = 57 // { int symlink(char *path, char *link); }
|
||||
SYS_READLINK = 58 // { int readlink(char *path, char *buf, int count); }
|
||||
SYS_EXECVE = 59 // { int execve(char *fname, char **argv, char **envv); }
|
||||
SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args int
|
||||
SYS_CHROOT = 61 // { int chroot(char *path); }
|
||||
SYS_MSYNC = 65 // { int msync(void *addr, size_t len, int flags); }
|
||||
SYS_VFORK = 66 // { pid_t vfork(void); }
|
||||
SYS_SBRK = 69 // { int sbrk(int incr); }
|
||||
SYS_SSTK = 70 // { int sstk(int incr); }
|
||||
SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); }
|
||||
SYS_MPROTECT = 74 // { int mprotect(void *addr, size_t len, int prot); }
|
||||
SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, int behav); }
|
||||
SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, \
|
||||
SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, gid_t *gidset); }
|
||||
SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, gid_t *gidset); }
|
||||
SYS_GETPGRP = 81 // { int getpgrp(void); }
|
||||
SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); }
|
||||
SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, \
|
||||
SYS_SWAPON = 85 // { int swapon(char *name); }
|
||||
SYS_GETITIMER = 86 // { int getitimer(u_int which, struct itimerval *itv); }
|
||||
SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); }
|
||||
SYS_DUP2 = 90 // { int dup2(u_int from, u_int to); }
|
||||
SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); }
|
||||
SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, \
|
||||
SYS_FSYNC = 95 // { int fsync(int fd); }
|
||||
SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, int prio); }
|
||||
SYS_SOCKET = 97 // { int socket(int domain, int type, int protocol); }
|
||||
SYS_CONNECT = 98 // { int connect(int s, caddr_t name, int namelen); }
|
||||
SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); }
|
||||
SYS_BIND = 104 // { int bind(int s, caddr_t name, int namelen); }
|
||||
SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, \
|
||||
SYS_LISTEN = 106 // { int listen(int s, int backlog); }
|
||||
SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, \
|
||||
SYS_GETRUSAGE = 117 // { int getrusage(int who, struct rusage *rusage); }
|
||||
SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, \
|
||||
SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); }
|
||||
SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, \
|
||||
SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, \
|
||||
SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); }
|
||||
SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); }
|
||||
SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); }
|
||||
SYS_SETREGID = 127 // { int setregid(int rgid, int egid); }
|
||||
SYS_RENAME = 128 // { int rename(char *from, char *to); }
|
||||
SYS_FLOCK = 131 // { int flock(int fd, int how); }
|
||||
SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); }
|
||||
SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, \
|
||||
SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); }
|
||||
SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, \
|
||||
SYS_MKDIR = 136 // { int mkdir(char *path, int mode); }
|
||||
SYS_RMDIR = 137 // { int rmdir(char *path); }
|
||||
SYS_UTIMES = 138 // { int utimes(char *path, struct timeval *tptr); }
|
||||
SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, \
|
||||
SYS_SETSID = 147 // { int setsid(void); }
|
||||
SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, \
|
||||
SYS_STATFS = 157 // { int statfs(char *path, struct statfs *buf); }
|
||||
SYS_FSTATFS = 158 // { int fstatfs(int fd, struct statfs *buf); }
|
||||
SYS_GETFH = 161 // { int getfh(char *fname, struct fhandle *fhp); }
|
||||
SYS_GETDOMAINNAME = 162 // { int getdomainname(char *domainname, int len); }
|
||||
SYS_SETDOMAINNAME = 163 // { int setdomainname(char *domainname, int len); }
|
||||
SYS_UNAME = 164 // { int uname(struct utsname *name); }
|
||||
SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); }
|
||||
SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, \
|
||||
SYS_EXTPREAD = 173 // { ssize_t extpread(int fd, void *buf, \
|
||||
SYS_EXTPWRITE = 174 // { ssize_t extpwrite(int fd, const void *buf, \
|
||||
SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); }
|
||||
SYS_SETGID = 181 // { int setgid(gid_t gid); }
|
||||
SYS_SETEGID = 182 // { int setegid(gid_t egid); }
|
||||
SYS_SETEUID = 183 // { int seteuid(uid_t euid); }
|
||||
SYS_PATHCONF = 191 // { int pathconf(char *path, int name); }
|
||||
SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); }
|
||||
SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, \
|
||||
SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, \
|
||||
SYS_MMAP = 197 // { caddr_t mmap(caddr_t addr, size_t len, int prot, \
|
||||
// SYS_NOSYS = 198; // { int nosys(void); } __syscall __syscall_args int
|
||||
SYS_LSEEK = 199 // { off_t lseek(int fd, int pad, off_t offset, \
|
||||
SYS_TRUNCATE = 200 // { int truncate(char *path, int pad, off_t length); }
|
||||
SYS_FTRUNCATE = 201 // { int ftruncate(int fd, int pad, off_t length); }
|
||||
SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, void *old, \
|
||||
SYS_MLOCK = 203 // { int mlock(const void *addr, size_t len); }
|
||||
SYS_MUNLOCK = 204 // { int munlock(const void *addr, size_t len); }
|
||||
SYS_UNDELETE = 205 // { int undelete(char *path); }
|
||||
SYS_FUTIMES = 206 // { int futimes(int fd, struct timeval *tptr); }
|
||||
SYS_GETPGID = 207 // { int getpgid(pid_t pid); }
|
||||
SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, \
|
||||
SYS___SEMCTL = 220 // { int __semctl(int semid, int semnum, int cmd, \
|
||||
SYS_SEMGET = 221 // { int semget(key_t key, int nsems, int semflg); }
|
||||
SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, \
|
||||
SYS_MSGCTL = 224 // { int msgctl(int msqid, int cmd, \
|
||||
SYS_MSGGET = 225 // { int msgget(key_t key, int msgflg); }
|
||||
SYS_MSGSND = 226 // { int msgsnd(int msqid, void *msgp, size_t msgsz, \
|
||||
SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, \
|
||||
SYS_SHMAT = 228 // { caddr_t shmat(int shmid, const void *shmaddr, \
|
||||
SYS_SHMCTL = 229 // { int shmctl(int shmid, int cmd, \
|
||||
SYS_SHMDT = 230 // { int shmdt(const void *shmaddr); }
|
||||
SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, int shmflg); }
|
||||
SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, \
|
||||
SYS_CLOCK_SETTIME = 233 // { int clock_settime(clockid_t clock_id, \
|
||||
SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, \
|
||||
SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, \
|
||||
SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, int inherit); }
|
||||
SYS_RFORK = 251 // { int rfork(int flags); }
|
||||
SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, \
|
||||
SYS_ISSETUGID = 253 // { int issetugid(void); }
|
||||
SYS_LCHOWN = 254 // { int lchown(char *path, int uid, int gid); }
|
||||
SYS_LCHMOD = 274 // { int lchmod(char *path, mode_t mode); }
|
||||
SYS_LUTIMES = 276 // { int lutimes(char *path, struct timeval *tptr); }
|
||||
SYS_EXTPREADV = 289 // { ssize_t extpreadv(int fd, struct iovec *iovp, \
|
||||
SYS_EXTPWRITEV = 290 // { ssize_t extpwritev(int fd, struct iovec *iovp,\
|
||||
SYS_FHSTATFS = 297 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
|
||||
SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); }
|
||||
SYS_MODNEXT = 300 // { int modnext(int modid); }
|
||||
SYS_MODSTAT = 301 // { int modstat(int modid, struct module_stat* stat); }
|
||||
SYS_MODFNEXT = 302 // { int modfnext(int modid); }
|
||||
SYS_MODFIND = 303 // { int modfind(const char *name); }
|
||||
SYS_KLDLOAD = 304 // { int kldload(const char *file); }
|
||||
SYS_KLDUNLOAD = 305 // { int kldunload(int fileid); }
|
||||
SYS_KLDFIND = 306 // { int kldfind(const char *file); }
|
||||
SYS_KLDNEXT = 307 // { int kldnext(int fileid); }
|
||||
SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); }
|
||||
SYS_KLDFIRSTMOD = 309 // { int kldfirstmod(int fileid); }
|
||||
SYS_GETSID = 310 // { int getsid(pid_t pid); }
|
||||
SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
|
||||
SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
|
||||
SYS_AIO_RETURN = 314 // { int aio_return(struct aiocb *aiocbp); }
|
||||
SYS_AIO_SUSPEND = 315 // { int aio_suspend(struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
|
||||
SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); }
|
||||
SYS_AIO_ERROR = 317 // { int aio_error(struct aiocb *aiocbp); }
|
||||
SYS_AIO_READ = 318 // { int aio_read(struct aiocb *aiocbp); }
|
||||
SYS_AIO_WRITE = 319 // { int aio_write(struct aiocb *aiocbp); }
|
||||
SYS_LIO_LISTIO = 320 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); }
|
||||
SYS_YIELD = 321 // { int yield(void); }
|
||||
SYS_MLOCKALL = 324 // { int mlockall(int how); }
|
||||
SYS_MUNLOCKALL = 325 // { int munlockall(void); }
|
||||
SYS___GETCWD = 326 // { int __getcwd(u_char *buf, u_int buflen); }
|
||||
SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); }
|
||||
SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); }
|
||||
SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
|
||||
SYS_SCHED_GETSCHEDULER = 330 // { int sched_getscheduler (pid_t pid); }
|
||||
SYS_SCHED_YIELD = 331 // { int sched_yield (void); }
|
||||
SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); }
|
||||
SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); }
|
||||
SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, struct timespec *interval); }
|
||||
SYS_UTRACE = 335 // { int utrace(const void *addr, size_t len); }
|
||||
SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, void *data); }
|
||||
SYS_JAIL = 338 // { int jail(struct jail *jail); }
|
||||
SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, const sigset_t *set, \
|
||||
SYS_SIGSUSPEND = 341 // { int sigsuspend(const sigset_t *sigmask); }
|
||||
SYS_SIGACTION = 342 // { int sigaction(int sig, const struct sigaction *act, \
|
||||
SYS_SIGPENDING = 343 // { int sigpending(sigset_t *set); }
|
||||
SYS_SIGRETURN = 344 // { int sigreturn(ucontext_t *sigcntxp); }
|
||||
SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set,\
|
||||
SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set,\
|
||||
SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, \
|
||||
SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, \
|
||||
SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, acl_type_t type, \
|
||||
SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, acl_type_t type, \
|
||||
SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, \
|
||||
SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, acl_type_t type); }
|
||||
SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, \
|
||||
SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, \
|
||||
SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, \
|
||||
SYS_EXTATTR_SET_FILE = 356 // { int extattr_set_file(const char *path, \
|
||||
SYS_EXTATTR_GET_FILE = 357 // { int extattr_get_file(const char *path, \
|
||||
SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, \
|
||||
SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
|
||||
SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
|
||||
SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
|
||||
SYS_KQUEUE = 362 // { int kqueue(void); }
|
||||
SYS_KEVENT = 363 // { int kevent(int fd, \
|
||||
SYS_SCTP_PEELOFF = 364 // { int sctp_peeloff(int sd, caddr_t name ); }
|
||||
SYS_LCHFLAGS = 391 // { int lchflags(char *path, int flags); }
|
||||
SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, int count); }
|
||||
SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, \
|
||||
SYS_VARSYM_SET = 450 // { int varsym_set(int level, const char *name, const char *data); }
|
||||
SYS_VARSYM_GET = 451 // { int varsym_get(int mask, const char *wild, char *buf, int bufsize); }
|
||||
SYS_VARSYM_LIST = 452 // { int varsym_list(int level, char *buf, int maxsize, int *marker); }
|
||||
SYS_EXEC_SYS_REGISTER = 465 // { int exec_sys_register(void *entry); }
|
||||
SYS_EXEC_SYS_UNREGISTER = 466 // { int exec_sys_unregister(int id); }
|
||||
SYS_SYS_CHECKPOINT = 467 // { int sys_checkpoint(int type, int fd, pid_t pid, int retval); }
|
||||
SYS_MOUNTCTL = 468 // { int mountctl(const char *path, int op, int fd, const void *ctl, int ctllen, void *buf, int buflen); }
|
||||
SYS_UMTX_SLEEP = 469 // { int umtx_sleep(volatile const int *ptr, int value, int timeout); }
|
||||
SYS_UMTX_WAKEUP = 470 // { int umtx_wakeup(volatile const int *ptr, int count); }
|
||||
SYS_JAIL_ATTACH = 471 // { int jail_attach(int jid); }
|
||||
SYS_SET_TLS_AREA = 472 // { int set_tls_area(int which, struct tls_info *info, size_t infosize); }
|
||||
SYS_GET_TLS_AREA = 473 // { int get_tls_area(int which, struct tls_info *info, size_t infosize); }
|
||||
SYS_CLOSEFROM = 474 // { int closefrom(int fd); }
|
||||
SYS_STAT = 475 // { int stat(const char *path, struct stat *ub); }
|
||||
SYS_FSTAT = 476 // { int fstat(int fd, struct stat *sb); }
|
||||
SYS_LSTAT = 477 // { int lstat(const char *path, struct stat *ub); }
|
||||
SYS_FHSTAT = 478 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
|
||||
SYS_GETDIRENTRIES = 479 // { int getdirentries(int fd, char *buf, u_int count, \
|
||||
SYS_GETDENTS = 480 // { int getdents(int fd, char *buf, size_t count); }
|
||||
SYS_USCHED_SET = 481 // { int usched_set(pid_t pid, int cmd, void *data, \
|
||||
SYS_EXTACCEPT = 482 // { int extaccept(int s, int flags, caddr_t name, int *anamelen); }
|
||||
SYS_EXTCONNECT = 483 // { int extconnect(int s, int flags, caddr_t name, int namelen); }
|
||||
SYS_MCONTROL = 485 // { int mcontrol(void *addr, size_t len, int behav, off_t value); }
|
||||
SYS_VMSPACE_CREATE = 486 // { int vmspace_create(void *id, int type, void *data); }
|
||||
SYS_VMSPACE_DESTROY = 487 // { int vmspace_destroy(void *id); }
|
||||
SYS_VMSPACE_CTL = 488 // { int vmspace_ctl(void *id, int cmd, \
|
||||
SYS_VMSPACE_MMAP = 489 // { int vmspace_mmap(void *id, void *addr, size_t len, \
|
||||
SYS_VMSPACE_MUNMAP = 490 // { int vmspace_munmap(void *id, void *addr, \
|
||||
SYS_VMSPACE_MCONTROL = 491 // { int vmspace_mcontrol(void *id, void *addr, \
|
||||
SYS_VMSPACE_PREAD = 492 // { ssize_t vmspace_pread(void *id, void *buf, \
|
||||
SYS_VMSPACE_PWRITE = 493 // { ssize_t vmspace_pwrite(void *id, const void *buf, \
|
||||
SYS_EXTEXIT = 494 // { void extexit(int how, int status, void *addr); }
|
||||
SYS_LWP_CREATE = 495 // { int lwp_create(struct lwp_params *params); }
|
||||
SYS_LWP_GETTID = 496 // { lwpid_t lwp_gettid(void); }
|
||||
SYS_LWP_KILL = 497 // { int lwp_kill(pid_t pid, lwpid_t tid, int signum); }
|
||||
SYS_LWP_RTPRIO = 498 // { int lwp_rtprio(int function, pid_t pid, lwpid_t tid, struct rtprio *rtp); }
|
||||
SYS_PSELECT = 499 // { int pselect(int nd, fd_set *in, fd_set *ou, \
|
||||
SYS_STATVFS = 500 // { int statvfs(const char *path, struct statvfs *buf); }
|
||||
SYS_FSTATVFS = 501 // { int fstatvfs(int fd, struct statvfs *buf); }
|
||||
SYS_FHSTATVFS = 502 // { int fhstatvfs(const struct fhandle *u_fhp, struct statvfs *buf); }
|
||||
SYS_GETVFSSTAT = 503 // { int getvfsstat(struct statfs *buf, \
|
||||
SYS_OPENAT = 504 // { int openat(int fd, char *path, int flags, int mode); }
|
||||
SYS_FSTATAT = 505 // { int fstatat(int fd, char *path, \
|
||||
SYS_FCHMODAT = 506 // { int fchmodat(int fd, char *path, int mode, \
|
||||
SYS_FCHOWNAT = 507 // { int fchownat(int fd, char *path, int uid, int gid, \
|
||||
SYS_UNLINKAT = 508 // { int unlinkat(int fd, char *path, int flags); }
|
||||
SYS_FACCESSAT = 509 // { int faccessat(int fd, char *path, int amode, \
|
||||
SYS_MQ_OPEN = 510 // { mqd_t mq_open(const char * name, int oflag, \
|
||||
SYS_MQ_CLOSE = 511 // { int mq_close(mqd_t mqdes); }
|
||||
SYS_MQ_UNLINK = 512 // { int mq_unlink(const char *name); }
|
||||
SYS_MQ_GETATTR = 513 // { int mq_getattr(mqd_t mqdes, \
|
||||
SYS_MQ_SETATTR = 514 // { int mq_setattr(mqd_t mqdes, \
|
||||
SYS_MQ_NOTIFY = 515 // { int mq_notify(mqd_t mqdes, \
|
||||
SYS_MQ_SEND = 516 // { int mq_send(mqd_t mqdes, const char *msg_ptr, \
|
||||
SYS_MQ_RECEIVE = 517 // { ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, \
|
||||
SYS_MQ_TIMEDSEND = 518 // { int mq_timedsend(mqd_t mqdes, \
|
||||
SYS_MQ_TIMEDRECEIVE = 519 // { ssize_t mq_timedreceive(mqd_t mqdes, \
|
||||
SYS_IOPRIO_SET = 520 // { int ioprio_set(int which, int who, int prio); }
|
||||
SYS_IOPRIO_GET = 521 // { int ioprio_get(int which, int who); }
|
||||
SYS_CHROOT_KERNEL = 522 // { int chroot_kernel(char *path); }
|
||||
SYS_RENAMEAT = 523 // { int renameat(int oldfd, char *old, int newfd, \
|
||||
SYS_MKDIRAT = 524 // { int mkdirat(int fd, char *path, mode_t mode); }
|
||||
SYS_MKFIFOAT = 525 // { int mkfifoat(int fd, char *path, mode_t mode); }
|
||||
SYS_MKNODAT = 526 // { int mknodat(int fd, char *path, mode_t mode, \
|
||||
SYS_READLINKAT = 527 // { int readlinkat(int fd, char *path, char *buf, \
|
||||
SYS_SYMLINKAT = 528 // { int symlinkat(char *path1, int fd, char *path2); }
|
||||
SYS_SWAPOFF = 529 // { int swapoff(char *name); }
|
||||
SYS_VQUOTACTL = 530 // { int vquotactl(const char *path, \
|
||||
SYS_LINKAT = 531 // { int linkat(int fd1, char *path1, int fd2, \
|
||||
SYS_EACCESS = 532 // { int eaccess(char *path, int flags); }
|
||||
SYS_LPATHCONF = 533 // { int lpathconf(char *path, int name); }
|
||||
SYS_VMM_GUEST_CTL = 534 // { int vmm_guest_ctl(int op, struct vmm_guest_options *options); }
|
||||
SYS_VMM_GUEST_SYNC_ADDR = 535 // { int vmm_guest_sync_addr(long *dstaddr, long *srcaddr); }
|
||||
)
|
||||
-437
@@ -1,437 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_dragonfly.go
|
||||
|
||||
// +build 386,dragonfly
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
sizeofPtr = 0x4
|
||||
sizeofShort = 0x2
|
||||
sizeofInt = 0x4
|
||||
sizeofLong = 0x4
|
||||
sizeofLongLong = 0x8
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int32
|
||||
_C_long_long int64
|
||||
)
|
||||
|
||||
type Timespec struct {
|
||||
Sec int32
|
||||
Nsec int32
|
||||
}
|
||||
|
||||
type Timeval struct {
|
||||
Sec int32
|
||||
Usec int32
|
||||
}
|
||||
|
||||
type Rusage struct {
|
||||
Utime Timeval
|
||||
Stime Timeval
|
||||
Maxrss int32
|
||||
Ixrss int32
|
||||
Idrss int32
|
||||
Isrss int32
|
||||
Minflt int32
|
||||
Majflt int32
|
||||
Nswap int32
|
||||
Inblock int32
|
||||
Oublock int32
|
||||
Msgsnd int32
|
||||
Msgrcv int32
|
||||
Nsignals int32
|
||||
Nvcsw int32
|
||||
Nivcsw int32
|
||||
}
|
||||
|
||||
type Rlimit struct {
|
||||
Cur int64
|
||||
Max int64
|
||||
}
|
||||
|
||||
type _Gid_t uint32
|
||||
|
||||
const (
|
||||
S_IFMT = 0xf000
|
||||
S_IFIFO = 0x1000
|
||||
S_IFCHR = 0x2000
|
||||
S_IFDIR = 0x4000
|
||||
S_IFBLK = 0x6000
|
||||
S_IFREG = 0x8000
|
||||
S_IFLNK = 0xa000
|
||||
S_IFSOCK = 0xc000
|
||||
S_ISUID = 0x800
|
||||
S_ISGID = 0x400
|
||||
S_ISVTX = 0x200
|
||||
S_IRUSR = 0x100
|
||||
S_IWUSR = 0x80
|
||||
S_IXUSR = 0x40
|
||||
)
|
||||
|
||||
type Stat_t struct {
|
||||
Ino uint64
|
||||
Nlink uint32
|
||||
Dev uint32
|
||||
Mode uint16
|
||||
Padding1 uint16
|
||||
Uid uint32
|
||||
Gid uint32
|
||||
Rdev uint32
|
||||
Atim Timespec
|
||||
Mtim Timespec
|
||||
Ctim Timespec
|
||||
Size int64
|
||||
Blocks int64
|
||||
Blksize uint32
|
||||
Flags uint32
|
||||
Gen uint32
|
||||
Lspare int32
|
||||
Qspare1 int64
|
||||
Qspare2 int64
|
||||
}
|
||||
|
||||
type Statfs_t struct {
|
||||
Spare2 int32
|
||||
Bsize int32
|
||||
Iosize int32
|
||||
Blocks int32
|
||||
Bfree int32
|
||||
Bavail int32
|
||||
Files int32
|
||||
Ffree int32
|
||||
Fsid Fsid
|
||||
Owner uint32
|
||||
Type int32
|
||||
Flags int32
|
||||
Syncwrites int32
|
||||
Asyncwrites int32
|
||||
Fstypename [16]int8
|
||||
Mntonname [80]int8
|
||||
Syncreads int32
|
||||
Asyncreads int32
|
||||
Spares1 int16
|
||||
Mntfromname [80]int8
|
||||
Spares2 int16
|
||||
Spare [2]int32
|
||||
}
|
||||
|
||||
type Flock_t struct {
|
||||
Start int64
|
||||
Len int64
|
||||
Pid int32
|
||||
Type int16
|
||||
Whence int16
|
||||
}
|
||||
|
||||
type Dirent struct {
|
||||
Fileno uint64
|
||||
Namlen uint16
|
||||
Type uint8
|
||||
Unused1 uint8
|
||||
Unused2 uint32
|
||||
Name [256]int8
|
||||
}
|
||||
|
||||
type Fsid struct {
|
||||
Val [2]int32
|
||||
}
|
||||
|
||||
type RawSockaddrInet4 struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Port uint16
|
||||
Addr [4]byte /* in_addr */
|
||||
Zero [8]int8
|
||||
}
|
||||
|
||||
type RawSockaddrInet6 struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Port uint16
|
||||
Flowinfo uint32
|
||||
Addr [16]byte /* in6_addr */
|
||||
Scope_id uint32
|
||||
}
|
||||
|
||||
type RawSockaddrUnix struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Path [104]int8
|
||||
}
|
||||
|
||||
type RawSockaddrDatalink struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Index uint16
|
||||
Type uint8
|
||||
Nlen uint8
|
||||
Alen uint8
|
||||
Slen uint8
|
||||
Data [12]int8
|
||||
Rcf uint16
|
||||
Route [16]uint16
|
||||
}
|
||||
|
||||
type RawSockaddr struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Data [14]int8
|
||||
}
|
||||
|
||||
type RawSockaddrAny struct {
|
||||
Addr RawSockaddr
|
||||
Pad [92]int8
|
||||
}
|
||||
|
||||
type _Socklen uint32
|
||||
|
||||
type Linger struct {
|
||||
Onoff int32
|
||||
Linger int32
|
||||
}
|
||||
|
||||
type Iovec struct {
|
||||
Base *byte
|
||||
Len uint32
|
||||
}
|
||||
|
||||
type IPMreq struct {
|
||||
Multiaddr [4]byte /* in_addr */
|
||||
Interface [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
type IPv6Mreq struct {
|
||||
Multiaddr [16]byte /* in6_addr */
|
||||
Interface uint32
|
||||
}
|
||||
|
||||
type Msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Iov *Iovec
|
||||
Iovlen int32
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type Cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
type Inet6Pktinfo struct {
|
||||
Addr [16]byte /* in6_addr */
|
||||
Ifindex uint32
|
||||
}
|
||||
|
||||
type IPv6MTUInfo struct {
|
||||
Addr RawSockaddrInet6
|
||||
Mtu uint32
|
||||
}
|
||||
|
||||
type ICMPv6Filter struct {
|
||||
Filt [8]uint32
|
||||
}
|
||||
|
||||
const (
|
||||
SizeofSockaddrInet4 = 0x10
|
||||
SizeofSockaddrInet6 = 0x1c
|
||||
SizeofSockaddrAny = 0x6c
|
||||
SizeofSockaddrUnix = 0x6a
|
||||
SizeofSockaddrDatalink = 0x36
|
||||
SizeofLinger = 0x8
|
||||
SizeofIPMreq = 0x8
|
||||
SizeofIPv6Mreq = 0x14
|
||||
SizeofMsghdr = 0x1c
|
||||
SizeofCmsghdr = 0xc
|
||||
SizeofInet6Pktinfo = 0x14
|
||||
SizeofIPv6MTUInfo = 0x20
|
||||
SizeofICMPv6Filter = 0x20
|
||||
)
|
||||
|
||||
const (
|
||||
PTRACE_TRACEME = 0x0
|
||||
PTRACE_CONT = 0x7
|
||||
PTRACE_KILL = 0x8
|
||||
)
|
||||
|
||||
type Kevent_t struct {
|
||||
Ident uint32
|
||||
Filter int16
|
||||
Flags uint16
|
||||
Fflags uint32
|
||||
Data int32
|
||||
Udata *byte
|
||||
}
|
||||
|
||||
type FdSet struct {
|
||||
Bits [32]uint32
|
||||
}
|
||||
|
||||
const (
|
||||
SizeofIfMsghdr = 0x68
|
||||
SizeofIfData = 0x58
|
||||
SizeofIfaMsghdr = 0x14
|
||||
SizeofIfmaMsghdr = 0x10
|
||||
SizeofIfAnnounceMsghdr = 0x18
|
||||
SizeofRtMsghdr = 0x5c
|
||||
SizeofRtMetrics = 0x38
|
||||
)
|
||||
|
||||
type IfMsghdr struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Addrs int32
|
||||
Flags int32
|
||||
Index uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Data IfData
|
||||
}
|
||||
|
||||
type IfData struct {
|
||||
Type uint8
|
||||
Physical uint8
|
||||
Addrlen uint8
|
||||
Hdrlen uint8
|
||||
Recvquota uint8
|
||||
Xmitquota uint8
|
||||
Pad_cgo_0 [2]byte
|
||||
Mtu uint32
|
||||
Metric uint32
|
||||
Link_state uint32
|
||||
Baudrate uint64
|
||||
Ipackets uint32
|
||||
Ierrors uint32
|
||||
Opackets uint32
|
||||
Oerrors uint32
|
||||
Collisions uint32
|
||||
Ibytes uint32
|
||||
Obytes uint32
|
||||
Imcasts uint32
|
||||
Omcasts uint32
|
||||
Iqdrops uint32
|
||||
Noproto uint32
|
||||
Hwassist uint32
|
||||
Unused uint32
|
||||
Lastchange Timeval
|
||||
}
|
||||
|
||||
type IfaMsghdr struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Addrs int32
|
||||
Flags int32
|
||||
Index uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Metric int32
|
||||
}
|
||||
|
||||
type IfmaMsghdr struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Addrs int32
|
||||
Flags int32
|
||||
Index uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
}
|
||||
|
||||
type IfAnnounceMsghdr struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Index uint16
|
||||
Name [16]int8
|
||||
What uint16
|
||||
}
|
||||
|
||||
type RtMsghdr struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Index uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
Flags int32
|
||||
Addrs int32
|
||||
Pid int32
|
||||
Seq int32
|
||||
Errno int32
|
||||
Use int32
|
||||
Inits uint32
|
||||
Rmx RtMetrics
|
||||
}
|
||||
|
||||
type RtMetrics struct {
|
||||
Locks uint32
|
||||
Mtu uint32
|
||||
Pksent uint32
|
||||
Expire uint32
|
||||
Sendpipe uint32
|
||||
Ssthresh uint32
|
||||
Rtt uint32
|
||||
Rttvar uint32
|
||||
Recvpipe uint32
|
||||
Hopcount uint32
|
||||
Mssopt uint16
|
||||
Pad uint16
|
||||
Msl uint32
|
||||
Iwmaxsegs uint32
|
||||
Iwcapsegs uint32
|
||||
}
|
||||
|
||||
const (
|
||||
SizeofBpfVersion = 0x4
|
||||
SizeofBpfStat = 0x8
|
||||
SizeofBpfProgram = 0x8
|
||||
SizeofBpfInsn = 0x8
|
||||
SizeofBpfHdr = 0x14
|
||||
)
|
||||
|
||||
type BpfVersion struct {
|
||||
Major uint16
|
||||
Minor uint16
|
||||
}
|
||||
|
||||
type BpfStat struct {
|
||||
Recv uint32
|
||||
Drop uint32
|
||||
}
|
||||
|
||||
type BpfProgram struct {
|
||||
Len uint32
|
||||
Insns *BpfInsn
|
||||
}
|
||||
|
||||
type BpfInsn struct {
|
||||
Code uint16
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
K uint32
|
||||
}
|
||||
|
||||
type BpfHdr struct {
|
||||
Tstamp Timeval
|
||||
Caplen uint32
|
||||
Datalen uint32
|
||||
Hdrlen uint16
|
||||
Pad_cgo_0 [2]byte
|
||||
}
|
||||
|
||||
type Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]uint8
|
||||
Ispeed uint32
|
||||
Ospeed uint32
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
// +build !std_json
|
||||
|
||||
/*-
|
||||
* Copyright 2014 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package jose
|
||||
|
||||
import (
|
||||
"gopkg.in/square/go-jose.v1/json"
|
||||
)
|
||||
|
||||
func MarshalJSON(v interface{}) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
func UnmarshalJSON(data []byte, v interface{}) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
// +build std_json
|
||||
|
||||
/*-
|
||||
* Copyright 2014 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package jose
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func MarshalJSON(v interface{}) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
func UnmarshalJSON(data []byte, v interface{}) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
@@ -150,7 +150,7 @@ func (c *Client) EnableDebug() {
|
||||
|
||||
// Issue obtains a new SAN certificate from the Lets Encrypt CA
|
||||
func (c *Client) Issue(certName string, domains []string) (*AcmeCertificate, map[string]error) {
|
||||
certRes, failures := c.client.ObtainCertificate(domains, true, nil)
|
||||
certRes, failures := c.client.ObtainCertificate(domains, true, nil, false)
|
||||
if len(failures) > 0 {
|
||||
return nil, failures
|
||||
}
|
||||
@@ -172,7 +172,7 @@ func (c *Client) Renew(certName string) (*AcmeCertificate, error) {
|
||||
}
|
||||
|
||||
certRes := acmeCert.CertificateResource
|
||||
newCertRes, err := c.client.RenewCertificate(certRes, true)
|
||||
newCertRes, err := c.client.RenewCertificate(certRes, true, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Generated
Vendored
Generated
Vendored
+188
@@ -0,0 +1,188 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// BlockStorage on Vultr account
|
||||
type BlockStorage struct {
|
||||
ID string `json:"SUBID,string"`
|
||||
Name string `json:"label"`
|
||||
RegionID int `json:"DCID,string"`
|
||||
SizeGB int `json:"size_gb,string"`
|
||||
Created string `json:"date_created"`
|
||||
Cost string `json:"cost_per_month"`
|
||||
Status string `json:"status"`
|
||||
AttachedTo string `json:"attached_to_SUBID"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaller on BlockStorage.
|
||||
// This is needed because the Vultr API is inconsistent in it's JSON responses.
|
||||
// Some fields can change type, from JSON number to JSON string and vice-versa.
|
||||
func (b *BlockStorage) UnmarshalJSON(data []byte) (err error) {
|
||||
if b == nil {
|
||||
*b = BlockStorage{}
|
||||
}
|
||||
|
||||
var fields map[string]interface{}
|
||||
if err := json.Unmarshal(data, &fields); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value := fmt.Sprintf("%v", fields["SUBID"])
|
||||
if len(value) == 0 || value == "<nil>" || value == "0" {
|
||||
b.ID = ""
|
||||
} else {
|
||||
id, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.ID = strconv.FormatFloat(id, 'f', -1, 64)
|
||||
}
|
||||
|
||||
value = fmt.Sprintf("%v", fields["DCID"])
|
||||
if len(value) == 0 || value == "<nil>" {
|
||||
value = "0"
|
||||
}
|
||||
region, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.RegionID = int(region)
|
||||
|
||||
value = fmt.Sprintf("%v", fields["size_gb"])
|
||||
if len(value) == 0 || value == "<nil>" {
|
||||
value = "0"
|
||||
}
|
||||
size, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.SizeGB = int(size)
|
||||
|
||||
value = fmt.Sprintf("%v", fields["attached_to_SUBID"])
|
||||
if len(value) == 0 || value == "<nil>" || value == "0" {
|
||||
b.AttachedTo = ""
|
||||
} else {
|
||||
attached, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.AttachedTo = strconv.FormatFloat(attached, 'f', -1, 64)
|
||||
}
|
||||
|
||||
b.Name = fmt.Sprintf("%v", fields["label"])
|
||||
b.Created = fmt.Sprintf("%v", fields["date_created"])
|
||||
b.Status = fmt.Sprintf("%v", fields["status"])
|
||||
b.Cost = fmt.Sprintf("%v", fields["cost_per_month"])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetBlockStorages returns a list of all active block storages on Vultr account
|
||||
func (c *Client) GetBlockStorages() (storages []BlockStorage, err error) {
|
||||
if err := c.get(`block/list`, &storages); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return storages, nil
|
||||
}
|
||||
|
||||
// GetBlockStorage returns block storage with given ID
|
||||
func (c *Client) GetBlockStorage(id string) (BlockStorage, error) {
|
||||
storages, err := c.GetBlockStorages()
|
||||
if err != nil {
|
||||
return BlockStorage{}, err
|
||||
}
|
||||
|
||||
for _, s := range storages {
|
||||
if s.ID == id {
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
return BlockStorage{}, fmt.Errorf("BlockStorage with ID %v not found", id)
|
||||
}
|
||||
|
||||
// CreateBlockStorage creates a new block storage on Vultr account
|
||||
func (c *Client) CreateBlockStorage(name string, regionID, size int) (BlockStorage, error) {
|
||||
values := url.Values{
|
||||
"label": {name},
|
||||
"DCID": {fmt.Sprintf("%v", regionID)},
|
||||
"size_gb": {fmt.Sprintf("%v", size)},
|
||||
}
|
||||
|
||||
var storage BlockStorage
|
||||
if err := c.post(`block/create`, values, &storage); err != nil {
|
||||
return BlockStorage{}, err
|
||||
}
|
||||
storage.RegionID = regionID
|
||||
storage.Name = name
|
||||
storage.SizeGB = size
|
||||
|
||||
return storage, nil
|
||||
}
|
||||
|
||||
// ResizeBlockStorage resizes an existing block storage
|
||||
func (c *Client) ResizeBlockStorage(id string, size int) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
"size_gb": {fmt.Sprintf("%v", size)},
|
||||
}
|
||||
|
||||
if err := c.post(`block/resize`, values, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LabelBlockStorage changes the label on an existing block storage
|
||||
func (c *Client) LabelBlockStorage(id, name string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
"label": {name},
|
||||
}
|
||||
|
||||
if err := c.post(`block/label_set`, values, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AttachBlockStorage attaches block storage to an existing virtual machine
|
||||
func (c *Client) AttachBlockStorage(id, serverID string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
"attach_to_SUBID": {serverID},
|
||||
}
|
||||
|
||||
if err := c.post(`block/attach`, values, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetachBlockStorage detaches block storage from virtual machine
|
||||
func (c *Client) DetachBlockStorage(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
}
|
||||
|
||||
if err := c.post(`block/detach`, values, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteBlockStorage deletes an existing block storage
|
||||
func (c *Client) DeleteBlockStorage(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
}
|
||||
|
||||
if err := c.post(`block/delete`, values, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+8
-1
@@ -1,6 +1,7 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -17,7 +18,7 @@ import (
|
||||
|
||||
const (
|
||||
// Version of this libary
|
||||
Version = "v1.8"
|
||||
Version = "1.12.0"
|
||||
|
||||
// APIVersion of Vultr
|
||||
APIVersion = "v1"
|
||||
@@ -35,6 +36,7 @@ var retryableStatusCodes = map[int]struct{}{
|
||||
500: {}, // Internal server error. Try again at a later time.
|
||||
}
|
||||
|
||||
// Client represents the Vultr API client
|
||||
type Client struct {
|
||||
// HTTP client for communication with the Vultr API
|
||||
client *http.Client
|
||||
@@ -55,6 +57,7 @@ type Client struct {
|
||||
bucket *ratelimit.Bucket
|
||||
}
|
||||
|
||||
// Options represents optional settings and flags that can be passed to NewClient
|
||||
type Options struct {
|
||||
// HTTP client for communication with the Vultr API
|
||||
HTTPClient *http.Client
|
||||
@@ -75,7 +78,11 @@ type Options struct {
|
||||
// NewClient creates new Vultr API client. Options are optional and can be nil.
|
||||
func NewClient(apiKey string, options *Options) *Client {
|
||||
userAgent := "vultr-go/" + Version
|
||||
transport := &http.Transport{
|
||||
TLSNextProto: make(map[string]func(string, *tls.Conn) http.RoundTripper),
|
||||
}
|
||||
client := http.DefaultClient
|
||||
client.Transport = transport
|
||||
endpoint, _ := url.Parse(DefaultEndpoint)
|
||||
rate := 505 * time.Millisecond
|
||||
attempts := 1
|
||||
Generated
Vendored
+25
-18
@@ -5,14 +5,14 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// DNS Domain
|
||||
type DnsDomain struct {
|
||||
// DNSDomain represents a DNS domain on Vultr
|
||||
type DNSDomain struct {
|
||||
Domain string `json:"domain"`
|
||||
Created string `json:"date_created"`
|
||||
}
|
||||
|
||||
// DNS Record
|
||||
type DnsRecord struct {
|
||||
// DNSRecord represents a DNS record on Vultr
|
||||
type DNSRecord struct {
|
||||
RecordID int `json:"RECORDID"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
@@ -21,17 +21,27 @@ type DnsRecord struct {
|
||||
TTL int `json:"ttl"`
|
||||
}
|
||||
|
||||
func (c *Client) GetDnsDomains() (dnsdomains []DnsDomain, err error) {
|
||||
// GetDNSDomains returns a list of available domains on Vultr account
|
||||
func (c *Client) GetDNSDomains() (dnsdomains []DNSDomain, err error) {
|
||||
if err := c.get(`dns/list`, &dnsdomains); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dnsdomains, nil
|
||||
}
|
||||
|
||||
func (c *Client) CreateDnsDomain(domain, serverip string) error {
|
||||
// GetDNSRecords returns a list of all DNS records of a particular domain
|
||||
func (c *Client) GetDNSRecords(domain string) (dnsrecords []DNSRecord, err error) {
|
||||
if err := c.get(`dns/records?domain=`+domain, &dnsrecords); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dnsrecords, nil
|
||||
}
|
||||
|
||||
// CreateDNSDomain creates a new DNS domain name on Vultr
|
||||
func (c *Client) CreateDNSDomain(domain, serverIP string) error {
|
||||
values := url.Values{
|
||||
"domain": {domain},
|
||||
"serverip": {serverip},
|
||||
"serverIP": {serverIP},
|
||||
}
|
||||
|
||||
if err := c.post(`dns/create_domain`, values, nil); err != nil {
|
||||
@@ -40,7 +50,8 @@ func (c *Client) CreateDnsDomain(domain, serverip string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) DeleteDnsDomain(domain string) error {
|
||||
// DeleteDNSDomain deletes an existing DNS domain name
|
||||
func (c *Client) DeleteDNSDomain(domain string) error {
|
||||
values := url.Values{
|
||||
"domain": {domain},
|
||||
}
|
||||
@@ -51,14 +62,8 @@ func (c *Client) DeleteDnsDomain(domain string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) GetDnsRecords(domain string) (dnsrecords []DnsRecord, err error) {
|
||||
if err := c.get(`dns/records?domain=`+domain, &dnsrecords); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dnsrecords, nil
|
||||
}
|
||||
|
||||
func (c *Client) CreateDnsRecord(domain, name, rtype, data string, priority, ttl int) error {
|
||||
// CreateDNSRecord creates a new DNS record
|
||||
func (c *Client) CreateDNSRecord(domain, name, rtype, data string, priority, ttl int) error {
|
||||
values := url.Values{
|
||||
"domain": {domain},
|
||||
"name": {name},
|
||||
@@ -74,7 +79,8 @@ func (c *Client) CreateDnsRecord(domain, name, rtype, data string, priority, ttl
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) UpdateDnsRecord(domain string, dnsrecord DnsRecord) error {
|
||||
// UpdateDNSRecord updates an existing DNS record
|
||||
func (c *Client) UpdateDNSRecord(domain string, dnsrecord DNSRecord) error {
|
||||
values := url.Values{
|
||||
"domain": {domain},
|
||||
"RECORDID": {fmt.Sprintf("%v", dnsrecord.RecordID)},
|
||||
@@ -99,7 +105,8 @@ func (c *Client) UpdateDnsRecord(domain string, dnsrecord DnsRecord) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) DeleteDnsRecord(domain string, recordID int) error {
|
||||
// DeleteDNSRecord deletes an existing DNS record
|
||||
func (c *Client) DeleteDNSRecord(domain string, recordID int) error {
|
||||
values := url.Values{
|
||||
"domain": {domain},
|
||||
"RECORDID": {fmt.Sprintf("%v", recordID)},
|
||||
Generated
Vendored
+7
@@ -25,6 +25,7 @@ type ReverseDNSIPv6 struct {
|
||||
ReverseDNS string `json:"reverse"`
|
||||
}
|
||||
|
||||
// ListIPv4 lists the IPv4 information of a virtual machine
|
||||
func (c *Client) ListIPv4(id string) (list []IPv4, err error) {
|
||||
var ipMap map[string][]IPv4
|
||||
if err := c.get(`server/list_ipv4?SUBID=`+id, &ipMap); err != nil {
|
||||
@@ -39,6 +40,7 @@ func (c *Client) ListIPv4(id string) (list []IPv4, err error) {
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// ListIPv6 lists the IPv4 information of a virtual machine
|
||||
func (c *Client) ListIPv6(id string) (list []IPv6, err error) {
|
||||
var ipMap map[string][]IPv6
|
||||
if err := c.get(`server/list_ipv6?SUBID=`+id, &ipMap); err != nil {
|
||||
@@ -53,6 +55,7 @@ func (c *Client) ListIPv6(id string) (list []IPv6, err error) {
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// ListIPv6ReverseDNS lists the IPv6 reverse DNS entries of a virtual machine
|
||||
func (c *Client) ListIPv6ReverseDNS(id string) (list []ReverseDNSIPv6, err error) {
|
||||
var ipMap map[string][]ReverseDNSIPv6
|
||||
if err := c.get(`server/reverse_list_ipv6?SUBID=`+id, &ipMap); err != nil {
|
||||
@@ -67,6 +70,7 @@ func (c *Client) ListIPv6ReverseDNS(id string) (list []ReverseDNSIPv6, err error
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// DeleteIPv6ReverseDNS removes a reverse DNS entry for an IPv6 address of a virtual machine
|
||||
func (c *Client) DeleteIPv6ReverseDNS(id string, ip string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -79,6 +83,7 @@ func (c *Client) DeleteIPv6ReverseDNS(id string, ip string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetIPv6ReverseDNS sets a reverse DNS entry for an IPv6 address of a virtual machine
|
||||
func (c *Client) SetIPv6ReverseDNS(id, ip, entry string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -92,6 +97,7 @@ func (c *Client) SetIPv6ReverseDNS(id, ip, entry string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultIPv4ReverseDNS sets a reverse DNS entry for an IPv4 address of a virtual machine to the original setting
|
||||
func (c *Client) DefaultIPv4ReverseDNS(id, ip string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -104,6 +110,7 @@ func (c *Client) DefaultIPv4ReverseDNS(id, ip string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetIPv4ReverseDNS sets a reverse DNS entry for an IPv4 address of a virtual machine
|
||||
func (c *Client) SetIPv4ReverseDNS(id, ip, entry string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
Generated
Vendored
+1
@@ -9,6 +9,7 @@ type ISO struct {
|
||||
MD5sum string `json:"md5sum"`
|
||||
}
|
||||
|
||||
// GetISO returns a list of all ISO images on Vultr account
|
||||
func (c *Client) GetISO() ([]ISO, error) {
|
||||
var isoMap map[string]ISO
|
||||
if err := c.get(`iso/list`, &isoMap); err != nil {
|
||||
Generated
Vendored
+1
@@ -10,6 +10,7 @@ type OS struct {
|
||||
Surcharge string `json:"surcharge"`
|
||||
}
|
||||
|
||||
// GetOS returns a list of all available operating systems on Vultr
|
||||
func (c *Client) GetOS() ([]OS, error) {
|
||||
var osMap map[string]OS
|
||||
if err := c.get(`os/list`, &osMap); err != nil {
|
||||
Generated
Vendored
+2
@@ -14,6 +14,7 @@ type Plan struct {
|
||||
Regions []int `json:"available_locations"`
|
||||
}
|
||||
|
||||
// GetPlans returns a list of all available plans on Vultr account
|
||||
func (c *Client) GetPlans() ([]Plan, error) {
|
||||
var planMap map[string]Plan
|
||||
if err := c.get(`plans/list`, &planMap); err != nil {
|
||||
@@ -27,6 +28,7 @@ func (c *Client) GetPlans() ([]Plan, error) {
|
||||
return planList, nil
|
||||
}
|
||||
|
||||
// GetAvailablePlansForRegion returns available plans for specified region
|
||||
func (c *Client) GetAvailablePlansForRegion(id int) (planIDs []int, err error) {
|
||||
if err := c.get(fmt.Sprintf(`regions/availability?DCID=%v`, id), &planIDs); err != nil {
|
||||
return nil, err
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package lib
|
||||
|
||||
// Region on Vultr
|
||||
type Region struct {
|
||||
ID int `json:"DCID,string"`
|
||||
Name string `json:"name"`
|
||||
Country string `json:"country"`
|
||||
Continent string `json:"continent"`
|
||||
State string `json:"state"`
|
||||
Ddos bool `json:"ddos_protection"`
|
||||
BlockStorage bool `json:"block_storage"`
|
||||
Code string `json:"regioncode"`
|
||||
}
|
||||
|
||||
// GetRegions returns a list of all available Vultr regions
|
||||
func (c *Client) GetRegions() ([]Region, error) {
|
||||
var regionMap map[string]Region
|
||||
if err := c.get(`regions/list`, ®ionMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var regionList []Region
|
||||
for _, os := range regionMap {
|
||||
regionList = append(regionList, os)
|
||||
}
|
||||
return regionList, nil
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// IP on Vultr
|
||||
type IP struct {
|
||||
ID string `json:"SUBID,string"`
|
||||
RegionID int `json:"DCID,string"`
|
||||
IPType string `json:"ip_type"`
|
||||
Subnet string `json:"subnet"`
|
||||
SubnetSize int `json:"subnet_size"`
|
||||
Label string `json:"label"`
|
||||
AttachedTo string `json:"attached_SUBID,string"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaller on IP.
|
||||
// This is needed because the Vultr API is inconsistent in it's JSON responses.
|
||||
// Some fields can change type, from JSON number to JSON string and vice-versa.
|
||||
func (i *IP) UnmarshalJSON(data []byte) (err error) {
|
||||
if i == nil {
|
||||
*i = IP{}
|
||||
}
|
||||
|
||||
var fields map[string]interface{}
|
||||
if err := json.Unmarshal(data, &fields); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value := fmt.Sprintf("%v", fields["SUBID"])
|
||||
if len(value) == 0 || value == "<nil>" || value == "0" {
|
||||
i.ID = ""
|
||||
} else {
|
||||
id, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.ID = strconv.FormatFloat(id, 'f', -1, 64)
|
||||
}
|
||||
|
||||
value = fmt.Sprintf("%v", fields["DCID"])
|
||||
if len(value) == 0 || value == "<nil>" {
|
||||
value = "0"
|
||||
}
|
||||
region, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.RegionID = int(region)
|
||||
|
||||
value = fmt.Sprintf("%v", fields["attached_SUBID"])
|
||||
if len(value) == 0 || value == "<nil>" || value == "0" || value == "false" {
|
||||
i.AttachedTo = ""
|
||||
} else {
|
||||
attached, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.AttachedTo = strconv.FormatFloat(attached, 'f', -1, 64)
|
||||
}
|
||||
|
||||
value = fmt.Sprintf("%v", fields["subnet_size"])
|
||||
if len(value) == 0 || value == "<nil>" {
|
||||
value = "0"
|
||||
}
|
||||
size, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.SubnetSize = int(size)
|
||||
|
||||
i.IPType = fmt.Sprintf("%v", fields["ip_type"])
|
||||
i.Subnet = fmt.Sprintf("%v", fields["subnet"])
|
||||
i.Label = fmt.Sprintf("%v", fields["label"])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListReservedIP returns a list of all available reserved IPs on Vultr account
|
||||
func (c *Client) ListReservedIP() ([]IP, error) {
|
||||
var ipMap map[string]IP
|
||||
|
||||
err := c.get(`reservedip/list`, &ipMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ips := make([]IP, 0)
|
||||
for _, ip := range ipMap {
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
// GetReservedIP returns reserved IP with given ID
|
||||
func (c *Client) GetReservedIP(id string) (IP, error) {
|
||||
var ipMap map[string]IP
|
||||
|
||||
err := c.get(`reservedip/list`, &ipMap)
|
||||
if err != nil {
|
||||
return IP{}, err
|
||||
}
|
||||
if ip, ok := ipMap[id]; ok {
|
||||
return ip, nil
|
||||
}
|
||||
return IP{}, fmt.Errorf("IP with ID %v not found", id)
|
||||
}
|
||||
|
||||
// CreateReservedIP creates a new reserved IP on Vultr account
|
||||
func (c *Client) CreateReservedIP(regionID int, ipType string, label string) (string, error) {
|
||||
values := url.Values{
|
||||
"DCID": {fmt.Sprintf("%v", regionID)},
|
||||
"ip_type": {ipType},
|
||||
}
|
||||
if len(label) > 0 {
|
||||
values.Add("label", label)
|
||||
}
|
||||
|
||||
result := IP{}
|
||||
err := c.post(`reservedip/create`, values, &result)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return result.ID, nil
|
||||
}
|
||||
|
||||
// DestroyReservedIP deletes an existing reserved IP
|
||||
func (c *Client) DestroyReservedIP(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
}
|
||||
return c.post(`reservedip/destroy`, values, nil)
|
||||
}
|
||||
|
||||
// AttachReservedIP attaches a reserved IP to a virtual machine
|
||||
func (c *Client) AttachReservedIP(ip string, serverID string) error {
|
||||
values := url.Values{
|
||||
"ip_address": {ip},
|
||||
"attach_SUBID": {serverID},
|
||||
}
|
||||
return c.post(`reservedip/attach`, values, nil)
|
||||
}
|
||||
|
||||
// DetachReservedIP detaches a reserved IP from an existing virtual machine
|
||||
func (c *Client) DetachReservedIP(serverID string, ip string) error {
|
||||
values := url.Values{
|
||||
"ip_address": {ip},
|
||||
"detach_SUBID": {serverID},
|
||||
}
|
||||
return c.post(`reservedip/detach`, values, nil)
|
||||
}
|
||||
|
||||
// ConvertReservedIP converts an existing virtual machines IP to a reserved IP
|
||||
func (c *Client) ConvertReservedIP(serverID string, ip string) (string, error) {
|
||||
values := url.Values{
|
||||
"SUBID": {serverID},
|
||||
"ip_address": {ip},
|
||||
}
|
||||
|
||||
result := IP{}
|
||||
err := c.post(`reservedip/convert`, values, &result)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return result.ID, err
|
||||
}
|
||||
Generated
Vendored
+7
-2
@@ -14,8 +14,8 @@ type StartupScript struct {
|
||||
Content string `json:"script"`
|
||||
}
|
||||
|
||||
// Implements json.Unmarshaller on StartupScript.
|
||||
// Necessary because the SRIPTID field has inconsistent types.
|
||||
// UnmarshalJSON implements json.Unmarshaller on StartupScript.
|
||||
// Necessary because the SCRIPTID field has inconsistent types.
|
||||
func (s *StartupScript) UnmarshalJSON(data []byte) (err error) {
|
||||
if s == nil {
|
||||
*s = StartupScript{}
|
||||
@@ -34,6 +34,7 @@ func (s *StartupScript) UnmarshalJSON(data []byte) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// GetStartupScripts returns a list of all startup scripts on the current Vultr account
|
||||
func (c *Client) GetStartupScripts() (scripts []StartupScript, err error) {
|
||||
var scriptMap map[string]StartupScript
|
||||
if err := c.get(`startupscript/list`, &scriptMap); err != nil {
|
||||
@@ -49,6 +50,7 @@ func (c *Client) GetStartupScripts() (scripts []StartupScript, err error) {
|
||||
return scripts, nil
|
||||
}
|
||||
|
||||
// GetStartupScript returns the startup script with the given ID
|
||||
func (c *Client) GetStartupScript(id string) (StartupScript, error) {
|
||||
scripts, err := c.GetStartupScripts()
|
||||
if err != nil {
|
||||
@@ -63,6 +65,7 @@ func (c *Client) GetStartupScript(id string) (StartupScript, error) {
|
||||
return StartupScript{}, nil
|
||||
}
|
||||
|
||||
// CreateStartupScript creates a new startup script
|
||||
func (c *Client) CreateStartupScript(name, content, scriptType string) (StartupScript, error) {
|
||||
values := url.Values{
|
||||
"name": {name},
|
||||
@@ -81,6 +84,7 @@ func (c *Client) CreateStartupScript(name, content, scriptType string) (StartupS
|
||||
return script, nil
|
||||
}
|
||||
|
||||
// UpdateStartupScript updates an existing startup script
|
||||
func (c *Client) UpdateStartupScript(script StartupScript) error {
|
||||
values := url.Values{
|
||||
"SCRIPTID": {script.ID},
|
||||
@@ -98,6 +102,7 @@ func (c *Client) UpdateStartupScript(script StartupScript) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteStartupScript deletes an existing startup script from Vultr account
|
||||
func (c *Client) DeleteStartupScript(id string) error {
|
||||
values := url.Values{
|
||||
"SCRIPTID": {id},
|
||||
Generated
Vendored
+62
@@ -50,6 +50,8 @@ type ServerOptions struct {
|
||||
PrivateNetworking bool
|
||||
AutoBackups bool
|
||||
DontNotifyOnActivate bool
|
||||
Hostname string
|
||||
Tag string
|
||||
}
|
||||
|
||||
// V6Network represents a IPv6 network of a Vultr server
|
||||
@@ -59,6 +61,12 @@ type V6Network struct {
|
||||
NetworkSize string `json:"v6_network_size"`
|
||||
}
|
||||
|
||||
// ISOStatus represents an ISO image attached to a Vultr server
|
||||
type ISOStatus struct {
|
||||
State string `json:"state"`
|
||||
ISOID string `json:"ISOID"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaller on Server.
|
||||
// This is needed because the Vultr API is inconsistent in it's JSON responses for servers.
|
||||
// Some fields can change type, from JSON number to JSON string and vice-versa.
|
||||
@@ -171,6 +179,7 @@ func (s *Server) UnmarshalJSON(data []byte) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// GetServers returns a list of current virtual machines on Vultr account
|
||||
func (c *Client) GetServers() (servers []Server, err error) {
|
||||
var serverMap map[string]Server
|
||||
if err := c.get(`server/list`, &serverMap); err != nil {
|
||||
@@ -183,6 +192,7 @@ func (c *Client) GetServers() (servers []Server, err error) {
|
||||
return servers, nil
|
||||
}
|
||||
|
||||
// GetServersByTag returns a list of all virtual machines matching by tag
|
||||
func (c *Client) GetServersByTag(tag string) (servers []Server, err error) {
|
||||
var serverMap map[string]Server
|
||||
if err := c.get(`server/list?tag=`+tag, &serverMap); err != nil {
|
||||
@@ -195,6 +205,7 @@ func (c *Client) GetServersByTag(tag string) (servers []Server, err error) {
|
||||
return servers, nil
|
||||
}
|
||||
|
||||
// GetServer returns the virtual machine with the given ID
|
||||
func (c *Client) GetServer(id string) (server Server, err error) {
|
||||
if err := c.get(`server/list?SUBID=`+id, &server); err != nil {
|
||||
return Server{}, err
|
||||
@@ -202,6 +213,7 @@ func (c *Client) GetServer(id string) (server Server, err error) {
|
||||
return server, nil
|
||||
}
|
||||
|
||||
// CreateServer creates a new virtual machine on Vultr. ServerOptions are optional settings.
|
||||
func (c *Client) CreateServer(name string, regionID, planID, osID int, options *ServerOptions) (Server, error) {
|
||||
values := url.Values{
|
||||
"label": {name},
|
||||
@@ -254,6 +266,14 @@ func (c *Client) CreateServer(name string, regionID, planID, osID int, options *
|
||||
if options.DontNotifyOnActivate {
|
||||
values.Set("notify_activate", "no")
|
||||
}
|
||||
|
||||
if options.Hostname != "" {
|
||||
values.Add("hostname", options.Hostname)
|
||||
}
|
||||
|
||||
if options.Tag != "" {
|
||||
values.Add("tag", options.Tag)
|
||||
}
|
||||
}
|
||||
|
||||
var server Server
|
||||
@@ -267,6 +287,7 @@ func (c *Client) CreateServer(name string, regionID, planID, osID int, options *
|
||||
return server, nil
|
||||
}
|
||||
|
||||
// RenameServer renames an existing virtual machine
|
||||
func (c *Client) RenameServer(id, name string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -279,6 +300,7 @@ func (c *Client) RenameServer(id, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartServer starts an existing virtual machine
|
||||
func (c *Client) StartServer(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -290,6 +312,7 @@ func (c *Client) StartServer(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// HaltServer stops an existing virtual machine
|
||||
func (c *Client) HaltServer(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -301,6 +324,7 @@ func (c *Client) HaltServer(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RebootServer reboots an existing virtual machine
|
||||
func (c *Client) RebootServer(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -312,6 +336,7 @@ func (c *Client) RebootServer(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReinstallServer reinstalls the operating system on an existing virtual machine
|
||||
func (c *Client) ReinstallServer(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -323,6 +348,7 @@ func (c *Client) ReinstallServer(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChangeOSofServer changes the virtual machine to a different operating system
|
||||
func (c *Client) ChangeOSofServer(id string, osID int) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -335,6 +361,7 @@ func (c *Client) ChangeOSofServer(id string, osID int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListOSforServer lists all available operating systems to which an existing virtual machine can be changed
|
||||
func (c *Client) ListOSforServer(id string) (os []OS, err error) {
|
||||
var osMap map[string]OS
|
||||
if err := c.get(`server/os_change_list?SUBID=`+id, &osMap); err != nil {
|
||||
@@ -347,6 +374,40 @@ func (c *Client) ListOSforServer(id string) (os []OS, err error) {
|
||||
return os, nil
|
||||
}
|
||||
|
||||
// AttachISOtoServer attaches an ISO image to an existing virtual machine and reboots it
|
||||
func (c *Client) AttachISOtoServer(id string, isoID int) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
"ISOID": {fmt.Sprintf("%v", isoID)},
|
||||
}
|
||||
|
||||
if err := c.post(`server/iso_attach`, values, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetachISOfromServer detaches the currently mounted ISO image from the virtual machine and reboots it
|
||||
func (c *Client) DetachISOfromServer(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
}
|
||||
|
||||
if err := c.post(`server/iso_detach`, values, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetISOStatusofServer retrieves the current ISO image state of an existing virtual machine
|
||||
func (c *Client) GetISOStatusofServer(id string) (isoStatus ISOStatus, err error) {
|
||||
if err := c.get(`server/iso_status?SUBID=`+id, &isoStatus); err != nil {
|
||||
return ISOStatus{}, err
|
||||
}
|
||||
return isoStatus, nil
|
||||
}
|
||||
|
||||
// DeleteServer deletes an existing virtual machine
|
||||
func (c *Client) DeleteServer(id string) error {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -358,6 +419,7 @@ func (c *Client) DeleteServer(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// BandwidthOfServer retrieves the bandwidth used by a virtual machine
|
||||
func (c *Client) BandwidthOfServer(id string) (bandwidth []map[string]string, err error) {
|
||||
var bandwidthMap map[string][][]string
|
||||
if err := c.get(`server/bandwidth?SUBID=`+id, &bandwidthMap); err != nil {
|
||||
Generated
Vendored
+3
@@ -11,6 +11,7 @@ type Snapshot struct {
|
||||
Created string `json:"date_created"`
|
||||
}
|
||||
|
||||
// GetSnapshots retrieves a list of all snapshots on Vultr account
|
||||
func (c *Client) GetSnapshots() (snapshots []Snapshot, err error) {
|
||||
var snapshotMap map[string]Snapshot
|
||||
if err := c.get(`snapshot/list`, &snapshotMap); err != nil {
|
||||
@@ -23,6 +24,7 @@ func (c *Client) GetSnapshots() (snapshots []Snapshot, err error) {
|
||||
return snapshots, nil
|
||||
}
|
||||
|
||||
// CreateSnapshot creates a new virtual machine snapshot
|
||||
func (c *Client) CreateSnapshot(id, description string) (Snapshot, error) {
|
||||
values := url.Values{
|
||||
"SUBID": {id},
|
||||
@@ -38,6 +40,7 @@ func (c *Client) CreateSnapshot(id, description string) (Snapshot, error) {
|
||||
return snapshot, nil
|
||||
}
|
||||
|
||||
// DeleteSnapshot deletes an existing virtual machine snapshot
|
||||
func (c *Client) DeleteSnapshot(id string) error {
|
||||
values := url.Values{
|
||||
"SNAPSHOTID": {id},
|
||||
Generated
Vendored
+4
@@ -10,6 +10,7 @@ type SSHKey struct {
|
||||
Created string `json:"date_created"`
|
||||
}
|
||||
|
||||
// GetSSHKeys returns a list of SSHKeys from Vultr account
|
||||
func (c *Client) GetSSHKeys() (keys []SSHKey, err error) {
|
||||
var keyMap map[string]SSHKey
|
||||
if err := c.get(`sshkey/list`, &keyMap); err != nil {
|
||||
@@ -22,6 +23,7 @@ func (c *Client) GetSSHKeys() (keys []SSHKey, err error) {
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
// CreateSSHKey creates new SSHKey on Vultr
|
||||
func (c *Client) CreateSSHKey(name, key string) (SSHKey, error) {
|
||||
values := url.Values{
|
||||
"name": {name},
|
||||
@@ -38,6 +40,7 @@ func (c *Client) CreateSSHKey(name, key string) (SSHKey, error) {
|
||||
return sshKey, nil
|
||||
}
|
||||
|
||||
// UpdateSSHKey updates an existing SSHKey entry
|
||||
func (c *Client) UpdateSSHKey(key SSHKey) error {
|
||||
values := url.Values{
|
||||
"SSHKEYID": {key.ID},
|
||||
@@ -55,6 +58,7 @@ func (c *Client) UpdateSSHKey(key SSHKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteSSHKey deletes an existing SSHKey from Vultr account
|
||||
func (c *Client) DeleteSSHKey(id string) error {
|
||||
values := url.Values{
|
||||
"SSHKEYID": {id},
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.6
|
||||
- 1.7
|
||||
- tip
|
||||
install:
|
||||
- go get -t ./...
|
||||
script: GOMAXPROCS=4 GORACE="halt_on_error=1" go test -race -v ./...
|
||||
Generated
Vendored
+12
-1
@@ -1,10 +1,21 @@
|
||||
# 0.9.0 (Unreleased)
|
||||
# 0.10.0
|
||||
|
||||
* feature: Add a test hook (#180)
|
||||
* feature: `ParseLevel` is now case-insensitive (#326)
|
||||
* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
|
||||
* performance: avoid re-allocations on `WithFields` (#335)
|
||||
|
||||
# 0.9.0
|
||||
|
||||
* logrus/text_formatter: don't emit empty msg
|
||||
* logrus/hooks/airbrake: move out of main repository
|
||||
* logrus/hooks/sentry: move out of main repository
|
||||
* logrus/hooks/papertrail: move out of main repository
|
||||
* logrus/hooks/bugsnag: move out of main repository
|
||||
* logrus/core: run tests with `-race`
|
||||
* logrus/core: detect TTY based on `stderr`
|
||||
* logrus/core: support `WithError` on logger
|
||||
* logrus/core: Solaris support
|
||||
|
||||
# 0.8.7
|
||||
|
||||
Generated
Vendored
+79
-11
@@ -1,4 +1,10 @@
|
||||
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/Sirupsen/logrus) [][godoc]
|
||||
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/Sirupsen/logrus) [](https://godoc.org/github.com/Sirupsen/logrus)
|
||||
|
||||
**Seeing weird case-sensitive problems?** See [this
|
||||
issue](https://github.com/sirupsen/logrus/issues/451#issuecomment-264332021).
|
||||
This change has been reverted. I apologize for causing this. I greatly
|
||||
underestimated the impact this would have. Logrus strives for stability and
|
||||
backwards compatibility and failed to provide that.
|
||||
|
||||
Logrus is a structured logger for Go (golang), completely API compatible with
|
||||
the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not
|
||||
@@ -12,7 +18,7 @@ plain text):
|
||||
|
||||

|
||||
|
||||
With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash
|
||||
With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash
|
||||
or Splunk:
|
||||
|
||||
```json
|
||||
@@ -32,7 +38,7 @@ ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
|
||||
"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
|
||||
```
|
||||
|
||||
With the default `log.Formatter = new(&log.TextFormatter{})` when a TTY is not
|
||||
With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not
|
||||
attached, the output is compatible with the
|
||||
[logfmt](http://godoc.org/github.com/kr/logfmt) format:
|
||||
|
||||
@@ -81,8 +87,8 @@ func init() {
|
||||
// Log as JSON instead of the default ASCII formatter.
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
|
||||
// Output to stderr instead of stdout, could also be a file.
|
||||
log.SetOutput(os.Stderr)
|
||||
// Output to stdout instead of the default stderr, could also be a file.
|
||||
log.SetOutput(os.Stdout)
|
||||
|
||||
// Only log the warning severity or above.
|
||||
log.SetLevel(log.WarnLevel)
|
||||
@@ -218,9 +224,24 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
|
||||
| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar |
|
||||
| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
|
||||
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
||||
| [Influxus] (http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB] (http://influxdata.com/) |
|
||||
| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb |
|
||||
| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
|
||||
| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic |
|
||||
| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) |
|
||||
| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) |
|
||||
| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka |
|
||||
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
|
||||
| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch|
|
||||
| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
|
||||
| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)|
|
||||
| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
|
||||
| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash |
|
||||
| [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) |
|
||||
| [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) |
|
||||
| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) |
|
||||
| [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) |
|
||||
|
||||
|
||||
#### Level logging
|
||||
|
||||
@@ -298,14 +319,10 @@ The built-in logging formatters are:
|
||||
field to `true`. To force no colored output even if there is a TTY set the
|
||||
`DisableColors` field to `true`
|
||||
* `logrus.JSONFormatter`. Logs fields as JSON.
|
||||
* `logrus/formatters/logstash.LogstashFormatter`. Logs fields as [Logstash](http://logstash.net) Events.
|
||||
|
||||
```go
|
||||
logrus.SetFormatter(&logstash.LogstashFormatter{Type: "application_name"})
|
||||
```
|
||||
|
||||
Third party logging formatters:
|
||||
|
||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
||||
|
||||
@@ -361,5 +378,56 @@ entries. It should not be a feature of the application-level logger.
|
||||
| Tool | Description |
|
||||
| ---- | ----------- |
|
||||
|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.|
|
||||
|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper arround Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
|
||||
|
||||
[godoc]: https://godoc.org/github.com/Sirupsen/logrus
|
||||
#### Testing
|
||||
|
||||
Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
|
||||
|
||||
* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook
|
||||
* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
|
||||
|
||||
```go
|
||||
logger, hook := NewNullLogger()
|
||||
logger.Error("Hello error")
|
||||
|
||||
assert.Equal(1, len(hook.Entries))
|
||||
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
|
||||
assert.Equal("Hello error", hook.LastEntry().Message)
|
||||
|
||||
hook.Reset()
|
||||
assert.Nil(hook.LastEntry())
|
||||
```
|
||||
|
||||
#### Fatal handlers
|
||||
|
||||
Logrus can register one or more functions that will be called when any `fatal`
|
||||
level message is logged. The registered handlers will be executed before
|
||||
logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need
|
||||
to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
|
||||
|
||||
```
|
||||
...
|
||||
handler := func() {
|
||||
// gracefully shutdown something...
|
||||
}
|
||||
logrus.RegisterExitHandler(handler)
|
||||
...
|
||||
```
|
||||
|
||||
#### Thread safety
|
||||
|
||||
By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs.
|
||||
If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
|
||||
|
||||
Situation when locking is not needed includes:
|
||||
|
||||
* You have no hooks registered, or hooks calling is already thread-safe.
|
||||
|
||||
* Writing to logger.Out is already thread-safe, for example:
|
||||
|
||||
1) logger.Out is protected by locks.
|
||||
|
||||
2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing)
|
||||
|
||||
(Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package logrus
|
||||
|
||||
// The following code was sourced and modified from the
|
||||
// https://bitbucket.org/tebeka/atexit package governed by the following license:
|
||||
//
|
||||
// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var handlers = []func(){}
|
||||
|
||||
func runHandler(handler func()) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
handler()
|
||||
}
|
||||
|
||||
func runHandlers() {
|
||||
for _, handler := range handlers {
|
||||
runHandler(handler)
|
||||
}
|
||||
}
|
||||
|
||||
// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
|
||||
func Exit(code int) {
|
||||
runHandlers()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
|
||||
// all handlers. The handlers will also be invoked when any Fatal log entry is
|
||||
// made.
|
||||
//
|
||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||
// message but also needs to gracefully shutdown. An example usecase could be
|
||||
// closing database connections, or sending a alert that the application is
|
||||
// closing.
|
||||
func RegisterExitHandler(handler func()) {
|
||||
handlers = append(handlers, handler)
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
+35
-24
@@ -3,11 +3,21 @@ package logrus
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var bufferPool *sync.Pool
|
||||
|
||||
func init() {
|
||||
bufferPool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Defines the key when adding errors using WithError.
|
||||
var ErrorKey = "error"
|
||||
|
||||
@@ -29,6 +39,9 @@ type Entry struct {
|
||||
|
||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||
Message string
|
||||
|
||||
// When formatter is called in entry.log(), an Buffer may be set to entry
|
||||
Buffer *bytes.Buffer
|
||||
}
|
||||
|
||||
func NewEntry(logger *Logger) *Entry {
|
||||
@@ -39,21 +52,15 @@ func NewEntry(logger *Logger) *Entry {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a reader for the entry, which is a proxy to the formatter.
|
||||
func (entry *Entry) Reader() (*bytes.Buffer, error) {
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
return bytes.NewBuffer(serialized), err
|
||||
}
|
||||
|
||||
// Returns the string representation from the reader and ultimately the
|
||||
// formatter.
|
||||
func (entry *Entry) String() (string, error) {
|
||||
reader, err := entry.Reader()
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return reader.String(), err
|
||||
str := string(serialized)
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
||||
@@ -68,7 +75,7 @@ func (entry *Entry) WithField(key string, value interface{}) *Entry {
|
||||
|
||||
// Add a map of fields to the Entry.
|
||||
func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||
data := Fields{}
|
||||
data := make(Fields, len(entry.Data)+len(fields))
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
@@ -81,6 +88,7 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||
// This function is not declared with a pointer value because otherwise
|
||||
// race conditions will occur when using multiple goroutines
|
||||
func (entry Entry) log(level Level, msg string) {
|
||||
var buffer *bytes.Buffer
|
||||
entry.Time = time.Now()
|
||||
entry.Level = level
|
||||
entry.Message = msg
|
||||
@@ -90,20 +98,23 @@ func (entry Entry) log(level Level, msg string) {
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
reader, err := entry.Reader()
|
||||
buffer = bufferPool.Get().(*bytes.Buffer)
|
||||
buffer.Reset()
|
||||
defer bufferPool.Put(buffer)
|
||||
entry.Buffer = buffer
|
||||
serialized, err := entry.Logger.Formatter.Format(&entry)
|
||||
entry.Buffer = nil
|
||||
if err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
|
||||
_, err = io.Copy(entry.Logger.Out, reader)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
} else {
|
||||
entry.Logger.mu.Lock()
|
||||
_, err = entry.Logger.Out.Write(serialized)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
}
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
// To avoid Entry#log() returning a value that only would make sense for
|
||||
@@ -150,7 +161,7 @@ func (entry *Entry) Fatal(args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.log(FatalLevel, fmt.Sprint(args...))
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panic(args ...interface{}) {
|
||||
@@ -198,7 +209,7 @@ func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.Fatal(fmt.Sprintf(format, args...))
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||
@@ -245,7 +256,7 @@ func (entry *Entry) Fatalln(args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.Fatal(entry.sprintlnn(args...))
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicln(args ...interface{}) {
|
||||
Generated
Vendored
Generated
Vendored
+6
-9
@@ -31,18 +31,15 @@ type Formatter interface {
|
||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||
// avoid code duplication between the two default formatters.
|
||||
func prefixFieldClashes(data Fields) {
|
||||
_, ok := data["time"]
|
||||
if ok {
|
||||
data["fields.time"] = data["time"]
|
||||
if t, ok := data["time"]; ok {
|
||||
data["fields.time"] = t
|
||||
}
|
||||
|
||||
_, ok = data["msg"]
|
||||
if ok {
|
||||
data["fields.msg"] = data["msg"]
|
||||
if m, ok := data["msg"]; ok {
|
||||
data["fields.msg"] = m
|
||||
}
|
||||
|
||||
_, ok = data["level"]
|
||||
if ok {
|
||||
data["fields.level"] = data["level"]
|
||||
if l, ok := data["level"]; ok {
|
||||
data["fields.level"] = l
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+74
@@ -0,0 +1,74 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type fieldKey string
|
||||
type FieldMap map[fieldKey]string
|
||||
|
||||
const (
|
||||
FieldKeyMsg = "msg"
|
||||
FieldKeyLevel = "level"
|
||||
FieldKeyTime = "time"
|
||||
)
|
||||
|
||||
func (f FieldMap) resolve(key fieldKey) string {
|
||||
if k, ok := f[key]; ok {
|
||||
return k
|
||||
}
|
||||
|
||||
return string(key)
|
||||
}
|
||||
|
||||
type JSONFormatter struct {
|
||||
// TimestampFormat sets the format used for marshaling timestamps.
|
||||
TimestampFormat string
|
||||
|
||||
// DisableTimestamp allows disabling automatic timestamps in output
|
||||
DisableTimestamp bool
|
||||
|
||||
// FieldMap allows users to customize the names of keys for various fields.
|
||||
// As an example:
|
||||
// formatter := &JSONFormatter{
|
||||
// FieldMap: FieldMap{
|
||||
// FieldKeyTime: "@timestamp",
|
||||
// FieldKeyLevel: "@level",
|
||||
// FieldKeyLevel: "@message",
|
||||
// },
|
||||
// }
|
||||
FieldMap FieldMap
|
||||
}
|
||||
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data := make(Fields, len(entry.Data)+3)
|
||||
for k, v := range entry.Data {
|
||||
switch v := v.(type) {
|
||||
case error:
|
||||
// Otherwise errors are ignored by `encoding/json`
|
||||
// https://github.com/Sirupsen/logrus/issues/137
|
||||
data[k] = v.Error()
|
||||
default:
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
prefixFieldClashes(data)
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
|
||||
if !f.DisableTimestamp {
|
||||
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
|
||||
}
|
||||
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
Generated
Vendored
+129
-33
@@ -26,8 +26,31 @@ type Logger struct {
|
||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||
// logged. `logrus.Debug` is useful in
|
||||
Level Level
|
||||
// Used to sync writing to the log.
|
||||
mu sync.Mutex
|
||||
// Used to sync writing to the log. Locking is enabled by Default
|
||||
mu MutexWrap
|
||||
// Reusable empty entry
|
||||
entryPool sync.Pool
|
||||
}
|
||||
|
||||
type MutexWrap struct {
|
||||
lock sync.Mutex
|
||||
disabled bool
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Lock() {
|
||||
if !mw.disabled {
|
||||
mw.lock.Lock()
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Unlock() {
|
||||
if !mw.disabled {
|
||||
mw.lock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Disable() {
|
||||
mw.disabled = true
|
||||
}
|
||||
|
||||
// Creates a new logger. Configuration should be set by changing `Formatter`,
|
||||
@@ -51,162 +74,235 @@ func New() *Logger {
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a field to the log entry, note that you it doesn't log until you call
|
||||
func (logger *Logger) newEntry() *Entry {
|
||||
entry, ok := logger.entryPool.Get().(*Entry)
|
||||
if ok {
|
||||
return entry
|
||||
}
|
||||
return NewEntry(logger)
|
||||
}
|
||||
|
||||
func (logger *Logger) releaseEntry(entry *Entry) {
|
||||
logger.entryPool.Put(entry)
|
||||
}
|
||||
|
||||
// Adds a field to the log entry, note that it doesn't log until you call
|
||||
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
||||
// If you want multiple fields, use `WithFields`.
|
||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
||||
return NewEntry(logger).WithField(key, value)
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithField(key, value)
|
||||
}
|
||||
|
||||
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
||||
// each `Field`.
|
||||
func (logger *Logger) WithFields(fields Fields) *Entry {
|
||||
return NewEntry(logger).WithFields(fields)
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithFields(fields)
|
||||
}
|
||||
|
||||
// Add an error as single field to the log entry. All it does is call
|
||||
// `WithError` for the given `error`.
|
||||
func (logger *Logger) WithError(err error) *Entry {
|
||||
return NewEntry(logger).WithError(err)
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithError(err)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debugf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Debugf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Infof(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Infof(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||
NewEntry(logger).Printf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Printf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Errorf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Errorf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatalf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panicf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Panicf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debug(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Debug(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Info(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Print(args ...interface{}) {
|
||||
NewEntry(logger).Info(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warn(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warn(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warn(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Error(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Error(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatal(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Fatal(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panic(args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panic(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Panic(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugln(args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debugln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Debugln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Infoln(args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Infoln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Infoln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Println(args ...interface{}) {
|
||||
NewEntry(logger).Println(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Println(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnln(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningln(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorln(args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Errorln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Errorln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatalln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicln(args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panicln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Panicln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
//When file is opened with appending mode, it's safe to
|
||||
//write concurrently to a file (within 4k message on Linux).
|
||||
//In these cases user can choose to disable the lock.
|
||||
func (logger *Logger) SetNoLock() {
|
||||
logger.mu.Disable()
|
||||
}
|
||||
Generated
Vendored
+46
-1
@@ -3,6 +3,7 @@ package logrus
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Fields type, used to pass to `WithFields`.
|
||||
@@ -33,7 +34,7 @@ func (level Level) String() string {
|
||||
|
||||
// ParseLevel takes a string level and returns the Logrus log level constant.
|
||||
func ParseLevel(lvl string) (Level, error) {
|
||||
switch lvl {
|
||||
switch strings.ToLower(lvl) {
|
||||
case "panic":
|
||||
return PanicLevel, nil
|
||||
case "fatal":
|
||||
@@ -52,6 +53,16 @@ func ParseLevel(lvl string) (Level, error) {
|
||||
return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
|
||||
}
|
||||
|
||||
// A constant exposing all logging levels
|
||||
var AllLevels = []Level{
|
||||
PanicLevel,
|
||||
FatalLevel,
|
||||
ErrorLevel,
|
||||
WarnLevel,
|
||||
InfoLevel,
|
||||
DebugLevel,
|
||||
}
|
||||
|
||||
// These are the different logging levels. You can set the logging level to log
|
||||
// on your instance of logger, obtained with `logrus.New()`.
|
||||
const (
|
||||
@@ -96,3 +107,37 @@ type StdLogger interface {
|
||||
Panicf(string, ...interface{})
|
||||
Panicln(...interface{})
|
||||
}
|
||||
|
||||
// The FieldLogger interface generalizes the Entry and Logger types
|
||||
type FieldLogger interface {
|
||||
WithField(key string, value interface{}) *Entry
|
||||
WithFields(fields Fields) *Entry
|
||||
WithError(err error) *Entry
|
||||
|
||||
Debugf(format string, args ...interface{})
|
||||
Infof(format string, args ...interface{})
|
||||
Printf(format string, args ...interface{})
|
||||
Warnf(format string, args ...interface{})
|
||||
Warningf(format string, args ...interface{})
|
||||
Errorf(format string, args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
Panicf(format string, args ...interface{})
|
||||
|
||||
Debug(args ...interface{})
|
||||
Info(args ...interface{})
|
||||
Print(args ...interface{})
|
||||
Warn(args ...interface{})
|
||||
Warning(args ...interface{})
|
||||
Error(args ...interface{})
|
||||
Fatal(args ...interface{})
|
||||
Panic(args ...interface{})
|
||||
|
||||
Debugln(args ...interface{})
|
||||
Infoln(args ...interface{})
|
||||
Println(args ...interface{})
|
||||
Warnln(args ...interface{})
|
||||
Warningln(args ...interface{})
|
||||
Errorln(args ...interface{})
|
||||
Fatalln(args ...interface{})
|
||||
Panicln(args ...interface{})
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// +build appengine
|
||||
|
||||
package logrus
|
||||
|
||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||
func IsTerminal() bool {
|
||||
return true
|
||||
}
|
||||
Generated
Vendored
+1
@@ -1,4 +1,5 @@
|
||||
// +build darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
Generated
Vendored
+2
@@ -3,6 +3,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
||||
Generated
Vendored
+1
@@ -4,6 +4,7 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
// +build solaris
|
||||
// +build solaris,!appengine
|
||||
|
||||
package logrus
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -3,7 +3,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
// +build windows,!appengine
|
||||
|
||||
package logrus
|
||||
|
||||
Generated
Vendored
+22
-17
@@ -28,10 +28,6 @@ func init() {
|
||||
isTerminal = IsTerminal()
|
||||
}
|
||||
|
||||
func miniTS() int {
|
||||
return int(time.Since(baseTimestamp) / time.Second)
|
||||
}
|
||||
|
||||
type TextFormatter struct {
|
||||
// Set to true to bypass checking for a TTY before outputting colors.
|
||||
ForceColors bool
|
||||
@@ -57,7 +53,8 @@ type TextFormatter struct {
|
||||
}
|
||||
|
||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
var keys []string = make([]string, 0, len(entry.Data))
|
||||
var b *bytes.Buffer
|
||||
keys := make([]string, 0, len(entry.Data))
|
||||
for k := range entry.Data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
@@ -65,8 +62,11 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
if !f.DisableSorting {
|
||||
sort.Strings(keys)
|
||||
}
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
if entry.Buffer != nil {
|
||||
b = entry.Buffer
|
||||
} else {
|
||||
b = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
prefixFieldClashes(entry.Data)
|
||||
|
||||
@@ -111,14 +111,17 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
|
||||
|
||||
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
||||
|
||||
if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
|
||||
if f.DisableTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
|
||||
} else if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
|
||||
} else {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := entry.Data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v)
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
||||
f.appendValue(b, v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,34 +131,36 @@ func needsQuoting(text string) bool {
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '-' || ch == '.') {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||
|
||||
b.WriteString(key)
|
||||
b.WriteByte('=')
|
||||
f.appendValue(b, value)
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
if needsQuoting(value) {
|
||||
if !needsQuoting(value) {
|
||||
b.WriteString(value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%q", value)
|
||||
}
|
||||
case error:
|
||||
errmsg := value.Error()
|
||||
if needsQuoting(errmsg) {
|
||||
if !needsQuoting(errmsg) {
|
||||
b.WriteString(errmsg)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%q", value)
|
||||
fmt.Fprintf(b, "%q", errmsg)
|
||||
}
|
||||
default:
|
||||
fmt.Fprint(b, value)
|
||||
}
|
||||
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func (logger *Logger) Writer() *io.PipeWriter {
|
||||
return logger.WriterLevel(InfoLevel)
|
||||
}
|
||||
|
||||
func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
|
||||
reader, writer := io.Pipe()
|
||||
|
||||
var printFunc func(args ...interface{})
|
||||
switch level {
|
||||
case DebugLevel:
|
||||
printFunc = logger.Debug
|
||||
case InfoLevel:
|
||||
printFunc = logger.Info
|
||||
case WarnLevel:
|
||||
printFunc = logger.Warn
|
||||
case ErrorLevel:
|
||||
printFunc = logger.Error
|
||||
case FatalLevel:
|
||||
printFunc = logger.Fatal
|
||||
case PanicLevel:
|
||||
printFunc = logger.Panic
|
||||
default:
|
||||
printFunc = logger.Print
|
||||
}
|
||||
|
||||
go logger.writerScanner(reader, printFunc)
|
||||
runtime.SetFinalizer(writer, writerFinalizer)
|
||||
|
||||
return writer
|
||||
}
|
||||
|
||||
func (logger *Logger) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
printFunc(scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
logger.Errorf("Error while reading from Writer: %s", err)
|
||||
}
|
||||
reader.Close()
|
||||
}
|
||||
|
||||
func writerFinalizer(writer *io.PipeWriter) {
|
||||
writer.Close()
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+2
-2
@@ -44,7 +44,7 @@ type Error interface {
|
||||
|
||||
// BatchError is a batch of errors which also wraps lower level errors with
|
||||
// code, message, and original errors. Calling Error() will include all errors
|
||||
// that occured in the batch.
|
||||
// that occurred in the batch.
|
||||
//
|
||||
// Deprecated: Replaced with BatchedErrors. Only defined for backwards
|
||||
// compatibility.
|
||||
@@ -64,7 +64,7 @@ type BatchError interface {
|
||||
|
||||
// BatchedErrors is a batch of errors which also wraps lower level errors with
|
||||
// code, message, and original errors. Calling Error() will include all errors
|
||||
// that occured in the batch.
|
||||
// that occurred in the batch.
|
||||
//
|
||||
// Replaces BatchError
|
||||
type BatchedErrors interface {
|
||||
Generated
Vendored
+1
-1
@@ -98,7 +98,7 @@ func (b baseError) OrigErr() error {
|
||||
return NewBatchError(err.Code(), err.Message(), b.errs[1:])
|
||||
}
|
||||
return NewBatchError("BatchedErrors",
|
||||
"multiple errors occured", b.errs)
|
||||
"multiple errors occurred", b.errs)
|
||||
}
|
||||
}
|
||||
|
||||
Generated
Vendored
+9
-1
@@ -3,6 +3,7 @@ package awsutil
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Copy deeply copies a src structure to dst. Useful for copying request and
|
||||
@@ -49,7 +50,14 @@ func rcopy(dst, src reflect.Value, root bool) {
|
||||
} else {
|
||||
e := src.Type().Elem()
|
||||
if dst.CanSet() && !src.IsNil() {
|
||||
dst.Set(reflect.New(e))
|
||||
if _, ok := src.Interface().(*time.Time); !ok {
|
||||
dst.Set(reflect.New(e))
|
||||
} else {
|
||||
tempValue := reflect.New(e)
|
||||
tempValue.Elem().Set(src.Elem())
|
||||
// Sets time.Time's unexported values
|
||||
dst.Set(tempValue)
|
||||
}
|
||||
}
|
||||
if src.Elem().IsValid() {
|
||||
// Keep the current root state since the depth hasn't changed
|
||||
Generated
Vendored
Generated
Vendored
+2
-2
@@ -106,8 +106,8 @@ func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTer
|
||||
|
||||
if indexStar || index != nil {
|
||||
nextvals = []reflect.Value{}
|
||||
for _, value := range values {
|
||||
value := reflect.Indirect(value)
|
||||
for _, valItem := range values {
|
||||
value := reflect.Indirect(valItem)
|
||||
if value.Kind() != reflect.Slice {
|
||||
continue
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+22
-5
@@ -2,7 +2,6 @@ package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http/httputil"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
@@ -87,16 +86,24 @@ const logReqMsg = `DEBUG: Request %s/%s Details:
|
||||
%s
|
||||
-----------------------------------------------------`
|
||||
|
||||
const logReqErrMsg = `DEBUG ERROR: Request %s/%s:
|
||||
---[ REQUEST DUMP ERROR ]-----------------------------
|
||||
%s
|
||||
-----------------------------------------------------`
|
||||
|
||||
func logRequest(r *request.Request) {
|
||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
||||
dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
||||
dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
||||
if err != nil {
|
||||
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err))
|
||||
return
|
||||
}
|
||||
|
||||
if logBody {
|
||||
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
|
||||
// Body as a NoOpCloser and will not be reset after read by the HTTP
|
||||
// client reader.
|
||||
r.Body.Seek(r.BodyStart, 0)
|
||||
r.HTTPRequest.Body = ioutil.NopCloser(r.Body)
|
||||
r.ResetBody()
|
||||
}
|
||||
|
||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody)))
|
||||
@@ -107,11 +114,21 @@ const logRespMsg = `DEBUG: Response %s/%s Details:
|
||||
%s
|
||||
-----------------------------------------------------`
|
||||
|
||||
const logRespErrMsg = `DEBUG ERROR: Response %s/%s:
|
||||
---[ RESPONSE DUMP ERROR ]-----------------------------
|
||||
%s
|
||||
-----------------------------------------------------`
|
||||
|
||||
func logResponse(r *request.Request) {
|
||||
var msg = "no response data"
|
||||
if r.HTTPResponse != nil {
|
||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
||||
dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody)
|
||||
dumpedBody, err := httputil.DumpResponse(r.HTTPResponse, logBody)
|
||||
if err != nil {
|
||||
r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err))
|
||||
return
|
||||
}
|
||||
|
||||
msg = string(dumpedBody)
|
||||
} else if r.Error != nil {
|
||||
msg = r.Error.Error()
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+96
-35
@@ -7,24 +7,36 @@ import (
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
)
|
||||
|
||||
// UseServiceDefaultRetries instructs the config to use the service's own default
|
||||
// number of retries. This will be the default action if Config.MaxRetries
|
||||
// is nil also.
|
||||
// UseServiceDefaultRetries instructs the config to use the service's own
|
||||
// default number of retries. This will be the default action if
|
||||
// Config.MaxRetries is nil also.
|
||||
const UseServiceDefaultRetries = -1
|
||||
|
||||
// RequestRetryer is an alias for a type that implements the request.Retryer interface.
|
||||
// RequestRetryer is an alias for a type that implements the request.Retryer
|
||||
// interface.
|
||||
type RequestRetryer interface{}
|
||||
|
||||
// A Config provides service configuration for service clients. By default,
|
||||
// all clients will use the {defaults.DefaultConfig} structure.
|
||||
// all clients will use the defaults.DefaultConfig tructure.
|
||||
//
|
||||
// // Create Session with MaxRetry configuration to be shared by multiple
|
||||
// // service clients.
|
||||
// sess, err := session.NewSession(&aws.Config{
|
||||
// MaxRetries: aws.Int(3),
|
||||
// })
|
||||
//
|
||||
// // Create S3 service client with a specific Region.
|
||||
// svc := s3.New(sess, &aws.Config{
|
||||
// Region: aws.String("us-west-2"),
|
||||
// })
|
||||
type Config struct {
|
||||
// Enables verbose error printing of all credential chain errors.
|
||||
// Should be used when wanting to see all errors while attempting to retreive
|
||||
// credentials.
|
||||
// Should be used when wanting to see all errors while attempting to
|
||||
// retrieve credentials.
|
||||
CredentialsChainVerboseErrors *bool
|
||||
|
||||
// The credentials object to use when signing requests. Defaults to
|
||||
// a chain of credential providers to search for credentials in environment
|
||||
// The credentials object to use when signing requests. Defaults to a
|
||||
// chain of credential providers to search for credentials in environment
|
||||
// variables, shared credential file, and EC2 Instance Roles.
|
||||
Credentials *credentials.Credentials
|
||||
|
||||
@@ -63,11 +75,12 @@ type Config struct {
|
||||
Logger Logger
|
||||
|
||||
// The maximum number of times that a request will be retried for failures.
|
||||
// Defaults to -1, which defers the max retry setting to the service specific
|
||||
// configuration.
|
||||
// Defaults to -1, which defers the max retry setting to the service
|
||||
// specific configuration.
|
||||
MaxRetries *int
|
||||
|
||||
// Retryer guides how HTTP requests should be retried in case of recoverable failures.
|
||||
// Retryer guides how HTTP requests should be retried in case of
|
||||
// recoverable failures.
|
||||
//
|
||||
// When nil or the value does not implement the request.Retryer interface,
|
||||
// the request.DefaultRetryer will be used.
|
||||
@@ -82,8 +95,8 @@ type Config struct {
|
||||
//
|
||||
Retryer RequestRetryer
|
||||
|
||||
// Disables semantic parameter validation, which validates input for missing
|
||||
// required fields and/or other semantic request input errors.
|
||||
// Disables semantic parameter validation, which validates input for
|
||||
// missing required fields and/or other semantic request input errors.
|
||||
DisableParamValidation *bool
|
||||
|
||||
// Disables the computation of request and response checksums, e.g.,
|
||||
@@ -91,8 +104,8 @@ type Config struct {
|
||||
DisableComputeChecksums *bool
|
||||
|
||||
// Set this to `true` to force the request to use path-style addressing,
|
||||
// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client will
|
||||
// use virtual hosted bucket addressing when possible
|
||||
// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client
|
||||
// will use virtual hosted bucket addressing when possible
|
||||
// (`http://BUCKET.s3.amazonaws.com/KEY`).
|
||||
//
|
||||
// @note This configuration option is specific to the Amazon S3 service.
|
||||
@@ -109,44 +122,81 @@ type Config struct {
|
||||
// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
|
||||
//
|
||||
// 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s
|
||||
// `ExpectContinueTimeout` for information on adjusting the continue wait timeout.
|
||||
// https://golang.org/pkg/net/http/#Transport
|
||||
// `ExpectContinueTimeout` for information on adjusting the continue wait
|
||||
// timeout. https://golang.org/pkg/net/http/#Transport
|
||||
//
|
||||
// You should use this flag to disble 100-Continue if you experiance issues
|
||||
// with proxies or thrid party S3 compatible services.
|
||||
// You should use this flag to disble 100-Continue if you experience issues
|
||||
// with proxies or third party S3 compatible services.
|
||||
S3Disable100Continue *bool
|
||||
|
||||
// Set this to `true` to enable S3 Accelerate feature. For all operations compatible
|
||||
// with S3 Accelerate will use the accelerate endpoint for requests. Requests not compatible
|
||||
// will fall back to normal S3 requests.
|
||||
// Set this to `true` to enable S3 Accelerate feature. For all operations
|
||||
// compatible with S3 Accelerate will use the accelerate endpoint for
|
||||
// requests. Requests not compatible will fall back to normal S3 requests.
|
||||
//
|
||||
// The bucket must be enable for accelerate to be used with S3 client with accelerate
|
||||
// enabled. If the bucket is not enabled for accelerate an error will be returned.
|
||||
// The bucket name must be DNS compatible to also work with accelerate.
|
||||
// The bucket must be enable for accelerate to be used with S3 client with
|
||||
// accelerate enabled. If the bucket is not enabled for accelerate an error
|
||||
// will be returned. The bucket name must be DNS compatible to also work
|
||||
// with accelerate.
|
||||
S3UseAccelerate *bool
|
||||
|
||||
// Set this to `true` to disable the EC2Metadata client from overriding the
|
||||
// default http.Client's Timeout. This is helpful if you do not want the EC2Metadata
|
||||
// client to create a new http.Client. This options is only meaningful if you're not
|
||||
// already using a custom HTTP client with the SDK. Enabled by default.
|
||||
// default http.Client's Timeout. This is helpful if you do not want the
|
||||
// EC2Metadata client to create a new http.Client. This options is only
|
||||
// meaningful if you're not already using a custom HTTP client with the
|
||||
// SDK. Enabled by default.
|
||||
//
|
||||
// Must be set and provided to the session.New() in order to disable the EC2Metadata
|
||||
// overriding the timeout for default credentials chain.
|
||||
// Must be set and provided to the session.NewSession() in order to disable
|
||||
// the EC2Metadata overriding the timeout for default credentials chain.
|
||||
//
|
||||
// Example:
|
||||
// sess := session.New(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true))
|
||||
// sess, err := session.NewSession(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true))
|
||||
//
|
||||
// svc := s3.New(sess)
|
||||
//
|
||||
EC2MetadataDisableTimeoutOverride *bool
|
||||
|
||||
// Instructs the endpiont to be generated for a service client to
|
||||
// be the dual stack endpoint. The dual stack endpoint will support
|
||||
// both IPv4 and IPv6 addressing.
|
||||
//
|
||||
// Setting this for a service which does not support dual stack will fail
|
||||
// to make requets. It is not recommended to set this value on the session
|
||||
// as it will apply to all service clients created with the session. Even
|
||||
// services which don't support dual stack endpoints.
|
||||
//
|
||||
// If the Endpoint config value is also provided the UseDualStack flag
|
||||
// will be ignored.
|
||||
//
|
||||
// Only supported with.
|
||||
//
|
||||
// sess, err := session.NewSession()
|
||||
//
|
||||
// svc := s3.New(sess, &aws.Config{
|
||||
// UseDualStack: aws.Bool(true),
|
||||
// })
|
||||
UseDualStack *bool
|
||||
|
||||
// SleepDelay is an override for the func the SDK will call when sleeping
|
||||
// during the lifecycle of a request. Specifically this will be used for
|
||||
// request delays. This value should only be used for testing. To adjust
|
||||
// the delay of a request see the aws/client.DefaultRetryer and
|
||||
// aws/request.Retryer.
|
||||
SleepDelay func(time.Duration)
|
||||
}
|
||||
|
||||
// NewConfig returns a new Config pointer that can be chained with builder methods to
|
||||
// set multiple configuration values inline without using pointers.
|
||||
// NewConfig returns a new Config pointer that can be chained with builder
|
||||
// methods to set multiple configuration values inline without using pointers.
|
||||
//
|
||||
// svc := s3.New(aws.NewConfig().WithRegion("us-west-2").WithMaxRetries(10))
|
||||
// // Create Session with MaxRetry configuration to be shared by multiple
|
||||
// // service clients.
|
||||
// sess, err := session.NewSession(aws.NewConfig().
|
||||
// WithMaxRetries(3),
|
||||
// )
|
||||
//
|
||||
// // Create S3 service client with a specific Region.
|
||||
// svc := s3.New(sess, aws.NewConfig().
|
||||
// WithRegion("us-west-2"),
|
||||
// )
|
||||
func NewConfig() *Config {
|
||||
return &Config{}
|
||||
}
|
||||
@@ -249,6 +299,13 @@ func (c *Config) WithS3UseAccelerate(enable bool) *Config {
|
||||
return c
|
||||
}
|
||||
|
||||
// WithUseDualStack sets a config UseDualStack value returning a Config
|
||||
// pointer for chaining.
|
||||
func (c *Config) WithUseDualStack(enable bool) *Config {
|
||||
c.UseDualStack = &enable
|
||||
return c
|
||||
}
|
||||
|
||||
// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
|
||||
// returning a Config pointer for chaining.
|
||||
func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
|
||||
@@ -335,6 +392,10 @@ func mergeInConfig(dst *Config, other *Config) {
|
||||
dst.S3UseAccelerate = other.S3UseAccelerate
|
||||
}
|
||||
|
||||
if other.UseDualStack != nil {
|
||||
dst.UseDualStack = other.UseDualStack
|
||||
}
|
||||
|
||||
if other.EC2MetadataDisableTimeoutOverride != nil {
|
||||
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
|
||||
}
|
||||
Generated
Vendored
+18
-6
@@ -2,7 +2,7 @@ package aws
|
||||
|
||||
import "time"
|
||||
|
||||
// String returns a pointer to of the string value passed in.
|
||||
// String returns a pointer to the string value passed in.
|
||||
func String(v string) *string {
|
||||
return &v
|
||||
}
|
||||
@@ -61,7 +61,7 @@ func StringValueMap(src map[string]*string) map[string]string {
|
||||
return dst
|
||||
}
|
||||
|
||||
// Bool returns a pointer to of the bool value passed in.
|
||||
// Bool returns a pointer to the bool value passed in.
|
||||
func Bool(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func BoolValueMap(src map[string]*bool) map[string]bool {
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int returns a pointer to of the int value passed in.
|
||||
// Int returns a pointer to the int value passed in.
|
||||
func Int(v int) *int {
|
||||
return &v
|
||||
}
|
||||
@@ -179,7 +179,7 @@ func IntValueMap(src map[string]*int) map[string]int {
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64 returns a pointer to of the int64 value passed in.
|
||||
// Int64 returns a pointer to the int64 value passed in.
|
||||
func Int64(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
@@ -238,7 +238,7 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64 returns a pointer to of the float64 value passed in.
|
||||
// Float64 returns a pointer to the float64 value passed in.
|
||||
func Float64(v float64) *float64 {
|
||||
return &v
|
||||
}
|
||||
@@ -297,7 +297,7 @@ func Float64ValueMap(src map[string]*float64) map[string]float64 {
|
||||
return dst
|
||||
}
|
||||
|
||||
// Time returns a pointer to of the time.Time value passed in.
|
||||
// Time returns a pointer to the time.Time value passed in.
|
||||
func Time(v time.Time) *time.Time {
|
||||
return &v
|
||||
}
|
||||
@@ -311,6 +311,18 @@ func TimeValue(v *time.Time) time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC".
|
||||
// The result is undefined if the Unix time cannot be represented by an int64.
|
||||
// Which includes calling TimeUnixMilli on a zero Time is undefined.
|
||||
//
|
||||
// This utility is useful for service API's such as CloudWatch Logs which require
|
||||
// their unix time values to be in milliseconds.
|
||||
//
|
||||
// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information.
|
||||
func TimeUnixMilli(t time.Time) int64 {
|
||||
return t.UnixNano() / int64(time.Millisecond/time.Nanosecond)
|
||||
}
|
||||
|
||||
// TimeSlice converts a slice of time.Time values into a slice of
|
||||
// time.Time pointers
|
||||
func TimeSlice(src []time.Time) []*time.Time {
|
||||
Generated
Vendored
+30
@@ -10,9 +10,11 @@ import (
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
@@ -67,6 +69,34 @@ var SDKVersionUserAgentHandler = request.NamedHandler{
|
||||
|
||||
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
|
||||
|
||||
// ValidateReqSigHandler is a request handler to ensure that the request's
|
||||
// signature doesn't expire before it is sent. This can happen when a request
|
||||
// is built and signed signficantly before it is sent. Or signficant delays
|
||||
// occur whne retrying requests that would cause the signature to expire.
|
||||
var ValidateReqSigHandler = request.NamedHandler{
|
||||
Name: "core.ValidateReqSigHandler",
|
||||
Fn: func(r *request.Request) {
|
||||
// Unsigned requests are not signed
|
||||
if r.Config.Credentials == credentials.AnonymousCredentials {
|
||||
return
|
||||
}
|
||||
|
||||
signedTime := r.Time
|
||||
if !r.LastSignedAt.IsZero() {
|
||||
signedTime = r.LastSignedAt
|
||||
}
|
||||
|
||||
// 10 minutes to allow for some clock skew/delays in transmission.
|
||||
// Would be improved with aws/aws-sdk-go#423
|
||||
if signedTime.Add(10 * time.Minute).After(time.Now()) {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("request expired, resigning")
|
||||
r.Sign()
|
||||
},
|
||||
}
|
||||
|
||||
// SendHandler is a request handler to send service request using HTTP client.
|
||||
var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) {
|
||||
var err error
|
||||
Generated
Vendored
Generated
Vendored
+1
-1
@@ -34,7 +34,7 @@ var (
|
||||
//
|
||||
// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
|
||||
// In this example EnvProvider will first check if any credentials are available
|
||||
// vai the environment variables. If there are none ChainProvider will check
|
||||
// via the environment variables. If there are none ChainProvider will check
|
||||
// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
|
||||
// does not return any credentials ChainProvider will return the error
|
||||
// ErrNoValidProvidersFoundInChain
|
||||
Generated
Vendored
+191
@@ -0,0 +1,191 @@
|
||||
// Package endpointcreds provides support for retrieving credentials from an
|
||||
// arbitrary HTTP endpoint.
|
||||
//
|
||||
// The credentials endpoint Provider can receive both static and refreshable
|
||||
// credentials that will expire. Credentials are static when an "Expiration"
|
||||
// value is not provided in the endpoint's response.
|
||||
//
|
||||
// Static credentials will never expire once they have been retrieved. The format
|
||||
// of the static credentials response:
|
||||
// {
|
||||
// "AccessKeyId" : "MUA...",
|
||||
// "SecretAccessKey" : "/7PC5om....",
|
||||
// }
|
||||
//
|
||||
// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration
|
||||
// value in the response. The format of the refreshable credentials response:
|
||||
// {
|
||||
// "AccessKeyId" : "MUA...",
|
||||
// "SecretAccessKey" : "/7PC5om....",
|
||||
// "Token" : "AQoDY....=",
|
||||
// "Expiration" : "2016-02-25T06:03:31Z"
|
||||
// }
|
||||
//
|
||||
// Errors should be returned in the following format and only returned with 400
|
||||
// or 500 HTTP status codes.
|
||||
// {
|
||||
// "code": "ErrorCode",
|
||||
// "message": "Helpful error message."
|
||||
// }
|
||||
package endpointcreds
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// ProviderName is the name of the credentials provider.
|
||||
const ProviderName = `CredentialsEndpointProvider`
|
||||
|
||||
// Provider satisfies the credentials.Provider interface, and is a client to
|
||||
// retrieve credentials from an arbitrary endpoint.
|
||||
type Provider struct {
|
||||
staticCreds bool
|
||||
credentials.Expiry
|
||||
|
||||
// Requires a AWS Client to make HTTP requests to the endpoint with.
|
||||
// the Endpoint the request will be made to is provided by the aws.Config's
|
||||
// Endpoint value.
|
||||
Client *client.Client
|
||||
|
||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
||||
// the credentials actually expiring. This is beneficial so race conditions
|
||||
// with expiring credentials do not cause request to fail unexpectedly
|
||||
// due to ExpiredTokenException exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
//
|
||||
// If ExpiryWindow is 0 or less it will be ignored.
|
||||
ExpiryWindow time.Duration
|
||||
}
|
||||
|
||||
// NewProviderClient returns a credentials Provider for retrieving AWS credentials
|
||||
// from arbitrary endpoint.
|
||||
func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider {
|
||||
p := &Provider{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "CredentialsEndpoint",
|
||||
Endpoint: endpoint,
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler)
|
||||
p.Client.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||
p.Client.Handlers.Validate.Clear()
|
||||
p.Client.Handlers.Validate.PushBack(validateEndpointHandler)
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// NewCredentialsClient returns a Credentials wrapper for retrieving credentials
|
||||
// from an arbitrary endpoint concurrently. The client will request the
|
||||
func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials {
|
||||
return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...))
|
||||
}
|
||||
|
||||
// IsExpired returns true if the credentials retrieved are expired, or not yet
|
||||
// retrieved.
|
||||
func (p *Provider) IsExpired() bool {
|
||||
if p.staticCreds {
|
||||
return false
|
||||
}
|
||||
return p.Expiry.IsExpired()
|
||||
}
|
||||
|
||||
// Retrieve will attempt to request the credentials from the endpoint the Provider
|
||||
// was configured for. And error will be returned if the retrieval fails.
|
||||
func (p *Provider) Retrieve() (credentials.Value, error) {
|
||||
resp, err := p.getCredentials()
|
||||
if err != nil {
|
||||
return credentials.Value{ProviderName: ProviderName},
|
||||
awserr.New("CredentialsEndpointError", "failed to load credentials", err)
|
||||
}
|
||||
|
||||
if resp.Expiration != nil {
|
||||
p.SetExpiration(*resp.Expiration, p.ExpiryWindow)
|
||||
} else {
|
||||
p.staticCreds = true
|
||||
}
|
||||
|
||||
return credentials.Value{
|
||||
AccessKeyID: resp.AccessKeyID,
|
||||
SecretAccessKey: resp.SecretAccessKey,
|
||||
SessionToken: resp.Token,
|
||||
ProviderName: ProviderName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type getCredentialsOutput struct {
|
||||
Expiration *time.Time
|
||||
AccessKeyID string
|
||||
SecretAccessKey string
|
||||
Token string
|
||||
}
|
||||
|
||||
type errorOutput struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (p *Provider) getCredentials() (*getCredentialsOutput, error) {
|
||||
op := &request.Operation{
|
||||
Name: "GetCredentials",
|
||||
HTTPMethod: "GET",
|
||||
}
|
||||
|
||||
out := &getCredentialsOutput{}
|
||||
req := p.Client.NewRequest(op, nil, out)
|
||||
req.HTTPRequest.Header.Set("Accept", "application/json")
|
||||
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
func validateEndpointHandler(r *request.Request) {
|
||||
if len(r.ClientInfo.Endpoint) == 0 {
|
||||
r.Error = aws.ErrMissingEndpoint
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalHandler(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
out := r.Data.(*getCredentialsOutput)
|
||||
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil {
|
||||
r.Error = awserr.New("SerializationError",
|
||||
"failed to decode endpoint credentials",
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalError(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
var errOut errorOutput
|
||||
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil {
|
||||
r.Error = awserr.New("SerializationError",
|
||||
"failed to decode endpoint credentials",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
// Response body format is not consistent between metadata endpoints.
|
||||
// Grab the error message as a string and include that as the source error
|
||||
r.Error = awserr.New(errOut.Code, errOut.Message, nil)
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+10
-1
@@ -30,13 +30,22 @@ func NewStaticCredentials(id, secret, token string) *Credentials {
|
||||
}})
|
||||
}
|
||||
|
||||
// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object
|
||||
// wrapping the static credentials value provide. Same as NewStaticCredentials
|
||||
// but takes the creds Value instead of individual fields
|
||||
func NewStaticCredentialsFromCreds(creds Value) *Credentials {
|
||||
return NewCredentials(&StaticProvider{Value: creds})
|
||||
}
|
||||
|
||||
// Retrieve returns the credentials or error if the credentials are invalid.
|
||||
func (s *StaticProvider) Retrieve() (Value, error) {
|
||||
if s.AccessKeyID == "" || s.SecretAccessKey == "" {
|
||||
return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty
|
||||
}
|
||||
|
||||
s.Value.ProviderName = StaticProviderName
|
||||
if len(s.Value.ProviderName) == 0 {
|
||||
s.Value.ProviderName = StaticProviderName
|
||||
}
|
||||
return s.Value, nil
|
||||
}
|
||||
|
||||
Generated
Vendored
+161
@@ -0,0 +1,161 @@
|
||||
// Package stscreds are credential Providers to retrieve STS AWS credentials.
|
||||
//
|
||||
// STS provides multiple ways to retrieve credentials which can be used when making
|
||||
// future AWS service API operation calls.
|
||||
package stscreds
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
)
|
||||
|
||||
// ProviderName provides a name of AssumeRole provider
|
||||
const ProviderName = "AssumeRoleProvider"
|
||||
|
||||
// AssumeRoler represents the minimal subset of the STS client API used by this provider.
|
||||
type AssumeRoler interface {
|
||||
AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
|
||||
}
|
||||
|
||||
// DefaultDuration is the default amount of time in minutes that the credentials
|
||||
// will be valid for.
|
||||
var DefaultDuration = time.Duration(15) * time.Minute
|
||||
|
||||
// AssumeRoleProvider retrieves temporary credentials from the STS service, and
|
||||
// keeps track of their expiration time. This provider must be used explicitly,
|
||||
// as it is not included in the credentials chain.
|
||||
type AssumeRoleProvider struct {
|
||||
credentials.Expiry
|
||||
|
||||
// STS client to make assume role request with.
|
||||
Client AssumeRoler
|
||||
|
||||
// Role to be assumed.
|
||||
RoleARN string
|
||||
|
||||
// Session name, if you wish to reuse the credentials elsewhere.
|
||||
RoleSessionName string
|
||||
|
||||
// Expiry duration of the STS credentials. Defaults to 15 minutes if not set.
|
||||
Duration time.Duration
|
||||
|
||||
// Optional ExternalID to pass along, defaults to nil if not set.
|
||||
ExternalID *string
|
||||
|
||||
// The policy plain text must be 2048 bytes or shorter. However, an internal
|
||||
// conversion compresses it into a packed binary format with a separate limit.
|
||||
// The PackedPolicySize response element indicates by percentage how close to
|
||||
// the upper size limit the policy is, with 100% equaling the maximum allowed
|
||||
// size.
|
||||
Policy *string
|
||||
|
||||
// The identification number of the MFA device that is associated with the user
|
||||
// who is making the AssumeRole call. Specify this value if the trust policy
|
||||
// of the role being assumed includes a condition that requires MFA authentication.
|
||||
// The value is either the serial number for a hardware device (such as GAHT12345678)
|
||||
// or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
|
||||
SerialNumber *string
|
||||
|
||||
// The value provided by the MFA device, if the trust policy of the role being
|
||||
// assumed requires MFA (that is, if the policy includes a condition that tests
|
||||
// for MFA). If the role being assumed requires MFA and if the TokenCode value
|
||||
// is missing or expired, the AssumeRole call returns an "access denied" error.
|
||||
TokenCode *string
|
||||
|
||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
||||
// the credentials actually expiring. This is beneficial so race conditions
|
||||
// with expiring credentials do not cause request to fail unexpectedly
|
||||
// due to ExpiredTokenException exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
//
|
||||
// If ExpiryWindow is 0 or less it will be ignored.
|
||||
ExpiryWindow time.Duration
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials object wrapping the
|
||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
||||
// role will be named after a nanosecond timestamp of this operation.
|
||||
//
|
||||
// Takes a Config provider to create the STS client. The ConfigProvider is
|
||||
// satisfied by the session.Session type.
|
||||
func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
||||
p := &AssumeRoleProvider{
|
||||
Client: sts.New(c),
|
||||
RoleARN: roleARN,
|
||||
Duration: DefaultDuration,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the
|
||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
||||
// role will be named after a nanosecond timestamp of this operation.
|
||||
//
|
||||
// Takes an AssumeRoler which can be satisfiede by the STS client.
|
||||
func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
||||
p := &AssumeRoleProvider{
|
||||
Client: svc,
|
||||
RoleARN: roleARN,
|
||||
Duration: DefaultDuration,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// Retrieve generates a new set of temporary credentials using STS.
|
||||
func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
|
||||
|
||||
// Apply defaults where parameters are not set.
|
||||
if p.RoleSessionName == "" {
|
||||
// Try to work out a role name that will hopefully end up unique.
|
||||
p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
|
||||
}
|
||||
if p.Duration == 0 {
|
||||
// Expire as often as AWS permits.
|
||||
p.Duration = DefaultDuration
|
||||
}
|
||||
input := &sts.AssumeRoleInput{
|
||||
DurationSeconds: aws.Int64(int64(p.Duration / time.Second)),
|
||||
RoleArn: aws.String(p.RoleARN),
|
||||
RoleSessionName: aws.String(p.RoleSessionName),
|
||||
ExternalId: p.ExternalID,
|
||||
}
|
||||
if p.Policy != nil {
|
||||
input.Policy = p.Policy
|
||||
}
|
||||
if p.SerialNumber != nil && p.TokenCode != nil {
|
||||
input.SerialNumber = p.SerialNumber
|
||||
input.TokenCode = p.TokenCode
|
||||
}
|
||||
roleOutput, err := p.Client.AssumeRole(input)
|
||||
|
||||
if err != nil {
|
||||
return credentials.Value{ProviderName: ProviderName}, err
|
||||
}
|
||||
|
||||
// We will proactively generate new credentials before they expire.
|
||||
p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow)
|
||||
|
||||
return credentials.Value{
|
||||
AccessKeyID: *roleOutput.Credentials.AccessKeyId,
|
||||
SecretAccessKey: *roleOutput.Credentials.SecretAccessKey,
|
||||
SessionToken: *roleOutput.Credentials.SessionToken,
|
||||
ProviderName: ProviderName,
|
||||
}, nil
|
||||
}
|
||||
Generated
Vendored
+40
-7
@@ -8,6 +8,7 @@
|
||||
package defaults
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/endpoints"
|
||||
@@ -66,9 +68,11 @@ func Handlers() request.Handlers {
|
||||
var handlers request.Handlers
|
||||
|
||||
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||
handlers.Validate.AfterEachFn = request.HandlerListStopOnError
|
||||
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
||||
handlers.Build.AfterEachFn = request.HandlerListStopOnError
|
||||
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
||||
handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler)
|
||||
handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
||||
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
||||
handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
|
||||
@@ -82,16 +86,45 @@ func Handlers() request.Handlers {
|
||||
// is available if you need to reset the credentials of an
|
||||
// existing service client or session's Config.
|
||||
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
|
||||
endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true)
|
||||
|
||||
return credentials.NewCredentials(&credentials.ChainProvider{
|
||||
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
|
||||
Providers: []credentials.Provider{
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
||||
&ec2rolecreds.EC2RoleProvider{
|
||||
Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion),
|
||||
ExpiryWindow: 5 * time.Minute,
|
||||
},
|
||||
}})
|
||||
RemoteCredProvider(*cfg, handlers),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// RemoteCredProvider returns a credenitials provider for the default remote
|
||||
// endpoints such as EC2 or ECS Roles.
|
||||
func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
||||
ecsCredURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI")
|
||||
|
||||
if len(ecsCredURI) > 0 {
|
||||
return ecsCredProvider(cfg, handlers, ecsCredURI)
|
||||
}
|
||||
|
||||
return ec2RoleProvider(cfg, handlers)
|
||||
}
|
||||
|
||||
func ecsCredProvider(cfg aws.Config, handlers request.Handlers, uri string) credentials.Provider {
|
||||
const host = `169.254.170.2`
|
||||
|
||||
return endpointcreds.NewProviderClient(cfg, handlers,
|
||||
fmt.Sprintf("http://%s%s", host, uri),
|
||||
func(p *endpointcreds.Provider) {
|
||||
p.ExpiryWindow = 5 * time.Minute
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
||||
endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName,
|
||||
aws.StringValue(cfg.Region), true, false)
|
||||
|
||||
return &ec2rolecreds.EC2RoleProvider{
|
||||
Client: ec2metadata.NewClient(cfg, handlers, endpoint, signingRegion),
|
||||
ExpiryWindow: 5 * time.Minute,
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+22
@@ -3,6 +3,7 @@ package ec2metadata
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -27,6 +28,27 @@ func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
||||
return output.Content, req.Send()
|
||||
}
|
||||
|
||||
// GetUserData returns the userdata that was configured for the service. If
|
||||
// there is no user-data setup for the EC2 instance a "NotFoundError" error
|
||||
// code will be returned.
|
||||
func (c *EC2Metadata) GetUserData() (string, error) {
|
||||
op := &request.Operation{
|
||||
Name: "GetUserData",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: path.Join("/", "user-data"),
|
||||
}
|
||||
|
||||
output := &metadataOutput{}
|
||||
req := c.NewRequest(op, nil, output)
|
||||
req.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
|
||||
if r.HTTPResponse.StatusCode == http.StatusNotFound {
|
||||
r.Error = awserr.New("NotFoundError", "user-data not found", r.Error)
|
||||
}
|
||||
})
|
||||
|
||||
return output.Content, req.Send()
|
||||
}
|
||||
|
||||
// GetDynamicData uses the path provided to request information from the EC2
|
||||
// instance metadata service for dynamic data. The content will be returned
|
||||
// as a string, or error if the request failed.
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
|
||||
req := new(http.Request)
|
||||
*req = *r
|
||||
req.URL = &url.URL{}
|
||||
*req.URL = *r.URL
|
||||
req.Body = body
|
||||
|
||||
req.Header = http.Header{}
|
||||
for k, v := range r.Header {
|
||||
for _, vv := range v {
|
||||
req.Header.Add(k, vv)
|
||||
}
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
Generated
Vendored
+14
-5
@@ -9,7 +9,7 @@ import (
|
||||
// with retrying requests
|
||||
type offsetReader struct {
|
||||
buf io.ReadSeeker
|
||||
lock sync.RWMutex
|
||||
lock sync.Mutex
|
||||
closed bool
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader {
|
||||
return reader
|
||||
}
|
||||
|
||||
// Close is a thread-safe close. Uses the write lock.
|
||||
// Close will close the instance of the offset reader's access to
|
||||
// the underlying io.ReadSeeker.
|
||||
func (o *offsetReader) Close() error {
|
||||
o.lock.Lock()
|
||||
defer o.lock.Unlock()
|
||||
@@ -29,10 +30,10 @@ func (o *offsetReader) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read is a thread-safe read using a read lock.
|
||||
// Read is a thread-safe read of the underlying io.ReadSeeker
|
||||
func (o *offsetReader) Read(p []byte) (int, error) {
|
||||
o.lock.RLock()
|
||||
defer o.lock.RUnlock()
|
||||
o.lock.Lock()
|
||||
defer o.lock.Unlock()
|
||||
|
||||
if o.closed {
|
||||
return 0, io.EOF
|
||||
@@ -41,6 +42,14 @@ func (o *offsetReader) Read(p []byte) (int, error) {
|
||||
return o.buf.Read(p)
|
||||
}
|
||||
|
||||
// Seek is a thread-safe seeking operation.
|
||||
func (o *offsetReader) Seek(offset int64, whence int) (int64, error) {
|
||||
o.lock.Lock()
|
||||
defer o.lock.Unlock()
|
||||
|
||||
return o.buf.Seek(offset, whence)
|
||||
}
|
||||
|
||||
// CloseAndCopy will return a new offsetReader with a copy of the old buffer
|
||||
// and close the old buffer.
|
||||
func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader {
|
||||
Generated
Vendored
+45
-24
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
)
|
||||
|
||||
@@ -38,8 +38,15 @@ type Request struct {
|
||||
RetryDelay time.Duration
|
||||
NotHoist bool
|
||||
SignedHeaderVals http.Header
|
||||
LastSignedAt time.Time
|
||||
|
||||
built bool
|
||||
|
||||
// Need to persist an intermideant body betweend the input Body and HTTP
|
||||
// request body because the HTTP Client's transport can maintain a reference
|
||||
// to the HTTP request's body after the client has returned. This value is
|
||||
// safe to use concurrently and rewraps the input Body for each HTTP request.
|
||||
safeBody *offsetReader
|
||||
}
|
||||
|
||||
// An Operation is the service API operation to be made.
|
||||
@@ -71,13 +78,15 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
||||
if method == "" {
|
||||
method = "POST"
|
||||
}
|
||||
p := operation.HTTPPath
|
||||
if p == "" {
|
||||
p = "/"
|
||||
}
|
||||
|
||||
httpReq, _ := http.NewRequest(method, "", nil)
|
||||
httpReq.URL, _ = url.Parse(clientInfo.Endpoint + p)
|
||||
|
||||
var err error
|
||||
httpReq.URL, err = url.Parse(clientInfo.Endpoint + operation.HTTPPath)
|
||||
if err != nil {
|
||||
httpReq.URL = &url.URL{}
|
||||
err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
|
||||
}
|
||||
|
||||
r := &Request{
|
||||
Config: cfg,
|
||||
@@ -91,7 +100,7 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
||||
HTTPRequest: httpReq,
|
||||
Body: nil,
|
||||
Params: params,
|
||||
Error: nil,
|
||||
Error: err,
|
||||
Data: data,
|
||||
}
|
||||
r.SetBufferBody([]byte{})
|
||||
@@ -131,8 +140,8 @@ func (r *Request) SetStringBody(s string) {
|
||||
|
||||
// SetReaderBody will set the request's body reader.
|
||||
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
||||
r.HTTPRequest.Body = newOffsetReader(reader, 0)
|
||||
r.Body = reader
|
||||
r.ResetBody()
|
||||
}
|
||||
|
||||
// Presign returns the request's signed URL. Error will be returned
|
||||
@@ -185,7 +194,6 @@ func debugLogReqError(r *Request, stage string, retrying bool, err error) {
|
||||
// which occurred will be returned.
|
||||
func (r *Request) Build() error {
|
||||
if !r.built {
|
||||
r.Error = nil
|
||||
r.Handlers.Validate.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Validate Request", false, r.Error)
|
||||
@@ -202,7 +210,7 @@ func (r *Request) Build() error {
|
||||
return r.Error
|
||||
}
|
||||
|
||||
// Sign will sign the request retuning error if errors are encountered.
|
||||
// Sign will sign the request returning error if errors are encountered.
|
||||
//
|
||||
// Send will build the request prior to signing. All Sign Handlers will
|
||||
// be executed in the order they were set.
|
||||
@@ -217,6 +225,24 @@ func (r *Request) Sign() error {
|
||||
return r.Error
|
||||
}
|
||||
|
||||
// ResetBody rewinds the request body backto its starting position, and
|
||||
// set's the HTTP Request body reference. When the body is read prior
|
||||
// to being sent in the HTTP request it will need to be rewound.
|
||||
func (r *Request) ResetBody() {
|
||||
if r.safeBody != nil {
|
||||
r.safeBody.Close()
|
||||
}
|
||||
|
||||
r.safeBody = newOffsetReader(r.Body, r.BodyStart)
|
||||
r.HTTPRequest.Body = r.safeBody
|
||||
}
|
||||
|
||||
// GetBody will return an io.ReadSeeker of the Request's underlying
|
||||
// input body with a concurrency safe wrapper.
|
||||
func (r *Request) GetBody() io.ReadSeeker {
|
||||
return r.safeBody
|
||||
}
|
||||
|
||||
// Send will send the request returning error if errors are encountered.
|
||||
//
|
||||
// Send will sign the request prior to sending. All Send Handlers will
|
||||
@@ -228,6 +254,8 @@ func (r *Request) Sign() error {
|
||||
//
|
||||
// readLoop() and getConn(req *Request, cm connectMethod)
|
||||
// https://github.com/golang/go/blob/master/src/net/http/transport.go
|
||||
//
|
||||
// Send will not close the request.Request's body.
|
||||
func (r *Request) Send() error {
|
||||
for {
|
||||
if aws.BoolValue(r.Retryable) {
|
||||
@@ -236,21 +264,15 @@ func (r *Request) Send() error {
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
||||
}
|
||||
|
||||
var body io.ReadCloser
|
||||
if reader, ok := r.HTTPRequest.Body.(*offsetReader); ok {
|
||||
body = reader.CloseAndCopy(r.BodyStart)
|
||||
} else {
|
||||
if r.Config.Logger != nil {
|
||||
r.Config.Logger.Log("Request body type has been overwritten. May cause race conditions")
|
||||
}
|
||||
r.Body.Seek(r.BodyStart, 0)
|
||||
body = ioutil.NopCloser(r.Body)
|
||||
}
|
||||
// The previous http.Request will have a reference to the r.Body
|
||||
// and the HTTP Client's Transport may still be reading from
|
||||
// the request's body even though the Client's Do returned.
|
||||
r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil)
|
||||
r.ResetBody()
|
||||
|
||||
r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, body)
|
||||
// Closing response body to ensure that no response body is leaked
|
||||
// between retry attempts.
|
||||
if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
|
||||
// Closing response body. Since we are setting a new request to send off, this
|
||||
// response will get squashed and leaked.
|
||||
r.HTTPResponse.Body.Close()
|
||||
}
|
||||
}
|
||||
@@ -278,7 +300,6 @@ func (r *Request) Send() error {
|
||||
debugLogReqError(r, "Send Request", true, err)
|
||||
continue
|
||||
}
|
||||
|
||||
r.Handlers.UnmarshalMeta.Run(r)
|
||||
r.Handlers.ValidateResponse.Run(r)
|
||||
if r.Error != nil {
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+223
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
Package session provides configuration for the SDK's service clients.
|
||||
|
||||
Sessions can be shared across all service clients that share the same base
|
||||
configuration. The Session is built from the SDK's default configuration and
|
||||
request handlers.
|
||||
|
||||
Sessions should be cached when possible, because creating a new Session will
|
||||
load all configuration values from the environment, and config files each time
|
||||
the Session is created. Sharing the Session value across all of your service
|
||||
clients will ensure the configuration is loaded the fewest number of times possible.
|
||||
|
||||
Concurrency
|
||||
|
||||
Sessions are safe to use concurrently as long as the Session is not being
|
||||
modified. The SDK will not modify the Session once the Session has been created.
|
||||
Creating service clients concurrently from a shared Session is safe.
|
||||
|
||||
Sessions from Shared Config
|
||||
|
||||
Sessions can be created using the method above that will only load the
|
||||
additional config if the AWS_SDK_LOAD_CONFIG environment variable is set.
|
||||
Alternatively you can explicitly create a Session with shared config enabled.
|
||||
To do this you can use NewSessionWithOptions to configure how the Session will
|
||||
be created. Using the NewSessionWithOptions with SharedConfigState set to
|
||||
SharedConfigEnabled will create the session as if the AWS_SDK_LOAD_CONFIG
|
||||
environment variable was set.
|
||||
|
||||
Creating Sessions
|
||||
|
||||
When creating Sessions optional aws.Config values can be passed in that will
|
||||
override the default, or loaded config values the Session is being created
|
||||
with. This allows you to provide additional, or case based, configuration
|
||||
as needed.
|
||||
|
||||
By default NewSession will only load credentials from the shared credentials
|
||||
file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is
|
||||
set to a truthy value the Session will be created from the configuration
|
||||
values from the shared config (~/.aws/config) and shared credentials
|
||||
(~/.aws/credentials) files. See the section Sessions from Shared Config for
|
||||
more information.
|
||||
|
||||
Create a Session with the default config and request handlers. With credentials
|
||||
region, and profile loaded from the environment and shared config automatically.
|
||||
Requires the AWS_PROFILE to be set, or "default" is used.
|
||||
|
||||
// Create Session
|
||||
sess, err := session.NewSession()
|
||||
|
||||
// Create a Session with a custom region
|
||||
sess, err := session.NewSession(&aws.Config{Region: aws.String("us-east-1")})
|
||||
|
||||
// Create a S3 client instance from a session
|
||||
sess, err := session.NewSession()
|
||||
if err != nil {
|
||||
// Handle Session creation error
|
||||
}
|
||||
svc := s3.New(sess)
|
||||
|
||||
Create Session With Option Overrides
|
||||
|
||||
In addition to NewSession, Sessions can be created using NewSessionWithOptions.
|
||||
This func allows you to control and override how the Session will be created
|
||||
through code instead of being driven by environment variables only.
|
||||
|
||||
Use NewSessionWithOptions when you want to provide the config profile, or
|
||||
override the shared config state (AWS_SDK_LOAD_CONFIG).
|
||||
|
||||
// Equivalent to session.NewSession()
|
||||
sess, err := session.NewSessionWithOptions(session.Options{})
|
||||
|
||||
// Specify profile to load for the session's config
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
Profile: "profile_name",
|
||||
})
|
||||
|
||||
// Specify profile for config and region for requests
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
Config: aws.Config{Region: aws.String("us-east-1")},
|
||||
Profile: "profile_name",
|
||||
})
|
||||
|
||||
// Force enable Shared Config support
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
SharedConfigState: SharedConfigEnable,
|
||||
})
|
||||
|
||||
Adding Handlers
|
||||
|
||||
You can add handlers to a session for processing HTTP requests. All service
|
||||
clients that use the session inherit the handlers. For example, the following
|
||||
handler logs every request and its payload made by a service client:
|
||||
|
||||
// Create a session, and add additional handlers for all service
|
||||
// clients created with the Session to inherit. Adds logging handler.
|
||||
sess, err := session.NewSession()
|
||||
sess.Handlers.Send.PushFront(func(r *request.Request) {
|
||||
// Log every request made and its payload
|
||||
logger.Println("Request: %s/%s, Payload: %s",
|
||||
r.ClientInfo.ServiceName, r.Operation, r.Params)
|
||||
})
|
||||
|
||||
Deprecated "New" function
|
||||
|
||||
The New session function has been deprecated because it does not provide good
|
||||
way to return errors that occur when loading the configuration files and values.
|
||||
Because of this, NewSession was created so errors can be retrieved when
|
||||
creating a session fails.
|
||||
|
||||
Shared Config Fields
|
||||
|
||||
By default the SDK will only load the shared credentials file's (~/.aws/credentials)
|
||||
credentials values, and all other config is provided by the environment variables,
|
||||
SDK defaults, and user provided aws.Config values.
|
||||
|
||||
If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable
|
||||
option is used to create the Session the full shared config values will be
|
||||
loaded. This includes credentials, region, and support for assume role. In
|
||||
addition the Session will load its configuration from both the shared config
|
||||
file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both
|
||||
files have the same format.
|
||||
|
||||
If both config files are present the configuration from both files will be
|
||||
read. The Session will be created from configuration values from the shared
|
||||
credentials file (~/.aws/credentials) over those in the shared credentials
|
||||
file (~/.aws/config).
|
||||
|
||||
Credentials are the values the SDK should use for authenticating requests with
|
||||
AWS Services. They arfrom a configuration file will need to include both
|
||||
aws_access_key_id and aws_secret_access_key must be provided together in the
|
||||
same file to be considered valid. The values will be ignored if not a complete
|
||||
group. aws_session_token is an optional field that can be provided if both of
|
||||
the other two fields are also provided.
|
||||
|
||||
aws_access_key_id = AKID
|
||||
aws_secret_access_key = SECRET
|
||||
aws_session_token = TOKEN
|
||||
|
||||
Assume Role values allow you to configure the SDK to assume an IAM role using
|
||||
a set of credentials provided in a config file via the source_profile field.
|
||||
Both "role_arn" and "source_profile" are required. The SDK does not support
|
||||
assuming a role with MFA token Via the Session's constructor. You can use the
|
||||
stscreds.AssumeRoleProvider credentials provider to specify custom
|
||||
configuration and support for MFA.
|
||||
|
||||
role_arn = arn:aws:iam::<account_number>:role/<role_name>
|
||||
source_profile = profile_with_creds
|
||||
external_id = 1234
|
||||
mfa_serial = not supported!
|
||||
role_session_name = session_name
|
||||
|
||||
Region is the region the SDK should use for looking up AWS service endpoints
|
||||
and signing requests.
|
||||
|
||||
region = us-east-1
|
||||
|
||||
Environment Variables
|
||||
|
||||
When a Session is created several environment variables can be set to adjust
|
||||
how the SDK functions, and what configuration data it loads when creating
|
||||
Sessions. All environment values are optional, but some values like credentials
|
||||
require multiple of the values to set or the partial values will be ignored.
|
||||
All environment variable values are strings unless otherwise noted.
|
||||
|
||||
Environment configuration values. If set both Access Key ID and Secret Access
|
||||
Key must be provided. Session Token and optionally also be provided, but is
|
||||
not required.
|
||||
|
||||
# Access Key ID
|
||||
AWS_ACCESS_KEY_ID=AKID
|
||||
AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set.
|
||||
|
||||
# Secret Access Key
|
||||
AWS_SECRET_ACCESS_KEY=SECRET
|
||||
AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set.
|
||||
|
||||
# Session Token
|
||||
AWS_SESSION_TOKEN=TOKEN
|
||||
|
||||
Region value will instruct the SDK where to make service API requests to. If is
|
||||
not provided in the environment the region must be provided before a service
|
||||
client request is made.
|
||||
|
||||
AWS_REGION=us-east-1
|
||||
|
||||
# AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set,
|
||||
# and AWS_REGION is not also set.
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
|
||||
Profile name the SDK should load use when loading shared config from the
|
||||
configuration files. If not provided "default" will be used as the profile name.
|
||||
|
||||
AWS_PROFILE=my_profile
|
||||
|
||||
# AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set,
|
||||
# and AWS_PROFILE is not also set.
|
||||
AWS_DEFAULT_PROFILE=my_profile
|
||||
|
||||
SDK load config instructs the SDK to load the shared config in addition to
|
||||
shared credentials. This also expands the configuration loaded so the shared
|
||||
credentials will have parity with the shared config file. This also enables
|
||||
Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE
|
||||
env values as well.
|
||||
|
||||
AWS_SDK_LOAD_CONFIG=1
|
||||
|
||||
Shared credentials file path can be set to instruct the SDK to use an alternative
|
||||
file for the shared credentials. If not set the file will be loaded from
|
||||
$HOME/.aws/credentials on Linux/Unix based systems, and
|
||||
%USERPROFILE%\.aws\credentials on Windows.
|
||||
|
||||
AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials
|
||||
|
||||
Shared config file path can be set to instruct the SDK to use an alternative
|
||||
file for the shared config. If not set the file will be loaded from
|
||||
$HOME/.aws/config on Linux/Unix based systems, and
|
||||
%USERPROFILE%\.aws\config on Windows.
|
||||
|
||||
AWS_CONFIG_FILE=$HOME/my_shared_config
|
||||
|
||||
|
||||
*/
|
||||
package session
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user